diff --git a/.gitea/checker/notify-templates/README.md b/.gitea/checker/notify-templates/README.md
index d81368e..38eee78 100644
--- a/.gitea/checker/notify-templates/README.md
+++ b/.gitea/checker/notify-templates/README.md
@@ -18,7 +18,7 @@ Push 触发 CI 后,按变更类的后缀(`Dto` / `Vo` / `Entity` / `Model`
## 布局约定
-1. **# 【类变更通知】** — 头部 4 项,每项一行 `>**标签: 值**`(加粗,冒号后两空格)
+1. **# 【类变更通知】** — 头部 4 项,每项一行 `>**标签: 值**`(加粗,冒号后两空格);变更对象括号内展示类中文说明(@Schema / Javadoc),无说明则仅类名
2. **## 【对象变更细节】** — 统计行 + 每条变更单行(标签/说明/类型合并)
3. **## 【影响范围】** — 各 ### 小节内,每项一行引用
@@ -27,7 +27,7 @@ Push 触发 CI 后,按变更类的后缀(`Dto` / `Vo` / `Entity` / `Model`
```
# 【类变更通知】
-> **变更对象: ApplyAttendanceChangeDto(Dto)**
+> **变更对象: ApplyAttendanceChangeDto(流程表单 [出勤变更])**
> **修改人: dongzi**
> **时间: 2026-06-07 20:14:35**
> **路径: jnpf-ftb/.../ApplyAttendanceChangeDto.java**
diff --git a/.gitea/checker/notify-templates/dto.md b/.gitea/checker/notify-templates/dto.md
index 8598477..ebcb2d4 100644
--- a/.gitea/checker/notify-templates/dto.md
+++ b/.gitea/checker/notify-templates/dto.md
@@ -10,7 +10,7 @@
```
# 【类变更通知】
-> **变更对象: ApplyAttendanceChangeDto(Dto)**
+> **变更对象: ApplyAttendanceChangeDto(流程表单 [出勤变更])**
> **修改人: dongzi**
> **时间: 2026-06-07 20:14:35**
> **路径: jnpf-ftb/jnpf-ftb-entity/src/main/java/jnpf/model/workflow/dto/ApplyAttendanceChangeDto.java**
diff --git a/.gitea/checker/notify-templates/entity.md b/.gitea/checker/notify-templates/entity.md
index 9ddd1a9..77e8e8a 100644
--- a/.gitea/checker/notify-templates/entity.md
+++ b/.gitea/checker/notify-templates/entity.md
@@ -10,7 +10,7 @@
```
# 【类变更通知】
-> **变更对象: TrainingPositionEntity(Entity)**
+> **变更对象: TrainingPositionEntity(培训岗位)**
> **修改人: 张三**
> **时间: 2026-06-07 14:30:00**
> **路径: jnpf-ftb/jnpf-ftb-entity/src/main/java/jnpf/entity/training/TrainingPositionEntity.java**
diff --git a/.gitea/checker/notify-templates/model.md b/.gitea/checker/notify-templates/model.md
index eabb659..cc93d4d 100644
--- a/.gitea/checker/notify-templates/model.md
+++ b/.gitea/checker/notify-templates/model.md
@@ -10,7 +10,7 @@
```
# 【类变更通知】
-> **变更对象: AttendanceRuleModel(Model)**
+> **变更对象: AttendanceRuleModel(考勤规则)**
> **修改人: 张三**
> **时间: 2026-06-07 14:30:00**
> **路径: jnpf-ftb/jnpf-ftb-entity/src/main/java/jnpf/model/attendance/AttendanceRuleModel.java**
diff --git a/.gitea/checker/notify-templates/vo.md b/.gitea/checker/notify-templates/vo.md
index c5a1c55..02c8a10 100644
--- a/.gitea/checker/notify-templates/vo.md
+++ b/.gitea/checker/notify-templates/vo.md
@@ -10,7 +10,7 @@
```
# 【类变更通知】
-> **变更对象: AttendanceDetailVo(Vo)**
+> **变更对象: AttendanceDetailVo(考勤详情)**
> **修改人: 张三**
> **时间: 2026-06-07 14:30:00**
> **路径: jnpf-ftb/jnpf-ftb-entity/src/main/java/jnpf/model/attendance/vo/AttendanceDetailVo.java**
diff --git a/.gitea/checker/src/main/java/com/autoCheck/analyzer/ClassChangeAnalyzer.java b/.gitea/checker/src/main/java/com/autoCheck/analyzer/ClassChangeAnalyzer.java
index b22ae06..f9e539f 100644
--- a/.gitea/checker/src/main/java/com/autoCheck/analyzer/ClassChangeAnalyzer.java
+++ b/.gitea/checker/src/main/java/com/autoCheck/analyzer/ClassChangeAnalyzer.java
@@ -56,13 +56,17 @@ public class ClassChangeAnalyzer {
String path = changedFile.getRelativePath();
String oldSource = gitScanner.readFileAtCommit(oldSha, path);
+ String classDescription = classDeclParser.extractClassDescription(
+ oldSource, changedFile.getClassName());
+
ClassChangeReport report = new ClassChangeReport(
changedFile.getClassName(),
null,
changedFile.getClassType(),
ClassChangeKind.DELETED,
path,
- config.isDtoEntityConversionEnabled()
+ config.isDtoEntityConversionEnabled(),
+ classDescription
);
impactAnalyzer.analyze(report, endpointIndex, config, repoRoot, oldSource, oldSource);
return report;
@@ -105,13 +109,16 @@ public class ClassChangeAnalyzer {
return null;
}
+ String classDescription = classDeclParser.extractClassDescription(newSource, newClassName);
+
ClassChangeReport report = new ClassChangeReport(
newClassName,
renamed ? oldClassName : null,
changedFile.getClassType(),
changeKind,
newPath,
- config.isDtoEntityConversionEnabled()
+ config.isDtoEntityConversionEnabled(),
+ classDescription
);
fieldChanges.forEach(report::addFieldChange);
impactAnalyzer.analyze(report, endpointIndex, config, repoRoot, newSource, oldSource);
diff --git a/.gitea/checker/src/main/java/com/autoCheck/model/ClassChangeReport.java b/.gitea/checker/src/main/java/com/autoCheck/model/ClassChangeReport.java
index 70e1fc8..2f47c4d 100644
--- a/.gitea/checker/src/main/java/com/autoCheck/model/ClassChangeReport.java
+++ b/.gitea/checker/src/main/java/com/autoCheck/model/ClassChangeReport.java
@@ -12,6 +12,7 @@ public class ClassChangeReport {
private final ClassType classType;
private final ClassChangeKind changeKind;
private final String sourceFile;
+ private final String classDescription;
private final List fieldChanges = new ArrayList<>();
private final List inputImpactEndpoints = new ArrayList<>();
private final List conversionEntities = new ArrayList<>();
@@ -20,13 +21,14 @@ public class ClassChangeReport {
public ClassChangeReport(String className, String oldClassName, ClassType classType,
ClassChangeKind changeKind, String sourceFile,
- boolean conversionCheckEnabled) {
+ boolean conversionCheckEnabled, String classDescription) {
this.className = className;
this.oldClassName = oldClassName;
this.classType = classType;
this.changeKind = changeKind;
this.sourceFile = sourceFile;
this.conversionCheckEnabled = conversionCheckEnabled;
+ this.classDescription = classDescription == null ? "" : classDescription.trim();
}
/** 当前(新)简单类名 */
@@ -62,6 +64,11 @@ public class ClassChangeReport {
return sourceFile;
}
+ /** 类级中文说明(@Schema / 类 Javadoc),无则空串 */
+ public String getClassDescription() {
+ return classDescription;
+ }
+
/** 是否整文件删除 */
public boolean isDeleted() {
return changeKind == ClassChangeKind.DELETED;
diff --git a/.gitea/checker/src/main/java/com/autoCheck/notify/WeComNotifier.java b/.gitea/checker/src/main/java/com/autoCheck/notify/WeComNotifier.java
index f68d9d0..c46b195 100644
--- a/.gitea/checker/src/main/java/com/autoCheck/notify/WeComNotifier.java
+++ b/.gitea/checker/src/main/java/com/autoCheck/notify/WeComNotifier.java
@@ -82,11 +82,20 @@ public class WeComNotifier {
return truncate(sb.toString());
}
+ /** 变更对象行:类名(绿)+ 可选中文说明(灰,整行加粗) */
+ private String formatChangeTarget(ClassChangeReport report) {
+ String name = colorInfo(safe(report.getClassName()));
+ String description = report.getClassDescription();
+ if (description == null || description.isBlank()) {
+ return name;
+ }
+ return name + "(" + colorComment(description) + ")";
+ }
+
/** 头部元信息,每项一行引用(加粗) */
private void appendHeader(StringBuilder sb, ClassChangeReport report,
String modifier, String modifyTime) {
- sb.append(quoteKvBold("变更对象", colorInfo(safe(report.getClassName()))
- + "(" + report.getClassType().getLabel() + ")")).append("\n");
+ sb.append(quoteKvBold("变更对象", formatChangeTarget(report))).append("\n");
sb.append(quoteKvBold("修改人", colorComment(modifier))).append("\n");
sb.append(quoteKvBold("时间", colorComment(modifyTime))).append("\n");
sb.append(quoteKvBold("路径", colorComment(report.getSourceFile()))).append("\n");
diff --git a/.gitea/checker/src/main/java/com/autoCheck/parser/ClassDeclParser.java b/.gitea/checker/src/main/java/com/autoCheck/parser/ClassDeclParser.java
index d01df8a..f8ed0c3 100644
--- a/.gitea/checker/src/main/java/com/autoCheck/parser/ClassDeclParser.java
+++ b/.gitea/checker/src/main/java/com/autoCheck/parser/ClassDeclParser.java
@@ -4,9 +4,16 @@ import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+
+import java.util.Optional;
/**
- * 从 Java 源文件路径或 AST 解析类名(简单名 / 全限定名)。
+ * 从 Java 源文件路径或 AST 解析类名(简单名 / 全限定名)及类级中文说明。
*/
public class ClassDeclParser {
@@ -60,6 +67,100 @@ public class ClassDeclParser {
return inferQualifiedFromPath(relativePath, simpleName);
}
+ /**
+ * 提取类级中文说明:@Schema(description/title) > 类 Javadoc 首段。
+ */
+ public String extractClassDescription(String source, String expectedClassName) {
+ if (source == null || source.isBlank()) {
+ return "";
+ }
+ try {
+ CompilationUnit cu = StaticJavaParser.parse(source);
+ ClassOrInterfaceDeclaration classDecl = findClass(cu, expectedClassName);
+ if (classDecl == null) {
+ return "";
+ }
+ String fromSchema = readSchemaDescription(classDecl);
+ if (!fromSchema.isEmpty()) {
+ return fromSchema;
+ }
+ return extractClassJavadoc(classDecl);
+ } catch (Exception ignored) {
+ return "";
+ }
+ }
+
+ private ClassOrInterfaceDeclaration findClass(CompilationUnit cu, String expectedClassName) {
+ if (expectedClassName != null && !expectedClassName.isBlank()) {
+ for (TypeDeclaration> type : cu.getTypes()) {
+ if (type instanceof ClassOrInterfaceDeclaration) {
+ ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration) type;
+ if (classDecl.getNameAsString().equals(expectedClassName)) {
+ return classDecl;
+ }
+ }
+ }
+ }
+ for (TypeDeclaration> type : cu.getTypes()) {
+ if (type instanceof ClassOrInterfaceDeclaration) {
+ return (ClassOrInterfaceDeclaration) type;
+ }
+ }
+ return null;
+ }
+
+ private String readSchemaDescription(ClassOrInterfaceDeclaration classDecl) {
+ for (AnnotationExpr annotation : classDecl.getAnnotations()) {
+ if (!"Schema".equals(annotation.getNameAsString())) {
+ continue;
+ }
+ String description = readAnnotationStringValue(annotation, "description");
+ if (!description.isEmpty()) {
+ return description;
+ }
+ String title = readAnnotationStringValue(annotation, "title");
+ if (!title.isEmpty()) {
+ return title;
+ }
+ }
+ return "";
+ }
+
+ private String readAnnotationStringValue(AnnotationExpr annotation, String attributeName) {
+ if (annotation.isNormalAnnotationExpr()) {
+ NormalAnnotationExpr normal = annotation.asNormalAnnotationExpr();
+ for (var pair : normal.getPairs()) {
+ if (pair.getNameAsString().equals(attributeName)) {
+ return literalString(pair.getValue());
+ }
+ }
+ return "";
+ }
+ if (annotation.isSingleMemberAnnotationExpr()) {
+ SingleMemberAnnotationExpr single = annotation.asSingleMemberAnnotationExpr();
+ if ("value".equals(attributeName) || "description".equals(attributeName)) {
+ return literalString(single.getMemberValue());
+ }
+ }
+ return "";
+ }
+
+ private String literalString(Expression expression) {
+ if (expression.isStringLiteralExpr()) {
+ return expression.asStringLiteralExpr().getValue().trim();
+ }
+ return "";
+ }
+
+ private String extractClassJavadoc(ClassOrInterfaceDeclaration classDecl) {
+ Optional javadoc = classDecl.getJavadocComment();
+ if (javadoc.isEmpty()) {
+ return "";
+ }
+ String text = javadoc.get().parse().getDescription().toText();
+ return text == null ? "" : text.trim().replaceAll("\\s+", " ");
+ }
+
/** 从 src/main/java/ 后的路径推断 package.className */
public static String inferQualifiedFromPath(String relativePath, String className) {
if (relativePath == null || relativePath.isBlank()) {