From fdbc5af6474abb39120b771af87005aeb6186ae5 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期一, 14 九月 2026 15:28:28 +0800
Subject: [PATCH] feat: 售后工单按条绑定部门与原因类型;新增加班工资管理;员工附件留档

---
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java |  107 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 88 insertions(+), 19 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 02e3c20..92a709e 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
@@ -31,8 +31,11 @@
 import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
 import cn.iocoder.yudao.module.system.api.permission.RoleApi;
 import cn.iocoder.yudao.module.system.api.permission.dto.RoleRespDTO;
+import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
+import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 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 org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -82,6 +85,8 @@
     @Resource
     private RoleApi roleApi;
     @Resource
+    private StorageAttachmentApi storageAttachmentApi;
+    @Resource
     @Lazy // 鑷敞鍏ラ渶寤惰繜鍔犺浇锛屽惁鍒� bean 琚唬鐞嗗寘瑁呭悗娉ㄥ叆鍘熷鐗堟湰瀵艰嚧鍚姩澶辫触
     private HrmEmployeeService self;
 
@@ -91,7 +96,7 @@
         // 1. 鏍¢獙閮ㄩ棬
         deptApi.validateDeptList(Collections.singleton(createReqVO.getDeptId()));
         // 2. 鏍¢獙宀椾綅
