菜单管理

This commit is contained in:
2026-01-13 14:06:36 +08:00
parent aaa2d25367
commit 1516caa21a
15 changed files with 938 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package com.cczsa.xinghe.codegen.controller;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuAddReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuBindFunReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuEditReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuQueryReq;
import com.cczsa.xinghe.codegen.entity.res.menu.MenuQueryRes;
import com.cczsa.xinghe.codegen.service.MenuService;
import com.cczsa.xinghe.codegen.util.XResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import java.util.List;
/**
* 菜单管理 控制层。
*
* @author xia
* @version 0.0.1
*/
@Tag(name = "菜单管理")
@RequiredArgsConstructor
@RestController
@RequestMapping("/menu")
public class MenuController {
private final MenuService menuService;
@Operation(summary = "获取菜单列表", description = "获取菜单列表")
@PostMapping("/query")
public XResult<List<MenuQueryRes>> query(@RequestBody @Valid MenuQueryReq req) {
return menuService.query(req);
}
@Operation(summary = "创建菜单", description = "创建菜单")
@PutMapping("/add")
public XResult<Void> add(@RequestBody @Valid MenuAddReq req) {
return menuService.add(req);
}
@Operation(summary = "修改菜单", description = "修改菜单")
@PostMapping("/edit")
public XResult<Void> edit(@RequestBody @Valid MenuEditReq req) {
return menuService.edit(req);
}
@Operation(summary = "删除菜单", description = "删除菜单")
@DeleteMapping("/delete/{id}")
public XResult<Void> delete(@PathVariable Long id) {
return menuService.delete(id);
}
@Operation(summary = "菜单绑定权限", description = "菜单绑定权限")
@PostMapping("/bind/fun")
public XResult<Void> bindFun(@RequestBody @Valid MenuBindFunReq req) {
return menuService.bindFun(req);
}
}

View File

@@ -0,0 +1,50 @@
package com.cczsa.xinghe.codegen.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
/**
* 菜单绑定权限 实体类。
*
* @author My
* @since 0.0.1
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Table("cg_menu_bind_fun")
public class MenuBindFunEntity extends BaseEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 菜单ID
*/
private Long menuId;
/**
* 功能ID
*/
private Long funId;
}

View File

@@ -0,0 +1,82 @@
package com.cczsa.xinghe.codegen.entity;
import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.io.Serial;
import com.mybatisflex.core.keygen.KeyGenerators;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
/**
* 菜单 实体类。
*
* @author My
* @since 0.0.1
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Table("cg_menu")
public class MenuEntity extends BaseEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 客户端类型0 PC端1 小程序端2 H5端
*/
private ClientTypeEnum clientType;
/**
* 菜单名称
*/
private String menuName;
/**
* 父菜单ID
*/
private Long parentId;
/**
* 路由路径
*/
private String path;
/**
* 菜单图标
*/
private String icon;
/**
* 是否租户
*/
private Boolean isTenant;
/**
* 是否隐藏
*/
private Boolean isHide;
/**
* 排序
*/
private Integer sortOrder;
}

View File

@@ -0,0 +1,36 @@
package com.cczsa.xinghe.codegen.entity.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import com.mybatisflex.annotation.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
/**
* 客户端类型枚举
*
* @author My
*/
@Schema(description = "客户端类型",
example = "0",
allowableValues = {"0: PC端", "1: 小程序端", "2: H5端"})
@Getter
public enum ClientTypeEnum {
// 客户端类型0 PC端1 小程序端2 H5端
PC(0, "PC端"),
MINI_PROGRAM(1, "小程序端"),
H5(2, "H5端");
private final int code;
private final String desc;
ClientTypeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
@JsonValue
@EnumValue
public int getCode() {
return code;
}
}

View File

