lixuliang
2024-08-29 d780b942227a527584a0320723574b7e00e5fc85
Merge branch 'master' of http://192.168.11.205:9000/r/se-cloud
已添加1个文件
已修改7个文件
152 ■■■■ 文件已修改
.gitignore 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker-compose/docker-compose.yml 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker-compose/file/bootstrap.yml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker-compose/mysql/initdb/se_config_20231204.sql 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker-compose/nginx/conf/nginx.conf 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/StringUtils.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-gateway/src/main/java/com/se/gateway/config/CorsConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-gateway/src/main/java/com/se/gateway/filter/AuthFilter.java 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -48,3 +48,5 @@
*.jar
/docker-compose/nginx/html
/docker-compose/mysql/data
/docker-compose/nacos/logs/nacos_gc.log.0.current
/docker-compose/redis/data/dump.rdb
docker-compose/docker-compose.yml
@@ -36,8 +36,8 @@
      - ./nacos/conf/application.properties:/home/nacos/conf/application.properties
    ports:
      - 8848:8848
      - 9848:9848
      - 9849:9849
#      - 9848:9848
#      - 9849:9849
    depends_on:
      - se-mysql
    networks:
@@ -58,8 +58,8 @@
  # gateway
  se-gateway:
    image: openjdk:8-jre
    ports:
      - 9204:8080
#    ports:
#      - 9204:8080
    volumes:
      - ./gateway:/data
    environment:
@@ -77,8 +77,8 @@
  # auth
  se-auth:
    image: openjdk:8-jre
    ports:
      - 9200:9200
#    ports:
#      - 9200:9200
    volumes:
      - ./auth:/data
    environment:
@@ -93,8 +93,8 @@
  # system
  se-system:
    image: openjdk:8-jre
    ports:
      - 9201:9201
#    ports:
#      - 9201:9201
    volumes:
      - ./system:/data
    environment:
@@ -107,6 +107,21 @@
    networks:
      - network-se
    restart: always
  # se-file
  se-file:
    image: openjdk:8-jre
#    ports:
#      - 9300:9300
    volumes:
      - ./file:/data
    environment:
      TZ: Asia/Shanghai
    entrypoint: java -jar /data/se-modules-file.jar --spring.config.location=file:/data/
    depends_on:
      - se-nacos
    networks:
      - network-se
    restart: always
  # nginx
  se-nginx:
    image: nginx:latest
docker-compose/file/bootstrap.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
# Tomcat
server:
  port: 9300
