mybatis-plus menu

master
冯凯 2023-11-20 21:53:06 +08:00
parent 9ca60722ec
commit 2ef57a708b
6 changed files with 830 additions and 0 deletions

View File

@ -1,5 +1,8 @@
package com.dragon.system.common.domain; package com.dragon.system.common.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dragon.common.core.web.domain.BaseEntity; import com.dragon.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -15,12 +18,14 @@ import java.util.List;
* *
* @author dragon * @author dragon
*/ */
@TableName(value = "sys_menu")
public class SysMenu extends BaseEntity { public class SysMenu extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* ID * ID
*/ */
@TableId(type = IdType.AUTO)
private Long menuId; private Long menuId;
/** /**

View File

@ -0,0 +1,141 @@
package com.dragon.system.server.controller;
import com.dragon.common.core.constant.UserConstants;
import com.dragon.common.core.domain.Result;
import com.dragon.common.core.utils.StringUtils;
import com.dragon.common.core.web.controller.BaseController;
import com.dragon.common.log.annotation.Log;
import com.dragon.common.log.enums.BusinessType;
import com.dragon.common.security.annotation.RequiresPermissions;
import com.dragon.common.security.utils.SecurityUtils;
import com.dragon.system.common.domain.SysMenu;
import com.dragon.system.common.domain.res.RoleMenuTreeRes;
import com.dragon.system.server.service.ISysMenuPlusService;
import com.dragon.system.server.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
;
/**
*
*
* @author dragon
*/
@RestController
@RequestMapping("/menu/plus")
public class SysMenuPlusController extends BaseController {
@Autowired
private ISysMenuPlusService menuService;
/**
*
*/
@RequiresPermissions("system:menu:list")
@GetMapping("/list")
public Result list(SysMenu menu) {
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuList(menu, userId);
return success(menus);
}
/**
*
*/
@RequiresPermissions("system:menu:query")
@GetMapping(value = "/{menuId}")
public Result getInfo(@PathVariable Long menuId) {
return success(menuService.getById(menuId));
}
/**
*
*/
@GetMapping("/treeselect")
public Result treeselect(SysMenu menu) {
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuList(menu, userId);
return success(menuService.buildMenuTreeSelect(menus));
}
/**
*
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public Result roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuList(userId);
return Result.success(RoleMenuTreeRes.builder()
.checkedKeys(menuService.selectMenuListByRoleId(roleId))
.menus(menuService.buildMenuTreeSelect(menus))
.build()
);
}
/**
*
*/
@RequiresPermissions("system:menu:add")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping
public Result add(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return error("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
menu.setCreateBy(SecurityUtils.getUsername());
return toAjax(menuService.save(menu));
}
/**
*
*/
@RequiresPermissions("system:menu:edit")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return error("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
} else if (menu.getMenuId().equals(menu.getParentId())) {
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
menu.setUpdateBy(SecurityUtils.getUsername());
return toAjax(menuService.updateById(menu));
}
/**
*
*/
@RequiresPermissions("system:menu:remove")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public Result remove(@PathVariable("menuId") Long menuId) {
if (menuService.hasChildByMenuId(menuId)) {
return warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId)) {
return warn("菜单已分配,不允许删除");
}
return toAjax(menuService.removeById(menuId));
}
/**
*
*
* @return
*/
@GetMapping("getRouters")
public Result getRouters() {
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return success(menuService.buildMenus(menus));
}
}

View File

@ -0,0 +1,24 @@
package com.dragon.system.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dragon.system.common.domain.SysMenu;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author
* @version 1.0
* @description:
* @date 2023/11/20 20:36
*/
@Mapper
public interface SysMenuPlusMapper extends BaseMapper<SysMenu> {
List<String> selectMenuPermsByRoleId(Long roleId);
List<String> selectMenuPermsByUserId(Long userId);
List<SysMenu> selectMenuTreeByUserId(Long userId);
List<Long> selectMenuListByRoleId(Long roleId, boolean menuCheckStrictly);
}

View File

@ -0,0 +1,117 @@
package com.dragon.system.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dragon.system.common.domain.SysMenu;
import com.dragon.system.common.domain.vo.RouterVo;
import com.dragon.system.common.domain.vo.TreeSelect;
import java.util.List;
import java.util.Set;
/**
*
*
* @author dragon
*/
public interface ISysMenuPlusService extends IService<SysMenu> {
/**
*
*
* @param userId ID
* @return
*/
public List<SysMenu> selectMenuList(Long userId);
/**
*
*
* @param menu
* @param userId ID
* @return
*/
public List<SysMenu> selectMenuList(SysMenu menu, Long userId);
/**
* ID
*
* @param userId ID
* @return
*/
public Set<String> selectMenuPermsByUserId(Long userId);
/**
* ID
*
* @param roleId ID
* @return
*/
public Set<String> selectMenuPermsByRoleId(Long roleId);
/**
* ID
*
* @param userId ID
* @return
*/
public List<SysMenu> selectMenuTreeByUserId(Long userId);
/**
* ID
*
* @param roleId ID
* @return
*/
public List<Long> selectMenuListByRoleId(Long roleId);
/**
*
*
* @param menus
* @return
*/
public List<RouterVo> buildMenus(List<SysMenu> menus);
/**
*
*
* @param menus
* @return
*/
public List<SysMenu> buildMenuTree(List<SysMenu> menus);
/**
*
*
* @param menus
* @return
*/
public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus);
/**
*
*
* @param menuId ID
* @return true false
*/
public boolean hasChildByMenuId(Long menuId);
/**
*
*
* @param menuId ID
* @return true false
*/
public boolean checkMenuExistRole(Long menuId);
/**
*
*
* @param menu
* @return
*/
public boolean checkMenuNameUnique(SysMenu menu);
}