-        postApi.validPostList(Collections.singleton(createReqVO.getPostId()));
+        postApi.validPostList(createReqVO.getPostIds());
         // 3. 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪
         if (employeeMapper.selectByPhone(createReqVO.getPhone()) != null) {
             throw exception(EMPLOYEE_PHONE_EXISTS);
@@ -101,7 +106,7 @@
         userCreateReqDTO.setUsername(createReqVO.getPhone());
         userCreateReqDTO.setNickname(createReqVO.getName());
         userCreateReqDTO.setDeptId(createReqVO.getDeptId());
-        userCreateReqDTO.setPostIds(Collections.singleton(createReqVO.getPostId()));
+        userCreateReqDTO.setPostIds(new LinkedHashSet<>(createReqVO.getPostIds()));
         userCreateReqDTO.setMobile(createReqVO.getPhone());
         userCreateReqDTO.setPassword(createReqVO.getPhone());
         userCreateReqDTO.setSex(createReqVO.getGender());
@@ -122,8 +127,14 @@
         if (CollUtil.isNotEmpty(createReqVO.getRoleIds())) {
             employee.setRoleIds(JSONUtil.toJsonStr(createReqVO.getRoleIds()));
         }
+        // postIds 瀛樺偍涓� JSON
+        if (CollUtil.isNotEmpty(createReqVO.getPostIds())) {
+            employee.setPostIds(JSONUtil.toJsonStr(createReqVO.getPostIds()));
+        }
         employeeMapper.insert(employee);
         Long employeeId = employee.getId();
+        // 缁戝畾闄勪欢
+        storageAttachmentApi.bindAttachments("file", "hrm_employee", employeeId, createReqVO.getBlobIds());
         // 7. 鍚屾娣诲姞鏁欒偛缁忓巻
         if (CollUtil.isNotEmpty(createReqVO.getEducations())) {
             createReqVO.getEducations().forEach(educationVO -> {
@@ -167,7 +178,7 @@
         // 鏍¢獙閮ㄩ棬
         deptApi.validateDeptList(Collections.singleton(updateReqVO.getDeptId()));
         // 鏍¢獙宀椾綅
-        postApi.validPostList(Collections.singleton(updateReqVO.getPostId()));
+        postApi.validPostList(updateReqVO.getPostIds());
         // 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪锛堝鏋滄墜鏈哄彿鏈夊彉鏇达級
         if (!Objects.equals(employee.getPhone(), updateReqVO.getPhone())
                 && employeeMapper.selectByPhone(updateReqVO.getPhone()) != null) {
@@ -179,7 +190,24 @@
         if (CollUtil.isNotEmpty(updateReqVO.getRoleIds())) {
             updateObj.setRoleIds(JSONUtil.toJsonStr(updateReqVO.getRoleIds()));
         }
+        // postIds 瀛樺偍涓� JSON
+        if (CollUtil.isNotEmpty(updateReqVO.getPostIds())) {
+            updateObj.setPostIds(JSONUtil.toJsonStr(updateReqVO.getPostIds()));
+        }
         employeeMapper.updateById(updateObj);
+        // 鍚屾鏇存柊鍏宠仈绯荤粺鐢ㄦ埛锛堝矖浣�/閮ㄩ棬/鏄电О/瑙掕壊/閭/澶囨敞锛夛紝淇濇寔涓庣敤鎴风鐞嗕竴鑷�
+        if (employee.getUserId() != null) {
+            AdminUserUpdateReqDTO userUpdateReqDTO = new AdminUserUpdateReqDTO();
+            userUpdateReqDTO.setId(employee.getUserId());
+            userUpdateReqDTO.setNickname(updateReqVO.getName());
+            userUpdateReqDTO.setDeptId(updateReqVO.getDeptId());
+            userUpdateReqDTO.setPostIds(new LinkedHashSet<>(updateReqVO.getPostIds()));
+            userUpdateReqDTO.setRoleIds(CollUtil.isEmpty(updateReqVO.getRoleIds()) ? null
+                    : new LinkedHashSet<>(updateReqVO.getRoleIds()));
+            userUpdateReqDTO.setEmail(updateReqVO.getEmail());
+            userUpdateReqDTO.setRemark(updateReqVO.getRemark());
+            adminUserApi.updateUser(userUpdateReqDTO);
+        }
         Long employeeId = updateReqVO.getId();
 
         // 鍚屾鏁欒偛缁忓巻
@@ -188,6 +216,8 @@
         syncWorkHistoryList(employeeId, updateReqVO.getWorkHistories());
         // 鍚屾绱ф�ヨ仈绯讳汉
         syncEmergencyContactList(employeeId, updateReqVO.getEmergencyContacts());
+        // 鏇存柊闄勪欢
+        storageAttachmentApi.updateAttachments("file", "hrm_employee", employeeId, updateReqVO.getBlobIds());
     }
 
     private void syncEducationList(Long employeeId, List<HrmEmployeeEducationSaveReqVO> newList) {
@@ -235,6 +265,8 @@
         educationMapper.deleteByEmployeeId(id);
         workHistoryMapper.deleteByEmployeeId(id);
         emergencyContactMapper.deleteByEmployeeId(id);
+        // 鍒犻櫎闄勪欢
+        storageAttachmentApi.deleteAttachmentsByRecord("hrm_employee", id);
         // 鍒犻櫎鍛樺伐
         employeeMapper.deleteById(id);
     }
@@ -270,12 +302,16 @@
                 respVO.setDeptName(dept.getName());
             }
         }
-        // 濉厖宀椾綅鍚嶇О
-        if (employee.getPostId() != null) {
-            Map<Long, PostRespDTO> postMap = postApi.getPostMap(Collections.singleton(employee.getPostId()));
-            PostRespDTO post = postMap.get(employee.getPostId());
-            if (post != null) {
-                respVO.setPostName(post.getName());
+        // 濉厖宀椾綅淇℃伅
+        if (StrUtil.isNotBlank(employee.getPostIds())) {
+            List<Long> postIds = JSONUtil.toList(employee.getPostIds(), Long.class);
+            respVO.setPostIds(postIds);
+            if (CollUtil.isNotEmpty(postIds)) {
+                Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
+                respVO.setPostNames(postIds.stream()
+                        .filter(postMap::containsKey)
+                        .map(postId -> postMap.get(postId).getName())
+                        .collect(Collectors.joining(",")));
             }
         }
         // 濉厖瑙掕壊鍚嶇О
@@ -285,6 +321,8 @@
                 respVO.setRoleNames(roles.stream().map(RoleRespDTO::getName).collect(Collectors.joining(",")));
             }
         }
+        // 濉厖闄勪欢
+        respVO.setAttachmentList(storageAttachmentApi.listAttachments("hrm_employee", id));
         return respVO;
     }
 
@@ -299,6 +337,16 @@
 
     @Override
     public PageResult<HrmEmployeeDO> getEmployeePage(HrmEmployeePageReqVO pageReqVO) {
+        if (pageReqVO.getDeptId() != null) {
+            // 閫変腑閮ㄩ棬鏃讹紝杩炲甫鏌ヨ鍏舵墍鏈夊瓙閮ㄩ棬鐨勫憳宸ワ紙鍚嚜韬級
+            List<DeptRespDTO> childDepts = deptApi.getChildDeptList(pageReqVO.getDeptId());
+            Set<Long> deptIds = new LinkedHashSet<>();
+            deptIds.add(pageReqVO.getDeptId());
+            if (CollUtil.isNotEmpty(childDepts)) {
+                childDepts.forEach(dept -> deptIds.add(dept.getId()));
+            }
+            return employeeMapper.selectPageByDeptIds(pageReqVO, deptIds);
+        }
         return employeeMapper.selectPage(pageReqVO);
     }
 
@@ -335,6 +383,16 @@
     }
 
     @Override
