| | |
| | | |
| | | 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()); |
| | | } |
| | | |
| | | /** |
| | |
| | | // 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; |
| | | } |
| | |
| | | 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); |
| | |
| | | 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())) { |
| | | // 清除旧字段关联,避免已移除的首个门店仍被当作该员工所属门店。 |
| | |
| | | |
| | | 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); |