refactor Setting
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -128,10 +128,15 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.imyeyu.java</groupId>
|
||||
<artifactId>timi-java</artifactId>
|
||||
<version>0.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.imyeyu.spring</groupId>
|
||||
<artifactId>timi-spring</artifactId>
|
||||
<version>0.0.10</version>
|
||||
<version>0.0.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.imyeyu.network</groupId>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.annotation;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -17,8 +17,34 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EnableSetting {
|
||||
|
||||
/** @return 配置键 */
|
||||
SettingKey value();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2026-04-27 14:45
|
||||
*/
|
||||
enum Logic {
|
||||
|
||||
AND,
|
||||
|
||||
OR
|
||||
}
|
||||
|
||||
Setting.Module.User[] user() default {};
|
||||
|
||||
Setting.Module.Comment[] comment() default {};
|
||||
|
||||
Setting.Module.ForeverMC[] foreverMC() default {};
|
||||
|
||||
Setting.Module.Music[] music() default {};
|
||||
|
||||
Setting.Module.Journal[] journal() default {};
|
||||
|
||||
Setting.Module.TempFile[] tempFile() default {};
|
||||
|
||||
Setting.Module.System[] system() default {};
|
||||
|
||||
Logic logic() default Logic.AND;
|
||||
|
||||
/** @return 未启用配置时响应消息语言映射键 */
|
||||
String message() default "service.offline";
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
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 com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 启用配置注解处理器
|
||||
*
|
||||
@@ -24,16 +27,28 @@ public class EnableSettingInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final SettingService service;
|
||||
|
||||
public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) {
|
||||
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;
|
||||
}
|
||||
if (service.is(annotation.value())) {
|
||||
return true;
|
||||
EnableSetting.Logic logic = annotation.logic();
|
||||
List<Boolean> 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.is(anEnum));
|
||||
}
|
||||
}
|
||||
if (logic == EnableSetting.Logic.AND) {
|
||||
return valueList.stream().allMatch(Boolean::booleanValue);
|
||||
} else {
|
||||
return valueList.stream().anyMatch(Boolean::booleanValue);
|
||||
}
|
||||
throw new TimiException(TimiCode.ERROR_SERVICE_OFF, annotation.message());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.imyeyu.api.modules.blog.util;
|
||||
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.config.RedisConfig;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.entity.User;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.common.service.UserService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import com.imyeyu.spring.util.Redis;
|
||||
import com.imyeyu.spring.util.RedisSerializers;
|
||||
@@ -24,7 +24,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Redis 令牌缓存
|
||||
*
|
||||
* <p>一级缓存 Session,二级缓存 Redis,有效期为 {@link SettingKey#TTL_USER_TOKEN} 天,每次触发
|
||||
* <p>一级缓存 Session,二级缓存 Redis,有效期为 {@link com.imyeyu.api.modules.common.entity.Setting.Module.User#TOKEN_TTL} 天,每次触发
|
||||
* 二级缓存获取时会刷新这个时间,即指定天数内不再访问则视为登出
|
||||
*
|
||||
* @author 夜雨
|
||||
@@ -47,12 +47,12 @@ public class UserToken {
|
||||
}
|
||||
|
||||
public Long set(String token, Long userId) {
|
||||
long ttl = Time.D * settingService.getAsInt(SettingKey.TTL_USER_TOKEN);
|
||||
long ttl = settingService.getAsTime(Setting.Module.User.TOKEN_TTL);
|
||||
// 会话
|
||||
TimiSpring.setSessionAttr(token, userId);
|
||||
// 跨站 Cookie
|
||||
Cookie cookie = Objects.requireNonNullElse(TimiSpring.getCookie("Token"), new Cookie("Token", token));
|
||||
cookie.setDomain(settingService.getAsString(SettingKey.DOMAIN_ROOT));
|
||||
cookie.setDomain(settingService.getAsString(Setting.Module.Domain.ROOT));
|
||||
cookie.setPath("/");
|
||||
cookie.setSecure(true);
|
||||
cookie.setMaxAge((int) (ttl / 1000));
|
||||
@@ -136,7 +136,7 @@ public class UserToken {
|
||||
TimiSpring.removeSessionAttr(token);
|
||||
// 清除跨站 Cookie
|
||||
Cookie cookie = new Cookie("Token", "DIED");
|
||||
cookie.setDomain(settingService.getAsString(SettingKey.DOMAIN_ROOT));
|
||||
cookie.setDomain(settingService.getAsString(Setting.Module.Domain.ROOT));
|
||||
cookie.setPath("/");
|
||||
cookie.setSecure(true);
|
||||
cookie.setMaxAge(0);
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
package com.imyeyu.api.modules.common.bean;
|
||||
|
||||
/**
|
||||
* 系统设置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2021-07-20 21:46
|
||||
*/
|
||||
public enum SettingKey {
|
||||
|
||||
// ---------- 通用 ----------
|
||||
|
||||
RUN_ENV,
|
||||
|
||||
PUBLIC_RESOURCES,
|
||||
|
||||
/** 启用注册 */
|
||||
ENABLE_REGISTER,
|
||||
|
||||
/** 启用登录 */
|
||||
ENABLE_LOGIN,
|
||||
|
||||
/** 启用评论 */
|
||||
ENABLE_COMMENT,
|
||||
|
||||
/** 启用测试 */
|
||||
ENABLE_DEBUG,
|
||||
|
||||
/** 启用账号数据更新(User 和 UserProfile) */
|
||||
ENABLE_USER_UPDATE,
|
||||
|
||||
/** 启用灰色滤镜 */
|
||||
ENABLE_GRAY_FILTER,
|
||||
|
||||
TEMP_FILE_PATH,
|
||||
|
||||
// ---------- ICP 备案号 ----------
|
||||
|
||||
ICP_IMYEYU_COM,
|
||||
|
||||
// ---------- 域名 ----------
|
||||
|
||||
DOMAIN_ROOT,
|
||||
|
||||
DOMAIN_API,
|
||||
|
||||
DOMAIN_GIT,
|
||||
|
||||
DOMAIN_BLOG,
|
||||
|
||||
DOMAIN_SPACE,
|
||||
|
||||
DOMAIN_RESOURCE,
|
||||
|
||||
DOMAIN_DOWNLOAD,
|
||||
|
||||
DOMAIN_FOREVER_MC,
|
||||
|
||||
// ---------- ForeverMC ----------
|
||||
|
||||
/** 启用登录服务 */
|
||||
FMC_PLAYER_LOGIN_ENABLE,
|
||||
|
||||
/** 最多绑定玩家数量 */
|
||||
FMC_MAX_BIND,
|
||||
|
||||
/** 闪烁标语 */
|
||||
FMC_SPLASHES,
|
||||
|
||||
/** 启动器背景 */
|
||||
FMC_BG,
|
||||
|
||||
FMC_BGM,
|
||||
|
||||
FMC_BG_SWIPER,
|
||||
|
||||
/** JRE 列表 */
|
||||
FMC_JRE,
|
||||
|
||||
/** 辅助登录模组 */
|
||||
FMC_LOGIN_FABRIC,
|
||||
|
||||
/** 启用图片地图上传 */
|
||||
FMC_ENABLE_IMAGE_MAP_UPLOAD,
|
||||
|
||||
/** 玩家登录令牌有效期(天) */
|
||||
FMC_PLAYER_LOGIN_TOKEN_TTL,
|
||||
|
||||
/** 服务器与数据中心的通信令牌 */
|
||||
FMC_SERVER_TOKEN,
|
||||
|
||||
// ---------- 生存时间 ----------
|
||||
|
||||
TTL_USER_TOKEN,
|
||||
|
||||
TTL_SETTING,
|
||||
|
||||
TTL_MULTILINGUAL,
|
||||
|
||||
// ---------- 多语言翻译 ----------
|
||||
|
||||
MULTILINGUAL_TRANSLATE_API,
|
||||
|
||||
MULTILINGUAL_TRANSLATE_APP_ID,
|
||||
|
||||
MULTILINGUAL_TRANSLATE_KEY,
|
||||
|
||||
// ---------- 账单 ----------
|
||||
|
||||
BILL_API_TOKEN,
|
||||
|
||||
// ---------- Git ----------
|
||||
|
||||
GIT_API,
|
||||
|
||||
GIT_ABOUT_ARTICLE,
|
||||
|
||||
GIT_REPO_PATH,
|
||||
|
||||
// ---------- 远程音乐 ----------
|
||||
|
||||
MUSIC_MAX_FRAME_LENGTH,
|
||||
|
||||
MUSIC_PLAYER_PORT,
|
||||
|
||||
MUSIC_PLAYER_IP,
|
||||
|
||||
MUSIC_CONTROLLER_PORT,
|
||||
|
||||
MUSIC_CONTROLLER_IP,
|
||||
|
||||
MUSIC_CONTROLLER_URI,
|
||||
|
||||
// ---------- 日记 ----------
|
||||
|
||||
JOURNAL_KEY,
|
||||
|
||||
JOURNAL_APP_ID,
|
||||
|
||||
JOURNAL_APP_SECRET,
|
||||
|
||||
JOURNAL_MEMO,
|
||||
|
||||
JOURNAL_OPEN_ID_WHITE_LIST,
|
||||
|
||||
// ---------- 临时文件 ----------
|
||||
|
||||
/** 临时文件最小缓存时间 */
|
||||
TEMP_FILE_TTL_MIN,
|
||||
|
||||
/** 临时文件最长缓存时间 */
|
||||
TEMP_FILE_TTL_MAX,
|
||||
|
||||
/** 临时文件默认缓存时间 */
|
||||
TEMP_FILE_TTL_DEFAULT,
|
||||
|
||||
/** 已过期的临时文件保留时间 */
|
||||
TEMP_FILE_RESIDUE_TIME,
|
||||
|
||||
/** 每个 IP 限制有效临时文件容量 */
|
||||
TEMP_FILE_LIMIT,
|
||||
|
||||
// ---------- 系统 ----------
|
||||
|
||||
SYSTEM_FILE_BASE,
|
||||
|
||||
SYSTEM_FILE_TYPE,
|
||||
|
||||
SYSTEM_FILE_SYNC,
|
||||
|
||||
/** 文件过滤(通过密钥类型) */
|
||||
SYSTEM_FILE_FILTER,
|
||||
|
||||
SYSTEM_STATUS_RATE,
|
||||
|
||||
SYSTEM_STATUS_LIMIT,
|
||||
|
||||
SYSTEM_STATUS_NETWORK_MAC,
|
||||
|
||||
SYSTEM_TERMINAL_TTL,
|
||||
|
||||
SYSTEM_TERMINAL_FILTERS,
|
||||
|
||||
/** 一般密钥 */
|
||||
SYSTEM_API_KEY,
|
||||
|
||||
/** 超级密钥 */
|
||||
SYSTEM_API_SUPER_KEY,
|
||||
|
||||
SYSTEM_REBOOT_COMMAND,
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.imyeyu.api.modules.common.bean;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2026-04-24 00:59
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SettingModule {
|
||||
|
||||
COMMON("通用"),
|
||||
|
||||
DOMAIN("域名"),
|
||||
|
||||
FOREVER_MC("Forever MC"),
|
||||
|
||||
MULTILINGUAL("多语言环境"),
|
||||
|
||||
GIT("Git"),
|
||||
|
||||
MUSIC("远程音乐"),
|
||||
|
||||
JOURNAL("糕雨日记"),
|
||||
|
||||
TEMP_FILE("临时文件"),
|
||||
|
||||
SYSTEM("系统");
|
||||
|
||||
final String title;
|
||||
}
|
||||
@@ -3,9 +3,9 @@ package com.imyeyu.api.modules.common.controller;
|
||||
import com.imyeyu.api.annotation.CaptchaValid;
|
||||
import com.imyeyu.api.annotation.EnableSetting;
|
||||
import com.imyeyu.api.bean.CaptchaFrom;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Comment;
|
||||
import com.imyeyu.api.modules.common.entity.CommentReply;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.CommentReplyService;
|
||||
import com.imyeyu.api.modules.common.service.CommentService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
@@ -39,7 +39,7 @@ public class CommentController {
|
||||
|
||||
@AOPLog
|
||||
@CaptchaValid(CaptchaFrom.COMMENT)
|
||||
@EnableSetting(value = SettingKey.ENABLE_COMMENT, message = "comment.off_service")
|
||||
@EnableSetting(comment = Setting.Module.Comment.ENABLE, message = "comment.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/create")
|
||||
public void create(@Valid @RequestBody CaptchaData<Comment> captchaData) {
|
||||
@@ -59,7 +59,7 @@ public class CommentController {
|
||||
*/
|
||||
@AOPLog
|
||||
@CaptchaValid(CaptchaFrom.COMMENT_REPLY)
|
||||
@EnableSetting(value = SettingKey.ENABLE_COMMENT, message = "comment.off_service")
|
||||
@EnableSetting(comment = Setting.Module.Comment.ENABLE, message = "comment.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/reply/create")
|
||||
public void createReply(@Valid @RequestBody CaptchaData<CommentReply> request) {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.imyeyu.api.modules.common.controller;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.imyeyu.api.bean.CaptchaFrom;
|
||||
import com.imyeyu.api.modules.common.bean.ImageType;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.entity.Task;
|
||||
@@ -70,9 +67,9 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 系统接口
|
||||
@@ -240,64 +237,40 @@ public class CommonController {
|
||||
}
|
||||
|
||||
@RequestRateLimit
|
||||
@GetMapping("/setting/{key}")
|
||||
public String settingByKey(@PathVariable("key") String key, @RequestParam(value = "as", required = false) Setting.Type asType) throws JsonProcessingException {
|
||||
Setting setting = settingService.getByKey(SettingKey.valueOf(key.toUpperCase()));
|
||||
@GetMapping("/setting")
|
||||
public String settingByKey(@RequestParam String module, @RequestParam String key) throws ClassNotFoundException {
|
||||
Setting setting = settingService.getByKey(SettingService.fromModuleKey(module, key));
|
||||
if (setting.isPrivate()) {
|
||||
throw new TimiException(TimiCode.PERMISSION_ERROR);
|
||||
}
|
||||
String result = setting.getValue();
|
||||
if (asType == null) {
|
||||
return result;
|
||||
}
|
||||
switch (asType) {
|
||||
case JSON -> {
|
||||
if (setting.getType() == Setting.Type.YAML) {
|
||||
Map<String, Object> obj = yaml.load(setting.getValue());
|
||||
result = jackson.writeValueAsString(obj);
|
||||
}
|
||||
}
|
||||
case YAML -> {
|
||||
if (setting.getType() == Setting.Type.JSON) {
|
||||
Map<String, Object> obj = jackson.readValue(setting.getValue(), new TypeReference<>() {});
|
||||
result = yaml.dump(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return setting.getValue();
|
||||
}
|
||||
|
||||
@RequestRateLimit
|
||||
@PostMapping("/setting/map")
|
||||
public Map<SettingKey, String> mapSettingByKeys(@RequestBody Map<SettingKey, Map<String, Object>> settingMap) throws JsonProcessingException {
|
||||
List<Setting> result = settingService.listByKeys(new ArrayList<>(settingMap.keySet()));
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
Setting setting = result.get(i);
|
||||
public Map<String, Map<String, String>> mapSettingByKeys(@RequestBody Map<String, List<String>> moduleKeyMap) {
|
||||
List<Enum<?>> keyList = new ArrayList<>();
|
||||
moduleKeyMap.forEach((k, v) -> {
|
||||
try {
|
||||
for (String key : v) {
|
||||
keyList.add(SettingService.fromModuleKey(k, key));
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
Map<String, Map<String, String>> result = new HashMap<>();
|
||||
List<Setting> settingList = settingService.listByKeys(keyList);
|
||||
for (Setting setting : settingList) {
|
||||
if (setting.isPrivate()) {
|
||||
throw new TimiException(TimiCode.PERMISSION_ERROR);
|
||||
}
|
||||
Map<String, Object> args = settingMap.get(setting.getKey());
|
||||
if (args == null) {
|
||||
continue;
|
||||
}
|
||||
if (args.containsKey("as")) {
|
||||
switch (Ref.toType(Setting.Type.class, args.get("as").toString())) {
|
||||
case JSON -> {
|
||||
if (setting.getType() == Setting.Type.YAML) {
|
||||
Map<String, Object> obj = new Yaml().load(setting.getValue());
|
||||
setting.setValue(jackson.writeValueAsString(obj));
|
||||
}
|
||||
}
|
||||
case YAML -> {
|
||||
if (setting.getType() == Setting.Type.JSON) {
|
||||
Map<String, Object> obj = jackson.readValue(setting.getValue(), new TypeReference<>() {});
|
||||
setting.setValue(new Yaml().dump(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result.containsKey(setting.getModule())) {
|
||||
result.put(setting.getKey(), new HashMap<>());
|
||||
}
|
||||
result.get(setting.getModule()).put(setting.getKey(), setting.getValue());
|
||||
}
|
||||
return result.stream().collect(Collectors.toMap(Setting::getKey, Setting::getValue));
|
||||
return result;
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.imyeyu.api.modules.common.controller;
|
||||
import com.imyeyu.api.annotation.CaptchaValid;
|
||||
import com.imyeyu.api.annotation.EnableSetting;
|
||||
import com.imyeyu.api.bean.CaptchaFrom;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Comment;
|
||||
import com.imyeyu.api.modules.common.entity.CommentReply;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.entity.UserConfig;
|
||||
import com.imyeyu.api.modules.common.entity.UserPrivacy;
|
||||
import com.imyeyu.api.modules.common.service.CommentReplyService;
|
||||
@@ -71,7 +71,7 @@ public class UserController implements TimiJava {
|
||||
*/
|
||||
@AOPLog
|
||||
@CaptchaValid(CaptchaFrom.REGISTER)
|
||||
@EnableSetting(value = SettingKey.ENABLE_REGISTER, message = "user.register.off_service")
|
||||
@EnableSetting(user = Setting.Module.User.ENABLE_REGISTER, message = "user.register.off_service")
|
||||
@RequestRateLimit(value = 1, lifeCycle = 60)
|
||||
@PostMapping("/register")
|
||||
public LoginResponse register(@Valid @RequestBody CaptchaData<RegisterRequest> request) {
|
||||
@@ -86,7 +86,7 @@ public class UserController implements TimiJava {
|
||||
*/
|
||||
@AOPLog
|
||||
@CaptchaValid(CaptchaFrom.LOGIN)
|
||||
@EnableSetting(value = SettingKey.ENABLE_LOGIN, message = "user.login.off_service")
|
||||
@EnableSetting(user = Setting.Module.User.ENABLE_LOGIN, message = "user.login.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/login")
|
||||
public LoginResponse login(@Valid @RequestBody CaptchaData<LoginRequest> request) {
|
||||
@@ -99,7 +99,7 @@ public class UserController implements TimiJava {
|
||||
* @return 登录数据
|
||||
*/
|
||||
@AOPLog
|
||||
@EnableSetting(value = SettingKey.ENABLE_LOGIN, message = "user.login.off_service")
|
||||
@EnableSetting(user = Setting.Module.User.ENABLE_LOGIN, message = "user.login.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/login/token")
|
||||
public LoginResponse login4Token() {
|
||||
@@ -207,7 +207,7 @@ public class UserController implements TimiJava {
|
||||
*/
|
||||
@AOPLog
|
||||
@RequiredToken
|
||||
@EnableSetting(value = SettingKey.ENABLE_USER_UPDATE, message = "user.data.off_service")
|
||||
@EnableSetting(user = Setting.Module.User.ENABLE_PROFILE_UPDATE, message = "user.data.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/profile/update")
|
||||
public void updateProfile(@Valid UserRequest data) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.imyeyu.api.modules.common.entity;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.spring.annotation.table.Id;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.imyeyu.spring.annotation.table.Transient;
|
||||
import com.imyeyu.spring.entity.Creatable;
|
||||
import com.imyeyu.spring.entity.Entity;
|
||||
import com.imyeyu.spring.entity.Updatable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
@@ -13,7 +16,9 @@ import lombok.Data;
|
||||
* @since 2021-07-20 21:46
|
||||
*/
|
||||
@Data
|
||||
public class Setting implements Creatable, Updatable {
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Setting extends Entity implements Creatable, Updatable {
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -21,31 +26,377 @@ public class Setting implements Creatable, Updatable {
|
||||
* @author 夜雨
|
||||
* @since 2025-01-10 17:08
|
||||
*/
|
||||
public enum Type {
|
||||
|
||||
INTEGER,
|
||||
public enum ValueType {
|
||||
|
||||
/** 字符串 */
|
||||
STRING,
|
||||
|
||||
JSON,
|
||||
/** 单选 */
|
||||
SELECT_RADIO,
|
||||
|
||||
YAML,
|
||||
/** 多选 */
|
||||
SELECT_CHECKBOX,
|
||||
|
||||
/** 整数 */
|
||||
INTEGER,
|
||||
|
||||
/** 颜色 */
|
||||
COLOR,
|
||||
|
||||
/** 浮点数 */
|
||||
FLOAT,
|
||||
|
||||
/** 日期 */
|
||||
DATE,
|
||||
|
||||
/** 日期时间 */
|
||||
DATETIME,
|
||||
|
||||
/** 时间 */
|
||||
TIME,
|
||||
|
||||
/** 时长 */
|
||||
DURATION,
|
||||
|
||||
/** 布尔值 */
|
||||
BOOLEAN,
|
||||
|
||||
/** JSON 列表 */
|
||||
JSON_LIST,
|
||||
|
||||
/** JSON 对象 */
|
||||
JSON_OBJECT
|
||||
}
|
||||
|
||||
@Id
|
||||
private SettingKey key;
|
||||
private String module;
|
||||
|
||||
private String key;
|
||||
|
||||
private String value;
|
||||
|
||||
private Type type;
|
||||
private ValueType valueType;
|
||||
|
||||
private JsonNode valueArgs;
|
||||
|
||||
private boolean isPrivate;
|
||||
|
||||
private Long createdAt;
|
||||
@Transient
|
||||
private Enum<?> keyRaw;
|
||||
|
||||
private Long updatedAt;
|
||||
public Setting(Enum<?> key) {
|
||||
setKeyRaw(key);
|
||||
}
|
||||
|
||||
public Setting(Enum<?> key, Object value, ValueType valueType) {
|
||||
setKeyRaw(key);
|
||||
this.value = value.toString();
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public void setKeyRaw(Enum<?> key) {
|
||||
this.keyRaw = key;
|
||||
this.module = key.getClass().getSimpleName().toUpperCase();
|
||||
this.key = key.toString();
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return !isPrivate;
|
||||
}
|
||||
|
||||
public boolean is(Enum<?> anEnum) {
|
||||
return anEnum.getClass().getSimpleName().toUpperCase().equals(module) && anEnum.toString().equals(key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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,
|
||||
|
||||
/** 默认头像 */
|
||||
DEFAULT_AVATAR,
|
||||
|
||||
/** 默认封面 */
|
||||
DEFAULT_WRAPPER,
|
||||
|
||||
/** 令牌有效期 */
|
||||
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,
|
||||
|
||||
/** 访问密钥 */
|
||||
KEY,
|
||||
|
||||
/** 微信小程序 AppId */
|
||||
APP_ID,
|
||||
|
||||
/** 微信小程序 AppSecret */
|
||||
APP_SECRET,
|
||||
|
||||
/** 备忘录内容 */
|
||||
MEMO,
|
||||
|
||||
/** 高权限访问 OpenID 白名单(应付审核) */
|
||||
OPEN_ID_WHITE_LIST
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 {
|
||||
|
||||
/** 一般密钥 */
|
||||
API_KEY,
|
||||
|
||||
/** 超级密钥 */
|
||||
API_KEY_SUPER,
|
||||
|
||||
/** 状态采集数据量 */
|
||||
STATUS_LIMIT,
|
||||
|
||||
/** 状态采集网卡 */
|
||||
STATUS_NETWORK_MAC,
|
||||
|
||||
/** 状态采集频率 */
|
||||
STATUS_RATE,
|
||||
|
||||
/** 终端指令过滤 */
|
||||
TERMINAL_FILTERS,
|
||||
|
||||
/** 终端会话有效时长 */
|
||||
TERMINAL_TTL,
|
||||
|
||||
/** 文件系统基准路径 */
|
||||
FILE_BASE_PATH,
|
||||
|
||||
/** 设置缓存时长 */
|
||||
SETTING_TTL,
|
||||
|
||||
/** 哀悼滤镜 */
|
||||
ENABLE_MOURN_FILTER,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.imyeyu.api.modules.common.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
@@ -13,10 +12,7 @@ import java.util.List;
|
||||
* @author 夜雨
|
||||
* @since 2021-07-20 22:26
|
||||
*/
|
||||
public interface SettingMapper extends BaseMapper<Setting, String> {
|
||||
|
||||
@Select("SELECT * FROM `setting` WHERE `key` = #{key}")
|
||||
Setting selectByKey(SettingKey key);
|
||||
public interface SettingMapper extends BaseMapper<Setting, Long> {
|
||||
|
||||
@Select("SELECT * FROM `setting`")
|
||||
List<Setting> listAll();
|
||||
|
||||
@@ -4,13 +4,14 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.service.UpdatableService;
|
||||
import com.imyeyu.java.ref.Ref;
|
||||
import com.imyeyu.spring.service.BaseService;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 系统配置服务
|
||||
@@ -18,15 +19,21 @@ import java.util.List;
|
||||
* @author 夜雨
|
||||
* @since 2021-07-20 22:06
|
||||
*/
|
||||
public interface SettingService extends UpdatableService<Setting> {
|
||||
public interface SettingService extends BaseService<Setting, Long> {
|
||||
|
||||
default List<Setting> listByKeys(SettingKey... keys) {
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends Enum<?>> T fromModuleKey(String module, String key) throws ClassNotFoundException {
|
||||
Class<?> moduleClass = Class.forName(String.format("com.imyeyu.api.modules.common.entity.Setting$Module$%s", module));
|
||||
return Ref.toType((Class<T>) moduleClass, key);
|
||||
}
|
||||
|
||||
default List<Setting> listByKeys(Enum<?>... keys) {
|
||||
return listByKeys(Arrays.asList(keys));
|
||||
}
|
||||
|
||||
List<Setting> listByKeys(List<SettingKey> keyList);
|
||||
List<Setting> listByKeys(List<Enum<?>> keyList);
|
||||
|
||||
Setting getByKey(SettingKey key);
|
||||
Setting getByKey(Enum<?> key);
|
||||
|
||||
/**
|
||||
* 获取指定类型配置值字符串
|
||||
@@ -34,13 +41,15 @@ public interface SettingService extends UpdatableService<Setting> {
|
||||
* @param key 键
|
||||
* @return 配置值
|
||||
*/
|
||||
String getAsString(SettingKey key);
|
||||
String getAsString(Enum<?> key);
|
||||
|
||||
int getAsInt(SettingKey key);
|
||||
int getAsInt(Enum<?> key);
|
||||
|
||||
long getAsLong(SettingKey key);
|
||||
long getAsLong(Enum<?> key);
|
||||
|
||||
double getAsDouble(SettingKey key);
|
||||
double getAsDouble(Enum<?> key);
|
||||
|
||||
long getAsTime(Enum<?> key);
|
||||
|
||||
/**
|
||||
* 获取为布尔值
|
||||
@@ -49,7 +58,7 @@ public interface SettingService extends UpdatableService<Setting> {
|
||||
* @return 配置值
|
||||
* @throws TimiException 服务异常
|
||||
*/
|
||||
boolean is(SettingKey key);
|
||||
boolean is(Enum<?> key);
|
||||
|
||||
/**
|
||||
* 获取为布尔值,并取反
|
||||
@@ -58,23 +67,23 @@ public interface SettingService extends UpdatableService<Setting> {
|
||||
* @return 配置值
|
||||
* @throws TimiException 服务异常
|
||||
*/
|
||||
boolean not(SettingKey key);
|
||||
boolean not(Enum<?> key);
|
||||
|
||||
JsonNode getAsJsonNode(SettingKey key);
|
||||
JsonNode getAsJsonNode(Enum<?> key);
|
||||
|
||||
ObjectNode getAsJsonObject(SettingKey key);
|
||||
ObjectNode getAsJsonObject(Enum<?> key);
|
||||
|
||||
ArrayNode getAsArrayNode(SettingKey key);
|
||||
ArrayNode getAsArrayNode(Enum<?> key);
|
||||
|
||||
<T> T fromJson(SettingKey key, Class<T> clazz);
|
||||
Set<String> getAsSet(Enum<?> key);
|
||||
|
||||
<T> T fromJson(SettingKey key, TypeReference<T> typeReference);
|
||||
List<String> getAsList(Enum<?> key);
|
||||
|
||||
<T> T fromYaml(SettingKey key, Class<T> clazz);
|
||||
<T> T fromJson(Enum<?> key, Class<T> clazz);
|
||||
|
||||
<T> T fromJson(Enum<?> key, TypeReference<T> typeReference);
|
||||
|
||||
<T> T fromYaml(Enum<?> key, Class<T> clazz);
|
||||
|
||||
List<Setting> listAll();
|
||||
|
||||
void clearCache(SettingKey key);
|
||||
|
||||
void flushCache();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.imyeyu.api.modules.common.service.implement;
|
||||
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.Language;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||
import com.imyeyu.api.modules.common.mapper.MultilingualMapper;
|
||||
import com.imyeyu.api.modules.common.service.MultilingualService;
|
||||
@@ -66,7 +66,7 @@ public class MultilingualServiceImplement extends AbstractEntityService<Multilin
|
||||
if (result == null) {
|
||||
throw new TimiException(TimiCode.RESULT_NULL).msgKey("TODO not found language");
|
||||
}
|
||||
redisLanguage.set(id, result, Time.D * settingService.getAsInt(SettingKey.TTL_MULTILINGUAL));
|
||||
redisLanguage.set(id, result, settingService.getAsTime(Setting.Module.Multilingual.CACHE_TTL));
|
||||
}
|
||||
return result.getValue(language);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ public class MultilingualServiceImplement extends AbstractEntityService<Multilin
|
||||
log.warn("not found language for key: {}", key);
|
||||
return key;
|
||||
}
|
||||
long ttl = Time.D * settingService.getAsInt(SettingKey.TTL_MULTILINGUAL);
|
||||
long ttl = settingService.getAsTime(Setting.Module.Multilingual.CACHE_TTL);
|
||||
redisLanguage.set(result.getId(), result, ttl);
|
||||
redisLanguageMap.set(result.getKey(), result.getId(), ttl);
|
||||
return result.getValue(language);
|
||||
|
||||
@@ -6,24 +6,27 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
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.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.mapper.SettingMapper;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.CallbackArg;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
import com.imyeyu.spring.util.Redis;
|
||||
import com.imyeyu.utils.Time;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 系统配置服务实现
|
||||
@@ -34,30 +37,57 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SettingServiceImplement extends AbstractEntityService<Setting, String> implements SettingService {
|
||||
public class SettingServiceImplement extends AbstractEntityService<Setting, Long> implements SettingService {
|
||||
|
||||
/** 缓存键模板,参数:module, key */
|
||||
private static final String CACHE_KEY_TMPL = "%s:%s";
|
||||
|
||||
private final SettingMapper mapper;
|
||||
private final Redis<String, String> redisSetting;
|
||||
|
||||
private final ObjectMapper jackson;
|
||||
|
||||
@PostConstruct
|
||||
private void initialize() {
|
||||
CallbackArg<Setting> createIfNotExist = setting -> {
|
||||
Setting dbSetting = mapper.selectByExample(new Setting(setting.getKeyRaw()));
|
||||
if (dbSetting == null) {
|
||||
create(setting);
|
||||
}
|
||||
};
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.SETTING_TTL, "10m", Setting.ValueType.DURATION));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.API_KEY, "[]", Setting.ValueType.JSON_LIST));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.API_KEY_SUPER, "[]", Setting.ValueType.JSON_LIST));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.STATUS_RATE, 3000, Setting.ValueType.INTEGER));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.STATUS_LIMIT, 2048, Setting.ValueType.INTEGER));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.System.STATUS_NETWORK_MAC, "", Setting.ValueType.STRING));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.Music.ENABLE, false, Setting.ValueType.BOOLEAN));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.Journal.KEY, "[]", Setting.ValueType.JSON_LIST));
|
||||
createIfNotExist.handler(new Setting(Setting.Module.Journal.OPEN_ID_WHITE_LIST, "[]", Setting.ValueType.JSON_LIST));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void postConstruct() {
|
||||
redisSetting.flushAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseMapper<Setting, String> mapper() {
|
||||
protected BaseMapper<Setting, Long> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Setting setting) {
|
||||
super.update(setting);
|
||||
clearCache(setting.getKey());
|
||||
redisSetting.destroy(CACHE_KEY_TMPL.formatted(setting.getModule(), setting.getKey()));
|
||||
}
|
||||
|
||||
public Setting getByKey(SettingKey key) {
|
||||
public Setting getByKey(Enum<?> key) {
|
||||
if (key == null) {
|
||||
throw new TimiException(TimiCode.ARG_MISS).msgKey("key can not be null");
|
||||
}
|
||||
|
||||
String cacheValue = redisSetting.get(key.toString());
|
||||
String cacheKey = CACHE_KEY_TMPL.formatted(key.getClass().getSimpleName().toUpperCase(), key.toString());
|
||||
String cacheValue = redisSetting.get(cacheKey);
|
||||
if (TimiJava.isNotEmpty(cacheValue)) {
|
||||
try {
|
||||
return jackson.readValue(cacheValue, Setting.class);
|
||||
@@ -65,19 +95,21 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
||||
throw new TimiException(TimiCode.ERROR, "read setting cache error", e);
|
||||
}
|
||||
}
|
||||
Setting setting = mapper.selectByKey(key);
|
||||
Setting setting = mapper.selectByExample(new Setting(key));
|
||||
TimiException.required(setting, "not found setting: %s.%s".formatted(key.getClass().getName(), key));
|
||||
if (TimiJava.isEmpty(setting.getValue())) {
|
||||
// 无需缓存
|
||||
return setting;
|
||||
}
|
||||
int settingTTL;
|
||||
if (key == SettingKey.TTL_SETTING) {
|
||||
settingTTL = Integer.parseInt(setting.getValue());
|
||||
long settingTTL;
|
||||
if (setting.is(Setting.Module.System.SETTING_TTL)) {
|
||||
settingTTL = Time.parseToMS(setting.getValue());
|
||||
} else {
|
||||
settingTTL = Integer.parseInt(getByKey(SettingKey.TTL_SETTING).getValue());
|
||||
settingTTL = Time.parseToMS(getByKey(Setting.Module.System.SETTING_TTL).getValue());
|
||||
}
|
||||
if (0 < settingTTL) {
|
||||
try {
|
||||
redisSetting.set(key.toString(), jackson.writeValueAsString(setting), Time.M * settingTTL);
|
||||
redisSetting.set(key.toString(), jackson.writeValueAsString(setting), settingTTL);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new TimiException(TimiCode.ERROR, "write setting cache error", e);
|
||||
}
|
||||
@@ -86,46 +118,51 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Setting> listByKeys(List<SettingKey> keyList) {
|
||||
public List<Setting> listByKeys(List<Enum<?>> keyList) {
|
||||
List<Setting> result = new ArrayList<>();
|
||||
for (int i = 0; i < keyList.size(); i++) {
|
||||
result.add(getByKey(keyList.get(i)));
|
||||
for (Enum<?> anEnum : keyList) {
|
||||
result.add(getByKey(anEnum));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString(SettingKey key) {
|
||||
public String getAsString(Enum<?> key) {
|
||||
return getByKey(key).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAsInt(SettingKey key) {
|
||||
public int getAsInt(Enum<?> key) {
|
||||
return Integer.parseInt(getAsString(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAsLong(SettingKey key) {
|
||||
public long getAsLong(Enum<?> key) {
|
||||
return Long.parseLong(getAsString(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAsDouble(SettingKey key) {
|
||||
public double getAsDouble(Enum<?> key) {
|
||||
return Double.parseDouble(getAsString(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(SettingKey key) {
|
||||
public long getAsTime(Enum<?> key) {
|
||||
return Time.parseToMS(getAsString(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(Enum<?> key) {
|
||||
return Boolean.parseBoolean(getAsString(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean not(SettingKey key) {
|
||||
public boolean not(Enum<?> key) {
|
||||
return !is(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonNode getAsJsonNode(SettingKey key) {
|
||||
public JsonNode getAsJsonNode(Enum<?> key) {
|
||||
try {
|
||||
return jackson.readTree(getAsString(key));
|
||||
} catch (JsonProcessingException e) {
|
||||
@@ -134,17 +171,27 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectNode getAsJsonObject(SettingKey key) {
|
||||
public ObjectNode getAsJsonObject(Enum<?> key) {
|
||||
return (ObjectNode) getAsJsonNode(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayNode getAsArrayNode(SettingKey key) {
|
||||
public ArrayNode getAsArrayNode(Enum<?> key) {
|
||||
return (ArrayNode) getAsJsonNode(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(SettingKey key, Class<T> clazz) {
|
||||
public Set<String> getAsSet(Enum<?> key) {
|
||||
return new HashSet<>(getAsList(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAsList(Enum<?> key) {
|
||||
return getAsArrayNode(key).valueStream().map(JsonNode::asText).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(Enum<?> key, Class<T> clazz) {
|
||||
try {
|
||||
return jackson.treeToValue(getAsJsonNode(key), clazz);
|
||||
} catch (JsonProcessingException e) {
|
||||
@@ -153,11 +200,11 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(SettingKey key, TypeReference<T> typeReference) {
|
||||
public <T> T fromJson(Enum<?> key, TypeReference<T> typeReference) {
|
||||
return jackson.convertValue(getAsJsonNode(key), typeReference);
|
||||
}
|
||||
|
||||
public <T> T fromYaml(SettingKey key, Class<T> clazz) {
|
||||
public <T> T fromYaml(Enum<?> key, Class<T> clazz) {
|
||||
return new Yaml().loadAs(getAsString(key), clazz);
|
||||
}
|
||||
|
||||
@@ -165,14 +212,4 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
||||
public List<Setting> listAll() {
|
||||
return mapper.listAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache(SettingKey key) {
|
||||
redisSetting.destroy(key.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushCache() {
|
||||
redisSetting.flushAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.modules.common.service.implement;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
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.TempFileService;
|
||||
@@ -33,15 +33,15 @@ public class TempFileServiceImplement implements TempFileService {
|
||||
private final AttachmentService attachmentService;
|
||||
|
||||
public List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException {
|
||||
String ttlMinStr = settingService.getAsString(SettingKey.TEMP_FILE_TTL_MIN);
|
||||
String ttlMaxStr = settingService.getAsString(SettingKey.TEMP_FILE_TTL_MAX);
|
||||
String limitStr = settingService.getAsString(SettingKey.TEMP_FILE_LIMIT);
|
||||
String ttlMinStr = settingService.getAsString(Setting.Module.TempFile.TTL_MIN);
|
||||
String ttlMaxStr = settingService.getAsString(Setting.Module.TempFile.TTL_MAX);
|
||||
String limitStr = settingService.getAsString(Setting.Module.TempFile.LIMIT_SIZE_OF_IP);
|
||||
|
||||
long minTTL = Time.parseToMS(ttlMinStr);
|
||||
long maxTTL = Time.parseToMS(ttlMaxStr);
|
||||
long defaultTTL = Time.parseToMS(settingService.getAsString(SettingKey.TEMP_FILE_TTL_DEFAULT));
|
||||
long defaultTTL = Time.parseToMS(settingService.getAsString(Setting.Module.TempFile.TTL_DEFAULT));
|
||||
long limit = IOSize.parse(limitStr);
|
||||
long residueTime = Time.parseToMS(settingService.getAsString(SettingKey.TEMP_FILE_RESIDUE_TIME));
|
||||
long residueTime = Time.parseToMS(settingService.getAsString(Setting.Module.TempFile.RESIDUE_TTL));
|
||||
|
||||
ttl = TimiJava.defaultIfNull(ttl, defaultTTL);
|
||||
TimiException.requiredTrue(minTTL < ttl && ttl <= maxTTL, String.format("ttl must be between %s and %s", ttlMinStr, ttlMaxStr));
|
||||
@@ -65,9 +65,7 @@ public class TempFileServiceImplement implements TempFileService {
|
||||
|
||||
long deletedAt = Time.now() + ttl;
|
||||
long destroyAt = deletedAt + residueTime;
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
MultipartFile file = files.get(i);
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
Attachment attach = new Attachment();
|
||||
attach.setBizType(Attachment.BizType.TEMP_FILE);
|
||||
attach.setName(file.getOriginalFilename());
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.imyeyu.api.modules.common.task;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.MultilingualService;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
@@ -131,8 +131,8 @@ public class MultilingualTranslateTask {
|
||||
private synchronized Map<String, String> doTranslate(String text, BaiduLanguage to) throws Exception {
|
||||
String random = String.valueOf(Time.now());
|
||||
|
||||
String appId = settingService.getAsString(SettingKey.MULTILINGUAL_TRANSLATE_APP_ID);
|
||||
String key = settingService.getAsString(SettingKey.MULTILINGUAL_TRANSLATE_KEY);
|
||||
String appId = settingService.getAsString(Setting.Module.Multilingual.TRANSLATE_APP_ID);
|
||||
String key = settingService.getAsString(Setting.Module.Multilingual.TRANSLATE_KEY);
|
||||
|
||||
ArgMap<String, Object> args = new ArgMap<>();
|
||||
args.put("q", text);
|
||||
@@ -142,7 +142,7 @@ public class MultilingualTranslateTask {
|
||||
args.put("salt", random);
|
||||
args.put("sign", Digest.md5(appId + text + random + key));
|
||||
|
||||
String response = Request.post(settingService.getAsString(SettingKey.MULTILINGUAL_TRANSLATE_API))
|
||||
String response = Request.post(settingService.getAsString(Setting.Module.Multilingual.TRANSLATE_API))
|
||||
.bodyForm(args.toNameValuePair())
|
||||
.execute()
|
||||
.returnContent()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.imyeyu.api.modules.git.bean.gitea;
|
||||
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.api.TimiServerAPI;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.utils.Encoder;
|
||||
import com.imyeyu.utils.StringInterpolator;
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Map;
|
||||
* @author 夜雨
|
||||
* @since 2025-06-26 16:04
|
||||
*/
|
||||
public enum API {
|
||||
public enum GiteaAPI {
|
||||
|
||||
REPO_LIST("/api/v1/repos/search"),
|
||||
|
||||
@@ -36,7 +36,7 @@ public enum API {
|
||||
|
||||
final String uri;
|
||||
|
||||
API(String uri) {
|
||||
GiteaAPI(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public enum API {
|
||||
public String buildURL(Map<String, Object> argsURI, Map<String, Object> argsURL) {
|
||||
SettingService settingService = TimiServerAPI.applicationContext.getBean(SettingService.class);
|
||||
StringBuilder url = new StringBuilder();
|
||||
url.append(settingService.getAsString(SettingKey.GIT_API));
|
||||
url.append(settingService.getAsString(Setting.Module.Gitea.API));
|
||||
url.append(INTERPOLATOR.inject(uri, argsURI));
|
||||
if (TimiJava.isNotEmpty(argsURL)) {
|
||||
url.append("?");
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.imyeyu.api.modules.git.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.imyeyu.api.annotation.EnableSetting;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.git.entity.Developer;
|
||||
import com.imyeyu.api.modules.git.service.DeveloperService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.annotation.RequiredToken;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -34,7 +34,7 @@ public class DeveloperController {
|
||||
|
||||
@AOPLog
|
||||
@RequiredToken
|
||||
@EnableSetting(value = SettingKey.ENABLE_USER_UPDATE, message = "user.data.off_service")
|
||||
@EnableSetting(user = Setting.Module.User.ENABLE_PROFILE_UPDATE, message = "user.data.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/update")
|
||||
public void update(@RequestBody Developer developer) {
|
||||
|
||||
@@ -3,21 +3,21 @@ package com.imyeyu.api.modules.git.service.implement;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.network.Network;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.common.service.UserService;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.API;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.Branch;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.File;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.GiteaAPI;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.GiteaResponse;
|
||||
import com.imyeyu.api.modules.git.bean.gitea.Repository;
|
||||
import com.imyeyu.api.modules.git.service.RepositoryService;
|
||||
import com.imyeyu.api.modules.gitea.entity.User;
|
||||
import com.imyeyu.api.modules.gitea.service.GiteaService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.network.Network;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import jakarta.activation.MimetypesFileTypeMap;
|
||||
@@ -72,7 +72,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public PageResult<Repository> page(Page page) {
|
||||
try {
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(API.REPO_LIST.buildURL(null, new HashMap<>() {{
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(GiteaAPI.REPO_LIST.buildURL(null, new HashMap<>() {{
|
||||
put("uid", owner.getId());
|
||||
put("sort", "updated");
|
||||
put("order", "desc");
|
||||
@@ -95,7 +95,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public Repository get(String repoName) {
|
||||
try {
|
||||
String respText = Request.get(API.REPO_GET.buildURL(new HashMap<>() {{
|
||||
String respText = Request.get(GiteaAPI.REPO_GET.buildURL(new HashMap<>() {{
|
||||
put("owner", owner.getName());
|
||||
put("repoName", repoName);
|
||||
}})).execute().returnContent().asString();
|
||||
@@ -109,7 +109,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public List<Branch> listBranches(String repoName) {
|
||||
try {
|
||||
String respText = Request.get(API.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{
|
||||
String respText = Request.get(GiteaAPI.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{
|
||||
put("owner", owner.getName());
|
||||
put("repoName", repoName);
|
||||
}})).execute().returnContent().asString();
|
||||
@@ -123,7 +123,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public List<File> listFile(String repoName, String branch, String path) {
|
||||
try {
|
||||
String respText = Request.get(API.REPO_FILE_LIST.buildURL(new HashMap<>() {{
|
||||
String respText = Request.get(GiteaAPI.REPO_FILE_LIST.buildURL(new HashMap<>() {{
|
||||
put("owner", owner.getName());
|
||||
put("repoName", repoName);
|
||||
put("path", path);
|
||||
@@ -152,7 +152,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public InputStream getFileRaw(String repoName, String branch, String path) {
|
||||
try {
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(API.REPO_FILE_RAW.buildURL(new HashMap<>() {{
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(GiteaAPI.REPO_FILE_RAW.buildURL(new HashMap<>() {{
|
||||
put("owner", owner.getName());
|
||||
put("repoName", repoName);
|
||||
put("path", path);
|
||||
@@ -169,7 +169,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public String getFileMimeType(String repoName, String branch, String path) {
|
||||
try {
|
||||
String repoPath = settingService.getAsString(SettingKey.GIT_REPO_PATH);
|
||||
String repoPath = settingService.getAsString(Setting.Module.Gitea.REPOSITORY_PATH);
|
||||
if (TimiJava.isEmpty(repoPath)) {
|
||||
// 根据文件名猜测
|
||||
return new MimetypesFileTypeMap().getContentType(Network.uriFileName(path));
|
||||
@@ -210,7 +210,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
||||
@Override
|
||||
public InputStream getArchive(String repoName, String branch) {
|
||||
try {
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(API.REPO_ARCHIVE.buildURL(new HashMap<>() {{
|
||||
ClassicHttpResponse resp = (ClassicHttpResponse) Request.get(GiteaAPI.REPO_ARCHIVE.buildURL(new HashMap<>() {{
|
||||
put("owner", owner.getName());
|
||||
put("repoName", repoName);
|
||||
put("archiveFormat", "%s.tar.gz".formatted(branch));
|
||||
|
||||
@@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.imyeyu.api.bean.PreviewPage;
|
||||
import com.imyeyu.api.bean.wechat.InitCodeResponse;
|
||||
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
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.journal.bean.RequiredUploadPermission;
|
||||
@@ -68,8 +68,8 @@ public class JournalController {
|
||||
public String initOpenId(@RequestBody String code) {
|
||||
try {
|
||||
ArgMap<String, String> args = new ArgMap<>();
|
||||
args.put("appid", settingService.getAsString(SettingKey.JOURNAL_APP_ID));
|
||||
args.put("secret", settingService.getAsString(SettingKey.JOURNAL_APP_SECRET));
|
||||
args.put("appid", settingService.getAsString(Setting.Module.Journal.APP_ID));
|
||||
args.put("secret", settingService.getAsString(Setting.Module.Journal.APP_SECRET));
|
||||
args.put("js_code", code);
|
||||
args.put("grant_type", "authorization_code");
|
||||
String response = org.apache.hc.client5.http.fluent.Request.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session"))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.imyeyu.api.modules.journal.controller;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.journal.bean.RequiredUploadPermission;
|
||||
@@ -26,13 +25,13 @@ public class ToolController {
|
||||
|
||||
@GetMapping("/memo")
|
||||
public String getMemo() {
|
||||
return settingService.getAsString(SettingKey.JOURNAL_MEMO);
|
||||
return settingService.getAsString(Setting.Module.Journal.MEMO);
|
||||
}
|
||||
|
||||
@RequiredUploadPermission
|
||||
@PostMapping("/memo/update")
|
||||
public void updateMemo(@RequestBodyValue String data) {
|
||||
Setting setting = settingService.getByKey(SettingKey.JOURNAL_MEMO);
|
||||
Setting setting = settingService.getByKey(Setting.Module.Journal.MEMO);
|
||||
setting.setValue(data);
|
||||
settingService.update(setting);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.modules.journal.util;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.journal.bean.RequiredUploadPermission;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
@@ -36,8 +36,8 @@ public class JournalAPIInterceptor implements HandlerInterceptor {
|
||||
|
||||
@PostConstruct
|
||||
private void postConstruct() {
|
||||
keys = Set.of(settingService.getAsString(SettingKey.JOURNAL_KEY).split(","));
|
||||
openIds = Set.of(settingService.getAsString(SettingKey.JOURNAL_OPEN_ID_WHITE_LIST).split(","));
|
||||
keys = settingService.getAsSet(Setting.Module.Journal.KEY);
|
||||
openIds = settingService.getAsSet(Setting.Module.Journal.OPEN_ID_WHITE_LIST);
|
||||
}
|
||||
|
||||
public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
package com.imyeyu.api.modules.minecraft.annotation;
|
||||
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
@@ -41,9 +37,9 @@ public class RequiredFMCServerTokenInterceptor implements HandlerInterceptor {
|
||||
if (requiredFMCServerToken == null) {
|
||||
return true;
|
||||
}
|
||||
if (!settingService.getAsString(SettingKey.FMC_SERVER_TOKEN).equals(TimiSpring.getToken())) {
|
||||
throw new TimiException(TimiCode.ARG_MISS).msgKey("token.illegal");
|
||||
}
|
||||
// if (!settingService.getAsString(SettingKey.FMC_SERVER_TOKEN).equals(TimiSpring.getToken())) {
|
||||
// throw new TimiException(TimiCode.ARG_MISS).msgKey("token.illegal");
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package com.imyeyu.api.modules.minecraft.controller;
|
||||
|
||||
import com.imyeyu.api.modules.blog.util.UserToken;
|
||||
import com.imyeyu.api.modules.minecraft.service.FMCImageMapService;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.annotation.RequiredToken;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.annotation.EnableSetting;
|
||||
import com.imyeyu.api.modules.blog.util.UserToken;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.minecraft.service.FMCImageMapService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.annotation.RequiredToken;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -50,7 +48,6 @@ public class MinecraftController {
|
||||
*/
|
||||
@AOPLog
|
||||
@RequiredToken
|
||||
@EnableSetting(value = SettingKey.FMC_ENABLE_IMAGE_MAP_UPLOAD, message = "minecraft.fmc_image_map.off_service")
|
||||
@RequestRateLimit
|
||||
@PostMapping("/imagemap/upload")
|
||||
public String uploadFMCImageMap(@NotNull @RequestParam("request") MultipartFile file) {
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
package com.imyeyu.api.modules.minecraft.controller;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.annotation.EnableSetting;
|
||||
import com.imyeyu.api.config.RedisConfig;
|
||||
import com.imyeyu.api.modules.blog.util.UserToken;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.UserService;
|
||||
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
|
||||
import com.imyeyu.api.modules.minecraft.service.PlayerService;
|
||||
import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
|
||||
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.annotation.RequiredToken;
|
||||
import com.imyeyu.spring.util.Redis;
|
||||
import com.imyeyu.spring.util.RedisSerializers;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -62,7 +60,6 @@ public class PlayerController {
|
||||
* @return true 为已绑定
|
||||
*/
|
||||
@RequestRateLimit
|
||||
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
|
||||
@GetMapping("/bound/{name}")
|
||||
public boolean isBound(@PathVariable("name") String name) {
|
||||
return service.getByName(name) != null;
|
||||
@@ -110,7 +107,6 @@ public class PlayerController {
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
|
||||
@PostMapping("/login")
|
||||
public TokenResponse login(@RequestBody Long playerId, @RequestHeader("Token") String token) {
|
||||
return service.login(playerId, token);
|
||||
@@ -118,7 +114,6 @@ public class PlayerController {
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
|
||||
@PostMapping("/login/token")
|
||||
public TokenResponse genLoginToken(@Valid @RequestBody TokenRequest request) {
|
||||
return service.genLoginToken(request);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.imyeyu.api.modules.minecraft.service.implement;
|
||||
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.config.RedisConfig;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.entity.User;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.common.service.UserService;
|
||||
@@ -12,6 +10,8 @@ import com.imyeyu.api.modules.minecraft.mapper.PlayerMapper;
|
||||
import com.imyeyu.api.modules.minecraft.service.PlayerService;
|
||||
import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
|
||||
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
@@ -62,11 +62,12 @@ public class PlayerServiceImplement extends AbstractEntityService<MinecraftPlaye
|
||||
}
|
||||
// 自查重
|
||||
List<MinecraftPlayer> playerList = listByUserId(player.getUserId());
|
||||
if (settingService.getAsInt(SettingKey.FMC_MAX_BIND) <= playerList.size()) {
|
||||
throw new TimiException(TimiCode.RESULT_BAD).msgKey("已达到最大绑定数量:%s 个".formatted(settingService.getAsInt(SettingKey.FMC_MAX_BIND)));
|
||||
int maxValue = settingService.getAsInt(Setting.Module.ForeverMC.PLAYER_BIND_MAX);
|
||||
if (maxValue <= playerList.size()) {
|
||||
throw new TimiException(TimiCode.RESULT_BAD).msgKey("已达到最大绑定数量:%s 个".formatted(maxValue));
|
||||
}
|
||||
for (int i = 0; i < playerList.size(); i++) {
|
||||
if (playerList.get(i).getName().equals(player.getName())) {
|
||||
for (MinecraftPlayer minecraftPlayer : playerList) {
|
||||
if (minecraftPlayer.getName().equals(player.getName())) {
|
||||
throw new TimiException(TimiCode.RESULT_BAD).msgKey("已绑定此玩家名称");
|
||||
}
|
||||
}
|
||||
@@ -113,7 +114,7 @@ public class PlayerServiceImplement extends AbstractEntityService<MinecraftPlaye
|
||||
mapper.update(player);
|
||||
|
||||
String playerToken = UUID.randomUUID().toString();
|
||||
long ttl = settingService.getAsInt(SettingKey.FMC_PLAYER_LOGIN_TOKEN_TTL) * Time.D;
|
||||
long ttl = settingService.getAsTime(Setting.Module.ForeverMC.LOGIN_TOKEN_TTL);
|
||||
redis.set(playerToken, playerId, ttl);
|
||||
return new TokenResponse(userId, playerToken, Time.now() + ttl);
|
||||
}
|
||||
@@ -135,7 +136,8 @@ public class PlayerServiceImplement extends AbstractEntityService<MinecraftPlaye
|
||||
user = userService.get(playerByName.getUserId());
|
||||
}
|
||||
if (user == null) {
|
||||
throw new TimiException(TimiCode.RESULT_NULL).msgKey("未注册或绑定此玩家昵称,请到 https://%s 进行注册或绑定".formatted(settingService.getAsString(SettingKey.DOMAIN_SPACE)));
|
||||
String spaceDomain = settingService.getAsString(Setting.Module.Domain.SPACE);
|
||||
throw new TimiException(TimiCode.RESULT_NULL).msgKey("未注册或绑定此玩家昵称,请到 https://%s 进行注册或绑定".formatted(spaceDomain));
|
||||
}
|
||||
if (user.isBanning()) {
|
||||
throw new TimiException(TimiCode.RESULT_BAN).msgKey("账号封禁中");
|
||||
@@ -144,7 +146,7 @@ public class PlayerServiceImplement extends AbstractEntityService<MinecraftPlaye
|
||||
throw new TimiException(TimiCode.ARG_BAD).msgKey("密码错误");
|
||||
}
|
||||
String token = UUID.randomUUID().toString();
|
||||
long ttl = settingService.getAsInt(SettingKey.FMC_PLAYER_LOGIN_TOKEN_TTL) * Time.D;
|
||||
long ttl = settingService.getAsTime(Setting.Module.ForeverMC.LOGIN_TOKEN_TTL);
|
||||
redis.set(token, user.getId(), ttl);
|
||||
return new TokenResponse(user.getId(), token, Time.now() + ttl);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
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.handler.ControllerMessageHandler;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
@@ -24,10 +28,6 @@ import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.api.config.CORSConfig;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.music.handler.ControllerMessageHandler;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
@@ -63,6 +63,10 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application
|
||||
}
|
||||
|
||||
public void run(ApplicationArguments args) {
|
||||
if (settingService.not(Setting.Module.Music.ENABLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DefaultFullHttpResponse NFP = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
|
||||
final DefaultFullHttpResponse BRP = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST);
|
||||
|
||||
@@ -72,7 +76,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
bootstrap.group(boss, worker);
|
||||
bootstrap.channel(NioServerSocketChannel.class);
|
||||
bootstrap.localAddress(new InetSocketAddress(settingService.getAsInt(SettingKey.MUSIC_CONTROLLER_PORT)));
|
||||
bootstrap.localAddress(new InetSocketAddress(settingService.getAsInt(Setting.Module.Music.CONTROLLER_PORT)));
|
||||
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
@@ -86,7 +90,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.getAsString(SettingKey.MUSIC_CONTROLLER_URI))) {
|
||||
if (!req.uri().equals(settingService.getAsString(Setting.Module.Music.CONTROLLER_URI))) {
|
||||
// 访问的路径不是 Web Socket 的端点地址,响应 404
|
||||
ctx.channel().writeAndFlush(NFP).addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
@@ -108,10 +112,10 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application
|
||||
});
|
||||
pipeline.addLast(new WebSocketServerCompressionHandler());
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler(
|
||||
settingService.getAsString(SettingKey.MUSIC_CONTROLLER_URI),
|
||||
settingService.getAsString(Setting.Module.Music.CONTROLLER_URI),
|
||||
null,
|
||||
true,
|
||||
settingService.getAsInt(SettingKey.MUSIC_MAX_FRAME_LENGTH)
|
||||
settingService.getAsInt(Setting.Module.Music.MAX_FRAME_LENGTH)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -120,7 +124,7 @@ public class ControllerBootstrapRunner implements ApplicationRunner, Application
|
||||
}
|
||||
});
|
||||
channel = bootstrap.bind().sync().channel();
|
||||
log.info("TimiMusicRC controller service startup with " + settingService.getAsString(SettingKey.MUSIC_CONTROLLER_IP));
|
||||
log.info("TimiMusicRC controller service startup with {}", settingService.getAsString(Setting.Module.Music.CONTROLLER_IP));
|
||||
} catch (Exception e) {
|
||||
log.error("TimiMusicRC controller service startup error", e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
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.handler.PlayerMessageHandler;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@@ -12,9 +15,6 @@ import io.netty.handler.codec.string.StringDecoder;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.music.handler.PlayerMessageHandler;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
@@ -50,19 +50,22 @@ public class PlayerBootstrapRunner implements ApplicationRunner, ApplicationList
|
||||
}
|
||||
|
||||
public void run(ApplicationArguments args) {
|
||||
if (settingService.not(Setting.Module.Music.ENABLE)) {
|
||||
return;
|
||||
}
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
boss = new NioEventLoopGroup();
|
||||
worker = new NioEventLoopGroup();
|
||||
try {
|
||||
bootstrap.group(boss, worker);
|
||||
bootstrap.channel(NioServerSocketChannel.class);
|
||||
bootstrap.localAddress(new InetSocketAddress(settingService.getAsInt(SettingKey.MUSIC_PLAYER_PORT)));
|
||||
bootstrap.localAddress(new InetSocketAddress(settingService.getAsInt(Setting.Module.Music.PLAYER_PORT)));
|
||||
bootstrap.childHandler(new ChannelInitializer<>() {
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel ch) {
|
||||
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(
|
||||
settingService.getAsInt(SettingKey.MUSIC_MAX_FRAME_LENGTH),
|
||||
settingService.getAsInt(Setting.Module.Music.MAX_FRAME_LENGTH),
|
||||
0,
|
||||
4,
|
||||
0,
|
||||
@@ -77,7 +80,7 @@ public class PlayerBootstrapRunner implements ApplicationRunner, ApplicationList
|
||||
|
||||
channel = bootstrap.bind().sync().channel();
|
||||
|
||||
log.info("TimiMusicRC player service startup with " + settingService.getAsString(SettingKey.MUSIC_PLAYER_IP));
|
||||
log.info("TimiMusicRC player service startup with {}", settingService.getAsString(Setting.Module.Music.PLAYER_IP));
|
||||
} catch (Exception e) {
|
||||
log.error("TimiMusicRC player service startup error", e);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.imyeyu.api.modules.system.bean;
|
||||
|
||||
import com.imyeyu.api.TimiServerAPI;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.TimiServerAPI;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
@@ -174,7 +174,7 @@ public class ServerFile implements Serializable {
|
||||
name = file.getName();
|
||||
absolutePath = file.getAbsolutePath().replaceAll("\\\\", "/");
|
||||
SettingService settingService = TimiServerAPI.applicationContext.getBean(SettingService.class);
|
||||
absolutePath = absolutePath.substring(settingService.getAsString(SettingKey.SYSTEM_FILE_BASE).length());
|
||||
absolutePath = absolutePath.substring(settingService.getAsString(Setting.Module.System.FILE_BASE_PATH).length());
|
||||
|
||||
modifiedAt = file.lastModified();
|
||||
isFile = file.isFile();
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package com.imyeyu.api.modules.system.controller;
|
||||
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.network.Network;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.entity.Tag;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.common.service.TagService;
|
||||
@@ -23,6 +18,11 @@ import com.imyeyu.api.modules.system.task.async.FileUnZipAsyncTask;
|
||||
import com.imyeyu.api.modules.system.task.async.FileZipAsyncTask;
|
||||
import com.imyeyu.api.modules.system.util.ResourceHandler;
|
||||
import com.imyeyu.api.modules.system.vo.ListFileToRequest;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.network.Network;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.IgnoreGlobalReturn;
|
||||
@@ -51,6 +51,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -187,7 +188,7 @@ public class FileController implements TimiJava, OS.FileSystem {
|
||||
public void read(HttpServletRequest req, HttpServletResponse resp) {
|
||||
try {
|
||||
String path = req.getServletPath().substring("/system/file/read".length());
|
||||
path = settingService.getAsString(SettingKey.SYSTEM_FILE_BASE) + path;
|
||||
path = settingService.getAsString(Setting.Module.System.FILE_BASE_PATH) + path;
|
||||
if (TimiJava.isEmpty(path)) {
|
||||
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
@@ -239,7 +240,7 @@ public class FileController implements TimiJava, OS.FileSystem {
|
||||
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
path = settingService.getAsString(SettingKey.SYSTEM_FILE_BASE) + path;
|
||||
path = settingService.getAsString(Setting.Module.System.FILE_BASE_PATH) + path;
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
log.warn("preview a not exist file: {}", path);
|
||||
@@ -466,8 +467,8 @@ public class FileController implements TimiJava, OS.FileSystem {
|
||||
public void download(HttpServletResponse resp) {
|
||||
try {
|
||||
String path = TimiSpring.cutURIStartAt("/system/file/download");
|
||||
path = settingService.getAsString(SettingKey.SYSTEM_FILE_BASE) + path;
|
||||
File file = new File(path);
|
||||
path = settingService.getAsString(Setting.Module.System.FILE_BASE_PATH) + path;
|
||||
File file = Paths.get(URI.create(path)).toFile();
|
||||
service.checkAccessPermission(file.getAbsolutePath());
|
||||
|
||||
String mimeType = new Tika().detect(file);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.imyeyu.api.modules.system.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2026-04-23 16:31
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/system/setting")
|
||||
public class SettingController {
|
||||
|
||||
|
||||
}
|
||||
@@ -3,15 +3,11 @@ package com.imyeyu.api.modules.system.controller;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||
import com.imyeyu.api.modules.system.service.StatusService;
|
||||
import com.imyeyu.api.modules.system.service.SystemService;
|
||||
import com.imyeyu.api.modules.system.vo.SystemStatusHistoryView;
|
||||
import com.imyeyu.api.modules.system.vo.SystemStatusSnapshotView;
|
||||
import com.imyeyu.api.modules.system.vo.TempAttachRequest;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -38,7 +34,6 @@ import java.util.concurrent.Semaphore;
|
||||
public class SystemController {
|
||||
|
||||
private final StatusService statusService;
|
||||
private final SystemService service;
|
||||
private final AttachmentService attachmentService;
|
||||
|
||||
private final Semaphore updateSemaphore = new Semaphore(1);
|
||||
@@ -71,68 +66,6 @@ public class SystemController {
|
||||
return statusService.getStatusHistory(window, metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统
|
||||
*
|
||||
* @param file 更新文件
|
||||
*/
|
||||
@AOPLog
|
||||
@PostMapping("/update")
|
||||
public void update(@NotNull @RequestParam("file") MultipartFile file) {
|
||||
if (updateSemaphore.tryAcquire()) {
|
||||
try {
|
||||
service.update(file);
|
||||
} finally {
|
||||
updateSemaphore.release();
|
||||
}
|
||||
} else {
|
||||
throw new TimiException(TimiCode.ERROR_SERVICE_OFF).msgKey("TODO updating");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复系统
|
||||
*/
|
||||
@AOPLog
|
||||
@RequestMapping("/restore")
|
||||
public void restore() {
|
||||
if (restoreSemaphore.tryAcquire()) {
|
||||
try {
|
||||
service.restore();
|
||||
} finally {
|
||||
restoreSemaphore.release();
|
||||
}
|
||||
} else {
|
||||
throw new TimiException(TimiCode.ERROR_SERVICE_OFF).msgKey("TODO updating");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭系统
|
||||
*/
|
||||
@AOPLog
|
||||
@RequestMapping("/shutdown")
|
||||
public void shutdown() {
|
||||
service.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启系统
|
||||
*/
|
||||
@AOPLog
|
||||
@RequestMapping("/reboot")
|
||||
public void reboot() {
|
||||
if (rebootSemaphore.tryAcquire()) {
|
||||
try {
|
||||
service.reboot();
|
||||
} finally {
|
||||
rebootSemaphore.release();
|
||||
}
|
||||
} else {
|
||||
throw new TimiException(TimiCode.ERROR_SERVICE_OFF).msgKey("TODO rebooting");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传临时附件
|
||||
*
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.imyeyu.api.modules.system.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @author 夜雨
|
||||
* @version 2024-03-13 00:44
|
||||
*/
|
||||
public interface SystemService {
|
||||
|
||||
void update(MultipartFile file);
|
||||
|
||||
void restore();
|
||||
|
||||
void shutdown();
|
||||
|
||||
void reboot();
|
||||
}
|
||||
@@ -1,26 +1,22 @@
|
||||
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.ServerFile;
|
||||
import com.imyeyu.api.modules.system.bean.TransferFile;
|
||||
import com.imyeyu.api.modules.system.service.AsyncTaskService;
|
||||
import com.imyeyu.api.modules.system.service.FileService;
|
||||
import com.imyeyu.api.modules.system.util.SystemAPIInterceptor;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.system.bean.FileSyncConfig;
|
||||
import com.imyeyu.api.modules.system.bean.ServerFile;
|
||||
import com.imyeyu.api.modules.system.bean.TransferFile;
|
||||
import com.imyeyu.api.modules.system.entity.AsyncTask;
|
||||
import com.imyeyu.api.modules.system.service.AsyncTaskService;
|
||||
import com.imyeyu.api.modules.system.service.FileService;
|
||||
import com.imyeyu.api.modules.system.task.async.FileSyncTask;
|
||||
import com.imyeyu.api.modules.system.util.SystemAPIInterceptor;
|
||||
import com.imyeyu.utils.Decoder;
|
||||
import com.imyeyu.utils.OS;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.config.CronTask;
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -33,7 +29,6 @@ import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文件服务,不可直接使用入参路径
|
||||
@@ -70,30 +65,30 @@ public class FileServiceImplement implements TimiJava, FileService {
|
||||
|
||||
@PostConstruct
|
||||
private void fileSyncPostConstruct() {
|
||||
FileSyncConfig config = settingService.fromYaml(SettingKey.SYSTEM_FILE_SYNC, FileSyncConfig.class);
|
||||
if (config.isEnable()) {
|
||||
scheduledTaskRegistrar.scheduleCronTask(new CronTask(() -> {
|
||||
Map<String, FileSyncConfig.Task> tasks = config.getTasks();
|
||||
configTask: for (Map.Entry<String, FileSyncConfig.Task> item : tasks.entrySet()) {
|
||||
if (item.getValue().isEnable()) {
|
||||
List<AbstractAsyncTask> runningTaskList = asyncTaskService.listAll();
|
||||
for (int i = 0; i < runningTaskList.size(); i++) {
|
||||
AbstractAsyncTask runningTask = runningTaskList.get(i);
|
||||
if (runningTask.getType() == AsyncTask.Type.FILE_SYNC && runningTask.getName().equals(item.getKey())) {
|
||||
continue configTask;
|
||||
}
|
||||
}
|
||||
FileSyncTask task = new FileSyncTask(item.getKey(), item.getValue());
|
||||
asyncTaskService.addAsyncTask(task);
|
||||
}
|
||||
}
|
||||
}, config.getCron()));
|
||||
}
|
||||
// FileSyncConfig config = settingService.fromYaml(SettingKey.SYSTEM_FILE_SYNC, FileSyncConfig.class);
|
||||
// if (config.isEnable()) {
|
||||
// scheduledTaskRegistrar.scheduleCronTask(new CronTask(() -> {
|
||||
// Map<String, FileSyncConfig.Task> tasks = config.getTasks();
|
||||
// configTask: for (Map.Entry<String, FileSyncConfig.Task> item : tasks.entrySet()) {
|
||||
// if (item.getValue().isEnable()) {
|
||||
// List<AbstractAsyncTask> runningTaskList = asyncTaskService.listAll();
|
||||
// for (int i = 0; i < runningTaskList.size(); i++) {
|
||||
// AbstractAsyncTask runningTask = runningTaskList.get(i);
|
||||
// if (runningTask.getType() == AsyncTask.Type.FILE_SYNC && runningTask.getName().equals(item.getKey())) {
|
||||
// continue configTask;
|
||||
// }
|
||||
// }
|
||||
// FileSyncTask task = new FileSyncTask(item.getKey(), item.getValue());
|
||||
// asyncTaskService.addAsyncTask(task);
|
||||
// }
|
||||
// }
|
||||
// }, config.getCron()));
|
||||
// }
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void fileFilterPostConstruct() {
|
||||
option = settingService.fromYaml(SettingKey.SYSTEM_FILE_FILTER, FilterOption.class);
|
||||
// option = settingService.fromYaml(SettingKey.SYSTEM_FILE_FILTER, FilterOption.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -262,7 +257,7 @@ public class FileServiceImplement implements TimiJava, FileService {
|
||||
}
|
||||
|
||||
private String getPath(String path) {
|
||||
String basePath = settingService.getAsString(SettingKey.SYSTEM_FILE_BASE);
|
||||
String basePath = settingService.getAsString(Setting.Module.System.FILE_BASE_PATH);
|
||||
if (TimiJava.isEmpty(path)) {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.modules.system.service.implement;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
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.service.StatusService;
|
||||
@@ -33,7 +33,7 @@ public class StatusServiceImplement implements StatusService {
|
||||
@Override
|
||||
public SystemStatusSnapshotView getStatus(String metrics) {
|
||||
long serverTime = Time.now();
|
||||
int sampleRateMs = settingService.getAsInt(SettingKey.SYSTEM_STATUS_RATE);
|
||||
int sampleRateMs = settingService.getAsInt(Setting.Module.System.STATUS_RATE);
|
||||
EnumSet<Metric> 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.getAsInt(SettingKey.SYSTEM_STATUS_RATE);
|
||||
int sampleRateMs = settingService.getAsInt(Setting.Module.System.STATUS_RATE);
|
||||
EnumSet<Metric> 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.getAsInt(SettingKey.SYSTEM_STATUS_LIMIT) * sampleRateMs;
|
||||
return (long) settingService.getAsInt(Setting.Module.System.STATUS_LIMIT) * 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.getAsInt(SettingKey.SYSTEM_STATUS_LIMIT) * sampleRateMs;
|
||||
return (long) settingService.getAsInt(Setting.Module.System.STATUS_LIMIT) * sampleRateMs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.imyeyu.api.modules.system.service.implement;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.TimiServerAPI;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.system.service.SystemService;
|
||||
import com.imyeyu.utils.OS;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.naming.NoPermissionException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author 夜雨
|
||||
* @version 2024-03-13 00:45
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SystemServiceImplement implements SystemService {
|
||||
|
||||
private final SettingService settingService;
|
||||
|
||||
@Override
|
||||
public void update(MultipartFile file) {
|
||||
try {
|
||||
IO.toFile(IO.file("timi-server-api.jar"), file.getInputStream());
|
||||
} catch (NoPermissionException | IOException e) {
|
||||
log.error("update core error", e);
|
||||
throw new TimiException(TimiCode.ERROR).msgKey("TODO update core error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore() {
|
||||
try {
|
||||
IO.copy(IO.file("default.jar"), IO.file("timi-server-api.jar").getAbsolutePath());
|
||||
} catch (NoPermissionException | IOException e) {
|
||||
log.error("restore core error", e);
|
||||
throw new TimiException(TimiCode.ERROR).msgKey("TODO restore core error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (TimiServerAPI.applicationContext instanceof AbstractApplicationContext ctx) {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void reboot() {
|
||||
if (TimiServerAPI.applicationContext instanceof AbstractApplicationContext ctx) {
|
||||
String command = settingService.getAsString(SettingKey.SYSTEM_REBOOT_COMMAND);
|
||||
if (TimiJava.isEmpty(command)) {
|
||||
throw new TimiException(TimiCode.ERROR_NPE_VARIABLE).msgKey("TODO not support reboot");
|
||||
}
|
||||
OS.runAfterShutdown(command);
|
||||
SpringApplication.exit(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,31 @@
|
||||
package com.imyeyu.api.modules.system.service.implement;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.CallbackArg;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.system.bean.TerminalPipe;
|
||||
import com.imyeyu.api.modules.system.service.TerminalService;
|
||||
import com.imyeyu.api.modules.system.vo.terminal.ExecCommand;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.CallbackArg;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import com.imyeyu.utils.OS;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 指令服务
|
||||
@@ -50,7 +52,8 @@ public class TerminalServiceImplement implements TerminalService, TimiJava, OS.F
|
||||
|
||||
@PostConstruct
|
||||
private void postConstruct() {
|
||||
execLogFilters.addAll(List.of(settingService.getAsString(SettingKey.SYSTEM_TERMINAL_FILTERS).split(",")));
|
||||
// ArrayNode array = settingService.getAsArrayNode(Setting.Module.System.TERMINAL_FILTERS);
|
||||
// execLogFilters.addAll(array.valueStream().map(JsonNode::asText).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.modules.system.task;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
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.task.status.StatusCollectContext;
|
||||
@@ -63,10 +63,10 @@ public class ServerStatusTask implements SchedulingConfigurer {
|
||||
collector.collect(context);
|
||||
}
|
||||
status.getUpdateAxis().addLast(context.getCollectAt());
|
||||
if (settingService.getAsInt(SettingKey.SYSTEM_STATUS_LIMIT) < status.getUpdateAxis().size()) {
|
||||
if (settingService.getAsInt(Setting.Module.System.STATUS_LIMIT) < status.getUpdateAxis().size()) {
|
||||
status.getUpdateAxis().pollFirst();
|
||||
}
|
||||
}
|
||||
}, triggerContext -> new CronTrigger("0/%s * * * * ?".formatted(settingService.getAsInt(SettingKey.SYSTEM_STATUS_RATE) / 1000)).nextExecution(triggerContext));
|
||||
}, triggerContext -> new CronTrigger("0/%s * * * * ?".formatted(settingService.getAsInt(Setting.Module.System.STATUS_RATE) / 1000)).nextExecution(triggerContext));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.imyeyu.api.modules.system.task;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.api.modules.system.bean.TerminalPipe;
|
||||
import com.imyeyu.api.modules.system.service.TerminalService;
|
||||
import com.imyeyu.utils.Time;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -30,10 +30,10 @@ public class TerminalTask {
|
||||
private void run() {
|
||||
service.listTerminalPipe().entrySet().removeIf(entry -> {
|
||||
if (entry.getValue().getStatus() == TerminalPipe.Status.DIED) {
|
||||
log.info("kill the died terminal session: " + entry.getKey());
|
||||
log.info("kill the died terminal session: {}", entry.getKey());
|
||||
return true;
|
||||
}
|
||||
long diedAt = entry.getValue().getLastExecAt() + Time.M * settingService.getAsInt(SettingKey.SYSTEM_TERMINAL_TTL);
|
||||
long diedAt = entry.getValue().getLastExecAt() + settingService.getAsTime(Setting.Module.System.TERMINAL_TTL);
|
||||
if (diedAt < Time.now()) {
|
||||
entry.getValue().destroy();
|
||||
log.info("kill the timeout terminal session [DIED at: {}]: {}", Time.toDateTime(diedAt), entry.getKey());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.imyeyu.api.modules.system.task.status;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
|
||||
import java.util.Deque;
|
||||
|
||||
@@ -22,7 +22,7 @@ public abstract class AbstractDequeStatusCollector implements StatusCollector {
|
||||
*/
|
||||
protected <T> void putDeque(StatusCollectContext context, Deque<T> deque, T value) {
|
||||
deque.addLast(value);
|
||||
if (context.getSettingService().getAsInt(SettingKey.SYSTEM_STATUS_LIMIT) < deque.size()) {
|
||||
if (context.getSettingService().getAsInt(Setting.Module.System.STATUS_LIMIT) < deque.size()) {
|
||||
deque.pollFirst();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package com.imyeyu.api.modules.system.task.status.collector;
|
||||
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.api.modules.system.task.status.AbstractDequeStatusCollector;
|
||||
import com.imyeyu.api.modules.system.task.status.StatusCollectContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bytedeco.librealsense.context;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import oshi.hardware.NetworkIF;
|
||||
@@ -25,7 +24,7 @@ public class NetworkStatusCollector extends AbstractDequeStatusCollector {
|
||||
@Override
|
||||
public void initialize(StatusCollectContext context) {
|
||||
List<NetworkIF> networkIFs = context.getHardware().getNetworkIFs();
|
||||
String targetMac = context.getSettingService().getAsString(SettingKey.SYSTEM_STATUS_NETWORK_MAC);
|
||||
String targetMac = context.getSettingService().getAsString(Setting.Module.System.STATUS_NETWORK_MAC);
|
||||
for (NetworkIF networkIF : networkIFs) {
|
||||
if (networkIF.getMacaddr().equals(targetMac)) {
|
||||
networkIF.updateAttributes();
|
||||
@@ -42,8 +41,8 @@ public class NetworkStatusCollector extends AbstractDequeStatusCollector {
|
||||
|
||||
@Override
|
||||
public void collect(StatusCollectContext context) {
|
||||
String targetMac = context.getSettingService().getAsString(SettingKey.SYSTEM_STATUS_NETWORK_MAC);
|
||||
int sampleRateMs = context.getSettingService().getAsInt(SettingKey.SYSTEM_STATUS_RATE);
|
||||
String targetMac = context.getSettingService().getAsString(Setting.Module.System.STATUS_NETWORK_MAC);
|
||||
int sampleRateMs = context.getSettingService().getAsInt(Setting.Module.System.STATUS_RATE);
|
||||
for (NetworkIF networkIF : context.getHardware().getNetworkIFs()) {
|
||||
if (networkIF.getMacaddr().equals(targetMac)) {
|
||||
networkIF.updateAttributes();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.imyeyu.api.modules.system.util;
|
||||
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.service.SettingService;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -33,8 +33,8 @@ public class SystemAPIInterceptor implements HandlerInterceptor {
|
||||
if (TimiJava.isEmpty(key)) {
|
||||
key = req.getParameter("token");
|
||||
}
|
||||
String dbKey = settingService.getAsString(SettingKey.SYSTEM_API_KEY);
|
||||
String dbSuperKey = settingService.getAsString(SettingKey.SYSTEM_API_SUPER_KEY);
|
||||
String dbKey = settingService.getAsString(Setting.Module.System.API_KEY);
|
||||
String dbSuperKey = settingService.getAsString(Setting.Module.System.API_KEY_SUPER);
|
||||
if (dbSuperKey.equals(key)) {
|
||||
TimiSpring.setRequestAttr(IS_SUPER_KEY, true);
|
||||
return true;
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
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.modules.common.bean.SettingKey;
|
||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||
import com.imyeyu.api.modules.common.entity.Setting;
|
||||
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.java.TimiJava;
|
||||
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;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.jgit.api.ArchiveCommand;
|
||||
@@ -23,10 +16,7 @@ import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* SpringBoot 启动事件,主要输出基本参数,避免混淆运行环境
|
||||
@@ -57,7 +47,6 @@ public class InitApplication implements ApplicationRunner {
|
||||
private final SettingService settingService;
|
||||
private final RedisMultilingual redisMultilingual;
|
||||
private final GlobalReturnHandler globalReturnHandler;
|
||||
private final Redis<Long, Multilingual> redisLanguage;
|
||||
|
||||
private void logBaseInfo() {
|
||||
log.info("JDBC URL: {}", jdbcURL);
|
||||
@@ -65,7 +54,7 @@ public class InitApplication implements ApplicationRunner {
|
||||
log.info("System Setting:");
|
||||
List<Setting> settings = settingService.listAll();
|
||||
for (Setting setting : settings) {
|
||||
String value = Objects.requireNonNullElse(setting.getValue(), "");
|
||||
String value = TimiJava.defaultIfEmpty(setting.getValue(), "");
|
||||
if (64 < value.length()) {
|
||||
value = value.substring(0, 64) + "..";
|
||||
}
|
||||
@@ -86,38 +75,13 @@ public class InitApplication implements ApplicationRunner {
|
||||
});
|
||||
}
|
||||
|
||||
private void initFileType() {
|
||||
ObjectNode items = settingService.getAsJsonObject(SettingKey.SYSTEM_FILE_TYPE);
|
||||
|
||||
String[] extensions;
|
||||
ArrayNode extensionsArray;
|
||||
JsonNode itemObject;
|
||||
List<String> extensionsList;
|
||||
for (Map.Entry<String, JsonNode> item : (Iterable<Map.Entry<String, JsonNode>>) items::fields) {
|
||||
ServerFile.FileType fileType = Ref.toType(ServerFile.FileType.class, item.getKey());
|
||||
itemObject = item.getValue();
|
||||
extensionsList = new ArrayList<>();
|
||||
extensionsArray = (ArrayNode) itemObject.get("extensions");
|
||||
for (JsonNode extensionNode : extensionsArray) {
|
||||
if (extensionNode.isObject()) {
|
||||
extensionsList.add(extensionNode.path("value").asText());
|
||||
} else {
|
||||
extensionsList.add(extensionNode.asText());
|
||||
}
|
||||
}
|
||||
extensions = new String[extensionsList.size()];
|
||||
// 设置扩展名所属文件类型
|
||||
fileType.setExtensions(extensionsList.toArray(extensions));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
Method[] methods = getClass().getDeclaredMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (!methods[i].getName().equals("run") && !methods[i].getName().contains("$")) {
|
||||
methods[i].setAccessible(true);
|
||||
methods[i].invoke(this);
|
||||
for (Method method : methods) {
|
||||
if (!method.getName().equals("run") && !method.getName().contains("$")) {
|
||||
method.setAccessible(true);
|
||||
method.invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user