View File

@ -0,0 +1,481 @@
package com.dragon.system.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.core.constant.Constants;
import com.dragon.common.core.constant.UserConstants;
import com.dragon.common.core.utils.StringUtils;
import com.dragon.common.security.utils.SecurityUtils;
import com.dragon.system.common.domain.SysMenu;
import com.dragon.system.common.domain.SysRole;
import com.dragon.system.common.domain.SysUser;
import com.dragon.system.common.domain.vo.MetaVo;
import com.dragon.system.common.domain.vo.RouterVo;
import com.dragon.system.common.domain.vo.TreeSelect;
import com.dragon.system.server.mapper.SysMenuMapper;
import com.dragon.system.server.mapper.SysMenuPlusMapper;
import com.dragon.system.server.mapper.SysRoleMapper;
import com.dragon.system.server.mapper.SysRoleMenuMapper;
import com.dragon.system.server.service.ISysMenuPlusService;
import com.dragon.system.server.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*
* @author dragon
*/
@Service
public class SysMenuServicePlusImpl extends ServiceImpl<SysMenuPlusMapper,SysMenu> implements ISysMenuPlusService {
public static final String PREMISSION_STRING = "perms[\"{0}\"]";
@Autowired
private SysMenuPlusMapper menuMapper;
@Autowired
private SysRoleMapper roleMapper;
@Autowired
private SysRoleMenuMapper roleMenuMapper;
/**
*
*
* @param userId ID
* @return
*/
@Override
public List<SysMenu> selectMenuList(Long userId) {
return selectMenuList(new SysMenu(), userId);
}
/**
*
*
* @param menu
* @return
*/
@Override
public List<SysMenu> selectMenuList(SysMenu menu, Long userId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotEmpty(menu.getMenuName())){
queryWrapper.like(SysMenu::getMenuName,menu.getMenuName());
}if (StringUtils.isNotEmpty(menu.getVisible())){
queryWrapper.like(SysMenu::getVisible,menu.getVisible());
}if (StringUtils.isNotEmpty(menu.getStatus())){
queryWrapper.like(SysMenu::getStatus,menu.getStatus());
}
queryWrapper.orderByAsc(SysMenu::getParentId,SysMenu::getOrderNum);
List<SysMenu> menuList = null;
// 管理员显示所有菜单信息
if (SysUser.isAdmin(userId)) {
menuList = menuMapper.selectList(queryWrapper);
} else {
menu.getParams().put("userId", userId);
menuList = menuMapper.selectList(queryWrapper);
}
return menuList;
}
/**
* ID
*
* @param userId ID
* @return
*/
@Override
public Set<String> selectMenuPermsByUserId(Long userId) {
List<String> perms = menuMapper.selectMenuPermsByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/**
* ID
*
* @param roleId ID
* @return
*/
@Override
public Set<String> selectMenuPermsByRoleId(Long roleId) {
List<String> perms = menuMapper.selectMenuPermsByRoleId(roleId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/**
* ID
*
* @param userId
* @return
*/
@Override
public List<SysMenu> selectMenuTreeByUserId(Long userId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
ArrayList<String> strings = new ArrayList<>();
Collections.addAll(strings,"M","C");
queryWrapper.in(SysMenu::getMenuType,strings);
queryWrapper.eq(SysMenu::getStatus,0);
queryWrapper.orderByAsc(SysMenu::getParentId,SysMenu::getOrderNum);
List<SysMenu> menus = null;
if (SecurityUtils.isAdmin(userId)) {
menus = menuMapper.selectList(queryWrapper);
} else {
menus = menuMapper.selectMenuTreeByUserId(userId);
}
return getChildPerms(menus, 0);
}
/**
* ID
*
* @param roleId ID
* @return
*/
@Override
public List<Long> selectMenuListByRoleId(Long roleId) {
SysRole role = roleMapper.selectRoleById(roleId);
return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly());
}
/**
*
*
* @param menus
* @return
*/
@Override
public List<RouterVo> buildMenus(List<SysMenu> menus) {
List<RouterVo> routers = new LinkedList<RouterVo>();
for (SysMenu menu : menus) {
RouterVo router = new RouterVo();
router.setHidden("1".equals(menu.getVisible()));
router.setName(getRouteName(menu));
router.setPath(getRouterPath(menu));
router.setComponent(getComponent(menu));
router.setQuery(menu.getQuery());
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
List<SysMenu> cMenus = menu.getChildren();
if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
router.setAlwaysShow(true);
router.setRedirect("noRedirect");
router.setChildren(buildMenus(cMenus));
} else if (isMenuFrame(menu)) {
router.setMeta(null);
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
children.setPath(menu.getPath());
children.setComponent(menu.getComponent());
children.setName(StringUtils.capitalize(menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQuery());
childrenList.add(children);
router.setChildren(childrenList);
} else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/");
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
String routerPath = innerLinkReplaceEach(menu.getPath());
children.setPath(routerPath);
children.setComponent(UserConstants.INNER_LINK);
children.setName(StringUtils.capitalize(routerPath));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
childrenList.add(children);
router.setChildren(childrenList);
}
routers.add(router);
}
return routers;
}
/**
*
*
* @param menus
* @return
*/
@Override
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;
}
/**
*
*
* @param menus
* @return
*/
@Override
public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) {
List<SysMenu> menuTrees = buildMenuTree(menus);
return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
}
/**
*
*
* @param menuId ID
* @return
*/
@Override
public boolean hasChildByMenuId(Long menuId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
if (menuId!=null && !menuId.equals("")){
queryWrapper.eq(SysMenu::getParentId,menuId);
}
Long result = menuMapper.selectCount(queryWrapper);
return result > 0;
}
/**
* 使
*
* @param menuId ID
* @return
*/
@Override
public boolean checkMenuExistRole(Long menuId) {
int result = roleMenuMapper.checkMenuExistRole(menuId);
return result > 0;
}
/**
*
*
* @param menu
* @return
*/
// @Override
// public int insertMenu(SysMenu menu) {
// return menuMapper.insertMenu(menu);
// }
/**
*
*
* @param menu
* @return
*/
/**
*
*
* @param menuId ID
* @return
*/
// @Override
// public int deleteMenuById(Long menuId) {
// return menuMapper.deleteMenuById(menuId);
// }
/**
*
*
* @param menu
* @return
*/
@Override
public boolean checkMenuNameUnique(SysMenu menu) {
Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotEmpty(menu.getMenuName())){
queryWrapper.eq(SysMenu::getMenuName,menu.getMenuName());
}if (menu.getParentId()!=null && !menu.getParentId().equals("")){
queryWrapper.eq(SysMenu::getParentId,menu.getParentId());
}
SysMenu info = menuMapper.selectOne(queryWrapper);
if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
*
*
* @param menu
* @return
*/
public String getRouteName(SysMenu menu) {
String routerName = StringUtils.capitalize(menu.getPath());
// 非外链并且是一级目录(类型为目录)
if (isMenuFrame(menu)) {
routerName = StringUtils.EMPTY;
}
return routerName;
}
/**
*
*
* @param menu
* @return
*/
public String getRouterPath(SysMenu menu) {
String routerPath = menu.getPath();
// 内链打开外网方式
if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
routerPath = innerLinkReplaceEach(routerPath);
}
// 非外链并且是一级目录(类型为目录)
if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
&& UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
routerPath = "/" + menu.getPath();
}
// 非外链并且是一级目录(类型为菜单)
else if (isMenuFrame(menu)) {
routerPath = "/";
}
return routerPath;
}
/**
*
*
* @param menu
* @return
*/
public String getComponent(SysMenu menu) {
String component = UserConstants.LAYOUT;
if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
component = menu.getComponent();
} else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
component = UserConstants.INNER_LINK;
} else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
component = UserConstants.PARENT_VIEW;
}
return component;
}
/**
*
*
* @param menu
* @return
*/
public boolean isMenuFrame(SysMenu menu) {
return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
}
/**
*
*
* @param menu
* @return
*/
public boolean isInnerLink(SysMenu menu) {
return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
}
/**
* parent_view
*
* @param menu
* @return
*/
public boolean isParentView(SysMenu menu) {
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
}
/**
* ID
*
* @param list
* @param parentId ID
* @return String
*/
public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
List<SysMenu> returnList = new ArrayList<SysMenu>();
for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext(); ) {
SysMenu t = (SysMenu) iterator.next();
// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
if (t.getParentId() == parentId) {
recursionFn(list, t);
returnList.add(t);
}
}
return returnList;
}
/**
*
*
* @param list
* @param t
*/
private void recursionFn(List<SysMenu> list, SysMenu t) {
// 得到子节点列表
List<SysMenu> childList = getChildList(list, t);
t.setChildren(childList);
for (SysMenu tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
*
*/
private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
List<SysMenu> tlist = new ArrayList<SysMenu>();
Iterator<SysMenu> it = list.iterator();
while (it.hasNext()) {
SysMenu n = (SysMenu) it.next();
if (n.getParentId().longValue() == t.getMenuId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
/**
*
*/
private boolean hasChild(List<SysMenu> list, SysMenu t) {
return getChildList(list, t).size() > 0;
}
/**
*
*
* @return
*/
public String innerLinkReplaceEach(String path) {
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":"},
new String[]{"", "", "", "/", "/"});
}
}

View File

@ -0,0 +1,62 @@
<?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.dragon.system.server.mapper.SysMenuPlusMapper">
<select id="selectMenuPermsByRoleId" resultType="java.lang.String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where m.status = '0'
and rm.role_id = #{roleId}
</select>
<select id="selectMenuPermsByUserId" resultType="java.lang.String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role ur on rm.role_id = ur.role_id
left join sys_role r on r.role_id = ur.role_id
where m.status = '0'
and r.status = '0'
and ur.user_id = #{userId}
</select>
<select id="selectMenuTreeByUserId" resultType="com.dragon.system.common.domain.SysMenu">
select distinct m.menu_id,
m.parent_id,
m.menu_name,
m.path,
m.component,
m.`query`,
m.visible,
m.status,
ifnull(m.perms, '') as perms,
m.is_frame,
m.is_cache,
m.menu_type,
m.icon,
m.order_num,
m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role ur on rm.role_id = ur.role_id
left join sys_role ro on ur.role_id = ro.role_id
left join sys_user u on ur.user_id = u.user_id
where u.user_id = #{userId}
and m.menu_type in ('M', 'C')
and m.status = 0
AND ro.status = 0
order by m.parent_id, m.order_num
</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}
<if test="menuCheckStrictly">
and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id =
rm.menu_id and rm.role_id = #{roleId})
</if>
order by m.parent_id, m.order_num
</select>
</mapper>