1、system服务国际化相关表免校验租户、token配置;2、system服务枚举相关国际化处理;3、system服务资金管理easyexcel导出表头国际化处理;

This commit is contained in:
gaoqr
2025-11-21 16:08:21 +08:00
parent cafdc15fad
commit ff71a6afbb
55 changed files with 472 additions and 629 deletions
@@ -0,0 +1,14 @@
package com.cf.imes.framework.common.constants;
/**
* 国际化资源包常量
*
* @author Gqr
* @since 2025/11/21 11:33
*/
public final class ResourceBundleConstants {
/**
* 枚举资源包
*/
public static final String MESSAGE_ENUM_PATH = "message_enum";
}
@@ -0,0 +1,40 @@
package com.cf.imes.framework.common.util.i18n.core.util;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
/**
* 国际化资源包工具类
*
* @author Gqr
* @since 2025/11/21 11:16
*/
@Slf4j
public class ResourceBundleUtils {
/**
* 获取国际化资源值
*
* @param baseName 资源包位置
* @param key i18n key
* @param defaultMessage 没有获取到资源描述返回的缺省值
* @param locale 语种
* @param args 占位符数组
* @return
*/
public static String getMessage(String baseName, String key, String defaultMessage, Locale locale, Object args) {
try {
ResourceBundle messageEnum = ResourceBundle.getBundle(baseName, locale);
if (messageEnum != null) {
String i18nMessage = messageEnum.getString(key);
return MessageFormat.format(i18nMessage, args);
}
} catch (Exception e) {
log.error("[ResourceBundleUtils][getMessage]异常", e);
}
return defaultMessage;
}
}
@@ -1,14 +1,13 @@
package com.cf.imes.framework.common.validation;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.core.IntArrayValuable;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Collection;
@@ -17,14 +16,10 @@ import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
@Component
public class InEnumCollectionValidator implements ConstraintValidator<InEnum, Collection<Integer>> {
private List<Integer> values;
@Autowired
private MessageSource messageSource;
@Override
public void initialize(InEnum annotation) {
IntArrayValuable[] values = annotation.value().getEnumConstants();
@@ -41,14 +36,15 @@ public class InEnumCollectionValidator implements ConstraintValidator<InEnum, Co
if (CollUtil.containsAll(values, list)) {
return true;
}
String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();
Locale locale = LocaleContextHolder.getLocale();
String message = messageSource.getMessage(defaultConstraintMessageTemplate, new Object[]{CollUtil.join(list, ",")}, locale);
defaultConstraintMessageTemplate = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, defaultConstraintMessageTemplate, defaultConstraintMessageTemplate, locale, CollUtil.join(list, ","));;
// 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate(message).addConstraintViolation(); // 重新添加错误提示语句
context.buildConstraintViolationWithTemplate(defaultConstraintMessageTemplate).addConstraintViolation(); // 重新添加错误提示语句
return false;
}
}
@@ -1,13 +1,12 @@
package com.cf.imes.framework.common.validation;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.core.IntArrayValuable;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Collections;
@@ -15,14 +14,10 @@ import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
@Component
public class InEnumValidator implements ConstraintValidator<InEnum, Integer> {
private List<Integer> values;
@Autowired
private MessageSource messageSource;
@Override
public void initialize(InEnum annotation) {
IntArrayValuable[] values = annotation.value().getEnumConstants();
@@ -45,12 +40,12 @@ public class InEnumValidator implements ConstraintValidator<InEnum, Integer> {
}
String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();
Locale locale = LocaleContextHolder.getLocale();
String message = messageSource.getMessage(defaultConstraintMessageTemplate, new Object[]{values.toString()}, locale);
defaultConstraintMessageTemplate = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, defaultConstraintMessageTemplate, defaultConstraintMessageTemplate, locale, values.toString());
// 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate(message).addConstraintViolation(); // 重新添加错误提示语句
context.buildConstraintViolationWithTemplate(defaultConstraintMessageTemplate).addConstraintViolation(); // 重新添加错误提示语句
return false;
}
}
@@ -28,7 +28,7 @@ public @interface InScope {
*/
Class<? extends IntArrayValuable> value();
String message() default "{desc}不合法";
String message() default "inScope.message";
String desc() default "";
@@ -1,13 +1,17 @@
package com.cf.imes.framework.common.validation;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.core.IntArrayValuable;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
/**
@@ -40,12 +44,14 @@ public class InScopeValidator implements ConstraintValidator<InScope, List<Integ
if (values.containsAll(integers)) {
return true;
}
String defaultConstraintMessageTemplate = constraintValidatorContext.getDefaultConstraintMessageTemplate();
Locale locale = LocaleContextHolder.getLocale();
String descValue = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, desc, desc, locale, null);
defaultConstraintMessageTemplate = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, defaultConstraintMessageTemplate, defaultConstraintMessageTemplate, locale, descValue);;
// 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
constraintValidatorContext.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
constraintValidatorContext.buildConstraintViolationWithTemplate(constraintValidatorContext.getDefaultConstraintMessageTemplate()
.replace("{desc}", desc)).addConstraintViolation(); // 重新添加错误提示语句
constraintValidatorContext.buildConstraintViolationWithTemplate(defaultConstraintMessageTemplate).addConstraintViolation(); // 重新添加错误提示语句
return false;
}
}
@@ -83,10 +83,11 @@ public class ChenfengOrganAutoConfiguration {
public FilterRegistrationBean<OrganSecurityWebFilter> organSecurityWebFilter(OrganProperties tenantProperties,
WebProperties webProperties,
GlobalExceptionHandler globalExceptionHandler,
OrganFrameworkService organFrameworkService) {
OrganFrameworkService organFrameworkService,
I18nUtils i18nUtils) {
FilterRegistrationBean<OrganSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new OrganSecurityWebFilter(tenantProperties, webProperties,
globalExceptionHandler, organFrameworkService));
globalExceptionHandler, organFrameworkService, i18nUtils));
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
return registrationBean;
}
@@ -53,18 +53,19 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
private final GlobalExceptionHandler globalExceptionHandler;
private final OrganFrameworkService organFrameworkService;
@Resource
private I18nUtils i18nUtils;
private final I18nUtils i18nUtils;
public OrganSecurityWebFilter(OrganProperties organProperties,
WebProperties webProperties,
GlobalExceptionHandler globalExceptionHandler,
OrganFrameworkService organFrameworkService) {
OrganFrameworkService organFrameworkService,
I18nUtils i18nUtils) {
super(webProperties);
this.organProperties = organProperties;
this.pathMatcher = new AntPathMatcher();
this.globalExceptionHandler = globalExceptionHandler;
this.organFrameworkService = organFrameworkService;
this.i18nUtils = i18nUtils;
}
@Override
@@ -5,8 +5,11 @@ import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import com.cf.imes.framework.excel.core.annotations.EnumFormat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.i18n.LocaleContextHolder;
import java.lang.reflect.Field;
@@ -40,7 +43,7 @@ public class EnumBoolValConvert implements Converter<Boolean> {
for (Object e : enumClass.getEnumConstants()) {
BaseBoolValEnum baseEnum = (BaseBoolValEnum) e;
if (baseEnum.getCode().equals(code)) {
return new WriteCellData<>(baseEnum.getDesc());
return new WriteCellData<>(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, baseEnum.getDesc(), baseEnum.getDesc(), LocaleContextHolder.getLocale(), null));
}
}
}
@@ -5,8 +5,11 @@ import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import com.cf.imes.framework.excel.core.annotations.EnumFormat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.i18n.LocaleContextHolder;
import java.lang.reflect.Field;
@@ -40,7 +43,7 @@ public class EnumConvert implements Converter<Integer> {
for (Object e : enumClass.getEnumConstants()) {
BaseEnum baseEnum = (BaseEnum) e;
if (baseEnum.getCode().equals(code)) {
return new WriteCellData<>(baseEnum.getDesc());
return new WriteCellData<>(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, baseEnum.getDesc(), baseEnum.getDesc(), LocaleContextHolder.getLocale(), null));
}
}
}
@@ -35,6 +35,7 @@ public class ExcelUtils {
EasyExcelFactory.write(response.getOutputStream(), head)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
.registerWriteHandler(new I18nHeadWriteHandler())
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
@@ -0,0 +1,29 @@
package com.cf.imes.framework.excel.core.util;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.List;
/**
* 表头国际化处理器
*
* @author Gqr
* @since 2025/11/21 11:05
*/
public class I18nHeadWriteHandler implements CellWriteHandler {
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (Boolean.TRUE.equals(isHead)) {
String key = head.getHeadNameList().get(0);
cell.setCellValue(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, key, key, LocaleContextHolder.getLocale(), null));
}
}
}
@@ -0,0 +1,24 @@
package com.cf.imes.framework.web.config;
import com.cf.imes.framework.web.core.rpc.LanguageRequestInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
/**
* WEB RPC 组件的自动配置
*
* @author Gqr
* @since 2025/11/20 13:55
*/
@AutoConfiguration
public class ChenfengWebRpcAutoConfiguration {
/**
* 国际化组件
*
* @return
*/
@Bean
public LanguageRequestInterceptor languageRequestInterceptor() {
return new LanguageRequestInterceptor();
}
}
@@ -0,0 +1,29 @@
package com.cf.imes.framework.web.core.rpc;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpHeaders;
import java.util.Locale;
/**
* 国际化 的 RequestInterceptor 实现类:Feign 请求时,将 {@link LocaleContextHolder} 设置到 header 中,继续透传给被调用的服务
*
* @author 晨丰科技
*/
@Slf4j
public class LanguageRequestInterceptor implements RequestInterceptor {
@Override
@SneakyThrows
public void apply(RequestTemplate requestTemplate) {
Locale locale = LocaleContextHolder.getLocale();
if (locale != null) {
requestTemplate.header(HttpHeaders.ACCEPT_LANGUAGE, locale.toString());
}
}
}
@@ -2,6 +2,7 @@ com.cf.imes.framework.apilog.config.ChenfengApiLogAutoConfiguration
com.cf.imes.framework.jackson.config.ChenfengJacksonAutoConfiguration
com.cf.imes.framework.swagger.config.ChenfengSwaggerAutoConfiguration
com.cf.imes.framework.web.config.ChenfengWebAutoConfiguration
com.cf.imes.framework.web.config.ChenfengWebRpcAutoConfiguration
com.cf.imes.framework.apilog.config.ChenfengApiLogRpcAutoConfiguration
com.cf.imes.framework.async.ChenfengAsyncAutoConfiguration
com.cf.imes.framework.banner.config.ChenfengBannerAutoConfiguration