@@ -0,0 +1,53 @@
package com.cczsa.xinghe.codegen.entity.req.menu;
import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
/**
* 创建菜单 请求参数
*
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "创建菜单-参数")
public class MenuAddReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "客户端类型不能为空")
@Schema(description = "客户端类型0 PC端1 小程序端2 H5端")
private ClientTypeEnum clientType;
@NotNull(message = "菜单名称不能为空")
@Schema(description = "菜单名称")
private String menuName;
@Schema(description = "父菜单ID")
private Long parentId = 0L;
@Schema(description = "路由路径")
private String path;
@Schema(description = "菜单图标")
private String icon;
@NotNull(message = "是否租户不能为空")
@Schema(description = "是否租户")
private Boolean isTenant;
@Schema(description = "是否隐藏")
private Boolean isHide;
@Schema(description = "排序")
private Integer sortOrder;
}

View File

@@ -0,0 +1,33 @@
package com.cczsa.xinghe.codegen.entity.req.menu;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
/**
* 菜单绑定权限 请求参数
*
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "菜单绑定权限-参数")
public class MenuBindFunReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "菜单ID不能为空")
@Schema(description = "菜单ID")
private Long menuId;
@NotNull(message = "功能ID不能为空")
@Schema(description = "功能ID")
private Long funId;
}

View File

@@ -0,0 +1,55 @@
package com.cczsa.xinghe.codegen.entity.req.menu;
import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
/**
* 修改菜单 请求参数
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "修改菜单-参数")
public class MenuEditReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "主键ID不能为空")
@Schema(description = "主键ID")
private Long id;
@NotNull(message = "客户端类型不能为空")
@Schema(description = "客户端类型0 PC端1 小程序端2 H5端")
private ClientTypeEnum clientType;
@NotNull(message = "菜单名称不能为空")
@Schema(description = "菜单名称")
private String menuName;
@Schema(description = "父菜单ID")
private Long parentId = 0L;
@Schema(description = "路由路径")
private String path;
@Schema(description = "菜单图标")
private String icon;
@NotNull(message = "是否租户不能为空")
@Schema(description = "是否租户")
private Boolean isTenant;
@Schema(description = "是否隐藏")
private Boolean isHide;
@Schema(description = "排序")
private Integer sortOrder;
}

View File

@@ -0,0 +1,34 @@
package com.cczsa.xinghe.codegen.entity.req.menu;
import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
/**
* 获取菜单列表 请求参数
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "获取菜单列表-参数")
public class MenuQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull( message = "客户端类型不能为空")
@Schema(description = "客户端类型0 PC端1 小程序端2 H5端")
private ClientTypeEnum clientType;
@Schema(description = "菜单名称")
private String menuName;
@Schema(description = "父菜单ID")
private Long parentId;
}

View File

@@ -0,0 +1,55 @@
package com.cczsa.xinghe.codegen.entity.res.menu;
import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 获取菜单列表 响应参数
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "获取菜单列表-响应")
public class MenuQueryRes implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "主键ID")
private Long id;
@Schema(description = "客户端类型0 PC端1 小程序端2 H5端")
private ClientTypeEnum clientType;
@Schema(description = "菜单名称")
private String menuName;
@Schema(description = "父菜单ID")
private Long parentId = 0L;
@Schema(description = "路由路径")
private String path;
@Schema(description = "菜单图标")
private String icon;
@Schema(description = "是否租户")
private Boolean isTenant;
@Schema(description = "是否隐藏")
private Boolean isHide;
@Schema(description = "排序")
private Integer sortOrder;
@Schema(description = "子菜单")
private List<MenuQueryRes> children;
}

View File

@@ -0,0 +1,16 @@
package com.cczsa.xinghe.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.mybatisflex.core.BaseMapper;
import com.cczsa.xinghe.codegen.entity.MenuBindFunEntity;
/**
* 菜单绑定权限 映射层。
*
* @author My
* @since 0.0.1
*/
@Mapper
public interface MenuBindFunMapper extends BaseMapper<MenuBindFunEntity> {
}

View File

@@ -0,0 +1,16 @@
package com.cczsa.xinghe.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.mybatisflex.core.BaseMapper;
import com.cczsa.xinghe.codegen.entity.MenuEntity;
/**
* 菜单 映射层。
*
* @author My
* @since 0.0.1
*/
@Mapper
public interface MenuMapper extends BaseMapper<MenuEntity> {
}

View File

