liu
3 天以前 9aa810eae18397cc5e452feedbe453800d9aaa5c
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -48,6 +48,7 @@
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -103,9 +104,15 @@
        deptApi.validateDeptList(Collections.singleton(createReqVO.getDeptId()));
        // 2. 校验岗位
        postApi.validPostList(createReqVO.getPostIds());
        // 3. 校验手机号是否已存在
        if (employeeMapper.selectByPhone(createReqVO.getPhone()) != null) {
            throw exception(EMPLOYEE_PHONE_EXISTS);
        // 3. 校验手机号是否已存在(**包含已删除档案**:uk_phone 唯一索引不区分 deleted,
        //    只查未删除记录会漏判,导致写库时抛唯一约束异常,前端显示“系统异常”)
        if (createReqVO.getPhone() != null) {
            HrmEmployeeDO existPhone = employeeMapper.selectByPhoneIgnoreDeleted(createReqVO.getPhone());
            if (existPhone != null) {
                throw existPhone.getDeleted() != null && existPhone.getDeleted()
                        ? exception(EMPLOYEE_PHONE_OCCUPIED_BY_DELETED, createReqVO.getPhone())
                        : exception(EMPLOYEE_PHONE_EXISTS);
            }
        }
        // 4. 同步创建系统用户
        AdminUserCreateReqDTO userCreateReqDTO = new AdminUserCreateReqDTO();
@@ -185,10 +192,14 @@
        deptApi.validateDeptList(Collections.singleton(updateReqVO.getDeptId()));
        // 校验岗位
        postApi.validPostList(updateReqVO.getPostIds());
        // 校验手机号是否已存在(如果手机号有变更)
        if (!Objects.equals(employee.getPhone(), updateReqVO.getPhone())
                && employeeMapper.selectByPhone(updateReqVO.getPhone()) != null) {
            throw exception(EMPLOYEE_PHONE_EXISTS);
        // 校验手机号是否已存在(如果手机号有变更;**包含已删除档案**,原因见 createEmployee)
        if (!Objects.equals(employee.getPhone(), updateReqVO.getPhone()) && updateReqVO.getPhone() != null) {
            HrmEmployeeDO existPhone = employeeMapper.selectByPhoneIgnoreDeleted(updateReqVO.getPhone());
            if (existPhone != null && !Objects.equals(existPhone.getId(), updateReqVO.getId())) {
                throw existPhone.getDeleted() != null && existPhone.getDeleted()
                        ? exception(EMPLOYEE_PHONE_OCCUPIED_BY_DELETED, updateReqVO.getPhone())
                        : exception(EMPLOYEE_PHONE_EXISTS);
            }
        }
        // 更新员工主表
        HrmEmployeeDO updateObj = BeanUtils.toBean(updateReqVO, HrmEmployeeDO.class);
@@ -370,19 +381,68 @@
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(deptIds);
        // 解析岗位ID(post_ids 存的是 JSON 数组字符串,如 [38]),并批量加载岗位名称
        Map<Long, List<Long>> empPostIdsMap = new LinkedHashMap<>();
        Set<Long> allPostIds = new LinkedHashSet<>();
        for (HrmEmployeeDO emp : list) {
            List<Long> postIdList = parseEmployeePostIds(emp.getPostIds());
            empPostIdsMap.put(emp.getId(), postIdList);
            allPostIds.addAll(postIdList);
        }
        Map<Long, PostRespDTO> postMap = CollUtil.isEmpty(allPostIds)
                ? Collections.emptyMap() : postApi.getPostMap(allPostIds);
        return list.stream().map(emp -> {
            HrmEmployeeSimpleRespVO vo = new HrmEmployeeSimpleRespVO();
            vo.setId(emp.getId());
            vo.setEmployeeNo(emp.getEmployeeNo());
            vo.setName(emp.getName());
            vo.setEmployeeStatus(emp.getEmployeeStatus());
            vo.setDeptId(emp.getDeptId());
            if (emp.getDeptId() != null && deptMap.containsKey(emp.getDeptId())) {
                vo.setDeptName(deptMap.get(emp.getDeptId()).getName());
            }
            // 岗位信息(用于调岗等场景自动带出原岗位)
            List<Long> postIdList = empPostIdsMap.getOrDefault(emp.getId(), Collections.emptyList());
            vo.setPostIds(postIdList);
            if (CollUtil.isNotEmpty(postIdList)) {
                vo.setPostName(postIdList.stream()
                        .map(postMap::get)
                        .filter(Objects::nonNull)
                        .map(PostRespDTO::getName)
                        .collect(Collectors.joining(",")));
            }
            return vo;
        }).collect(Collectors.toList());
    }
    /**
     * 解析员工的岗位ID字符串(JSON 数组格式,如 [38] 或 [1,2])
     */
    /**
     * 解析员工岗位ID字符串(post_ids 存 JSON 数组,如 [38] 或 [1,2])
     */
    private java.util.List<Long> parseEmployeePostIds(String postIds) {
        if (StrUtil.isBlank(postIds)) {
            return Collections.emptyList();
        }
        // post_ids 形如 "[38]" 或 "[1,2]":去掉中括号后按逗号解析
        return Arrays.stream(postIds.replace("[", "").replace("]", "").split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .map(s -> {
                    try {
                        return Long.valueOf(s);
                    } catch (NumberFormatException ex) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    @Override
    public HrmEmployeeDO getEmployeeByUserId(Long userId) {
        return employeeMapper.selectByUserId(userId);