diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/exception/enums/GlobalErrorCodeConstants.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/exception/enums/GlobalErrorCodeConstants.java index 1d5fe67c9..1510b4488 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/exception/enums/GlobalErrorCodeConstants.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/exception/enums/GlobalErrorCodeConstants.java @@ -18,19 +18,23 @@ public class GlobalErrorCodeConstants { // ========== 客户端错误段 ========== - public static final ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确"); + public static final ErrorCode BAD_REQUEST = new ErrorCode(400, "global.error.bad.request"); + public static final ErrorCode REQUEST_ORGAN_ID_NOT_EXIST = new ErrorCode(400, "global.error.request.organId.notExist"); + public static final ErrorCode NO_PERMISSION_TO_VISIT_ORG = new ErrorCode(400, "global.error.no.permission.to.visit.org"); + public static final ErrorCode REQUEST_PARAM_TYPE_ERROR = new ErrorCode(400, "global.error.request.param.type.error"); public static final ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录"); - public static final ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限"); - public static final ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到"); - public static final ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确"); - public static final ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许 - public static final ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试"); - public static final ErrorCode ORG_PRODUCT_EXPIRED = new ErrorCode(410, "组织产品套餐已过期,请续费后继续使用"); - public static final ErrorCode USER_PRODUCTID_NOT_EXIST = new ErrorCode(411, "账号登录异常,套餐信息不存在,请重新登陆"); + public static final ErrorCode FORBIDDEN = new ErrorCode(403, "global.error.no.permission"); + public static final ErrorCode REQUEST_PARAM_MISSING = new ErrorCode(403, "global.error.request.param.missing"); + public static final ErrorCode NOT_FOUND = new ErrorCode(404, "global.error.request.not.found"); + public static final ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "global.error.request.method.error"); + public static final ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "global.error.request.too.many"); + public static final ErrorCode ORG_PRODUCT_EXPIRED = new ErrorCode(410, "global.org.product.expired"); + public static final ErrorCode USER_PRODUCTID_NOT_EXIST = new ErrorCode(410, "global.org.product.not.exist"); // ========== 服务端错误段 ========== - public static final ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统繁忙,请稍后再试"); + public static final ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "global.error.default.error"); + public static final ErrorCode DUPLICATE_DATA_ERROR = new ErrorCode(500, "global.error.request.duplicate.data.error"); public static final ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启"); // ES文档更新失败 @@ -41,6 +45,5 @@ public class GlobalErrorCodeConstants { public static final ErrorCode DATA_DATA_ERROR = new ErrorCode(506, "文档数据异常,请勿频繁操作,请稍后重试"); // ========== 自定义错误段 ========== - public static final ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 public static final ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作"); } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonResult.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonResult.java index ea847ec33..b9a6f9aa4 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonResult.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonResult.java @@ -48,6 +48,12 @@ public class CommonResult implements Serializable { @JsonInclude(JsonInclude.Include.NON_NULL) private String traceId; + /** + * 占位补充参数 + */ + @JsonIgnore + private Object[] args; + /** * 将传入的 result 对象,转换成另外一个泛型结果的对象 * @@ -74,10 +80,28 @@ public class CommonResult implements Serializable { return result; } + public static CommonResult error(Integer code, String message, Object... args) { + Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!"); + CommonResult result = new CommonResult<>(); + result.code = code; + result.msg = message; + result.args = args; + + String traceId = MDC.get(TRACE_ID); + if (StringUtils.hasText(traceId)) { + result.traceId = traceId; + } + return result; + } + public static CommonResult error(ErrorCode errorCode) { return error(errorCode.getCode(), errorCode.getMsg()); } + public static CommonResult error(ErrorCode errorCode, Object... args) { + return error(errorCode.getCode(), errorCode.getMsg(), args); + } + public static CommonResult success(T data) { CommonResult result = new CommonResult<>(); result.code = GlobalErrorCodeConstants.SUCCESS.getCode(); diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java index cb07cc30b..50be3ec21 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java @@ -23,7 +23,7 @@ public class CommonStatisticsReqVO { * 统计维度单位 */ @Schema(description = "统计维度单位", example = "0", allowableValues = {"0", "1", "2", "3"}, type = "integer") - @NotNull(message = "统计维度单位不能为空") + @NotNull(message = "{statistics.unit.notNull}") @StatisticsUnitInEnum private Integer unit; } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/PageParam.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/PageParam.java index 9393c056b..cb8f69875 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/PageParam.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/PageParam.java @@ -23,14 +23,14 @@ public class PageParam implements Serializable { public static final Integer PAGE_SIZE_NONE = -1; @Schema(description = "页码,从 1 开始", requiredMode = Schema.RequiredMode.REQUIRED,example = "1") - @NotNull(message = "页码不能为空") - @Min(value = 1, message = "页码最小值为 1") + @NotNull(message = "{page.pageNo.notNull}") + @Min(value = 1, message = "{page.pageNo.min}") private Integer pageNo = PAGE_NO; @Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - @NotNull(message = "每页条数不能为空") - @Min(value = -1, message = "每页条数最小值为 -1") - @Max(value = 100, message = "每页条数最大值为 100") + @NotNull(message = "{page.pageSize.notNull}") + @Min(value = -1, message = "{page.pageSize.min}") + @Max(value = 100, message = "{page.pageSize.max}") private Integer pageSize = PAGE_SIZE; } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/core/util/I18nUtils.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/core/util/I18nUtils.java new file mode 100644 index 000000000..cebdf833a --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/core/util/I18nUtils.java @@ -0,0 +1,32 @@ +package com.cf.imes.framework.common.util.i18n.core.util; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +/** + * 国际化工具类 + * + * @author Gqr + * @since 2025/11/18 11:18 + */ +@Slf4j +@Component +@AllArgsConstructor +public class I18nUtils { + + private MessageSource messageSource; + + /** + * 获取国际化描述 + * + * @param code + * @param args + * @return + */ + public String getMessage(String code, Object... args) { + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/package-info.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/package-info.java new file mode 100644 index 000000000..e2c4eea08 --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/i18n/package-info.java @@ -0,0 +1,4 @@ +/** + * 针对 MessageSource 的基础封装 + */ +package com.cf.imes.framework.common.util.i18n; diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java index 48521e491..0d62edf89 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; validatedBy = {StatisticsUnitInEnumValidator.class} ) public @interface StatisticsUnitInEnum { - String message() default "统计维度单位[unit]错误,请检查"; + String message() default "{statistics.unit.invalid}"; Class[] groups() default {}; diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnum.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnum.java index 6449de7d8..129e8ef83 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnum.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnum.java @@ -26,7 +26,7 @@ public @interface InEnum { */ Class value(); - String message() default "必须在指定范围 {value}"; + String message() default "inEnum.message"; Class[] groups() default {}; diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnumCollectionValidator.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnumCollectionValidator.java index 2a56d4b70..280b90680 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnumCollectionValidator.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/InEnumCollectionValidator.java @@ -5,16 +5,26 @@ import com.cf.imes.framework.common.core.IntArrayValuable; 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; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; +@Component public class InEnumCollectionValidator implements ConstraintValidator> { private List values; + @Autowired + private MessageSource messageSource; + @Override public void initialize(InEnum annotation) { IntArrayValuable[] values = annotation.value().getEnumConstants(); @@ -31,10 +41,12 @@ public class InEnumCollectionValidator implements ConstraintValidator { private List values; + @Autowired + private MessageSource messageSource; + @Override public void initialize(InEnum annotation) { IntArrayValuable[] values = annotation.value().getEnumConstants(); @@ -33,10 +43,12 @@ public class InEnumValidator implements ConstraintValidator { if (values.contains(value)) { return true; } + String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate(); + Locale locale = LocaleContextHolder.getLocale(); + String message = messageSource.getMessage(defaultConstraintMessageTemplate, new Object[]{values.toString()}, locale); // 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值) context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值 - context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate() - .replace("\\{value}", values.toString())).addConstraintViolation(); // 重新添加错误提示语句 + context.buildConstraintViolationWithTemplate(message).addConstraintViolation(); // 重新添加错误提示语句 return false; } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValid.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValid.java index 1c7a9e7a7..492108a30 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValid.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValid.java @@ -40,7 +40,7 @@ public @interface NumberValid { * * @return */ - String message() default "数字不合法"; + String message() default ""; Class[] groups() default {}; diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java index 73ea026d3..cc82f4da3 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java @@ -5,19 +5,26 @@ import org.apache.commons.lang3.StringUtils; 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.math.BigDecimal; import java.text.DecimalFormat; +import java.util.Locale; /** * @author Gqr * @since 2024/10/17 11:27 */ +@Component public class NumberValidator implements ConstraintValidator { private static final String ZERO = "0"; - private static final String GREATER_THAN_ZERO_NOTIFICATION = "%s必须大于0"; + private static final String GREATER_THAN_ZERO_NOTIFICATION = "number.greaterThanZero"; - private static final String FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION = "%s长度不合法,总长度不超过%d位,小数点后不超过%d位"; + private static final String FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION = "number.float.length.error"; private String name; @@ -25,13 +32,15 @@ public class NumberValidator implements ConstraintValidator private int fraction; + @Autowired + private MessageSource messageSource; + @Override public void initialize(NumberValid constraintAnnotation) { ConstraintValidator.super.initialize(constraintAnnotation); this.name = constraintAnnotation.name(); this.integer = constraintAnnotation.integer(); this.fraction = constraintAnnotation.fraction(); - ; } @Override @@ -67,7 +76,10 @@ public class NumberValidator implements ConstraintValidator */ private String handleInteger(Integer value) { if (value < Integer.parseInt(ZERO)) { - return String.format(GREATER_THAN_ZERO_NOTIFICATION, name); + Locale locale = LocaleContextHolder.getLocale(); + return messageSource.getMessage(GREATER_THAN_ZERO_NOTIFICATION, new Object[]{ + messageSource.getMessage(name, null, locale) + }, locale); } return null; } @@ -80,7 +92,10 @@ public class NumberValidator implements ConstraintValidator */ private String handleLong(Long value) { if (value < Long.parseLong(ZERO)) { - return String.format(GREATER_THAN_ZERO_NOTIFICATION, name); + Locale locale = LocaleContextHolder.getLocale(); + return messageSource.getMessage(GREATER_THAN_ZERO_NOTIFICATION, new Object[]{ + messageSource.getMessage(name, null, locale) + }, locale); } return null; } @@ -92,8 +107,10 @@ public class NumberValidator implements ConstraintValidator * @return */ private String handleDouble(Double value) { + Locale locale = LocaleContextHolder.getLocale(); + String fieldName = messageSource.getMessage(name, null, locale); if (value < Double.parseDouble(ZERO)) { - return String.format(GREATER_THAN_ZERO_NOTIFICATION, name); + return messageSource.getMessage(GREATER_THAN_ZERO_NOTIFICATION, new Object[]{fieldName}, locale); } // 处理科学计数法,保留小数点后四位 DecimalFormat decimalFormat = new DecimalFormat("#.####"); @@ -110,7 +127,9 @@ public class NumberValidator implements ConstraintValidator // 总位数不超过 8 位,小数点后位数不超过 3 位 if (integerPartLength > integer || fractionalPartLength > fraction) { - return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name, integer, fraction); + return messageSource.getMessage(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, new Object[]{ + fieldName, integer, fraction + }, locale); } return null; } @@ -122,8 +141,10 @@ public class NumberValidator implements ConstraintValidator * @return */ private String handleBigDecimal(BigDecimal value) { + Locale locale = LocaleContextHolder.getLocale(); + String fieldName = messageSource.getMessage(name, null, locale); if (value.compareTo(BigDecimal.ZERO) < 0) { - return String.format(GREATER_THAN_ZERO_NOTIFICATION, name); + return messageSource.getMessage(GREATER_THAN_ZERO_NOTIFICATION, new Object[]{fieldName}, locale); } String[] split = value.toPlainString().split("\\."); @@ -137,7 +158,9 @@ public class NumberValidator implements ConstraintValidator // 总位数不超过 8 位,小数点后位数不超过 3 位 if (integerPartLength > integer || fractionalPartLength > fraction) { - return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name, integer, fraction); + return messageSource.getMessage(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, new Object[]{ + fieldName, integer, fraction + }, locale); } return null; } diff --git a/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/config/ChenfengOrganAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/config/ChenfengOrganAutoConfiguration.java index 51329d918..b4f179726 100644 --- a/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/config/ChenfengOrganAutoConfiguration.java +++ b/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/config/ChenfengOrganAutoConfiguration.java @@ -1,6 +1,7 @@ package com.cf.imes.framework.organ.config; import com.cf.imes.framework.common.enums.WebFilterOrderEnum; +import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils; import com.cf.imes.framework.mybatis.core.util.MyBatisUtils; import com.cf.imes.framework.redis.config.ChenfengCacheProperties; import com.cf.imes.framework.organ.core.aop.OrganIgnoreAspect; @@ -80,12 +81,13 @@ public class ChenfengOrganAutoConfiguration { @Bean public FilterRegistrationBean organSecurityWebFilter(OrganProperties tenantProperties, - WebProperties webProperties, - GlobalExceptionHandler globalExceptionHandler, - OrganFrameworkService organFrameworkService) { + WebProperties webProperties, + GlobalExceptionHandler globalExceptionHandler, + OrganFrameworkService organFrameworkService, + I18nUtils i18nUtils) { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new OrganSecurityWebFilter(tenantProperties, webProperties, - globalExceptionHandler, organFrameworkService)); + globalExceptionHandler, organFrameworkService, i18nUtils)); registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); return registrationBean; } diff --git a/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/core/security/OrganSecurityWebFilter.java b/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/core/security/OrganSecurityWebFilter.java index b6356b9ab..c9d058160 100644 --- a/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/core/security/OrganSecurityWebFilter.java +++ b/cf-framework/cf-spring-boot-starter-biz-organ/src/main/java/com/cf/imes/framework/organ/core/security/OrganSecurityWebFilter.java @@ -7,6 +7,7 @@ import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants; import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.common.util.servlet.ServletUtils; +import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils; import com.cf.imes.framework.security.core.LoginUser; import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.framework.organ.config.OrganProperties; @@ -28,6 +29,9 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Objects; +import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.NO_PERMISSION_TO_VISIT_ORG; +import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.REQUEST_ORGAN_ID_NOT_EXIST; + /** * 多组织 Security Web 过滤器 * 1. 如果是登陆的用户,校验是否有权限访问该组织,避免越权问题。 @@ -48,15 +52,19 @@ public class OrganSecurityWebFilter extends ApiRequestFilter { private final GlobalExceptionHandler globalExceptionHandler; private final OrganFrameworkService organFrameworkService; + 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 @@ -77,8 +85,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter { log.error("[doFilterInternal][组织({}) User({}/{}) 越权访问组织({}) URL({}/{})]", user.getOrganId(), user.getId(), user.getUserType(), OrganContextHolder.getOrganId(), request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), - "您无权访问该组织的数据")); + ServletUtils.writeJSON(response, CommonResult.error(NO_PERMISSION_TO_VISIT_ORG.getCode(), i18nUtils.getMessage(NO_PERMISSION_TO_VISIT_ORG.getMsg()))); return; } } @@ -88,8 +95,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter { // 2. 如果请求未带组织的编号,不允许访问。 if (organId == null) { log.error("[doFilterInternal][URL({}/{}) 未传递组织编号]", request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), - "请求的组织标识未传递,请进行排查")); + ServletUtils.writeJSON(response, CommonResult.error(REQUEST_ORGAN_ID_NOT_EXIST.getCode(), i18nUtils.getMessage(REQUEST_ORGAN_ID_NOT_EXIST.getMsg()))); return; } // 3. 校验组织是合法,例如说被禁用、到期 @@ -108,6 +114,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter { CommonResult result = globalExceptionHandler.allExceptionHandler(request, ex); // 组织失效返回401踢出系统 needUnauthorizedWhenOrgExpired(ex, result); + result.setMsg(i18nUtils.getMessage(result.getMsg(), null)); ServletUtils.writeJSON(response, result); return; } @@ -133,7 +140,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter { // 非管理端校验产品的有效性 if (!isManageEndPoint) { if (ObjectUtil.isNull(productId)) { - throw new ServiceException(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), GlobalErrorCodeConstants.USER_PRODUCTID_NOT_EXIST.getMsg()); + throw new ServiceException(GlobalErrorCodeConstants.USER_PRODUCTID_NOT_EXIST); } if (!isProductIgnoreUrl(request)) { organFrameworkService.validOrgProduct(user.getOrganId(), productId); diff --git a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/config/ChenfengWebAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/config/ChenfengWebAutoConfiguration.java index 192f413e9..82bc4d74d 100644 --- a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/config/ChenfengWebAutoConfiguration.java +++ b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/config/ChenfengWebAutoConfiguration.java @@ -2,6 +2,7 @@ package com.cf.imes.framework.web.config; import com.cf.imes.framework.aop.ControllerResolver; import com.cf.imes.framework.common.enums.WebFilterOrderEnum; +import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils; import com.cf.imes.framework.web.core.filter.CacheRequestBodyFilter; import com.cf.imes.framework.web.core.filter.DataSourceFilter; import com.cf.imes.framework.web.core.handler.GlobalExceptionHandler; @@ -15,6 +16,7 @@ import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigu import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RestController; @@ -59,7 +61,12 @@ public class ChenfengWebAutoConfiguration implements WebMvcConfigurer { } @Bean - public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogApi apiErrorLogApi) { + public I18nUtils i18nUtils(MessageSource messageSource) { + return new I18nUtils(messageSource); + } + + @Bean + public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogApi apiErrorLogApi, I18nUtils i18nUtils) { return new GlobalExceptionHandler(applicationName, apiErrorLogApi); } diff --git a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalExceptionHandler.java b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalExceptionHandler.java index 187302ecc..588dc1a7a 100644 --- a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalExceptionHandler.java +++ b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalExceptionHandler.java @@ -11,7 +11,6 @@ import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.framework.common.util.servlet.ServletUtils; import com.cf.imes.module.infra.api.logger.ApiErrorLogApi; import com.cf.imes.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -33,12 +32,9 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import jakarta.validation.ValidationException; -import java.io.IOException; import java.time.LocalDateTime; import java.util.Map; import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.*; @@ -109,7 +105,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(value = MissingServletRequestParameterException.class) public CommonResult missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException ex) { log.warn(String.format("==========[missingServletRequestParameterExceptionHandler]==========,%s", ex.getMessage())); - return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数缺失:%s", ex.getParameterName())); + return CommonResult.error(REQUEST_PARAM_MISSING, ex.getParameterName()); } /** @@ -120,7 +116,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentTypeMismatchException.class) public CommonResult methodArgumentTypeMismatchExceptionHandler(MethodArgumentTypeMismatchException ex) { log.warn(String.format("==========[missingServletRequestParameterExceptionHandler]==========,%s", ex.getMessage())); - return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误,%s:%s", ex.getName(), ex.getValue())); + return CommonResult.error(REQUEST_PARAM_TYPE_ERROR, ex.getName() + ":" + ex.getValue()); } /** @@ -147,7 +143,7 @@ public class GlobalExceptionHandler { if (CharSequenceUtil.isNotEmpty(defaultMessage) && fieldError.contains(ConstraintViolation.class)) { return CommonResult.error(BAD_REQUEST.getCode(), defaultMessage); } else { - return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确,%s:%s", fieldError.getField(), fieldError.getRejectedValue())); + return CommonResult.error(BAD_REQUEST, fieldError.getField() + ":" + fieldError.getRejectedValue()); } } @@ -162,7 +158,7 @@ public class GlobalExceptionHandler { if (StringUtils.isNotEmpty(message)) { return CommonResult.error(BAD_REQUEST.getCode(), message); } else { - return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", message)); + return CommonResult.error(BAD_REQUEST, message); } } @@ -186,7 +182,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(NoHandlerFoundException.class) public CommonResult noHandlerFoundExceptionHandler(NoHandlerFoundException ex) { log.warn(String.format("==========[noHandlerFoundExceptionHandler]==========,%s", ex.getMessage())); - return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL())); + return CommonResult.error(NOT_FOUND, ex.getRequestURL()); } /** @@ -197,7 +193,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public CommonResult httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException ex) { log.warn(String.format("==========[httpRequestMethodNotSupportedExceptionHandler]==========,%s", ex.getMessage())); - return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage())); + return CommonResult.error(METHOD_NOT_ALLOWED, ex.getMessage()); } /** @@ -223,25 +219,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(value = HttpMessageNotReadableException.class) public CommonResult httpMessageNotReadableExceptionHandler(HttpServletRequest req, HttpMessageNotReadableException ex) { log.warn(String.format("==========[httpMessageNotReadableExceptionHandler]==========,%s", ex.getMessage())); - - Throwable rootCause = ex.getRootCause(); - // 无效格式异常处理。 - if (rootCause instanceof InvalidFormatException) { // MismatchedInputException - InvalidFormatException e = (InvalidFormatException) rootCause; - return CommonResult.error(BAD_REQUEST.getCode(), String.format("参数校验失败:'%s' 格式出错", e.getValue())); - } - // 文件格式错误处理 - if (rootCause instanceof IOException) { - // 使用正则提取数值 - Pattern pattern = Pattern.compile("Numeric value \\(([-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?)\\) out of range"); - Matcher matcher = pattern.matcher(rootCause.getMessage()); - if (matcher.find()) { - String invalidValue = matcher.group(1); - return CommonResult.error(BAD_REQUEST.getCode(), String.format("参数校验失败:'%s' 超出范围", invalidValue)); - } - } - - return CommonResult.error(BAD_REQUEST.getCode(), "请求参数不合法"); + return CommonResult.error(BAD_REQUEST); } /** @@ -269,7 +247,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(value = DuplicateKeyException.class) public CommonResult duplicateKeyExceptionHandler(DuplicateKeyException ex) { log.warn(String.format("==========[duplicateKeyExceptionHandler]==========,%s", ex.getMessage())); - return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), "请求数据已存在,请检查"); + return CommonResult.error(DUPLICATE_DATA_ERROR); } /** @@ -293,7 +271,7 @@ public class GlobalExceptionHandler { // 插入异常日志 this.createExceptionLog(req, ex); // 返回 ERROR CommonResult - return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); + return CommonResult.error(INTERNAL_SERVER_ERROR); } private void createExceptionLog(HttpServletRequest req, Throwable e) { diff --git a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalResponseBodyHandler.java b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalResponseBodyHandler.java index 9c0531083..50491aba7 100644 --- a/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalResponseBodyHandler.java +++ b/cf-framework/cf-spring-boot-starter-web/src/main/java/com/cf/imes/framework/web/core/handler/GlobalResponseBodyHandler.java @@ -3,6 +3,9 @@ package com.cf.imes.framework.web.core.handler; import com.cf.imes.framework.apilog.core.filter.ApiAccessLogFilter; import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.web.core.util.WebFrameworkUtils; +import jakarta.annotation.Resource; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; @@ -24,6 +27,9 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @ControllerAdvice public class GlobalResponseBodyHandler implements ResponseBodyAdvice { + @Resource + private MessageSource messageSource; + @Override @SuppressWarnings("NullableProblems") // 避免 IDEA 警告 public boolean supports(MethodParameter returnType, Class converterType) { @@ -38,6 +44,14 @@ public class GlobalResponseBodyHandler implements ResponseBodyAdvice { @SuppressWarnings("NullableProblems") // 避免 IDEA 警告 public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + if (body instanceof CommonResult) { + CommonResult res = (CommonResult) body; + if (!res.isSuccess()) { + String key = res.getMsg(); + String i18nMsg = messageSource.getMessage(key, res.getArgs(), key, LocaleContextHolder.getLocale()); + res.setMsg(i18nMsg); + } + } // 记录 Controller 结果 WebFrameworkUtils.setCommonResult(((ServletServerHttpRequest) request).getServletRequest(), (CommonResult) body); return body; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementRePublishReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementRePublishReqVO.java index fe02d819f..c00613d08 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementRePublishReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementRePublishReqVO.java @@ -19,12 +19,12 @@ public class AdvertisementRePublishReqVO { @Schema(description = "投放开始时间,重新发布时传") - @NotNull(message = "投放开始时间不能为空") + @NotNull(message = "{ad.startTime.notNull}") private LocalDate startTime; @Schema(description = "投放结束时间,重新发布时传") - @NotNull(message = "投放结束时间不能为空") + @NotNull(message = "{ad.endTime.notNull}") private LocalDate endTime; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementSaveReqVO.java index 6d55a7b0e..e217e0d81 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/advertisement/vo/AdvertisementSaveReqVO.java @@ -25,41 +25,41 @@ public class AdvertisementSaveReqVO { @Schema(description = "广告名称") - @NotBlank(message = "广告名称不能为空") - @Size(max = 32, message = "广告名称长度不能超过 32 个字符") + @NotBlank(message = "{ad.name.notBlank}") + @Size(max = 32, message = "{ad.name.size}") private String adName; @Schema(description = "广告位置,字典键值", example = "[1,2]") - @NotEmpty(message = "广告位置不能为空") + @NotEmpty(message = "{ad.position.notEmpty}") @InScope(value = AdvertisementPositionEnum.class, desc = "广告位置") private List adPosition; @Schema(description = "广告图片文件路径") - @NotBlank(message = "广告图片文件路径不能为空") - @Size(max = 255, message = "广告图片文件路径长度不能超过 255 个字符") + @NotBlank(message = "{ad.adImagePath.notBlank}") + @Size(max = 255, message = "{ad.adImagePath.size}") private String adImagePath; @Schema(description = "投放开始时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) - @NotNull(message = "投放开始时间不能为空") + @NotNull(message = "{ad.startTime.notNull}") private LocalDate startTime; @Schema(description = "投放结束时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) - @NotNull(message = "投放结束时间不能为空") + @NotNull(message = "{ad.endTime.notNull}") private LocalDate endTime; @Schema(description = "跳转路径") - @Size(max = 255, message = "链接长度不能超过 255 个字符") + @Size(max = 255, message = "{ad.adRedirectUrl.size}") private String adRedirectUrl; @Schema(description = "广告顺序") - @NumberValid(name = "广告顺序") + @NumberValid(name = "ad.sort.field") private Integer sort; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelayPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelayPageReqVO.java index 1520898d0..27424375a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelayPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelayPageReqVO.java @@ -22,7 +22,7 @@ public class ProductDelayPageReqVO extends PageParam { private String organName; @Schema(description = "产品名称") - @Size(max = 64, message = "产品名称长度不能超过64个字符") + @Size(max = 64, message = "{product.delay.page.productName.size}") private String productName; @Schema(description = "延期时长") @@ -32,6 +32,6 @@ public class ProductDelayPageReqVO extends PageParam { private LocalDate[] createTime; @Schema(description = "操作人") - @Size(max = 64, message = "操作人长度不能超过64个字符") + @Size(max = 64, message = "{product.delay.page.operator.size}") private String operator; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelaySaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelaySaveReqVO.java index 8740062a6..3133d18df 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelaySaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/delay/vo/ProductDelaySaveReqVO.java @@ -14,23 +14,23 @@ import lombok.Data; @Data public class ProductDelaySaveReqVO { @Schema(description = "组织编号") - @NotNull(message = "组织编号不能为空") + @NotNull(message = "{product.delay.save.organId.notNull}") private Long organId; @Schema(description = "购买记录编号") - @NotNull(message = "购买记录编号不能为空") + @NotNull(message = "{product.delay.save.purchaseId.notNull}") private Long purchaseId; @Schema(description = "延期时长", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "延期时长不能为空") + @NotNull(message = "{product.delay.save.duration.notNull}") private Integer delayDuration; @Schema(description = "延期时长单位,0:年、1:月、2:日", example = "1") - @NotNull(message = "延期时长单位不能为空") + @NotNull(message = "{product.delay.save.duration.unit.notNull}") @DurationUnitValid private Integer delayDurationUnit; @Schema(description = "备注") - @Size(max = 1024, message = "备注不能超过1024个字符") + @Size(max = 1024, message = "{product.delay.save.remark.size}") private String remark; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java index b01b08d52..3a7046dbe 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java @@ -29,14 +29,14 @@ public class InvoiceAmountAndAvailablePageReqVO extends PageParam { private LocalDateTime[] createTime; @Schema(description = "开票金额起") - @DecimalMin(value = "0", message = "开票金额必须大于等于零") - @DecimalMax(value = "100000", message = "开票金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "开票金额格式不正确") + @DecimalMin(value = "0", message = "{invoce.page.amount.min}") + @DecimalMax(value = "100000", message = "{invoice.page.amount.max}") + @Digits(integer = 6, fraction = 2, message = "{invoice.page.amount.format}") private BigDecimal invoiceAmountStart; @Schema(description = "开票金额止") - @DecimalMin(value = "0", message = "开票金额必须大于等于零") - @DecimalMax(value = "100000", message = "开票金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "开票金额格式不正确") + @DecimalMin(value = "0", message = "{invoce.page.amount.min}") + @DecimalMax(value = "100000", message = "{invoice.page.amount.max}") + @Digits(integer = 6, fraction = 2, message = "{invoice.page.amount.format}") private BigDecimal invoiceAmountEnd; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceConfirmReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceConfirmReqVO.java index a140b9b94..eb30b5ece 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceConfirmReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceConfirmReqVO.java @@ -12,7 +12,7 @@ public class InvoiceConfirmReqVO { @Schema(description = "发票申请记录编号",example = "1") - @NotNull(message = "发票申请记录编号不能为空") + @NotNull(message = "{invoice.confirm.id.notNull}") private Long id; @@ -21,11 +21,11 @@ public class InvoiceConfirmReqVO { @Schema(description = "发票号") - @Length(max = 32, message = "发票号长度不能超过 32 个字符") + @Length(max = 32, message = "{invoice.confirm.invoiceNo.length}") private String invoiceNo; @Schema(description = "备注") - @Length(max = 1024, message = "备注1长度不能超过 1024 个字符") + @Length(max = 1024, message = "{invoice.confirm.remark.length}") private String remark; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java index c49cc94c7..1f3df55a9 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java @@ -2,6 +2,7 @@ package com.cf.imes.module.system.controller.admin.funds.invoice.vo; import com.cf.imes.framework.common.pojo.PageParam; +import com.cf.imes.module.system.validation.invoice.InvoiceStatusValid; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; @@ -32,6 +33,7 @@ public class InvoiceDetailsPageReqVO extends PageParam { @Schema(description = "发票状态,1待开票 2已开票 3开票失败") + @InvoiceStatusValid private Integer status; @@ -44,15 +46,15 @@ public class InvoiceDetailsPageReqVO extends PageParam { @Schema(description = "发票金额起") - @DecimalMin(value = "0", message = "开票金额必须大于等于零") - @DecimalMax(value = "100000", message = "开票金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "开票金额格式不正确") + @DecimalMin(value = "0", message = "{invoice.page.amount.min}") + @DecimalMax(value = "100000", message = "{invoice.page.amount.max}") + @Digits(integer = 6, fraction = 2, message = "{invoice.page.amount.format}") private BigDecimal invoiceAmountStart; @Schema(description = "发票金额起") - @DecimalMin(value = "0", message = "开票金额必须大于等于零") - @DecimalMax(value = "100000", message = "开票金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "开票金额格式不正确") + @DecimalMin(value = "0", message = "{invoice.page.amount.min}") + @DecimalMax(value = "100000", message = "{invoice.page.amount.max}") + @Digits(integer = 6, fraction = 2, message = "{invoice.page.amount.format}") private BigDecimal invoiceAmountEnd; @Schema(description = "开票时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceRecordsReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceRecordsReqVO.java index 69e648a79..e6e6935c9 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceRecordsReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceRecordsReqVO.java @@ -13,8 +13,8 @@ import java.util.List; public class InvoiceRecordsReqVO { @Schema(description = "购买记录ID") - @Size(max = 100, message = "单次开票选择记录不能超过100条") - @NotEmpty + @Size(max = 100, message = "{invoice.apply.purchase.size}") + @NotEmpty(message = "{invoice.apply.purchase.list.notEmpty}") private List purchaseRecordId; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleSaveReqVO.java index 476cbd39c..b3bb2f973 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleSaveReqVO.java @@ -21,13 +21,13 @@ public class InvoiceTitleSaveReqVO { @Schema(description = "发票抬头") - @NotBlank(message = "发票抬头不能为空") - @Size(max = 64, message = "发票抬头长度不能超过64个字符") + @NotBlank(message = "{invoice.title.save.title.notBlank}") + @Size(max = 64, message = "{invoice.title.save.title.size}") private String invoiceTitle; @Schema(description = "开具类型,0企业 1个人") - @NotNull(message = "开具类型不能为空") + @NotNull(message = "{invoice.title.save.issueType.notNull}") @InvoiceIssueTypeValid private Integer issueType; @@ -39,34 +39,34 @@ public class InvoiceTitleSaveReqVO { @Schema(description = "统一社会信用代码") - @Size(max = 20, message = "统一社会信用代码长度不能超过18个字符") + @Size(max = 20, message = "{invoice.title.save.taxNumber.size}") private String taxNumber; @Schema(description = "开户银行名称") - @Size(max = 64, message = "开户银行名称长度不能超过64个字符") + @Size(max = 64, message = "{invoice.title.save.bankName.size}") private String bankName; @Schema(description = "开户银行账号") - @Size(max = 40, message = "开户银行账号长度不能超过40个字符") + @Size(max = 40, message = "{invoice.title.save.bankAccount.size}") private String bankAccount; @Schema(description = "注册场所地址") - @Size(max = 64, message = "注册场所地址长度不能超过64个字符") + @Size(max = 64, message = "{invoice.title.save.registeredAddress.size}") private String registeredAddress; @Schema(description = "注册固定电话") - @Size(max = 20, message = "注册固定电话长度不能超过20个字符") + @Size(max = 20, message = "{invoice.title.save.fixedPhone.size}") private String fixedPhone; @Schema(description = "邮箱") - @NotNull(message = "邮箱不能为空") - @Size(max = 64, message = "邮箱长度不能超过64个字符") - @Email(message = "邮箱格式不正确") + @NotNull(message = "{invoice.title.save.email.notNull}") + @Size(max = 64, message = "{invoice.title.save.email.size}") + @Email(message = "{invoice.title.save.email.format}") private String email; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/productpromotion/vo/ProductPromotionSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/productpromotion/vo/ProductPromotionSaveReqVO.java index b269a4daf..97a59e0f9 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/productpromotion/vo/ProductPromotionSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/productpromotion/vo/ProductPromotionSaveReqVO.java @@ -15,37 +15,37 @@ public class ProductPromotionSaveReqVO { private Long id; @Schema(description = "活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") - @NotNull(message = "活动名称不能为空") + @NotNull(message = "{product.promotion.save.activityName.notNull}") private String activityName; @Schema(description = "购买时长",example = "1") - @NotNull(message = "购买时长不能为空") + @NotNull(message = "{product.promotion.save.purchase.duration.notNull}") private Integer purchaseDuration; @Schema(description = "产品ID", example = "1") - @NotNull(message = "关联产品不能为空") + @NotNull(message = "{product.promotion.save.productId.notNull}") private Long productId; @Schema(description = "购买时长单位,0:年、1:月、2:日",example = "1") @DurationUnitValid - @NotNull(message = "购买时长单位不能为空") + @NotNull(message = "{product.promotion.save.purchase.duration.unit.notNull}") private Integer purchaseDurationUnit; @Schema(description = "赠送时长",example = "1") - @NotNull(message = "赠送时长不能为空") + @NotNull(message = "{product.promotion.save.gift.duration.notNull}") private Integer giftDuration; @Schema(description = "赠送时长单位",example = "1") @DurationUnitValid - @NotNull(message = "赠送时长单位不能为空") + @NotNull(message = "{product.promotion.save.gift.duration.unit.notNull}") private Integer giftDurationUnit; @Schema(description = "开始时间") - @NotNull(message = "开始时间不能为空") + @NotNull(message = "{product.promotion.save.startTime.notNull}") private LocalDateTime startTime; @Schema(description = "结束时间") - @NotNull(message = "结束时间不能为空") + @NotNull(message = "{product.promotion.save.endTime.notNull}") private LocalDateTime endTime; @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java index 3bcd14300..e7a6c7820 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java @@ -29,8 +29,8 @@ public class ProductPageReqVO extends PageParam { private Integer status; @Schema(description = "单价") - @DecimalMin(value = "0.01", message = "单价必须大于零") - @DecimalMax(value = "100000", message = "单价不能超过十万") - @Digits(integer = 6, fraction = 2, message = "单价格式不正确") + @DecimalMin(value = "0.01", message = "{product.page.price.min}") + @DecimalMax(value = "100000", message = "{product.page.price.max}") + @Digits(integer = 6, fraction = 2, message = "{product.page.price.format}") private BigDecimal price; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java index 4c90b965c..edcc4560a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java @@ -21,15 +21,15 @@ public class ProductSaveReqVO { private Long id; @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") - @NotEmpty(message = "产品名称不能为空") - @Size(max = 64, message = "产品名称长度不能超过64") + @NotEmpty(message = "{product.save.productName.notEmpty}") + @Size(max = 64, message = "{product.save.productName.size}") private String productName; @Schema(description = "产品建议价格") - @NotNull(message = "产品建议价格不能为空") - @DecimalMin(value = "0.01", message = "产品建议价格必须大于零") - @DecimalMax(value = "100000", message = "产品建议价格不能超过十万") - @Digits(integer = 6, fraction = 2, message = "产品建议价格格式不正确") + @NotNull(message = "{product.save.price.notNull}") + @DecimalMin(value = "0.01", message = "{product.save.price.min}") + @DecimalMax(value = "100000", message = "{product.save.price.max}") + @Digits(integer = 6, fraction = 2, message = "{product.save.price.format}") private BigDecimal price; @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java index 5cee0af91..846c1beba 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java @@ -19,24 +19,24 @@ public class ProductDetailsSaveReqVO { private Long id; @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "产品名称不能为空") + @NotNull(message = "{product.detail.save.productId.notNull}") private Long productId; @Schema(description = "产品时长,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @Min(value = 1, message = "产品时长必须大于0") - @NotNull(message = "产品时长不能为空") + @Min(value = 1, message = "{product.detail.save.duration.min}") + @NotNull(message = "{product.detail.duration.notNull}") private Integer duration; @Schema(description = "产品时长单位,0:年", example = "1") @ProductDurationUnitValid - @NotNull(message = "产品时长单位不能为空") + @NotNull(message = "{product.detail.duration.unit.notNull}") private Integer durationUnit; @Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8") - @DecimalMax(value = "100", message = "折扣必须小于等于100") - @DecimalMin(value = "0", message = "折扣必须大于等于0") - @Digits(integer = 3, fraction = 0, message = "折扣必须是0 ~ 100间的整数") - @NotNull(message = "折扣不能为空") + @DecimalMax(value = "100", message = "{product.detail.save.discount.max}") + @DecimalMin(value = "0", message = "{product.detail.save.discount.min}") + @Digits(integer = 3, fraction = 0, message = "{product.detail.save.discount.format}") + @NotNull(message = "{product.detail.save.discount.notNull}") private BigDecimal discount; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/PurchaseRecordPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/PurchaseRecordPageReqVO.java index ee45fb35b..b92e09619 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/PurchaseRecordPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/PurchaseRecordPageReqVO.java @@ -50,7 +50,7 @@ public class PurchaseRecordPageReqVO extends PageParam { private String creator; @Schema(description = "订单号") - @Size(max = 20, message = "订单号长度不能超过20个字符") + @Size(max = 20, message = "{purchase.record.page.id.size}") private String id; @Schema(description = "有效时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") @@ -61,8 +61,8 @@ public class PurchaseRecordPageReqVO extends PageParam { private LocalDateTime[] endTimeSection; @Schema(description = "产品金额") - @DecimalMin(value = "0.01", message = "产品购买金额必须大于零") - @DecimalMax(value = "100000", message = "产品购买金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "产品购买金额格式不正确") + @DecimalMin(value = "0.01", message = "{purchase.record.page.productPrice.min}") + @DecimalMax(value = "100000", message = "{purchase.record.page.productPrice.max}") + @Digits(integer = 6, fraction = 2, message = "{purchase.record.page.productPrice.format}") private BigDecimal productPrice; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/SalesDetailsPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/SalesDetailsPageReqVO.java index 2ab1e9c3d..1bb305f56 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/SalesDetailsPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/vo/SalesDetailsPageReqVO.java @@ -32,13 +32,13 @@ public class SalesDetailsPageReqVO extends PageParam { private Long id; @Schema(description = "产品金额") - @DecimalMin(value = "0.01", message = "产品购买金额必须大于零") - @DecimalMax(value = "100000", message = "产品购买金额不能超过十万") - @Digits(integer = 6, fraction = 2, message = "产品购买金额格式不正确") + @DecimalMin(value = "0.01", message = "{sales.detail.page.productPrice.min}") + @DecimalMax(value = "100000", message = "{sales.detail.page.productPrice.max}") + @Digits(integer = 6, fraction = 2, message = "{sales.detail.page.productPrice.format}") private BigDecimal productPrice; @Schema(description = "操作人") - @Size(max = 64, message = "操作人长度不能超过64个字符") + @Size(max = 64, message = "{sales.detail.page.operator.size}") private String operator; @Schema(description = "交易时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductGroup.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductGroup.java deleted file mode 100644 index cd20a25e7..000000000 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductGroup.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.cf.imes.module.system.controller.admin.pay.vo; - -/** - * 产品购买请求校验组 - * - * @author Gqr - * @since 2025/9/24 16:28 - */ -public interface PayProductGroup { -} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java index 6017919b2..901d7fb0d 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java @@ -19,15 +19,15 @@ public class PayProductOrderUnifiedReqVO { * 产品定价规则编号 */ @Schema(description = "产品定价规则编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "产品定价规则编号不能为空") + @NotNull(message = "{pay.product.productDetailsId.notNull}") private Long productDetailsId; @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "产品ID不能为空") + @NotNull(message = "{pay.product.productId.notNull}") private Long productId; @Schema(description = "产品支付渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") - @NotNull(message = "产品支付渠道编码不能为空", groups = PayProductGroup.class) + @NotNull(message = "{pay.product.productChannelCode.notNull}") @PayChannelCodeValid private Integer productChannelCode; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/framework/trans/config/TransConfiguration.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/framework/trans/config/TransConfiguration.java index a8939bd62..ffd64eb97 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/framework/trans/config/TransConfiguration.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/framework/trans/config/TransConfiguration.java @@ -1,9 +1,20 @@ package com.cf.imes.module.system.framework.trans.config; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; + +import java.util.Locale; @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(TransProperties.class) public class TransConfiguration { + @Bean + public LocaleResolver localeResolver() { + AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver(); + resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE); + return resolver; + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/advertisement/AdvertisementStatus.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/advertisement/AdvertisementStatus.java index dd4d0d39e..4c92ee551 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/advertisement/AdvertisementStatus.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/advertisement/AdvertisementStatus.java @@ -19,7 +19,7 @@ import java.lang.annotation.*; validatedBy = {AdvertisementStatusValidator.class} ) public @interface AdvertisementStatus { - String message() default "广告状态不合法,0:全部、1:未发布、2:已发布、3:已结束"; + String message() default "{ad.status.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java index 13bf962a3..e699801bf 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java @@ -24,7 +24,7 @@ import java.lang.annotation.Target; validatedBy = {InvoiceIssueTypeValidtor.class} ) public @interface InvoiceIssueTypeValid { - String message() default "不支持的发票开具类型"; + String message() default "{invoice.title.issueType.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValid.java new file mode 100644 index 000000000..d81365e71 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValid.java @@ -0,0 +1,32 @@ +package com.cf.imes.module.system.validation.invoice; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 发票状态校验注解 + * + * @author Gqr + * @since 2025/11/17 16:37 + */ +@Target({ + ElementType.FIELD, +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {InvoiceStatusValidtor.class} +) +public @interface InvoiceStatusValid { + String message() default "{invoice.status.invalid}"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValidtor.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValidtor.java new file mode 100644 index 000000000..29a66226c --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceStatusValidtor.java @@ -0,0 +1,27 @@ +package com.cf.imes.module.system.validation.invoice; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.module.system.enums.pay.InvoiceStatusEnum; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +/** + * 发票状态校验器 + * + * @author Gqr + * @since 2025/8/21 14:37 + */ +public class InvoiceStatusValidtor implements ConstraintValidator { + @Override + public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) { + if (ObjectUtil.isNull(integer)) { + return true; + } + for (InvoiceStatusEnum invoiceStatusEnum : InvoiceStatusEnum.values()) { + if (invoiceStatusEnum.getCode().equals(integer)) { + return true; + } + } + return false; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java index a77c4117b..ccf8ae3b6 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java @@ -24,7 +24,7 @@ import java.lang.annotation.Target; validatedBy = {InvoiceTypeValidtor.class} ) public @interface InvoiceTypeValid { - String message() default "不支持的发票类型"; + String message() default "{invoice.title.type.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java index fa81325a6..b719af2a3 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java @@ -22,7 +22,7 @@ import java.lang.annotation.Target; validatedBy = {PayChannelCodeValidator.class} ) public @interface PayChannelCodeValid { - String message() default "不支持的支付渠道"; + String message() default "{pay.channelCode.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/DurationUnitValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/DurationUnitValid.java index 616fd51f8..14a08900a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/DurationUnitValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/DurationUnitValid.java @@ -24,7 +24,7 @@ import java.lang.annotation.Target; validatedBy = {DurationUnitValidator.class} ) public @interface DurationUnitValid { - String message() default "时长单位不合法"; + String message() default "{product.duration.unit.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductDurationUnitValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductDurationUnitValid.java index fec741bf5..607a8d0e7 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductDurationUnitValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductDurationUnitValid.java @@ -24,7 +24,7 @@ import java.lang.annotation.Target; validatedBy = {ProductDurationUnitValidator.class} ) public @interface ProductDurationUnitValid { - String message() default "时长单位不合法"; + String message() default "{product.detail.duration.unit.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductStatus.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductStatus.java index 3732e3b85..152fd01ca 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductStatus.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductStatus.java @@ -18,7 +18,7 @@ import java.lang.annotation.*; ) public @interface ProductStatus { - String message() default "产品状态不合法,0:待上架 1:已上架 2:已下架"; + String message() default "{product.status.invalid}"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/application.yaml b/cf-module-system/cf-module-system-biz/src/main/resources/application.yaml index c2bddba0a..594ce0b56 100644 --- a/cf-module-system/cf-module-system-biz/src/main/resources/application.yaml +++ b/cf-module-system/cf-module-system-biz/src/main/resources/application.yaml @@ -97,7 +97,8 @@ spring: redis: repositories: enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 - + messages: + basename: message trans: config: appId: 20251110002494620 diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/message.properties b/cf-module-system/cf-module-system-biz/src/main/resources/message.properties new file mode 100644 index 000000000..c9177cb35 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/resources/message.properties @@ -0,0 +1,102 @@ +ad.adImagePath.notBlank=广告图片文件路径不能为空 +ad.adImagePath.size=广告图片文件路径长度不能超过 255 个字符 +ad.adRedirectUrl.size=链接长度不能超过 255 个字符 +ad.endTime.notNull=投放结束时间不能为空 +ad.name.notBlank=广告名称不能为空 +ad.name.size=广告名称长度不能超过 32 个字符 +ad.position.notEmpty=广告位置不能为空 +ad.sort.field=广告顺序 +ad.startTime.notNull=投放开始时间不能为空 +ad.status.invalid=广告状态不合法 +inEnum.message=必须在指定范围 {0} +invoice.apply.purchase.list.notEmpty=单词开票选择购买记录不能为空 +invoice.apply.purchase.size=单次开票选择购买记录不能超过100条 +invoice.confirm.id.notNull=发票申请记录编号不能为空 +invoice.confirm.invoiceNo.length=发票号长度不能超过 32 个字符 +invoice.confirm.remark.length=备注长度不能超过 1024 个字符 +invoice.page.amount.format=开票金额格式不正确 +invoice.page.amount.max=开票金额不能超过十万 +invoice.page.amount.min=开票金额必须大于等于零 +invoice.status.invalid=不支持的发票状态 +invoice.title.issueType.invalid=不支持的发票开具类型 +invoice.title.save.bankAccount.size=开户银行账号长度不能超过40个字符 +invoice.title.save.bankName.size=开户银行名称长度不能超过64个字符 +invoice.title.save.email.format=邮箱格式不正确 +invoice.title.save.email.notNull=邮箱不能为空 +invoice.title.save.email.size=邮箱长度不能超过64个字符 +invoice.title.save.fixedPhone.size=注册固定电话长度不能超过20个字符 +invoice.title.save.issueType.notNull=开具类型不能为空 +invoice.title.save.registeredAddress.size=注册场所地址长度不能超过64个字符 +invoice.title.save.taxNumber.size=统一社会信用代码长度不能超过18个字符 +invoice.title.save.title.notBlank=发票抬头不能为空 +invoice.title.save.title.size=发票抬头长度不能超过64个字符 +invoice.title.type.invalid=不支持的发票类型 +number.float.length.error={0} 长度不合法,总长度不超过{1}位,小数点后不超过{2}位 +number.greaterThanZero={0} 必须大于0 +page.pageNo.min=页码最小值为 1 +page.pageNo.notNull=页码不能为空 +page.pageSize.max=每页条数最大值为 100 +page.pageSize.min=每页条数最小值为 -1 +page.pageSize.notNull=每页条数不能为空 +product.delay.page.operator.size=操作人长度不能超过64个字符 +product.delay.page.productName.size=产品名称长度不能超过64个字符 +product.delay.save.duration.notNull=延期时长不能为空 +product.delay.save.duration.unit.notNull=延期时长单位不能为空 +product.delay.save.organId.notNull=组织编号不能为空 +product.delay.save.purchaseId.notNull=购买记录编号不能为空 +product.delay.save.remark.size=备注不能超过1024个字符 +product.detail.duration.notNull=产品时长不能为空 +product.detail.duration.unit.invalid=产品折扣时长单位不合法 +product.detail.duration.unit.notNull=产品时长单位不能为空 +product.detail.save.discount.format=折扣必须是0 ~ 100间的整数 +product.detail.save.discount.max=折扣必须小于等于100 +product.detail.save.discount.min=折扣必须大于等于0 +product.detail.save.discount.notNull=折扣不能为空 +product.detail.save.duration.min=产品时长必须大于0 +product.detail.save.productId.notNull=产品名称不能为空 +product.duration.unit.invalid=时长单位不合法 +product.page.price.format=单价格式不正确 +product.page.price.max=单价不能超过十万 +product.page.price.min=单价必须大于零 +product.promotion.save.activityName.notNull=活动名称不能为空 +product.promotion.save.endTime.notNull=结束时间不能为空 +product.promotion.save.gift.duration.notNull=赠送时长不能为空 +product.promotion.save.gift.duration.unit.notNull=赠送时长单位不能为空 +product.promotion.save.productId.notNull=关联产品不能为空 +product.promotion.save.purchase.duration.notNull=购买时长不能为空 +product.promotion.save.purchase.duration.unit.notNull=购买时长单位不能为空 +product.promotion.save.startTime.notNull=开始时间不能为空 +product.save.price.format=产品建议价格格式不正确 +product.save.price.max=产品建议价格不能超过十万 +product.save.price.min=产品建议价格必须大于零 +product.save.price.notNull=产品建议价格不能为空 +product.save.productName.notEmpty=产品名称不能为空 +product.save.productName.size=产品名称长度不能超过64 +product.status.invalid=产品状态不合法 +purchase.record.page.id.size=订单号长度不能超过20个字符 +purchase.record.page.productPrice.format=产品购买金额格式不正确 +purchase.record.page.productPrice.max=产品购买金额不能超过十万 +purchase.record.page.productPrice.min=产品购买金额必须大于零 +sales.detail.page.operator.size=操作人长度不能超过64个字符 +sales.detail.page.productPrice.format=产品购买金额格式不正确 +sales.detail.page.productPrice.max=产品购买金额不能超过十万 +sales.detail.page.productPrice.min=产品购买金额必须大于零 +statistics.unit.invalid=统计维度单位不合法 +statistics.unit.notNull=统计维度单位不能为空 +pay.channelCode.invalid=不支持的支付渠道 +pay.product.productChannelCode.notNull=产品支付渠道编码不能为空 +pay.product.productDetailsId.notNull=产品定价规则编号不能为空 +pay.product.productId.notNull=产品ID不能为空 +global.error.request.param.missing=请求参数缺失:{0} +global.error.bad.request=请求参数不正确:{0} +global.error.request.param.type.error=请求参数类型错误:{0} +global.error.request.not.found=请求未找到:{0} +global.error.request.method.error=请求方法不正确:{0} +global.error.request.too.many=请求过于频繁,请稍后重试 +global.error.request.duplicate.data.error=请求数据已存在,请检查 +global.error.default.error=系统繁忙,请稍后再试 +global.error.no.permission=没有该操作权限 +global.error.no.permission.to.visit.org=您无权访问该组织的数据 +global.error.request.organId.notExist=请求的组织标识未传递,请进行排查 +global.org.product.not.exist=账号登录异常,套餐信息不存在,请重新登陆 +global.org.product.expired=组织产品套餐已过期,请续费后继续使用 \ No newline at end of file diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/message_cht.properties b/cf-module-system/cf-module-system-biz/src/main/resources/message_cht.properties new file mode 100644 index 000000000..a3847a108 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/resources/message_cht.properties @@ -0,0 +1,102 @@ +ad.adImagePath.notBlank=廣告圖片檔案路徑不能為空 +ad.adImagePath.size=廣告圖片檔案路徑長度不能超過 255 個字元 +ad.adRedirectUrl.size=連結長度不能超過 255 個字元 +ad.endTime.notNull=投放結束時間不能為空 +ad.name.notBlank=廣告名稱不能為空 +ad.name.size=廣告名稱長度不能超過 32 個字元 +ad.position.notEmpty=廣告位置不能為空 +ad.sort.field=廣告順序 +ad.startTime.notNull=投放開始時間不能為空 +ad.status.invalid=廣告狀態不合法 +inEnum.message=必須在指定範圍 {0} +invoice.apply.purchase.list.notEmpty=單次開票選擇的購買記錄不能為空 +invoice.apply.purchase.size=單次開票選擇的購買記錄不能超過 100 條 +invoice.confirm.id.notNull=發票申請記錄編號不能為空 +invoice.confirm.invoiceNo.length=發票號長度不能超過 32 個字元 +invoice.confirm.remark.length=備註長度不能超過 1024 個字元 +invoice.page.amount.format=開票金額格式不正確 +invoice.page.amount.max=開票金額不能超過十萬 +invoice.page.amount.min=開票金額必須大於等於零 +invoice.status.invalid=不支援的發票狀態 +invoice.title.issueType.invalid=不支援的發票開具類型 +invoice.title.save.bankAccount.size=開戶銀行帳號長度不能超過 40 個字元 +invoice.title.save.bankName.size=開戶銀行名稱長度不能超過 64 個字元 +invoice.title.save.email.format=郵箱格式不正確 +invoice.title.save.email.notNull=郵箱不能為空 +invoice.title.save.email.size=郵箱長度不能超過 64 個字元 +invoice.title.save.fixedPhone.size=註冊固定電話長度不能超過 20 個字元 +invoice.title.save.issueType.notNull=開具類型不能為空 +invoice.title.save.registeredAddress.size=註冊場所地址長度不能超過 64 個字元 +invoice.title.save.taxNumber.size=統一社會信用代碼長度不能超過 18 個字元 +invoice.title.save.title.notBlank=發票抬頭不能為空 +invoice.title.save.title.size=發票抬頭長度不能超過 64 個字元 +invoice.title.type.invalid=不支援的發票類型 +number.float.length.error={0} 長度不合法,總長度不能超過 {1} 位,小數點後不能超過 {2} 位 +number.greaterThanZero={0} 必須大於 0 +page.pageNo.min=頁碼最小值為 1 +page.pageNo.notNull=頁碼不能為空 +page.pageSize.max=每頁條數最大值為 100 +page.pageSize.min=每頁條數最小值為 -1 +page.pageSize.notNull=每頁條數不能為空 +product.delay.page.operator.size=操作人長度不能超過 64 個字元 +product.delay.page.productName.size=產品名稱長度不能超過 64 個字元 +product.delay.save.duration.notNull=延期時長不能為空 +product.delay.save.duration.unit.notNull=延期時長單位不能為空 +product.delay.save.organId.notNull=組織編號不能為空 +product.delay.save.purchaseId.notNull=購買記錄編號不能為空 +product.delay.save.remark.size=備註不能超過 1024 個字元 +product.detail.duration.notNull=產品時長不能為空 +product.detail.duration.unit.invalid=產品折扣時長單位不合法 +product.detail.duration.unit.notNull=產品時長單位不能為空 +product.detail.save.discount.format=折扣必須是 0 ~ 100 之間的整數 +product.detail.save.discount.max=折扣必須小於等於 100 +product.detail.save.discount.min=折扣必須大於等於 0 +product.detail.save.discount.notNull=折扣不能為空 +product.detail.save.duration.min=產品時長必須大於 0 +product.detail.save.productId.notNull=產品名稱不能為空 +product.duration.unit.invalid=時長單位不合法 +product.page.price.format=單價格式不正確 +product.page.price.max=單價不能超過十萬 +product.page.price.min=單價必須大於零 +product.promotion.save.activityName.notNull=活動名稱不能為空 +product.promotion.save.endTime.notNull=結束時間不能為空 +product.promotion.save.gift.duration.notNull=贈送時長不能為空 +product.promotion.save.gift.duration.unit.notNull=贈送時長單位不能為空 +product.promotion.save.productId.notNull=關聯產品不能為空 +product.promotion.save.purchase.duration.notNull=購買時長不能為空 +product.promotion.save.purchase.duration.unit.notNull=購買時長單位不能為空 +product.promotion.save.startTime.notNull=開始時間不能為空 +product.save.price.format=產品建議價格格式不正確 +product.save.price.max=產品建議價格不能超過十萬 +product.save.price.min=產品建議價格必須大於零 +product.save.price.notNull=產品建議價格不能為空 +product.save.productName.notEmpty=產品名稱不能為空 +product.save.productName.size=產品名稱長度不能超過 64 個字元 +product.status.invalid=產品狀態不合法 +purchase.record.page.id.size=訂單號長度不能超過 20 個字元 +purchase.record.page.productPrice.format=產品購買金額格式不正確 +purchase.record.page.productPrice.max=產品購買金額不能超過十萬 +purchase.record.page.productPrice.min=產品購買金額必須大於零 +sales.detail.page.operator.size=操作人長度不能超過 64 個字元 +sales.detail.page.productPrice.format=產品購買金額格式不正確 +sales.detail.page.productPrice.max=產品購買金額不能超過十萬 +sales.detail.page.productPrice.min=產品購買金額必須大於零 +statistics.unit.invalid=統計維度單位不合法 +statistics.unit.notNull=統計維度單位不能為空 +pay.channelCode.invalid=不支援的支付渠道 +pay.product.productChannelCode.notNull=產品支付渠道編碼不能為空 +pay.product.productDetailsId.notNull=產品定價規則編號不能為空 +pay.product.productId.notNull=產品 ID 不能為空 +global.error.request.param.missing=請求參數缺失:{0} +global.error.bad.request=請求參數不正確:{0} +global.error.request.param.type.error=請求參數類型錯誤:{0} +global.error.request.not.found=請求未找到:{0} +global.error.request.method.error=請求方法不正確:{0} +global.error.request.too.many=請求過於頻繁,請稍後重試 +global.error.request.duplicate.data.error=請求數據已存在,請檢查 +global.error.default.error=系統繁忙,請稍後再試 +global.error.no.permission=您沒有該操作的權限 +global.error.no.permission.to.visit.org=您無權訪問該組織的數據 +global.error.request.organId.notExist=請求的組織標識未傳遞,請進行排查 +global.org.product.not.exist=帳號登入異常,套餐資訊不存在,請重新登入 +global.org.product.expired=組織產品套餐已過期,請續費後繼續使用 \ No newline at end of file diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/message_en.properties b/cf-module-system/cf-module-system-biz/src/main/resources/message_en.properties new file mode 100644 index 000000000..19736b57d --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/resources/message_en.properties @@ -0,0 +1,102 @@ +ad.adImagePath.notBlank=Ad image file path cannot be empty +ad.adImagePath.size=Ad image file path length cannot exceed 255 characters +ad.adRedirectUrl.size=Redirect URL length cannot exceed 255 characters +ad.endTime.notNull=End time cannot be empty +ad.name.notBlank=Ad name cannot be empty +ad.name.size=Ad name length cannot exceed 32 characters +ad.position.notEmpty=Ad position cannot be empty +ad.sort.field=Ad sort order +ad.startTime.notNull=Start time cannot be empty +ad.status.invalid=Invalid ad status +inEnum.message=Must be within the specified range {0} +invoice.apply.purchase.list.notEmpty=Selected purchase records cannot be empty +invoice.apply.purchase.size=You cannot select more than 100 purchase records at once +invoice.confirm.id.notNull=Invoice application ID cannot be empty +invoice.confirm.invoiceNo.length=Invoice number length cannot exceed 32 characters +invoice.confirm.remark.length=Remark length cannot exceed 1024 characters +invoice.page.amount.format=Invalid amount format +invoice.page.amount.max=Amount cannot exceed 100,000 +invoice.page.amount.min=Amount must be greater than or equal to zero +invoice.status.invalid=Unsupported invoice status +invoice.title.issueType.invalid=Unsupported invoice issue type +invoice.title.save.bankAccount.size=Bank account length cannot exceed 40 characters +invoice.title.save.bankName.size=Bank name length cannot exceed 64 characters +invoice.title.save.email.format=Invalid email format +invoice.title.save.email.notNull=Email cannot be empty +invoice.title.save.email.size=Email length cannot exceed 64 characters +invoice.title.save.fixedPhone.size=Fixed phone number length cannot exceed 20 characters +invoice.title.save.issueType.notNull=Issue type cannot be empty +invoice.title.save.registeredAddress.size=Registered address length cannot exceed 64 characters +invoice.title.save.taxNumber.size=Tax identification number length cannot exceed 18 characters +invoice.title.save.title.notBlank=Invoice title cannot be empty +invoice.title.save.title.size=Invoice title length cannot exceed 64 characters +invoice.title.type.invalid=Unsupported invoice type +number.float.length.error={0} length is invalid. Total length must not exceed {1} digits, and decimal places must not exceed {2} digits +number.greaterThanZero={0} must be greater than 0 +page.pageNo.min=Page number must be at least 1 +page.pageNo.notNull=Page number cannot be empty +page.pageSize.max=Page size cannot exceed 100 +page.pageSize.min=Page size must be at least -1 +page.pageSize.notNull=Page size cannot be empty +product.delay.page.operator.size=Operator length cannot exceed 64 characters +product.delay.page.productName.size=Product name length cannot exceed 64 characters +product.delay.save.duration.notNull=Delay duration cannot be empty +product.delay.save.duration.unit.notNull=Delay duration unit cannot be empty +product.delay.save.organId.notNull=Organization ID cannot be empty +product.delay.save.purchaseId.notNull=Purchase record ID cannot be empty +product.delay.save.remark.size=Remark length cannot exceed 1024 characters +product.detail.duration.notNull=Product duration cannot be empty +product.detail.duration.unit.invalid=Invalid product duration unit +product.detail.duration.unit.notNull=Product duration unit cannot be empty +product.detail.save.discount.format=Discount must be an integer between 0 and 100 +product.detail.save.discount.max=Discount must be less than or equal to 100 +product.detail.save.discount.min=Discount must be greater than or equal to 0 +product.detail.save.discount.notNull=Discount cannot be empty +product.detail.save.duration.min=Product duration must be greater than 0 +product.detail.save.productId.notNull=Product ID cannot be empty +product.duration.unit.invalid=Invalid duration unit +product.page.price.format=Invalid price format +product.page.price.max=Unit price cannot exceed 100,000 +product.page.price.min=Unit price must be greater than zero +product.promotion.save.activityName.notNull=Activity name cannot be empty +product.promotion.save.endTime.notNull=End time cannot be empty +product.promotion.save.gift.duration.notNull=Gift duration cannot be empty +product.promotion.save.gift.duration.unit.notNull=Gift duration unit cannot be empty +product.promotion.save.productId.notNull=Product cannot be empty +product.promotion.save.purchase.duration.notNull=Purchase duration cannot be empty +product.promotion.save.purchase.duration.unit.notNull=Purchase duration unit cannot be empty +product.promotion.save.startTime.notNull=Start time cannot be empty +product.save.price.format=Invalid suggested price format +product.save.price.max=Suggested price cannot exceed 100,000 +product.save.price.min=Suggested price must be greater than zero +product.save.price.notNull=Suggested price cannot be empty +product.save.productName.notEmpty=Product name cannot be empty +product.save.productName.size=Product name length cannot exceed 64 characters +product.status.invalid=Invalid product status +purchase.record.page.id.size=Order ID length cannot exceed 20 characters +purchase.record.page.productPrice.format=Invalid purchase amount format +purchase.record.page.productPrice.max=Purchase amount cannot exceed 100,000 +purchase.record.page.productPrice.min=Purchase amount must be greater than zero +sales.detail.page.operator.size=Operator length cannot exceed 64 characters +sales.detail.page.productPrice.format=Invalid purchase amount format +sales.detail.page.productPrice.max=Purchase amount cannot exceed 100,000 +sales.detail.page.productPrice.min=Purchase amount must be greater than zero +statistics.unit.invalid=Invalid statistics unit +statistics.unit.notNull=Statistics unit cannot be empty +pay.channelCode.invalid=Unsupported payment channel +pay.product.productChannelCode.notNull=Product payment channel code cannot be empty +pay.product.productDetailsId.notNull=Product pricing rule ID cannot be empty +pay.product.productId.notNull=Product ID cannot be empty +global.error.request.param.missing=Missing request parameter: {0} +global.error.bad.request=Invalid request parameter: {0} +global.error.request.param.type.error=Request parameter type mismatch: {0} +global.error.request.not.found=Request not found: {0} +global.error.request.method.error=Incorrect request method: {0} +global.error.request.too.many=Too many requests, please try again later +global.error.request.duplicate.data.error=Data already exists, please check +global.error.default.error=System is busy, please try again later +global.error.no.permission=You do not have permission to perform this action +global.error.no.permission.to.visit.org=You do not have permission to access this organization’s data +global.error.request.organId.notExist=The requested organization ID was not provided, please check +global.org.product.not.exist=Account login exception: product package does not exist, please log in again +global.org.product.expired=The organization's product package has expired, please renew before continuing to use the service \ No newline at end of file