办学质量监测教学评价系统
ageer
2025-05-03 d22d2cb708c6387e01c8b7456b4dd4d5ee8759f8
pom.xml
@@ -20,7 +20,7 @@
        <java.version>17</java.version>
        <mysql.version>8.0.33</mysql.version>
        <mybatis.version>3.5.16</mybatis.version>
        <springdoc.version>2.1.0</springdoc.version>
        <springdoc.version>2.8.5</springdoc.version>
        <therapi-javadoc.version>0.15.0</therapi-javadoc.version>
        <poi.version>5.2.3</poi.version>
        <easyexcel.version>3.2.1</easyexcel.version>
ruoyi-admin/src/main/resources/application.yml
@@ -215,20 +215,25 @@
  publicKey:
  privateKey:
# Swagger配置
swagger:
springdoc:
  api-docs:
    # æ˜¯å¦å¼€å¯æŽ¥å£æ–‡æ¡£
    enabled: true
  #  swagger-ui:
  #    # æŒä¹…化认证数据
  #    persistAuthorization: true
  info:
    # æ ‡é¢˜
    title: '标题:${ruoyi.name}多租户管理系统_接口文档'
    title: '标题:RuoYi-Vue-Plus多租户管理系统_接口文档'
    # æè¿°
    description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
    # ç‰ˆæœ¬
    version: '版本号: ${ruoyi.version}'
    # ä½œè€…信息
    contact:
      name: ageerle
      email: ageerle@163.com
      url: https://gitee.com/ageerle/ruoyi-ai
      name: Lion Li
      email: crazylionli@163.com
      url: https://gitee.com/dromara/RuoYi-Vue-Plus
  components:
    # é‰´æƒæ–¹å¼é…ç½®
    security-schemes:
@@ -236,24 +241,18 @@
        type: APIKEY
        in: HEADER
        name: ${sa-token.token-name}
springdoc:
  api-docs:
    # æ˜¯å¦å¼€å¯æŽ¥å£æ–‡æ¡£
    enabled: true
  swagger-ui:
    # æŒä¹…化认证数据
    persistAuthorization: true
  #这里定义了两个分组,可定义多个,也可以不定义
  group-configs:
    - group: 1.演示模块
      packages-to-scan: org.ruoyi.demo
      packages-to-scan: org.dromara.demo
    - group: 2.通用模块
      packages-to-scan: org.ruoyi.web
      packages-to-scan: org.dromara.web
    - group: 3.系统模块
      packages-to-scan: org.ruoyi.system
      packages-to-scan: org.dromara.system
    - group: 4.代码生成模块
      packages-to-scan: org.ruoyi.generator
      packages-to-scan: org.dromara.generator
    - group: 5.工作流模块
      packages-to-scan: org.dromara.workflow
# é˜²æ­¢XSS攻击
xss:
ruoyi-admin/src/main/resources/static/favicon.ico
ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/SpringDocConfig.java
ÎļþÃû´Ó ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/SwaggerConfig.java ÐÞ¸Ä
@@ -6,7 +6,7 @@
import io.swagger.v3.oas.models.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.doc.config.properties.SwaggerProperties;
import org.ruoyi.common.doc.config.properties.SpringDocProperties;
import org.ruoyi.common.doc.handler.OpenApiHandler;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
@@ -36,26 +36,26 @@
 */
