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 extends SettingEnum> 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 extends Enum>> 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;
+ }
+}