From ba100c651a81162a9a9a4533ff4d072f2889171a Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期五, 06 十一月 2026 09:38:46 +0800
Subject: [PATCH] fix(hrm): 考勤统计支持员工姓名搜索;缺卡统计补全(与考勤记录联动)

---
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java |   93 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
index d32b4c5..23778f5 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
+++ b/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. 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪锛�**鍖呭惈宸插垹闄ゆ。妗�**锛歶k_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) {
+        // 闃插尽锛歁yBatis-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][绯荤粺鐢ㄦ埛({}) 娌℃湁瀵瑰簲鍛樺伐妗f锛岃烦杩囩鑱屽悓姝", 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. 鏍¢獙闈炵┖

--
Gitblit v1.9.3