e752b8834e034957ff9ffdc33eb8b3f8ee15c8ed..a2d8705903ec73b585eaca24f013e081929db953
昨天 maven
yys
a2d870 对比 | 目录
昨天 maven
yys 增加接口文档
3b9d4c 对比 | 目录
已修改4个文件
已添加4个文件
597 ■■■■■ 文件已修改
ruoyi-admin/pom.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java 181 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-druid.yml.example 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml.example 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/logback.xml.example 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml
@@ -16,7 +16,12 @@
    </description>
    <dependencies>
        <!-- ruoyi-springboot2 / swagger knife4j é…ç½® -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>
        <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java
@@ -1,64 +1,157 @@
package com.ruoyi.web.core.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.security.SecurityScheme.In;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.providers.JavadocProvider;
import org.springdoc.core.service.OpenAPIService;
import org.springdoc.core.service.SecurityService;
import org.springdoc.core.utils.PropertyResolverUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
/**
 * Swagger2的接口配置
 *
 * @author ruoyi
 * Swagger è‡ªåŠ¨é…ç½®ç±»ï¼ŒåŸºäºŽ OpenAPI + Springdoc å®žçŽ°ã€‚
 *
 * å‹æƒ…提示:
 * 1. Springdoc æ–‡æ¡£åœ°å€ï¼š<a href="https://github.com/springdoc/springdoc-openapi">仓库</a>
 * 2. Swagger è§„范,于 2015 æ›´åä¸º OpenAPI è§„范,本质是一个东西
 *
 */
