feat(hrm): 新增员工紧急联系人管理功能
完成员工紧急联系人模块的全流程开发,包括: 1. 数据库表结构、Mapper、Service、Controller后端代码 2. 前端页面、API接口、导入导出功能 3. 配套SQL脚本、导入模板与使用文档 4. 支持批量导入导出、数据校验与用户关联匹配
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
package com.ruoyi.hrm.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.service.IHrmEmergencyContactService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/hrm/emergencyContact")
|
||||
public class HrmEmergencyContactController extends BaseController {
|
||||
|
||||
private final IHrmEmergencyContactService service;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<HrmEmergencyContactVo> list(HrmEmergencyContactBo bo, PageQuery pageQuery) {
|
||||
return service.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
@GetMapping("/{contactId}")
|
||||
public R<HrmEmergencyContactVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long contactId) {
|
||||
return R.ok(service.queryById(contactId));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated @RequestBody HrmEmergencyContactBo bo) {
|
||||
return toAjax(service.insertByBo(bo));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated @RequestBody HrmEmergencyContactBo bo) {
|
||||
return toAjax(service.updateByBo(bo));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{contactIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] contactIds) {
|
||||
return toAjax(service.deleteWithValidByIds(Arrays.asList(contactIds), true));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HrmEmergencyContactBo bo, HttpServletResponse response) {
|
||||
List<HrmEmergencyContactVo> list = service.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "紧急联系人数据", HrmEmergencyContactVo.class, response);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<String> importData(@RequestPart("file") MultipartFile file, @RequestParam(defaultValue = "false") boolean updateSupport) throws IOException {
|
||||
List<HrmEmergencyContactImportVo> list = ExcelUtil.importExcel(file.getInputStream(), HrmEmergencyContactImportVo.class, false).getList();
|
||||
String msg = service.importByVoList(list, updateSupport);
|
||||
return R.ok(msg);
|
||||
}
|
||||
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("紧急联系人导入模板", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
// 示例数据(字段名第一行,示例数据第二行)
|
||||
List<HrmEmergencyContactImportVo> exampleList = new ArrayList<>();
|
||||
|
||||
// 添加示例数据
|
||||
HrmEmergencyContactImportVo example = new HrmEmergencyContactImportVo();
|
||||
example.setHireDate("2025.06.18");
|
||||
example.setCompanyName("山东福安德信息科技有限公司");
|
||||
example.setDeptName("信息化部");
|
||||
example.setRealName("张三");
|
||||
example.setPhone("183xxxxxxxx");
|
||||
example.setIdCard("341xxxxxxxxxxxxxxx");
|
||||
example.setGender("男");
|
||||
example.setAge(23);
|
||||
example.setEmergencyContact("李四");
|
||||
example.setRelationship("母子");
|
||||
example.setEmergencyPhone1("159xxxxxxxx");
|
||||
example.setEmergencyPhone2("");
|
||||
example.setEmergencyAddress("xx省xx市xx县xx镇xx村");
|
||||
example.setRemark("仅紧急情况联系");
|
||||
exampleList.add(example);
|
||||
|
||||
// 使用EasyExcel写入(字段名在第一行,示例数据在第二行)
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
EasyExcel.write(out, HrmEmergencyContactImportVo.class)
|
||||
.sheet("导入模板")
|
||||
.doWrite(exampleList);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ruoyi.hrm.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hrm_emergency_contact")
|
||||
public class HrmEmergencyContact extends BaseEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long contactId;
|
||||
private Long userId;
|
||||
private Long deptId;
|
||||
private String realName;
|
||||
private String phone;
|
||||
private String idCard;
|
||||
private String gender;
|
||||
private Integer age;
|
||||
private String companyName;
|
||||
private Date hireDate;
|
||||
private String emergencyContact;
|
||||
private String relationship;
|
||||
private String emergencyPhone1;
|
||||
private String emergencyPhone2;
|
||||
private String emergencyAddress;
|
||||
private String remark;
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ruoyi.hrm.domain.bo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class HrmEmergencyContactBo extends BaseEntity {
|
||||
|
||||
private Long contactId;
|
||||
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long userId;
|
||||
|
||||
private Long deptId;
|
||||
private String realName;
|
||||
private String phone;
|
||||
private String idCard;
|
||||
private String gender;
|
||||
private Integer age;
|
||||
private String companyName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date hireDate;
|
||||
|
||||
@NotBlank(message = "紧急联系人姓名不能为空")
|
||||
private String emergencyContact;
|
||||
|
||||
private String relationship;
|
||||
|
||||
@NotBlank(message = "紧急联系人电话1不能为空")
|
||||
private String emergencyPhone1;
|
||||
|
||||
private String emergencyPhone2;
|
||||
private String emergencyAddress;
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.ruoyi.hrm.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.excel.annotation.write.style.ContentStyle;
|
||||
import com.alibaba.excel.annotation.write.style.HeadStyle;
|
||||
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 紧急联系人导入 VO
|
||||
* 与用户提供的Excel格式保持一致
|
||||
*
|
||||
* Excel表头顺序:
|
||||
* 入职时间 | 公司名称 | 部门 | 姓名 | 联系电话 | 身份证号 | 性别 | 年龄 | 紧急联系人 | 与本人关系 | 联系电话1 | 联系电话2 | 紧急联系人地址 | 备注
|
||||
*/
|
||||
@Data
|
||||
@HeadStyle(fillForegroundColor = 44, horizontalAlignment = HorizontalAlignmentEnum.CENTER)
|
||||
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.LEFT)
|
||||
public class HrmEmergencyContactImportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 入职时间
|
||||
* 格式:yyyy.MM.dd 或 yyyy-MM-dd
|
||||
*/
|
||||
@Excel(name = "入职时间", width = 12)
|
||||
@ExcelProperty("入职时间")
|
||||
@ColumnWidth(12)
|
||||
private String hireDate;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
@Excel(name = "公司名称", width = 40)
|
||||
@ExcelProperty("公司名称")
|
||||
@ColumnWidth(40)
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
@Excel(name = "部门", width = 12)
|
||||
@ExcelProperty("部门")
|
||||
@ColumnWidth(12)
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
@Excel(name = "姓名", width = 10)
|
||||
@ExcelProperty("姓名")
|
||||
@ColumnWidth(10)
|
||||
private String realName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
@Excel(name = "联系电话", width = 15)
|
||||
@ExcelProperty("联系电话")
|
||||
@ColumnWidth(15)
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
@Excel(name = "身份证号", width = 22)
|
||||
@ExcelProperty("身份证号")
|
||||
@ColumnWidth(22)
|
||||
private String idCard;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
@Excel(name = "性别", width = 8, readConverterExp = "男=0,女=1,未知=2")
|
||||
@ExcelProperty("性别")
|
||||
@ColumnWidth(8)
|
||||
private String gender;
|
||||
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
@Excel(name = "年龄", width = 8)
|
||||
@ExcelProperty("年龄")
|
||||
@ColumnWidth(8)
|
||||
private Integer age;
|
||||
|
||||
/**
|
||||
* 紧急联系人
|
||||
*/
|
||||
@Excel(name = "紧急联系人", width = 12)
|
||||
@ExcelProperty("紧急联系人")
|
||||
@ColumnWidth(12)
|
||||
private String emergencyContact;
|
||||
|
||||
/**
|
||||
* 与本人关系
|
||||
*/
|
||||
@Excel(name = "与本人关系", width = 12)
|
||||
@ExcelProperty("与本人关系")
|
||||
@ColumnWidth(12)
|
||||
private String relationship;
|
||||
|
||||
/**
|
||||
* 联系电话1
|
||||
*/
|
||||
@Excel(name = "联系电话1", width = 15)
|
||||
@ExcelProperty("联系电话1")
|
||||
@ColumnWidth(15)
|
||||
private String emergencyPhone1;
|
||||
|
||||
/**
|
||||
* 联系电话2
|
||||
*/
|
||||
@Excel(name = "联系电话2", width = 15)
|
||||
@ExcelProperty("联系电话2")
|
||||
@ColumnWidth(15)
|
||||
private String emergencyPhone2;
|
||||
|
||||
/**
|
||||
* 紧急联系人地址
|
||||
*/
|
||||
@Excel(name = "紧急联系人地址", width = 40)
|
||||
@ExcelProperty("紧急联系人地址")
|
||||
@ColumnWidth(40)
|
||||
private String emergencyAddress;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Excel(name = "备注", width = 20)
|
||||
@ExcelProperty("备注")
|
||||
@ColumnWidth(20)
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ruoyi.hrm.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class HrmEmergencyContactVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "联系人ID")
|
||||
private Long contactId;
|
||||
|
||||
@Excel(name = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Excel(name = "部门ID")
|
||||
private Long deptId;
|
||||
|
||||
@Excel(name = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Excel(name = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Excel(name = "联系电话")
|
||||
private String phone;
|
||||
|
||||
@Excel(name = "身份证号")
|
||||
private String idCard;
|
||||
|
||||
@Excel(name = "性别", readConverterExp = "0=男,1=女,2=未知")
|
||||
private String gender;
|
||||
|
||||
@Excel(name = "年龄")
|
||||
private Integer age;
|
||||
|
||||
@Excel(name = "公司名称")
|
||||
private String companyName;
|
||||
|
||||
@Excel(name = "入职时间", width = 20, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date hireDate;
|
||||
|
||||
@Excel(name = "紧急联系人")
|
||||
private String emergencyContact;
|
||||
|
||||
@Excel(name = "与本人关系")
|
||||
private String relationship;
|
||||
|
||||
@Excel(name = "紧急电话1")
|
||||
private String emergencyPhone1;
|
||||
|
||||
@Excel(name = "紧急电话2")
|
||||
private String emergencyPhone2;
|
||||
|
||||
@Excel(name = "紧急联系人地址")
|
||||
private String emergencyAddress;
|
||||
|
||||
@Excel(name = "备注")
|
||||
private String remark;
|
||||
|
||||
private String createBy;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
private String updateBy;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.ruoyi.hrm.mapper;
|
||||
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import com.ruoyi.hrm.domain.HrmEmergencyContact;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
|
||||
public interface HrmEmergencyContactMapper extends BaseMapperPlus<HrmEmergencyContactMapper, HrmEmergencyContact, HrmEmergencyContactVo> {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ruoyi.hrm.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface IHrmEmergencyContactService {
|
||||
|
||||
HrmEmergencyContactVo queryById(Long contactId);
|
||||
|
||||
TableDataInfo<HrmEmergencyContactVo> queryPageList(HrmEmergencyContactBo bo, PageQuery pageQuery);
|
||||
|
||||
List<HrmEmergencyContactVo> queryList(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean insertByBo(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean updateByBo(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
String importByVoList(List<HrmEmergencyContactImportVo> voList, boolean updateSupport);
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package com.ruoyi.hrm.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.hrm.domain.HrmEmergencyContact;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.hrm.mapper.HrmEmergencyContactMapper;
|
||||
import com.ruoyi.hrm.service.IHrmEmergencyContactService;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HrmEmergencyContactServiceImpl implements IHrmEmergencyContactService {
|
||||
|
||||
private final HrmEmergencyContactMapper baseMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
|
||||
// 手机号正则
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||
// 身份证号正则(15位或18位)
|
||||
private static final Pattern ID_CARD_PATTERN = Pattern.compile("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)");
|
||||
|
||||
@Override
|
||||
public HrmEmergencyContactVo queryById(Long contactId) {
|
||||
return baseMapper.selectVoById(contactId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<HrmEmergencyContactVo> queryPageList(HrmEmergencyContactBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = buildQueryWrapper(bo);
|
||||
Page<HrmEmergencyContactVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HrmEmergencyContactVo> queryList(HrmEmergencyContactBo bo) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(HrmEmergencyContactBo bo) {
|
||||
HrmEmergencyContact add = BeanUtil.toBean(bo, HrmEmergencyContact.class);
|
||||
return baseMapper.insert(add) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(HrmEmergencyContactBo bo) {
|
||||
HrmEmergencyContact update = BeanUtil.toBean(bo, HrmEmergencyContact.class);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importByVoList(List<HrmEmergencyContactImportVo> voList, boolean updateSupport) {
|
||||
if (CollUtil.isEmpty(voList)) {
|
||||
throw new ServiceException("导入数据不能为空");
|
||||
}
|
||||
int successNum = 0;
|
||||
int failNum = 0;
|
||||
StringBuilder failMsg = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < voList.size(); i++) {
|
||||
HrmEmergencyContactImportVo vo = voList.get(i);
|
||||
int rowNum = i + 2;
|
||||
|
||||
try {
|
||||
// 转换日期格式:将 yyyy.MM.dd 转换为 yyyy-MM-dd
|
||||
Date hireDate = null;
|
||||
if (StrUtil.isNotBlank(vo.getHireDate())) {
|
||||
String dateStr = vo.getHireDate().replace(".", "-");
|
||||
vo.setHireDate(dateStr);
|
||||
hireDate = DateUtil.parseDate(dateStr);
|
||||
}
|
||||
|
||||
// 性别转换:Excel 中为"男"/"女"/"未知",统一转代码值
|
||||
String gender = vo.getGender();
|
||||
if (StrUtil.isNotBlank(gender)) {
|
||||
if ("男".equals(gender)) { gender = "0"; }
|
||||
else if ("女".equals(gender)) { gender = "1"; }
|
||||
else if ("未知".equals(gender)) { gender = "2"; }
|
||||
vo.setGender(gender);
|
||||
}
|
||||
|
||||
// 数据校验
|
||||
String validateMsg = validateImportData(vo);
|
||||
if (StrUtil.isNotBlank(validateMsg)) {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(StrUtil.blankToDefault(vo.getRealName(), "无名")).append(":").append(validateMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
HrmEmergencyContact entity = BeanUtil.toBean(vo, HrmEmergencyContact.class);
|
||||
// 根据姓名+身份证号匹配 sys_user,自动填充 userId/deptId
|
||||
Long matchedUserId = matchUserId(vo.getRealName(), vo.getIdCard());
|
||||
entity.setUserId(matchedUserId != null ? matchedUserId : 0L);
|
||||
// 显式设置入职日期(BeanUtil 可能无法自动转换 String -> Date)
|
||||
if (hireDate != null) {
|
||||
entity.setHireDate(hireDate);
|
||||
}
|
||||
|
||||
// 按「姓名 + 身份证号」去重
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(HrmEmergencyContact::getRealName, entity.getRealName());
|
||||
lqw.eq(HrmEmergencyContact::getIdCard, entity.getIdCard());
|
||||
HrmEmergencyContact existing = baseMapper.selectOne(lqw);
|
||||
|
||||
if (existing != null) {
|
||||
if (updateSupport) {
|
||||
entity.setContactId(existing.getContactId());
|
||||
baseMapper.updateById(entity);
|
||||
successNum++;
|
||||
} else {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(vo.getRealName()).append(":数据已存在(姓名+身份证号重复)");
|
||||
}
|
||||
} else {
|
||||
baseMapper.insert(entity);
|
||||
successNum++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(StrUtil.blankToDefault(vo.getRealName(), "无名")).append(":导入失败,").append(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (failNum > 0) {
|
||||
return "导入完成!成功 " + successNum + " 条,失败 " + failNum + " 条。错误信息:" + failMsg;
|
||||
}
|
||||
return "恭喜您,数据已全部导入成功!共 " + successNum + " 条";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据姓名+身份证号匹配 sys_user,返回 userId;匹配不到返回 null
|
||||
*/
|
||||
private Long matchUserId(String realName, String idCard) {
|
||||
// 1. 优先按 realName + idCard 精确匹配
|
||||
if (StrUtil.isNotBlank(realName) && StrUtil.isNotBlank(idCard)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getNickName, realName)
|
||||
.eq(SysUser::getIdCard, idCard)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
// 2. 仅按 idCard 匹配(唯一性高)
|
||||
if (StrUtil.isNotBlank(idCard)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getIdCard, idCard)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
// 3. 仅按 realName 匹配(有重名风险,作为最后的兜底)
|
||||
if (StrUtil.isNotBlank(realName)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getNickName, realName)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验导入数据
|
||||
*/
|
||||
private String validateImportData(HrmEmergencyContactImportVo vo) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
|
||||
if (StrUtil.isBlank(vo.getRealName())) {
|
||||
msg.append("姓名为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getPhone())) {
|
||||
msg.append("联系电话为空;");
|
||||
} else if (!PHONE_PATTERN.matcher(vo.getPhone()).matches()) {
|
||||
msg.append("联系电话格式错误(需11位手机号);");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getIdCard())) {
|
||||
msg.append("身份证号为空;");
|
||||
} else if (!ID_CARD_PATTERN.matcher(vo.getIdCard()).matches()) {
|
||||
msg.append("身份证号格式错误;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getGender())) {
|
||||
msg.append("性别为空;");
|
||||
}
|
||||
if (vo.getAge() == null) {
|
||||
msg.append("年龄为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyContact())) {
|
||||
msg.append("紧急联系人为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getRelationship())) {
|
||||
msg.append("与本人关系为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyPhone1())) {
|
||||
msg.append("联系电话1为空;");
|
||||
} else if (!PHONE_PATTERN.matcher(vo.getEmergencyPhone1()).matches()) {
|
||||
msg.append("联系电话1格式错误(需11位手机号);");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyAddress())) {
|
||||
msg.append("紧急联系人地址为空;");
|
||||
}
|
||||
if (StrUtil.isNotBlank(vo.getEmergencyPhone2()) && !PHONE_PATTERN.matcher(vo.getEmergencyPhone2()).matches()) {
|
||||
msg.append("联系电话2格式错误(需11位手机号);");
|
||||
}
|
||||
|
||||
return msg.toString();
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HrmEmergencyContact> buildQueryWrapper(HrmEmergencyContactBo bo) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getContactId() != null, HrmEmergencyContact::getContactId, bo.getContactId());
|
||||
lqw.eq(bo.getUserId() != null, HrmEmergencyContact::getUserId, bo.getUserId());
|
||||
lqw.like(bo.getRealName() != null, HrmEmergencyContact::getRealName, bo.getRealName());
|
||||
lqw.like(bo.getPhone() != null, HrmEmergencyContact::getPhone, bo.getPhone());
|
||||
lqw.like(bo.getEmergencyContact() != null, HrmEmergencyContact::getEmergencyContact, bo.getEmergencyContact());
|
||||
lqw.eq(bo.getDeptId() != null, HrmEmergencyContact::getDeptId, bo.getDeptId());
|
||||
lqw.eq(bo.getGender() != null, HrmEmergencyContact::getGender, bo.getGender());
|
||||
return lqw;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user