feat(国际化): 新增国际化

This commit is contained in:
gx_ma
2026-03-24 11:41:41 +08:00
parent abe46baf18
commit e70c198071
97 changed files with 10802 additions and 5302 deletions

View File

@@ -183,6 +183,19 @@
<artifactId>easyexcel-core</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -171,4 +171,20 @@ public class Constants
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
/**
* 语言类型
*/
public static final String LANGUAGE = "language";
public static final String ZH_CN = "zh-CN";
public static final String EN_US = "en-US";
/**
* 翻译数据类型
*/
public static final String MENU = "menu";
public static final String DICT_DATA = "dict_data";
public static final String DICT_TYPE = "dict_type";
public static final String THINGS_MODEL = "things_model";
public static final String THINGS_MODEL_TEMPLATE = "things_model_template";
}

View File

@@ -8,10 +8,7 @@ import com.fastbee.common.core.page.PageDomain;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.core.page.TableSupport;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.PageUtils;
import com.fastbee.common.utils.SecurityUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.*;
import com.fastbee.common.utils.sql.SqlUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@@ -91,12 +88,22 @@ public class BaseController
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setMsg(MessageUtils.message("query.success"));
rspData.setRows(list);
rspData.setTotal(new PageInfo(list).getTotal());
return rspData;
}
protected TableDataInfo getDataTable(List<?> list, Long total)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg(MessageUtils.message("query.success"));
rspData.setRows(list);
rspData.setTotal(total);
return rspData;
}
/**
* 返回成功
*/

View File

