初始化提交

This commit is contained in:
liweijie
2026-08-18 09:49:02 +08:00
commit 5a74ab0b0d
1102 changed files with 119160 additions and 0 deletions
@@ -0,0 +1,36 @@
package com.roomroot.jwgl.unit;
import static com.roomroot.jwgl.utils.AccountManagementConstants.*;
/**
* 表示密码校验失败且失败统计需要保留的账户登录业务异常。
*
* <p>该异常由项目统一业务异常处理器转换为标准错误响应,
* 同时供登录事务通过异常类型识别不需要回滚的登录失败场景,
* 从而保留已经写入的登录失败次数和临时锁定状态。</p>
*/
public final class AccountLoginFailedException extends BusinessException {
/**
* 声明当前异常类的序列化版本,保证异常对象序列化时的版本一致性。
*/
private static final long serialVersionUID = 1L;
/**
* 创建不泄露账号存在状态和密码校验细节的普通登录失败异常。
*/
public AccountLoginFailedException() {
// 使用统一的请求错误状态码和登录失败提示,避免暴露具体失败原因。
super(BAD_REQUEST, ACCOUNT_LOGIN_FAILED_MESSAGE);
}
/**
* 创建需要保留失败统计的指定登录失败异常。
*
* @param message 对外返回的登录失败提示
*/
public AccountLoginFailedException(String message) {
// 使用冲突状态码返回账户临时锁定等需要明确提示的登录失败结果。
super(CONFLICT, message);
}
}
@@ -0,0 +1,49 @@
package com.roomroot.jwgl.unit;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 实体基类 - 抽取公共字段
* <p>
* 所有数据库实体继承此类,自动获得创建时间、更新时间、创建人、更新人及逻辑删除标记等公共属性。
* 配合 MyBatis-Plus 的自动填充机制,在插入/更新时自动设置对应字段。
* </p>
*
* @author management
*/
@Data
public class BaseEntity {
/**
* 创建时间(自动填充,仅在插入时赋值)
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间(自动填充,插入和更新时均赋值)
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/**
* 创建人(自动填充,仅在插入时赋值)
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 更新人(自动填充,插入和更新时均赋值)
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 逻辑删除标记:0-正常,1-已删除
*/
private Integer delFlag;
}
@@ -0,0 +1,36 @@
package com.roomroot.jwgl.unit;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 查询基类
* <p>
* 封装列表查询的通用参数,包括关键字搜索和创建时间范围筛选。
* 具体的业务查询DTO可继承此类以复用公共查询条件。
* </p>
*
* @author management
*/
@Data
public class BaseQuery implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创建时间范围查询 - 起始时间
*/
private LocalDateTime createTimeStart;
/**
* 创建时间范围查询 - 截止时间
*/
private LocalDateTime createTimeEnd;
/**
* 关键字模糊搜索
*/
private String keyword;
}
@@ -0,0 +1,59 @@
package com.roomroot.jwgl.unit;
/**
* 业务异常类
* <p>
* 用于业务逻辑校验失败、数据不合法、操作不允许等场景的统一异常抛出。
* 由 {@link GlobalExceptionHandler} 全局捕获后转换为统一响应格式返回前端。
* </p>
*
* @author management
*/
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 业务错误码,默认500
*/
private Integer code;
/**
* 构造方法 - 使用默认错误码500
*
* @param message 异常提示信息
*/
public BusinessException(String message) {
super(message);
this.code = 500;
}
/**
* 构造方法 - 指定错误码
*
* @param code 自定义业务错误码
* @param message 异常提示信息
*/
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
/**
* 获取错误码
*
* @return 错误码
*/
public Integer getCode() {
return code;
}
/**
* 设置错误码
*
* @param code 错误码
*/
public void setCode(Integer code) {
this.code = code;
}
}
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.unit;
/**
* 通用系统常量
* <p>
* 定义系统全局使用的各类常量值,包括状态标记和逻辑删除标记等。
* 所有模块统一引用此处的常量,保证系统内数值含义一致。
* </p>
*
* @author management
*/
public final class Constants {
/** 私有构造,防止实例化 */
private Constants() {}
/** 通用启用状态码 */
public static final Integer STATUS_ENABLED = 1;
/** 通用禁用状态码 */
public static final Integer STATUS_DISABLED = 0;
/** 逻辑删除标记:已删除 */
public static final Integer DEL_FLAG_DELETED = 1;
/** 逻辑删除标记:正常(未删除) */
public static final Integer DEL_FLAG_NORMAL = 0;
/** 树形结构根节点的父级ID */
public static final Long ROOT_PARENT_ID = 0L;
}
@@ -0,0 +1,42 @@
package com.roomroot.jwgl.unit;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 分页查询基类
* <p>
* 继承 {@link BaseQuery},增加分页参数(页码、每页大小)。
* 配合 MyBatis-Plus 的 {@code Page} 对象使用,实现统一分页查询。
* </p>
*
* @author management
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PageQuery extends BaseQuery {
/**
* 当前页码,默认第1页,最小为1
*/
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小为1")
private Integer pageNum;
/**
* 每页记录数,默认20条,最小1条,最大100条
*/
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页最小为1条")
@Max(value = 100, message = "每页最大为100条")
private Integer pageSize;
public PageQuery() {}
public PageQuery(Integer pageNum, Integer pageSize) {
this.pageNum = pageNum;
this.pageSize = pageSize;
}
}
@@ -0,0 +1,69 @@
package com.roomroot.jwgl.unit;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 分页结果封装
* <p>
* 统一分页查询返回结构,包含数据列表、总记录数、当前页码、每页大小及总页数。
* 前端可根据此结构渲染分页组件。
* </p>
*
* @param <T> 数据泛型
* @author management
*/
@Data
public class PageResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 当前页数据列表
*/
private List<T> records;
/**
* 总记录数(满足查询条件的全部记录数,非当前页记录数)
*/
private Long total;
/**
* 当前页码
*/
private Integer pageNum;
/**
* 每页记录数
*/
private Integer pageSize;
/**
* 总页数(由 total 和 pageSize 计算得出)
*/
private Integer pages;
/**
* 无参构造方法
*/
public PageResult() {
}
/**
* 全参构造方法,自动计算总页数
*
* @param records 数据列表
* @param total 总记录数
* @param pageNum 当前页码
* @param pageSize 每页大小
*/
public PageResult(List<T> records, Long total, Integer pageNum, Integer pageSize) {
this.records = records;
this.total = total;
this.pageNum = pageNum;
this.pageSize = pageSize;
this.pages = (int) Math.ceil((double) total / pageSize);
}
}
@@ -0,0 +1,188 @@
package com.roomroot.jwgl.unit;
import lombok.Data;
import java.io.Serializable;
/**
* 统一接口返回结果
* <p>
* 所有Controller接口返回此对象,前端根据code判断请求是否成功。
* 泛型T为实际返回的数据类型,当无数据返回时使用 {@code Result<Void>}。
* </p>
* <p>状态码约定:</p>
* <ul>
* <li>200 - 操作成功</li>
* <li>400 - 请求参数错误</li>
* <li>401 - 未授权</li>
* <li>403 - 禁止访问</li>
* <li>404 - 资源未找到</li>
* <li>500 - 服务器内部错误</li>
* </ul>
*
* @param <T> 返回数据的泛型类型
* @author management
*/
@Data
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 状态码,遵循HTTP状态码语义
*/
private Integer code;
/**
* 提示信息,用于前端展示
*/
private String message;
/**
* 返回数据,可为任意类型
*/
private T data;
/**
* 操作成功 - 无返回数据
*
* @param <T> 泛型
* @return Result对象,code=200
*/
public static <T> Result<T> success() {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("操作成功");
return result;
}
/**
* 操作成功 - 返回数据
*
* @param data 返回的业务数据
* @param <T> 泛型
* @return Result对象,code=200
*/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("操作成功");
result.setData(data);
return result;
}
/**
* 操作成功 - 自定义消息和返回数据
*
* @param message 自定义成功消息
* @param data 返回的业务数据
* @param <T> 泛型
* @return Result对象,code=200
*/
public static <T> Result<T> success(String message, T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage(message);
result.setData(data);
return result;
}
/**
* 操作失败 - 默认错误
*
* @param <T> 泛型
* @return Result对象,code=500
*/
public static <T> Result<T> error() {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage("操作失败");
return result;
}
/**
* 操作失败 - 自定义消息
*
* @param message 错误提示消息
* @param <T> 泛型
* @return Result对象,code=500
*/
public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage(message);
return result;
}
/**
* 操作失败 - 自定义错误码和消息
*
* @param code 业务错误码
* @param message 错误提示消息
* @param <T> 泛型
* @return Result对象
*/
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}
/**
* 请求参数错误
*
* @param message 错误描述
* @param <T> 泛型
* @return Result对象,code=400
*/
public static <T> Result<T> badRequest(String message) {
Result<T> result = new Result<>();
result.setCode(400);
result.setMessage(message);
return result;
}
/**
* 未授权/未登录
*
* @param message 提示消息
* @param <T> 泛型
* @return Result对象,code=401
*/
public static <T> Result<T> unauthorized(String message) {
Result<T> result = new Result<>();
result.setCode(401);
result.setMessage(message);
return result;
}
/**
* 禁止访问/权限不足
*
* @param message 提示消息
* @param <T> 泛型
* @return Result对象,code=403
*/
public static <T> Result<T> forbidden(String message) {
Result<T> result = new Result<>();
result.setCode(403);
result.setMessage(message);
return result;
}
/**
* 资源未找到
*
* @param message 提示消息
* @param <T> 泛型
* @return Result对象,code=404
*/
public static <T> Result<T> notFound(String message) {
Result<T> result = new Result<>();
result.setCode(404);
result.setMessage(message);
return result;
}
}
@@ -0,0 +1,61 @@
package com.roomroot.jwgl.unit;
/**
* 通用状态枚举
* <p>
* 定义系统中通用的启用/禁用/删除状态枚举值。
* 通过枚举统一管理状态码与中文描述,避免代码中散布魔法数字。
* </p>
*
* @author management
*/
public enum StatusEnum {
/** 启用状态:状态码1 */
ENABLED(1, "启用"),
/** 禁用状态:状态码0 */
DISABLED(0, "禁用"),
/** 已删除状态:状态码-1 */
DELETED(-1, "已删除");
/**
* 状态码
*/
private final Integer code;
/**
* 状态描述
*/
private final String desc;
/**
* 枚举构造方法
*
* @param code 状态码
* @param desc 状态描述
*/
StatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取状态码
*
* @return 状态码
*/
public Integer getCode() {
return code;
}
/**
* 获取状态描述
*
* @return 状态描述
*/
public String getDesc() {
return desc;
}
}