# Spring
spring:
  application:
    # åº”用名称
    name: se-file
  profiles:
    # çŽ¯å¢ƒé…ç½®
    active: dev
  cloud:
    nacos:
      discovery:
        # æœåŠ¡æ³¨å†Œåœ°å€
        server-addr: se-nacos:8848
      config:
        # é…ç½®ä¸­å¿ƒåœ°å€
        server-addr: se-nacos:8848
        # é…ç½®æ–‡ä»¶æ ¼å¼
        file-extension: yml
        # å…±äº«é…ç½®
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
docker-compose/mysql/initdb/se_config_20231204.sql
@@ -40,7 +40,7 @@
(5,'se-system-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n  redis:\n    host: se-redis\n    port: 6379\n    password: Redis_s!E_6.2.6\n  datasource:\n    druid:\n      stat-view-servlet:\n        enabled: false\n        loginUsername: admin\n        loginPassword: 123456\n    dynamic:\n      druid:\n        initial-size: 5\n        min-idle: 5\n        maxActive: 20\n        maxWait: 60000\n        connectTimeout: 30000\n        socketTimeout: 60000\n        timeBetweenEvictionRunsMillis: 60000\n        minEvictableIdleTimeMillis: 300000\n        validationQuery: SELECT 1 FROM DUAL\n        testWhileIdle: true\n        testOnBorrow: false\n        testOnReturn: false\n        poolPreparedStatements: true\n        maxPoolPreparedStatementPerConnectionSize: 20\n        filters: stat,slf4j\n        connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n      datasource:\n          # ä¸»åº“数据源\n          master:\n            driver-class-name: com.mysql.cj.jdbc.Driver\n            url: jdbc:mysql://se-mysql:3306/se-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n            username: root\n            password: My_Sql_s!E_v5.7\n          # ä»Žåº“数据源\n          # slave:\n            # username: \n            # password: \n            # url: \n            # driver-class-name: \n\n# mybatis配置\nmybatis:\n    # æœç´¢æŒ‡å®šåŒ…别名\n    typeAliasesPackage: com.se.system\n    # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件\n    mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n  title: ç³»ç»Ÿæ¨¡å—接口文档\n  license: Powered By se','00678c89684ec0b825cb9b71e032db64','2020-11-20 00:00:00','2023-12-04 07:51:28','nacos','0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','',''),
(6,'se-gen-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n  redis:\n    host: se-redis\n    port: 6379\n    password: Redis_s!E_6.2.6\n  datasource:\n    driver-class-name: com.mysql.cj.jdbc.Driver\n    url: jdbc:mysql://se-mysql:3306/se-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n    username: root\n    password: My_Sql_s!E_v5.7\n\n# mybatis配置\nmybatis:\n    # æœç´¢æŒ‡å®šåŒ…别名\n    typeAliasesPackage: com.se.gen.domain\n    # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件\n    mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n  title: ä»£ç ç”ŸæˆæŽ¥å£æ–‡æ¡£\n  # ä»£ç ç”Ÿæˆ\ngen:\n  # ä½œè€…\n  author: se\n  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool\n  packageName: com.se.system\n  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯false\n  autoRemovePre: false\n  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)\n  tablePrefix: sys_\n','eb592420b3fceae1402881887b8a6a0d','2020-11-20 00:00:00','2022-09-29 02:49:42','nacos','0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','',''),
(7,'se-job-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n  redis:\n    host: se-redis\n    port: 6379\n    password: Redis_s!E_6.2.6\n  datasource:\n    driver-class-name: com.mysql.cj.jdbc.Driver\n    url: jdbc:mysql://se-mysql:3306/se-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n    username: root\n    password: My_Sql_s!E_v5.7\n\n# mybatis配置\nmybatis:\n    # æœç´¢æŒ‡å®šåŒ…别名\n    typeAliasesPackage: com.se.job.domain\n    # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件\n    mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n  title: å®šæ—¶ä»»åŠ¡æŽ¥å£æ–‡æ¡£\n ','edcf0e3fe13fea07b4ec08b1088f30b3','2020-11-20 00:00:00','2022-09-29 02:50:50','nacos','0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','',''),
(8,'se-file-dev.yml','DEFAULT_GROUP','# æœ¬åœ°æ–‡ä»¶ä¸Šä¼     \r\nfile:\r\n    domain: http://127.0.0.1:9300\r\n    path: D:/se/uploadPath\r\n    prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n  domain: http://8.129.231.12\r\n  soTimeout: 3000\r\n  connectTimeout: 2000\r\n  trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n  url: http://8.129.231.12:9000\r\n  accessKey: minioadmin\r\n  secretKey: minioadmin\r\n  bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''),
(8,'se-file-dev.yml','DEFAULT_GROUP','# æœ¬åœ°æ–‡ä»¶ä¸Šä¼     \r\nfile:\r\n    domain: http://127.0.0.1:9300\r\n    path: /data/uploadPath\r\n    prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n  domain: http://8.129.231.12\r\n  soTimeout: 3000\r\n  connectTimeout: 2000\r\n  trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n  url: http://8.129.231.12:9000\r\n  accessKey: minioadmin\r\n  secretKey: minioadmin\r\n  bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''),
(9,'sentinel-se-gateway','DEFAULT_GROUP','[\r\n    {\r\n        \"resource\": \"se-auth\",\r\n        \"count\": 500,\r\n        \"grade\": 1,\r\n        \"limitApp\": \"default\",\r\n        \"strategy\": 0,\r\n        \"controlBehavior\": 0\r\n    },\r\n    {\r\n        \"resource\": \"se-system\",\r\n        \"count\": 1000,\r\n        \"grade\": 1,\r\n        \"limitApp\": \"default\",\r\n        \"strategy\": 0,\r\n        \"controlBehavior\": 0\r\n    },\r\n    {\r\n        \"resource\": \"se-gen\",\r\n        \"count\": 200,\r\n        \"grade\": 1,\r\n        \"limitApp\": \"default\",\r\n        \"strategy\": 0,\r\n        \"controlBehavior\": 0\r\n    },\r\n    {\r\n        \"resource\": \"se-job\",\r\n        \"count\": 300,\r\n        \"grade\": 1,\r\n        \"limitApp\": \"default\",\r\n        \"strategy\": 0,\r\n        \"controlBehavior\": 0\r\n    }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,'');
docker-compose/nginx/conf/nginx.conf
@@ -31,6 +31,15 @@
            try_files $uri $uri/ /sys/;
            #index  index.html index.htm;
        }
        location /se-file/ {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://se-file:9300/;
        }
        
        location /prod-api/ {
            proxy_set_header Host $http_host;
se-common/se-common-core/src/main/java/com/se/common/core/utils/StringUtils.java
@@ -6,7 +6,11 @@
import com.se.common.core.constant.Constants;
import com.se.common.core.text.StrFormatter;
import org.springframework.http.HttpCookie;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@@ -609,6 +613,23 @@
        return sb.toString();
    }
    public static String getValueFromCookie(ServerHttpRequest request, String key) {
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        if (CollectionUtils.isEmpty(cookies)) {
            return null;
        }
        for (Map.Entry<String, List<HttpCookie>> itemList  : cookies.entrySet()) {
            for (HttpCookie cookie :itemList.getValue()) {
                if (cookie.getName().equals(key)){
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
    public static String getValueFromCookie(HttpServletRequest request,String key) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null || cookies.length == 0) {
se-gateway/src/main/java/com/se/gateway/config/CorsConfig.java
@@ -20,6 +20,7 @@
 * @date 2024-08-28
 */
@Configuration
@SuppressWarnings("ALL")
public class CorsConfig
{
    /**
se-gateway/src/main/java/com/se/gateway/filter/AuthFilter.java
@@ -27,8 +27,7 @@
 * @author admin
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
public class AuthFilter implements GlobalFilter, Ordered {
    private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
    // æŽ’除过滤的 uri åœ°å€ï¼Œnacos自行添加
@@ -40,37 +39,31 @@
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();
        String url = request.getURI().getPath();
        // è·³è¿‡ä¸éœ€è¦éªŒè¯çš„路径
        if (StringUtils.matches(url, ignoreWhite.getWhites()))
        {
        if (StringUtils.matches(url, ignoreWhite.getWhites())) {
            return chain.filter(exchange);
        }
        String token = getToken(request);
        if (StringUtils.isEmpty(token))
        {
        if (StringUtils.isEmpty(token)) {
            return unauthorizedResponse(exchange, "令牌不能为空");
        }
        Claims claims = JwtUtils.parseToken(token);
        if (claims == null)
        {
        if (claims == null) {
            return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
        }
        String userkey = JwtUtils.getUserKey(claims);
        boolean islogin = redisService.hasKey(getTokenKey(userkey));
        if (!islogin)
        {
        if (!islogin) {
            return unauthorizedResponse(exchange, "登录状态已过期");
        }
        String userid = JwtUtils.getUserId(claims);
        String username = JwtUtils.getUserName(claims);
        if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
        {
        if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) {
            return unauthorizedResponse(exchange, "令牌验证失败");
        }
@@ -83,10 +76,8 @@
        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }
    private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value)
    {
        if (value == null)
        {
    private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
        if (value == null) {
            return;
        }
        String valueStr = value.toString();
@@ -94,13 +85,11 @@
        mutate.header(name, valueEncode);
    }
    private void removeHeader(ServerHttpRequest.Builder mutate, String name)
    {
    private void removeHeader(ServerHttpRequest.Builder mutate, String name) {
        mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
    }
    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg)
    {
    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
        log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
        return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
    }
@@ -108,28 +97,40 @@
    /**
     * èŽ·å–ç¼“å­˜key
     */
    private String getTokenKey(String token)
    {
    private String getTokenKey(String token) {
        return CacheConstants.LOGIN_TOKEN_KEY + token;
    }
    /**
     * èŽ·å–è¯·æ±‚token
     */
    private String getToken(ServerHttpRequest request)
    {
    private String getToken(ServerHttpRequest request) {
        // ä»Žheader获取token标识
        String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION);
        // ä»Žurl获取token标识
        if (StringUtils.isEmpty(token)) {
            token = request.getQueryParams().getFirst(TokenConstants.ACCESS_TOKEN);
        }
        if (StringUtils.isEmpty(token)) {
            token = request.getQueryParams().getFirst(TokenConstants.TOKEN);
        }
        // ä»Žcookie获取token标识
        if (StringUtils.isEmpty(token)) {
            token = StringUtils.getValueFromCookie(request, TokenConstants.COOKIE_TOKEN);
        }
        //String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION);
        // å¦‚果前端设置了令牌前缀,则裁剪掉前缀
        if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
        {
        if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) {
            token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY);
        }
        return token;
    }
    @Override
    public int getOrder()
    {
    public int getOrder() {
        return -200;
    }
}