From 5f612ab2f67b2c6f6894c624a7780799526d566d Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期四, 05 十一月 2026 20:20:05 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_business_新高电力' into dev_business_新高电力

---
 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
index dd46571..9b98bb5 100644
--- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
+++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
@@ -14,12 +14,16 @@
 import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
 import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserSyncReqDTO;
+import cn.iocoder.yudao.module.system.api.user.event.AdminUserDeletedEvent;
+import cn.iocoder.yudao.module.system.api.user.event.AdminUserUpdatedEvent;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@@ -38,6 +42,7 @@
 import jakarta.annotation.Resource;
 import jakarta.validation.ConstraintViolationException;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
@@ -91,6 +96,9 @@
 
     @Resource
     private AdminUserProducer adminUserProducer;
+
+    @Resource
+    private ApplicationEventPublisher eventPublisher;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -172,6 +180,11 @@
         // 3. 璁板綍鎿嶄綔鏃ュ織涓婁笅鏂�
         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldUser, UserSaveReqVO.class));
         LogRecordContext.putVariable("user", oldUser);
+
+        // 4. 閫氱煡 hrm 妯″潡鍚屾鍛樺伐妗f锛堟病鏈夊憳宸ユ。妗堢殑璐﹀彿浼氳鐩戝惉鍣ㄧ洿鎺ヨ烦杩囷級
+        eventPublisher.publishEvent(new AdminUserUpdatedEvent(updateReqVO.getId(),
+                updateReqVO.getNickname(), updateReqVO.getMobile(), updateReqVO.getDeptId(),
+                updateReqVO.getSex(), updateReqVO.getEmail()));
     }
 
     private void updateUserPost(UserSaveReqVO reqVO, AdminUserDO updateObj) {
@@ -197,6 +210,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateUserProfile(Long id, UserProfileUpdateReqVO reqVO) {
         // 1. 鏍¢獙姝g‘鎬�
         AdminUserDO oldUser = validateUserExists(id);
@@ -208,6 +222,10 @@
 
         // 3. 鏄电О / 澶村儚鍙樺寲鏃讹紝鍙戦�佹秷鎭緵涓嬫父璁㈤槄锛堝 IM 妯″潡鎺� FRIEND_INFO_UPDATED锛�
         publishUserProfileUpdatedIfChanged(oldUser, reqVO.getNickname(), reqVO.getAvatar());
+
+        // 4. 閫氱煡 hrm 妯″潡鍚屾鍛樺伐妗f锛堟病鏈夊憳宸ユ。妗堢殑璐﹀彿浼氳鐩戝惉鍣ㄧ洿鎺ヨ烦杩囷級
+        eventPublisher.publishEvent(new AdminUserUpdatedEvent(id,
+                reqVO.getNickname(), reqVO.getMobile(), null, reqVO.getSex(), reqVO.getEmail()));
     }
 
     /**
@@ -273,6 +291,18 @@
     @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_DELETE_SUB_TYPE, bizNo = "{{#id}}",
             success = SYSTEM_USER_DELETE_SUCCESS)
     public void deleteUser(Long id) {
+        doDeleteUser(id);
+        // 閫氱煡 hrm 妯″潡鑱斿姩鍒犻櫎鍛樺伐妗f锛堟病鏈夊憳宸ユ。妗堢殑璐﹀彿浼氳鐩戝惉鍣ㄧ洿鎺ヨ烦杩囷級
+        eventPublisher.publishEvent(new AdminUserDeletedEvent(id));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteUserSilently(Long id) {
+        doDeleteUser(id);
+    }
+
+    private void doDeleteUser(Long id) {
         // 1. 鏍¢獙鐢ㄦ埛瀛樺湪
         AdminUserDO user = validateUserExists(id);
 
@@ -298,6 +328,44 @@
             permissionService.processUserDeleted(id);
             userPostMapper.deleteByUserId(id);
         });
+
+        // 3. 閫氱煡 hrm 妯″潡鑱斿姩鍒犻櫎鍛樺伐妗f
+        ids.forEach(id -> eventPublisher.publishEvent(new AdminUserDeletedEvent(id)));
+    }
+
+    @Override
+    public void updateUserForEmployee(AdminUserSyncReqDTO reqDTO) {
+        if (reqDTO == null || reqDTO.getUserId() == null) {
+            return;
+        }
+        // 1. 鏍¢獙鐢ㄦ埛瀛樺湪
+        AdminUserDO user = validateUserExists(reqDTO.getUserId());
+        // 2. 鏍¢獙鎵嬫満鍙� / 閭鍞竴锛堜笌鏃у�间笉鍚屾椂鎵嶆牎楠岋級
+        if (StrUtil.isNotBlank(reqDTO.getMobile()) && !ObjUtil.equal(user.getMobile(), reqDTO.getMobile())) {
+            validateMobileUnique(reqDTO.getUserId(), reqDTO.getMobile());
+        }
+        if (StrUtil.isNotBlank(reqDTO.getEmail()) && !ObjUtil.equal(user.getEmail(), reqDTO.getEmail())) {
+            validateEmailUnique(reqDTO.getUserId(), reqDTO.getEmail());
+        }
+        // 3. 鍙洿鏂伴潪绌哄瓧娈�
+        AdminUserDO updateObj = new AdminUserDO();
+        updateObj.setId(reqDTO.getUserId());
+        if (StrUtil.isNotBlank(reqDTO.getNickname())) {
+            updateObj.setNickname(reqDTO.getNickname());
+        }
+        if (StrUtil.isNotBlank(reqDTO.getMobile())) {
+            updateObj.setMobile(reqDTO.getMobile());
+        }
+        if (reqDTO.getDeptId() != null) {
+            updateObj.setDeptId(reqDTO.getDeptId());
+        }
+        if (reqDTO.getSex() != null) {
+            updateObj.setSex(reqDTO.getSex());
+        }
+        if (StrUtil.isNotBlank(reqDTO.getEmail())) {
+            updateObj.setEmail(reqDTO.getEmail());
+        }
+        userMapper.updateById(updateObj);
     }
 
     @Override
@@ -514,6 +582,12 @@
         }
         // 1.2 绯荤粺鍙傛暟涓殑鍒濆瀵嗙爜锛屼綔涓� Excel 鏈~鍐欏瘑鐮佹椂鐨勫厹搴�
         String initPassword = configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY);
+        // 1.3 棰勫姞杞介儴闂細鍚嶇О -> 閮ㄩ棬锛岀敤浜庢寜鍚嶇О瑙f瀽锛堟ā鏉胯姹傚~閮ㄩ棬鍚嶇О锛岃�岄潪鏁版嵁搴撲富閿� ID锛�
+        List<DeptDO> allDepts = deptService.getDeptList(new DeptListReqVO());
+        Map<String, DeptDO> deptByName = new HashMap<>(Math.max(allDepts.size(), 1));
+        for (DeptDO dept : allDepts) {
+            deptByName.put(dept.getName().trim(), dept);
+        }
 
         // 2. 閬嶅巻锛岄�愪釜鍒涘缓 or 鏇存柊
         UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
@@ -522,6 +596,14 @@
         importUsers.forEach(importUser -> {
             int currentIndex = index.getAndIncrement();
             String key = StrUtil.blankToDefault(importUser.getUsername(), "绗� " + currentIndex + " 琛�");
+            // 2.0 瑙f瀽閮ㄩ棬锛氭寜閮ㄩ棬鍚嶇О绮剧‘鍖归厤锛屽尮閰嶄笉鍒扮粰鍑烘槑纭彁绀猴紙涓嶅啀瑕佹眰濉暟鎹簱涓婚敭 ID锛�
+            DeptDO importDept = resolveImportDept(importUser.getDeptName(), deptByName);
+            if (importDept == null && StrUtil.isNotBlank(importUser.getDeptName())) {
+                respVO.getFailureUsernames().put(key,
+                        "閮ㄩ棬銆�" + importUser.getDeptName().trim() + "銆嶄笉瀛樺湪锛岃濉啓閮ㄩ棬绠$悊涓殑瀹屾暣閮ㄩ棬鍚嶇О");
+                return;
+            }
+            Long importDeptId = importDept != null ? importDept.getId() : null;
             // 2.1.0 瑙f瀽璇ヨ鍒濆瀵嗙爜锛欵xcel 濉啓浜嗗氨鐢ㄥ~鍐欑殑锛屽惁鍒欒鍙栫郴缁熷弬鏁�
             String effectivePassword = StrUtil.isNotBlank(importUser.getPassword())
                     ? importUser.getPassword() : initPassword;
@@ -533,7 +615,8 @@
             }
             // 2.1.1 鏍¢獙瀛楁鏄惁绗﹀悎瑕佹眰
             try {
-                ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(effectivePassword));
+                ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class)
+                        .setPassword(effectivePassword).setDeptId(importDeptId));
             } catch (ConstraintViolationException ex) {
                 respVO.getFailureUsernames().put(key, ex.getMessage());
                 return;
@@ -541,7 +624,7 @@
             // 2.1.2 鏍¢獙锛屽垽鏂槸鍚︽湁涓嶇鍚堢殑鍘熷洜
             try {
                 validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
-                        importUser.getDeptId(), null);
+                        importDeptId, null);
             } catch (ServiceException ex) {
                 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
                 return;
@@ -551,6 +634,7 @@
             AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
             if (existUser == null) {
                 userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class)
+                        .setDeptId(importDeptId) // 閮ㄩ棬宸叉寜鍚嶇О瑙f瀽锛岄渶鏄惧紡鍥炲~ ID
                         .setPassword(encodePassword(effectivePassword)).setPostIds(new HashSet<>())); // 璁剧疆鍒濆瀵嗙爜鍙婄┖宀椾綅缂栧彿鏁扮粍
                 respVO.getCreateUsernames().add(importUser.getUsername());
                 return;
@@ -562,6 +646,7 @@
             }
             AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);
             updateUser.setId(existUser.getId());
+            updateUser.setDeptId(importDeptId); // 閮ㄩ棬宸叉寜鍚嶇О瑙f瀽锛岄渶鏄惧紡鍥炲~ ID
             // 瀵嗙爜鍗曠嫭澶勭悊锛欵xcel 濉啓浜嗘墠鏇存柊锛涙湭濉啓鍒欑疆绌猴紝淇濇寔鍘熷瘑鐮佷笉鍙橈紙閬垮厤鎶婃槑鏂囧啓杩涘簱锛�
             updateUser.setPassword(StrUtil.isNotBlank(importUser.getPassword())
                     ? encodePassword(importUser.getPassword()) : null);
@@ -571,6 +656,23 @@
         return respVO;
     }
 
+    /**
+     * 瑙f瀽瀵煎叆琛岄噷鐨勯儴闂ㄥ悕绉�
+     *
+     * <p>鍙寜閮ㄩ棬鍚嶇О绮剧‘鍖归厤锛堜笉鍐嶈姹傚~鍐欐暟鎹簱涓婚敭 ID锛夛紝
+     * 閬垮厤浣跨敤鑰呮棤浠庡緱鐭ラ儴闂� ID 瀵艰嚧瀵煎叆蹇呯劧澶辫触銆�</p>
+     *
+     * @param raw    瀵煎叆濉啓鐨勯儴闂ㄥ悕绉�
+     * @param byName 閮ㄩ棬鍚嶇О -> 閮ㄩ棬
+     * @return 鍖归厤鍒扮殑閮ㄩ棬锛涙湭濉啓鎴栧尮閰嶄笉鍒拌繑鍥� null
+     */
+    private DeptDO resolveImportDept(String raw, Map<String, DeptDO> byName) {
+        if (StrUtil.isBlank(raw)) {
+            return null;
+        }
+        return byName.get(raw.trim());
+    }
+
     @Override
     public List<AdminUserDO> getUserListByStatus(Integer status) {
         return userMapper.selectListByStatus(status);

--
Gitblit v1.9.3