Explorar o código

优化用户角色

SpringSunYY hai 4 meses
pai
achega
77140a994a

+ 15 - 20
ruoyi-ui/src/views/system/role/index.vue

@@ -516,22 +516,17 @@ export default {
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
-      const roleId = row.roleId || this.ids
-      const roleMenu = this.getRoleMenuTreeselect(roleId);
-      getRole(roleId).then(response => {
-        this.form = response.data;
+      const roleId = row.roleId || this.ids;
+      Promise.all([this.getRoleMenuTreeselect(roleId), getRole(roleId)]).then(([menuRes, roleRes]) => {
+        this.form = roleRes.data;
         this.open = true;
+        this.title = "修改角色";
         this.$nextTick(() => {
-          roleMenu.then(res => {
-            let checkedKeys = res.checkedKeys
-            checkedKeys.forEach((v) => {
-                this.$nextTick(()=>{
-                    this.$refs.menu.setChecked(v, true ,false);
-                })
-            })
-          });
+          const checkedKeys = (this.form.menuIds && this.form.menuIds.length) ? this.form.menuIds : (menuRes.checkedKeys || []);
+          if (this.$refs.menu) {
+            this.$refs.menu.setCheckedKeys(checkedKeys);
+          }
         });
-        this.title = "修改角色";
       });
     },
     /** 选择角色权限范围触发 */
@@ -543,16 +538,16 @@ export default {
     /** 分配数据权限操作 */
     handleDataScope(row) {
       this.reset();
-      const roleDeptTreeselect = this.getRoleDeptTreeselect(row.roleId);
-      getRole(row.roleId).then(response => {
-        this.form = response.data;
+      Promise.all([this.getRoleDeptTreeselect(row.roleId), getRole(row.roleId)]).then(([deptRes, roleRes]) => {
+        this.form = roleRes.data;
         this.openDataScope = true;
+        this.title = "分配数据权限";
         this.$nextTick(() => {
-          roleDeptTreeselect.then(res => {
-            this.$refs.dept.setCheckedKeys(res.checkedKeys);
-          });
+          const checkedKeys = (this.form.deptIds && this.form.deptIds.length) ? this.form.deptIds : (deptRes.checkedKeys || []);
+          if (this.$refs.dept) {
+            this.$refs.dept.setCheckedKeys(checkedKeys);
+          }
         });
-        this.title = "分配数据权限";
       });
     },
     /** 分配用户操作 */

+ 1 - 1
ruoyi_admin/controller/system/user.py

@@ -118,7 +118,7 @@ def system_update_user(dto: SysUser):
             f"新增用户'{dto.phonenumber}'失败,手机号码已存在"
         )
     elif dto.email \
-            and SysUserService.check_email_unique(dto.email) \
+            and SysUserService.check_email_unique(dto) \
             == UserConstants.NOT_UNIQUE:
         return AjaxResponse.from_error(
             f"新增用户'{dto.email}'失败,邮箱已存在"

+ 1 - 1
ruoyi_framework/service/sys_login.py

@@ -141,7 +141,7 @@ class LoginService:
             login_ip=IpUtil.get_ip(),
             login_date=datetime.datetime.now()
             )
-        SysUserService.update_user(sysuser)
+        SysUserService.update_user_login_info(sysuser)
     
     @classmethod
     def build_logininfor(cls, username:str,status:str,message:str) -> SysLogininfor:

+ 15 - 0
ruoyi_system/mapper/sys_role_dept.py

@@ -81,3 +81,18 @@ class SysRoleDeptMapper:
             .where(SysRoleDeptPo.dept_id == dept_id)
         return db.session.execute(stmt).scalar_one_or_none() or 0
 
+    @classmethod
+    def select_dept_ids_by_role_id(cls, role_id: int) -> List[int]:
+        """
+        查询角色下的部门ID列表
+
+        Args:
+            role_id (int): 角色ID
+
+        Returns:
+            List[int]: 部门ID列表
+        """
+        stmt = select(SysRoleDeptPo.dept_id) \
+            .where(SysRoleDeptPo.role_id == role_id)
+        return db.session.execute(stmt).scalars().all()
+

+ 15 - 0
ruoyi_system/mapper/sys_role_menu.py

@@ -17,6 +17,21 @@ class SysRoleMenuMapper:
     """
     
     @classmethod
+    def select_menu_ids_by_role_id(cls, role_id: int) -> List[int]:
+        """
+        查询角色下的菜单ID列表
+
+        Args:
+            role_id: 角色ID
+
+        Returns:
+            菜单ID列表
+        """
+        stmt = select(SysRoleMenuPo.menu_id) \
+            .where(SysRoleMenuPo.role_id == role_id)
+        return db.session.execute(stmt).scalars().all()
+    
+    @classmethod
     def check_menu_exist_role(cls, menu_id: int) -> int:
         """
         查询菜单下的菜单数量

+ 32 - 2
ruoyi_system/mapper/sys_user.py

@@ -305,9 +305,14 @@ class SysUserMapper:
             "remark", "update_time"
         }
         data = user.model_dump(
-            include=fields, exclude_unset=True, exclude_none=True
+            include=fields,
+            exclude_unset=True,
+            exclude_none=True
         )
-        if user.password is not None:
+        # 如果密码为空字符串或 None,则不更新密码字段,避免把密码清空
+        if not user.password:
+            data.pop("password", None)
+        else:
             data["password"] = user.password
         stmt = update(SysUserPo) \
             .where(SysUserPo.user_id == user.user_id) \
@@ -316,6 +321,31 @@ class SysUserMapper:
 
     @classmethod
     @Transactional(db.session)
+    def update_user_login_info(cls, user: SysUser) -> int:
+        """
+        更新用户登录信息(登录IP、时间等)
+
+        Args:
+            user (SysUser): 用户信息(需包含 user_id)
+
+        Returns:
+            int: 修改数量
+        """
+        fields = {"login_ip", "login_date", "update_time"}
+        data = user.model_dump(
+            include=fields,
+            exclude_unset=True,
+            exclude_none=True
+        )
+        if not data:
+            return 0
+        stmt = update(SysUserPo) \
+            .where(SysUserPo.user_id == user.user_id) \
+            .values(data)
+        return db.session.execute(stmt).rowcount
+
+    @classmethod
+    @Transactional(db.session)
     def update_user_avatar(cls, user_name: str, avatar: str) -> int:
         """
         修改用户头像

+ 7 - 3
ruoyi_system/service/sys_role.py

@@ -113,7 +113,11 @@ class SysRoleService:
         Returns:
             SysRole: 角色信息
         """
-        return SysRoleMapper.select_role_by_id(role_id)
+        role = SysRoleMapper.select_role_by_id(role_id)
+        if role:
+            role.menu_ids = SysRoleMenuMapper.select_menu_ids_by_role_id(role_id)
+            role.dept_ids = SysRoleDeptMapper.select_dept_ids_by_role_id(role_id)
+        return role
     
     @classmethod
     def check_role_name_unique(cls, role: SysRole) -> Literal['0', '1']:
@@ -141,8 +145,8 @@ class SysRoleService:
         Returns:
             Literal['0', '1'] : 唯一性校验结果, 0:唯一, 1:不唯一
         """
-        eo:SysRole = SysRoleMapper.check_role_key_unique(role.role_key)
-        if eo and eo.role_id == role.role_id:
+        eo: SysRole = SysRoleMapper.check_role_key_unique(role.role_key)
+        if eo and eo.role_id != role.role_id:
             return UserConstants.NOT_UNIQUE
         return UserConstants.UNIQUE
 

+ 14 - 0
ruoyi_system/service/sys_user.py

@@ -270,6 +270,20 @@ class SysUserService:
         return SysUserMapper.update_user(user)
 
     @classmethod
+    def update_user_login_info(cls, user: SysUser) -> bool:
+        """
+        更新用户登录信息(登录IP、时间)
+
+        Args:
+            user (SysUser): 用户信息
+
+        Returns:
+            bool: 操作结果
+        """
+        user.update_time = datetime.now()
+        return SysUserMapper.update_user_login_info(user) > 0
+
+    @classmethod
     @Transactional(db.session)
     def insert_user_auth(cls, user_id: int, role_ids: List[int]):
         """