+    public HrmEmployeeDO getEmployeeByName(String name) {
+        return employeeMapper.selectByName(name);
+    }
+
+    @Override
+    public List<HrmEmployeeDO> getEmployeeListByName(String name) {
+        return employeeMapper.selectListByName(name);
+    }
+
+    @Override
     public HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees,
                                                       HrmEmployeeImportReqVO importReqVO) {
         // 1. 鏍¢獙闈炵┖
@@ -360,10 +418,10 @@
             try {
                 // 3.1 鍚嶇О杞� ID
                 Long deptId = parseDeptId(importEmployee.getDeptName(), deptMap);
-                Long postId = parsePostId(importEmployee.getPostName(), postMap);
+                Set<Long> postIds = parsePostIds(importEmployee.getPostName(), postMap);
                 Set<Long> roleIds = parseRoleIds(importEmployee.getRoleNames(), roleMap);
                 // 3.2 鏋勫缓淇濆瓨璇锋眰
-                HrmEmployeeSaveReqVO saveReqVO = buildImportSaveReqVO(importEmployee, deptId, postId, roleIds);
+                HrmEmployeeSaveReqVO saveReqVO = buildImportSaveReqVO(importEmployee, deptId, postIds, roleIds);
                 // 3.3 鍒ゆ柇瀛樺湪鎬э細鎸夋墜鏈哄彿
                 HrmEmployeeDO existEmployee = employeeMapper.selectByPhone(importEmployee.getPhone());
                 if (existEmployee == null) {
@@ -388,7 +446,7 @@
     }
 
     private HrmEmployeeSaveReqVO buildImportSaveReqVO(HrmEmployeeImportExcelVO importEmployee,
-                                                      Long deptId, Long postId, Set<Long> roleIds) {
+                                                      Long deptId, Set<Long> postIds, Set<Long> roleIds) {
         if (StrUtil.isBlank(importEmployee.getName())) {
             throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "鍛樺伐濮撳悕");
         }
@@ -403,7 +461,7 @@
         reqVO.setGender(importEmployee.getGender() != null ? importEmployee.getGender() : 1); // 榛樿鐢�
         reqVO.setPhone(importEmployee.getPhone());
         reqVO.setDeptId(deptId);
-        reqVO.setPostId(postId);
+        reqVO.setPostIds(CollUtil.isEmpty(postIds) ? null : new ArrayList<>(postIds));
         reqVO.setRoleIds(CollUtil.isEmpty(roleIds) ? null : new ArrayList<>(roleIds));
         reqVO.setHireDate(importEmployee.getHireDate());
         reqVO.setEmployeeStatus(importEmployee.getEmployeeStatus() != null
@@ -431,15 +489,26 @@
         return dept.getId();
     }
 
-    private Long parsePostId(String postName, Map<String, PostRespDTO> postMap) {
-        if (StrUtil.isBlank(postName)) {
+    private Set<Long> parsePostIds(String postNames, Map<String, PostRespDTO> postMap) {
+        if (StrUtil.isBlank(postNames)) {
             throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "宀椾綅鍚嶇О");
         }
-        PostRespDTO post = postMap.get(postName.trim());
-        if (post == null) {
-            throw exception(EMPLOYEE_POST_NAME_NOT_EXISTS, postName.trim());
+        Set<Long> postIds = new LinkedHashSet<>();
+        for (String postName : postNames.split("[,锛宂")) {
+            String trimmed = postName.trim();
+            if (StrUtil.isBlank(trimmed)) {
+                continue;
+            }
+            PostRespDTO post = postMap.get(trimmed);
+            if (post == null) {
+                throw exception(EMPLOYEE_POST_NAME_NOT_EXISTS, trimmed);
+            }
+            postIds.add(post.getId());
         }
-        return post.getId();
+        if (CollUtil.isEmpty(postIds)) {
+            throw exception(EMPLOYEE_IMPORT_FIELD_REQUIRED, "宀椾綅鍚嶇О");
+        }
+        return postIds;
     }
 
     private Set<Long> parseRoleIds(String roleNames, Map<String, RoleRespDTO> roleMap) {

--
Gitblit v1.9.3