// @AutoConfiguration
@Configuration
@ConditionalOnClass({OpenAPI.class})
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // è®¾ç½®ä¸º false æ—¶ï¼Œç¦ç”¨
public class SwaggerConfig
{
    /** ç³»ç»ŸåŸºç¡€é…ç½® */
    @Autowired
    private RuoYiConfig ruoyiConfig;
    /**
     * è‡ªå®šä¹‰çš„ OpenAPI å¯¹è±¡
     */
    public static final String HEADER_TENANT_ID = "tenant-id";
    // ========== å…¨å±€ OpenAPI é…ç½® ==========
    @Bean
    public OpenAPI customOpenApi()
    {
        return new OpenAPI().components(new Components()
            // è®¾ç½®è®¤è¯çš„请求头
            .addSecuritySchemes("apikey", securityScheme()))
            .addSecurityItem(new SecurityRequirement().addList("apikey"))
            .info(getApiInfo());
    public OpenAPI createApi(SwaggerProperties properties) {
        Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes();
        OpenAPI openAPI = new OpenAPI()
                // æŽ¥å£ä¿¡æ¯
                .info(buildInfo(properties))
                // æŽ¥å£å®‰å…¨é…ç½®
                .components(new Components().securitySchemes(securitySchemas))
                .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
        securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key)));
        return openAPI;
    }
    @Bean
    public SecurityScheme securityScheme()
    {
        return new SecurityScheme()
            .type(SecurityScheme.Type.APIKEY)
            .name("Authorization")
            .in(SecurityScheme.In.HEADER)
            .scheme("Bearer");
    }
    /**
     * æ·»åŠ æ‘˜è¦ä¿¡æ¯
     * API æ‘˜è¦ä¿¡æ¯
     */
    public Info getApiInfo()
    {
    private Info buildInfo(SwaggerProperties properties) {
        return new Info()
            // è®¾ç½®æ ‡é¢˜
            .title("标题:若依管理系统_接口文档")
            // æè¿°
            .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
            // ä½œè€…信息
            .contact(new Contact().name(ruoyiConfig.getName()))
            // ç‰ˆæœ¬
            .version("版本号:" + ruoyiConfig.getVersion());
                .title(properties.getTitle())
                .description(properties.getDescription())
                .version(properties.getVersion())
                .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail()))
                .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl()));
    }
}
    /**
     * å®‰å…¨æ¨¡å¼ï¼Œè¿™é‡Œé…ç½®é€šè¿‡è¯·æ±‚头 Authorization ä¼ é€’ token å‚æ•°
     */
    private Map<String, SecurityScheme> buildSecuritySchemes() {
        Map<String, SecurityScheme> securitySchemes = new HashMap<>();
        SecurityScheme securityScheme = new SecurityScheme()
                .type(SecurityScheme.Type.APIKEY) // ç±»åž‹
                .name(HttpHeaders.AUTHORIZATION) // è¯·æ±‚头的 name
                .in(SecurityScheme.In.HEADER); // token æ‰€åœ¨ä½ç½®
        securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme);
        return securitySchemes;
    }
    /**
     * è‡ªå®šä¹‰ OpenAPI å¤„理器
     */
    @Bean
    public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
                                         SecurityService securityParser,
                                         SpringDocConfigProperties springDocConfigProperties,
                                         PropertyResolverUtils propertyResolverUtils,
                                         Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
                                         Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
                                         Optional<JavadocProvider> javadocProvider) {
        return new OpenAPIService(openAPI, securityParser, springDocConfigProperties,
                propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
    }
    // ========== åˆ†ç»„ OpenAPI é…ç½® ==========
    /**
     * æ‰€æœ‰æ¨¡å—çš„ API åˆ†ç»„
     */
    @Bean
    public GroupedOpenApi allGroupedOpenApi() {
        return buildGroupedOpenApi("all", "");
    }
    public static GroupedOpenApi buildGroupedOpenApi(String group) {
        return buildGroupedOpenApi(group, group);
    }
    public static GroupedOpenApi buildGroupedOpenApi(String group, String path) {
        return GroupedOpenApi.builder()
                .group(group)
                .pathsToMatch("/admin-api/" + path + "/**", "/app-api/" + path + "/**", "/**")
                .addOperationCustomizer((operation, handlerMethod) -> operation
                        // .addParametersItem(buildTenantHeaderParameter())
                        .addParametersItem(buildSecurityHeaderParameter()))
                .build();
    }
    /**
     * æž„建 Authorization è®¤è¯è¯·æ±‚头参数
     *
     * è§£å†³ Knife4j <a href="https://gitee.com/xiaoym/knife4j/issues/I69QBU">Authorize æœªç”Ÿæ•ˆï¼Œè¯·æ±‚header里未包含参数</a>
     *
     * @return è®¤è¯å‚æ•°
     */
    private static Parameter buildSecurityHeaderParameter() {
        return new Parameter()
                .name(HttpHeaders.AUTHORIZATION) // header å
                .description("认证 Token") // æè¿°
                .in(String.valueOf(SecurityScheme.In.HEADER)) // è¯·æ±‚ header
                .schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("认证 Token")); // é»˜è®¤ï¼šä½¿ç”¨ç”¨æˆ·ç¼–号为 1
    }
    /**
     * æž„建 Tenant ç§Ÿæˆ·ç¼–号请求头参数
     * @return å¤šç§Ÿæˆ·å‚æ•°
     */
/*   private static Parameter buildTenantHeaderParameter() {
    return new Parameter()
        .name(HEADER_TENANT_ID) // header å
        .description("租户编号") // æè¿°
        .in(String.valueOf(SecurityScheme.In.HEADER)) // è¯·æ±‚ header
        .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("租户编号")); // é»˜è®¤ï¼šä½¿ç”¨ç§Ÿæˆ·ç¼–号为 1
  } */
}
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.web.core.config;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
 * @author :yys
 * @date : 2025/8/22 9:16
 */
/**
 * Swagger é…ç½®å±žæ€§*/