@@ -3,8 +3,11 @@ package com.fastbee.common.core.domain.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.annotation.Excel;
@@ -17,6 +20,8 @@ import com.fastbee.common.core.domain.BaseEntity;
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "SysDictData", description = "字典数据表 sys_dict_data")
public class SysDictData extends BaseEntity
{
@@ -65,125 +70,18 @@ public class SysDictData extends BaseEntity
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictCode()
{
return dictCode;
}
/** 字典标签 */
@TableField(exist = false)
@ApiModelProperty("中文字典标签")
private String dictLabel_zh_CN;
public void setDictCode(Long dictCode)
{
this.dictCode = dictCode;
}
/** 字典标签 */
@TableField(exist = false)
@ApiModelProperty("英文字典标签")
private String dictLabel_en_US;
public Long getDictSort()
{
return dictSort;
}
@TableField(exist = false)
@Deprecated
private String language;
public void setDictSort(Long dictSort)
{
this.dictSort = dictSort;
}
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel()
{
return dictLabel;
}
public void setDictLabel(String dictLabel)
{
this.dictLabel = dictLabel;
}
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue()
{
return dictValue;
}
public void setDictValue(String dictValue)
{
this.dictValue = dictValue;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass()
{
return cssClass;
}
public void setCssClass(String cssClass)
{
this.cssClass = cssClass;
}
public String getListClass()
{
return listClass;
}
public void setListClass(String listClass)
{
this.listClass = listClass;
}
public boolean getDefault()
{
return UserConstants.YES.equals(this.isDefault);
}
public String getIsDefault()
{
return isDefault;
}
public void setIsDefault(String isDefault)
{
this.isDefault = isDefault;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode())
.append("dictSort", getDictSort())
.append("dictLabel", getDictLabel())
.append("dictValue", getDictValue())
.append("dictType", getDictType())
.append("cssClass", getCssClass())
.append("listClass", getListClass())
.append("isDefault", getIsDefault())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -4,8 +4,11 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.annotation.Excel;
@@ -17,6 +20,8 @@ import com.fastbee.common.core.domain.BaseEntity;
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "SysDictType", description = "字典类型表 sys_dict_type")
public class SysDictType extends BaseEntity
{
@@ -42,63 +47,18 @@ public class SysDictType extends BaseEntity
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictId()
{
return dictId;
}
/** 字典类型标签 */
@ApiModelProperty("中文字典标签")
@TableField(exist = false)
private String dictName_zh_CN;
public void setDictId(Long dictId)
{
this.dictId = dictId;
}
/** 字典类型标签 */
@ApiModelProperty("英文字典标签")
@TableField(exist = false)
private String dictName_en_US;
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName()
{
return dictName;
}
@TableField(exist = false)
@Deprecated
private String language;
public void setDictName(String dictName)
{
this.dictName = dictName;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -6,8 +6,11 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.core.domain.BaseEntity;
@@ -17,6 +20,8 @@ import com.fastbee.common.core.domain.BaseEntity;
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "SysMenu", description = "菜单权限表 sys_menu")
public class SysMenu extends BaseEntity
{
@@ -89,206 +94,18 @@ public class SysMenu extends BaseEntity
@ApiModelProperty("子菜单")
private List<SysMenu> children = new ArrayList<SysMenu>();
public Long getMenuId()
{
return menuId;
}
@Deprecated
@TableField(exist = false)
private String language;
public void setMenuId(Long menuId)
{
this.menuId = menuId;
}
/** 菜单名称 */
@TableField(exist = false)
@ApiModelProperty("中文菜单名称")
private String menuName_zh_CN;
@NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
public String getMenuName()
{
return menuName;
}
/** 菜单名称 */
@TableField(exist = false)
@ApiModelProperty("英文菜单名称")
private String menuName_en_US;
public void setMenuName(String menuName)
{
this.menuName = menuName;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
public String getPath()
{
return path;
}
public void setPath(String path)
{
this.path = path;
}
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
public String getComponent()
{
return component;
}
public void setComponent(String component)
{
this.component = component;
}
public String getQuery()
{
return query;
}
public void setQuery(String query)
{
this.query = query;
}
public String getRouteName()
{
return routeName;
}
public void setRouteName(String routeName)
{
this.routeName = routeName;
}
public String getIsFrame()
{
return isFrame;
}
public void setIsFrame(String isFrame)
{
this.isFrame = isFrame;
}
public String getIsCache()
{
return isCache;
}
public void setIsCache(String isCache)
{
this.isCache = isCache;
}
@NotBlank(message = "菜单类型不能为空")
public String getMenuType()
{
return menuType;
}
public void setMenuType(String menuType)
{
this.menuType = menuType;
}
public String getVisible()
{
return visible;
}
public void setVisible(String visible)
{
this.visible = visible;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms()
{
return perms;
}
public void setPerms(String perms)
{
this.perms = perms;
}
public String getIcon()
{
return icon;
}
public void setIcon(String icon)
{
this.icon = icon;
}
public List<SysMenu> getChildren()
{
return children;
}
public void setChildren(List<SysMenu> children)
{
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("menuId", getMenuId())
.append("menuName", getMenuName())
.append("parentId", getParentId())
.append("orderNum", getOrderNum())
.append("path", getPath())
.append("component", getComponent())
.append("query", getQuery())
.append("routeName", getRouteName())
.append("isFrame", getIsFrame())
.append("IsCache", getIsCache())
.append("menuType", getMenuType())
.append("visible", getVisible())
.append("status ", getStatus())
.append("perms", getPerms())
.append("icon", getIcon())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -4,8 +4,11 @@ import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.annotation.Excel;
@@ -20,6 +23,8 @@ import com.fastbee.common.xss.Xss;
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "SysUser", description = "用户对象 sys_user")
public class SysUser extends BaseEntity
{
@@ -111,236 +116,26 @@ public class SysUser extends BaseEntity
@ApiModelProperty("角色ID")
private Long roleId;
public SysUser()
{
@TableField(exist = false)
private String language;
@TableField(exist = false)
private String timeZone;
public SysUser() {
}
public SysUser(Long userId)
{
public SysUser(Long userId) {
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public boolean isAdmin()
{
public boolean isAdmin() {
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId)
{
public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
return nickName;
}
public void setNickName(String nickName)
{
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getAvatar()
{
return avatar;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getLoginIp()
{
return loginIp;
}
public void setLoginIp(String loginIp)
{
this.loginIp = loginIp;
}
public Date getLoginDate()
{
return loginDate;
}
public void setLoginDate(Date loginDate)
{
this.loginDate = loginDate;
}
public SysDept getDept()
{
return dept;
}
public void setDept(SysDept dept)
{
this.dept = dept;
}
public List<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> roles)
{
this.roles = roles;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
public Long[] getPostIds()
{
return postIds;
}
public void setPostIds(Long[] postIds)
{
this.postIds = postIds;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
}
}

View File

@@ -0,0 +1,25 @@
package com.fastbee.common.enums;
public enum Language {
ZH_CN("zh-CN"),
EN("en-US"),
DEFAULT("default");
private String value;
Language(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static String matches(String language) {
if(language.equals("zh")){
return Language.ZH_CN.value;
}else {
return Language.EN.value;
}
}
}

View File

@@ -0,0 +1,24 @@
package com.fastbee.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import static com.fastbee.common.constant.Constants.*;
@Getter
@AllArgsConstructor
public enum TranslateType {
MENU_TYPE(MENU, "sys_menu_translate", "sys_menu", "menu_id", "menu_name"),
DICT_DATA_TYPE(DICT_DATA, "sys_dict_data_translate", "sys_dict_data", "dict_code", "dict_label"),
DICT_TYPE_TYPE(DICT_TYPE, "sys_dict_type_translate", "sys_dict_type", "dict_id", "dict_name"),
THINGS_MODEL_TYPE(THINGS_MODEL, "iot_things_model_translate", "iot_things_model", "model_id", "model_name"),
THINGS_MODEL_TEMPLATE_TYPE(THINGS_MODEL_TEMPLATE, "iot_things_model_template_translate", "iot_things_model_template", "template_id", "template_name");
String value;
String translateTable;
String sourceTable;
String idColumn;
String nameColumn;
}

View File

@@ -9,6 +9,9 @@ import com.fastbee.common.utils.spring.SpringUtils;
import java.util.Collection;
import java.util.List;
import static com.fastbee.common.constant.Constants.EN_US;
import static com.fastbee.common.constant.Constants.ZH_CN;
/**
* 字典工具类
*
@@ -53,15 +56,16 @@ public class DictUtils
*
* @param dictType 字典类型
* @param dictValue 字典值
* @param language 语言
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue)
public static String getDictLabel(String dictType, String dictValue, String language)
{
if (StringUtils.isEmpty(dictValue))
{
return StringUtils.EMPTY;
}
return getDictLabel(dictType, dictValue, SEPARATOR);
return getDictLabel(dictType, dictValue, SEPARATOR, language);
}
/**
@@ -86,9 +90,10 @@ public class DictUtils
* @param dictType 字典类型
* @param dictValue 字典值
* @param separator 分隔符
* @param language 语言
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue, String separator)
public static String getDictLabel(String dictType, String dictValue, String separator, String language)
{
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
@@ -116,7 +121,13 @@ public class DictUtils
{
if (dictValue.equals(dict.getDictValue()))
{
return dict.getDictLabel();
if (ZH_CN.equals(language)) {
return dict.getDictLabel_zh_CN();
} else if (EN_US.equals(language)) {
return dict.getDictLabel_en_US();
} else {
return dict.getDictLabel();
}
}
}
}

View File

@@ -176,4 +176,23 @@ public class SecurityUtils
.anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));
}
/**
* 获取语言
* @return
*/
public static String getLanguage(){
try
{
String language = getLoginUser().getLanguage();
if (StringUtils.isEmpty(language)){
return "en-US";
}
return language;
}
catch (Exception e)
{
return "en-US";
}
}
}