diff --git a/core/core-backend/src/main/java/io/dataease/home/RestIndexController.java b/core/core-backend/src/main/java/io/dataease/home/RestIndexController.java index 701dfa52a0..aee4db25ae 100644 --- a/core/core-backend/src/main/java/io/dataease/home/RestIndexController.java +++ b/core/core-backend/src/main/java/io/dataease/home/RestIndexController.java @@ -1,6 +1,7 @@ package io.dataease.home; import io.dataease.home.manage.DeIndexManage; +import io.dataease.i18n.Translator; import io.dataease.utils.ModelUtils; import io.dataease.utils.RsaUtils; import jakarta.annotation.Resource; @@ -43,4 +44,9 @@ public class RestIndexController { return deIndexManage.xpackModel(); } + @GetMapping("/testi18n") + public String testi18n() { + return Translator.get("i18n_default_org"); + } + } diff --git a/sdk/common/src/main/java/io/dataease/i18n/DeI18nMessageConfig.java b/sdk/common/src/main/java/io/dataease/i18n/DeI18nMessageConfig.java new file mode 100644 index 0000000000..8484829a37 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/i18n/DeI18nMessageConfig.java @@ -0,0 +1,24 @@ +package io.dataease.i18n; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; + +import java.util.Arrays; + +@Configuration +public class DeI18nMessageConfig { + + @Value("${spring.messages.basename}") + private String messageBaseName; + + @Bean + public ReloadableResourceBundleMessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new DeReloadableResourceBundleMessageSource(); + messageSource.setResourceLoader(new AnnotationConfigServletWebServerApplicationContext()); + Arrays.stream(messageBaseName.split(",")).map(item -> "classpath:" + item).forEach(messageSource::addBasenames); + return messageSource; + } +} diff --git a/sdk/common/src/main/java/io/dataease/i18n/DeI18nStarter.java b/sdk/common/src/main/java/io/dataease/i18n/DeI18nStarter.java new file mode 100644 index 0000000000..7877527485 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/i18n/DeI18nStarter.java @@ -0,0 +1,18 @@ +package io.dataease.i18n; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(1000) +public class DeI18nStarter implements ApplicationRunner { + + + @Override + public void run(ApplicationArguments args) throws Exception { + DynamicI18nUtils.addOrUpdate("file:/opt/dataease2.0/data/i18n/custom"); + } + +} diff --git a/sdk/common/src/main/java/io/dataease/i18n/DeReloadableResourceBundleMessageSource.java b/sdk/common/src/main/java/io/dataease/i18n/DeReloadableResourceBundleMessageSource.java new file mode 100644 index 0000000000..dd4cf85a2f --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/i18n/DeReloadableResourceBundleMessageSource.java @@ -0,0 +1,19 @@ +package io.dataease.i18n; + +import org.springframework.context.support.ReloadableResourceBundleMessageSource; + +import java.util.Set; +import java.util.stream.Collectors; + +public class DeReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource { + + @Override + public Set getBasenameSet() { + return super.getBasenameSet().stream().sorted(this::compare).collect(Collectors.toSet()); + } + + private int compare(String o1, String o2) { + return o1.substring(0, 1).compareTo(o2.substring(0, 1)); + } + +} diff --git a/sdk/common/src/main/java/io/dataease/i18n/DynamicI18nUtils.java b/sdk/common/src/main/java/io/dataease/i18n/DynamicI18nUtils.java new file mode 100644 index 0000000000..6ec3096052 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/i18n/DynamicI18nUtils.java @@ -0,0 +1,23 @@ +package io.dataease.i18n; + +import jakarta.annotation.Resource; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.stereotype.Component; + +@Component +public class DynamicI18nUtils { + + + private static ReloadableResourceBundleMessageSource messageSource; + + @Resource + public void setMessageSource(ReloadableResourceBundleMessageSource messageSource) { + DynamicI18nUtils.messageSource = messageSource; + } + + public static void addOrUpdate(String baseName) { + messageSource.addBasenames(baseName); + messageSource.setCacheSeconds(0); + messageSource.clearCache(); + } +} diff --git a/sdk/common/src/main/java/io/dataease/i18n/I18n.java b/sdk/common/src/main/java/io/dataease/i18n/I18n.java index 63db002633..35a0f53718 100644 --- a/sdk/common/src/main/java/io/dataease/i18n/I18n.java +++ b/sdk/common/src/main/java/io/dataease/i18n/I18n.java @@ -7,5 +7,5 @@ import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface I18n { - String value() default I18nConstants.LANG_COOKIE_NAME; -} \ No newline at end of file + String value() default ""; +} diff --git a/sdk/common/src/main/java/io/dataease/i18n/I18nConstants.java b/sdk/common/src/main/java/io/dataease/i18n/I18nConstants.java deleted file mode 100644 index 80fb83718d..0000000000 --- a/sdk/common/src/main/java/io/dataease/i18n/I18nConstants.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.dataease.i18n; - -public class I18nConstants { - - public static final String LANG_COOKIE_NAME = "DE_USER_LANG"; -} diff --git a/sdk/common/src/main/java/io/dataease/i18n/Lang.java b/sdk/common/src/main/java/io/dataease/i18n/Lang.java index a3b107f84c..adeb160cf1 100644 --- a/sdk/common/src/main/java/io/dataease/i18n/Lang.java +++ b/sdk/common/src/main/java/io/dataease/i18n/Lang.java @@ -1,21 +1,19 @@ package io.dataease.i18n; +import lombok.Getter; import org.apache.commons.lang3.StringUtils; +@Getter public enum Lang { zh_CN("zh-CN"), zh_TW("zh-TW"), en_US("en-US"); - private String desc; + private final String desc; Lang(String desc) { this.desc = desc; } - public String getDesc() { - return this.desc; - } - public static Lang getLang(String lang) { Lang result = getLangWithoutDefault(lang); if (result == null) { diff --git a/sdk/common/src/main/java/io/dataease/i18n/Translator.java b/sdk/common/src/main/java/io/dataease/i18n/Translator.java index a073cf488b..3b4405222e 100644 --- a/sdk/common/src/main/java/io/dataease/i18n/Translator.java +++ b/sdk/common/src/main/java/io/dataease/i18n/Translator.java @@ -1,6 +1,7 @@ package io.dataease.i18n; import com.baomidou.mybatisplus.core.metadata.IPage; +import io.dataease.exception.DEException; import io.dataease.utils.BeanUtils; import io.dataease.utils.JsonUtil; import io.dataease.utils.LogUtil; @@ -14,7 +15,10 @@ import org.springframework.stereotype.Component; import java.lang.reflect.Array; import java.lang.reflect.Field; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; @Component public class Translator { @@ -40,7 +44,7 @@ public class Translator { /** * 获取国际化消息并替换占位符 * - * @param key 国际化键 如:确定删除名为{0}的{1}吗? + * @param key 国际化键 如:确定删除名为{0}的{1}吗? * @param placeholders 占位值 * @return 替换后的消息 */ @@ -146,7 +150,8 @@ public class Translator { } } } catch (Exception e) { - + LogUtil.error(e.getMessage()); + DEException.throwException(e); } } diff --git a/sdk/common/src/main/java/io/dataease/result/ResultResponseBodyAdvice.java b/sdk/common/src/main/java/io/dataease/result/ResultResponseBodyAdvice.java index 68606db69f..ef2dc5a03c 100644 --- a/sdk/common/src/main/java/io/dataease/result/ResultResponseBodyAdvice.java +++ b/sdk/common/src/main/java/io/dataease/result/ResultResponseBodyAdvice.java @@ -29,8 +29,7 @@ public class ResultResponseBodyAdvice implements ResponseBodyAdvice { } //if true, need to translate if (methodParameter.hasMethodAnnotation(I18n.class)) { - I18n i18n = methodParameter.getMethodAnnotation(I18n.class); - o = translate(o, i18n.value()); + o = translate(o); } if (!(o instanceof ResultMessage)) { @@ -45,7 +44,7 @@ public class ResultResponseBodyAdvice implements ResponseBodyAdvice { // i18n - private Object translate(Object obj, String type) { + private Object translate(Object obj) { return Translator.translateObject(obj); }