@ConfigurationProperties("aixin.swagger")
@Data
public class SwaggerProperties {
    /**
     * æ ‡é¢˜
     */
    @NotEmpty(message = "标题不能为空")
    private String title;
    /**
     * æè¿°
     */
    @NotEmpty(message = "描述不能为空")
    private String description;
    /**
     * ä½œè€…
     */
    @NotEmpty(message = "作者不能为空")
    private String author;
    /**
     * ç‰ˆæœ¬
     */
    @NotEmpty(message = "版本不能为空")
    private String version;
    /**
     * url
     */
    @NotEmpty(message = "扫描的 package ä¸èƒ½ä¸ºç©º")
    private String url;
    /**
     * email
     */
    @NotEmpty(message = "扫描的 email ä¸èƒ½ä¸ºç©º")
    private String email;
    /**
     * license
     */
    @NotEmpty(message = "扫描的 license ä¸èƒ½ä¸ºç©º")
    private String license;
    /**
     * license-url
     */
    @NotEmpty(message = "扫描的 license-url ä¸èƒ½ä¸ºç©º")
    private String licenseUrl;
}
ruoyi-admin/src/main/resources/application-druid.yml.example
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
# æ•°æ®æºé…ç½®
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        #        driverClassName: com.mysql.cj.jdbc.Driver     # mysql驱动
        driverClassName: org.postgresql.Driver
        druid:
            # ä¸»åº“数据源
            master:
                #                mysql
                #                url: jdbc:mysql://124.220.0.228:3300/ruoyi-java?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                #                pg
                #                url: jdbc:postgresql://localhost:5433/ruoyi-zd
                url: jdbc:postgresql://114.132.189.42:5432/zd_production-demo
                username: postgres
                password: bYD#nM+-BiLb
            # ä»Žåº“数据源
            slave:
                # ä»Žæ•°æ®æºå¼€å…³/默认关闭
                enabled: false
                url:
                username:
                password:
            # åˆå§‹è¿žæŽ¥æ•°
            initialSize: 5
            # æœ€å°è¿žæŽ¥æ± æ•°é‡
            minIdle: 10
            # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
            maxActive: 20
            # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
            maxWait: 60000
            # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
            connectTimeout: 30000
            # é…ç½®ç½‘络超时时间
            socketTimeout: 60000
            # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
            minEvictableIdleTimeMillis: 300000
            # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
            validationQuery: SELECT VERSION()
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            webStatFilter:
                enabled: true
            statViewServlet:
                enabled: true
                # è®¾ç½®ç™½åå•,不填则允许所有访问
                allow:
                url-pattern: /druid/*
                # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
                login-username: ruoyi
                login-password: 123456
            filter:
                stat:
                    enabled: true
                    # æ…¢SQL记录
                    log-slow-sql: true
                    slow-sql-millis: 1000
                    merge-sql: true
                wall:
                    config:
                        multi-statement-allow: true
    data:
        # redis é…ç½®
        redis:
            # åœ°å€
            host: 127.0.0.1
            # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
            port: 6379
            # æ•°æ®åº“索引
            database: 0
            # å¯†ç 
            #            password: root2022!
            #      password: 123456
            password:
            # è¿žæŽ¥è¶…æ—¶æ—¶é—´
            timeout: 10s
            lettuce:
                pool:
                    # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
                    min-idle: 0
                    # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
                    max-idle: 8
                    # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
                    max-active: 8
                    # #连接池最大阻塞等待时间(使用负值表示没有限制)
                    max-wait: -1ms
# å…¬å¸æœåС噍 minio
minio:
    #    endpoint: http://114.132.189.42/
    #    port: 7019
    #    secure: false
    #    accessKey: admin
    #    secretKey: 12345678
    #    preview-expiry: 24 # é¢„览地址默认24小时
    #    default-bucket: ruoyi-zd #  é»˜è®¤å­˜å‚¨æ¡¶
    endpoint: 127.0.0.1
    port: 9002
    secure: false
    accessKey: admin
    secretKey: 12345678
    preview-expiry: 24 # é¢„览地址默认24小时
    default-bucket: ruoyi-zd #  é»˜è®¤å­˜å‚¨æ¡¶
ruoyi-admin/src/main/resources/application.yml.example
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,140 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/Backup/桌面/download
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 7016
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: debug
    org.springframework: warn
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 10
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 1
# Spring配置
spring:
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  profiles:
    active: druid
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 10MB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 20MB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  flyway:
    enabled: false
    baseline-on-migrate: true
    baseline-version: 20230720000000
    clean-disabled: true
    out-of-order: true
    #指定sql文件路径
    locations:
      - classpath:db/migration/postgresql
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名
  typeAliasesPackage: com.ruoyi.**.domain
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
knife4j:
  enable: true
  setting:
    language: zh_cn
aixin:
  swagger:
    title: fk开发平台
    description: æä¾›ç®¡ç†åŽå°ã€ç”¨æˆ· App çš„æ‰€æœ‰åŠŸèƒ½
    version: ${ruoyi.version}
    url: xxxx
    email: qq.com
    license: xxx
    license-url: xxx
# Springdoc配置
springdoc:
  api-docs:
    enabled: true
    path: /v3/api-docs
  swagger-ui:
    enabled: true
    path: /swagger-ui.html
    tags-sorter: alpha
  group-configs:
    - group: 'default'
      display-name: '测试模块'
      paths-to-match: '/**'
      packages-to-scan: com.ruoyi.web.controller.tool
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
ruoyi-admin/src/main/resources/logback.xml.example
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- æ—¥å¿—存放路径 -->
    <property name="log.path" value="E:\logs" />
    <!-- æ—¥å¿—输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
    <!-- æŽ§åˆ¶å°è¾“出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- ç³»ç»Ÿæ—¥å¿—输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- å¾ªçŽ¯æ”¿ç­–ï¼šåŸºäºŽæ—¶é—´åˆ›å»ºæ—¥å¿—æ–‡ä»¶ -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- æ—¥å¿—文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- æ—¥å¿—最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- è¿‡æ»¤çš„级别 -->
            <level>INFO</level>
            <!-- åŒ¹é…æ—¶çš„æ“ä½œï¼šæŽ¥æ”¶ï¼ˆè®°å½•) -->
            <onMatch>ACCEPT</onMatch>
            <!-- ä¸åŒ¹é…æ—¶çš„æ“ä½œï¼šæ‹’绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- å¾ªçŽ¯æ”¿ç­–ï¼šåŸºäºŽæ—¶é—´åˆ›å»ºæ—¥å¿—æ–‡ä»¶ -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- æ—¥å¿—文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- æ—¥å¿—最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- è¿‡æ»¤çš„级别 -->
            <level>ERROR</level>
            <!-- åŒ¹é…æ—¶çš„æ“ä½œï¼šæŽ¥æ”¶ï¼ˆè®°å½•) -->
            <onMatch>ACCEPT</onMatch>
            <!-- ä¸åŒ¹é…æ—¶çš„æ“ä½œï¼šæ‹’绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- ç”¨æˆ·è®¿é—®æ—¥å¿—输出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- æŒ‰å¤©å›žæ»š daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- æ—¥å¿—最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- ç³»ç»Ÿæ¨¡å—日志级别控制  -->
    <logger name="com.ruoyi" level="info" />
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn" />
    <root level="info">
        <appender-ref ref="console" />
    </root>
    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>
    <!--系统用户操作日志-->
    <logger name="sys-user" level="info">
        <appender-ref ref="sys-user"/>
    </logger>
</configuration>
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
@@ -55,6 +55,7 @@
    public CorsFilter corsFilter()
    {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        // è®¾ç½®è®¿é—®æºåœ°å€
        config.addAllowedOriginPattern("*");
        // è®¾ç½®è®¿é—®æºè¯·æ±‚头
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -114,7 +114,7 @@
                requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
                    // é™æ€èµ„源,可匿名访问
                    .requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll()
                    .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll()
                    .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**","/swagger-resources", "/druid/**","/swagger-resources","/webjars/**", "/favicon.ico", "/doc.html").permitAll()
                    // é™¤ä¸Šé¢å¤–的所有请求全部需要鉴权认证
                    .anyRequest().authenticated();
            })