diff --git a/pom.xml b/pom.xml
index fb63efb..30e9a8c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,25 +190,6 @@
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.1.0
-
-
- run-code-generator
- compile
-
- java
-
-
- com.cool.core.plugin.I18nGenerator
- compile
-
-
-
-
diff --git a/src/main/java/com/cool/core/base/BaseController.java b/src/main/java/com/cool/core/base/BaseController.java
index 29dae1b..c16dfd5 100644
--- a/src/main/java/com/cool/core/base/BaseController.java
+++ b/src/main/java/com/cool/core/base/BaseController.java
@@ -51,9 +51,11 @@ public abstract class BaseController, T extends BaseEnt
protected final String COOL_PAGE_OP = "COOL_PAGE_OP";
protected final String COOL_LIST_OP = "COOL_LIST_OP";
+ protected final String COOL_INFO_OP = "COOL_INFO_OP";
private final ThreadLocal> pageOption = new ThreadLocal<>();
private final ThreadLocal> listOption = new ThreadLocal<>();
+ private final ThreadLocal> infoOption = new ThreadLocal<>();
private final ThreadLocal requestParams = new ThreadLocal<>();
@ModelAttribute
@@ -61,16 +63,20 @@ public abstract class BaseController, T extends BaseEnt
@RequestAttribute JSONObject requestParams) {
String requestPath = ((ServletRequestAttributes) Objects.requireNonNull(
RequestContextHolder.getRequestAttributes())).getRequest().getRequestURI();
- if (!requestPath.endsWith("/page") && !requestPath.endsWith("/list")) {
+ if (!requestPath.endsWith("/page") && !requestPath.endsWith("/list")
+ && !requestPath.endsWith("/info")) {
// 非page或list不执行
return;
}
this.pageOption.set(new CrudOption<>(requestParams));
this.listOption.set(new CrudOption<>(requestParams));
+ this.infoOption.set(new CrudOption<>(requestParams));
this.requestParams.set(requestParams);
init(request, requestParams);
request.setAttribute(COOL_PAGE_OP, this.pageOption.get());
request.setAttribute(COOL_LIST_OP, this.listOption.get());
+ request.setAttribute(COOL_INFO_OP, this.infoOption.get());
+
removeThreadLocal();
}
@@ -87,6 +93,10 @@ public abstract class BaseController, T extends BaseEnt
return new CrudOption<>(this.requestParams.get());
}
+ public void setInfoOption(CrudOption infoOption) {
+ this.infoOption.set(infoOption);
+ }
+
public void setListOption(CrudOption listOption) {
this.listOption.set(listOption);
}
@@ -153,8 +163,11 @@ public abstract class BaseController, T extends BaseEnt
@Operation(summary = "信息", description = "根据ID查询单个信息")
@GetMapping("/info")
protected R info(@RequestAttribute() JSONObject requestParams,
- @RequestParam() Long id) {
- return R.ok((T) service.info(requestParams, id));
+ @RequestParam() Long id,
+ @RequestAttribute(COOL_INFO_OP) CrudOption option) {
+ T info = (T) service.info(requestParams, id);
+ invokerTransform(option, info);
+ return R.ok(info);
}
/**
@@ -219,7 +232,7 @@ public abstract class BaseController, T extends BaseEnt
* @param page 分页返回数据
*/
protected PageResult pageResult(Page page) {
- return PageResult.of( page );
+ return PageResult.of(page);
}
public Class currentEntityClass() {
diff --git a/src/main/java/com/cool/core/exception/CoolPreconditions.java b/src/main/java/com/cool/core/exception/CoolPreconditions.java
index fc6d298..8779f3a 100644
--- a/src/main/java/com/cool/core/exception/CoolPreconditions.java
+++ b/src/main/java/com/cool/core/exception/CoolPreconditions.java
@@ -1,6 +1,7 @@
package com.cool.core.exception;
import cn.hutool.core.util.ObjectUtil;
+import com.cool.core.util.I18nUtil;
import java.util.Arrays;
import java.util.Optional;
import lombok.Getter;
@@ -69,6 +70,7 @@ public class CoolPreconditions {
}
private static String formatMessage(String messagePattern, Object... arguments) {
+ messagePattern = I18nUtil.getI18nMsg(messagePattern);
StringBuilder sb = new StringBuilder();
int argumentIndex = 0;
int placeholderIndex = messagePattern.indexOf("{}");
diff --git a/src/main/java/com/cool/core/i18n/I18nGenerator.java b/src/main/java/com/cool/core/i18n/I18nGenerator.java
new file mode 100644
index 0000000..40741a5
--- /dev/null
+++ b/src/main/java/com/cool/core/i18n/I18nGenerator.java
@@ -0,0 +1,219 @@
+package com.cool.core.i18n;
+
+import static com.cool.core.util.I18nUtil.*;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.cool.core.lock.CoolLock;
+import com.cool.core.util.CoolPluginInvokers;
+import com.cool.core.util.I18nUtil;
+import com.cool.core.util.PathUtils;
+import com.cool.modules.base.entity.sys.BaseSysMenuEntity;
+import com.cool.modules.base.service.sys.BaseSysMenuService;
+import com.cool.modules.dict.entity.DictInfoEntity;
+import com.cool.modules.dict.entity.DictTypeEntity;
+import com.cool.modules.dict.service.DictInfoService;
+import com.cool.modules.dict.service.DictTypeService;
+import com.mybatisflex.core.query.QueryWrapper;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class I18nGenerator {
+ private final BaseSysMenuService baseSysMenuService;
+ private final DictTypeService dictTypeService;
+ private final DictInfoService dictInfoService;
+ private final CoolLock coolLock;
+ private final I18nUtil i18nUtil;
+
+ private List languages;
+ private static final Duration DURATION = Duration.ofSeconds(30);
+ public void run(Map map) {
+ log.info("国际化 翻译...");
+ languages = (List) map.getOrDefault("languages", List.of("zh-cn", "zh-tw", "en"));
+ path = (String) map.getOrDefault("path", "assets/i18n");
+ init();
+ log.info("✅国际化 翻译 成功!!!");
+ enable = true;
+ }
+
+ public void init() {
+ // 四个任务并发执行
+ CompletableFuture futureMsg = CompletableFuture.runAsync(this::genBaseMsg);
+ CompletableFuture futureMenu = CompletableFuture.runAsync(this::genBaseMenu);
+ CompletableFuture futureDictInfo = CompletableFuture.runAsync(this::genBaseDictInfo);
+ CompletableFuture futureDictType = CompletableFuture.runAsync(this::genBaseDictType);
+
+ // 等待全部执行完成
+ CompletableFuture.allOf(futureMsg, futureMenu, futureDictInfo, futureDictType).join();
+ }
+
+ private void genBaseMsg() {
+ try {
+ Map msgMap = new HashMap<>();
+ // 从idea本地启动时,从项目目录中读取
+ Files.walk(Paths.get(System.getProperty("user.dir")))
+ .filter(Files::isRegularFile)
+ .filter(path -> path.toString().endsWith(".java"))
+ .filter(path -> !path.toString().contains("/target/") && !path.toString().contains("/.git/"))
+ .forEach(path -> msgMap.putAll(processFile(path)));
+ if (ObjUtil.isNotEmpty(msgMap)) {
+ // 系统异常信息,输出到resources/i18n 文件夹下,只有本地运行会生成
+ File msgfile = FileUtil.file(PathUtils.getUserDir(),
+ "src", "main", "resources", "cool", "i18n", "msg", "template.json");
+ // 确保父目录存在
+ FileUtil.mkParentDirs(msgfile);
+ // 写入内容
+ FileUtil.writeUtf8String(JSONUtil.toJsonStr(msgMap), msgfile);
+ } else {
+ try {
+ // jar启动时,从jar包中读取
+ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ Resource resource = resolver.getResource("classpath:cool/i18n/msg/template.json");
+ String content = FileUtil.readUtf8String(resource.getFile());
+ msgMap.putAll(JSONUtil.toBean(content, Map.class));
+ } catch (Exception e) {
+ log.error("获取系统异常信息失败", e);
+ }
+ }
+ extracted(MSG_PREFIX, msgMap);
+ } catch (Exception e) {
+ log.error("国际化系统异常信息失败", e);
+ }
+ }
+
+ /**
+ * 生成菜单信息国际化
+ */
+ @Async
+ public void asyncGenBaseMenu() {
+ if (coolLock.tryLock(MENU_PREFIX, DURATION)) {
+ genBaseMenu();
+ coolLock.unlock(MENU_PREFIX);
+ }
+ }
+ private void genBaseMenu() {
+ try {
+ Map menuMap = baseSysMenuService.list(QueryWrapper.create().select(BaseSysMenuEntity::getName))
+ .stream()
+ .collect(Collectors.toMap(
+ BaseSysMenuEntity::getName,
+ BaseSysMenuEntity::getName,
+ (oldValue, newValue) -> oldValue
+ ));
+ extracted(MENU_PREFIX, menuMap);
+ } catch (Exception e) {
+ log.error("国际化菜单信息失败", e);
+ }
+ }
+ @Async
+ public void asyncGenBaseDictType() {
+ if (coolLock.tryLock(DICT_TYPE_PREFIX, DURATION)) {
+ genBaseDictType();
+ coolLock.unlock(DICT_TYPE_PREFIX);
+ }
+ }
+ private void genBaseDictType() {
+ try {
+ Map dataMap = dictTypeService.list(QueryWrapper.create().select(DictTypeEntity::getName))
+ .stream()
+ .collect(Collectors.toMap(
+ DictTypeEntity::getName,
+ DictTypeEntity::getName,
+ (oldValue, newValue) -> oldValue
+ ));
+ extracted(DICT_TYPE_PREFIX, dataMap);
+ } catch (Exception e) {
+ log.error("国际化字段类型信息失败", e);
+ }
+ }
+ @Async
+ public void asyncGenBaseDictInfo() {
+ if (coolLock.tryLock(DICT_INFO_PREFIX, DURATION)) {
+ genBaseDictInfo();
+ coolLock.unlock(DICT_INFO_PREFIX);
+ }
+ }
+ private void genBaseDictInfo() {
+ try {
+ Map dataMap = dictInfoService.list(QueryWrapper.create().select(DictInfoEntity::getName))
+ .stream()
+ .collect(Collectors.toMap(
+ DictInfoEntity::getName,
+ DictInfoEntity::getName,
+ (oldValue, newValue) -> oldValue
+ ));
+ extracted(DICT_INFO_PREFIX, dataMap);
+ } catch (Exception e) {
+ log.error("国际化字段类型信息失败", e);
+ }
+ }
+
+ private void extracted(String prefix, Map dataMap) {
+ languages.forEach(language -> {
+ String key = prefix + language;
+ if (!i18nUtil.exist(key)) {
+ JSONObject jsonObject = invokeTranslate(dataMap, language);
+ if (ObjUtil.isNotNull(jsonObject)) {
+ i18nUtil.update(key, jsonObject);
+ }
+ }
+ });
+ }
+
+ private JSONObject invokeTranslate(Map map, String language) {
+ return (JSONObject) CoolPluginInvokers.invoke("i18n", "invokeTranslate", map, language);
+ }
+
+ // 匹配 CoolPreconditions 抛异常语句中的中文字符串
+ private static final Pattern EXCEPTION_PATTERN = Pattern.compile(
+ "CoolPreconditions\\.(\\w+)\\s*\\([^;]*?\"([^\"]*[\u4e00-\u9fa5]+[^\"]*)\"", Pattern.MULTILINE
+ );
+
+ private static Map processFile(Path path) {
+ Map map = new HashMap<>();
+ try {
+ String content = Files.readString(path, StandardCharsets.UTF_8);
+ // 去掉注释
+ content = removeComments(content);
+
+ // 仅查找方法体内的 CoolPreconditions 调用
+ Matcher matcher = EXCEPTION_PATTERN.matcher(content);
+ while (matcher.find()) {
+ String chineseText = matcher.group(2).trim();
+ map.put(chineseText, chineseText);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return map;
+ }
+
+ // 移除注释(单行与多行)
+ private static String removeComments(String code) {
+ String noMultiLine = code.replaceAll("/\\*.*?\\*/", ""); // 多行注释
+ return noMultiLine.replaceAll("//.*", ""); // 单行注释
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/cool/core/plugin/I18nGenerator.java b/src/main/java/com/cool/core/plugin/I18nGenerator.java
deleted file mode 100644
index aeca1db..0000000
--- a/src/main/java/com/cool/core/plugin/I18nGenerator.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package com.cool.core.plugin;
-
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONArray;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class I18nGenerator {
- public static void main(String[] args) {
- new I18nGenerator().run();
- }
- public void run() {
- System.out.println("i18n translate ...");
- // 要生成的文件路径
- File msgfile = FileUtil.file(System.getProperty("user.dir"),
- "src", "main", "resources", "cool", "i18n", "msg", "en.json");
- if (!msgfile.exists()) {
- JSONObject jsonObject = genExceptionMsg();
-
- // 确保父目录存在
- FileUtil.mkParentDirs(msgfile);
- // 写入内容
- FileUtil.writeUtf8String(JSONUtil.toJsonStr(jsonObject), msgfile);
- }
- // 要生成的文件路径
- File menufile = FileUtil.file(System.getProperty("user.dir"),
- "src", "main", "resources", "cool", "i18n", "menu", "en.json");
- if (!menufile.exists()) {
- JSONObject jsonObject = genBaseMenu();
- // 确保父目录存在
- FileUtil.mkParentDirs(menufile);
- // 写入内容
- FileUtil.writeUtf8String(JSONUtil.toJsonStr(jsonObject), menufile);
- }
- System.out.println("✅i18n translate success !!!");
- }
-
- /**
- * 生成菜单信息国际化
- */
- private JSONObject genBaseMenu() {
- try {
- PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
- Resource[] resources = resolver.getResources("classpath:cool/data/menu/*.json");
- Map map = new HashMap<>();
- List list = new ArrayList<>();
- // 遍历所有.json文件
- for (Resource resource : resources) {
- String jsonStr = IoUtil.read(resource.getInputStream(), StandardCharsets.UTF_8);
- // 使用 解析 JSON 字符串
- JSONArray jsonArray = JSONUtil.parseArray(jsonStr);
- // 遍历 JSON 数组
- for (Object obj : jsonArray) {
- JSONObject jsonObj = (JSONObject) obj;
- parseMenu(jsonObj, list);
- }
- }
- for (String value : list) {
- map.put(value, value);
- }
- return invokeTranslate(map, "en");
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- private void parseMenu(JSONObject jsonObj, List list) {
- list.add(jsonObj.getStr("name"));
- // 递归处理子菜单
- JSONArray childMenus = jsonObj.getJSONArray("childMenus");
- if (childMenus != null) {
- for (Object obj : childMenus) {
- JSONObject childObj = (JSONObject) obj;
- parseMenu(childObj, list);
- }
- }
- }
-
- /**
- * 生成异常信息国际化
- */
- private JSONObject genExceptionMsg() {
- Path rootPath = Paths.get(System.getProperty("user.dir"));
- try {
- Map map = new HashMap<>();
- Files.walk(rootPath)
- .filter(Files::isRegularFile)
- .filter(path -> path.toString().endsWith(".java"))
- .filter(path -> !path.toString().contains("/target/") && !path.toString().contains("/.git/"))
- .forEach(path -> map.putAll(processFile(path)));
- return invokeTranslate(map, "en");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- private JSONObject invokeTranslate(Map map, String language) {
- if (map.isEmpty()) {
- return new JSONObject();
- }
- Map data = new HashMap<>();
- data.put("label", "i18n-node");
- data.put("params", Map.of("text", JSONUtil.toJsonStr(map), "language", language));
- data.put("stream", false);
- String res = HttpUtil.post("https://service.cool-js.com/api/open/flow/run/invoke", JSONUtil.toJsonStr(data));
- JSONObject jsonObject = JSONUtil.parseObj(res);
- return jsonObject.getJSONObject("data").getJSONObject("result").getJSONObject("data");
- }
-
- // 匹配 CoolPreconditions 抛异常语句中的中文字符串
- private static final Pattern EXCEPTION_PATTERN = Pattern.compile(
- "CoolPreconditions\\.(\\w+)\\s*\\([^;]*?\"([^\"]*[\u4e00-\u9fa5]+[^\"]*)\"", Pattern.MULTILINE
- );
-
- private static Map processFile(Path path) {
- Map map = new HashMap<>();
- try {
- String content = Files.readString(path, StandardCharsets.UTF_8);
- // 去掉注释
- content = removeComments(content);
-
- // 仅查找方法体内的 CoolPreconditions 调用
- Matcher matcher = EXCEPTION_PATTERN.matcher(content);
- while (matcher.find()) {
- String chineseText = matcher.group(2).trim();
- map.put(chineseText, chineseText);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return map;
- }
-
- // 移除注释(单行与多行)
- private static String removeComments(String code) {
- String noMultiLine = code.replaceAll("/\\*.*?\\*/", ""); // 多行注释
- return noMultiLine.replaceAll("//.*", ""); // 单行注释
- }
-}
diff --git a/src/main/java/com/cool/core/plugin/consts/PluginConsts.java b/src/main/java/com/cool/core/plugin/consts/PluginConsts.java
index eb07fee..1d80f37 100644
--- a/src/main/java/com/cool/core/plugin/consts/PluginConsts.java
+++ b/src/main/java/com/cool/core/plugin/consts/PluginConsts.java
@@ -4,7 +4,10 @@ package com.cool.core.plugin.consts;
* 常量工具
*/
public interface PluginConsts {
-
+ /**
+ * 国际化插件
+ */
+ String i18n = "i18n";
/**
* 上传文件hook
*/
diff --git a/src/main/java/com/cool/core/plugin/event/PluginActionEnum.java b/src/main/java/com/cool/core/plugin/event/PluginActionEnum.java
new file mode 100644
index 0000000..064b807
--- /dev/null
+++ b/src/main/java/com/cool/core/plugin/event/PluginActionEnum.java
@@ -0,0 +1,7 @@
+package com.cool.core.plugin.event;
+
+public enum PluginActionEnum {
+ INSTALL,
+ UNINSTALL,
+ UPDATE,
+}
diff --git a/src/main/java/com/cool/core/plugin/event/PluginEvent.java b/src/main/java/com/cool/core/plugin/event/PluginEvent.java
new file mode 100644
index 0000000..d4726c0
--- /dev/null
+++ b/src/main/java/com/cool/core/plugin/event/PluginEvent.java
@@ -0,0 +1,26 @@
+package com.cool.core.plugin.event;
+
+import com.cool.modules.plugin.entity.PluginInfoEntity;
+import java.time.Clock;
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+public class PluginEvent extends ApplicationEvent {
+ @Getter
+ private String key;
+ @Getter
+ private PluginActionEnum actionEnum;
+ @Getter
+ private PluginInfoEntity pluginInfoEntity;
+ public PluginEvent(Object source, String key, PluginActionEnum actionEnum, PluginInfoEntity data) {
+ super(source);
+ this.key = key;
+ this.actionEnum = actionEnum;
+ this.pluginInfoEntity = data;
+ }
+
+ public PluginEvent(Object source, Clock clock) {
+ super(source, clock);
+ }
+}
+
diff --git a/src/main/java/com/cool/core/plugin/event/PluginEventListener.java b/src/main/java/com/cool/core/plugin/event/PluginEventListener.java
new file mode 100644
index 0000000..8c56577
--- /dev/null
+++ b/src/main/java/com/cool/core/plugin/event/PluginEventListener.java
@@ -0,0 +1,46 @@
+package com.cool.core.plugin.event;
+
+import static com.cool.core.plugin.consts.PluginConsts.i18n;
+
+import cn.hutool.core.util.ObjUtil;
+import com.cool.core.i18n.I18nGenerator;
+import com.cool.core.util.I18nUtil;
+import com.cool.modules.plugin.entity.PluginInfoEntity;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class PluginEventListener implements ApplicationListener {
+ private final I18nGenerator i18nGenerator;
+ private final I18nUtil i18nUtil;
+ @Async
+ @Override
+ public void onApplicationEvent(PluginEvent event) {
+ if (ObjUtil.equals(event.getKey(), i18n)) {
+ // 国际化插件变更
+ PluginActionEnum actionEnum = event.getActionEnum();
+ PluginInfoEntity pluginInfoEntity = event.getPluginInfoEntity();
+
+ if (ObjUtil.equals(actionEnum, PluginActionEnum.INSTALL) && ObjUtil.equals(pluginInfoEntity.getStatus(), 1)) {
+ // 安装插件后,如果插件状态为启用,则生成国际化文件
+ i18nGenerator.run((Map) pluginInfoEntity.getConfig());
+ } else if (ObjUtil.equals(actionEnum, PluginActionEnum.UPDATE)) {
+ if (ObjUtil.equals(pluginInfoEntity.getStatus(), 1)) {
+ // 更新插件配置
+ i18nGenerator.run((Map) pluginInfoEntity.getConfig());
+ } else {
+ // 停用
+ I18nUtil.enable = false;
+ }
+ } else if (ObjUtil.equals(actionEnum, PluginActionEnum.UNINSTALL)) {
+ // 卸载国际化插件,则删除国际化文件
+ i18nUtil.clear();
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/com/cool/core/plugin/event/PluginEventPublisher.java b/src/main/java/com/cool/core/plugin/event/PluginEventPublisher.java
new file mode 100644
index 0000000..78d9474
--- /dev/null
+++ b/src/main/java/com/cool/core/plugin/event/PluginEventPublisher.java
@@ -0,0 +1,19 @@
+package com.cool.core.plugin.event;
+
+import com.cool.modules.plugin.entity.PluginInfoEntity;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class PluginEventPublisher {
+ private final ApplicationEventPublisher applicationEventPublisher;
+
+ public void publish(String key, PluginActionEnum actionEnum, PluginInfoEntity data) {
+ PluginEvent event = new PluginEvent(this, key, actionEnum, data);
+ applicationEventPublisher.publishEvent(event);
+ }
+
+
+}
diff --git a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
index 16b57d4..34f6bd0 100644
--- a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
+++ b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
@@ -11,6 +11,8 @@ import com.cool.core.config.PluginJson;
import com.cool.core.exception.CoolException;
import com.cool.core.exception.CoolPreconditions;
import com.cool.core.plugin.config.DynamicJarClassLoader;
+import com.cool.core.plugin.event.PluginActionEnum;
+import com.cool.core.plugin.event.PluginEventPublisher;
import com.cool.core.util.CoolPluginInvokers;
import com.cool.core.util.MapExtUtil;
import com.cool.core.util.PathUtils;
@@ -24,6 +26,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
+import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.PersistenceException;
@@ -43,14 +46,15 @@ public class CoolPluginService {
final private PluginInfoService pluginInfoService;
+ final private PluginEventPublisher pluginEventPublisher;
+
@Value("${cool.plugin.path}")
private String pluginPath;
public void init() {
List list = pluginInfoService
.list(QueryWrapper
- .create().select(PluginInfoEntity::getId, PluginInfoEntity::getPluginJson,
- PluginInfoEntity::getKey, PluginInfoEntity::getName)
+ .create()
.eq(PluginInfoEntity::getStatus, 1));
if (ObjUtil.isEmpty(list)) {
log.info("没有可初始化的插件");
@@ -77,6 +81,7 @@ public class CoolPluginService {
dynamicJarLoaderService.install(pluginJson.getJarPath(), true);
// 设置配置
CoolPluginInvokers.setPluginJson(entity.getKey(), entity);
+ pluginEventPublisher.publish(entity.getKey(), PluginActionEnum.INSTALL, entity);
} catch (Exception e) {
log.error("初始化{}插件失败", entity.getName(), e);
} finally {
@@ -100,9 +105,10 @@ public class CoolPluginService {
PluginJson pluginJson = dynamicJarLoaderService.install(jarFilePath, force);
key = pluginJson.getKey();
// 保存插件信息入库
- savePluginInfo(pluginJson, jarFilePath, jarFile, force);
+ PluginInfoEntity pluginInfoEntity = savePluginInfo(pluginJson, jarFilePath, jarFile, force);
// 把 ApplicationContext 对象传递打插件类中,使其在插件中也能正常使用spring bean对象
CoolPluginInvokers.setApplicationContext(pluginJson.getKey());
+ pluginEventPublisher.publish(pluginJson.getKey(), PluginActionEnum.INSTALL, pluginInfoEntity);
} catch (PersistenceException persistenceException) {
extractedAfterErr(jarFile, key);
if (persistenceException.getMessage().contains("Duplicate entry")) {
@@ -165,13 +171,14 @@ public class CoolPluginService {
boolean flag = pluginInfoEntity.removeById();
if (flag) {
FileUtil.del(pluginInfoEntity.getPluginJson().getJarPath());
+ pluginEventPublisher.publish(pluginInfoEntity.getKey(), PluginActionEnum.UNINSTALL, null);
}
}
/**
* 保存插件信息
*/
- private void savePluginInfo(PluginJson pluginJson, String jarFilePath ,
+ private PluginInfoEntity savePluginInfo(PluginJson pluginJson, String jarFilePath ,
File jarFile,
boolean force) {
CoolPreconditions.checkEmpty(pluginJson, "插件安装失败");
@@ -186,9 +193,11 @@ public class CoolPluginService {
closeSameNamePlugin(pluginJson);
// 覆盖插件
coverPlugin(pluginJson, pluginInfo);
- return;
+ return pluginInfo;
}
+ pluginInfo.setStatus(1);
pluginInfo.save();
+ return pluginInfo;
}
/**
@@ -201,7 +210,7 @@ public class CoolPluginService {
String oldJarPath = one.getPluginJson().getJarPath();
// 重新加载配置不更新
pluginInfo.setConfig(one.getConfig());
- pluginInfo.getPluginJson().setConfig(one.getConfig());
+ pluginInfo.getPluginJson().setConfig((Map) one.getConfig());
// 设置插件配置
CoolPluginInvokers.setPluginJson(pluginInfo.getKey(), pluginInfo);
CopyOptions options = CopyOptions.create().setIgnoreNullValue(true);
@@ -274,10 +283,11 @@ public class CoolPluginService {
entity.getId());
// 调用插件更新配置标识
boolean invokePluginConfig = false;
- if (!MapExtUtil.compareMaps(entity.getConfig(), dbPluginInfoEntity.getConfig())) {
+ if (!MapExtUtil.compareMaps((Map) entity.getConfig(),
+ (Map) dbPluginInfoEntity.getConfig())) {
// 不一致,说明更新了配置
entity.setPluginJson(dbPluginInfoEntity.getPluginJson());
- entity.getPluginJson().setConfig(entity.getConfig());
+ entity.getPluginJson().setConfig((Map) entity.getConfig());
// 更新了配置, 且插件是开启状态
invokePluginConfig = ObjUtil.equals(dbPluginInfoEntity.getStatus(), 1);
}
@@ -290,6 +300,8 @@ public class CoolPluginService {
CoolPluginInvokers.setPluginJson(dbPluginInfoEntity.getKey(), entity);
}
pluginInfoService.update(entity);
+ pluginEventPublisher.publish(dbPluginInfoEntity.getKey(), PluginActionEnum.UPDATE, pluginInfoService.getPluginInfoEntityById(
+ entity.getId()));
}
/**
diff --git a/src/main/java/com/cool/core/request/RequestParamsFilter.java b/src/main/java/com/cool/core/request/RequestParamsFilter.java
index 257e197..2ac9923 100644
--- a/src/main/java/com/cool/core/request/RequestParamsFilter.java
+++ b/src/main/java/com/cool/core/request/RequestParamsFilter.java
@@ -31,12 +31,14 @@ public class RequestParamsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
- throws IOException, ServletException {
+ throws IOException, ServletException {
// 防止流读取一次后就没有了, 所以需要将流继续写出去
HttpServletRequest request = (HttpServletRequest) servletRequest;
JSONObject requestParams = new JSONObject();
+ String language = request.getHeader("language");
if (StrUtil.isNotEmpty(request.getContentType()) && request.getContentType().contains("multipart/form-data")) {
servletRequest.setAttribute("requestParams", requestParams);
+ servletRequest.setAttribute("cool-language", language);
filterChain.doFilter(servletRequest, servletResponse);
} else {
BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
@@ -57,7 +59,7 @@ public class RequestParamsFilter implements Filter {
requestParams.set("tokenInfo", ((JWT) jwtObj).getPayload().getClaimsJson());
}
requestWrapper.setAttribute("requestParams", requestParams);
-
+ requestWrapper.setAttribute("cool-language", language);
filterChain.doFilter(requestWrapper, servletResponse);
}
}
diff --git a/src/main/java/com/cool/core/util/I18nUtil.java b/src/main/java/com/cool/core/util/I18nUtil.java
new file mode 100644
index 0000000..91b92fb
--- /dev/null
+++ b/src/main/java/com/cool/core/util/I18nUtil.java
@@ -0,0 +1,136 @@
+package com.cool.core.util;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import jakarta.annotation.PostConstruct;
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+@Slf4j
+@Component
+public class I18nUtil {
+
+ public static final String MSG_PREFIX = "msg_";
+ public static final String MENU_PREFIX = "menu_";
+ public static final String DICT_INFO_PREFIX = "dictInfo_";
+ public static final String DICT_TYPE_PREFIX = "dictType_";
+
+ public static boolean enable = false;
+
+ public static String path;
+ public static String getLanguage() {
+ RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+ if (attributes == null) {
+ return null;
+ }
+ return (String) attributes.getAttribute("cool-language", RequestAttributes.SCOPE_REQUEST);
+ }
+
+ private static final Map data = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void init() {
+ if (!enable) {
+ return;
+ }
+ try {
+ // 获取该目录下所有的 .json 文件
+ List jsonFiles = FileUtil.loopFiles(getPath(), file ->
+ file.isFile() && file.getName().endsWith(".json")
+ );
+ jsonFiles.forEach(file -> {
+ String parentName = file.getParentFile().getName();
+ String content = FileUtil.readUtf8String(file);
+ String key = parentName + "_" + file.getName().replace(".json", "");
+ data.put(key, JSONUtil.parseObj(content));
+ });
+ } catch (Exception e) {
+ log.error("读取国际化文件失败", e);
+ }
+ }
+
+ public boolean exist(String name) {
+ // 获取该目录下所有的 .json 文件
+ List jsonFiles = FileUtil.loopFiles(getPath(), file ->
+ file.isFile() && file.getName().endsWith(".json")
+ );
+ AtomicReference flag = new AtomicReference<>(false);
+ jsonFiles.forEach(file -> {
+ String parentName = file.getParentFile().getName();
+ String key = parentName + "_" + file.getName().replace(".json", "");
+ if (key.equals(name)) {
+ flag.set(true);
+ }
+ });
+ return flag.get();
+ }
+
+ public static String getI18nMenu(String name) {
+ return getI18n(name, MENU_PREFIX);
+ }
+
+ public static String getI18nMsg(String name) {
+ return getI18n(name, MSG_PREFIX);
+ }
+
+ public static String getI18nDictInfo(String name) {
+ return getI18n(name, DICT_INFO_PREFIX);
+ }
+ public static String getI18nDictType(String name) {
+ return getI18n(name, DICT_TYPE_PREFIX);
+ }
+ private static String getI18n(String name, String prefix) {
+ if (!enable) {
+ return name;
+ }
+ String language = I18nUtil.getLanguage();
+ if (language == null) {
+ return name;
+ }
+ JSONObject jsonObject = data.get(prefix + language);
+ if (jsonObject == null) {
+ return name;
+ }
+ String str = jsonObject.getStr(name);
+ if (str == null) {
+ return name;
+ }
+ return str;
+ }
+
+ public void update(String key, JSONObject object) {
+ data.put(key, object);
+ String[] split = key.split("_");
+ String absolutePath = getPath();
+ File file = FileUtil.file(absolutePath, split[0], split[1] + ".json");
+ // 确保父目录存在
+ FileUtil.mkParentDirs(file);
+ // 写入内容
+ FileUtil.writeUtf8String(JSONUtil.toJsonStr(object), file);
+ }
+
+ private String getPath() {
+ String absolutePath = path;
+ if (!PathUtils.isAbsolutePath(absolutePath)) {
+ absolutePath = PathUtils.getUserDir() + File.separator + absolutePath;
+ }
+ return absolutePath;
+ }
+
+ public void clear() {
+ data.clear();
+ List jsonFiles = FileUtil.loopFiles(getPath(), file ->
+ file.isFile() && file.getName().endsWith(".json")
+ );
+ jsonFiles.forEach(File::delete);
+ enable = false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java b/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
index 8e1fc59..451ab3c 100644
--- a/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
+++ b/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
@@ -6,6 +6,8 @@ import com.cool.core.annotation.TokenIgnore;
import com.cool.core.eps.CoolEps;
import com.cool.core.file.FileUploadStrategyFactory;
import com.cool.core.request.R;
+import com.cool.core.util.I18nUtil;
+import com.cool.modules.base.entity.sys.BaseSysMenuEntity;
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
import com.cool.modules.base.service.sys.BaseSysLoginService;
import com.cool.modules.base.service.sys.BaseSysPermsService;
@@ -14,6 +16,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
@@ -67,7 +70,10 @@ public class AdminBaseCommController {
@Operation(summary = "权限与菜单")
@GetMapping("/permmenu")
public R permmenu(@RequestAttribute() Long adminUserId) {
- return R.ok(baseSysPermsService.permmenu(adminUserId));
+ Dict permmenu = baseSysPermsService.permmenu(adminUserId);
+ List list = (List) permmenu.getObj("menus");
+ list.forEach(o -> o.setName(I18nUtil.getI18nMenu(o.getName())));
+ return R.ok(permmenu);
}
@Operation(summary = "文件上传")
diff --git a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysMenuController.java b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysMenuController.java
index d1abeee..fbe96e2 100644
--- a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysMenuController.java
+++ b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysMenuController.java
@@ -4,7 +4,9 @@ import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.base.BaseController;
import com.cool.core.exception.CoolPreconditions;
+import com.cool.core.request.CrudOption;
import com.cool.core.request.R;
+import com.cool.core.util.I18nUtil;
import com.cool.modules.base.entity.sys.BaseSysMenuEntity;
import com.cool.modules.base.service.sys.BaseSysMenuService;
import io.swagger.v3.oas.annotations.Operation;
@@ -25,6 +27,14 @@ public class AdminBaseSysMenuController extends
@Override
protected void init(HttpServletRequest request, JSONObject requestParams) {
+ CrudOption transform = createOp()
+ .transform(o -> {
+ BaseSysMenuEntity entity = (BaseSysMenuEntity) o;
+ entity.setName(I18nUtil.getI18nMenu(entity.getName()));
+ });
+ setPageOption(transform);
+ setListOption(transform);
+ setInfoOption(transform);
}
@Operation(summary = "创建代码", description = "创建代码")
diff --git a/src/main/java/com/cool/modules/base/service/sys/BaseSysPermsService.java b/src/main/java/com/cool/modules/base/service/sys/BaseSysPermsService.java
index 2333b66..0e364db 100644
--- a/src/main/java/com/cool/modules/base/service/sys/BaseSysPermsService.java
+++ b/src/main/java/com/cool/modules/base/service/sys/BaseSysPermsService.java
@@ -1,8 +1,8 @@
package com.cool.modules.base.service.sys;
+import cn.hutool.core.lang.Dict;
import com.cool.modules.base.entity.sys.BaseSysMenuEntity;
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
-
import java.util.List;
/**
@@ -117,7 +117,7 @@ public interface BaseSysPermsService {
* @param adminUserId 登录的用户
* @return 权限菜单
*/
- Object permmenu(Long adminUserId);
+ Dict permmenu(Long adminUserId);
/**
* 更新角色权限
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
index d02bd00..0e3d930 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
@@ -3,11 +3,13 @@ package com.cool.modules.base.service.sys.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
+import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import com.cool.CoolApplication;
import com.cool.core.base.BaseServiceImpl;
import com.cool.core.base.ModifyEnum;
import com.cool.core.eps.CoolEps;
+import com.cool.core.i18n.I18nGenerator;
import com.cool.core.util.CompilerUtils;
import com.cool.core.util.CoolSecurityUtil;
import com.cool.core.util.PathUtils;
@@ -62,6 +64,9 @@ public class BaseSysMenuServiceImpl extends BaseServiceImpl menus) {
menus.forEach(this::importMenu);
+ SpringUtil.getBean(I18nGenerator.class).asyncGenBaseMenu();
return true;
}
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
index bcc6194..42919a5 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
@@ -168,7 +168,7 @@ public class BaseSysPermsServiceImpl implements BaseSysPermsService {
}
@Override
- public Object permmenu(Long adminUserId) {
+ public Dict permmenu(Long adminUserId) {
return Dict.create().set("menus", getMenus(adminUserId)).set("perms", getPerms(adminUserId));
}
diff --git a/src/main/java/com/cool/modules/dict/controller/admin/AdminDictInfoController.java b/src/main/java/com/cool/modules/dict/controller/admin/AdminDictInfoController.java
index 2ec84b1..a9288d0 100644
--- a/src/main/java/com/cool/modules/dict/controller/admin/AdminDictInfoController.java
+++ b/src/main/java/com/cool/modules/dict/controller/admin/AdminDictInfoController.java
@@ -5,7 +5,9 @@ import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.annotation.TokenIgnore;
import com.cool.core.base.BaseController;
+import com.cool.core.request.CrudOption;
import com.cool.core.request.R;
+import com.cool.core.util.I18nUtil;
import com.cool.modules.dict.entity.DictInfoEntity;
import com.cool.modules.dict.entity.table.DictInfoEntityTableDef;
import com.cool.modules.dict.service.DictInfoService;
@@ -26,8 +28,18 @@ public class AdminDictInfoController extends BaseController {
+ DictInfoEntity entity = (DictInfoEntity) o;
+ entity.setName(I18nUtil.getI18nDictInfo(entity.getName()));
+ }));
+ CrudOption transform = createOp().transform(o -> {
+ DictInfoEntity entity = (DictInfoEntity) o;
+ entity.setName(I18nUtil.getI18nDictInfo(entity.getName()));
+ });
+ setPageOption(transform);
+ setInfoOption(transform);
}
@Operation(summary = "获得字典数据", description = "获得字典数据信息")
diff --git a/src/main/java/com/cool/modules/dict/controller/admin/AdminDictTypeController.java b/src/main/java/com/cool/modules/dict/controller/admin/AdminDictTypeController.java
index f94d5bb..fb0ff5f 100644
--- a/src/main/java/com/cool/modules/dict/controller/admin/AdminDictTypeController.java
+++ b/src/main/java/com/cool/modules/dict/controller/admin/AdminDictTypeController.java
@@ -1,15 +1,17 @@
package com.cool.modules.dict.controller.admin;
+import static com.cool.modules.dict.entity.table.DictTypeEntityTableDef.DICT_TYPE_ENTITY;
+
import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.base.BaseController;
+import com.cool.core.request.CrudOption;
+import com.cool.core.util.I18nUtil;
import com.cool.modules.dict.entity.DictTypeEntity;
import com.cool.modules.dict.service.DictTypeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
-import static com.cool.modules.dict.entity.table.DictTypeEntityTableDef.DICT_TYPE_ENTITY;
-
/**
* 字典类型
*/
@@ -20,6 +22,15 @@ public class AdminDictTypeController extends BaseController {
+ DictTypeEntity entity = (DictTypeEntity) o;
+ entity.setName(I18nUtil.getI18nDictType(entity.getName()));
+ }));
+ CrudOption transform = createOp().transform(o -> {
+ DictTypeEntity entity = (DictTypeEntity) o;
+ entity.setName(I18nUtil.getI18nDictType(entity.getName()));
+ });
+ setPageOption(transform);
+ setInfoOption(transform);
}
}
diff --git a/src/main/java/com/cool/modules/dict/service/impl/DictInfoServiceImpl.java b/src/main/java/com/cool/modules/dict/service/impl/DictInfoServiceImpl.java
index 7235875..51e6506 100644
--- a/src/main/java/com/cool/modules/dict/service/impl/DictInfoServiceImpl.java
+++ b/src/main/java/com/cool/modules/dict/service/impl/DictInfoServiceImpl.java
@@ -8,7 +8,11 @@ import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.json.JSONObject;
import com.cool.core.base.BaseServiceImpl;
+import com.cool.core.base.ModifyEnum;
+import com.cool.core.i18n.I18nGenerator;
import com.cool.modules.dict.entity.DictInfoEntity;
import com.cool.modules.dict.entity.DictTypeEntity;
import com.cool.modules.dict.mapper.DictInfoMapper;
@@ -121,4 +125,10 @@ public class DictInfoServiceImpl extends BaseServiceImpl 0;
}
+
+ @Override
+ public void modifyBefore(JSONObject requestParams, DictTypeEntity t, ModifyEnum type) {
+ if (ModifyEnum.ADD.equals(type) || ModifyEnum.UPDATE.equals(type)) {
+ SpringUtil.getBean(I18nGenerator.class).asyncGenBaseDictType();
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/cool/modules/plugin/controller/admin/AdminPluginInfoController.java b/src/main/java/com/cool/modules/plugin/controller/admin/AdminPluginInfoController.java
index 93d28e2..40f20a2 100644
--- a/src/main/java/com/cool/modules/plugin/controller/admin/AdminPluginInfoController.java
+++ b/src/main/java/com/cool/modules/plugin/controller/admin/AdminPluginInfoController.java
@@ -3,7 +3,9 @@ package com.cool.modules.plugin.controller.admin;
import static com.cool.modules.plugin.entity.table.PluginInfoEntityTableDef.PLUGIN_INFO_ENTITY;
import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.annotation.IgnoreRecycleData;
import com.cool.core.base.BaseController;
@@ -16,6 +18,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
+import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
@@ -45,6 +48,11 @@ public class AdminPluginInfoController extends BaseController());
+ }
coolPluginService.updatePlugin(t);
return R.ok();
}
diff --git a/src/main/java/com/cool/modules/plugin/entity/PluginInfoEntity.java b/src/main/java/com/cool/modules/plugin/entity/PluginInfoEntity.java
index 1905432..f38da3e 100644
--- a/src/main/java/com/cool/modules/plugin/entity/PluginInfoEntity.java
+++ b/src/main/java/com/cool/modules/plugin/entity/PluginInfoEntity.java
@@ -8,7 +8,6 @@ import com.mybatisflex.core.handler.Fastjson2TypeHandler;
import com.mybatisflex.core.handler.JacksonTypeHandler;
import com.tangzc.mybatisflex.autotable.annotation.ColumnDefine;
import com.tangzc.mybatisflex.autotable.annotation.UniIndex;
-import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import org.dromara.autotable.annotation.Ignore;
@@ -54,7 +53,7 @@ public class PluginInfoEntity extends BaseEntity {
@ColumnDefine(comment = "配置", type = "json")
@Column(typeHandler = JacksonTypeHandler.class)
- private Map config;
+ private Object config;
@Ignore
@Column(ignore = true)