From d41e0da5df20d559b0b9b8c180d1bf70ba7c1845 Mon Sep 17 00:00:00 2001
From: 刘帅 <rr.iii@qq.com>
Date: 星期三, 07 十月 2026 17:49:26 +0800
Subject: [PATCH] 员工管理权限修改(新需求)

---
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java |   98 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
index c62f9dd..2e78cf6 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
@@ -113,14 +113,21 @@
 
     private List<TStore> availableStores() {
         LambdaQueryWrapper<TStore> query = new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1);
-        Integer objectType = UserExt.getUser().getObjectType();
-        Integer objectId = UserExt.getUser().getObjectId();
-        if (Integer.valueOf(2).equals(objectType)) {
-            query.eq(TStore::getOperatorId, objectId);
-        } else if (Integer.valueOf(3).equals(objectType)) {
-            query.eq(TStore::getId, objectId);
+        User currentUser = UserExt.getUser();
+        // 超级管理员可维护全部启用门店;其他员工仅能看到自己被分配的门店。
+        // getStoreIdsByUserId 同时兼容 sys_user_store、多门店改造前的 objectId,及历史店长数据。
+        if (!isSuperAdmin(currentUser)) {
+            List<Integer> storeIds = userMapper.getStoreIdsByUserId(currentUser.getId());
+            if (storeIds == null || storeIds.isEmpty()) {
+                return Collections.emptyList();
+            }
+            query.in(TStore::getId, storeIds);
         }
         return storeService.list(query);
+    }
+
+    private boolean isSuperAdmin(User user) {
+        return user != null && "admin".equalsIgnoreCase(user.getAccount());
     }
 
     /**
@@ -313,10 +320,14 @@
 //                return res1;
                 return filteredList;
             case 3:
-                // 门店只查询门店员工
-                TStore store = storeService.getById(objectId);
-                List<Integer> storeIds = userQuery.getStoreIds();
-                storeIds.add(store.getStoreStaffId());
+                // 门店员工可同时归属多个门店,员工列表应汇总这些门店下的所有员工。
+                List<Integer> currentStoreIds = userMapper.getStoreIdsByUserId(UserExt.getUser().getId());
+                List<Integer> employeeIds = currentStoreIds == null || currentStoreIds.isEmpty()
+                        ? Collections.<Integer>emptyList()
+                        : userMapper.getUserIdsByStoreIds(currentStoreIds);
+                // searchUsers 在集合为空时不会拼接 IN 条件;用不存在的 ID 明确返回空结果,避免越权看到全部员工。
+                userQuery.setStoreIds(employeeIds == null || employeeIds.isEmpty()
+                        ? Collections.singletonList(-1) : employeeIds);
                 List<UserListVO> res2= userService.searchUsers(userQuery);
                 return res2;
         }
@@ -393,19 +404,8 @@
         objectUser.setCreatetime(new Date());
         List<TStore> assignedStores = new ArrayList<TStore>();
         if (user.getStoreIds() != null && !user.getStoreIds().isEmpty()) {
-            List<Integer> storeIds = user.getStoreIds().stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
-            if (storeIds.isEmpty()) return ResultUtil.error("请选择有效门店");
-            Integer currentType = UserExt.getUser().getObjectType();
-            Integer currentObjectId = UserExt.getUser().getObjectId();
-            for (Integer storeId : storeIds) {
-                TStore store = storeService.getById(storeId);
-                if (store == null || !Integer.valueOf(1).equals(store.getState())) return ResultUtil.error("所选门店不存在或已停用");
-                if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId()))
-                        || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) {
-                    return ResultUtil.error("所选门店不在当前账号的管理范围内");
-                }
-                assignedStores.add(store);
-            }
+            assignedStores = validateStores(user.getStoreIds());
+            if (assignedStores == null || assignedStores.isEmpty()) return ResultUtil.error("所选门店不存在、已停用或不在当前账号的管理范围内");
             // 首个门店同步写入旧字段,保证既有权限、数据查询和登录逻辑无需改造。
             TStore primaryStore = assignedStores.get(0);
             objectUser.setObjectType(3);
@@ -475,10 +475,13 @@
         if (user.getStoreIds() != null) {
             List<TStore> assignedStores = validateStores(user.getStoreIds());
             if (assignedStores == null) return ResultUtil.error("所选门店不存在、已停用或不在当前账号管理范围内");
-            replaceStoreRelations(oldUser.getId(), assignedStores);
-            if (!assignedStores.isEmpty()) {
+            // 非超级管理员的页面只会展示自己有权限的门店。保存时仅更新这个范围,
+            // 被编辑员工在其他门店(当前账号无权查看)的归属必须原样保留。
+            List<TStore> effectiveStores = mergeEditableAndProtectedStores(oldUser.getId(), assignedStores);
+            replaceStoreRelations(oldUser.getId(), effectiveStores);
+            if (!effectiveStores.isEmpty()) {
                 oldUser.setObjectType(3);
-                oldUser.setObjectId(assignedStores.get(0).getId());
+                oldUser.setObjectId(effectiveStores.get(0).getId());
                 oldUser.setRoleid("3");
             } else if (Integer.valueOf(3).equals(oldUser.getObjectType())) {
                 // 清除旧字段关联,避免已移除的首个门店仍被当作该员工所属门店。
@@ -531,18 +534,53 @@
 
     private List<TStore> validateStores(List<Integer> storeIds) {
         List<TStore> stores = new ArrayList<TStore>();
-        Integer currentType = UserExt.getUser().getObjectType();
-        Integer currentObjectId = UserExt.getUser().getObjectId();
+        User currentUser = UserExt.getUser();
+        if (storeIds == null) return stores;
+        Set<Integer> manageableStoreIds = null;
+        if (!isSuperAdmin(currentUser)) {
+            List<Integer> assignedStoreIds = userMapper.getStoreIdsByUserId(currentUser.getId());
+            manageableStoreIds = assignedStoreIds == null ? Collections.<Integer>emptySet() : new HashSet<>(assignedStoreIds);
+        }
         for (Integer storeId : storeIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList())) {
             TStore store = storeService.getById(storeId);
             if (store == null || !Integer.valueOf(1).equals(store.getState())) return null;
-            if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId()))
-                    || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) return null;
+            if (manageableStoreIds != null && !manageableStoreIds.contains(storeId)) return null;
             stores.add(store);
         }
         return stores;
     }
 
+    /**
+     * 合并本次可编辑范围内的选择与原有不可编辑门店,避免局部管理员覆盖其他门店的归属。
+     */
+    private List<TStore> mergeEditableAndProtectedStores(Integer userId, List<TStore> editableStores) {
+        if (isSuperAdmin(UserExt.getUser())) {
+            return editableStores;
+        }
+
+        List<Integer> currentUserStoreIds = userMapper.getStoreIdsByUserId(UserExt.getUser().getId());
+        Set<Integer> editableStoreIds = currentUserStoreIds == null
+                ? Collections.<Integer>emptySet() : new HashSet<>(currentUserStoreIds);
+        Map<Integer, TStore> effectiveStoreMap = new LinkedHashMap<>();
+        for (TStore store : editableStores) {
+            effectiveStoreMap.put(store.getId(), store);
+        }
+
+        List<Integer> previousStoreIds = userMapper.getStoreIdsByUserId(userId);
+        if (previousStoreIds != null) {
+            for (Integer storeId : previousStoreIds) {
+                if (storeId == null || editableStoreIds.contains(storeId)) {
+                    continue;
+                }
+                TStore store = storeService.getById(storeId);
+                if (store != null) {
+                    effectiveStoreMap.put(storeId, store);
+                }
+            }
+        }
+        return new ArrayList<>(effectiveStoreMap.values());
+    }
+
     /** 每条关联记录单独生成雪花主键,避免 MyBatis foreach 复用同一个绑定变量。 */
     private void replaceStoreRelations(Integer userId, List<TStore> stores) {
         userMapper.deleteStoreRelations(userId);

--
Gitblit v1.7.1