From 842a6e238355a4de76c9e275f4488d7965894523 Mon Sep 17 00:00:00 2001
From: ruying408 <1877972603@qq.com>
Date: Thu, 10 Apr 2025 00:06:25 +0800
Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E8=AF=91=E7=94=9F=E6=88=90=E4=BB=A3?=
=?UTF-8?q?=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 19 +++
.../com/cool/core/plugin/I18nGenerator.java | 157 ++++++++++++++++++
2 files changed, 176 insertions(+)
create mode 100644 src/main/java/com/cool/core/plugin/I18nGenerator.java
diff --git a/pom.xml b/pom.xml
index 30e9a8c..fb63efb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,6 +190,25 @@
+
+
+ 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/plugin/I18nGenerator.java b/src/main/java/com/cool/core/plugin/I18nGenerator.java
new file mode 100644
index 0000000..aeca1db
--- /dev/null
+++ b/src/main/java/com/cool/core/plugin/I18nGenerator.java
@@ -0,0 +1,157 @@
+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("//.*", ""); // 单行注释
+ }
+}