feat(admin-server): 新增角色与菜单权限管理相关功能及数据库表结构
This commit is contained in:
parent
ca189682e5
commit
d4ac89bd28
|
|
@ -0,0 +1,35 @@
|
|||
package com.example.admin_server.common.exception;
|
||||
|
||||
/**
|
||||
* 业务异常类
|
||||
*/
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer code;
|
||||
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
this.code = 500;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = 500;
|
||||
}
|
||||
|
||||
public BusinessException(Integer code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BusinessException(Integer code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.example.admin_server.controller.admin;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.example.admin_server.common.Result;
|
||||
import com.example.admin_server.model.dto.MenuDTO;
|
||||
import com.example.admin_server.model.entity.SysMenu;
|
||||
import com.example.admin_server.service.ISysMenuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单管理控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/menu")
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = {"菜单管理"})
|
||||
public class SysMenuController {
|
||||
|
||||
private final ISysMenuService menuService;
|
||||
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("创建菜单")
|
||||
public Result<?> createMenu(@Validated @RequestBody MenuDTO menuDTO) {
|
||||
SysMenu menu = new SysMenu();
|
||||
BeanUtil.copyProperties(menuDTO, menu);
|
||||
return Result.ok(menuService.save(menu));
|
||||
}
|
||||
|
||||
@PutMapping("/edit")
|
||||
@ApiOperation("更新菜单")
|
||||
public Result<?> updateMenu(@Validated @RequestBody MenuDTO menuDTO) {
|
||||
SysMenu menu = new SysMenu();
|
||||
BeanUtil.copyProperties(menuDTO, menu);
|
||||
return Result.ok(menuService.updateById(menu));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除菜单")
|
||||
public Result<?> deleteMenu(@RequestParam Long id) {
|
||||
// 检查是否有子菜单
|
||||
int count = Math.toIntExact(menuService.count(new LambdaQueryWrapper<SysMenu>()
|
||||
.eq(SysMenu::getParentId, id)));
|
||||
if (count > 0) {
|
||||
return Result.fail("存在子菜单,无法删除");
|
||||
}
|
||||
return Result.ok(menuService.removeById(id));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperation("获取菜单详情")
|
||||
public Result<SysMenu> getMenuDetail(@RequestParam Long id) {
|
||||
SysMenu menu = menuService.getById(id);
|
||||
return menu != null ? Result.ok(menu) : Result.fail("菜单不存在");
|
||||
}
|
||||
|
||||
@GetMapping("/tree")
|
||||
@ApiOperation("获取菜单树")
|
||||
public Result<List<SysMenu>> getMenuTree() {
|
||||
List<SysMenu> menuTree = menuService.getAllMenuTree();
|
||||
return Result.ok(menuTree);
|
||||
}
|
||||
|
||||
@GetMapping("/current")
|
||||
@ApiOperation("获取当前管理员的菜单树")
|
||||
public Result<List<SysMenu>> getCurrentAdminMenus() {
|
||||
// 这里应该从安全上下文中获取当前登录的管理员ID
|
||||
// 为了演示,这里使用一个固定的ID
|
||||
Long adminId = 1L; // 实际应用中应该从SecurityContext获取
|
||||
List<SysMenu> menuTree = menuService.getMenusByAdminId(adminId);
|
||||
return Result.ok(menuTree);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获取所有菜单列表")
|
||||
public Result<List<SysMenu>> getMenuList() {
|
||||
List<SysMenu> menus = menuService.list();
|
||||
return Result.ok(menus);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.example.admin_server.controller.admin;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.example.admin_server.common.Result;
|
||||
import com.example.admin_server.common.query.IPageRequest;
|
||||
import com.example.admin_server.model.dto.IdListDTO;
|
||||
import com.example.admin_server.model.dto.RoleDTO;
|
||||
import com.example.admin_server.model.entity.SysRole;
|
||||
import com.example.admin_server.service.ISysRoleService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/role")
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = {"角色管理"})
|
||||
public class SysRoleController {
|
||||
|
||||
private final ISysRoleService roleService;
|
||||
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("创建角色")
|
||||
public Result<?> createRole(@Validated @RequestBody RoleDTO roleDTO) {
|
||||
SysRole role = BeanUtil.copyProperties(roleDTO, SysRole.class);
|
||||
return Result.ok(roleService.save(role));
|
||||
}
|
||||
|
||||
@PutMapping("/edit")
|
||||
@ApiOperation("更新角色")
|
||||
public Result<?> updateRole(@Validated @RequestBody RoleDTO roleDTO) {
|
||||
SysRole role = BeanUtil.copyProperties(roleDTO, SysRole.class);
|
||||
return Result.ok(roleService.updateById(role));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("批量删除角色")
|
||||
public Result<?> deleteRoles(@Validated @RequestBody IdListDTO idList) {
|
||||
return Result.ok(roleService.removeByIds(idList.getIdList()));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperation("获取角色详情")
|
||||
public Result<SysRole> getRoleDetail(@RequestParam Long id) {
|
||||
SysRole role = roleService.getById(id);
|
||||
return role != null ? Result.ok(role) : Result.fail("角色不存在");
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获取角色列表")
|
||||
public Result<List<SysRole>> getRoleList() {
|
||||
return Result.ok(roleService.list());
|
||||
}
|
||||
|
||||
@PostMapping("/menu/assign")
|
||||
@ApiOperation("分配角色菜单")
|
||||
public Result<?> assignRoleMenu(@RequestParam Long roleId, @RequestBody List<Long> menuIds) {
|
||||
roleService.assignMenus(roleId, menuIds);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/menu/list")
|
||||
@ApiOperation("获取角色菜单")
|
||||
public Result<List<Long>> getRoleMenus(@RequestParam Long roleId) {
|
||||
return Result.ok(roleService.getMenuIdsByRoleId(roleId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.example.admin_server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.admin_server.model.entity.SysAdminRole;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理员角色关联Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysAdminRoleMapper extends BaseMapper<SysAdminRole> {
|
||||
|
||||
/**
|
||||
* 根据管理员ID查询角色ID列表
|
||||
* @param adminId 管理员ID
|
||||
* @return 角色ID列表
|
||||
*/
|
||||
@Select("SELECT role_id FROM sys_admin_role WHERE admin_id = #{adminId}")
|
||||
List<Long> selectRoleIdsByAdminId(@Param("adminId") Long adminId);
|
||||
|
||||
/**
|
||||
* 批量插入管理员角色关联
|
||||
* @param adminId 管理员ID
|
||||
* @param roleIds 角色ID列表
|
||||
* @return 影响行数
|
||||
*/
|
||||
int batchInsert(@Param("adminId") Long adminId, @Param("roleIds") List<Long> roleIds);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.example.admin_server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.admin_server.model.entity.SysMenu;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
||||
|
||||
/**
|
||||
* 根据管理员ID查询菜单列表
|
||||
* @param adminId 管理员ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
@Select("SELECT DISTINCT m.* FROM sys_menu m " +
|
||||
"INNER JOIN sys_role_menu rm ON m.id = rm.menu_id " +
|
||||
"INNER JOIN sys_admin_role ar ON rm.role_id = ar.role_id " +
|
||||
"WHERE ar.admin_id = #{adminId} AND m.status = 1 " +
|
||||
"ORDER BY m.sort_order")
|
||||
List<SysMenu> selectMenusByAdminId(@Param("adminId") Long adminId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询菜单ID列表
|
||||
* @param roleId 角色ID
|
||||
* @return 菜单ID列表
|
||||
*/
|
||||
@Select("SELECT menu_id FROM sys_role_menu WHERE role_id = #{roleId}")
|
||||
List<Long> selectMenuIdsByRoleId(@Param("roleId") Long roleId);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.example.admin_server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.admin_server.model.entity.SysRole;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 角色Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleMapper extends BaseMapper<SysRole> {
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.example.admin_server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.admin_server.model.entity.SysRoleMenu;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色菜单关联Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
|
||||
|
||||
/**
|
||||
* 批量插入角色菜单关联
|
||||
* @param roleId 角色ID
|
||||
* @param menuIds 菜单ID列表
|
||||
* @return 影响行数
|
||||
*/
|
||||
int batchInsert(@Param("roleId") Long roleId, @Param("menuIds") List<Long> menuIds);
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
package com.example.admin_server.model.common;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 通用响应结果类
|
||||
*/
|
||||
@Data
|
||||
public class Result<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 消息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* 私有构造方法,通过静态方法创建实例
|
||||
*/
|
||||
private Result() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功结果
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> success() {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功结果
|
||||
* @param data 数据
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return success(data, "操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功结果
|
||||
* @param data 数据
|
||||
* @param message 消息
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> success(T data, String message) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(200);
|
||||
result.setMessage(message);
|
||||
result.setData(data);
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> failed() {
|
||||
return failed("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果
|
||||
* @param message 消息
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> failed(String message) {
|
||||
return failed(message, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果
|
||||
* @param message 消息
|
||||
* @param code 状态码
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> failed(String message, Integer code) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数验证失败结果
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> validateFailed() {
|
||||
return validateFailed("参数验证失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数验证失败结果
|
||||
* @param message 消息
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> validateFailed(String message) {
|
||||
return failed(message, 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未授权结果
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> unauthorized() {
|
||||
return failed("暂未登录或token已经过期", 401);
|
||||
}
|
||||
|
||||
/**
|
||||
* 无权限结果
|
||||
* @param <T> 数据类型
|
||||
* @return 结果对象
|
||||
*/
|
||||
public static <T> Result<T> forbidden() {
|
||||
return failed("没有相关权限", 403);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.example.admin_server.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 菜单数据传输对象
|
||||
*/
|
||||
@Data
|
||||
public class MenuDTO {
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父级ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 路由路径
|
||||
*/
|
||||
@NotBlank(message = "路由路径不能为空")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 组件路径
|
||||
*/
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 是否隐藏:0-显示,1-隐藏
|
||||
*/
|
||||
@NotNull(message = "显示状态不能为空")
|
||||
private Integer hidden;
|
||||
|
||||
/**
|
||||
* 菜单类型:0-目录,1-菜单,2-按钮
|
||||
*/
|
||||
@NotNull(message = "菜单类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 权限标识
|
||||
*/
|
||||
private String permission;
|
||||
|
||||
/**
|
||||
* 状态:0-禁用,1-启用
|
||||
*/
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.example.admin_server.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色数据传输对象
|
||||
*/
|
||||
@Data
|
||||
public class RoleDTO {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
@NotBlank(message = "角色名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 角色编码
|
||||
*/
|
||||
@NotBlank(message = "角色编码不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态:0-禁用,1-启用
|
||||
*/
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 菜单ID列表
|
||||
*/
|
||||
private List<Long> menuIds;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.example.admin_server.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 管理员角色关联实体类
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_admin_role")
|
||||
public class SysAdminRole {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 管理员ID
|
||||
*/
|
||||
private Long adminId;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.example.admin_server.model.entity;
|
||||
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统菜单实体类
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_menu")
|
||||
public class SysMenu implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父菜单ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单URL
|
||||
*/
|
||||
private String menuUrl;
|
||||
|
||||
/**
|
||||
* 权限标识
|
||||
*/
|
||||
private String perms;
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 类型 0:目录 1:菜单 2:按钮
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sortOrder;
|
||||
|
||||
/**
|
||||
* 是否可见 0:不可见 1:可见
|
||||
*/
|
||||
private Integer visible;
|
||||
|
||||
/**
|
||||
* 状态 0:禁用 1:启用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 子菜单列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<SysMenu> children;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.example.admin_server.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 角色实体类
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_role")
|
||||
public class SysRole {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 角色编码
|
||||
*/
|
||||
private String roleCode;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 状态(0:禁用,1:启用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.example.admin_server.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 角色菜单关联实体类
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_role_menu")
|
||||
public class SysRoleMenu {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.example.admin_server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.admin_server.model.entity.SysAdminRole;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理员角色关联服务接口
|
||||
*/
|
||||
public interface ISysAdminRoleService extends IService<SysAdminRole> {
|
||||
|
||||
/**
|
||||
* 保存管理员角色关联
|
||||
* @param adminId 管理员ID
|
||||
* @param roleIds 角色ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean saveAdminRoles(Long adminId, List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 获取管理员的角色ID列表
|
||||
* @param adminId 管理员ID
|
||||
* @return 角色ID列表
|
||||
*/
|
||||
List<Long> getRoleIdsByAdminId(Long adminId);
|
||||
|
||||
/**
|
||||
* 删除管理员的所有角色关联
|
||||
* @param adminId 管理员ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean removeByAdminId(Long adminId);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.example.admin_server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.admin_server.model.entity.SysMenu;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单服务接口
|
||||
*/
|
||||
public interface ISysMenuService extends IService<SysMenu> {
|
||||
|
||||
/**
|
||||
* 获取管理员的菜单列表
|
||||
* @param adminId 管理员ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<SysMenu> getMenusByAdminId(Long adminId);
|
||||
|
||||
/**
|
||||
* 构建菜单树
|
||||
* @param menus 菜单列表
|
||||
* @return 菜单树
|
||||
*/
|
||||
List<SysMenu> buildMenuTree(List<SysMenu> menus);
|
||||
|
||||
/**
|
||||
* 获取所有菜单树
|
||||
* @return 菜单树
|
||||
*/
|
||||
List<SysMenu> getAllMenuTree();
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(allEntries = true)
|
||||
boolean removeById(Long id);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.example.admin_server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.admin_server.model.entity.SysRoleMenu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色菜单关联服务接口
|
||||
*/
|
||||
public interface ISysRoleMenuService extends IService<SysRoleMenu> {
|
||||
|
||||
/**
|
||||
* 保存角色菜单关联
|
||||
* @param roleId 角色ID
|
||||
* @param menuIds 菜单ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean saveRoleMenus(Long roleId, List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 删除角色的所有菜单关联
|
||||
* @param roleId 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean removeByRoleId(Long roleId);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.example.admin_server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.admin_server.model.entity.SysRole;
|
||||
import com.example.admin_server.model.query.RoleQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色服务接口
|
||||
*/
|
||||
public interface ISysRoleService extends IService<SysRole> {
|
||||
|
||||
/**
|
||||
* 创建角色
|
||||
* @param role 角色信息
|
||||
* @param menuIds 菜单ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean createRole(SysRole role, List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 更新角色
|
||||
* @param role 角色信息
|
||||
* @param menuIds 菜单ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateRole(SysRole role, List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
* @param roleId 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteRole(Long roleId);
|
||||
|
||||
/**
|
||||
* 获取角色的菜单ID列表
|
||||
* @param roleId 角色ID
|
||||
* @return 菜单ID列表
|
||||
*/
|
||||
List<Long> getRoleMenuIds(Long roleId);
|
||||
|
||||
/**
|
||||
* 角色分页查询
|
||||
* @param query 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
IPage<SysRole> pageList(RoleQuery query);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.example.admin_server.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.admin_server.mapper.SysAdminRoleMapper;
|
||||
import com.example.admin_server.model.entity.SysAdminRole;
|
||||
import com.example.admin_server.service.ISysAdminRoleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 管理员角色关联服务实现类
|
||||
*/
|
||||
@Service
|
||||
public class SysAdminRoleServiceImpl extends ServiceImpl<SysAdminRoleMapper, SysAdminRole> implements ISysAdminRoleService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean saveAdminRoles(Long adminId, List<Long> roleIds) {
|
||||
// 先删除原有的关联
|
||||
removeByAdminId(adminId);
|
||||
|
||||
// 如果roleIds为空,则直接返回true(表示只是清空关联)
|
||||
if (roleIds == null || roleIds.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 批量插入新的关联
|
||||
return baseMapper.batchInsert(adminId, roleIds) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getRoleIdsByAdminId(Long adminId) {
|
||||
// 查询管理员的角色关联
|
||||
List<SysAdminRole> adminRoles = list(new LambdaQueryWrapper<SysAdminRole>()
|
||||
.eq(SysAdminRole::getAdminId, adminId));
|
||||
|
||||
// 提取角色ID
|
||||
return adminRoles.stream()
|
||||
.map(SysAdminRole::getRoleId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean removeByAdminId(Long adminId) {
|
||||
return remove(new LambdaQueryWrapper<SysAdminRole>()
|
||||
.eq(SysAdminRole::getAdminId, adminId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
package com.example.admin_server.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.admin_server.common.exception.BusinessException;
|
||||
import com.example.admin_server.mapper.SysMenuMapper;
|
||||
import com.example.admin_server.model.entity.SysMenu;
|
||||
import com.example.admin_server.service.ISysMenuService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 菜单服务实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "sys_menu")
|
||||
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "'admin_menu:' + #adminId")
|
||||
public List<SysMenu> getMenusByAdminId(Long adminId) {
|
||||
if (adminId == null) {
|
||||
throw new BusinessException("管理员ID不能为空");
|
||||
}
|
||||
|
||||
log.info("获取管理员[{}]的菜单列表", adminId);
|
||||
// 获取管理员的菜单列表
|
||||
List<SysMenu> menus = baseMapper.selectMenusByAdminId(adminId);
|
||||
if (CollectionUtil.isEmpty(menus)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 构建菜单树并排序
|
||||
return buildMenuTree(menus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysMenu> buildMenuTree(List<SysMenu> menus) {
|
||||
if (CollectionUtil.isEmpty(menus)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 将菜单列表转换为Map,方便查找
|
||||
Map<Long, SysMenu> menuMap = menus.stream()
|
||||
.collect(Collectors.toMap(SysMenu::getId, menu -> menu));
|
||||
|
||||
List<SysMenu> rootMenus = new ArrayList<>();
|
||||
|
||||
// 遍历所有菜单,将子菜单添加到父菜单的children列表中
|
||||
menus.forEach(menu -> {
|
||||
Long parentId = menu.getParentId();
|
||||
if (parentId == null || parentId == 0) {
|
||||
// 如果是根菜单,直接添加到结果列表
|
||||
rootMenus.add(menu);
|
||||
} else {
|
||||
// 如果是子菜单,添加到父菜单的children列表
|
||||
SysMenu parentMenu = menuMap.get(parentId);
|
||||
if (parentMenu != null) {
|
||||
if (parentMenu.getChildren() == null) {
|
||||
parentMenu.setChildren(new ArrayList<>());
|
||||
}
|
||||
parentMenu.getChildren().add(menu);
|
||||
// 对子菜单列表进行排序
|
||||
parentMenu.getChildren().sort(Comparator.comparing(SysMenu::getSortOrder));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 对根菜单进行排序
|
||||
rootMenus.sort(Comparator.comparing(SysMenu::getSortOrder));
|
||||
return rootMenus;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "'all_menu_tree'")
|
||||
public List<SysMenu> getAllMenuTree() {
|
||||
log.info("获取所有菜单树");
|
||||
// 获取所有菜单,按照排序字段升序排列
|
||||
List<SysMenu> allMenus = list(new LambdaQueryWrapper<SysMenu>()
|
||||
.orderByAsc(SysMenu::getSortOrder));
|
||||
// 构建菜单树
|
||||
return buildMenuTree(allMenus);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(allEntries = true)
|
||||
public boolean save(SysMenu menu) {
|
||||
validateMenu(menu);
|
||||
return super.save(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(allEntries = true)
|
||||
public boolean updateById(SysMenu menu) {
|
||||
validateMenu(menu);
|
||||
return super.updateById(menu);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(allEntries = true)
|
||||
@Override
|
||||
public boolean removeById(Long id) {
|
||||
// 检查是否存在子菜单
|
||||
long count = count(new LambdaQueryWrapper<SysMenu>()
|
||||
.eq(SysMenu::getParentId, id));
|
||||
if (count > 0) {
|
||||
throw new BusinessException("存在子菜单,无法删除");
|
||||
}
|
||||
return super.removeById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证菜单信息
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
*/
|
||||
private void validateMenu(SysMenu menu) {
|
||||
if (menu == null) {
|
||||
throw new BusinessException("菜单信息不能为空");
|
||||
}
|
||||
if (menu.getParentId() != null && menu.getParentId() != 0) {
|
||||
// 验证父菜单是否存在
|
||||
SysMenu parentMenu = getById(menu.getParentId());
|
||||
if (parentMenu == null) {
|
||||
throw new BusinessException("父菜单不存在");
|
||||
}
|
||||
}
|
||||
// 验证菜单名称是否重复
|
||||
long count = count(new LambdaQueryWrapper<SysMenu>()
|
||||
.eq(SysMenu::getMenuName, menu.getMenuName())
|
||||
.ne(menu.getId() != null, SysMenu::getId, menu.getId()));
|
||||
if (count > 0) {
|
||||
throw new BusinessException("菜单名称已存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.example.admin_server.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.admin_server.mapper.SysRoleMenuMapper;
|
||||
import com.example.admin_server.model.entity.SysRoleMenu;
|
||||
import com.example.admin_server.service.ISysRoleMenuService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色菜单关联服务实现类
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements ISysRoleMenuService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean saveRoleMenus(Long roleId, List<Long> menuIds) {
|
||||
// 先删除原有的关联
|
||||
removeByRoleId(roleId);
|
||||
|
||||
// 如果menuIds为空,则直接返回true(表示只是清空关联)
|
||||
if (menuIds == null || menuIds.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 批量插入新的关联
|
||||
return baseMapper.batchInsert(roleId, menuIds) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean removeByRoleId(Long roleId) {
|
||||
return remove(new LambdaQueryWrapper<SysRoleMenu>()
|
||||
.eq(SysRoleMenu::getRoleId, roleId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package com.example.admin_server.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.admin_server.mapper.SysRoleMapper;
|
||||
import com.example.admin_server.model.entity.SysRole;
|
||||
import com.example.admin_server.model.query.RoleQuery;
|
||||
import com.example.admin_server.service.ISysRoleMenuService;
|
||||
import com.example.admin_server.service.ISysRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色服务实现类
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
|
||||
|
||||
@Autowired
|
||||
private ISysRoleMenuService roleMenuService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean createRole(SysRole role, List<Long> menuIds) {
|
||||
// 保存角色基本信息
|
||||
boolean saved = save(role);
|
||||
if (saved && menuIds != null && !menuIds.isEmpty()) {
|
||||
// 保存角色菜单关联
|
||||
return roleMenuService.saveRoleMenus(role.getId(), menuIds);
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateRole(SysRole role, List<Long> menuIds) {
|
||||
// 更新角色基本信息
|
||||
boolean updated = updateById(role);
|
||||
if (updated) {
|
||||
// 先删除原有的菜单关联
|
||||
roleMenuService.removeByRoleId(role.getId());
|
||||
// 如果有新的菜单关联,则保存
|
||||
if (menuIds != null && !menuIds.isEmpty()) {
|
||||
return roleMenuService.saveRoleMenus(role.getId(), menuIds);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteRole(Long roleId) {
|
||||
// 先删除角色菜单关联
|
||||
roleMenuService.removeByRoleId(roleId);
|
||||
// 删除角色
|
||||
return removeById(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getRoleMenuIds(Long roleId) {
|
||||
return baseMapper.selectMenuIdsByRoleId(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<SysRole> pageList(RoleQuery query) {
|
||||
Page<SysRole> page = new Page<>(query.getPageNum(), query.getPageSize());
|
||||
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
|
||||
if (query.getKeyword() != null && !query.getKeyword().trim().isEmpty()) {
|
||||
wrapper.like(SysRole::getName, query.getKeyword())
|
||||
.or()
|
||||
.like(SysRole::getCode, query.getKeyword());
|
||||
}
|
||||
wrapper.orderByAsc(SysRole::getSort);
|
||||
return this.page(page, wrapper);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
-- 角色表
|
||||
CREATE TABLE sys_role (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '角色ID',
|
||||
role_name VARCHAR(50) NOT NULL COMMENT '角色名称',
|
||||
role_code VARCHAR(50) NOT NULL COMMENT '角色编码',
|
||||
description VARCHAR(255) COMMENT '角色描述',
|
||||
status TINYINT DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
UNIQUE KEY uk_role_code (role_code)
|
||||
) COMMENT '角色表';
|
||||
|
||||
-- 菜单表
|
||||
CREATE TABLE sys_menu (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '菜单ID',
|
||||
parent_id BIGINT DEFAULT 0 COMMENT '父菜单ID',
|
||||
menu_name VARCHAR(50) NOT NULL COMMENT '菜单名称',
|
||||
path VARCHAR(200) COMMENT '路由路径',
|
||||
component VARCHAR(255) COMMENT '组件路径',
|
||||
redirect VARCHAR(255) COMMENT '重定向地址',
|
||||
icon VARCHAR(50) COMMENT '菜单图标',
|
||||
sort_order INT DEFAULT 0 COMMENT '排序',
|
||||
keep_alive TINYINT DEFAULT 0 COMMENT '是否缓存(0:不缓存,1:缓存)',
|
||||
hidden TINYINT DEFAULT 0 COMMENT '是否隐藏(0:显示,1:隐藏)',
|
||||
type TINYINT NOT NULL COMMENT '菜单类型(1:目录,2:菜单,3:按钮)',
|
||||
status TINYINT DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
|
||||
permission VARCHAR(100) COMMENT '权限标识',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
|
||||
) COMMENT '菜单表';
|
||||
|
||||
-- 角色菜单关联表
|
||||
CREATE TABLE sys_role_menu (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID',
|
||||
role_id BIGINT NOT NULL COMMENT '角色ID',
|
||||
menu_id BIGINT NOT NULL COMMENT '菜单ID',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
UNIQUE KEY uk_role_menu (role_id, menu_id)
|
||||
) COMMENT '角色菜单关联表';
|
||||
|
||||
-- 管理员角色关联表
|
||||
CREATE TABLE sys_admin_role (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID',
|
||||
admin_id BIGINT NOT NULL COMMENT '管理员ID',
|
||||
role_id BIGINT NOT NULL COMMENT '角色ID',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
UNIQUE KEY uk_admin_role (admin_id, role_id)
|
||||
) COMMENT '管理员角色关联表';
|
||||
|
||||
-- 初始化超级管理员角色
|
||||
INSERT INTO sys_role (role_name, role_code, description) VALUES
|
||||
('超级管理员', 'ROLE_SUPER_ADMIN', '系统超级管理员');
|
||||
|
||||
-- 初始化基础菜单数据
|
||||
INSERT INTO sys_menu (parent_id, menu_name, path, component, icon, type, permission) VALUES
|
||||
(0, '仪表盘', 'dashboard', 'Dashboard', 'dashboard', 2, 'dashboard:view'),
|
||||
(0, '系统管理', 'system', null, 'setting', 1, 'system:view'),
|
||||
(2, '用户管理', 'user', 'system/UserManagement', 'user', 2, 'system:user:view'),
|
||||
(2, '角色管理', 'role', 'system/RoleManagement', 'team', 2, 'system:role:view'),
|
||||
(2, '菜单管理', 'menu', 'system/MenuManagement', 'menu', 2, 'system:menu:view');
|
||||
|
||||
-- 为超级管理员分配所有菜单
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, id FROM sys_menu;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?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.example.admin_server.mapper.SysAdminRoleMapper">
|
||||
|
||||
<!-- 批量插入管理员角色关联 -->
|
||||
<insert id="batchInsert">
|
||||
INSERT INTO sys_admin_role (admin_id, role_id, create_time)
|
||||
VALUES
|
||||
<foreach collection="roleIds" item="roleId" separator=",">
|
||||
(#{adminId}, #{roleId}, NOW())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?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.example.admin_server.mapper.SysRoleMenuMapper">
|
||||
|
||||
<!-- 批量插入角色菜单关联 -->
|
||||
<insert id="batchInsert">
|
||||
INSERT INTO sys_role_menu (role_id, menu_id, create_time)
|
||||
VALUES
|
||||
<foreach collection="menuIds" item="menuId" separator=",">
|
||||
(#{roleId}, #{menuId}, NOW())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue