From c9774e78c48302af2891f84f679aacd7e9405509 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=A7=8B=E8=BE=9E=E6=9C=AA=E5=AF=92?= <545073804@qq.com>
Date: Fri, 6 Mar 2026 17:32:28 +0800
Subject: [PATCH] =?UTF-8?q?update=20=E9=80=9A=E8=BF=87=E7=B1=BB=E5=8A=A0?=
=?UTF-8?q?=E8=BD=BD=E7=9A=84=E6=96=B9=E5=BC=8F=E4=BC=98=E5=8C=96=20Javado?=
=?UTF-8?q?c=20=E8=A7=A3=E6=9E=90=E5=99=A8=EF=BC=8C=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=A4=9A=E4=B8=AA=20Javadoc=20=E8=A7=A3?=
=?UTF-8?q?=E6=9E=90=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-common/ruoyi-common-doc/pom.xml | 5 -
.../common/doc/config/SpringDocConfig.java | 14 +-
.../core/enhancer/SaTokenJavadocResolver.java | 185 ------------------
.../enhancer/SaTokenMetadataResolver.java | 38 ----
.../AbstractMetadataJavadocResolver.java | 163 +++++++++++++++
.../doc/core/resolver/JavadocResolver.java | 51 +++++
...okenAnnotationMetadataJavadocResolver.java | 163 +++++++++++++++
.../common/doc/handler/OpenApiHandler.java | 25 ++-
8 files changed, 395 insertions(+), 249 deletions(-)
delete mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenJavadocResolver.java
delete mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenMetadataResolver.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/AbstractMetadataJavadocResolver.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/JavadocResolver.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/SaTokenAnnotationMetadataJavadocResolver.java
diff --git a/ruoyi-common/ruoyi-common-doc/pom.xml b/ruoyi-common/ruoyi-common-doc/pom.xml
index 390d34f01..c6199a17c 100644
--- a/ruoyi-common/ruoyi-common-doc/pom.xml
+++ b/ruoyi-common/ruoyi-common-doc/pom.xml
@@ -21,11 +21,6 @@
ruoyi-common-core
-
- cn.dev33
- sa-token-core
-
-
org.springdoc
springdoc-openapi-starter-webmvc-api
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SpringDocConfig.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SpringDocConfig.java
index b22d91139..63b5e9494 100644
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SpringDocConfig.java
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SpringDocConfig.java
@@ -7,8 +7,8 @@ import io.swagger.v3.oas.models.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.doc.config.properties.SpringDocProperties;
-import org.dromara.common.doc.core.enhancer.SaTokenJavadocResolver;
-import org.dromara.common.doc.core.enhancer.SaTokenMetadataResolver;
+import org.dromara.common.doc.core.resolver.JavadocResolver;
+import org.dromara.common.doc.core.resolver.SaTokenAnnotationMetadataJavadocResolver;
import org.dromara.common.doc.handler.OpenApiHandler;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
@@ -87,8 +87,8 @@ public class SpringDocConfig {
SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
Optional> openApiBuilderCustomisers,
Optional> serverBaseUrlCustomisers, Optional javadocProvider,
- SaTokenMetadataResolver saTokenMetadataResolver) {
- return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider, saTokenMetadataResolver);
+ List javadocResolvers) {
+ return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider, javadocResolvers);
}
/**
@@ -116,11 +116,11 @@ public class SpringDocConfig {
}
/**
- * 注册JavaDoc权限解析器
+ * 注册SaToken JavaDoc权限注解解析器
*/
@Bean
- public SaTokenMetadataResolver saTokenJavadocResolver() {
- return new SaTokenJavadocResolver();
+ public JavadocResolver saTokenAnnotationJavadocResolver() {
+ return new SaTokenAnnotationMetadataJavadocResolver();
}
/**
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenJavadocResolver.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenJavadocResolver.java
deleted file mode 100644
index f7c12525c..000000000
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenJavadocResolver.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.dromara.common.doc.core.enhancer;
-
-import cn.dev33.satoken.annotation.SaCheckLogin;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.convert.Convert;
-import io.swagger.v3.oas.models.Operation;
-import org.dromara.common.doc.core.model.SaTokenSecurityMetadata;
-import org.springframework.web.method.HandlerMethod;
-
-import java.lang.annotation.Annotation;
-
-/**
- * 基于JavaDoc的SaToken权限解析器
- *
- * @author echo
- */
-public class SaTokenJavadocResolver implements SaTokenMetadataResolver {
-
- public static final Class SA_CHECK_ROLE_CLASS = SaCheckRole.class;
- public static final Class SA_CHECK_PERMISSION_CLASS = SaCheckPermission.class;
- public static final Class SA_IGNORE_CLASS = SaIgnore.class;
- public static final Class SA_CHECK_LOGIN = SaCheckLogin.class;
-
- /**
- * 核心解析方法
- */
- @Override
- public void resolve(HandlerMethod handlerMethod, Operation operation, SaTokenSecurityMetadata metadata) {
- // 检查是否忽略校验
- if (isIgnore(handlerMethod)) {
- metadata.setIgnore(true);
- return;
- }
-
- // 解析权限校验
- resolvePermissionCheck(handlerMethod, metadata);
-
- // 解析角色校验
- resolveRoleCheck(handlerMethod, metadata);
- }
-
- /**
- * 解析器优先级
- */
- @Override
- public int getOrder() {
- return 100;
- }
-
- /**
- * 判断是否支持当前HandlerMethod
- */
- @Override
- public boolean supports(HandlerMethod handlerMethod) {
- return hasAnnotation(handlerMethod
- .getMethodAnnotation(SA_CHECK_PERMISSION_CLASS)) || hasAnnotation(handlerMethod
- .getMethodAnnotation(SA_CHECK_ROLE_CLASS)) || hasAnnotation(handlerMethod
- .getMethodAnnotation(SA_IGNORE_CLASS)) || hasAnnotation(handlerMethod
- .getBeanType()
- .getAnnotation(SA_CHECK_PERMISSION_CLASS)) || hasAnnotation(handlerMethod
- .getBeanType()
- .getAnnotation(SA_CHECK_ROLE_CLASS)) || hasAnnotation(handlerMethod
- .getBeanType()
- .getAnnotation(SA_IGNORE_CLASS));
- }
-
- @Override
- public String getName() {
- return "SaTokenJavadocResolver";
- }
-
- /**
- * 检查是否忽略校验
- */
- private boolean isIgnore(HandlerMethod handlerMethod) {
- // 检查方法上的注解
- if (hasAnnotation(handlerMethod.getMethodAnnotation(SA_IGNORE_CLASS))) {
- return true;
- }
- // 检查类上的注解
- return hasAnnotation(handlerMethod.getBeanType().getAnnotation(SA_IGNORE_CLASS));
- }
-
- /**
- * 解析权限校验
- */
- private void resolvePermissionCheck(HandlerMethod handlerMethod, SaTokenSecurityMetadata metadata) {
- // 获取方法上的注解
- Annotation methodAnnotation = handlerMethod
- .getMethodAnnotation(SA_CHECK_PERMISSION_CLASS);
- // 获取类上的注解
- Annotation classAnnotation = handlerMethod.getBeanType()
- .getAnnotation(SA_CHECK_PERMISSION_CLASS);
-
- // 解析权限信息
- if (hasAnnotation(methodAnnotation)) {
- resolvePermissionAnnotation(metadata, methodAnnotation);
- }
- if (hasAnnotation(classAnnotation)) {
- resolvePermissionAnnotation(metadata, classAnnotation);
- }
- }
-
- /**
- * 解析权限注解
- */
- private void resolvePermissionAnnotation(SaTokenSecurityMetadata metadata, Annotation annotation) {
- try {
- // 反射获取注解属性
- Object value = getAnnotationValue(annotation, "value");
- Object mode = getAnnotationValue(annotation, "mode");
- Object type = getAnnotationValue(annotation, "type");
- Object orRole = getAnnotationValue(annotation, "orRole");
-
- String[] values = Convert.toStrArray(value);
- String modeStr = mode != null ? mode.toString() : "AND";
- String typeStr = type != null ? type.toString() : "";
- String[] orRoles = Convert.toStrArray(orRole);
-
- metadata.addPermission(values, modeStr, typeStr, orRoles);
- } catch (Exception ignore) {
- // 忽略解析错误
- }
- }
-
- /**
- * 解析角色校验
- */
- private void resolveRoleCheck(HandlerMethod handlerMethod, SaTokenSecurityMetadata metadata) {
- // 获取方法上的注解
- Annotation methodAnnotation = handlerMethod.getMethodAnnotation(SA_CHECK_ROLE_CLASS);
- // 获取类上的注解
- Annotation classAnnotation = handlerMethod.getBeanType()
- .getAnnotation(SA_CHECK_ROLE_CLASS);
-
- // 解析角色信息
- if (hasAnnotation(methodAnnotation)) {
- resolveRoleAnnotation(metadata, methodAnnotation);
- }
- if (hasAnnotation(classAnnotation)) {
- resolveRoleAnnotation(metadata, classAnnotation);
- }
- }
-
- /**
- * 解析角色注解
- */
- private void resolveRoleAnnotation(SaTokenSecurityMetadata metadata, Annotation annotation) {
- try {
- // 反射获取注解属性
- Object value = getAnnotationValue(annotation, "value");
- Object mode = getAnnotationValue(annotation, "mode");
- Object type = getAnnotationValue(annotation, "type");
-
- String[] values = Convert.toStrArray(value);
- String modeStr = mode != null ? mode.toString() : "AND";
- String typeStr = type != null ? type.toString() : "";
-
- metadata.addRole(values, modeStr, typeStr);
- } catch (Exception ignore) {
- // 忽略解析错误
- }
- }
-
- /**
- * 检查注解是否存在
- */
- private boolean hasAnnotation(Annotation annotation) {
- return annotation != null;
- }
-
- /**
- * 获取注解属性值
- */
- private Object getAnnotationValue(Annotation annotation, String attributeName) {
- try {
- return annotation.annotationType().getMethod(attributeName).invoke(annotation);
- } catch (Exception e) {
- return null;
- }
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenMetadataResolver.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenMetadataResolver.java
deleted file mode 100644
index 0b42b23c7..000000000
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/enhancer/SaTokenMetadataResolver.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.dromara.common.doc.core.enhancer;
-
-import io.swagger.v3.oas.models.Operation;
-import org.dromara.common.doc.core.model.SaTokenSecurityMetadata;
-import org.springframework.web.method.HandlerMethod;
-
-/**
- * 权限元数据解析器接口
- *
- * @author echo
- */
-public interface SaTokenMetadataResolver {
-
- /**
- * 解析权限元数据
- */
- void resolve(HandlerMethod handlerMethod, Operation operation, SaTokenSecurityMetadata metadata);
-
- /**
- * 获取解析器优先级
- */
- int getOrder();
-
- /**
- * 判断是否支持当前HandlerMethod
- */
- boolean supports(HandlerMethod handlerMethod);
-
- /**
- * 获取解析器的名称
- *
- * @return 解析器名称
- */
- default String getName() {
- return this.getClass().getSimpleName();
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/AbstractMetadataJavadocResolver.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/AbstractMetadataJavadocResolver.java
new file mode 100644
index 000000000..e9333c044
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/AbstractMetadataJavadocResolver.java
@@ -0,0 +1,163 @@
+package org.dromara.common.doc.core.resolver;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.util.ClassLoaderUtil;
+import io.swagger.v3.oas.models.Operation;
+import org.springframework.web.method.HandlerMethod;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.util.Map;
+import java.util.function.Supplier;
+
+/**
+ * 抽象元数据 Javadoc 解析器
+ *
+ * @param 元数据类型
+ * @author 秋辞未寒
+ */
+public abstract class AbstractMetadataJavadocResolver implements JavadocResolver {
+
+ public static final int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
+ public static final int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
+
+ private final Supplier metadataProvider;
+
+ private final int order;
+
+ public AbstractMetadataJavadocResolver(Supplier metadataProvider) {
+ this(metadataProvider, LOWEST_PRECEDENCE);
+ }
+
+ public AbstractMetadataJavadocResolver(Supplier metadataProvider, int order) {
+ this.metadataProvider = metadataProvider;
+ this.order = order;
+ }
+
+ @Override
+ public int getOrder() {
+ return order;
+ }
+
+ @Override
+ public String resolve(HandlerMethod handlerMethod, Operation operation) {
+ return resolve(handlerMethod, operation, metadataProvider.get());
+ }
+
+ /**
+ * 执行解析并返回解析到的 Javadoc 内容
+ * @param handlerMethod 处理器方法
+ * @param operation Swagger Operation实例
+ * @param metadata 元信息
+ * @return 解析到的 Javadoc 内容
+ */
+ public abstract String resolve(HandlerMethod handlerMethod, Operation operation, M metadata);
+
+ /**
+ * 检查处理器方法所属的类上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationClass 注解类
+ * @return 是否存在注解
+ */
+ public boolean hasClassAnnotation(HandlerMethod handlerMethod,Class extends Annotation> annotationClass){
+ return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationClass);
+ }
+
+ /**
+ * 检查处理器方法所属的类上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationTypeName 注解类名称
+ * @return 是否存在注解
+ */
+ public boolean hasClassAnnotation(HandlerMethod handlerMethod, String annotationTypeName){
+ return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationTypeName);
+ }
+
+ /**
+ * 检查处理器方法上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationClass 注解类
+ * @return 是否存在注解
+ */
+ public boolean hasMethodAnnotation(HandlerMethod handlerMethod,Class extends Annotation> annotationClass){
+ return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationClass);
+ }
+
+ /**
+ * 检查处理器方法上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationTypeName 注解类名称
+ * @return 是否存在注解
+ */
+ public boolean hasMethodAnnotation(HandlerMethod handlerMethod, String annotationTypeName){
+ return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationTypeName);
+ }
+
+ /**
+ * 检查处理器方法上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationClass 注解类
+ * @return 是否存在注解
+ */
+ public boolean hasAnnotation(HandlerMethod handlerMethod,Class extends Annotation> annotationClass){
+ return this.hasClassAnnotation(handlerMethod, annotationClass) || this.hasMethodAnnotation(handlerMethod, annotationClass);
+ }
+
+ /**
+ * 检查处理器方法上是否存在注解
+ * @param handlerMethod 处理器方法
+ * @param annotationTypeName 注解类名称
+ * @return 是否存在注解
+ */
+ public boolean hasAnnotation(HandlerMethod handlerMethod, String annotationTypeName){
+ return this.hasClassAnnotation(handlerMethod, annotationTypeName) || this.hasMethodAnnotation(handlerMethod, annotationTypeName);
+ }
+
+ /**
+ * 获取处理器方法所属类上的注解的值
+ * @param handlerMethod 处理器方法
+ * @param annotationClass 注解类
+ * @return 注解的值
+ */
+ public Map getClassAnnotationValueMap(HandlerMethod handlerMethod, Class extends Annotation> annotationClass) {
+ return AnnotationUtil.getAnnotationValueMap(handlerMethod.getBeanType(), annotationClass);
+ }
+
+ /**
+ * 获取处理器方法所属类上的注解的值
+ * @param handlerMethod 处理器方法
+ * @param annotationClassName 注解类名称
+ * @return 注解的值
+ */
+ @SuppressWarnings("unchecked")
+ public Map getClassAnnotationValueMap(HandlerMethod handlerMethod, String annotationClassName) {
+ Class extends Annotation> annotationClass = (Class extends Annotation>) ClassLoaderUtil.loadClass(annotationClassName, false);
+ return AnnotationUtil.getAnnotationValueMap(handlerMethod.getBeanType(), annotationClass);
+ }
+
+ /**
+ * 获取处理器方法上的注解的值
+ * @param handlerMethod 处理器方法
+ * @param annotationClass 注解类
+ * @return 注解的值
+ */
+ public Map getMethodAnnotationValueMap(HandlerMethod handlerMethod, Class extends Annotation> annotationClass) {
+ return AnnotationUtil.getAnnotationValueMap(handlerMethod.getMethod(), annotationClass);
+ }
+
+ /**
+ * 获取处理器方法所属类上的注解的值
+ * @param handlerMethod 处理器方法
+ * @param annotationClassName 注解类名称
+ * @return 注解的值
+ */
+ @SuppressWarnings("unchecked")
+ public Map getMethodAnnotationValueMap(HandlerMethod handlerMethod, String annotationClassName) {
+ Class extends Annotation> annotationClass = (Class extends Annotation>) ClassLoaderUtil.loadClass(annotationClassName, false);
+ return AnnotationUtil.getAnnotationValueMap(handlerMethod.getMethod(), annotationClass);
+ }
+
+ private Map getAnnotationValueMap(AnnotatedElement annotatedElement, Class extends Annotation> annotationClass) {
+ return AnnotationUtil.getAnnotationValueMap(annotatedElement, annotationClass);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/JavadocResolver.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/JavadocResolver.java
new file mode 100644
index 000000000..1e295b8a1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/JavadocResolver.java
@@ -0,0 +1,51 @@
+package org.dromara.common.doc.core.resolver;
+
+import io.swagger.v3.oas.models.Operation;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.core.Ordered;
+import org.springframework.web.method.HandlerMethod;
+
+/**
+ * Javadoc解析器接口
+ *
+ * @author echo
+ * @author 秋辞未寒
+ */
+public interface JavadocResolver extends Comparable, Ordered {
+
+ /**
+ * 检查解析器是否支持解析 HandlerMethod
+ * @param handlerMethod 处理器方法
+ * @return 是否支持解析
+ */
+ boolean supports(HandlerMethod handlerMethod);
+
+ /**
+ * 执行解析并返回解析到的 Javadoc 内容
+ * @param handlerMethod 处理器方法
+ * @param operation Swagger Operation实例
+ * @return 解析到的 Javadoc 内容
+ */
+ String resolve(HandlerMethod handlerMethod, Operation operation);
+
+ /**
+ * 获取解析器优先级
+ */
+ default int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE;
+ }
+
+ /**
+ * 获取解析器的名称
+ *
+ * @return 解析器名称
+ */
+ default String getName() {
+ return this.getClass().getSimpleName();
+ }
+
+ @Override
+ default int compareTo(@NotNull JavadocResolver o) {
+ return Integer.compare(getOrder(), o.getOrder());
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/SaTokenAnnotationMetadataJavadocResolver.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/SaTokenAnnotationMetadataJavadocResolver.java
new file mode 100644
index 000000000..4fe8933c7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/core/resolver/SaTokenAnnotationMetadataJavadocResolver.java
@@ -0,0 +1,163 @@
+package org.dromara.common.doc.core.resolver;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ClassLoaderUtil;
+import io.swagger.v3.oas.models.Operation;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.doc.core.model.SaTokenSecurityMetadata;
+import org.springframework.web.method.HandlerMethod;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+/**
+ * 基于JavaDoc的SaToken权限解析器
+ *
+ * @author echo
+ * @author 秋辞未寒
+ */
+@SuppressWarnings("unchecked")
+@Slf4j
+public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJavadocResolver {
+
+ /**
+ * 默认元数据提供者,每次解析都会创建一个新的元数据对象
+ */
+ public static final Supplier DEFAULT_METADATA_PROVIDER = SaTokenSecurityMetadata::new;
+
+ private static final String SA_CHECK_ROLE_CLASS_NAME = "cn.dev33.satoken.annotation.SaCheckRole";
+ private static final String SA_CHECK_PERMISSION_CLASS_NAME = "cn.dev33.satoken.annotation.SaCheckPermission";
+ private static final String SA_IGNORE_CLASS_NAME = "cn.dev33.satoken.annotation.SaIgnore";
+ private static final String SA_CHECK_LOGIN_NAME = "cn.dev33.satoken.annotation.SaCheckLogin";
+
+ private static final Class extends Annotation> SA_CHECK_ROLE_CLASS;
+ private static final Class extends Annotation> SA_CHECK_PERMISSION_CLASS;
+ private static final Class extends Annotation> SA_IGNORE_CLASS;
+ private static final Class extends Annotation> SA_CHECK_LOGIN_CLASS;
+
+
+ static {
+ // 通过类加载器去加载注解类Class实例
+ SA_CHECK_ROLE_CLASS = (Class extends Annotation>) ClassLoaderUtil.loadClass(SA_CHECK_ROLE_CLASS_NAME, false);
+ SA_CHECK_PERMISSION_CLASS = (Class extends Annotation>) ClassLoaderUtil.loadClass(SA_CHECK_PERMISSION_CLASS_NAME, false);
+ SA_IGNORE_CLASS = (Class extends Annotation>) ClassLoaderUtil.loadClass(SA_IGNORE_CLASS_NAME, false);
+ SA_CHECK_LOGIN_CLASS = (Class extends Annotation>) ClassLoaderUtil.loadClass(SA_CHECK_LOGIN_NAME, false);
+ if (log.isInfoEnabled()) {
+ log.info("SaTokenAnnotationJavadocResolver init success, load annotation class: {}", List.of(SA_CHECK_ROLE_CLASS, SA_CHECK_PERMISSION_CLASS, SA_IGNORE_CLASS, SA_CHECK_LOGIN_CLASS));
+ }
+ }
+
+ public SaTokenAnnotationMetadataJavadocResolver() {
+ this(DEFAULT_METADATA_PROVIDER);
+ }
+
+ public SaTokenAnnotationMetadataJavadocResolver(Supplier metadataProvider) {
+ super(metadataProvider);
+ }
+
+ public SaTokenAnnotationMetadataJavadocResolver(int order) {
+ this(DEFAULT_METADATA_PROVIDER,order);
+ }
+
+ public SaTokenAnnotationMetadataJavadocResolver(Supplier metadataProvider, int order) {
+ super(metadataProvider,order);
+ }
+
+ @Override
+ public boolean supports(HandlerMethod handlerMethod) {
+ return hasAnnotation(handlerMethod, SA_CHECK_ROLE_CLASS) || hasAnnotation(handlerMethod, SA_CHECK_PERMISSION_CLASS) || hasAnnotation(handlerMethod, SA_IGNORE_CLASS);
+ }
+
+ @Override
+ public String resolve(HandlerMethod handlerMethod, Operation operation, SaTokenSecurityMetadata metadata) {
+ // 检查是否忽略校验
+ if(hasAnnotation(handlerMethod, SA_IGNORE_CLASS_NAME)){
+ metadata.setIgnore(true);
+ return metadata.toMarkdownString();
+ }
+
+ // 解析权限校验
+ resolvePermissionCheck(handlerMethod, metadata);
+
+ // 解析角色校验
+ resolveRoleCheck(handlerMethod, metadata);
+ return metadata.toMarkdownString();
+ }
+
+ /**
+ * 解析权限校验
+ */
+ private void resolvePermissionCheck(HandlerMethod handlerMethod, SaTokenSecurityMetadata metadata) {
+ // 解析获取方法上的注解角色信息
+ if (hasMethodAnnotation(handlerMethod, SA_CHECK_PERMISSION_CLASS_NAME)) {
+ Map annotationValueMap = getMethodAnnotationValueMap(handlerMethod, SA_CHECK_PERMISSION_CLASS);
+ resolvePermissionAnnotation(metadata, annotationValueMap);
+ }
+ // 解析获取类上的注解角色信息
+ if (hasClassAnnotation(handlerMethod, SA_CHECK_PERMISSION_CLASS_NAME)) {
+ Map annotationValueMap = getClassAnnotationValueMap(handlerMethod, SA_CHECK_PERMISSION_CLASS);
+ resolvePermissionAnnotation(metadata, annotationValueMap);
+ }
+ }
+
+ /**
+ * 解析权限注解
+ */
+ private void resolvePermissionAnnotation(SaTokenSecurityMetadata metadata, Map annotationValueMap) {
+ try {
+ // 反射获取注解属性
+ Object value = annotationValueMap.get( "value");
+ Object mode = annotationValueMap.get( "mode");
+ Object type = annotationValueMap.get( "type");
+ Object orRole = annotationValueMap.get( "orRole");
+
+ String[] values = Convert.toStrArray(value);
+ String modeStr = mode != null ? mode.toString() : "AND";
+ String typeStr = type != null ? type.toString() : "";
+ String[] orRoles = Convert.toStrArray(orRole);
+
+ metadata.addPermission(values, modeStr, typeStr, orRoles);
+ } catch (Exception ignore) {
+ // 忽略解析错误
+ }
+ }
+
+ /**
+ * 解析角色校验
+ */
+ private void resolveRoleCheck(HandlerMethod handlerMethod, SaTokenSecurityMetadata metadata) {
+ // 解析获取方法上的注解角色信息
+ if (hasMethodAnnotation(handlerMethod, SA_CHECK_ROLE_CLASS_NAME)) {
+ Map annotationValueMap = getMethodAnnotationValueMap(handlerMethod, SA_CHECK_ROLE_CLASS);
+ resolveRoleAnnotation(metadata, annotationValueMap);
+ }
+ // 解析获取类上的注解角色信息
+ if (hasClassAnnotation(handlerMethod, SA_CHECK_ROLE_CLASS_NAME)) {
+ Map annotationValueMap = getClassAnnotationValueMap(handlerMethod, SA_CHECK_ROLE_CLASS);
+ resolveRoleAnnotation(metadata, annotationValueMap);
+ }
+ }
+
+ /**
+ * 解析角色注解
+ */
+ private void resolveRoleAnnotation(SaTokenSecurityMetadata metadata, Map annotationValueMap) {
+ try {
+ // 反射获取注解属性
+ Object value = annotationValueMap.get("value");
+ Object mode = annotationValueMap.get("mode");
+ Object type = annotationValueMap.get("type");
+
+ String[] values = Convert.toStrArray(value);
+ String modeStr = mode != null ? mode.toString() : "AND";
+ String typeStr = type != null ? type.toString() : "";
+
+ metadata.addRole(values, modeStr, typeStr);
+ } catch (Exception ignore) {
+ // 忽略解析错误
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
index b6e0195d3..32be73227 100644
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
@@ -12,8 +12,7 @@ import io.swagger.v3.oas.models.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.doc.core.enhancer.SaTokenMetadataResolver;
-import org.dromara.common.doc.core.model.SaTokenSecurityMetadata;
+import org.dromara.common.doc.core.resolver.JavadocResolver;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.properties.SpringDocConfigProperties;
@@ -86,9 +85,9 @@ public class OpenApiHandler extends OpenAPIService {
private final PropertyResolverUtils propertyResolverUtils;
/**
- * 权限元数据解析器接口
+ * Javadoc解析器接口
*/
- private final SaTokenMetadataResolver saTokenJavadocResolver;
+ private final List javadocResolvers;
/**
* The javadoc provider.
@@ -131,7 +130,7 @@ public class OpenApiHandler extends OpenAPIService {
Optional> openApiBuilderCustomizers,
Optional> serverBaseUrlCustomizers,
Optional javadocProvider,
- SaTokenMetadataResolver saTokenJavadocResolver) {
+ List javadocResolvers) {
super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
if (openAPI.isPresent()) {
this.openAPI = openAPI.get();
@@ -148,7 +147,7 @@ public class OpenApiHandler extends OpenAPIService {
this.openApiBuilderCustomisers = openApiBuilderCustomizers;
this.serverBaseUrlCustomizers = serverBaseUrlCustomizers;
this.javadocProvider = javadocProvider;
- this.saTokenJavadocResolver = saTokenJavadocResolver;
+ this.javadocResolvers = javadocResolvers == null ? new ArrayList<>() : javadocResolvers;
if (springDocConfigProperties.isUseFqn())
TypeNameResolver.std.setUseFqn(true);
}
@@ -235,16 +234,14 @@ public class OpenApiHandler extends OpenAPIService {
if (StringUtils.isNotBlank(description)){
operation.setSummary(summary);
}
- // 调用SaToken解析器提取JavaDoc中的权限信息
- if (saTokenJavadocResolver.supports(handlerMethod)) {
- SaTokenSecurityMetadata metadata = new SaTokenSecurityMetadata();
- saTokenJavadocResolver.resolve(handlerMethod, operation, metadata);
- String markdownString = metadata.toMarkdownString();
- if (StringUtils.isNotBlank(markdownString)) {
- description = description + markdownString;
+ // 调用解析器提取JavaDoc中的权限信息
+ if (javadocResolvers != null && !javadocResolvers.isEmpty()) {
+ for (JavadocResolver resolver : javadocResolvers) {
+ String desc = resolver.resolve(handlerMethod, operation);
+ description = description + desc;
}
+ operation.setDescription(description);
}
- operation.setDescription(description);
}
return operation;