菜单管理
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user