From 83dea93d02925e162ad88954b7d0ed97dd8a442a Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期二, 15 九月 2026 13:20:24 +0800
Subject: [PATCH] fix(mdm): 修复物料导入/下载模板报系统异常

---
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java |  110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java
index 7243ed7..80cb347 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java
@@ -2,26 +2,34 @@
 
 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;
@@ -50,11 +58,16 @@
     @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)
@@ -318,4 +331,101 @@
         }
     }
 
+    @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. 棰勫姞杞藉憳宸ュ鍚� -> 鍛樺伐妗f 鏄犲皠锛堝惈宸茬鑱岋紝渚夸簬琛ュ綍鍘嗗彶鍚堝悓锛�
+        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;
+    }
+
+    /**
+     * 鍛樺伐濮撳悕瑙f瀽涓哄憳宸� 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;
+    }
+
 }

--
Gitblit v1.9.3