@@ -0,0 +1,62 @@
package com.cczsa.xinghe.codegen.mapper.def;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.table.TableDef;
import java.io.Serial;
/**
* 菜单绑定权限 表定义层。
*
* @author My
* @since 0.0.1
*/
public class MenuBindFunDef extends TableDef {
@Serial
private static final long serialVersionUID = 1L;
/**
* 菜单绑定权限
*/
public static final MenuBindFunDef MENU_BIND_FUN_ENTITY = new MenuBindFunDef();
/**
* 主键ID
*/
public final QueryColumn ID = new QueryColumn(this, "id");
/**
* 功能ID
*/
public final QueryColumn FUN_ID = new QueryColumn(this, "fun_id");
/**
* 菜单ID
*/
public final QueryColumn MENU_ID = new QueryColumn(this, "menu_id");
/**
* 所有字段。
*/
public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*");
/**
* 默认字段,不包含逻辑删除或者 large 等字段。
*/
public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, MENU_ID, FUN_ID};
public MenuBindFunDef() {
super("", "cg_menu_bind_fun");
}
private MenuBindFunDef(String schema, String name, String alisa) {
super(schema, name, alisa);
}
public MenuBindFunDef as(String alias) {
String key = getNameWithSchema() + "." + alias;
return getCache(key, k -> new MenuBindFunDef("", "cg_menu_bind_fun", alias));
}
}

View File

@@ -0,0 +1,90 @@
package com.cczsa.xinghe.codegen.mapper.def;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.table.TableDef;
import java.io.Serial;
/**
* 菜单 表定义层。
*
* @author My
* @since 0.0.1
*/
public class MenuDef extends TableDef {
@Serial
private static final long serialVersionUID = 1L;
/**
* 菜单
*/
public static final MenuDef MENU_ENTITY = new MenuDef();
/**
* 主键ID
*/
public final QueryColumn ID = new QueryColumn(this, "id");
/**
* 菜单图标
*/
public final QueryColumn ICON = new QueryColumn(this, "icon");
/**
* 路由路径
*/
public final QueryColumn PATH = new QueryColumn(this, "path");
/**
* 是否隐藏
*/
public final QueryColumn IS_HIDE = new QueryColumn(this, "is_hide");
/**
* 是否租户
*/
public final QueryColumn IS_TENANT = new QueryColumn(this, "is_tenant");
/**
* 菜单名称
*/
public final QueryColumn MENU_NAME = new QueryColumn(this, "menu_name");
/**
* 父菜单ID
*/
public final QueryColumn PARENT_ID = new QueryColumn(this, "parent_id");
public final QueryColumn SORT_ORDER = new QueryColumn(this, "sort_order");
/**
* 客户端类型0 PC端1 小程序端2 H5端
*/
public final QueryColumn CLIENT_TYPE = new QueryColumn(this, "client_type");
/**
* 所有字段。
*/
public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*");
/**
* 默认字段,不包含逻辑删除或者 large 等字段。
*/
public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, CLIENT_TYPE, MENU_NAME, PARENT_ID, PATH, ICON, IS_TENANT, IS_HIDE, SORT_ORDER};
public MenuDef() {
super("", "cg_menu");
}
private MenuDef(String schema, String name, String alisa) {
super(schema, name, alisa);
}
public MenuDef as(String alias) {
String key = getNameWithSchema() + "." + alias;
return getCache(key, k -> new MenuDef("", "cg_menu", alias));
}
}

View File

@@ -0,0 +1,46 @@
package com.cczsa.xinghe.codegen.service;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuAddReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuBindFunReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuEditReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuQueryReq;
import com.cczsa.xinghe.codegen.entity.res.menu.MenuQueryRes;
import com.cczsa.xinghe.codegen.util.XResult;
import java.util.List;
/**
* 菜单管理 服务层接口。
*
* @author xia
* @version 0.0.1
*/
public interface MenuService {
/**
* 获取菜单列表
*/
XResult<List<MenuQueryRes>> query(MenuQueryReq req);
/**
* 创建菜单
*/
XResult<Void> add(MenuAddReq req);
/**
* 修改菜单
*/
XResult<Void> edit(MenuEditReq req);
/**
* 删除菜单
*/
XResult<Void> delete(Long id);
/**
* 菜单绑定权限
*/
XResult<Void> bindFun(MenuBindFunReq req);
}

View File