@RequiredArgsConstructor
@AutoConfiguration(before = SpringDocConfiguration.class)
@EnableConfigurationProperties(SwaggerProperties.class)
@EnableConfigurationProperties(SpringDocProperties.class)
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerConfig {
public class SpringDocConfig {
    private final ServerProperties serverProperties;
    @Bean
    @ConditionalOnMissingBean(OpenAPI.class)
    public OpenAPI openApi(SwaggerProperties swaggerProperties) {
    public OpenAPI openApi(SpringDocProperties properties) {
        OpenAPI openApi = new OpenAPI();
        // æ–‡æ¡£åŸºæœ¬ä¿¡æ¯
        SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo();
        SpringDocProperties.InfoProperties infoProperties = properties.getInfo();
        Info info = convertInfo(infoProperties);
        openApi.info(info);
        // æ‰©å±•文档信息
        openApi.externalDocs(swaggerProperties.getExternalDocs());
        openApi.tags(swaggerProperties.getTags());
        openApi.paths(swaggerProperties.getPaths());
        openApi.components(swaggerProperties.getComponents());
        Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet();
        openApi.externalDocs(properties.getExternalDocs());
        openApi.tags(properties.getTags());
        openApi.paths(properties.getPaths());
        openApi.components(properties.getComponents());
        Set<String> keySet = properties.getComponents().getSecuritySchemes().keySet();
        List<SecurityRequirement> list = new ArrayList<>();
        SecurityRequirement securityRequirement = new SecurityRequirement();
        keySet.forEach(securityRequirement::addList);
@@ -65,7 +65,7 @@
        return openApi;
    }
    private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) {
    private Info convertInfo(SpringDocProperties.InfoProperties infoProperties) {
        Info info = new Info();
        info.setTitle(infoProperties.getTitle());
        info.setDescription(infoProperties.getDescription());
ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SpringDocProperties.java
ÎļþÃû´Ó ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SwaggerProperties.java ÐÞ¸Ä
@@ -18,8 +18,8 @@
 * @author Lion Li
 */
@Data
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {
@ConfigurationProperties(prefix = "springdoc")
public class SpringDocProperties {
    /**
     * æ–‡æ¡£åŸºæœ¬ä¿¡æ¯
ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/handler/OpenApiHandler.java
@@ -11,6 +11,7 @@
import io.swagger.v3.oas.models.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.properties.SpringDocConfigProperties;
@@ -154,11 +155,11 @@
        if (!CollectionUtils.isEmpty(tagsStr))
            tagsStr = tagsStr.stream()
                .map(str -> propertyResolverUtils.resolve(str, locale))
                .collect(Collectors.toSet());
                    .map(str -> propertyResolverUtils.resolve(str, locale))
                    .collect(Collectors.toSet());
        if (springdocTags.containsKey(handlerMethod)) {
            Tag tag = springdocTags.get(handlerMethod);
            io.swagger.v3.oas.models.tags.Tag tag = springdocTags.get(handlerMethod);
            tagsStr.add(tag.getName());
            if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
                openAPI.addTagsItem(tag);
@@ -182,7 +183,7 @@
            if (javadocProvider.isPresent()) {
                String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType());
                if (StringUtils.isNotBlank(description)) {
                    Tag tag = new Tag();
                    io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();
                    // è‡ªå®šä¹‰éƒ¨åˆ† ä¿®æ”¹ä½¿ç”¨java注释当tag名
                    List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>());
@@ -203,7 +204,7 @@
        if (!CollectionUtils.isEmpty(tags)) {
            // Existing tags
            List<Tag> openApiTags = openAPI.getTags();
            List<io.swagger.v3.oas.models.tags.Tag> openApiTags = openAPI.getTags();
            if (!CollectionUtils.isEmpty(openApiTags))
                tags.addAll(openApiTags);
            openAPI.setTags(new ArrayList<>(tags));
@@ -211,7 +212,7 @@
        // Handle SecurityRequirement at operation level
        io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser
            .getSecurityRequirements(handlerMethod);
                .getSecurityRequirements(handlerMethod);
        if (securityRequirements != null) {
            if (securityRequirements.length == 0)
                operation.setSecurity(Collections.emptyList());
@@ -222,23 +223,23 @@
        return operation;
    }
    private void buildTagsFromMethod(Method method, Set<Tag> tags, Set<String> tagsStr, Locale locale) {
    private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
        // method tags
        Set<Tags> tagsSet = AnnotatedElementUtils
            .findAllMergedAnnotations(method, Tags.class);
                .findAllMergedAnnotations(method, Tags.class);
        Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream()
            .flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
                .flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
        methodTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class));
        if (!CollectionUtils.isEmpty(methodTags)) {
            tagsStr.addAll(methodTags.stream().map(tag -> propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet()));
            tagsStr.addAll(StreamUtils.toSet(methodTags, tag -> propertyResolverUtils.resolve(tag.name(), locale)));
            List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags);
            addTags(allTags, tags, locale);
        }
    }
    private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<Tag> tags, Locale locale) {
        Optional<Set<Tag>> optionalTagSet = AnnotationsUtils
            .getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
    private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
        Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils
                .getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
        optionalTagSet.ifPresent(tagsSet -> {
            tagsSet.forEach(tag -> {
                tag.name(propertyResolverUtils.resolve(tag.getName(), locale));
ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
org.ruoyi.common.doc.config.SwaggerConfig
org.ruoyi.common.doc.config.SpringDocConfig