menu
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
package com.agileboot.system.menu.controller;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.common.core.core.R;
|
||||
import com.agileboot.common.satoken.pojo.LoginUser;
|
||||
import com.agileboot.common.satoken.utils.LoginHelper;
|
||||
import com.agileboot.system.menu.pojo.dto.*;
|
||||
import com.agileboot.system.menu.service.ISysMenuService;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
@@ -14,4 +22,65 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequiredArgsConstructor
|
||||
public class SysMenuController {
|
||||
|
||||
private final ISysMenuService sysMenuService;
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
*/
|
||||
@GetMapping
|
||||
public R<List<MenuDTO>> menuList(MenuQuery menuQuery) {
|
||||
List<MenuDTO> menuList = sysMenuService.getMenuList(menuQuery);
|
||||
return R.ok(menuList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据菜单编号获取详细信息
|
||||
*/
|
||||
@GetMapping(value = "/{menuId}")
|
||||
public R<MenuDetailDTO> menuInfo(@PathVariable("menuId") @NotNull Long menuId) {
|
||||
MenuDetailDTO menu = sysMenuService.getMenuInfo(menuId);
|
||||
return R.ok(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单下拉树列表
|
||||
*/
|
||||
@GetMapping("/dropdown")
|
||||
public R<List<Tree<Long>>> dropdownList() {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
List<Tree<Long>> dropdownList = sysMenuService.getDropdownList(loginUser);
|
||||
return R.ok(dropdownList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增菜单
|
||||
* 需支持一级菜单以及 多级菜单 子菜单为一个 或者 多个的情况
|
||||
* 隐藏菜单不显示 以及rank排序
|
||||
* 内链 和 外链
|
||||
*/
|
||||
@PostMapping
|
||||
public R<Void> add(@RequestBody AddMenuCommand addCommand) {
|
||||
sysMenuService.addMenu(addCommand);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改菜单
|
||||
*/
|
||||
@PostMapping("/{menuId}")
|
||||
public R<Void> edit(@PathVariable("menuId") Long menuId, @RequestBody UpdateMenuCommand updateCommand) {
|
||||
updateCommand.setMenuId(menuId);
|
||||
sysMenuService.updateMenu(updateCommand);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
*/
|
||||
@PostMapping("/{menuId}")
|
||||
public R<Void> remove(@PathVariable("menuId") Long menuId) {
|
||||
sysMenuService.remove(menuId);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.agileboot.system.menu.mapper;
|
||||
|
||||
import com.agileboot.system.menu.pojo.entity.SysMenu;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 菜单权限表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2022-06-16
|
||||
*/
|
||||
public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
||||
|
||||
/**
|
||||
* 根据用户查询出所有菜单
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 菜单列表
|
||||
*/
|
||||
@Select("SELECT DISTINCT m.* "
|
||||
+ "FROM sys_menu m "
|
||||
+ " LEFT JOIN sys_role_menu rm ON m.menu_id = rm.menu_id "
|
||||
+ " LEFT JOIN sys_user u ON rm.role_id = u.role_id "
|
||||
+ "WHERE u.user_id = #{userId} "
|
||||
+ " AND m.status = 1 "
|
||||
+ " AND m.deleted = 0 "
|
||||
+ "ORDER BY m.parent_id")
|
||||
List<SysMenu> selectMenuListByUserId(@Param("userId")Long userId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据角色ID查询菜单树信息
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @return 选中菜单列表
|
||||
*/
|
||||
@Select("SELECT DISTINCT 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} "
|
||||
+ " AND m.deleted = 0 "
|
||||
+ "GROUP BY m.menu_id ")
|
||||
List<Long> selectMenuIdsByRoleId(@Param("roleId") Long roleId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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.agileboot.system.menu.pojo.entity.SysMenu">
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class AddMenuCommand {
|
||||
|
||||
private Long parentId;
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
@Size(max = 50, message = "菜单名称长度不能超过50个字符")
|
||||
private String menuName;
|
||||
/**
|
||||
* 路由名称 必须唯一
|
||||
*/
|
||||
private String routerName;
|
||||
|
||||
@Size(max = 200, message = "路由地址不能超过200个字符")
|
||||
private String path;
|
||||
|
||||
private Integer status;
|
||||
private Integer menuType;
|
||||
|
||||
private Boolean isButton;
|
||||
|
||||
@Size(max = 100, message = "权限标识长度不能超过100个字符")
|
||||
private String permission;
|
||||
|
||||
private MetaDTO meta;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class ExtraIconDTO {
|
||||
|
||||
// 是否是svg
|
||||
private boolean svg;
|
||||
// iconfont名称,目前只支持iconfont,后续拓展
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.enums.BasicEnumUtil;
|
||||
import com.agileboot.common.core.enums.common.MenuTypeEnum;
|
||||
import com.agileboot.common.core.enums.common.StatusEnum;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.system.menu.pojo.entity.SysMenu;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class MenuDTO {
|
||||
|
||||
public MenuDTO(SysMenu entity) {
|
||||
if (entity != null) {
|
||||
this.id = entity.getMenuId();
|
||||
this.parentId = entity.getParentId();
|
||||
this.menuName = entity.getMenuName();
|
||||
this.routerName = entity.getRouterName();
|
||||
this.path = entity.getPath();
|
||||
this.status = entity.getStatus();
|
||||
this.isButton = entity.getIsButton();
|
||||
this.statusStr = BasicEnumUtil.getDescriptionByValue(StatusEnum.class, entity.getStatus());
|
||||
|
||||
if (!entity.getIsButton()) {
|
||||
this.menuType = entity.getMenuType();
|
||||
this.menuTypeStr = BasicEnumUtil.getDescriptionByValue(MenuTypeEnum.class, entity.getMenuType());
|
||||
} else {
|
||||
this.menuType = 0;
|
||||
}
|
||||
|
||||
if (StrUtil.isNotEmpty(entity.getMetaInfo()) && JacksonUtil.isJson(entity.getMetaInfo())) {
|
||||
MetaDTO meta = JacksonUtil.from(entity.getMetaInfo(), MetaDTO.class);
|
||||
this.rank = meta.getRank();
|
||||
this.icon = meta.getIcon();
|
||||
}
|
||||
this.createTime = entity.getCreateTime();
|
||||
}
|
||||
}
|
||||
|
||||
// 设置成id和parentId 便于前端处理树级结构
|
||||
private Long id;
|
||||
|
||||
private Long parentId;
|
||||
|
||||
private String menuName;
|
||||
|
||||
private String routerName;
|
||||
|
||||
private String path;
|
||||
|
||||
private Integer rank;
|
||||
|
||||
private Integer menuType;
|
||||
|
||||
private String menuTypeStr;
|
||||
|
||||
private Boolean isButton;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String statusStr;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private String icon;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.system.menu.pojo.entity.SysMenu;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class MenuDetailDTO extends MenuDTO {
|
||||
|
||||
public MenuDetailDTO(SysMenu entity) {
|
||||
super(entity);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
if (StrUtil.isNotEmpty(entity.getMetaInfo()) && JacksonUtil.isJson(entity.getMetaInfo())) {
|
||||
this.meta = JacksonUtil.from(entity.getMetaInfo(), MetaDTO.class);
|
||||
}
|
||||
this.permission = entity.getPermission();
|
||||
}
|
||||
|
||||
private String permission;
|
||||
private MetaDTO meta;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class MenuQuery {
|
||||
// 直接交给前端筛选
|
||||
// private String menuName;
|
||||
// private Boolean isVisible;
|
||||
// private Integer status;
|
||||
private Boolean isButton;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 路由显示信息
|
||||
* 必须加上@JsonInclude(Include.NON_NULL)的注解 否则传null值给Vue动态路由渲染时会出错
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class MetaDTO {
|
||||
// 菜单名称(兼容国际化、非国际化,如果用国际化的写法就必须在根目录的locales文件夹下对应添加)
|
||||
private String title;
|
||||
// 菜单图标
|
||||
private String icon;
|
||||
// 是否显示该菜单
|
||||
private Boolean showLink;
|
||||
// 是否显示父级菜单
|
||||
private Boolean showParent;
|
||||
// 页面级别权限设置
|
||||
private List<String> roles;
|
||||
// 按钮级别权限设置
|
||||
private List<String> auths;
|
||||
// 需要内嵌的iframe链接地址
|
||||
private String frameSrc;
|
||||
/**
|
||||
* 是否是内部页面 使用frameSrc来嵌入页面时,当isFrameSrcInternal=true的时候, 前端需要做特殊处理
|
||||
* 比如链接是 /druid/login.html
|
||||
* 前端需要处理成 http://localhost:8080/druid/login.html
|
||||
*/
|
||||
private Boolean isFrameSrcInternal;
|
||||
|
||||
/**
|
||||
* 菜单排序,值越高排的越后(只针对顶级路由)
|
||||
*/
|
||||
private Integer rank;
|
||||
|
||||
|
||||
// ========= 目前系统仅支持以上这些参数的设置 后续有需要的话开发者可自行设置的这些参数 ===========
|
||||
|
||||
// 菜单名称右侧的额外图标
|
||||
private ExtraIconDTO extraIcon;
|
||||
// 是否缓存该路由页面(开启后,会保存该页面的整体状态,刷新后会清空状态)
|
||||
private Boolean keepAlive;
|
||||
// 内嵌的iframe页面是否开启首次加载动画
|
||||
private Boolean frameLoading;
|
||||
// 页面加载动画(两种模式,第一种直接采用vue内置的transitions动画,第二种是使用animate.css编写进、离场动画,平台更推荐使用第二种模式,已经内置了animate.css,直接写对应的动画名即可)
|
||||
private TransitionDTO transition;
|
||||
// 当前菜单名称或自定义信息禁止添加到标签页
|
||||
private Boolean hiddenTag;
|
||||
// 显示在标签页的最大数量,需满足后面的条件:不显示在菜单中的路由并且是通过query或params传参模式打开的页面。在完整版全局搜dynamicLevel即可查看代码演示
|
||||
private Integer dynamicLevel;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class TransitionDTO {
|
||||
|
||||
// 当前页面动画,这里是第一种模式,比如 name: "fade" 更具体看后面链接
|
||||
// https://cn.vuejs.org/api/built-in-components.html#transition
|
||||
private String name;
|
||||
// 当前页面进场动画,这里是第二种模式,比如 enterTransition: "animate__fadeInLeft"
|
||||
private String enterTransition;
|
||||
// 当前页面离场动画,这里是第二种模式,比如 leaveTransition: "animate__fadeOutRight"
|
||||
private String leaveTransition;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.agileboot.system.menu.pojo.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UpdateMenuCommand extends AddMenuCommand {
|
||||
|
||||
@NotNull
|
||||
private Long menuId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.agileboot.system.menu.pojo.entity;
|
||||
|
||||
import com.agileboot.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 菜单权限表
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2023-07-21
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("sys_menu")
|
||||
@ApiModel(value = "SysMenuEntity对象", description = "菜单权限表")
|
||||
public class SysMenu extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@ApiModelProperty("菜单ID")
|
||||
@TableId(value = "menu_id", type = IdType.AUTO)
|
||||
private Long menuId;
|
||||
|
||||
@ApiModelProperty("菜单名称")
|
||||
@TableField("menu_name")
|
||||
private String menuName;
|
||||
|
||||
@ApiModelProperty("菜单的类型(1为普通菜单2为目录3为iFrame4为外部网站)")
|
||||
@TableField("menu_type")
|
||||
private Integer menuType;
|
||||
|
||||
@ApiModelProperty("路由名称(需保持和前端对应的vue文件中的name保持一致defineOptions方法中设置的name)")
|
||||
@TableField("router_name")
|
||||
private String routerName;
|
||||
|
||||
@ApiModelProperty("父菜单ID")
|
||||
@TableField("parent_id")
|
||||
private Long parentId;
|
||||
|
||||
@ApiModelProperty("组件路径(对应前端项目view文件夹中的路径)")
|
||||
@TableField("path")
|
||||
private String path;
|
||||
|
||||
@ApiModelProperty("是否按钮")
|
||||
@TableField("is_button")
|
||||
private Boolean isButton;
|
||||
|
||||
@ApiModelProperty("权限标识")
|
||||
@TableField("permission")
|
||||
private String permission;
|
||||
|
||||
@ApiModelProperty("路由元信息(前端根据这个信息进行逻辑处理)")
|
||||
@TableField("meta_info")
|
||||
private String metaInfo;
|
||||
|
||||
@ApiModelProperty("菜单状态(1启用 0停用)")
|
||||
@TableField("`status`")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
@TableField("remark")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.agileboot.system.menu.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.common.satoken.pojo.LoginUser;
|
||||
import com.agileboot.system.menu.pojo.dto.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ISysMenuService {
|
||||
List<MenuDTO> getMenuList(MenuQuery menuQuery);
|
||||
|
||||
MenuDetailDTO getMenuInfo(Long menuId);
|
||||
|
||||
List<Tree<Long>> getDropdownList(LoginUser loginUser);
|
||||
|
||||
void addMenu(AddMenuCommand addCommand);
|
||||
|
||||
void updateMenu(UpdateMenuCommand updateCommand);
|
||||
|
||||
void remove(Long menuId);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.agileboot.system.menu.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import com.agileboot.common.core.enums.common.MenuTypeEnum;
|
||||
import com.agileboot.common.core.exception.BizException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.common.satoken.pojo.LoginUser;
|
||||
import com.agileboot.system.menu.mapper.SysMenuMapper;
|
||||
import com.agileboot.system.menu.pojo.dto.*;
|
||||
import com.agileboot.system.menu.pojo.entity.SysMenu;
|
||||
import com.agileboot.system.menu.service.ISysMenuService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 菜单应用服务
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
|
||||
|
||||
|
||||
@Override
|
||||
public List<MenuDTO> getMenuList(MenuQuery query) {
|
||||
Boolean isButton = query.getIsButton();
|
||||
List<SysMenu> list = super.lambdaQuery()
|
||||
.eq(isButton != null, SysMenu::getIsButton, isButton)
|
||||
.orderByDesc(SysMenu::getParentId)
|
||||
.list();
|
||||
return list.stream().map(MenuDTO::new)
|
||||
.sorted(Comparator.comparing(MenuDTO::getRank, Comparator.nullsLast(Integer::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuDetailDTO getMenuInfo(Long menuId) {
|
||||
SysMenu sysMenu = super.getById(menuId);
|
||||
return new MenuDetailDTO(sysMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tree<Long>> getDropdownList(LoginUser loginUser) {
|
||||
List<SysMenu> menuEntityList =
|
||||
// loginUser.isAdmin() ?
|
||||
super.list();
|
||||
// :
|
||||
// this.baseMapper.selectMenuListByUserId(loginUser.getUserId());
|
||||
|
||||
return buildMenuTreeSelect(menuEntityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMenu(AddMenuCommand addCommand) {
|
||||
SysMenu entity = new SysMenu();
|
||||
BeanUtils.copyProperties(addCommand, entity, "menuId");
|
||||
String metaInfo = JacksonUtil.to(addCommand.getMeta());
|
||||
entity.setMetaInfo(metaInfo);
|
||||
// 校验菜单名称是否唯一
|
||||
boolean exists = super.lambdaQuery()
|
||||
.eq(SysMenu::getMenuName, addCommand.getMenuName())
|
||||
.eq(addCommand.getParentId() != null, SysMenu::getParentId, addCommand.getParentId())
|
||||
.exists();
|
||||
if (exists) throw new BizException(ErrorCode.Business.MENU_NAME_IS_NOT_UNIQUE);
|
||||
|
||||
SysMenu parentMenu = super.getById(addCommand.getParentId());
|
||||
// Iframe和外链跳转类型 不允许添加按钮
|
||||
if (parentMenu != null && parentMenu.getIsButton() && (
|
||||
Objects.equals(parentMenu.getMenuType(), MenuTypeEnum.IFRAME.getValue())
|
||||
|| Objects.equals(parentMenu.getMenuType(), MenuTypeEnum.OUTSIDE_LINK_REDIRECT.getValue())
|
||||
)) {
|
||||
throw new BizException(ErrorCode.Business.MENU_NOT_ALLOWED_TO_CREATE_BUTTON_ON_IFRAME_OR_OUT_LINK);
|
||||
}
|
||||
// 只允许在目录菜单类型底下 添加子菜单
|
||||
if (parentMenu != null && !parentMenu.getIsButton() && (
|
||||
!Objects.equals(parentMenu.getMenuType(), MenuTypeEnum.CATALOG.getValue())
|
||||
)) {
|
||||
throw new BizException(ErrorCode.Business.MENU_ONLY_ALLOWED_TO_CREATE_SUB_MENU_IN_CATALOG);
|
||||
}
|
||||
super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMenu(UpdateMenuCommand updateCommand) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Long menuId) {
|
||||
// 是否存在菜单子节点
|
||||
if (super.lambdaQuery().eq(SysMenu::getParentId, menuId).exists()) {
|
||||
throw new BizException(ErrorCode.Business.MENU_EXIST_CHILD_MENU_NOT_ALLOW_DELETE);
|
||||
}
|
||||
// 查询菜单是否存在角色
|
||||
if (super.lambdaQuery().eq(SysMenu::getMenuId, menuId).exists()) {
|
||||
throw new BizException(ErrorCode.Business.MENU_ALREADY_ASSIGN_TO_ROLE_NOT_ALLOW_DELETE);
|
||||
}
|
||||
super.removeById(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建前端所需要树结构
|
||||
*
|
||||
* @param menus 菜单列表
|
||||
* @return 树结构列表
|
||||
*/
|
||||
public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
|
||||
TreeNodeConfig config = new TreeNodeConfig();
|
||||
//默认为id可以不设置
|
||||
config.setIdKey("menuId");
|
||||
return TreeUtil.build(menus, 0L, config, (menu, tree) -> {
|
||||
// 也可以使用 tree.setId(dept.getId());等一些默认值
|
||||
tree.setId(menu.getMenuId());
|
||||
tree.setParentId(menu.getParentId());
|
||||
tree.putExtra("label", menu.getMenuName());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.agileboot.system.role.controller.pojo.entity;
|
||||
|
||||
import com.agileboot.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色和菜单关联表
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2022-10-02
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("sys_role_menu")
|
||||
@ApiModel(value = "SysRoleMenuXEntity对象", description = "角色和菜单关联表")
|
||||
public class SysRoleMenu extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("角色ID")
|
||||
@TableId(value = "role_id", type = IdType.AUTO)
|
||||
private Long roleId;
|
||||
|
||||
@ApiModelProperty("菜单ID")
|
||||
@TableField("menu_id")
|
||||
private Long menuId;
|
||||
|
||||
|
||||
public Serializable pkVal() {
|
||||
return this.menuId;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user