刘帅
2026-09-21 86ce1aaf6819a6d62cfba4233219fa4661aacbff
cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
@@ -1,6 +1,7 @@
package com.dsh.guns.modular.system.controller.system;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -174,6 +175,11 @@
        }
        roleLambdaQueryWrapper.eq(Role::getObjType,UserExt.getUser().getObjectType());
        List<Role> list = roleService.list(roleLambdaQueryWrapper);
        // 员工可能是由平台账号创建、后续归属到门店的,原角色不一定属于当前登录人的角色范围。
        // 编辑时仍需保留该角色作为可选项,避免下拉框无法回显。
        if (role != null && list.stream().noneMatch(item -> Objects.equals(item.getId(), role.getId()))) {
            list.add(role);
        }
        model.addAttribute("list",list);
        model.addAttribute("language",UserExt.getLanguage());
        // 部门列表
@@ -331,6 +337,7 @@
    @BussinessLog(value = "添加管理员", key = "account", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Object add(@Valid UserDto user, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
@@ -340,7 +347,10 @@
        if (StringUtils.isEmpty(user.getPhone())) {
            return 5002;
        }
        User theUser = userService.getOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
        // 已逻辑删除的员工(status=3)不占用手机号,可用同一手机号重新创建员工。
        User theUser = userService.getOne(new QueryWrapper<User>()
                .eq("phone", user.getPhone())
                .ne("status", ManagerStatus.DELETED.getCode()));
        if (theUser != null || userService.getByAccount(user.getPhone()) != null){
            return 5001;
        }
@@ -404,13 +414,7 @@
        objectUser.setVersion(UserExt.getUser().getId());
        this.userService.save(objectUser);
        if (!assignedStores.isEmpty()) {
            userMapper.deleteStoreRelations(objectUser.getId());
            userMapper.insertStoreRelations(objectUser.getId(), assignedStores.stream().map(TStore::getId).collect(Collectors.toList()));
            // 各所选门店同步负责人账号;旧系统仍可通过 storeStaffId 查询主负责人。
            for (TStore store : assignedStores) {
                store.setStoreStaffId(objectUser.getId());
                storeService.updateById(store);
            }
            replaceStoreRelations(objectUser.getId(), assignedStores);
        }
        return SUCCESS_TIP;
    }
@@ -433,7 +437,7 @@
        if (user.getPhone() != null && user.getPhone().contains("*")) {
            // The edit view displays a masked phone. Treat an unchanged masked
            // value as "keep original", never as a value to persist.
        } else if (!oldUser.getPhone().equals(user.getPhone())){
        } else if (!Objects.equals(oldUser.getPhone(), user.getPhone())) {
            User phone = userService.getOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
            if (phone == null){
                oldUser.setPhone(user.getPhone());
@@ -452,17 +456,20 @@
        if (user.getStoreIds() != null) {
            List<TStore> assignedStores = validateStores(user.getStoreIds());
            if (assignedStores == null) return ResultUtil.error("所选门店不存在、已停用或不在当前账号管理范围内");
            userMapper.deleteStoreRelations(oldUser.getId());
            replaceStoreRelations(oldUser.getId(), assignedStores);
            if (!assignedStores.isEmpty()) {
                oldUser.setObjectType(3);
                oldUser.setObjectId(assignedStores.get(0).getId());
                oldUser.setRoleid("3");
                userMapper.insertStoreRelations(oldUser.getId(), assignedStores.stream().map(TStore::getId).collect(Collectors.toList()));
                for (TStore store : assignedStores) {
                    store.setStoreStaffId(oldUser.getId());
                    storeService.updateById(store);
                }
            } else if (Integer.valueOf(3).equals(oldUser.getObjectType())) {
                // 清除旧字段关联,避免已移除的首个门店仍被当作该员工所属门店。
                oldUser.setObjectId(null);
            }
        }
        // 门店关联会维护员工归属信息,但不能覆盖编辑页明确选择的角色。
        // 必须在关联处理后写入,否则有门店的员工会被上面的兼容逻辑强制改回角色 3。
        if (!StringUtils.isEmpty(user.getRoleid())) {
            oldUser.setRoleid(user.getRoleid());
        }
        this.userService.updateById(oldUser);
        return SUCCESS_TIP;
@@ -498,6 +505,14 @@
        return stores;
    }
    /** 每条关联记录单独生成雪花主键,避免 MyBatis foreach 复用同一个绑定变量。 */
    private void replaceStoreRelations(Integer userId, List<TStore> stores) {
        userMapper.deleteStoreRelations(userId);
        for (TStore store : stores) {
            userMapper.insertStoreRelation(IdWorker.getId(), userId, store.getId());
        }
    }
    /**
     * 删除管理员(逻辑删除)
     * Delete administrator (logical deletion)