feat(system): 新增角色与菜单的Vue接口及树形结构支持

- 为角色管理模块添加完整的Vue前端接口支持
- 实现菜单树形选择结构的构建与查询功能
- 添加根据角色ID查询已分配菜单列表的功能- 更新菜单与角色相关API路径以适配Vue前端
- 完善角色数据权限与状态变更的Vue接口- 支持角色授权用户的批量操作与查询功能
dev_1.0.0
chenhao 2025-11-18 18:24:42 +08:00
parent 3466208112
commit d92dd377cc
9 changed files with 243 additions and 28 deletions

View File

@ -20,7 +20,7 @@ export function getMenu(menuId) {
// 查询菜单下拉树结构
export function treeselect() {
return request({
url: '/system/menu/treeselect',
url: '/system/menu/vue/treeselect',
method: 'get'
})
}
@ -57,4 +57,4 @@ export function delMenu(menuId) {
url: '/system/menu/' + menuId,
method: 'delete'
})
}
}

View File

@ -3,8 +3,8 @@ import request from '@/utils/request'
// 查询角色列表
export function listRole(query) {
return request({
url: '/system/role/list',
method: 'post',
url: '/system/role/vue/list',
method: 'get',
params: query
})
}
@ -12,7 +12,7 @@ export function listRole(query) {
// 查询角色详细
export function getRole(roleId) {
return request({
url: '/system/role/' + roleId,
url: '/system/role/vue/' + roleId,
method: 'get'
})
}
@ -20,7 +20,7 @@ export function getRole(roleId) {
// 新增角色
export function addRole(data) {
return request({
url: '/system/role',
url: '/system/role/vue',
method: 'post',
data: data
})
@ -29,7 +29,7 @@ export function addRole(data) {
// 修改角色
export function updateRole(data) {
return request({
url: '/system/role',
url: '/system/role/vue',
method: 'put',
data: data
})
@ -38,7 +38,7 @@ export function updateRole(data) {
// 角色数据权限
export function dataScope(data) {
return request({
url: '/system/role/dataScope',
url: '/system/role/vue/dataScope',
method: 'put',
data: data
})
@ -51,7 +51,7 @@ export function changeRoleStatus(roleId, status) {
status
}
return request({
url: '/system/role/changeStatus',
url: '/system/role/vue/changeStatus',
method: 'put',
data: data
})
@ -60,7 +60,7 @@ export function changeRoleStatus(roleId, status) {
// 删除角色
export function delRole(roleId) {
return request({
url: '/system/role/' + roleId,
url: '/system/role/vue/' + roleId,
method: 'delete'
})
}
@ -68,7 +68,7 @@ export function delRole(roleId) {
// 查询角色已授权用户列表
export function allocatedUserList(query) {
return request({
url: '/system/role/authUser/allocatedList',
url: '/system/role/vue/authUser/allocatedList',
method: 'get',
params: query
})
@ -77,7 +77,7 @@ export function allocatedUserList(query) {
// 查询角色未授权用户列表
export function unallocatedUserList(query) {
return request({
url: '/system/role/authUser/unallocatedList',
url: '/system/role/vue/authUser/unallocatedList',
method: 'get',
params: query
})
@ -86,7 +86,7 @@ export function unallocatedUserList(query) {
// 取消用户授权角色
export function authUserCancel(data) {
return request({
url: '/system/role/authUser/cancel',
url: '/system/role/vue/authUser/cancel',
method: 'put',
data: data
})
@ -95,7 +95,7 @@ export function authUserCancel(data) {
// 批量取消用户授权角色
export function authUserCancelAll(data) {
return request({
url: '/system/role/authUser/cancelAll',
url: '/system/role/vue/authUser/cancelAll',
method: 'put',
params: data
})
@ -104,7 +104,7 @@ export function authUserCancelAll(data) {
// 授权用户选择
export function authUserSelectAll(data) {
return request({
url: '/system/role/authUser/selectAll',
url: '/system/role/vue/authUser/selectAll',
method: 'put',
params: data
})
@ -113,7 +113,7 @@ export function authUserSelectAll(data) {
// 根据角色ID查询部门树结构
export function deptTreeSelect(roleId) {
return request({
url: '/system/role/deptTree/' + roleId,
url: '/system/role/vue/deptTree/' + roleId,
method: 'get'
})
}

View File

@ -602,4 +602,4 @@ export default {
}
}
}
</script>
</script>

View File

@ -245,7 +245,29 @@ public class SysMenuController extends BaseController
List<Ztree> ztrees = menuService.menuTreeData(userId);
return ztrees;
}
/**
*
*/
@GetMapping("/vue/treeselect")
@ResponseBody
public AjaxResult treeselect(SysMenu menu)
{
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menuService.buildMenuTreeSelect(menus));
}
/**
*
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
@ResponseBody
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
{
List<SysMenu> menus = menuService.selectMenuList(new SysMenu(),getUserId());
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
return ajax;
}
/**
*
*/

View File

@ -1,14 +1,19 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysDept;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
@ -25,6 +30,8 @@ import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.impl.SysDeptServiceImpl;
import com.ruoyi.system.service.impl.SysRoleServiceImpl;
/**
*
@ -321,4 +328,143 @@ public class SysRoleController extends BaseController
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
// ================================= vue =================================
@RequiresPermissions("system:role:list")
@GetMapping("/vue/list")
@ResponseBody
public TableDataInfo listVue(SysRole role)
{
startPage();
List<SysRole> list = roleService.selectRoleList(role);
return getDataTable(list);
}
@RequiresPermissions("system:role:query")
@GetMapping(value = "/vue/{roleId}")
@ResponseBody
public AjaxResult getInfoVue(@PathVariable("roleId") Long roleId)
{
roleService.checkRoleDataScope(roleId);
return AjaxResult.success(roleService.selectRoleById(roleId));
}
@RequiresPermissions("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping("/vue")
@ResponseBody
public AjaxResult addVue(@Validated @RequestBody SysRole role)
{
if (!roleService.checkRoleNameUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getLoginName());
return toAjax(roleService.insertRole(role));
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/vue")
@ResponseBody
public AjaxResult editVue(@Validated @RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(getLoginName());
return toAjax(roleService.updateRole(role));
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/vue/dataScope")
@ResponseBody
public AjaxResult dataScopeVue(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.authDataScope(role));
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/vue/changeStatus")
@ResponseBody
public AjaxResult changeStatusVue(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.changeStatus(role));
}
@RequiresPermissions("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/vue/{roleIds}")
@ResponseBody
public AjaxResult removeVue(@PathVariable(value = "roleIds") String roleIds)
{
return toAjax(roleService.deleteRoleByIds(roleIds));
}
@RequiresPermissions("system:role:list")
@GetMapping("/vue/authUser/allocatedList")
@ResponseBody
public TableDataInfo allocatedListVue(SysUser user)
{
startPage();
List<SysUser> list = userService.selectAllocatedList(user);
return getDataTable(list);
}
@RequiresPermissions("system:role:list")
@GetMapping("/vue/authUser/unallocatedList")
@ResponseBody
public TableDataInfo unallocatedListVue(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUnallocatedList(user);
return getDataTable(list);
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/vue/authUser/cancel")
@ResponseBody
public AjaxResult cancelAuthUserVue(@RequestBody SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/vue/authUser/cancelAll")
@ResponseBody
public AjaxResult cancelAuthUserAllVue(Long roleId, String userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/vue/authUser/selectAll")
@ResponseBody
public AjaxResult selectAuthUserAllVue(Long roleId, String userIds)
{
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
}

View File

@ -129,4 +129,6 @@ public interface SysMenuMapper
* @return
*/
public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
List<Long> selectMenuListByRoleId(Long roleId);
}

View File

@ -3,6 +3,8 @@ package com.ruoyi.system.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
@ -136,4 +138,8 @@ public interface ISysMenuService
* @return
*/
public boolean checkMenuNameUnique(SysMenu menu);
List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus);
List<Long> selectMenuListByRoleId(Long roleId);
}

View File

@ -1,14 +1,11 @@
package com.ruoyi.system.service.impl;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.system.mapper.SysRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
@ -33,7 +30,8 @@ public class SysMenuServiceImpl implements ISysMenuService
@Autowired
private SysMenuMapper menuMapper;
@Autowired
private SysRoleMapper roleMapper;
@Autowired
private SysRoleMenuMapper roleMenuMapper;
@ -342,6 +340,40 @@ public class SysMenuServiceImpl implements ISysMenuService
return UserConstants.UNIQUE;
}
@Override
public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) {
List<SysMenu> menuTrees = buildMenuTree(menus);
return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
}
@Override
public List<Long> selectMenuListByRoleId(Long roleId) {
SysRole role = roleMapper.selectRoleById(roleId);
return menuMapper.selectMenuListByRoleId(roleId);
}
public List<SysMenu> buildMenuTree(List<SysMenu> menus)
{
List<SysMenu> returnList = new ArrayList<SysMenu>();
List<Long> tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();)
{
SysMenu menu = (SysMenu) iterator.next();
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(menu.getParentId()))
{
recursionFn(menus, menu);
returnList.add(menu);
}
}
if (returnList.isEmpty())
{
returnList = menus;
}
return returnList;
}
/**
* ID
*

View File

@ -133,8 +133,15 @@
<include refid="selectMenuVo"/>
where menu_name=#{menuName} and parent_id = #{parentId} limit 1
</select>
<select id="selectMenuListByRoleId" resultType="java.lang.Long">
select m.menu_id
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where rm.role_id = #{roleId}
order by m.parent_id, m.order_num
</select>
<update id="updateMenu" parameterType="SysMenu">
<update id="updateMenu" parameterType="SysMenu">
update sys_menu
<set>
<if test="menuName != null and menuName != ''">menu_name = #{menuName},</if>