tuqin
23 小时以前 ba100c651a81162a9a9a4533ff4d072f2889171a
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -40,6 +40,7 @@
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserCreateReqDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserUpdateReqDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -69,7 +70,11 @@
 */
@Service
@Validated
@Slf4j
public class HrmEmployeeServiceImpl implements HrmEmployeeService {
    /** 员工状态:离职(1-在职,2-试用,3-离职) */
    private static final Integer EMPLOYEE_STATUS_RESIGNED = 3;
    @Resource
    private HrmEmployeeMapper employeeMapper;
@@ -104,9 +109,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();
@@ -186,10 +197,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);
@@ -359,7 +374,63 @@
    @Override
    public List<HrmEmployeeDO> getEmployeeList(Collection<Long> ids) {
        // 防御:MyBatis-Plus 的 selectByIds(null) 会抛
        // BuilderException: The expression 'coll' evaluated to a null value
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return employeeMapper.selectByIds(ids);
    }
    @Override
    public List<HrmEmployeeDO> getEmployeeListByStatus(Integer employeeStatus) {
        return employeeMapper.selectListByStatus(employeeStatus);
    }
    @Override
    public void syncEmployeeTransfer(Long employeeId, Long targetDeptId, Long targetPostId) {
        if (employeeId == null) {
            return;
        }
        HrmEmployeeDO employee = employeeMapper.selectById(employeeId);
        if (employee == null) {
            log.warn("[syncEmployeeTransfer][员工({}) 不存在,跳过调岗同步]", employeeId);
            return;
        }
        if (targetDeptId == null && targetPostId == null) {
            return;
        }
        HrmEmployeeDO updateObj = new HrmEmployeeDO();
        updateObj.setId(employeeId);
        if (targetDeptId != null) {
            updateObj.setDeptId(targetDeptId);
        }
        if (targetPostId != null) {
            // hrm_employee.post_ids 存 JSON 数组字符串,如 [38]
            updateObj.setPostIds(JSONUtil.toJsonStr(java.util.List.of(targetPostId)));
        }
        employeeMapper.updateById(updateObj);
        log.info("[syncEmployeeTransfer][员工({}) 调岗生效:部门 {} -> {},岗位 -> {}]",
                employeeId, employee.getDeptId(), targetDeptId, targetPostId);
    }
    @Override
    public void syncEmployeeResignation(Long systemUserId, java.time.LocalDate leaveDate) {
        if (systemUserId == null) {
            return;
        }
        HrmEmployeeDO employee = employeeMapper.selectByUserId(systemUserId);
        if (employee == null) {
            log.warn("[syncEmployeeResignation][系统用户({}) 没有对应员工档案,跳过离职同步]", systemUserId);
            return;
        }
        employeeMapper.updateById(HrmEmployeeDO.builder()
                .id(employee.getId())
                .employeeStatus(EMPLOYEE_STATUS_RESIGNED)
                .leaveDate(leaveDate != null ? leaveDate : java.time.LocalDate.now())
                .build());
        log.info("[syncEmployeeResignation][员工({}) 离职生效,状态 {} -> {}]",
                employee.getId(), employee.getEmployeeStatus(), EMPLOYEE_STATUS_RESIGNED);
    }
    @Override
@@ -449,6 +520,14 @@
    }
    @Override
    public List<HrmEmployeeDO> getEmployeeListByNameLike(String name) {
        if (StrUtil.isBlank(name)) {
            return new ArrayList<>();
        }
        return employeeMapper.selectListByNameLike(name.trim());
    }
    @Override
    public HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees,
                                                      HrmEmployeeImportReqVO importReqVO) {
        // 1. 校验非空