| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportExcelVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractTerminateReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeContractDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeContractMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | @Resource |
| | | private HrmEmployeeMapper employeeMapper; |
| | | @Resource |
| | | private DeptApi deptApi; |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | | @Resource |
| | | private HrmNoRedisDAO noRedisDAO; |
| | | @Resource |
| | | @Lazy // 自注入需延迟加载,导入时逐条走事务边界 |
| | | private HrmEmployeeContractService self; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public HrmEmployeeContractImportRespVO importContractList(List<HrmEmployeeContractImportExcelVO> importContracts, |
| | | HrmEmployeeContractImportReqVO importReqVO) { |
| | | // 1. 过滤员工姓名为空的行 |
| | | importContracts = importContracts.stream() |
| | | .filter(item -> item.getName() != null && StrUtil.isNotBlank(item.getName().trim())) |
| | | .collect(Collectors.toList()); |
| | | if (CollUtil.isEmpty(importContracts)) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_LIST_IS_EMPTY); |
| | | } |
| | | // 2. 预加载员工姓名 -> 员工档案 映射(含已离职,便于补录历史合同) |
| | | Map<String, List<HrmEmployeeDO>> employeeNameMap = employeeMapper.selectList().stream() |
| | | .filter(emp -> StrUtil.isNotBlank(emp.getName())) |
| | | .collect(Collectors.groupingBy(emp -> emp.getName().trim(), LinkedHashMap::new, Collectors.toList())); |
| | | // 3. 逐条处理:匹配到则覆盖更新,否则新建 |
| | | HrmEmployeeContractImportRespVO respVO = HrmEmployeeContractImportRespVO.builder() |
| | | .createNames(new ArrayList<>()) |
| | | .updateNames(new ArrayList<>()) |
| | | .failureNames(new LinkedHashMap<>()) |
| | | .build(); |
| | | for (HrmEmployeeContractImportExcelVO importContract : importContracts) { |
| | | String name = importContract.getName().trim(); |
| | | try { |
| | | // 3.1 员工姓名转员工 ID |
| | | Long employeeId = parseEmployeeId(name, employeeNameMap); |
| | | // 3.2 组装保存请求(必填字段校验) |
| | | HrmEmployeeContractSaveReqVO saveReqVO = buildImportSaveReqVO(importContract, employeeId); |
| | | // 3.3 按「员工 + 合同类型 + 合同开始日期」判定已存在 |
| | | HrmEmployeeContractDO exist = contractMapper.selectByEmployeeTypeStartDate(employeeId, |
| | | saveReqVO.getContractType(), saveReqVO.getStartDate()); |
| | | if (exist == null) { |
| | | self.createContract(saveReqVO); |
| | | respVO.getCreateNames().add(name); |
| | | } else { |
| | | if (!Boolean.TRUE.equals(importReqVO.getUpdateSupport())) { |
| | | respVO.getFailureNames().put(name, |
| | | StrUtil.format(EMPLOYEE_CONTRACT_IMPORT_CONTRACT_EXISTS.getMsg(), |
| | | saveReqVO.getStartDate().toString())); |
| | | continue; |
| | | } |
| | | saveReqVO.setId(exist.getId()); |
| | | self.updateContract(saveReqVO); |
| | | respVO.getUpdateNames().add(name); |
| | | } |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureNames().put(name, ex.getMessage()); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureNames().put(name, ex.getMessage()); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | | * 员工姓名解析为员工 ID,重名时提示需手工处理 |
| | | */ |
| | | private Long parseEmployeeId(String name, Map<String, List<HrmEmployeeDO>> employeeNameMap) { |
| | | List<HrmEmployeeDO> employees = employeeNameMap.get(name); |
| | | if (CollUtil.isEmpty(employees)) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_NOT_EXISTS, name); |
| | | } |
| | | if (employees.size() > 1) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_MULTIPLE, name); |
| | | } |
| | | return employees.get(0).getId(); |
| | | } |
| | | |
| | | /** |
| | | * 组装导入合同保存请求并做必填字段校验(日期逻辑校验交由 create/update 处理) |
| | | */ |
| | | private HrmEmployeeContractSaveReqVO buildImportSaveReqVO(HrmEmployeeContractImportExcelVO importContract, |
| | | Long employeeId) { |
| | | if (importContract.getContractType() == null) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "合同类型"); |
| | | } |
| | | if (importContract.getContractTermType() == null) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "合同期限类型"); |
| | | } |
| | | if (importContract.getStartDate() == null) { |
| | | throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "合同开始日期"); |
| | | } |
| | | HrmEmployeeContractSaveReqVO reqVO = new HrmEmployeeContractSaveReqVO(); |
| | | reqVO.setEmployeeId(employeeId); |
| | | reqVO.setContractType(importContract.getContractType()); |
| | | reqVO.setContractTermType(importContract.getContractTermType()); |
| | | reqVO.setSignCompany(importContract.getSignCompany()); |
| | | reqVO.setSignDate(importContract.getSignDate()); |
| | | reqVO.setStartDate(importContract.getStartDate()); |
| | | reqVO.setEndDate(importContract.getEndDate()); |
| | | reqVO.setProbationStartDate(importContract.getProbationStartDate()); |
| | | reqVO.setProbationEndDate(importContract.getProbationEndDate()); |
| | | reqVO.setProbationSalary(importContract.getProbationSalary()); |
| | | reqVO.setRegularSalary(importContract.getRegularSalary()); |
| | | reqVO.setRemark(importContract.getRemark()); |
| | | return reqVO; |
| | | } |
| | | |
| | | } |