@@ -0,0 +1,241 @@
package com.cczsa.xinghe.codegen.service.impl;
import com.cczsa.xinghe.codegen.entity.FunItemEntity;
import com.cczsa.xinghe.codegen.entity.FunOperationEntity;
import com.cczsa.xinghe.codegen.entity.MenuBindFunEntity;
import com.cczsa.xinghe.codegen.entity.MenuEntity;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuAddReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuBindFunReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuEditReq;
import com.cczsa.xinghe.codegen.entity.req.menu.MenuQueryReq;
import com.cczsa.xinghe.codegen.entity.res.menu.MenuQueryRes;
import com.cczsa.xinghe.codegen.mapper.FunItemMapper;
import com.cczsa.xinghe.codegen.mapper.FunOperationMapper;
import com.cczsa.xinghe.codegen.mapper.MenuBindFunMapper;
import com.cczsa.xinghe.codegen.mapper.MenuMapper;
import com.cczsa.xinghe.codegen.mapper.def.MenuBindFunDef;
import com.cczsa.xinghe.codegen.mapper.def.MenuDef;
import com.cczsa.xinghe.codegen.service.MenuService;
import com.cczsa.xinghe.codegen.util.XResult;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 菜单管理 服务层实现。
*
* @author xia
* @version 0.0.1
*/
@Service
@RequiredArgsConstructor
public class MenuServiceImpl implements MenuService {
private final MenuMapper menuMapper;
private final MenuBindFunMapper menuBindFunMapper;
private final FunOperationMapper funOperationMapper;
private final FunItemMapper funItemMapper;
/**
* 获取菜单列表
*/
@Override
public XResult<List<MenuQueryRes>> query(MenuQueryReq req) {
MenuDef menuDef = MenuDef.MENU_ENTITY;
QueryWrapper query = new QueryWrapper();
query.select(menuDef.ALL_COLUMNS)
.from(menuDef)
.eq(MenuEntity::getClientType, req.getClientType())
.like(MenuEntity::getMenuName, req.getMenuName(), StrUtil.isNotBlank(req.getMenuName()))
.eq(MenuEntity::getParentId, req.getParentId(), req.getParentId() != null)
.orderBy(MenuEntity::getSortOrder, false);
List<MenuQueryRes> menuEntities = menuMapper.selectListByQueryAs(query, MenuQueryRes.class);
// 构建树形结构
List<MenuQueryRes> treeList = buildMenuTree(menuEntities);
return XResult.ok(treeList);
}
/**
* 构建树形结构
*/
private List<MenuQueryRes> buildMenuTree(List<MenuQueryRes> menuEntities) {
// 创建一个Map用于快速查找分组
Map<Long, MenuQueryRes> menuMap = new HashMap<>();
for (MenuQueryRes menu : menuEntities) {
menuMap.put(menu.getId(), menu);
}
// 构建树形结构
List<MenuQueryRes> rootMenuList = new ArrayList<>();
for (MenuQueryRes menu : menuEntities) {
Long parentId = menu.getParentId();
if (parentId == 0) {
// 根分组
rootMenuList.add(menu);
} else {
// 如果父节点在结果中,则挂到父节点下
MenuQueryRes parentMenu = menuMap.get(parentId);
if (parentMenu != null) {
if (parentMenu.getChildren() == null) {
parentMenu.setChildren(new ArrayList<>());
}
parentMenu.getChildren().add(menu);
} else {
// 如果父节点不在结果中,则将该节点作为根节点处理
rootMenuList.add(menu);
}
}
}
return rootMenuList;
}
/**
* 创建菜单
*/
@Override
public XResult<Void> add(MenuAddReq req) {
// 获取最大ID
MenuDef menuDef = MenuDef.MENU_ENTITY;
QueryWrapper queryId = new QueryWrapper();
queryId.select(menuDef.ID)
.from(menuDef)
.orderBy(MenuEntity::getId, false);
Long maxId = menuMapper.selectOneByQueryAs(queryId, Long.class);
if (maxId == null) {
maxId = 10000L;
} else {
maxId++;
}
QueryWrapper query = new QueryWrapper();
query.select(menuDef.ID)
.from(menuDef)
.eq(MenuEntity::getParentId, req.getParentId())
.eq(MenuEntity::getMenuName, req.getMenuName());
long count = menuMapper.selectCountByQuery(query);
if (count > 0) {
return XResult.failed("菜单已存在");
}
MenuEntity menuEntity = new MenuEntity();
menuEntity.setId(maxId);
BeanUtils.copyProperties(req, menuEntity);
menuMapper.insertSelective(menuEntity);
return XResult.ok();
}
/**
* 修改菜单
*/
@Override
public XResult<Void> edit(MenuEditReq req) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq(MenuEntity::getId, req.getId());
MenuEntity menuEntity = menuMapper.selectOneByQuery(queryWrapper);
if (menuEntity == null) {
return XResult.failed("菜单不存在");
}
MenuDef menuDef = MenuDef.MENU_ENTITY;
QueryWrapper queryCount = new QueryWrapper();
queryCount.select(menuDef.ID)
.from(menuDef)
.eq(MenuEntity::getParentId, req.getParentId())
.eq(MenuEntity::getMenuName, req.getMenuName())
.ne(MenuEntity::getId, req.getId());
long count = menuMapper.selectCountByQuery(queryCount);
if (count > 0) {
return XResult.failed("菜单已存在");
}
BeanUtils.copyProperties(req, menuEntity);
menuMapper.update(menuEntity);
return XResult.ok();
}
/**
* 删除菜单
*/
@Transactional
@Override
public XResult<Void> delete(Long id) {
// 是否有子菜单
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq(MenuEntity::getParentId, id);
long count = menuMapper.selectCountByQuery(queryWrapper);
if (count > 0) {
return XResult.failed("请先删除子菜单");
}
QueryWrapper deleteMenu = new QueryWrapper();
deleteMenu.eq(MenuEntity::getId, id);
menuMapper.deleteByQuery(deleteMenu);
// 删除菜单绑定的权限
QueryWrapper deleteMenuBindFun = new QueryWrapper();
deleteMenuBindFun.eq(MenuBindFunEntity::getMenuId, id);
menuBindFunMapper.deleteByQuery(deleteMenuBindFun);
return XResult.ok();
}
/**
* 菜单绑定权限
*/
@Transactional
@Override
public XResult<Void> bindFun(MenuBindFunReq req) {
// 获取菜单
QueryWrapper queryMenu = new QueryWrapper();
queryMenu.eq(MenuEntity::getId, req.getMenuId());
MenuEntity menuEntity = menuMapper.selectOneByQuery(queryMenu);
if (menuEntity == null) {
return XResult.failed("菜单不存在");
}
// 获取操作
QueryWrapper queryFun = new QueryWrapper();
queryFun.eq(FunOperationEntity::getId, req.getFunId());
FunOperationEntity funOperationEntity = funOperationMapper.selectOneByQuery(queryFun);
if (funOperationEntity == null) {
return XResult.failed("权限不存在");
}
// 获取功能
QueryWrapper queryItem = new QueryWrapper();
queryItem.eq(FunItemEntity::getId, funOperationEntity.getItemId());
FunItemEntity funItemEntity = funItemMapper.selectOneByQuery(queryItem);
if (funItemEntity == null) {
return XResult.failed("功能不存在");
}
Boolean menuIsTenant = menuEntity.getIsTenant();
Boolean itemIsTenant = funItemEntity.getIsTenant();
if (!menuIsTenant.equals(itemIsTenant)) {
return XResult.failed("菜单和权限是否租户不一致");
}
// 删除旧绑定
QueryWrapper deleteMenuBindFun = new QueryWrapper();
deleteMenuBindFun.eq(MenuBindFunEntity::getMenuId, req.getMenuId());
deleteMenuBindFun.eq(MenuBindFunEntity::getFunId, req.getFunId());
menuBindFunMapper.deleteByQuery(deleteMenuBindFun);
// 获取最大ID
MenuBindFunDef menuBindFunDef = MenuBindFunDef.MENU_BIND_FUN_ENTITY;
QueryWrapper queryId = new QueryWrapper();
queryId.select(menuBindFunDef.ID)
.from(menuBindFunDef)
.orderBy(MenuBindFunEntity::getId, false);
Long maxId = menuBindFunMapper.selectOneByQueryAs(queryId, Long.class);
if (maxId == null) {
maxId = 10000L;
} else {
maxId++;
}
// 新增绑定
MenuBindFunEntity menuBindFunEntity = new MenuBindFunEntity();
menuBindFunEntity.setId(maxId);
menuBindFunEntity.setMenuId(req.getMenuId());
menuBindFunEntity.setFunId(req.getFunId());
menuBindFunMapper.insertSelective(menuBindFunEntity);
return XResult.ok();
}
}