feat: 实现完整的 RBAC 权限管理系统与基础设施增强
在初始认证基础上,新增完整的 RBAC 权限模型(角色、权限、菜单三级管理), 集成审计日志、接口限流、登录失败锁定、Refresh Token 机制、Redis 分布式缓存与锁、 RocketMQ 消息队列,并引入 Flyway 数据库版本管理,同时补充项目文档与使用示例
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package com.aisi.template.domain.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 登录响应视图对象
|
||||
* 用于返回登录成功后的响应数据
|
||||
*
|
||||
* 主要字段:
|
||||
* 1. Token 信息:访问令牌、刷新令牌、过期时间
|
||||
* 2. 用户信息:用户ID、用户名、邮箱
|
||||
*
|
||||
* 使用场景:
|
||||
* - 用户登录成功后返回
|
||||
* - 用户注册成功后返回(自动登录)
|
||||
* - Token 刷新后返回
|
||||
*
|
||||
* @author Claude
|
||||
* @since 2024-04-09
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "登录响应")
|
||||
public class LoginResponseVo {
|
||||
|
||||
/**
|
||||
* 访问令牌(Access Token)
|
||||
* - 用于 API 访问认证
|
||||
* - 放在请求头:Authorization: Bearer {accessToken}
|
||||
* - 默认有效期:1 小时
|
||||
*/
|
||||
@Schema(description = "访问令牌")
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* 刷新令牌(Refresh Token)
|
||||
* - 用于获取新的 Access Token
|
||||
* - 当 Access Token 过期时使用
|
||||
* - 默认有效期:7 天
|
||||
*/
|
||||
@Schema(description = "刷新令牌")
|
||||
private String refreshToken;
|
||||
|
||||
/**
|
||||
* 访问令牌过期时间(秒)
|
||||
* - 默认:3600 秒(1 小时)
|
||||
* - 前端可根据此时间提前刷新 Token
|
||||
*/
|
||||
@Schema(description = "访问令牌过期时间(秒)")
|
||||
private Long expiresIn;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
* - 包含用户的基本信息
|
||||
* - 前端可显示用户名等信息
|
||||
*/
|
||||
@Schema(description = "用户信息")
|
||||
private UserInfoVo userInfo;
|
||||
|
||||
/**
|
||||
* 用户信息视图对象
|
||||
* 包含用户的基本信息
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "用户信息")
|
||||
public static class UserInfoVo {
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@Schema(description = "用户ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 邮箱地址
|
||||
*/
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
}
|
||||
}
|
||||
228
src/main/java/com/aisi/template/domain/vo/MenuVo.java
Normal file
228
src/main/java/com/aisi/template/domain/vo/MenuVo.java
Normal file
@@ -0,0 +1,228 @@
|
||||
package com.aisi.template.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单视图对象
|
||||
* 用于返回菜单信息给前端
|
||||
*
|
||||
* 主要字段:
|
||||
* 1. 基本信息:菜单ID、父菜单ID、菜单名称、菜单类型
|
||||
* 2. 菜单配置:路径、组件、图标、排序
|
||||
* 3. 显示控制:可见性、启用状态
|
||||
* 4. 权限控制:权限编码
|
||||
* 5. 子菜单:子菜单列表(树形结构)
|
||||
* 6. 时间信息:创建时间、更新时间
|
||||
*
|
||||
* @author Claude
|
||||
* @since 2024-04-09
|
||||
*/
|
||||
public class MenuVo {
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父菜单ID
|
||||
* - 0 或 null:根菜单
|
||||
* - 其他值:子菜单
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
* - 1:目录(DIRECTORY)
|
||||
* - 2:菜单(MENU)
|
||||
* - 3:按钮(BUTTON)
|
||||
*/
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 菜单路径
|
||||
* - 用于前端路由
|
||||
*/
|
||||
private String menuPath;
|
||||
|
||||
/**
|
||||
* 组件路径
|
||||
* - 前端组件文件路径
|
||||
*/
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 菜单图标
|
||||
* - 图标名称
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
* - 数值越小越靠前
|
||||
*/
|
||||
private Integer sortOrder;
|
||||
|
||||
/**
|
||||
* 可见性
|
||||
* - 1:可见
|
||||
* - 0:不可见
|
||||
*/
|
||||
private Integer visible;
|
||||
|
||||
/**
|
||||
* 菜单状态
|
||||
* - 1:启用
|
||||
* - 0:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 权限编码
|
||||
* - 用于控制菜单的访问权限
|
||||
*/
|
||||
private String permissionCode;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
/**
|
||||
* 子菜单列表
|
||||
* - 用于构建菜单树形结构
|
||||
* - 递归结构
|
||||
*/
|
||||
private List<MenuVo> children;
|
||||
|
||||
public MenuVo() {
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getMenuName() {
|
||||
return menuName;
|
||||
}
|
||||
|
||||
public void setMenuName(String menuName) {
|
||||
this.menuName = menuName;
|
||||
}
|
||||
|
||||
public Integer getMenuType() {
|
||||
return menuType;
|
||||
}
|
||||
|
||||
public void setMenuType(Integer menuType) {
|
||||
this.menuType = menuType;
|
||||
}
|
||||
|
||||
public String getMenuPath() {
|
||||
return menuPath;
|
||||
}
|
||||
|
||||
public void setMenuPath(String menuPath) {
|
||||
this.menuPath = menuPath;
|
||||
}
|
||||
|
||||
public String getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setComponent(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Integer getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(Integer sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public Integer getVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(Integer visible) {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getPermissionCode() {
|
||||
return permissionCode;
|
||||
}
|
||||
|
||||
public void setPermissionCode(String permissionCode) {
|
||||
this.permissionCode = permissionCode;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public List<MenuVo> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<MenuVo> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
154
src/main/java/com/aisi/template/domain/vo/PermissionVo.java
Normal file
154
src/main/java/com/aisi/template/domain/vo/PermissionVo.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.aisi.template.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 权限视图对象
|
||||
* 用于返回权限信息给前端
|
||||
*
|
||||
* 主要字段:
|
||||
* 1. 基本信息:权限ID、权限编码、权限名称
|
||||
* 2. 资源操作:资源名称、操作类型
|
||||
* 3. 描述和状态:描述信息、启用状态
|
||||
* 4. 时间信息:创建时间、更新时间
|
||||
*
|
||||
* @author Claude
|
||||
* @since 2024-04-09
|
||||
*/
|
||||
public class PermissionVo {
|
||||
|
||||
/**
|
||||
* 权限ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 权限编码
|
||||
* - 格式:资源:操作
|
||||
* - 示例:user:read, role:write
|
||||
*/
|
||||
private String permissionCode;
|
||||
|
||||
/**
|
||||
* 权限名称
|
||||
* - 用于界面展示
|
||||
* - 示例:查看用户、编辑角色
|
||||
*/
|
||||
private String permissionName;
|
||||
|
||||
/**
|
||||
* 资源名称
|
||||
* - 示例:user, role, menu
|
||||
*/
|
||||
private String resource;
|
||||
|
||||
/**
|
||||
* 操作类型
|
||||
* - read:读取(查看)
|
||||
* - write:写入(创建/编辑)
|
||||
* - delete:删除
|
||||
*/
|
||||
private String action;
|
||||
|
||||
/**
|
||||
* 权限描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 权限状态
|
||||
* - 1:启用
|
||||
* - 0:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public PermissionVo() {
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getPermissionCode() {
|
||||
return permissionCode;
|
||||
}
|
||||
|
||||
public void setPermissionCode(String permissionCode) {
|
||||
this.permissionCode = permissionCode;
|
||||
}
|
||||
|
||||
public String getPermissionName() {
|
||||
return permissionName;
|
||||
}
|
||||
|
||||
public void setPermissionName(String permissionName) {
|
||||
this.permissionName = permissionName;
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
152
src/main/java/com/aisi/template/domain/vo/RoleVo.java
Normal file
152
src/main/java/com/aisi/template/domain/vo/RoleVo.java
Normal file
@@ -0,0 +1,152 @@
|
||||
package com.aisi.template.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色视图对象
|
||||
* 用于返回角色信息给前端
|
||||
*
|
||||
* 主要字段:
|
||||
* 1. 基本信息:角色ID、角色编码、角色名称、描述
|
||||
* 2. 排序和状态:排序字段、启用状态
|
||||
* 3. 权限信息:关联的权限列表
|
||||
* 4. 时间信息:创建时间、更新时间
|
||||
*
|
||||
* @author Claude
|
||||
* @since 2024-04-09
|
||||
*/
|
||||
public class RoleVo {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色编码
|
||||
* - 格式:ROLE_ + 名称
|
||||
* - 示例:ROLE_USER, ROLE_ADMIN
|
||||
*/
|
||||
private String roleCode;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
* - 用于界面展示
|
||||
* - 示例:普通用户、管理员
|
||||
*/
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
* - 数值越小越靠前
|
||||
*/
|
||||
private Integer sortOrder;
|
||||
|
||||
/**
|
||||
* 角色状态
|
||||
* - 1:启用
|
||||
* - 0:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
/**
|
||||
* 角色拥有的权限列表
|
||||
*/
|
||||
private Set<PermissionVo> permissions;
|
||||
|
||||
public RoleVo() {
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public String getRoleName() {
|
||||
return roleName;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(Integer sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Set<PermissionVo> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<PermissionVo> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
}
|
||||
@@ -5,30 +5,73 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户视图对象
|
||||
* 用于返回用户信息给前端
|
||||
*
|
||||
* 主要字段:
|
||||
* 1. 基本信息:用户ID、用户名、邮箱
|
||||
* 2. 状态信息:启用/禁用状态
|
||||
* 3. 角色信息:角色编码列表
|
||||
* 4. 时间信息:创建时间、更新时间
|
||||
*
|
||||
* 注意:
|
||||
* - 不包含密码等敏感信息
|
||||
* - 角色只返回角色编码,不返回完整角色对象
|
||||
*
|
||||
* @author Claude
|
||||
* @since 2024-04-09
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户视图对象")
|
||||
public class UserVo {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@Schema(description = "用户ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 邮箱地址
|
||||
*/
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
* - 1:正常(启用)
|
||||
* - 0:禁用
|
||||
*/
|
||||
@Schema(description = "状态(1=正常 0=禁用)")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "角色(USER=普通用户,ADMIN=管理员)")
|
||||
private String role;
|
||||
/**
|
||||
* 角色编码列表
|
||||
* - 示例:["ROLE_USER", "ROLE_ADMIN"]
|
||||
* - 只返回角色编码,不返回完整角色对象
|
||||
*/
|
||||
@Schema(description = "角色列表")
|
||||
private Set<String> roles;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
Reference in New Issue
Block a user