huliang hace 1 año
padre
commit
036de08ad7

+ 18 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java

@@ -139,4 +139,22 @@ public class SysMenuController extends BaseController
         }
         return toAjax(menuService.deleteMenuById(menuId));
     }
+
+
+
+    /**
+     * 加载对应用户菜单列表树
+     */
+    @GetMapping(value = "/roleUserMenuTreeselect/{userId}")
+    public AjaxResult roleUserMenuTreeselect(@PathVariable("userId") Long userId)
+    {
+        //管理员菜单
+        List<SysMenu> menus = menuService.selectMenuList(1L);
+        AjaxResult ajax = AjaxResult.success();
+        //查询某个用户已有的惨淡
+        ajax.put("checkedKeys", menuService.selectUserMenuListByUserId(userId));
+        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
+        return ajax;
+    }
+
 }

+ 12 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java

@@ -89,6 +89,10 @@ public class SysUser extends BaseEntity
     /** 角色ID */
     private Long roleId;
 
+
+    /** 菜单组 */
+    private Long[] menuIds;
+
     public SysUser()
     {
 
@@ -287,6 +291,14 @@ public class SysUser extends BaseEntity
         this.postIds = postIds;
     }
 
+    public Long[] getMenuIds() {
+        return menuIds;
+    }
+
+    public void setMenuIds(Long[] menuIds) {
+        this.menuIds = menuIds;
+    }
+
     public Long getRoleId()
     {
         return roleId;

+ 46 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleUserMenu.java

@@ -0,0 +1,46 @@
+package com.ruoyi.system.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 用户和菜单关联 sys_role_user_menu
+ * 
+ * @author ruoyi
+ */
+public class SysRoleUserMenu
+{
+    /** 角色ID */
+    private Long userId;
+    
+    /** 菜单ID */
+    private Long menuId;
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getMenuId()
+    {
+        return menuId;
+    }
+
+    public void setMenuId(Long menuId)
+    {
+        this.menuId = menuId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("userId", getUserId())
+            .append("menuId", getMenuId())
+            .toString();
+    }
+}

+ 10 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java

@@ -74,6 +74,16 @@ public interface SysMenuMapper
      */
     public List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
 
+
+    /**
+     * 根据用户ID查询菜单树信息
+     *
+     * @param userId 角色ID
+     * @param menuCheckStrictly 菜单树选择项是否关联显示
+     * @return 选中菜单列表
+     */
+    public List<Long> selectUserMenuListByUserId(@Param("userId") Long userId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
+
     /**
      * 根据菜单ID查询信息
      *

+ 46 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleUserMenuMapper.java

@@ -0,0 +1,46 @@
+package com.ruoyi.system.mapper;
+
+import com.ruoyi.system.domain.SysRoleUserMenu;
+
+import java.util.List;
+
+/**
+ * 角色与菜单关联表 数据层
+ * 
+ * @author ruoyi
+ */
+public interface SysRoleUserMenuMapper
+{
+    /**
+     * 查询菜单使用数量
+     * 
+     * @param menuId 菜单ID
+     * @return 结果
+     */
+    public int checkUserMenuExistRole(Long menuId);
+
+    /**
+     * 通过用户ID删除角色和菜单关联
+     * 
+     * @param userId 用户ID
+     * @return 结果
+     */
+    public int deleteRoleUserMenuByUserId(Long userId);
+
+    /**
+     * 批量删除用户菜单关联信息
+     * 
+     * @param ids 需要删除的数据ID
+     * @return 结果
+     */
+
+    public int deleteRoleUserMenu(Long[] ids);
+
+    /**
+     * 批量新增用户菜单信息
+     * 
+     * @param roleUserMenuList 用户菜单列表
+     * @return 结果
+     */
+    public int batchRoleUserMenu(List<SysRoleUserMenu> roleUserMenuList);
+}

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java

@@ -142,4 +142,6 @@ public interface ISysMenuService
      * @return 结果
      */
     public boolean checkMenuNameUnique(SysMenu menu);
+
+    public List<Long> selectUserMenuListByUserId(Long userId);
 }

+ 11 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java

@@ -8,6 +8,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+
+import com.ruoyi.system.mapper.SysRoleUserMenuMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.common.constant.Constants;
@@ -44,6 +46,10 @@ public class SysMenuServiceImpl implements ISysMenuService
     @Autowired
     private SysRoleMenuMapper roleMenuMapper;
 
+
+    @Autowired
+    private SysRoleUserMenuMapper roleUserMenuMapper;
+
     /**
      * 根据用户查询系统菜单列表
      * 
@@ -346,6 +352,11 @@ public class SysMenuServiceImpl implements ISysMenuService
         return UserConstants.UNIQUE;
     }
 
+    @Override
+    public List<Long> selectUserMenuListByUserId(Long userId) {
+        return menuMapper.selectUserMenuListByUserId(userId, false);
+    }
+
     /**
      * 获取路由名称
      * 

+ 51 - 15
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -1,15 +1,5 @@
 package com.ruoyi.system.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.validation.Validator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysRole;
@@ -20,15 +10,23 @@ import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.bean.BeanValidators;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.system.domain.SysPost;
+import com.ruoyi.system.domain.SysRoleUserMenu;
 import com.ruoyi.system.domain.SysUserPost;
 import com.ruoyi.system.domain.SysUserRole;
-import com.ruoyi.system.mapper.SysPostMapper;
-import com.ruoyi.system.mapper.SysRoleMapper;
-import com.ruoyi.system.mapper.SysUserMapper;
-import com.ruoyi.system.mapper.SysUserPostMapper;
-import com.ruoyi.system.mapper.SysUserRoleMapper;
+import com.ruoyi.system.mapper.*;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.validation.Validator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 用户 业务层处理
@@ -61,6 +59,11 @@ public class SysUserServiceImpl implements ISysUserService
     @Autowired
     protected Validator validator;
 
+
+
+    @Autowired
+    private SysRoleUserMenuMapper roleUserMenuMapper;
+
     /**
      * 根据条件分页查询用户列表
      * 
@@ -262,6 +265,8 @@ public class SysUserServiceImpl implements ISysUserService
         insertUserPost(user);
         // 新增用户与角色管理
         insertUserRole(user);
+        //新增用户与菜单关联
+        insertRoleUserMenu(user);
         return rows;
     }
 
@@ -296,6 +301,9 @@ public class SysUserServiceImpl implements ISysUserService
         userPostMapper.deleteUserPostByUserId(userId);
         // 新增用户与岗位管理
         insertUserPost(user);
+        // 删除角色与菜单关联
+        roleUserMenuMapper.deleteRoleUserMenuByUserId(user.getUserId());
+        insertRoleUserMenu(user);
         return userMapper.updateUser(user);
     }
 
@@ -445,6 +453,8 @@ public class SysUserServiceImpl implements ISysUserService
         userRoleMapper.deleteUserRoleByUserId(userId);
         // 删除用户与岗位表
         userPostMapper.deleteUserPostByUserId(userId);
+        // 删除用户与菜单
+        roleUserMenuMapper.deleteRoleUserMenuByUserId(userId);
         return userMapper.deleteUserById(userId);
     }
 
@@ -541,4 +551,30 @@ public class SysUserServiceImpl implements ISysUserService
         }
         return successMsg.toString();
     }
+
+
+
+    /**
+     * 新增角色菜单信息
+     *
+     * @param role 角色对象
+     */
+    public int insertRoleUserMenu(SysUser user)
+    {
+        int rows = 1;
+        // 新增用户与角色管理
+        List<SysRoleUserMenu> list = new ArrayList<SysRoleUserMenu>();
+        for (Long menuId : user.getMenuIds())
+        {
+            SysRoleUserMenu rm = new SysRoleUserMenu();
+            rm.setUserId(user.getUserId());
+            rm.setMenuId(menuId);
+            list.add(rm);
+        }
+        if (list.size() > 0)
+        {
+            rows = roleUserMenuMapper.batchRoleUserMenu(list);
+        }
+        return rows;
+    }
 }

+ 12 - 0
ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml

@@ -98,6 +98,18 @@
             </if>
 		order by m.parent_id, m.order_num
 	</select>
+
+
+	<select id="selectUserMenuListByUserId" resultType="Long">
+		select m.menu_id
+		from sys_menu m
+		left join sys_role_user_menu rm on m.menu_id = rm.menu_id
+		where rm.user_id = #{userId}
+<!--		<if test="menuCheckStrictly">-->
+<!--			and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_user_menu rm on m.menu_id = rm.menu_id and rm.user_id = #{userId})-->
+<!--		</if>-->
+		order by m.parent_id, m.order_num
+	</select>
 	
 	<select id="selectMenuPerms" resultType="String">
 		select distinct m.perms

+ 34 - 0
ruoyi-system/src/main/resources/mapper/system/SysRoleUserMenuMapper.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.SysRoleUserMenuMapper">
+
+	<resultMap type="SysRoleUserMenu" id="SysRoleUserMenuResult">
+		<result property="userId"     column="user_id"      />
+		<result property="menuId"     column="menu_id"      />
+	</resultMap>
+	
+	<select id="checkUserMenuExistRole" resultType="Integer">
+	    select count(1) from sys_role_user_menu where menu_id = #{menuId}
+	</select>
+
+	<delete id="deleteRoleUserMenuByUserId" parameterType="Long">
+		delete from sys_role_user_menu where user_id=#{userId}
+	</delete>
+	
+	<delete id="deleteRoleUserMenu" parameterType="Long">
+ 		delete from sys_role_user_menu where userId in
+ 		<foreach collection="array" item="roleId" open="(" separator="," close=")">
+ 			#{userId}
+        </foreach> 
+ 	</delete>
+	
+	<insert id="batchRoleUserMenu">
+		insert into sys_role_user_menu(user_id, menu_id) values
+		<foreach item="item" index="index" collection="list" separator=",">
+			(#{item.userId},#{item.menuId})
+		</foreach>
+	</insert>
+	
+</mapper> 

+ 11 - 0
ruoyi-ui/src/api/system/menu.js

@@ -33,6 +33,17 @@ export function roleMenuTreeselect(roleId) {
   })
 }
 
