diff --git a/src/main/java/com/imyeyu/api/TimiServerAPI.java b/src/main/java/com/imyeyu/api/TimiServerAPI.java index 99b5d0f..6cb3ff3 100644 --- a/src/main/java/com/imyeyu/api/TimiServerAPI.java +++ b/src/main/java/com/imyeyu/api/TimiServerAPI.java @@ -1,10 +1,6 @@ package com.imyeyu.api; import com.imyeyu.io.IO; -import com.imyeyu.java.TimiJava; -import com.imyeyu.java.bean.Language; -import com.imyeyu.java.ref.Ref; -import com.imyeyu.spring.TimiSpring; import com.imyeyu.utils.OS; import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; @@ -13,7 +9,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.core.env.Environment; import org.springframework.transaction.annotation.EnableTransactionManagement; import java.io.File; @@ -31,8 +26,6 @@ import java.io.File; @EnableTransactionManagement public class TimiServerAPI implements OS.FileSystem, ApplicationContextAware { - private static final String DEV_LANG_CONFIG = "dev.lang"; - public static ApplicationContext applicationContext; @Override @@ -40,32 +33,18 @@ public class TimiServerAPI implements OS.FileSystem, ApplicationContextAware { TimiServerAPI.applicationContext = applicationContext; } - public static Language.Enum getUserLanguage() { - Language.Enum userLanguage = TimiSpring.getLanguage(); - Environment env = applicationContext.getBean(Environment.class); - if (env.containsProperty(DEV_LANG_CONFIG)) { - String property = env.getProperty(DEV_LANG_CONFIG); - if (TimiJava.isNotEmpty(property)) { - userLanguage = Ref.toType(Language.Enum.class, property); - } - } - return userLanguage; - } - public static void main(String[] args) { try { { - // 导出配置 - String[] files = {"application.yml", "logback.xml"}; - for (int i = 0; i < files.length; i++) { - File file = new File("config" + SEP + files[i]); - if (!file.exists() || !file.isFile()) { - log.info("exporting default config at {}", file.getAbsolutePath()); - IO.resourceToDisk(TimiServerAPI.class, files[i], file.getAbsolutePath()); - } + File application = new File("config" + SEP + "application.yml"); + if (!application.exists()) { + IO.resourceToDisk(TimiServerAPI.class, "application_export.yml", application.getAbsolutePath()); + } + File logback = new File("config" + SEP + "logback.xml"); + if (!logback.exists()) { + IO.resourceToDisk(TimiServerAPI.class, "logback.xml", logback.getAbsolutePath()); } } - // 启动 SpringBoot SpringApplication.run(TimiServerAPI.class, args); } catch (Exception e) { diff --git a/src/main/java/com/imyeyu/api/config/CORSConfig.java b/src/main/java/com/imyeyu/api/config/CORSConfig.java index ab8b885..af1e141 100644 --- a/src/main/java/com/imyeyu/api/config/CORSConfig.java +++ b/src/main/java/com/imyeyu/api/config/CORSConfig.java @@ -29,21 +29,12 @@ public class CORSConfig { /** 允许跨域的地址 */ private String[] allowOrigin; - /** 是否允许请求带有验证信息 */ - private boolean allowCredentials; - - /** 允许请求的方法 */ - private String allowMethods; - - /** 允许服务端访问的客户端请求头 */ - private String allowHeaders; - @Bean public FilterRegistrationBean corsFilter() { CorsConfiguration config = new CorsConfiguration(); - config.addAllowedHeader(allowHeaders); - config.addAllowedMethod(allowMethods); - config.setAllowCredentials(allowCredentials); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + config.setAllowCredentials(true); config.setAllowedOriginPatterns(Arrays.asList(allowOrigin)); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); diff --git a/src/main/java/com/imyeyu/api/config/RedisConfig.java b/src/main/java/com/imyeyu/api/config/RedisConfig.java index 4efa999..a6c67dc 100644 --- a/src/main/java/com/imyeyu/api/config/RedisConfig.java +++ b/src/main/java/com/imyeyu/api/config/RedisConfig.java @@ -1,14 +1,17 @@ package com.imyeyu.api.config; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.blog.entity.ArticleRanking; import com.imyeyu.api.modules.common.entity.Multilingual; import com.imyeyu.spring.bean.RedisConfigParams; import com.imyeyu.spring.config.AbstractRedisConfig; import com.imyeyu.spring.util.Redis; import com.imyeyu.spring.util.RedisSerializers; +import com.imyeyu.utils.Time; import io.lettuce.core.api.StatefulConnection; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -33,9 +36,12 @@ import java.time.Duration; @Configuration @EqualsAndHashCode(callSuper = true) @EnableAutoConfiguration +@RequiredArgsConstructor @ConfigurationProperties(prefix = "spring.redis") public class RedisConfig extends AbstractRedisConfig { + private final ObjectMapper jackson; + // ---------- 连接配置 ---------- /** 地址 */ @@ -47,50 +53,9 @@ public class RedisConfig extends AbstractRedisConfig { /** 密码 */ private String password; - /** 超时(毫秒) */ - private int timeout; - - /** 连接池 */ - private Lettuce lettuce; - /** 数据库 */ private Database database; - /** - * 连接池 - * - * @author 夜雨 - * @since 2023-08-21 16:23 - */ - @Data - public static class Lettuce { - - /** 配置 */ - private Pool pool; - - /** - * 配置 - * - * @author 夜雨 - * @since 2023-08-21 16:23 - */ - @Data - public static class Pool { - - /** 最大活跃连接 */ - private int maxActive; - - /** 最小空闲连接 */ - private int minIdle; - - /** 最大空闲连接 */ - private int maxIdle; - - /** 最大等待时间(秒) */ - private int maxWait; - } - } - /** * 数据库 * @@ -146,10 +111,10 @@ public class RedisConfig extends AbstractRedisConfig { setHost(host); setPort(port); setPassword(password); - setTimeout(timeout); - setMaxActive(lettuce.pool.maxActive); - setMinIdle(lettuce.pool.minIdle); - setMaxIdle(lettuce.pool.maxIdle); + setTimeout(Time.SI * 8); + setMaxActive(8); + setMinIdle(1); + setMaxIdle(8); }}; } @@ -226,7 +191,7 @@ public class RedisConfig extends AbstractRedisConfig { /** @return 文章访问统计,文章 ID: {@link ArticleRanking}(JSON) */ @Bean("redisArticleRanking") public Redis getArticleRankingRedisTemplate() { - return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.jacksonSerializer(ArticleRanking.class)); + return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.jacksonSerializer(jackson, ArticleRanking.class)); } /** @return 文章访问记录,IP: [文章 ID] */ diff --git a/src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java b/src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java index d4d3604..8bdaf41 100644 --- a/src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java +++ b/src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java @@ -2,8 +2,6 @@ package com.imyeyu.api.config; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -19,37 +17,17 @@ import java.util.concurrent.ThreadPoolExecutor; @Data @Slf4j @Configuration -@EnableAutoConfiguration -@ConfigurationProperties(prefix = "spring.async.thread-pool") public class ThreadPoolConfig { - /** 核心数量 */ - private int corePoolSize; - - /** 最大数量 */ - private int maxPoolSize; - - /** 等待区容量 */ - private int queueCapacity; - - /** 最大保持活跃时间(秒) */ - private int keepAliveSeconds; - - /** 最大等待时间(秒) */ - private int awaitTerminationSeconds; - - /** 线程名称前缀 */ - private String threadNamePrefix; - @Bean(name = "threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(corePoolSize); - executor.setMaxPoolSize(maxPoolSize); - executor.setQueueCapacity(queueCapacity); - executor.setKeepAliveSeconds(keepAliveSeconds); - executor.setAwaitTerminationSeconds(awaitTerminationSeconds); - executor.setThreadNamePrefix(threadNamePrefix); + executor.setCorePoolSize(16); + executor.setMaxPoolSize(32); + executor.setQueueCapacity(16); + executor.setKeepAliveSeconds(60); + executor.setAwaitTerminationSeconds(60); + executor.setThreadNamePrefix("thread-pool-task-executor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; diff --git a/src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java b/src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java index 54f6f95..a514b80 100644 --- a/src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java +++ b/src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java @@ -70,8 +70,8 @@ public class GiteaDBConfig { ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); List mapperLocations = new ArrayList<>(); mapperLocations.add("classpath:mapper/gitea/**/*.xml"); - for (int i = 0; i < mapperLocations.size(); i++) { - resources.addAll(List.of(resourceResolver.getResources(mapperLocations.get(i)))); + for (String mapperLocation : mapperLocations) { + resources.addAll(List.of(resourceResolver.getResources(mapperLocation))); } } String[] typeAliases = { diff --git a/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java b/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java index 02fa8b4..cc4ea35 100644 --- a/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java +++ b/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java @@ -83,8 +83,8 @@ public class TimiServerDBConfig { mapperLocations.add("classpath:mapper/system/**/*.xml"); mapperLocations.add("classpath:mapper/journal/**/*.xml"); mapperLocations.add("classpath:mapper/minecraft/**/*.xml"); - for (int i = 0; i < mapperLocations.size(); i++) { - resources.addAll(List.of(resourceResolver.getResources(mapperLocations.get(i)))); + for (String mapperLocation : mapperLocations) { + resources.addAll(List.of(resourceResolver.getResources(mapperLocation))); } } String[] typeAliases = { diff --git a/src/main/java/com/imyeyu/api/modules/blog/entity/ArticleRanking.java b/src/main/java/com/imyeyu/api/modules/blog/entity/ArticleRanking.java index 6ee6cf1..8afb5ab 100644 --- a/src/main/java/com/imyeyu/api/modules/blog/entity/ArticleRanking.java +++ b/src/main/java/com/imyeyu/api/modules/blog/entity/ArticleRanking.java @@ -1,8 +1,9 @@ package com.imyeyu.api.modules.blog.entity; +import com.imyeyu.spring.entity.Entity; import lombok.Data; import lombok.EqualsAndHashCode; -import com.imyeyu.spring.entity.Entity; +import lombok.NoArgsConstructor; /** * 访问排行(每周) @@ -12,6 +13,7 @@ import com.imyeyu.spring.entity.Entity; * @since 2021-03-01 17:10 */ @Data +@NoArgsConstructor @EqualsAndHashCode(callSuper = true) public class ArticleRanking extends Entity { diff --git a/src/main/java/com/imyeyu/api/util/InitApplication.java b/src/main/java/com/imyeyu/api/util/InitApplication.java index aa8408d..9362f7a 100644 --- a/src/main/java/com/imyeyu/api/util/InitApplication.java +++ b/src/main/java/com/imyeyu/api/util/InitApplication.java @@ -3,7 +3,6 @@ package com.imyeyu.api.util; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.imyeyu.api.TimiServerAPI; import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Multilingual; import com.imyeyu.api.modules.common.entity.Setting; @@ -11,6 +10,7 @@ import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.system.bean.ServerFile; import com.imyeyu.java.ref.Ref; import com.imyeyu.lang.mapper.AbstractLanguageMapper; +import com.imyeyu.spring.TimiSpring; import com.imyeyu.spring.util.GlobalReturnHandler; import com.imyeyu.spring.util.Redis; import lombok.RequiredArgsConstructor; @@ -80,9 +80,8 @@ public class InitApplication implements ApplicationRunner { } private void initMultilingual() { -// redisLanguage.flushAll(); globalReturnHandler.setMultilingualHeader(mapping -> { - AbstractLanguageMapper map = redisMultilingual.map(TimiServerAPI.getUserLanguage()); + AbstractLanguageMapper map = redisMultilingual.map(TimiSpring.getLanguage()); return map.textArgs(mapping.getMsgKey(), mapping.getMsgArgs()); }); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index aed4226..37224d4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,4 @@ server: - port: 8091 shutdown: graceful # 开发环境语言,激活开发配置时,多语言系统始终使用此语言环境 @@ -12,26 +11,13 @@ logging: # Spring spring: - profiles: - active: prod servlet: multipart: max-file-size: 4GB max-request-size: 4GB lifecycle: timeout-per-shutdown-phase: 32s - async: - thread-pool: - core-pool-size: 16 - max-pool-size: 32 - queueCapacity: 16 - keep-alive-seconds: 60 - thread-name-prefix: thread-pool-task-executor- - await-termination-seconds: 60 - mail: # 邮件配置 - host: smtp.qq.com - username: imyeyu@qq.com - password: saodifhaposjfoas + mail: properties: mail: smtp: @@ -40,60 +26,3 @@ spring: enable: true required: true default-encoding: UTF-8 - redis: # Redis 数据库 - host: dev.vm.imyeyu.test - port: 6379 - password: - timeout: 8000 - database: - locker: 0 # ID: Integer 全局锁,ID 规范:应用:模块:业务:方法 - multilingual: 1 # ID: Multilingual 多语言缓存 - multilingual-map: 2 # Key: ID 多语言键缓存 - article-ranking: 3 # AID: ArticleRanking(JSON) 热门文章排位 - article-read: 4 # IP: [AID..] IP 阅读文章记录 - user-token: 5 # TOKEN: LONG 用户登录令牌 - user-exp-flag: 6 # UID: NULL 用户登录经验标记,暂时没有值,数据死亡时间为次日零时 - user-email-verify: 7 # AES_KEY: UID 邮箱验证密钥缓存 - user-reset-pw-verify: 8 # AES_KEY: UID 重置密码密钥缓存 - qps-limit: 9 # APP.IP.method: COUNT_IN_LIFE_CYCLE 接口访问频率控制(多个系统公用,需要 App 标记) - setting: 10 # Setting: SettingValue 系统配置 - fmc-player-token: 11 # TOKEN: USER_ID|PLAYER_ID MC 登录缓存 - clipboard: 12 # ID: CONTENT 共享剪切板 - lettuce: # 连接池配置 - pool: - max-wait: -1 - max-idle: 8 - min-idle: 0 - max-active: 8 - datasource: # 数据库配置 - timiserver: - jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/timi_server?serverTimezone=UTC&characterEncoding=UTF-8 - username: root - password: 123123 - driver-class-name: com.mysql.cj.jdbc.Driver - forevermc: - jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8 - username: root - password: 123123 - driver-class-name: com.mysql.cj.jdbc.Driver - gitea: - jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8 - username: root - password: 123123 - driver-class-name: com.mysql.cj.jdbc.Driver - data: - mongodb: - host: dev.vm.imyeyu.test - port: 27017 - database: db - username: root - password: qweqwe123 - -# CORS 跨域 -cors: - # 允许访问的客户端域名,如:http://web.xxx.com,* 表示不做任何限制(不做任何限制时 allow-credentials 无效) - allow-origin: - - "http://localhost:8080" - allow-methods: "*" # 允许请求的方法名,多个方法名逗号分割,如:GET, POST, PUT, DELETE, OPTIONS - allow-credentials: true # 是否允许请求带有验证信息,若要获取客户端域下的 Cookie 或 Session 时,设置为 true - allow-headers: "*" # 允许服务端访问的客户端请求头,多个请求头逗号分割,如:Content-BizType diff --git a/src/main/resources/application_export.yml b/src/main/resources/application_export.yml new file mode 100644 index 0000000..1ae5249 --- /dev/null +++ b/src/main/resources/application_export.yml @@ -0,0 +1,58 @@ +server: + port: 8091 + +# Spring +spring: + profiles: + active: prod + mail: # 邮件配置 + host: smtp.qq.com + username: imyeyu@qq.com + password: saodifhaposjfoas + redis: # Redis 数据库 + host: dev.vm.imyeyu.test + port: 6379 + password: + database: + locker: 0 # ID: Integer 全局锁,ID 规范:应用:模块:业务:方法 + multilingual: 1 # ID: Multilingual 多语言缓存 + multilingual-map: 2 # Key: ID 多语言键缓存 + article-ranking: 3 # AID: ArticleRanking(JSON) 热门文章排位 + article-read: 4 # IP: [AID..] IP 阅读文章记录 + user-token: 5 # TOKEN: LONG 用户登录令牌 + user-exp-flag: 6 # UID: NULL 用户登录经验标记,暂时没有值,数据死亡时间为次日零时 + user-email-verify: 7 # AES_KEY: UID 邮箱验证密钥缓存 + user-reset-pw-verify: 8 # AES_KEY: UID 重置密码密钥缓存 + qps-limit: 9 # APP.IP.method: COUNT_IN_LIFE_CYCLE 接口访问频率控制(多个系统公用,需要 App 标记) + setting: 10 # Setting: SettingValue 系统配置 + fmc-player-token: 11 # TOKEN: USER_ID|PLAYER_ID MC 登录缓存 + clipboard: 12 # ID: CONTENT 共享剪切板 + datasource: # 数据库配置 + timiserver: + jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/timi_server?serverTimezone=UTC&characterEncoding=UTF-8 + username: root + password: 123123 + driver-class-name: com.mysql.cj.jdbc.Driver + forevermc: + jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8 + username: root + password: 123123 + driver-class-name: com.mysql.cj.jdbc.Driver + gitea: + jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8 + username: root + password: 123123 + driver-class-name: com.mysql.cj.jdbc.Driver + data: + mongodb: + host: dev.vm.imyeyu.test + port: 27017 + database: db + username: root + password: qweqwe123 + +# CORS 跨域 +cors: + # 允许访问的客户端域名,如:http://web.xxx.com,* 表示不做任何限制(不做任何限制时 allow-credentials 无效) + allow-origin: + - "http://localhost:8080"