2026-08-10 a378f38df1785cbc8c9f1d55ace6a37952d2f65b
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -3,10 +3,14 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
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.HrmEmployeeEducationSaveReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEmergencyContactSaveReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportExcelVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportRespVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeePageReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeRespVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeSaveReqVO;
@@ -30,12 +34,16 @@
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserCreateReqDTO;
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.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -43,6 +51,7 @@
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
/**
@@ -72,6 +81,9 @@
    private AdminUserApi adminUserApi;
    @Resource
    private RoleApi roleApi;
    @Resource
    @Lazy // 自注入需延迟加载,否则 bean 被代理包装后注入原始版本导致启动失败
    private HrmEmployeeService self;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -322,4 +334,131 @@
        return employeeMapper.selectByUserId(userId);
    }
    @Override
    public HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees,
                                                      HrmEmployeeImportReqVO importReqVO) {
        // 1. 校验非空
        importEmployees = filterList(importEmployees, item -> Objects.nonNull(item.getName()));
        if (CollUtil.isEmpty(importEmployees)) {
            throw exception(EMPLOYEE_IMPORT_LIST_IS_EMPTY);
        }
        // 2. 预加载部门/岗位/角色 名称 -> 实体 映射
        Map<String, DeptRespDTO> deptMap = deptApi.getDeptList().stream()
                .collect(Collectors.toMap(DeptRespDTO::getName, dept -> dept, (v1, v2) -> v1));
        Map<String, PostRespDTO> postMap = postApi.getPostList().stream()
                .collect(Collectors.toMap(PostRespDTO::getName, post -> post, (v1, v2) -> v1));
        Map<String, RoleRespDTO> roleMap = roleApi.getRoleList().stream()
                .collect(Collectors.toMap(RoleRespDTO::getName, role -> role, (v1, v2) -> v1));
        // 3. 逐条处理
        HrmEmployeeImportRespVO respVO = HrmEmployeeImportRespVO.builder()
                .createNames(new ArrayList<>())
                .updateNames(new ArrayList<>())
                .failureNames(new LinkedHashMap<>())
                .build();
        for (HrmEmployeeImportExcelVO importEmployee : importEmployees) {
            String name = importEmployee.getName();
            try {
                // 3.1 名称转 ID
                Long deptId = parseDeptId(importEmployee.getDeptName(), deptMap);
                Long postId = parsePostId(importEmployee.getPostName(), postMap);
                Set<Long> roleIds = parseRoleIds(importEmployee.getRoleNames(), roleMap);
                // 3.2 构建保存请求
                HrmEmployeeSaveReqVO saveReqVO = buildImportSaveReqVO(importEmployee, deptId, postId, roleIds);
                // 3.3 判断存在性:按手机号
                HrmEmployeeDO existEmployee = employeeMapper.selectByPhone(importEmployee.getPhone());
                if (existEmployee == null) {
                    self.createEmployee(saveReqVO);
                    respVO.getCreateNames().add(name);
                } else {
                    if (!Boolean.TRUE.equals(importReqVO.getUpdateSupport())) {
                        respVO.getFailureNames().put(name, EMPLOYEE_PHONE_EXISTS.getMsg());
                        continue;
                    }
                    saveReqVO.setId(existEmployee.getId());
                    self.updateEmployee(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;
    }
    private HrmEmployeeSaveReqVO buildImportSaveReqVO(HrmEmployeeImportExcelVO importEmployee,
                                                      Long deptId, Long postId, Set<Long> roleIds) {
        if (StrUtil.isBlank(importEmployee.getName())) {
            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "员工姓名");
        }
        if (StrUtil.isBlank(importEmployee.getPhone())) {
            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "手机号");
        }
        if (importEmployee.getHireDate() == null) {
            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "入职日期");
        }
        HrmEmployeeSaveReqVO reqVO = new HrmEmployeeSaveReqVO();
        reqVO.setName(importEmployee.getName());
        reqVO.setGender(importEmployee.getGender() != null ? importEmployee.getGender() : 1); // 默认男
        reqVO.setPhone(importEmployee.getPhone());
        reqVO.setDeptId(deptId);
        reqVO.setPostId(postId);
        reqVO.setRoleIds(CollUtil.isEmpty(roleIds) ? null : new ArrayList<>(roleIds));
        reqVO.setHireDate(importEmployee.getHireDate());
        reqVO.setEmployeeStatus(importEmployee.getEmployeeStatus() != null
                ? importEmployee.getEmployeeStatus() : 1); // 默认在职
        reqVO.setEmail(importEmployee.getEmail());
        reqVO.setBirthday(importEmployee.getBirthday());
        reqVO.setIdCard(importEmployee.getIdCard());
        reqVO.setNation(importEmployee.getNation());
        reqVO.setMarriageStatus(importEmployee.getMarriageStatus());
        reqVO.setAge(importEmployee.getAge());
        reqVO.setEducation(importEmployee.getEducation());
        reqVO.setPoliticalStatus(importEmployee.getPoliticalStatus());
        reqVO.setRemark(importEmployee.getRemark());
        return reqVO;
    }
    private Long parseDeptId(String deptName, Map<String, DeptRespDTO> deptMap) {
        if (StrUtil.isBlank(deptName)) {
            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "部门名称");
        }
        DeptRespDTO dept = deptMap.get(deptName.trim());
        if (dept == null) {
            throw exception(EMPLOYEE_DEPT_NAME_NOT_EXISTS, deptName.trim());
        }
        return dept.getId();
    }
    private Long parsePostId(String postName, Map<String, PostRespDTO> postMap) {
        if (StrUtil.isBlank(postName)) {
            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "岗位名称");
        }
        PostRespDTO post = postMap.get(postName.trim());
        if (post == null) {
            throw exception(EMPLOYEE_POST_NAME_NOT_EXISTS, postName.trim());
        }
        return post.getId();
    }
    private Set<Long> parseRoleIds(String roleNames, Map<String, RoleRespDTO> roleMap) {
        if (StrUtil.isBlank(roleNames)) {
            return Collections.emptySet();
        }
        Set<Long> roleIds = new LinkedHashSet<>();
        for (String roleName : roleNames.split("[,,]")) {
            String trimmed = roleName.trim();
            if (StrUtil.isBlank(trimmed)) {
                continue;
            }
            RoleRespDTO role = roleMap.get(trimmed);
            if (role == null) {
                throw exception(EMPLOYEE_ROLE_NAME_NOT_EXISTS, trimmed);
            }
            roleIds.add(role.getId());
        }
        return roleIds;
    }
}