feat: 国际化

This commit is contained in:
taojinlong 2021-05-18 09:39:00 +08:00
parent 8fadc27a29
commit 21e38a0ffd
9 changed files with 272 additions and 8 deletions

View File

@ -2,6 +2,7 @@ package io.dataease.auth.api;
import io.dataease.auth.api.dto.DynamicMenuDto;
import io.dataease.controller.handler.annotation.I18n;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -16,6 +17,7 @@ public interface DynamicMenuApi {
* @return
*/
@PostMapping("/menus")
@I18n
List<DynamicMenuDto> menus();
}

View File

@ -2,5 +2,5 @@ package io.dataease.commons.constants;
public class I18nConstants {
public static final String LANG_COOKIE_NAME = "MS_USER_LANG";
public static final String LANG_COOKIE_NAME = "DE_USER_LANG";
}

View File

@ -27,8 +27,6 @@ public class I18nController {
@Value("${run.mode:release}")
private String runMode;
// @Resource
// private UserService userService;
@GetMapping("lang/change/{lang}")
public void changeLang(@PathVariable String lang, HttpServletRequest request, HttpServletResponse response) {
@ -38,14 +36,13 @@ public class I18nController {
LogUtil.error("Invalid parameter: " + lang);
DEException.throwException(Translator.get("error_lang_invalid"));
}
// userService.setLanguage(targetLang.getDesc());
Cookie cookie = new Cookie(I18nConstants.LANG_COOKIE_NAME, targetLang.getDesc());
cookie.setPath("/");
cookie.setMaxAge(FOR_EVER);
response.addCookie(cookie);
//重新登录
if ("release".equals(runMode)) {
Cookie f2cCookie = new Cookie("MS_SESSION_ID", "deleteMe");
Cookie f2cCookie = new Cookie("DE_SESSION_ID", "deleteMe");
f2cCookie.setPath("/");
f2cCookie.setMaxAge(0);
response.addCookie(f2cCookie);

View File

@ -1,8 +1,17 @@
package io.dataease.controller.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JavaBeanSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.google.gson.Gson;
import io.dataease.commons.constants.I18nConstants;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.handler.annotation.I18n;
import io.dataease.controller.handler.annotation.NoResultHolder;
import io.dataease.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
@ -13,6 +22,10 @@ import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
/**
* 统一处理返回结果集
*/
@ -35,6 +48,12 @@ public class ResultResponseBodyAdvice implements ResponseBodyAdvice<Object> {
return o;
}
//if true, need to translate
if (methodParameter.hasMethodAnnotation(I18n.class)) {
I18n i18n = methodParameter.getMethodAnnotation(I18n.class);
o = translate(o, i18n.value());
}
if (!(o instanceof ResultHolder)) {
if (o instanceof String) {
return new Gson().toJson(ResultHolder.success(o));
@ -44,4 +63,11 @@ public class ResultResponseBodyAdvice implements ResponseBodyAdvice<Object> {
return o;
}
// i18n
private Object translate(Object obj, String type) {
return Translator.translateObject(obj);
}
}

View File

@ -1,12 +1,31 @@
package io.dataease.i18n;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JavaBeanSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.exception.DataEaseException;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
public class Translator {
private static MessageSource messageSource;
private static final String JSON_SYMBOL = "\":";
private static final HashSet<String> IGNORE_KEYS = new HashSet<>(Arrays.asList("id", "password", "passwd"));
@Resource
public void setMessageSource(MessageSource messageSource) {
@ -17,6 +36,117 @@ public class Translator {
* 单Key翻译
*/
public static String get(String key) {
return messageSource.getMessage(key, null, "Not Support Key: " + key, LocaleContextHolder.getLocale());
System.out.println(LocaleContextHolder.getLocale());
return messageSource.getMessage(key, null, key, LocaleContextHolder.getLocale());
}
private static Object translateRawString(String key, String rawString) {
if (StringUtils.isBlank(rawString)) {
return rawString;
}
for (String ignoreKey : IGNORE_KEYS) {
if (StringUtils.containsIgnoreCase(key, ignoreKey)) {
return rawString;
}
}
if (key != null) {
String desc = get(rawString);
if (StringUtils.isNotBlank(desc)) {
return desc;
}
}
return rawString;
}
public static Object translateObject(Object javaObject) {
if (javaObject == null) {
return null;
}
try {
if (javaObject instanceof String) {
String rawString = javaObject.toString();
if (StringUtils.contains(rawString, JSON_SYMBOL)) {
try {
Object jsonObject = JSON.parse(rawString);
Object a = translateObject(jsonObject);
return JSON.toJSONString(a);
} catch (Exception e) {
LogUtil.error("Failed to translate object: " + rawString, e);
e.printStackTrace();
LogUtil.warn("Failed to translate object " + rawString + ". Error: " + ExceptionUtils.getStackTrace(e));
return translateRawString(null, rawString);
}
} else {
return translateRawString(null, rawString);
}
}
if (javaObject instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) javaObject;
for (Map.Entry<Object, Object> entry : map.entrySet()) {
if (entry.getValue() != null) {
if (entry.getValue() instanceof String) {
if (StringUtils.contains(entry.getValue().toString(), JSON_SYMBOL)) {
map.put(entry.getKey(), translateObject(entry.getValue()));
} else {
map.put(entry.getKey(), translateRawString(entry.getKey().toString(), entry.getValue().toString()));
}
} else {
translateObject(entry.getValue());
}
}
}
}
if (javaObject instanceof Collection) {
Collection<Object> collection = (Collection<Object>) javaObject;
for (Object item : collection) {
translateObject(item);
}
}
if (javaObject.getClass().isArray()) {
for (int i = 0; i < Array.getLength(javaObject); ++i) {
Object item = Array.get(javaObject, i);
Array.set(javaObject, i, translateObject(item));
}
}
ObjectSerializer serializer = SerializeConfig.globalInstance.getObjectWriter(javaObject.getClass());
if (serializer instanceof JavaBeanSerializer) {
JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) serializer;
try {
Map<String, Object> values = javaBeanSerializer.getFieldValuesMap(javaObject);
for (Map.Entry<String, Object> entry : values.entrySet()) {
if (entry.getValue() != null) {
if (entry.getValue() instanceof String) {
if (StringUtils.contains(entry.getValue().toString(), JSON_SYMBOL)) {
BeanUtils.setFieldValueByName(javaObject, entry.getKey(), translateObject(entry.getValue()), String.class);
} else {
BeanUtils.setFieldValueByName(javaObject, entry.getKey(), translateRawString(entry.getKey(), entry.getValue().toString()), String.class);
}
} else {
translateObject(entry.getValue());
}
}
}
} catch (Exception e) {
DataEaseException.throwException(e);
}
}
return javaObject;
} catch (StackOverflowError stackOverflowError) {
try {
return JSON.parseObject(translateRawString(null, JSON.toJSONString(javaObject)).toString(), javaObject.getClass());
} catch (Exception e) {
LogUtil.error("Failed to translate object " + javaObject.toString(), e);
return javaObject;
}
}
}
}

View File

@ -185,3 +185,39 @@ authsource_name_already_exists=Authentication source name already exists
authsource_name_is_null=Authentication source name cannot be empty
authsource_configuration_is_null=Authentication source configuration cannot be empty
个人信息=Personal Information
仪表盘=Panel
修改密码=Change Password
创建用户=Create User
创建组织=Create Organization
创建菜单=Create Menu
创建角色=Create Role
创建连接=Create Connection
删除用户=Delete User
删除组织=Delete Organization
删除菜单=Delete Menu
删除角色=Delete Role
删除连接=Delete Connection
参数管理=Parameter Management
数据源=Data Source
数据源表单=Data source form
数据集=Data Set
权限管理=Authority Management
校验连接=Verify Connection
模板管理=Template Management
用户管理=User Management
用户表单=User Form
系统管理=System management
组织管理=Organization management
组织表单=Organization Form
编辑用户=Edit User
编辑组织=Edit Organization
编辑菜单=Edit Menu
编辑角色=Edit Role
编辑连接=Edit Connection
菜单管理=Menu management
菜单表单=Menu Form
视图=View
角色管理=Role management
角色表单=Role Form
重置密码=Reset Password

View File

@ -185,3 +185,40 @@ automation_exec_info=没有测试步骤,无法执行
authsource_name_already_exists=认证源名称已经存在
authsource_name_is_null=认证源名称不能为空
authsource_configuration_is_null=认证源配置不能为空
个人信息=个人信息
仪表盘=仪表盘
修改密码=修改密码
创建用户=创建用户
创建组织=创建组织
创建菜单=创建菜单
创建角色=创建角色
创建连接=创建连接
删除用户=删除用户
删除组织=删除组织
删除菜单=删除菜单
删除角色=删除角色
删除连接=删除连接
参数管理=参数管理
数据源=数据源
数据源表单=数据源表单
数据集=数据集
权限管理=权限管理
校验连接=校验连接
模板管理=模板管理
用户管理=用户管理
用户表单=用户表单
系统管理=系统管理
组织管理=组织管理
组织表单=组织表单
编辑用户=编辑用户
编辑组织=编辑组织
编辑菜单=编辑菜单
编辑角色=编辑角色
编辑连接=编辑连接
菜单管理=菜单管理
菜单表单=菜单表单
视图=视图
角色管理=角色管理
角色表单=角色表单
重置密码=重置密码

View File

@ -185,4 +185,40 @@ automation_exec_info=沒有測試步驟,無法執行
#authsource
authsource_name_already_exists=認證源名稱已經存在
authsource_name_is_null=認證源名稱不能為空
authsource_configuration_is_null=認證源配置不能為空
authsource_configuration_is_null=認證源配置不能為空
个人信息=個人信息
仪表盘=儀表盤
修改密码=修改密碼
创建用户=創建用戶
创建组织=創建組織
创建菜单=創建菜單
创建角色=創建角色
创建连接=創建鏈接
删除用户=刪除用戶
删除组织=刪除組織
删除菜单=刪除菜單
删除角色=刪除角色
删除连接=删除鏈接
参数管理=參數管理
数据源=數據源
数据源表单=數據源表單
数据集=數據集
权限管理=權限管理
校验连接=校驗鏈接
模板管理=模板管理
用户管理=用戶管理
用户表单=用戶表單
系统管理=系統管理
组织管理=組織管理
组织表单=組織表單
编辑用户=編輯用戶
编辑组织=編輯組織
编辑菜单=編輯菜單
编辑角色=編輯角色
编辑连接=編輯鏈接
菜单管理=菜單管理
菜单表单=表單管理
视图=視圖
角色管理=角色管理
角色表单=角色表單
重置密码=重置密碼

View File

@ -41,7 +41,7 @@
</el-col>
<el-col v-if="panelInfo.name.length===0" style="height: 100%;">
<el-row style="height: 100%;" class="custom-position">
{{ $t('panle.select_panel_from_left') }}
{{ $t('panel.select_panel_from_left') }}
</el-row>
</el-col>