From af76eb43b83c06983249fbdd3250db7bd49e5a32 Mon Sep 17 00:00:00 2001 From: Timi Date: Tue, 8 Sep 2026 16:52:32 +0800 Subject: [PATCH] update SystemSetting --- .idea/data_source_mapping.xml | 6 + .../imyeyu/api/annotation/EnableSetting.java | 35 -- .../annotation/EnableSettingInterceptor.java | 55 ---- .../imyeyu/api/annotation/SettingBizType.java | 17 + .../java/com/imyeyu/api/bean/SettingEnum.java | 27 ++ .../java/com/imyeyu/api/config/WebConfig.java | 3 - .../modules/common/bean/SettingModule.java | 52 --- .../modules/common/bean/TempFileSetting.java | 41 +++ .../common/controller/SettingController.java | 3 + .../api/modules/common/entity/Setting.java | 308 +----------------- .../common/service/SettingService.java | 6 +- .../implement/TempFileServiceImplement.java | 11 +- .../journal/controller/ToolController.java | 9 +- .../api/modules/music/bean/MusicSetting.java | 44 +++ .../runner/ControllerBootstrapRunner.java | 14 +- .../music/runner/PlayerBootstrapRunner.java | 10 +- .../system/bean/SystemStatusSetting.java | 32 ++ .../implement/StatusServiceImplement.java | 10 +- .../status/AbstractDequeStatusCollector.java | 4 +- .../collector/NetworkStatusCollector.java | 8 +- .../api/modules/user/bean/UserSetting.java | 35 ++ .../implement/UserLoginServiceImplement.java | 4 +- .../imyeyu/api/util/InitBuiltinSetting.java | 82 +++++ 23 files changed, 329 insertions(+), 487 deletions(-) create mode 100644 .idea/data_source_mapping.xml delete mode 100644 src/main/java/com/imyeyu/api/annotation/EnableSetting.java delete mode 100644 src/main/java/com/imyeyu/api/annotation/EnableSettingInterceptor.java create mode 100644 src/main/java/com/imyeyu/api/annotation/SettingBizType.java create mode 100644 src/main/java/com/imyeyu/api/bean/SettingEnum.java delete mode 100644 src/main/java/com/imyeyu/api/modules/common/bean/SettingModule.java create mode 100644 src/main/java/com/imyeyu/api/modules/common/bean/TempFileSetting.java create mode 100644 src/main/java/com/imyeyu/api/modules/music/bean/MusicSetting.java create mode 100644 src/main/java/com/imyeyu/api/modules/system/bean/SystemStatusSetting.java create mode 100644 src/main/java/com/imyeyu/api/modules/user/bean/UserSetting.java create mode 100644 src/main/java/com/imyeyu/api/util/InitBuiltinSetting.java diff --git a/.idea/data_source_mapping.xml b/.idea/data_source_mapping.xml new file mode 100644 index 0000000..a381639 --- /dev/null +++ b/.idea/data_source_mapping.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/imyeyu/api/annotation/EnableSetting.java b/src/main/java/com/imyeyu/api/annotation/EnableSetting.java deleted file mode 100644 index f1d9da3..0000000 --- a/src/main/java/com/imyeyu/api/annotation/EnableSetting.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.imyeyu.api.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 启用配置注解 - * - * @author 夜雨 - * @since 2023-07-15 10:00 - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface EnableSetting { - - /** - * - * - * @author 夜雨 - * @since 2026-04-27 14:45 - */ - enum Logic { - - AND, - - OR - } - - Logic logic() default Logic.AND; - - /** @return 未启用配置时响应消息语言映射键 */ - String message() default "service.offline"; -} diff --git a/src/main/java/com/imyeyu/api/annotation/EnableSettingInterceptor.java b/src/main/java/com/imyeyu/api/annotation/EnableSettingInterceptor.java deleted file mode 100644 index f2f2987..0000000 --- a/src/main/java/com/imyeyu/api/annotation/EnableSettingInterceptor.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.imyeyu.api.annotation; - -import com.imyeyu.api.modules.common.service.SettingService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Lazy; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerInterceptor; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -/** - * 启用配置注解处理器 - * - * @author 夜雨 - * @since 2023-07-15 10:01 - */ -@Component -@RequiredArgsConstructor(onConstructor_ = {@Lazy}) -public class EnableSettingInterceptor implements HandlerInterceptor { - - private final SettingService service; - - public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) throws InvocationTargetException, IllegalAccessException { - if (handler instanceof HandlerMethod handlerMethod) { - EnableSetting annotation = handlerMethod.getMethodAnnotation(EnableSetting.class); - if (annotation == null) { - return true; - } - EnableSetting.Logic logic = annotation.logic(); - List valueList = new ArrayList<>(); - for (Method method : annotation.getClass().getMethods()) { - if (method.getName().equals("message")) { - continue; - } - Enum[] enums = (Enum[]) method.invoke(annotation); - for (Enum anEnum : enums) { - valueList.add(service.getSystem(anEnum).isTrue()); - } - } - if (logic == EnableSetting.Logic.AND) { - return valueList.stream().allMatch(Boolean::booleanValue); - } else { - return valueList.stream().anyMatch(Boolean::booleanValue); - } - } - return true; - } -} diff --git a/src/main/java/com/imyeyu/api/annotation/SettingBizType.java b/src/main/java/com/imyeyu/api/annotation/SettingBizType.java new file mode 100644 index 0000000..323505a --- /dev/null +++ b/src/main/java/com/imyeyu/api/annotation/SettingBizType.java @@ -0,0 +1,17 @@ +package com.imyeyu.api.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// +/// +/// @author 夜雨 +/// @since 2026-09-08 15:22 +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface SettingBizType { + + String value(); +} diff --git a/src/main/java/com/imyeyu/api/bean/SettingEnum.java b/src/main/java/com/imyeyu/api/bean/SettingEnum.java new file mode 100644 index 0000000..8cad560 --- /dev/null +++ b/src/main/java/com/imyeyu/api/bean/SettingEnum.java @@ -0,0 +1,27 @@ +package com.imyeyu.api.bean; + +import com.imyeyu.api.annotation.SettingBizType; +import com.imyeyu.api.modules.common.entity.Setting; +import com.imyeyu.utils.Text; + +/// +/// +/// @author 夜雨 +/// @since 2026-09-08 15:18 +public interface SettingEnum { + + default String getBizType() { + Class implEnum = getClass(); + SettingBizType bizType = implEnum.getAnnotation(SettingBizType.class); + if (bizType == null) { + return Text.bizClassName(implEnum); + } + return bizType.value(); + } + + String name(); + + String getDefaultValue(); + + Setting.ValueType getValueType(); +} diff --git a/src/main/java/com/imyeyu/api/config/WebConfig.java b/src/main/java/com/imyeyu/api/config/WebConfig.java index dbf545c..89441bb 100644 --- a/src/main/java/com/imyeyu/api/config/WebConfig.java +++ b/src/main/java/com/imyeyu/api/config/WebConfig.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.imyeyu.api.annotation.EnableSettingInterceptor; import com.imyeyu.api.annotation.RequestRateLimitInterceptor; import com.imyeyu.api.annotation.RequireCorePermissionInterceptor; import com.imyeyu.api.modules.gao.annotation.RequireGaoPermissionInterceptor; @@ -40,7 +39,6 @@ public class WebConfig implements WebMvcConfigurer { private final ObjectMapper jackson; private final SystemAPIInterceptor systemAPIInterceptor; private final JournalAPIInterceptor journalAPIInterceptor; - private final EnableSettingInterceptor enableSettingInterceptor; private final RequestRateLimitInterceptor requestRateLimitInterceptor; private final RequireGaoPermissionInterceptor requireGaoPermissionInterceptor; private final RequireCorePermissionInterceptor requireCorePermissionInterceptor; @@ -54,7 +52,6 @@ public class WebConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(systemAPIInterceptor).addPathPatterns(SystemAPIInterceptor.PATH); registry.addInterceptor(journalAPIInterceptor).addPathPatterns(JournalAPIInterceptor.PATH); - registry.addInterceptor(enableSettingInterceptor).addPathPatterns("/**"); registry.addInterceptor(requireCorePermissionInterceptor).addPathPatterns("/**"); registry.addInterceptor(requireGaoPermissionInterceptor).addPathPatterns("/**"); registry.addInterceptor(requestRateLimitInterceptor).addPathPatterns("/**"); diff --git a/src/main/java/com/imyeyu/api/modules/common/bean/SettingModule.java b/src/main/java/com/imyeyu/api/modules/common/bean/SettingModule.java deleted file mode 100644 index 6af5d0d..0000000 --- a/src/main/java/com/imyeyu/api/modules/common/bean/SettingModule.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.imyeyu.api.modules.common.bean; - -import com.imyeyu.api.modules.common.entity.Setting; -import com.imyeyu.java.bean.timi.TimiCode; -import com.imyeyu.java.bean.timi.TimiException; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 设置模块 - * - * @author 夜雨 - * @since 2026-04-24 00:59 - */ -@Getter -@AllArgsConstructor -public enum SettingModule { - - COMMON(Setting.Module.Common.class), - - DOMAIN(Setting.Module.Domain.class), - - FOREVER_MC(Setting.Module.ForeverMC.class), - - MULTILINGUAL(Setting.Module.Multilingual.class), - - GITEA(Setting.Module.Gitea.class), - - MUSIC(Setting.Module.Music.class), - - JOURNAL(Setting.Module.Journal.class), - - TEMP_FILE(Setting.Module.TempFile.class), - - USER(Setting.Module.User.class), - - SYSTEM(Setting.Module.System.class), - - SYSTEM_STATUS(Setting.Module.SystemStatus.class); - - /** 模块枚举类 */ - final Class> clazz; - - public static > SettingModule fromClass(Class clazz) { - for (SettingModule value : values()) { - if (value.clazz.equals(clazz)) { - return value; - } - } - throw new TimiException(TimiCode.ERROR, "not found System Module: %s".formatted(clazz.getName())); - } -} diff --git a/src/main/java/com/imyeyu/api/modules/common/bean/TempFileSetting.java b/src/main/java/com/imyeyu/api/modules/common/bean/TempFileSetting.java new file mode 100644 index 0000000..93be145 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/common/bean/TempFileSetting.java @@ -0,0 +1,41 @@ +package com.imyeyu.api.modules.common.bean; + +import com.imyeyu.api.annotation.SettingBizType; +import com.imyeyu.api.bean.SettingEnum; +import com.imyeyu.api.modules.common.entity.Setting; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * + * + * @author 夜雨 + * @since 2026-04-24 14:47 + */ +@Getter +@SettingBizType("TEMP_FILE") +@AllArgsConstructor +public enum TempFileSetting implements SettingEnum { + + /** 启用服务 */ + ENABLE(Boolean.TRUE.toString(), Setting.ValueType.BOOLEAN), + + /** 最小缓存时长 */ + TTL_MIN("1h", Setting.ValueType.TIME), + + /** 默认缓存时长 */ + TTL_DEFAULT("3d", Setting.ValueType.TIME), + + /** 最大缓存时长 */ + TTL_MAX("7d", Setting.ValueType.TIME), + + /** 已过期文件残留时长 */ + RESIDUE_TTL("90d", Setting.ValueType.TIME), + + /** 每个 IP 限制有效临时文件容量 */ + LIMIT_SIZE_OF_IP("10 GB", Setting.ValueType.BYTE_SIZE); + + final String defaultValue; + + final Setting.ValueType valueType; +} \ No newline at end of file diff --git a/src/main/java/com/imyeyu/api/modules/common/controller/SettingController.java b/src/main/java/com/imyeyu/api/modules/common/controller/SettingController.java index eeb1b6c..27a9eec 100644 --- a/src/main/java/com/imyeyu/api/modules/common/controller/SettingController.java +++ b/src/main/java/com/imyeyu/api/modules/common/controller/SettingController.java @@ -53,6 +53,7 @@ public class SettingController { */ @JsonView(ResponseView.Admin.class) @RequestRateLimit + @RequireCorePermission(CorePermissionCode.SETTING_READ) @PostMapping("/detail") public Setting detail(@RequestBody String id) { return service.get(id); @@ -66,6 +67,7 @@ public class SettingController { */ @AOPLog @JsonView(ResponseView.Admin.class) + @RequireCorePermission(CorePermissionCode.SETTING_CREATE) @RequestRateLimit @PostMapping("/create") public Setting create(@RequestBody Setting setting) { @@ -80,6 +82,7 @@ public class SettingController { */ @AOPLog @RequestRateLimit + @RequireCorePermission(CorePermissionCode.SETTING_UPDATE) @PostMapping("/update") public void update(@RequestBody Setting setting) { service.update(setting); diff --git a/src/main/java/com/imyeyu/api/modules/common/entity/Setting.java b/src/main/java/com/imyeyu/api/modules/common/entity/Setting.java index 2800b0b..5442c0e 100644 --- a/src/main/java/com/imyeyu/api/modules/common/entity/Setting.java +++ b/src/main/java/com/imyeyu/api/modules/common/entity/Setting.java @@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; 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.SettingModule; import com.imyeyu.spring.annotation.table.Transient; import com.imyeyu.spring.entity.UUIDEntity; import com.imyeyu.spring.util.ResponseView; @@ -62,6 +61,9 @@ public class Setting extends UUIDEntity { /** 时间 */ TIME, + /// 字节大小 + BYTE_SIZE, + /** 时长 */ DURATION, @@ -102,16 +104,6 @@ public class Setting extends UUIDEntity { @Transient private Enum keyRaw; - public Setting(Enum key) { - setKeyRaw(key); - } - - public Setting(Enum key, Object value, ValueType valueType) { - setKeyRaw(key); - this.value = value.toString(); - this.valueType = valueType; - } - /** * 以字符串形式返回配置值 * @@ -221,298 +213,4 @@ public class Setting extends UUIDEntity { throw new IllegalArgumentException("setting value is not valid json: %s".formatted(value), e); } } - - public void setKeyRaw(Enum key) { - this.keyRaw = key; - this.bizType = SettingModule.fromClass(key.getClass()).toString(); - this.code = key.toString(); - } - - public boolean is(Enum key) { - return SettingModule.fromClass(key.getClass()).toString().equals(bizType) && key.toString().equals(code); - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:23 - */ - public static final class Module { - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:39 - */ - public enum Common { - - /** 微信收款码 */ - WECHAT_RECEIVE_QR_CODE - } - - /** - * 域名 - * - * @author 夜雨 - * @since 2026-04-26 17:18 - */ - public enum Domain { - - ROOT, - - API, - - GIT, - - BLOG, - - SPACE, - - FOREVER_MC - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:14 - */ - public enum Blog { - - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:03 - */ - public enum User { - - /** 启用登录 */ - ENABLE_LOGIN, - - /** 启用注册 */ - ENABLE_REGISTER, - - /** 允许数据更新 */ - ENABLE_PROFILE_UPDATE, - - /** 令牌有效期 */ - TOKEN_TTL - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:21 - */ - public enum Comment { - - /** 启用服务 */ - ENABLE - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:03 - */ - public enum ICP { - - IMYEYU_COM - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 15:01 - */ - public enum ForeverMC { - - PLAYER_BIND_MAX, - - LOGIN_TOKEN_TTL - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:57 - */ - public enum Multilingual { - - /** 翻译 API */ - TRANSLATE_API, - - /** 翻译 AppId */ - TRANSLATE_APP_ID, - - /** 翻译密钥 */ - TRANSLATE_KEY, - - /** 翻译计划任务表达式 */ - TRANSLATE_CORN, - - /** 缓存时长 */ - CACHE_TTL - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:55 - */ - public enum Gitea { - - /** 接口地址 */ - API, - - /** 关于页面所属文章 ID */ - ABOUT_ARTICLE_ID, - - /** 仓库文件地址 */ - REPOSITORY_PATH - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:52 - */ - public enum Music { - - /** 启用服务 */ - ENABLE, - - /** 通信消息最大帧长度 */ - MAX_FRAME_LENGTH, - - /** 受控端 IP */ - PLAYER_IP, - - /** 受控端端口 */ - PLAYER_PORT, - - /** 控制端 IP */ - CONTROLLER_IP, - - /** 控制端端口 */ - CONTROLLER_PORT, - - /** 控制端入口地址 */ - CONTROLLER_URI, - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:49 - */ - public enum Journal { - - /** 启用服务 */ - ENABLE, - - /** 审核中 */ - REVIEWING, - - /** 访问密钥 */ - KEY, - - /** 微信小程序 AppId */ - APP_ID, - - /** 微信小程序 AppSecret */ - APP_SECRET, - - /** 备忘录内容 */ - MEMO, - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:47 - */ - public enum TempFile { - - /** 启用服务 */ - ENABLE, - - /** 最小缓存时长 */ - TTL_MIN, - - /** 默认缓存时长 */ - TTL_DEFAULT, - - /** 最大缓存时长 */ - TTL_MAX, - - /** 已过期文件残留时长 */ - RESIDUE_TTL, - - /** 每个 IP 限制有效临时文件容量 */ - LIMIT_SIZE_OF_IP - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-27 14:35 - */ - public enum FileSync { - - ENABLE, - - CRON, - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:23 - */ - public enum System { - - /** 文件系统基准路径 */ - FILE_BASE_PATH, - - /** 设置缓存时长 */ - SETTING_TTL, - - /** 哀悼滤镜 */ - ENABLE_MOURN_FILTER, - } - - /** - * - * - * @author 夜雨 - * @since 2026-04-24 14:23 - */ - public enum SystemStatus { - - /** 状态采集数据量 */ - LIMIT, - - /** 状态采集网卡 */ - NETWORK_MAC, - - /** 状态采集频率 */ - RATE, - } - } } diff --git a/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java b/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java index 6333371..3032d99 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.common.service; -import com.imyeyu.api.modules.common.bean.SettingModule; +import com.imyeyu.api.bean.SettingEnum; import com.imyeyu.api.modules.common.bean.attachment.SettingSupport; import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.java.TimiJava; @@ -18,8 +18,8 @@ public interface SettingService extends BaseService { Setting getByCode(String bizType, String bizId, String code); - default Setting getSystem(Enum bizType) { - return getByCode(SettingModule.fromClass(bizType.getClass()).name(), TimiJava.ZERO_UUID, bizType.toString()); + default Setting getSystem(SettingEnum setting) { + return getByCode(setting.getBizType(), TimiJava.ZERO_UUID, setting.name()); } List listByBizId(String bizType, String bizId); diff --git a/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java b/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java index bc9f403..24c8aa8 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java @@ -3,6 +3,7 @@ package com.imyeyu.api.modules.common.service.implement; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.imyeyu.api.modules.common.bean.TempFileSetting; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.AttachmentService; @@ -52,11 +53,11 @@ public class TempFileServiceImplement implements TempFileService { try { logger.setContent(jackson.writeValueAsString(logRequestArgs(files, ttl))); - Setting ttlMin = settingService.getSystem(Setting.Module.TempFile.TTL_MIN); - Setting ttlMax = settingService.getSystem(Setting.Module.TempFile.TTL_MAX); - Setting ttlDefault = settingService.getSystem(Setting.Module.TempFile.TTL_DEFAULT); - Setting residueTime = settingService.getSystem(Setting.Module.TempFile.RESIDUE_TTL); - String limitStr = settingService.getSystem(Setting.Module.TempFile.LIMIT_SIZE_OF_IP).asString(); + Setting ttlMin = settingService.getSystem(TempFileSetting.TTL_MIN); + Setting ttlMax = settingService.getSystem(TempFileSetting.TTL_MAX); + Setting ttlDefault = settingService.getSystem(TempFileSetting.TTL_DEFAULT); + Setting residueTime = settingService.getSystem(TempFileSetting.RESIDUE_TTL); + String limitStr = settingService.getSystem(TempFileSetting.LIMIT_SIZE_OF_IP).asString(); long limit = IOSize.parse(limitStr); diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java index e5ef910..42755ae 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java @@ -25,14 +25,15 @@ public class ToolController { @GetMapping("/memo") public String getMemo() { - return settingService.getSystem(Setting.Module.Journal.MEMO).asString(); +// return settingService.getSystem(Setting.Module.Journal.MEMO).asString(); + return null; } @RequiredUploadPermission @PostMapping("/memo/update") public void updateMemo(@RequestBodyValue String data) { - Setting setting = settingService.getSystem(Setting.Module.Journal.MEMO); - setting.setValue(data); - settingService.update(setting); +// Setting setting = settingService.getSystem(Setting.Module.Journal.MEMO); +// setting.setValue(data); +// settingService.update(setting); } } diff --git a/src/main/java/com/imyeyu/api/modules/music/bean/MusicSetting.java b/src/main/java/com/imyeyu/api/modules/music/bean/MusicSetting.java new file mode 100644 index 0000000..d38e1eb --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/music/bean/MusicSetting.java @@ -0,0 +1,44 @@ +package com.imyeyu.api.modules.music.bean; + +import com.imyeyu.api.annotation.SettingBizType; +import com.imyeyu.api.bean.SettingEnum; +import com.imyeyu.api.modules.common.entity.Setting; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * + * + * @author 夜雨 + * @since 2026-04-24 14:52 + */ +@Getter +@SettingBizType("MUSIC") +@AllArgsConstructor +public enum MusicSetting implements SettingEnum { + + /** 启用服务 */ + ENABLE(Boolean.FALSE.toString(), Setting.ValueType.BOOLEAN), + + /** 通信消息最大帧长度 */ + MAX_FRAME_LENGTH("2048", Setting.ValueType.INTEGER), + + /** 受控端 IP */ + PLAYER_IP("0.0.0.0", Setting.ValueType.STRING), + + /** 受控端端口 */ + PLAYER_PORT("18392", Setting.ValueType.INTEGER), + + /** 控制端 IP */ + CONTROLLER_IP("0.0.0.0", Setting.ValueType.STRING), + + /** 控制端端口 */ + CONTROLLER_PORT("18391", Setting.ValueType.INTEGER), + + /** 控制端入口地址 */ + CONTROLLER_URI("/music/control", Setting.ValueType.STRING); + + final String defaultValue; + + final Setting.ValueType valueType; +} diff --git a/src/main/java/com/imyeyu/api/modules/music/runner/ControllerBootstrapRunner.java b/src/main/java/com/imyeyu/api/modules/music/runner/ControllerBootstrapRunner.java index 9534539..20d57f7 100644 --- a/src/main/java/com/imyeyu/api/modules/music/runner/ControllerBootstrapRunner.java +++ b/src/main/java/com/imyeyu/api/modules/music/runner/ControllerBootstrapRunner.java @@ -1,8 +1,8 @@ package com.imyeyu.api.modules.music.runner; import com.imyeyu.api.config.CORSConfig; -import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.SettingService; +import com.imyeyu.api.modules.music.bean.MusicSetting; import com.imyeyu.api.modules.music.handler.ControllerMessageHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -62,7 +62,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application } public void run(ApplicationArguments args) { - if (settingService.getSystem(Setting.Module.Music.ENABLE).isTrue()) { + if (settingService.getSystem(MusicSetting.ENABLE).isTrue()) { return; } @@ -75,7 +75,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, worker); bootstrap.channel(NioServerSocketChannel.class); - bootstrap.localAddress(new InetSocketAddress(settingService.getSystem(Setting.Module.Music.CONTROLLER_PORT).asInteger())); + bootstrap.localAddress(new InetSocketAddress(settingService.getSystem(MusicSetting.CONTROLLER_PORT).asInteger())); bootstrap.childHandler(new ChannelInitializer() { @Override @@ -89,7 +89,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application @Override public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception { if (obj instanceof FullHttpRequest req) { - if (!req.uri().equals(settingService.getSystem(Setting.Module.Music.CONTROLLER_URI).asString())) { + if (!req.uri().equals(settingService.getSystem(MusicSetting.CONTROLLER_URI).asString())) { // 访问的路径不是 Web Socket 的端点地址,响应 404 ctx.channel().writeAndFlush(NFP).addListener(ChannelFutureListener.CLOSE); return; @@ -111,10 +111,10 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application }); pipeline.addLast(new WebSocketServerCompressionHandler()); pipeline.addLast(new WebSocketServerProtocolHandler( - settingService.getSystem(Setting.Module.Music.CONTROLLER_URI).asString(), + settingService.getSystem(MusicSetting.CONTROLLER_URI).asString(), null, true, - settingService.getSystem(Setting.Module.Music.MAX_FRAME_LENGTH).asLong() + settingService.getSystem(MusicSetting.MAX_FRAME_LENGTH).asLong() ) ); @@ -123,7 +123,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application } }); channel = bootstrap.bind().sync().channel(); - log.info("TimiMusicRC controller service startup with {}", settingService.getSystem(Setting.Module.Music.CONTROLLER_IP).asString()); + log.info("TimiMusicRC controller service startup with {}", settingService.getSystem(MusicSetting.CONTROLLER_IP).asString()); } catch (Exception e) { log.error("TimiMusicRC controller service startup error", e); } diff --git a/src/main/java/com/imyeyu/api/modules/music/runner/PlayerBootstrapRunner.java b/src/main/java/com/imyeyu/api/modules/music/runner/PlayerBootstrapRunner.java index 2f356ff..6804162 100644 --- a/src/main/java/com/imyeyu/api/modules/music/runner/PlayerBootstrapRunner.java +++ b/src/main/java/com/imyeyu/api/modules/music/runner/PlayerBootstrapRunner.java @@ -1,7 +1,7 @@ package com.imyeyu.api.modules.music.runner; -import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.SettingService; +import com.imyeyu.api.modules.music.bean.MusicSetting; import com.imyeyu.api.modules.music.handler.PlayerMessageHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -49,7 +49,7 @@ public class PlayerBootstrapRunner implements ApplicationRunner, ApplicationList } public void run(ApplicationArguments args) { - if (settingService.getSystem(Setting.Module.Music.ENABLE).isTrue()) { + if (settingService.getSystem(MusicSetting.ENABLE).isTrue()) { return; } ServerBootstrap bootstrap = new ServerBootstrap(); @@ -58,13 +58,13 @@ public class PlayerBootstrapRunner implements ApplicationRunner, ApplicationList try { bootstrap.group(boss, worker); bootstrap.channel(NioServerSocketChannel.class); - bootstrap.localAddress(new InetSocketAddress(settingService.getSystem(Setting.Module.Music.PLAYER_PORT).asInteger())); + bootstrap.localAddress(new InetSocketAddress(settingService.getSystem(MusicSetting.PLAYER_PORT).asInteger())); bootstrap.childHandler(new ChannelInitializer<>() { @Override protected void initChannel(Channel ch) { ch.pipeline().addLast(new LengthFieldBasedFrameDecoder( - settingService.getSystem(Setting.Module.Music.MAX_FRAME_LENGTH).asInteger(), + settingService.getSystem(MusicSetting.MAX_FRAME_LENGTH).asInteger(), 0, 4, 0, @@ -79,7 +79,7 @@ public class PlayerBootstrapRunner implements ApplicationRunner, ApplicationList channel = bootstrap.bind().sync().channel(); - log.info("TimiMusicRC player service startup with {}", settingService.getSystem(Setting.Module.Music.PLAYER_IP).asString()); + log.info("TimiMusicRC player service startup with {}", settingService.getSystem(MusicSetting.PLAYER_IP).asString()); } catch (Exception e) { log.error("TimiMusicRC player service startup error", e); } diff --git a/src/main/java/com/imyeyu/api/modules/system/bean/SystemStatusSetting.java b/src/main/java/com/imyeyu/api/modules/system/bean/SystemStatusSetting.java new file mode 100644 index 0000000..85f9275 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/system/bean/SystemStatusSetting.java @@ -0,0 +1,32 @@ +package com.imyeyu.api.modules.system.bean; + +import com.imyeyu.api.annotation.SettingBizType; +import com.imyeyu.api.bean.SettingEnum; +import com.imyeyu.api.modules.common.entity.Setting; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * + * + * @author 夜雨 + * @since 2026-04-24 14:23 + */ +@Getter +@SettingBizType("SYSTEM_STATUS") +@AllArgsConstructor +public enum SystemStatusSetting implements SettingEnum { + + /** 状态采集数据量 */ + LIMIT("512", Setting.ValueType.INTEGER), + + /** 状态采集网卡 */ + NETWORK_MAC(null, Setting.ValueType.STRING), + + /** 状态采集频率 */ + RATE("3000", Setting.ValueType.INTEGER); + + final String defaultValue; + + final Setting.ValueType valueType; +} diff --git a/src/main/java/com/imyeyu/api/modules/system/service/implement/StatusServiceImplement.java b/src/main/java/com/imyeyu/api/modules/system/service/implement/StatusServiceImplement.java index fb5c123..218c441 100644 --- a/src/main/java/com/imyeyu/api/modules/system/service/implement/StatusServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/system/service/implement/StatusServiceImplement.java @@ -1,8 +1,8 @@ package com.imyeyu.api.modules.system.service.implement; -import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.system.bean.ServerStatus; +import com.imyeyu.api.modules.system.bean.SystemStatusSetting; import com.imyeyu.api.modules.system.service.StatusService; import com.imyeyu.api.modules.system.vo.SystemStatusDataView; import com.imyeyu.api.modules.system.vo.SystemStatusHistoryView; @@ -33,7 +33,7 @@ public class StatusServiceImplement implements StatusService { @Override public SystemStatusSnapshotView getStatus(String metrics) { long serverTime = Time.now(); - int sampleRateMs = settingService.getSystem(Setting.Module.SystemStatus.RATE).asInteger(); + int sampleRateMs = settingService.getSystem(SystemStatusSetting.RATE).asInteger(); EnumSet selectedMetrics = parseMetrics(metrics); synchronized (serverStatus) { @@ -48,7 +48,7 @@ public class StatusServiceImplement implements StatusService { @Override public SystemStatusHistoryView getStatusHistory(String window, String metrics) { long serverTime = Time.now(); - int sampleRateMs = settingService.getSystem(Setting.Module.SystemStatus.RATE).asInteger(); + int sampleRateMs = settingService.getSystem(SystemStatusSetting.RATE).asInteger(); EnumSet selectedMetrics = parseMetrics(metrics); synchronized (serverStatus) { @@ -261,7 +261,7 @@ public class StatusServiceImplement implements StatusService { */ private long parseWindowMs(String window, int sampleRateMs) { if (window == null || window.isBlank()) { - return (long) settingService.getSystem(Setting.Module.SystemStatus.RATE).asInteger() * sampleRateMs; + return (long) settingService.getSystem(SystemStatusSetting.RATE).asInteger() * sampleRateMs; } String normalized = window.trim().toLowerCase(Locale.ROOT); @@ -277,7 +277,7 @@ public class StatusServiceImplement implements StatusService { try { return Math.max(sampleRateMs, Long.parseLong(valueText) * unit); } catch (NumberFormatException e) { - return (long) settingService.getSystem(Setting.Module.SystemStatus.RATE).asInteger() * sampleRateMs; + return (long) settingService.getSystem(SystemStatusSetting.RATE).asInteger() * sampleRateMs; } } diff --git a/src/main/java/com/imyeyu/api/modules/system/task/status/AbstractDequeStatusCollector.java b/src/main/java/com/imyeyu/api/modules/system/task/status/AbstractDequeStatusCollector.java index b77286e..2148ce0 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/status/AbstractDequeStatusCollector.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/status/AbstractDequeStatusCollector.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.system.task.status; -import com.imyeyu.api.modules.common.entity.Setting; +import com.imyeyu.api.modules.system.bean.SystemStatusSetting; import java.util.Deque; @@ -22,7 +22,7 @@ public abstract class AbstractDequeStatusCollector implements StatusCollector { */ protected void putDeque(StatusCollectContext context, Deque deque, T value) { deque.addLast(value); - if (context.getSettingService().getSystem(Setting.Module.SystemStatus.LIMIT).asInteger() < deque.size()) { + if (context.getSettingService().getSystem(SystemStatusSetting.LIMIT).asInteger() < deque.size()) { deque.pollFirst(); } } diff --git a/src/main/java/com/imyeyu/api/modules/system/task/status/collector/NetworkStatusCollector.java b/src/main/java/com/imyeyu/api/modules/system/task/status/collector/NetworkStatusCollector.java index 24be298..abc847f 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/status/collector/NetworkStatusCollector.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/status/collector/NetworkStatusCollector.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.system.task.status.collector; -import com.imyeyu.api.modules.common.entity.Setting; +import com.imyeyu.api.modules.system.bean.SystemStatusSetting; import com.imyeyu.api.modules.system.task.status.AbstractDequeStatusCollector; import com.imyeyu.api.modules.system.task.status.StatusCollectContext; import lombok.extern.slf4j.Slf4j; @@ -24,7 +24,7 @@ public class NetworkStatusCollector extends AbstractDequeStatusCollector { @Override public void initialize(StatusCollectContext context) { List networkIFs = context.getHardware().getNetworkIFs(); - String targetMac = context.getSettingService().getSystem(Setting.Module.SystemStatus.NETWORK_MAC).asString(); + String targetMac = context.getSettingService().getSystem(SystemStatusSetting.NETWORK_MAC).asString(); for (NetworkIF networkIF : networkIFs) { if (networkIF.getMacaddr().equals(targetMac)) { networkIF.updateAttributes(); @@ -41,8 +41,8 @@ public class NetworkStatusCollector extends AbstractDequeStatusCollector { @Override public void collect(StatusCollectContext context) { - String targetMac = context.getSettingService().getSystem(Setting.Module.SystemStatus.NETWORK_MAC).asString(); - int sampleRateMs = context.getSettingService().getSystem(Setting.Module.SystemStatus.RATE).asInteger(); + String targetMac = context.getSettingService().getSystem(SystemStatusSetting.NETWORK_MAC).asString(); + int sampleRateMs = context.getSettingService().getSystem(SystemStatusSetting.RATE).asInteger(); for (NetworkIF networkIF : context.getHardware().getNetworkIFs()) { if (networkIF.getMacaddr().equals(targetMac)) { networkIF.updateAttributes(); diff --git a/src/main/java/com/imyeyu/api/modules/user/bean/UserSetting.java b/src/main/java/com/imyeyu/api/modules/user/bean/UserSetting.java new file mode 100644 index 0000000..dfe5688 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/user/bean/UserSetting.java @@ -0,0 +1,35 @@ +package com.imyeyu.api.modules.user.bean; + +import com.imyeyu.api.annotation.SettingBizType; +import com.imyeyu.api.bean.SettingEnum; +import com.imyeyu.api.modules.common.entity.Setting; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * + * + * @author 夜雨 + * @since 2026-04-24 15:03 + */ +@Getter +@SettingBizType("USER") +@AllArgsConstructor +public enum UserSetting implements SettingEnum { + + /** 启用登录 */ + ENABLE_LOGIN(Boolean.TRUE.toString(), Setting.ValueType.BOOLEAN), + + /** 启用注册 */ + ENABLE_REGISTER(Boolean.TRUE.toString(), Setting.ValueType.BOOLEAN), + + /** 允许数据更新 */ + ENABLE_PROFILE_UPDATE(Boolean.TRUE.toString(), Setting.ValueType.BOOLEAN), + + /** 令牌有效期 */ + TOKEN_TTL("7d", Setting.ValueType.TIME); + + final String defaultValue; + + final Setting.ValueType valueType; +} diff --git a/src/main/java/com/imyeyu/api/modules/user/service/implement/UserLoginServiceImplement.java b/src/main/java/com/imyeyu/api/modules/user/service/implement/UserLoginServiceImplement.java index 9f84b4c..9066aa3 100644 --- a/src/main/java/com/imyeyu/api/modules/user/service/implement/UserLoginServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/user/service/implement/UserLoginServiceImplement.java @@ -3,12 +3,12 @@ package com.imyeyu.api.modules.user.service.implement; import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.NotifyDetail; -import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.common.service.SmsService; import com.imyeyu.api.modules.common.vo.SmsCaptchaVerifyRequest; import com.imyeyu.api.modules.user.bean.BootstrapData; +import com.imyeyu.api.modules.user.bean.UserSetting; import com.imyeyu.api.modules.user.entity.User; import com.imyeyu.api.modules.user.service.UserLoginService; import com.imyeyu.api.modules.user.service.UserRoleService; @@ -79,7 +79,7 @@ public class UserLoginServiceImplement implements UserLoginService, TimiJava { @Override public LoginResponse login(String token, String userId) { - Long time = settingService.getSystem(Setting.Module.User.TOKEN_TTL).asTime(); + Long time = settingService.getSystem(UserSetting.TOKEN_TTL).asTime(); long now = Time.now(); long expireAt = now + time; redisUserToken.set(getUserTokenKey(token), userId, expireAt - now); diff --git a/src/main/java/com/imyeyu/api/util/InitBuiltinSetting.java b/src/main/java/com/imyeyu/api/util/InitBuiltinSetting.java new file mode 100644 index 0000000..e8a8237 --- /dev/null +++ b/src/main/java/com/imyeyu/api/util/InitBuiltinSetting.java @@ -0,0 +1,82 @@ +package com.imyeyu.api.util; + +import com.imyeyu.api.bean.SettingEnum; +import com.imyeyu.api.config.dbsource.TimiServerDBConfig; +import com.imyeyu.api.modules.common.entity.Setting; +import com.imyeyu.api.modules.common.service.SettingService; +import com.imyeyu.java.TimiJava; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/// 启动时初始化内建系统配置 +/// +/// @author 夜雨 +/// @since 2026-09-08 +@Component +@RequiredArgsConstructor +@Order(Ordered.HIGHEST_PRECEDENCE) +public class InitBuiltinSetting implements ApplicationRunner { + + /// 设置枚举所在的扫描包 + private static final String SCAN_PACKAGE = "com.imyeyu.api"; + + private final SettingService settingService; + + /// 初始化所有设置枚举对应的系统配置 + /// + /// @param args 启动参数 + /// @throws Exception 初始化异常 + @Override + @Transactional(TimiServerDBConfig.ROLLBACKER) + public void run(ApplicationArguments args) throws Exception { + for (SettingEnum item : findSettingEnumList()) { + if (settingService.getSystem(item) == null) { + Setting setting = new Setting(); + setting.setBizType(item.getBizType()); + setting.setBizId(TimiJava.ZERO_UUID); + setting.setCode(item.name()); + setting.setValue(item.getDefaultValue()); + setting.setValueType(item.getValueType()); + setting.setIsPrivate(true); + settingService.create(setting); + } + } + } + + /// 扫描所有实现设置枚举接口的枚举常量 + /// + /// @return 设置枚举常量列表 + /// @throws ClassNotFoundException 枚举类无法加载 + private List findSettingEnumList() throws ClassNotFoundException { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AssignableTypeFilter(SettingEnum.class)); + + List candidateList = new ArrayList<>(scanner.findCandidateComponents(SCAN_PACKAGE)); + List result = new ArrayList<>(); + for (BeanDefinition candidate : candidateList) { + String className = candidate.getBeanClassName(); + if (className == null) { + continue; + } + Class candidateClass = Class.forName(className); + if (!candidateClass.isEnum() || !SettingEnum.class.isAssignableFrom(candidateClass)) { + continue; + } + for (Object constant : candidateClass.getEnumConstants()) { + result.add((SettingEnum) constant); + } + } + return result; + } +}