+
+// 根据用户ID查询菜单下拉树结构
+export function roleUserMenuTreeselect(userId) {
+  return request({
+    url: '/system/menu/roleUserMenuTreeselect/' + userId,
+    method: 'get'
+  })
+}
+
+
+
 // 新增菜单
 export function addMenu(data) {
   return request({

+ 96 - 1
ruoyi-ui/src/views/system/user/index.vue

@@ -294,6 +294,21 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-form-item label="菜单权限">
+          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
+          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
+          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
+          <el-tree
+            class="tree-border"
+            :data="menuOptions"
+            show-checkbox
+            ref="menu"
+            node-key="id"
+            :check-strictly="!form.menuCheckStrictly"
+            empty-text="加载中,请稍候"
+            :props="defaultProps"
+          ></el-tree>
+        </el-form-item>
         <el-row>
           <el-col :span="24">
             <el-form-item label="备注">
@@ -342,6 +357,7 @@
 
 <script>
 import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user";
+import { treeselect as menuTreeselect, roleMenuTreeselect,roleUserMenuTreeselect } from "@/api/system/menu";
 import { getToken } from "@/utils/auth";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
@@ -376,6 +392,11 @@ export default {
       deptName: undefined,
       // 默认密码
       initPassword: undefined,
+      // 菜单列表
+      menuOptions: [],
+      // 是否显示弹出层(数据权限)
+      menuExpand: false,
+      menuNodeAll: false,
       // 日期范围
       dateRange: [],
       // 岗位选项
@@ -510,6 +531,11 @@ export default {
     },
     // 表单重置
     reset() {
+      if (this.$refs.menu != undefined) {
+        this.$refs.menu.setCheckedKeys([]);
+      }
+      this.menuExpand = false,
+      this.menuNodeAll = false,
       this.form = {
         userId: undefined,
         deptId: undefined,
@@ -522,7 +548,10 @@ export default {
         status: "0",
         remark: undefined,
         postIds: [],
-        roleIds: []
+        roleIds: [],
+        menuIds: [],
+        menuCheckStrictly: true,
+        deptCheckStrictly: true,
       };
       this.resetForm("form");
     },
@@ -561,6 +590,7 @@ export default {
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
+      this.getMenuTreeselect();
       getUser().then(response => {
         this.postOptions = response.posts;
         this.roleOptions = response.roles;
@@ -569,10 +599,33 @@ export default {
         this.form.password = this.initPassword;
       });
     },
+    /** 查询菜单树结构 */
+    getMenuTreeselect() {
+      menuTreeselect().then(response => {
+        this.menuOptions = response.data;
+      });
+    },
+    // 所有菜单节点数据
+    getMenuAllCheckedKeys() {
+      // 目前被选中的菜单节点
+      let checkedKeys = this.$refs.menu.getCheckedKeys();
+      // 半选中的菜单节点
+      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      return checkedKeys;
+    },
+    /** 根据用户ID查询菜单树结构 */
+    getRoleUserMenuTreeselect(userId) {
+      return roleUserMenuTreeselect(userId).then(response => {
+        this.menuOptions = response.menus;
+        return response;
+      });
+    },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
       const userId = row.userId || this.ids;
+      const userMenu = this.getRoleUserMenuTreeselect(userId);
       getUser(userId).then(response => {
         this.form = response.data;
         this.postOptions = response.posts;
@@ -580,6 +633,16 @@ export default {
         this.$set(this.form, "postIds", response.postIds);
         this.$set(this.form, "roleIds", response.roleIds);
         this.open = true;
+        this.$nextTick(() => {
+          userMenu.then(res => {
+            let checkedKeys = res.checkedKeys
+            checkedKeys.forEach((v) => {
+                this.$nextTick(()=>{
+                    this.$refs.menu.setChecked(v, true ,false);
+                })
+            })
+          });
+        });
         this.title = "修改用户";
         this.form.password = "";
       });
@@ -608,12 +671,14 @@ export default {
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.form.userId != undefined) {
+            this.form.menuIds = this.getMenuAllCheckedKeys();
             updateUser(this.form).then(response => {
               this.$modal.msgSuccess("修改成功");
               this.open = false;
               this.getList();
             });
           } else {
+            this.form.menuIds = this.getMenuAllCheckedKeys();
             addUser(this.form).then(response => {
               this.$modal.msgSuccess("新增成功");
               this.open = false;
@@ -623,6 +688,36 @@ export default {
         }
       });
     },
+    // 树权限(展开/折叠)
+    handleCheckedTreeExpand(value, type) {
+      if (type == 'menu') {
+        let treeList = this.menuOptions;
+        for (let i = 0; i < treeList.length; i++) {
+          this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
+        }
+      } else if (type == 'dept') {
+        let treeList = this.deptOptions;
+        for (let i = 0; i < treeList.length; i++) {
+          this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
+        }
+      }
+    },
+    // 树权限(全选/全不选)
+    handleCheckedTreeNodeAll(value, type) {
+      if (type == 'menu') {
+        this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
+      } else if (type == 'dept') {
+        this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
+      }
+    },
+    // 树权限(父子联动)
+    handleCheckedTreeConnect(value, type) {
+      if (type == 'menu') {
+        this.form.menuCheckStrictly = value ? true: false;
+      } else if (type == 'dept') {
+        this.form.deptCheckStrictly = value ? true: false;
+      }
+    },
     /** 删除按钮操作 */
     handleDelete(row) {
       const userIds = row.userId || this.ids;