From 3eddcf59ad978b99df6304a3836e736c214f5b06 Mon Sep 17 00:00:00 2001 From: ayi <2294931964@qq.com> Date: Fri, 21 Nov 2025 15:28:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=88=87=E9=9D=A2=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 9 +- .settings/org.eclipse.core.resources.prefs | 2 + .settings/org.eclipse.jdt.core.prefs | 1 + .settings/org.eclipse.m2e.core.prefs | 4 + .vscode/java-formatter.xml | 3 + .vscode/settings.json | 5 +- pom.xml | 24 +++++ xiaoyi-auth/pom.xml | 9 ++ .../auth/controller/TestController.java | 25 +++++ .../src/main/resources/application-dev.yml | 6 ++ .../src/main/resources/application.yml | 8 +- xiaoyi-framework/pom.xml | 1 + xiaoyi-framework/xiaoyi-common/pom.xml | 16 +++ .../src/main/java/top/crushtj/.gitkeep | 0 .../framework/common/utils/JsonUtils.java | 36 +++++++ .../pom.xml | 28 +++++ .../operationlog/ApiOperationLogAspect.java | 100 ++++++++++++++++++ .../operationlog/aspect/ApiOperationLog.java | 26 +++++ .../ApiOperationLogAutoConfiguration.java | 15 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + 20 files changed, 306 insertions(+), 13 deletions(-) create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 xiaoyi-auth/src/main/java/top/crushtj/xiaoyishu/auth/controller/TestController.java create mode 100644 xiaoyi-auth/src/main/resources/application-dev.yml delete mode 100644 xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/.gitkeep create mode 100644 xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/framework/common/utils/JsonUtils.java create mode 100644 xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/pom.xml create mode 100644 xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/ApiOperationLogAspect.java create mode 100644 xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/aspect/ApiOperationLog.java create mode 100644 xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/config/ApiOperationLogAutoConfiguration.java create mode 100644 xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/.gitignore b/.gitignore index 3c1b776..af96345 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,7 @@ target/ .kotlin ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea *.iws *.iml *.ipr @@ -18,7 +15,6 @@ target/ .classpath .factorypath .project -.settings .springBeans .sts4-cache @@ -34,4 +30,5 @@ build/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store +/.idea/ diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..4e8eac9 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1 @@ +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning \ No newline at end of file diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.vscode/java-formatter.xml b/.vscode/java-formatter.xml index ba43e02..9901b6b 100644 --- a/.vscode/java-formatter.xml +++ b/.vscode/java-formatter.xml @@ -376,5 +376,8 @@ + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 82c8f32..735a4f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "editor.accessibilitySupport": "auto", "editor.fontFamily": "JetBrains Mono", "java.compile.nullAnalysis.mode": "automatic", - "java.configuration.updateBuildConfiguration": "interactive", - "java.format.settings.url": ".vscode/java-formatter.xml" + "java.configuration.updateBuildConfiguration": "automatic", + "java.format.settings.url": ".vscode/java-formatter.xml", + "commentTranslate.targetLanguage": "zh-CN" } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2e7f7c1..0c0a8fd 100644 --- a/pom.xml +++ b/pom.xml @@ -38,11 +38,23 @@ 3.0.2 2022.0.0.0 2022.0.0 + 2.16.1 + + top.crushtj + xiaoyi-common + ${revision} + + + + top.crushtj + xiaoyi-spring-boot-starter-biz-operationlog + ${revision} + org.springframework.boot @@ -77,6 +89,18 @@ ${lombok.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + diff --git a/xiaoyi-auth/pom.xml b/xiaoyi-auth/pom.xml index a365dac..673794d 100644 --- a/xiaoyi-auth/pom.xml +++ b/xiaoyi-auth/pom.xml @@ -18,6 +18,15 @@ 小壹书:认证服务(负责处理用户登录、注册、账号注销等) + + top.crushtj + xiaoyi-common + + + + top.crushtj + xiaoyi-spring-boot-starter-biz-operationlog + org.springframework.boot spring-boot-starter-web diff --git a/xiaoyi-auth/src/main/java/top/crushtj/xiaoyishu/auth/controller/TestController.java b/xiaoyi-auth/src/main/java/top/crushtj/xiaoyishu/auth/controller/TestController.java new file mode 100644 index 0000000..71fc4e5 --- /dev/null +++ b/xiaoyi-auth/src/main/java/top/crushtj/xiaoyishu/auth/controller/TestController.java @@ -0,0 +1,25 @@ +package top.crushtj.xiaoyishu.auth.controller; + +import org.springframework.web.bind.annotation.RestController; +import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog; +import top.crushtj.framework.common.response.Response; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * + * @Title: TestController + * @Description: 测试控制器 + * @Author: ayi + * @Date: 2025/11/21 + */ + +@RestController +public class TestController { + + @GetMapping("/test") + @ApiOperationLog(description = "测试接口") + public Response testController() { + return Response.success("Hello World!"); + } + +} diff --git a/xiaoyi-auth/src/main/resources/application-dev.yml b/xiaoyi-auth/src/main/resources/application-dev.yml new file mode 100644 index 0000000..fce073c --- /dev/null +++ b/xiaoyi-auth/src/main/resources/application-dev.yml @@ -0,0 +1,6 @@ +spring: + application: + name: xiaoyi-auth + output: + ansi: + enabled: always \ No newline at end of file diff --git a/xiaoyi-auth/src/main/resources/application.yml b/xiaoyi-auth/src/main/resources/application.yml index fce073c..ec870c1 100644 --- a/xiaoyi-auth/src/main/resources/application.yml +++ b/xiaoyi-auth/src/main/resources/application.yml @@ -1,6 +1,4 @@ spring: - application: - name: xiaoyi-auth - output: - ansi: - enabled: always \ No newline at end of file + profiles: + active: + - dev \ No newline at end of file diff --git a/xiaoyi-framework/pom.xml b/xiaoyi-framework/pom.xml index dc271da..1c5236f 100644 --- a/xiaoyi-framework/pom.xml +++ b/xiaoyi-framework/pom.xml @@ -17,6 +17,7 @@ xiaoyi-common + xiaoyi-spring-boot-starter-biz-operationlog \ No newline at end of file diff --git a/xiaoyi-framework/xiaoyi-common/pom.xml b/xiaoyi-framework/xiaoyi-common/pom.xml index ffff923..f613212 100644 --- a/xiaoyi-framework/xiaoyi-common/pom.xml +++ b/xiaoyi-framework/xiaoyi-common/pom.xml @@ -20,6 +20,22 @@ org.projectlombok lombok + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-core + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + \ No newline at end of file diff --git a/xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/.gitkeep b/xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/framework/common/utils/JsonUtils.java b/xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/framework/common/utils/JsonUtils.java new file mode 100644 index 0000000..e32b4b9 --- /dev/null +++ b/xiaoyi-framework/xiaoyi-common/src/main/java/top/crushtj/framework/common/utils/JsonUtils.java @@ -0,0 +1,36 @@ +package top.crushtj.framework.common.utils; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import lombok.SneakyThrows; + +/** + * + * @Title: JsonUtils + * @Description: JSON 工具类 + * @Author: ayi + * @Date: 2025/11/21 + */ +public class JsonUtils { + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + static { + OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + OBJECT_MAPPER.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化问题 + } + + /** + * 将对象转换为 JSON 字符串 + * + * @param obj 要转换的对象 + * @return JSON 字符串 + */ + @SneakyThrows + public static String toJsonString(Object obj) { + return OBJECT_MAPPER.writeValueAsString(obj); + } +} diff --git a/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/pom.xml b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/pom.xml new file mode 100644 index 0000000..5a337a8 --- /dev/null +++ b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + top.crushtj + xiaoyi-framework + ${revision} + + + xiaoyi-spring-boot-starter-biz-operationlog + ${project.artifactId} + 平台基础设施层:操作日志记录器 + + + + top.crushtj + xiaoyi-common + + + + org.springframework.boot + spring-boot-starter-aop + + + + \ No newline at end of file diff --git a/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/ApiOperationLogAspect.java b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/ApiOperationLogAspect.java new file mode 100644 index 0000000..0f2c6af --- /dev/null +++ b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/ApiOperationLogAspect.java @@ -0,0 +1,100 @@ +package top.crushtj.framework.biz.operationlog; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; + +import lombok.extern.slf4j.Slf4j; +import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog; +import top.crushtj.framework.common.utils.JsonUtils; + +@Slf4j +@Aspect +public class ApiOperationLogAspect { + /** 以自定义 @ApiOperationLog 注解为切点,凡是添加 @ApiOperationLog 的方法,都会执行环绕中的代码 */ + @Pointcut("@annotation(top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog)") + public void apiOperationLog() { + } + + /** + * 环绕 + * + * @param joinPoint + * @return + * @throws Throwable + */ + @Around("apiOperationLog()") + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + // 请求开始时间 + long startTime = System.currentTimeMillis(); + + // 获取被请求的类和方法 + String className = joinPoint.getTarget() + .getClass() + .getSimpleName(); + String methodName = joinPoint.getSignature() + .getName(); + + // 请求入参 + Object[] args = joinPoint.getArgs(); + // 入参转 JSON 字符串 + String argsJsonStr = Arrays.stream(args) + .map(toJsonStr()) + .collect(Collectors.joining(", ")); + + // 功能描述信息 + String description = getApiOperationLogDescription(joinPoint); + + // 打印请求相关参数 + log.info("====== 请求开始: [{}], 入参: {}, 请求类: {}, 请求方法: {} =================================== ", description, + argsJsonStr, className, methodName); + + // 执行切点方法 + Object result = joinPoint.proceed(); + + // 执行耗时 + long executionTime = System.currentTimeMillis() - startTime; + + // 打印出参等相关信息 + log.info("====== 请求结束: [{}], 耗时: {}ms, 出参: {} =================================== ", description, executionTime, + JsonUtils.toJsonString(result)); + + return result; + } + + /** + * 获取注解的描述信息 + * + * @param joinPoint + * @return + */ + private String getApiOperationLogDescription(ProceedingJoinPoint joinPoint) { + // 1. 从 ProceedingJoinPoint 获取 MethodSignature + MethodSignature signature = (MethodSignature)joinPoint.getSignature(); + + // 2. 使用 MethodSignature 获取当前被注解的 Method + Method method = signature.getMethod(); + + // 3. 从 Method 中提取 LogExecution 注解 + ApiOperationLog apiOperationLog = method.getAnnotation(ApiOperationLog.class); + + // 4. 从 LogExecution 注解中获取 description 属性 + return apiOperationLog.description(); + } + + /** + * 转 JSON 字符串 + * + * @return + */ + private Function toJsonStr() { + return JsonUtils::toJsonString; + } +} diff --git a/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/aspect/ApiOperationLog.java b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/aspect/ApiOperationLog.java new file mode 100644 index 0000000..c6583da --- /dev/null +++ b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/aspect/ApiOperationLog.java @@ -0,0 +1,26 @@ +package top.crushtj.framework.biz.operationlog.aspect; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @Title: ApiOperationLog + * @Description: 自定义注解,用于标记需要记录操作日志的方法 + * @Author: ayi + * @Date: 2025/11/21 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Documented +public @interface ApiOperationLog { + /** + * API 功能描述 + * + * @return + */ + String description() default ""; +} diff --git a/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/config/ApiOperationLogAutoConfiguration.java b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/config/ApiOperationLogAutoConfiguration.java new file mode 100644 index 0000000..aeb7931 --- /dev/null +++ b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/java/top/crushtj/framework/biz/operationlog/config/ApiOperationLogAutoConfiguration.java @@ -0,0 +1,15 @@ +package top.crushtj.framework.biz.operationlog.config; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; + +import top.crushtj.framework.biz.operationlog.ApiOperationLogAspect; + +@AutoConfiguration +public class ApiOperationLogAutoConfiguration { + + @Bean + public ApiOperationLogAspect apiOperationLogAspect() { + return new ApiOperationLogAspect(); + } +} diff --git a/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..c15c1d4 --- /dev/null +++ b/xiaoyi-framework/xiaoyi-spring-boot-starter-biz-operationlog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +top.crushtj.framework.biz.operationlog.config.ApiOperationLogAutoConfiguration \ No newline at end of file