feat: 添加代码格式化
This commit is contained in:
@@ -15,56 +15,47 @@ import java.time.format.DateTimeFormatter;
|
||||
@Component
|
||||
public class EnvironmentBanner implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
|
||||
Environment env = event.getApplicationContext().getEnvironment();
|
||||
Environment env = event.getApplicationContext().getEnvironment();
|
||||
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
|
||||
private void printBanner(String appName,
|
||||
String profiles,
|
||||
String port,
|
||||
String jvm,
|
||||
String pid,
|
||||
String time,
|
||||
String gitCommit) {
|
||||
private void printBanner(String appName, String profiles, String port, String jvm, String pid, String time,
|
||||
String gitCommit) {
|
||||
|
||||
String banner = "\n" + "------------------------------------------------------------\n"
|
||||
+ " ✨AI Online Judge✨ - " + appName + "\n" + " Environment : " + profiles + "\n" + " Port : "
|
||||
+ port + "\n" + " Git Commit : " + gitCommit + "\n" + " JVM : " + jvm + "\n"
|
||||
+ " PID : " + pid + "\n" + " Started At : " + time + "\n"
|
||||
+ "------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
|
||||
String banner = "\n" +
|
||||
"------------------------------------------------------------\n" +
|
||||
" ✨AI Online Judge✨ - " + appName + "\n" +
|
||||
" Environment : " + profiles + "\n" +
|
||||
" Port : " + port + "\n" +
|
||||
" Git Commit : " + gitCommit + "\n" +
|
||||
" JVM : " + jvm + "\n" +
|
||||
" PID : " + pid + "\n" +
|
||||
" Started At : " + time + "\n" +
|
||||
"------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.config;
|
||||
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.core.exception.handler.GlobalExceptionHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -8,8 +7,10 @@ import org.springframework.context.annotation.Bean;
|
||||
* 注册为bean,全局异常拦截器
|
||||
*/
|
||||
public class WebAutoConfiguration {
|
||||
@Bean
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
return new GlobalExceptionHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
return new GlobalExceptionHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@ package cn.meowrain.aioj.backend.framework.core.designpattern.chains;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
public interface AbstractChianHandler<T> extends Ordered {
|
||||
/**
|
||||
* 执行责任链逻辑
|
||||
*
|
||||
* @param requestParam 责任链执行入参
|
||||
*/
|
||||
void handle(T requestParam);
|
||||
|
||||
/**
|
||||
* 责任链组件标识
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String mark();
|
||||
/**
|
||||
* 执行责任链逻辑
|
||||
* @param requestParam 责任链执行入参
|
||||
*/
|
||||
void handle(T requestParam);
|
||||
|
||||
/**
|
||||
* 责任链组件标识
|
||||
* @return String
|
||||
*/
|
||||
String mark();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,53 +19,50 @@ import java.util.stream.Collectors;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommonChainContext<T> implements ApplicationContextAware, CommandLineRunner {
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private final Map<String, List<AbstractChianHandler<T>>> abstractChainHandlerMap = new HashMap<>();
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void handler(String mark, T requestParam) {
|
||||
List<AbstractChianHandler<T>> merchantAdminAbstractChainHandlers = abstractChainHandlerMap.get(mark);
|
||||
if (merchantAdminAbstractChainHandlers == null || merchantAdminAbstractChainHandlers.isEmpty()) {
|
||||
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
|
||||
}
|
||||
merchantAdminAbstractChainHandlers.forEach(h -> {
|
||||
h.handle(requestParam);
|
||||
});
|
||||
}
|
||||
private final Map<String, List<AbstractChianHandler<T>>> abstractChainHandlerMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("【责任链路初始化】开始加载并分组所有处理器...");
|
||||
applicationContext.getBeansOfType(AbstractChianHandler.class)
|
||||
.values()
|
||||
.forEach(handler -> {
|
||||
// 打印当前处理器的类名和它所属的 ChainMark
|
||||
String handlerName = handler.getClass().getSimpleName();
|
||||
String mark = handler.mark();
|
||||
log.info(" -> 发现处理器:{},归属链路:{}", handlerName, mark);
|
||||
abstractChainHandlerMap
|
||||
.computeIfAbsent(handler.mark(), k -> new ArrayList<>())
|
||||
.add(handler);
|
||||
});
|
||||
public void handler(String mark, T requestParam) {
|
||||
List<AbstractChianHandler<T>> merchantAdminAbstractChainHandlers = abstractChainHandlerMap.get(mark);
|
||||
if (merchantAdminAbstractChainHandlers == null || merchantAdminAbstractChainHandlers.isEmpty()) {
|
||||
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
|
||||
}
|
||||
merchantAdminAbstractChainHandlers.forEach(h -> {
|
||||
h.handle(requestParam);
|
||||
});
|
||||
}
|
||||
|
||||
// 步骤 2: 对每个链路中的处理器进行排序 (Sort 阶段)
|
||||
abstractChainHandlerMap.forEach((mark, handlers) -> {
|
||||
handlers.sort(Comparator.comparing(Ordered::getOrder));
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("【责任链路初始化】开始加载并分组所有处理器...");
|
||||
applicationContext.getBeansOfType(AbstractChianHandler.class).values().forEach(handler -> {
|
||||
// 打印当前处理器的类名和它所属的 ChainMark
|
||||
String handlerName = handler.getClass().getSimpleName();
|
||||
String mark = handler.mark();
|
||||
log.info(" -> 发现处理器:{},归属链路:{}", handlerName, mark);
|
||||
abstractChainHandlerMap.computeIfAbsent(handler.mark(), k -> new ArrayList<>()).add(handler);
|
||||
});
|
||||
|
||||
// 打印排序后的 Bean 列表
|
||||
String sortedList = handlers.stream()
|
||||
.map(h -> String.format("%s (Order:%d)", h.getClass().getSimpleName(), h.getOrder()))
|
||||
.collect(Collectors.joining(" -> "));
|
||||
// 步骤 2: 对每个链路中的处理器进行排序 (Sort 阶段)
|
||||
abstractChainHandlerMap.forEach((mark, handlers) -> {
|
||||
handlers.sort(Comparator.comparing(Ordered::getOrder));
|
||||
|
||||
log.info(" ✅ 链路 {} 排序完成:{}", mark, sortedList);
|
||||
});
|
||||
// 打印排序后的 Bean 列表
|
||||
String sortedList = handlers.stream()
|
||||
.map(h -> String.format("%s (Order:%d)", h.getClass().getSimpleName(), h.getOrder()))
|
||||
.collect(Collectors.joining(" -> "));
|
||||
|
||||
log.info("【责任链路初始化】所有处理器链已完全就绪。");
|
||||
}
|
||||
log.info(" ✅ 链路 {} 排序完成:{}", mark, sortedList);
|
||||
});
|
||||
|
||||
log.info("【责任链路初始化】所有处理器链已完全就绪。");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@ package cn.meowrain.aioj.backend.framework.core.enums;
|
||||
* 删除枚举
|
||||
*/
|
||||
public enum DelStatusEnum {
|
||||
STATUS_NORMAL("0"),
|
||||
STATUS_DELETE("1");
|
||||
|
||||
private final String code;
|
||||
DelStatusEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
public String code() {
|
||||
return this.code;
|
||||
}
|
||||
STATUS_NORMAL("0"), STATUS_DELETE("1");
|
||||
|
||||
private final String code;
|
||||
|
||||
DelStatusEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.errorcode;
|
||||
|
||||
public enum ErrorCode implements IErrorCode {
|
||||
SUCCESS("0", "ok"),
|
||||
PARAMS_ERROR("40000", "请求参数错误"),
|
||||
NOT_LOGIN_ERROR("40100", "未登录"),
|
||||
NO_AUTH_ERROR("40101", "无权限"),
|
||||
NOT_FOUND_ERROR("40400", "请求数据不存在"),
|
||||
FORBIDDEN_ERROR("40300", "禁止访问"),
|
||||
SYSTEM_ERROR("50000", "系统内部异常"),
|
||||
OPERATION_ERROR("50001", "操作失败"),
|
||||
API_REQUEST_ERROR("50010", "接口调用失败");
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
|
||||
private final String code;
|
||||
SUCCESS("0", "ok"), PARAMS_ERROR("40000", "请求参数错误"), NOT_LOGIN_ERROR("40100", "未登录"), NO_AUTH_ERROR("40101", "无权限"),
|
||||
NOT_FOUND_ERROR("40400", "请求数据不存在"), FORBIDDEN_ERROR("40300", "禁止访问"), SYSTEM_ERROR("50000", "系统内部异常"),
|
||||
OPERATION_ERROR("50001", "操作失败"), API_REQUEST_ERROR("50010", "接口调用失败");
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
private final String message;
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
private final String code;
|
||||
|
||||
@Override
|
||||
public String code() {
|
||||
return code;
|
||||
}
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.errorcode;
|
||||
|
||||
public interface IErrorCode {
|
||||
String code();
|
||||
String message();
|
||||
|
||||
String code();
|
||||
|
||||
String message();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,13 +12,16 @@ import java.util.Optional;
|
||||
@Getter
|
||||
|
||||
public class AbstractException extends RuntimeException {
|
||||
public final String errorCode;
|
||||
public final String errorMessage;
|
||||
|
||||
public AbstractException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message);
|
||||
this.errorCode = errorCode.code();
|
||||
this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null)
|
||||
.orElse(errorCode.message());
|
||||
}
|
||||
public final String errorCode;
|
||||
|
||||
public final String errorMessage;
|
||||
|
||||
public AbstractException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message);
|
||||
this.errorCode = errorCode.code();
|
||||
this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null)
|
||||
.orElse(errorCode.message());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,21 +8,22 @@ import lombok.ToString;
|
||||
* 客户端异常
|
||||
*/
|
||||
@ToString
|
||||
public class ClientException extends AbstractException{
|
||||
public ClientException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public class ClientException extends AbstractException {
|
||||
|
||||
public ClientException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public ClientException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
public ClientException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message) {
|
||||
this(message, null, ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
public ClientException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message) {
|
||||
this(message, null, ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,20 +8,22 @@ import lombok.ToString;
|
||||
* 调用第三方服务异常
|
||||
*/
|
||||
@ToString
|
||||
public class RemoteException extends AbstractException{
|
||||
public RemoteException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public class RemoteException extends AbstractException {
|
||||
|
||||
public RemoteException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
public RemoteException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public RemoteException(String message) {
|
||||
this(message, null, ErrorCode.API_REQUEST_ERROR);
|
||||
}
|
||||
public RemoteException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message) {
|
||||
this(message, null, ErrorCode.API_REQUEST_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,20 +9,21 @@ import lombok.ToString;
|
||||
*/
|
||||
@ToString
|
||||
public class ServiceException extends AbstractException {
|
||||
public ServiceException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(String message) {
|
||||
this(message, null, ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
public ServiceException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public ServiceException(String message) {
|
||||
this(message, null, ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
public ServiceException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public ServiceException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,64 +20,68 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
/**
|
||||
* 捕获所有参数错误,然后统一捕获并且抛出
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
public Result<Void> validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
|
||||
BindingResult bindingResult = ex.getBindingResult();
|
||||
// 收集所有错误字段
|
||||
List<String> errorMessages = bindingResult.getFieldErrors().stream()
|
||||
.map(FieldError::getDefaultMessage).toList();
|
||||
String exceptionMessage = String.join(",", errorMessages);
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionMessage);
|
||||
return Results.paramsValidFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽象异常捕获其
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = {AbstractException.class})
|
||||
public Result<Void> abstractExceptionHandler(HttpServletRequest request,AbstractException ex ) {
|
||||
if (ex.getCause() != null) {
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex, ex.getCause());
|
||||
return Results.failure(ex);
|
||||
}
|
||||
StringBuilder stackTraceBuilder = new StringBuilder();
|
||||
stackTraceBuilder.append(ex.getClass().getName()).append(": ").append(ex.getErrorMessage()).append("\n");
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
for (int i = 0; i < Math.min(5, stackTrace.length); i++) {
|
||||
stackTraceBuilder.append("\tat ").append(stackTrace[i]).append("\n");
|
||||
}
|
||||
log.error("[{}] {} [ex] {} \n\n{}", request.getMethod(), request.getRequestURL().toString(), ex,
|
||||
stackTraceBuilder);
|
||||
return Results.failure(ex);
|
||||
}
|
||||
/**
|
||||
* 捕获所有参数错误,然后统一捕获并且抛出
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
public Result<Void> validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
|
||||
BindingResult bindingResult = ex.getBindingResult();
|
||||
// 收集所有错误字段
|
||||
List<String> errorMessages = bindingResult.getFieldErrors()
|
||||
.stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.toList();
|
||||
String exceptionMessage = String.join(",", errorMessages);
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionMessage);
|
||||
return Results.paramsValidFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未捕获异常
|
||||
*/
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public Result<Void> defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
|
||||
log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
|
||||
return Results.failure();
|
||||
}
|
||||
/**
|
||||
* 抽象异常捕获其
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = { AbstractException.class })
|
||||
public Result<Void> abstractExceptionHandler(HttpServletRequest request, AbstractException ex) {
|
||||
if (ex.getCause() != null) {
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex, ex.getCause());
|
||||
return Results.failure(ex);
|
||||
}
|
||||
StringBuilder stackTraceBuilder = new StringBuilder();
|
||||
stackTraceBuilder.append(ex.getClass().getName()).append(": ").append(ex.getErrorMessage()).append("\n");
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
for (int i = 0; i < Math.min(5, stackTrace.length); i++) {
|
||||
stackTraceBuilder.append("\tat ").append(stackTrace[i]).append("\n");
|
||||
}
|
||||
log.error("[{}] {} [ex] {} \n\n{}", request.getMethod(), request.getRequestURL().toString(), ex,
|
||||
stackTraceBuilder);
|
||||
return Results.failure(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未捕获异常
|
||||
*/
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public Result<Void> defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
|
||||
log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
|
||||
return Results.failure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @return String
|
||||
*/
|
||||
private String getUrl(HttpServletRequest request) {
|
||||
if (!StringUtils.hasText(request.getQueryString())) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
return request.getRequestURL() + "?" + request.getQueryString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @return String
|
||||
*/
|
||||
private String getUrl(HttpServletRequest request) {
|
||||
if (!StringUtils.hasText(request.getQueryString())) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
return request.getRequestURL() + "?" + request.getQueryString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,39 +12,44 @@ import java.io.Serializable;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class Result<T> implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 正确返回码
|
||||
* */
|
||||
public static final String SUCCESS_CODE = "0";
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 返回是否是正确响应
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return SUCCESS_CODE.equals(code);
|
||||
}
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 正确返回码
|
||||
*/
|
||||
public static final String SUCCESS_CODE = "0";
|
||||
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 返回是否是正确响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return SUCCESS_CODE.equals(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回是否是错误响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isFail() {
|
||||
return !isSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回是否是错误响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isFail() {
|
||||
return !isSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.web;
|
||||
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
|
||||
import cn.meowrain.aioj.backend.framework.core.exception.AbstractException;
|
||||
|
||||
@@ -10,70 +9,61 @@ import java.util.Optional;
|
||||
* 构建响应的工具类
|
||||
*/
|
||||
public final class Results {
|
||||
/**
|
||||
* 成功响应,不返回任何信息
|
||||
*
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> success() {
|
||||
return new Result<Void>().setCode(Result.SUCCESS_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应 返回数据
|
||||
*
|
||||
* @param data 返回的响应体信息
|
||||
* @param <T> 泛型
|
||||
* @return {@link Result<T>}
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<T>().setCode(Result.SUCCESS_CODE)
|
||||
.setData(data);
|
||||
}
|
||||
/**
|
||||
* 成功响应,不返回任何信息
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> success() {
|
||||
return new Result<Void>().setCode(Result.SUCCESS_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端请求参数错误
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> paramsValidFailure() {
|
||||
return failure(ErrorCode.PARAMS_ERROR.code(), ErrorCode.PARAMS_ERROR.message());
|
||||
}
|
||||
/**
|
||||
* 成功响应 返回数据
|
||||
* @param data 返回的响应体信息
|
||||
* @param <T> 泛型
|
||||
* @return {@link Result<T>}
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<T>().setCode(Result.SUCCESS_CODE).setData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误默认响应 -- <b>内部错误</b>
|
||||
*
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure() {
|
||||
return new Result<Void>().setCode(ErrorCode.SYSTEM_ERROR.code())
|
||||
.setMessage(ErrorCode.SYSTEM_ERROR.message());
|
||||
}
|
||||
/**
|
||||
* 客户端请求参数错误
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> paramsValidFailure() {
|
||||
return failure(ErrorCode.PARAMS_ERROR.code(), ErrorCode.PARAMS_ERROR.message());
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应 - 接收一个AbstractException,里面定义了错误码和错误信息
|
||||
*
|
||||
* @param exception {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(AbstractException exception) {
|
||||
String errorCode = Optional.ofNullable(exception.getErrorCode()).orElse(ErrorCode.SYSTEM_ERROR.code());
|
||||
String errorMessage = Optional.ofNullable(exception.getMessage()).orElse(ErrorCode.SYSTEM_ERROR.message());
|
||||
/**
|
||||
* 服务端错误默认响应 -- <b>内部错误</b>
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure() {
|
||||
return new Result<Void>().setCode(ErrorCode.SYSTEM_ERROR.code()).setMessage(ErrorCode.SYSTEM_ERROR.message());
|
||||
}
|
||||
|
||||
return new Result<Void>()
|
||||
.setCode(errorCode)
|
||||
.setMessage(errorMessage);
|
||||
}
|
||||
/**
|
||||
* 服务端错误响应 - 接收一个AbstractException,里面定义了错误码和错误信息
|
||||
* @param exception {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(AbstractException exception) {
|
||||
String errorCode = Optional.ofNullable(exception.getErrorCode()).orElse(ErrorCode.SYSTEM_ERROR.code());
|
||||
String errorMessage = Optional.ofNullable(exception.getMessage()).orElse(ErrorCode.SYSTEM_ERROR.message());
|
||||
|
||||
return new Result<Void>().setCode(errorCode).setMessage(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应,自定义错误码和错误信息
|
||||
* @param errorCode {@link String}
|
||||
* @param errorMessage {@link String}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(String errorCode, String errorMessage) {
|
||||
return new Result<Void>().setCode(errorCode).setMessage(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应,自定义错误码和错误信息
|
||||
*
|
||||
* @param errorCode {@link String}
|
||||
* @param errorMessage {@link String}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(String errorCode, String errorMessage) {
|
||||
return new Result<Void>()
|
||||
.setCode(errorCode)
|
||||
.setMessage(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,19 +14,23 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
@EnableConfigurationProperties(AIOJLogPropertiesConfiguration.class)
|
||||
@ConditionalOnProperty(value = "aioj.log.enabled", matchIfMissing = true)
|
||||
public class LogAutoConfiguration {
|
||||
/**
|
||||
* 创建并返回SysLogListener的Bean实例
|
||||
*/
|
||||
@Bean
|
||||
public SysLogListener sysLogListener(AIOJLogPropertiesConfiguration logProperties, RemoteLogService remoteLogService) {
|
||||
return new SysLogListener(remoteLogService, logProperties);
|
||||
}
|
||||
/**
|
||||
* 返回切面类实例
|
||||
* @return {@link SysLogAspect}
|
||||
*/
|
||||
@Bean
|
||||
public SysLogAspect sysLogAspect() {
|
||||
return new SysLogAspect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回SysLogListener的Bean实例
|
||||
*/
|
||||
@Bean
|
||||
public SysLogListener sysLogListener(AIOJLogPropertiesConfiguration logProperties,
|
||||
RemoteLogService remoteLogService) {
|
||||
return new SysLogListener(remoteLogService, logProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回切面类实例
|
||||
* @return {@link SysLogAspect}
|
||||
*/
|
||||
@Bean
|
||||
public SysLogAspect sysLogAspect() {
|
||||
return new SysLogAspect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,17 @@ import java.lang.annotation.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SysLog {
|
||||
/**
|
||||
* 描述
|
||||
* @return {@link String}
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* Spel表达式
|
||||
* @return 日志描述
|
||||
*/
|
||||
String expression() default "";
|
||||
/**
|
||||
* 描述
|
||||
* @return {@link String}
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* Spel表达式
|
||||
* @return 日志描述
|
||||
*/
|
||||
String expression() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -15,17 +15,18 @@ import org.springframework.expression.EvaluationContext;
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogAspect {
|
||||
|
||||
@Around("@annotation(sysLog)")
|
||||
public Object around(ProceedingJoinPoint joinPoint,SysLog sysLog) throws Throwable {
|
||||
String strClassName = joinPoint.getTarget().getClass().getName();
|
||||
String strMethodName = joinPoint.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
String value = sysLog.value();
|
||||
String expression = sysLog.expression();
|
||||
if(StrUtil.isNotBlank(expression)) {
|
||||
// 解析SPEL
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
EvaluationContext context = SysLogUtils.getContext(point.getArgs(), signature.getMethod());
|
||||
}
|
||||
}
|
||||
@Around("@annotation(sysLog)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
|
||||
String strClassName = joinPoint.getTarget().getClass().getName();
|
||||
String strMethodName = joinPoint.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
String value = sysLog.value();
|
||||
String expression = sysLog.expression();
|
||||
if (StrUtil.isNotBlank(expression)) {
|
||||
// 解析SPEL
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
EvaluationContext context = SysLogUtils.getContext(point.getArgs(), signature.getMethod());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,14 +8,17 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@Setter
|
||||
@ConfigurationProperties(AIOJLogPropertiesConfiguration.PREFIX)
|
||||
public class AIOJLogPropertiesConfiguration {
|
||||
public static final String PREFIX = "aioj.log";
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 20000;
|
||||
public static final String PREFIX = "aioj.log";
|
||||
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 20000;
|
||||
|
||||
}
|
||||
|
||||
@@ -12,81 +12,82 @@ import java.time.LocalDateTime;
|
||||
@Data
|
||||
public class SysLog implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private String logType;
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private String logType;
|
||||
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
private String delFlag;
|
||||
}
|
||||
|
||||
@@ -9,12 +9,15 @@ import java.io.Serial;
|
||||
* 系统日志事件类
|
||||
*/
|
||||
public class SysLogEvent extends ApplicationEvent {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 构造方法,根据源SysLog对象创建SysLogEvent
|
||||
*/
|
||||
public SysLogEvent(SysLog source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造方法,根据源SysLog对象创建SysLogEvent
|
||||
*/
|
||||
public SysLogEvent(SysLog source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import java.io.Serializable;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SysLogEventSource extends SysLogEvent implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 参数重写成object
|
||||
*/
|
||||
private Object body;
|
||||
/**
|
||||
* 参数重写成object
|
||||
*/
|
||||
private Object body;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,24 +13,27 @@ import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogListener implements InitializingBean {
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final RemoteLogService remoteLogService;
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final AIOJLogPropertiesConfiguration logProperties;
|
||||
private final RemoteLogService remoteLogService;
|
||||
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveLog(SysLogEvent sysLogEvent){
|
||||
SysLogEventSource source = (SysLogEventSource) sysLogEvent.getSource();
|
||||
SysLog sysLog = new SysLog();
|
||||
BeanUtils.copyProperties(source, sysLog);
|
||||
private final AIOJLogPropertiesConfiguration logProperties;
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveLog(SysLogEvent sysLogEvent) {
|
||||
SysLogEventSource source = (SysLogEventSource) sysLogEvent.getSource();
|
||||
SysLog sysLog = new SysLog();
|
||||
BeanUtils.copyProperties(source, sysLog);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
public class ApplicationLoggerInitializer implements EnvironmentPostProcessor, Ordered {
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package cn.meowrain.aioj.backend.framework.log.utils;
|
||||
import cn.meowrain.aioj.backend.framework.log.event.SysLogEventSource;
|
||||
|
||||
public final class SysLogUtils {
|
||||
public static SysLogEventSource getSysLog() {
|
||||
|
||||
}
|
||||
public static SysLogEventSource getSysLog() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,19 +9,19 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class MybatisPlusAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回MybatisPlusMetaObjectHandler实例,用于审计字段自动填充
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
|
||||
return new MybatisPlusMetaObjectHandler();
|
||||
}
|
||||
/**
|
||||
* 创建并返回MybatisPlusMetaObjectHandler实例,用于审计字段自动填充
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
|
||||
return new MybatisPlusMetaObjectHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,38 +11,41 @@ import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 基础实体抽象类,包含通用实体字段
|
||||
* 基础实体抽象类,包含通用实体字段
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BaseEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@Schema(description = "更新人")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@Schema(description = "更新人")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
@@ -17,54 +17,56 @@ import java.util.Optional;
|
||||
*/
|
||||
@Slf4j
|
||||
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start insert fill ....");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
fillValIfNullByName("createTime", now, metaObject, true);
|
||||
fillValIfNullByName("updateTime", now, metaObject, true);
|
||||
fillValIfNullByName("createBy", getUserName(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start insert fill ....");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 删除标记自动填充
|
||||
fillValIfNullByName("delFlag", DelStatusEnum.STATUS_NORMAL.code(), metaObject, true);
|
||||
}
|
||||
fillValIfNullByName("createTime", now, metaObject, true);
|
||||
fillValIfNullByName("updateTime", now, metaObject, true);
|
||||
fillValIfNullByName("createBy", getUserName(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start update fill ....");
|
||||
fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
}
|
||||
// 删除标记自动填充
|
||||
fillValIfNullByName("delFlag", DelStatusEnum.STATUS_NORMAL.code(), metaObject, true);
|
||||
}
|
||||
|
||||
private void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
|
||||
//如果填充值为空
|
||||
if (fieldVal == null) {
|
||||
return;
|
||||
}
|
||||
// 没有 set 方法
|
||||
if (!metaObject.hasSetter(fieldName)) {
|
||||
return;
|
||||
}
|
||||
// field 类型相同时设置
|
||||
Class<?> getterType = metaObject.getGetterType(fieldName);
|
||||
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
|
||||
metaObject.setValue(fieldName, fieldVal);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start update fill ....");
|
||||
fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
}
|
||||
|
||||
private Object getUserName() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// 匿名接口直接返回
|
||||
if (authentication instanceof AnonymousAuthenticationToken) {
|
||||
return null;
|
||||
}
|
||||
private void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
|
||||
// 如果填充值为空
|
||||
if (fieldVal == null) {
|
||||
return;
|
||||
}
|
||||
// 没有 set 方法
|
||||
if (!metaObject.hasSetter(fieldName)) {
|
||||
return;
|
||||
}
|
||||
// field 类型相同时设置
|
||||
Class<?> getterType = metaObject.getGetterType(fieldName);
|
||||
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
|
||||
metaObject.setValue(fieldName, fieldVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (Optional.ofNullable(authentication).isPresent()) {
|
||||
return authentication.getName();
|
||||
}
|
||||
private Object getUserName() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// 匿名接口直接返回
|
||||
if (authentication instanceof AnonymousAuthenticationToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Optional.ofNullable(authentication).isPresent()) {
|
||||
return authentication.getName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.backend.common.mybaits.plugins;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
|
||||
@@ -16,47 +15,49 @@ import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
/**
|
||||
* * 分页拦截器实现类,用于处理分页查询逻辑
|
||||
* * <p>
|
||||
* * 分页拦截器实现类,用于处理分页查询逻辑 *
|
||||
* <p>
|
||||
* * 当分页大小小于0时自动设置为0,防止全表查询
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PaginationInterceptor extends PaginationInnerInterceptor {
|
||||
/**
|
||||
* 数据库类型
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private DbType dbType;
|
||||
|
||||
/**
|
||||
* 方言实现类
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private IDialect dialect;
|
||||
/**
|
||||
* 数据库类型
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private DbType dbType;
|
||||
|
||||
/**
|
||||
* 方言实现类
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private IDialect dialect;
|
||||
|
||||
public PaginationInterceptor(DbType dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
public PaginationInterceptor(DbType dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public PaginationInterceptor(IDialect dialect) {
|
||||
this.dialect = dialect;
|
||||
}
|
||||
public PaginationInterceptor(IDialect dialect) {
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在执行查询前处理分页参数
|
||||
*/
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
|
||||
ResultHandler resultHandler, BoundSql boundSql) {
|
||||
IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
|
||||
// size 小于 0 直接设置为 0 , 即不查询任何数据
|
||||
if (null != page && page.getSize() < 0) {
|
||||
page.setSize(0);
|
||||
}
|
||||
super.beforeQuery(executor, ms, page, rowBounds, resultHandler, boundSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在执行查询前处理分页参数
|
||||
*/
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
|
||||
IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
|
||||
// size 小于 0 直接设置为 0 , 即不查询任何数据
|
||||
if (null != page && page.getSize() < 0) {
|
||||
page.setSize(0);
|
||||
}
|
||||
super.beforeQuery(executor, ms, page, rowBounds, resultHandler, boundSql);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user