Commit 8fb01d0cecfce63c1e8027309622c86a98ddfe8a

Authored by dylan
1 parent 62b86bda

支持程序启动时加载错误码

src/main/java/cn/iocoder/dashboard/framework/errorcode/config/ErrorCodeAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.errorcode.config;
  2 +
  3 +import cn.iocoder.dashboard.framework.errorcode.core.ErrorCodeRemoteLoader;
  4 +import org.springframework.boot.context.properties.EnableConfigurationProperties;
  5 +import org.springframework.context.annotation.Bean;
  6 +import org.springframework.context.annotation.Configuration;
  7 +import org.springframework.scheduling.annotation.EnableScheduling;
  8 +
  9 +@Configuration
  10 +@EnableConfigurationProperties(ErrorCodeProperties.class)
  11 +@EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码
  12 +public class ErrorCodeAutoConfiguration {
  13 +
  14 + @Bean
  15 + public cn.iocoder.dashboard.framework.errorcode.core.ErrorCodeAutoGenerator errorCodeAutoGenerator(ErrorCodeProperties errorCodeProperties) {
  16 + return new cn.iocoder.dashboard.framework.errorcode.core.ErrorCodeAutoGenerator(errorCodeProperties.getGroup())
  17 + .setErrorCodeConstantsClass(errorCodeProperties.getConstantsClass());
  18 + }
  19 +
  20 + @Bean
  21 + public ErrorCodeRemoteLoader errorCodeRemoteLoader(ErrorCodeProperties errorCodeProperties) {
  22 + return new ErrorCodeRemoteLoader(errorCodeProperties.getGroup());
  23 + }
  24 +
  25 +}
0 \ No newline at end of file 26 \ No newline at end of file
src/main/java/cn/iocoder/dashboard/framework/errorcode/config/ErrorCodeProperties.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.errorcode.config;
  2 +
  3 +import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +import org.springframework.validation.annotation.Validated;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +@ConfigurationProperties("ruoyi.error-code")
  9 +@Validated
  10 +public class ErrorCodeProperties {
  11 +
  12 + /**
  13 + * 应用分组
  14 + */
  15 + @NotNull(message = "应用分组不能为空,请设置 ruoyi.error-code.group 配置项,推荐直接使用 spring. application.name 配置项")
  16 + private String group;
  17 + /**
  18 + * 错误码枚举类
  19 + */
  20 + private String constantsClass;
  21 +
  22 + public String getGroup() {
  23 + return group;
  24 + }
  25 +
  26 + public ErrorCodeProperties setGroup(String group) {
  27 + this.group = group;
  28 + return this;
  29 + }
  30 +
  31 + public String getConstantsClass() {
  32 + return constantsClass;
  33 + }
  34 +
  35 + public ErrorCodeProperties setConstantsClass(String constantsClass) {
  36 + this.constantsClass = constantsClass;
  37 + return this;
  38 + }
  39 +}
0 \ No newline at end of file 40 \ No newline at end of file
src/main/java/cn/iocoder/dashboard/framework/errorcode/core/ErrorCodeAutoGenerator.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.errorcode.core;
  2 +
  3 +import cn.iocoder.dashboard.common.exception.ErrorCode;
  4 +import cn.iocoder.dashboard.common.pojo.CommonResult;
  5 +import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeAutoGenerateDTO;
  6 +import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert;
  7 +import cn.iocoder.dashboard.modules.system.service.errorcode.ErrorCodeService;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.boot.context.event.ApplicationReadyEvent;
  11 +import org.springframework.context.event.EventListener;
  12 +import org.springframework.scheduling.annotation.Async;
  13 +import org.springframework.util.StringUtils;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.ArrayList;
  17 +import java.util.Arrays;
  18 +import java.util.List;
  19 +
  20 +public class ErrorCodeAutoGenerator {
  21 +
  22 + private Logger logger = LoggerFactory.getLogger(ErrorCodeAutoGenerator.class);
  23 +
  24 + /**
  25 + * 应用分组
  26 + */
  27 + private final String group;
  28 + /**
  29 + * 错误码枚举类
  30 + */
  31 + private String errorCodeConstantsClass;
  32 +
  33 + @Resource
  34 + private ErrorCodeService errorCodeService;
  35 +
  36 + public ErrorCodeAutoGenerator(String group) {
  37 + this.group = group;
  38 + }
  39 +
  40 + public ErrorCodeAutoGenerator setErrorCodeConstantsClass(String errorCodeConstantsClass) {
  41 + this.errorCodeConstantsClass = errorCodeConstantsClass;
  42 + return this;
  43 + }
  44 +
  45 + @EventListener(ApplicationReadyEvent.class)
  46 + @Async // 异步,保证项目的启动过程,毕竟非关键流程
  47 + public void execute() {
  48 + // 校验 errorCodeConstantsClass 参数
  49 + if (!StringUtils.hasText(errorCodeConstantsClass)) {
  50 + logger.info("[execute][未配置 ruoyi.error-code.constants-class 配置项,不进行自动写入到 system-service 服务]");
  51 + return;
  52 + }
  53 + Class errorCodeConstantsClazz;
  54 + try {
  55 + errorCodeConstantsClazz = Class.forName(errorCodeConstantsClass);
  56 + } catch (ClassNotFoundException e) {
  57 + logger.error("[execute][配置的 ({}) 找不到对应的类]", errorCodeConstantsClass);
  58 + return;
  59 + }
  60 + // 写入 system-service 服务
  61 + logger.info("[execute][自动将 ({}) 类的错误码,准备写入到 system-service 服务]", errorCodeConstantsClass);
  62 + List<ErrorCodeAutoGenerateDTO> autoGenerateDTOs = new ArrayList<>();
  63 + Arrays.stream(errorCodeConstantsClazz.getFields()).forEach(field -> {
  64 + if (field.getType() != ErrorCode.class) {
  65 + return;
  66 + }
  67 + try {
  68 + // TODO 芋艿:校验是否重复了;
  69 + ErrorCode errorCode = (ErrorCode) field.get(errorCodeConstantsClazz);
  70 + autoGenerateDTOs.add(new ErrorCodeAutoGenerateDTO().setGroup(group)
  71 + .setCode(errorCode.getCode()).setMessage(errorCode.getMessage()));
  72 + } catch (IllegalAccessException e) {
  73 + throw new RuntimeException(e);
  74 + }
  75 + });
  76 + CommonResult<Boolean> autoGenerateErrorCodesResult = errorCodeService.autoGenerateErrorCodes1(ErrorCodeConvert.INSTANCE.convertList03(autoGenerateDTOs));
  77 + if (autoGenerateErrorCodesResult.isSuccess()) {
  78 + logger.info("[execute][自动将 ({}) 类的错误码,成功写入到 system-service 服务]", errorCodeConstantsClass);
  79 + } else {
  80 + logger.error("[execute][自动将 ({}) 类的错误码,失败写入到 system-service 服务,原因为 ({}/{})]", errorCodeConstantsClass,
  81 + autoGenerateErrorCodesResult.getCode(), autoGenerateErrorCodesResult.getMsg());
  82 + }
  83 + }
  84 +
  85 +}
src/main/java/cn/iocoder/dashboard/framework/errorcode/core/ErrorCodeRemoteLoader.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.errorcode.core;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
  5 +import cn.iocoder.dashboard.common.pojo.CommonResult;
  6 +import cn.iocoder.dashboard.modules.system.controller.errorcode.vo.ErrorCodeVO;
  7 +import cn.iocoder.dashboard.modules.system.service.errorcode.ErrorCodeService;
  8 +import cn.iocoder.dashboard.modules.system.service.errorcode.bo.ErrorCodeBO;
  9 +import cn.iocoder.dashboard.util.date.DateUtils;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.boot.context.event.ApplicationReadyEvent;
  13 +import org.springframework.context.event.EventListener;
  14 +import org.springframework.scheduling.annotation.Scheduled;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.util.Date;
  18 +import java.util.List;
  19 +
  20 +public class ErrorCodeRemoteLoader {
  21 +
  22 + private static final int REFRESH_ERROR_CODE_PERIOD = 60 * 1000;
  23 +
  24 + private Logger logger = LoggerFactory.getLogger(ErrorCodeRemoteLoader.class);
  25 +
  26 + /**
  27 + * 应用分组
  28 + */
  29 + private final String group;
  30 +
  31 + @Resource
  32 + private ErrorCodeService errorCodeService;
  33 +
  34 + private Date maxUpdateTime;
  35 +
  36 + public ErrorCodeRemoteLoader(String group) {
  37 + this.group = group;
  38 + }
  39 +
  40 + @EventListener(ApplicationReadyEvent.class)
  41 + public void loadErrorCodes() {
  42 + // 从 ErrorCodeRpc 全量加载 ErrorCode 错误码
  43 + CommonResult<List<ErrorCodeVO>> listErrorCodesResult = errorCodeService.listErrorCodes1(group, null);
  44 + listErrorCodesResult.checkError();
  45 + logger.info("[loadErrorCodes][从 group({}) 全量加载到 {} 个 ErrorCode 错误码]", group, listErrorCodesResult.getData().size());
  46 + // 写入到 ServiceExceptionUtil 到
  47 + listErrorCodesResult.getData().forEach(errorCodeVO -> {
  48 + ServiceExceptionUtil.put(errorCodeVO.getCode(), errorCodeVO.getMessage());
  49 + // 记录下更新时间,方便增量更新
  50 + maxUpdateTime = DateUtils.max(maxUpdateTime, errorCodeVO.getUpdateTime());
  51 + });
  52 + }
  53 +
  54 + @Scheduled(fixedDelay = REFRESH_ERROR_CODE_PERIOD, initialDelay = REFRESH_ERROR_CODE_PERIOD)
  55 + public void refreshErrorCodes() {
  56 + // 从 ErrorCodeRpc 增量加载 ErrorCode 错误码
  57 + // TODO 优化点:假设删除错误码的配置,会存在问题;
  58 + CommonResult<List<ErrorCodeVO>> listErrorCodesResult = errorCodeService.listErrorCodes1(group, maxUpdateTime);
  59 + listErrorCodesResult.checkError();
  60 + if (CollUtil.isEmpty(listErrorCodesResult.getData())) {
  61 + return;
  62 + }
  63 + logger.info("[refreshErrorCodes][从 group({}) 增量加载到 {} 个 ErrorCode 错误码]", group, listErrorCodesResult.getData().size());
  64 + // 写入到 ServiceExceptionUtil 到
  65 + listErrorCodesResult.getData().forEach(errorCodeVO -> {
  66 + ServiceExceptionUtil.put(errorCodeVO.getCode(), errorCodeVO.getMessage());
  67 + // 记录下更新时间,方便增量更新
  68 + maxUpdateTime = DateUtils.max(maxUpdateTime, errorCodeVO.getUpdateTime());
  69 + });
  70 + }
  71 +
  72 +}
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/ErrorCodeController.http 0 → 100644
  1 +### 请求 /login 接口 => 成功
  2 +POST http://localhost:48080/api/login
  3 +Content-Type: application/json
  4 +
  5 +{
  6 + "username": "admin",
  7 + "password": "admin123",
  8 + "uuid": "9b2ffbc1-7425-4155-9894-9d5c08541d62",
  9 + "code": "1024"
  10 +}
  11 +
  12 +> {%
  13 + client.global.set("token", response.body.data.token)
  14 + %}
  15 +
  16 +
  17 +### list-group
  18 +GET http://localhost:48080/api/system/error-code/list-group
  19 +Authorization: Bearer {{token}}
  20 +Content-Type: application/x-www-form-urlencoded
  21 +
  22 +group=test&minUpdateTime=2021-03-14 14:37:47
  23 +
  24 +
  25 +
  26 +###
  27 +GET http://localhost:48080/api/system/error-code/query
  28 +Authorization: Bearer {{token}}
  29 +Content-Type: application/x-www-form-urlencoded
  30 +
  31 +errorCodeId=350
  32 +
  33 +###
  34 +POST http://localhost:48080/api/system/error-code/generate
  35 +Authorization: Bearer {{token}}
  36 +
  37 +[
  38 +{
  39 + "code": 202,
  40 + "message": "成功1",
  41 + "group": "test1"
  42 +}
  43 +]
  44 +
  45 +###
  46 +POST http://localhost:48080/api/system/error-code/create
  47 +Authorization: Bearer {{token}}
  48 +Content-Type:application/json
  49 +
  50 +{
  51 + "code": 200,
  52 + "message": "成功",
  53 + "group": "test",
  54 + "type": 1
  55 +}
  56 +
  57 +
  58 +
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/vo/ErrorCodeVO.java
@@ -29,5 +29,7 @@ public class ErrorCodeVO { @@ -29,5 +29,7 @@ public class ErrorCodeVO {
29 private String memo; 29 private String memo;
30 @ApiModelProperty(value = "创建时间", required = true) 30 @ApiModelProperty(value = "创建时间", required = true)
31 private Date createTime; 31 private Date createTime;
  32 + @ApiModelProperty(value = "更新时间", required = false)
  33 + private Date updateTime;
32 34
33 } 35 }
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/ErrorCodeService.java
@@ -2,8 +2,9 @@ package cn.iocoder.dashboard.modules.system.service.errorcode; @@ -2,8 +2,9 @@ package cn.iocoder.dashboard.modules.system.service.errorcode;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; 4 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
  5 +import cn.iocoder.dashboard.common.pojo.CommonResult;
5 import cn.iocoder.dashboard.common.pojo.PageResult; 6 import cn.iocoder.dashboard.common.pojo.PageResult;
6 -import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodePageDTO; 7 +import cn.iocoder.dashboard.modules.system.controller.errorcode.vo.ErrorCodeVO;
7 import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert; 8 import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert;
8 import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO; 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO;
9 import cn.iocoder.dashboard.modules.system.dal.mysql.errorcode.ErrorCodeMapper; 10 import cn.iocoder.dashboard.modules.system.dal.mysql.errorcode.ErrorCodeMapper;
@@ -24,6 +25,7 @@ import java.util.Map; @@ -24,6 +25,7 @@ import java.util.Map;
24 25
25 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_DUPLICATE; 26 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_DUPLICATE;
26 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_NOT_EXISTS; 27 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_NOT_EXISTS;
  28 +import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
27 29
28 /** 30 /**
29 * 错误码 Service 31 * 错误码 Service
@@ -106,6 +108,12 @@ public class ErrorCodeService { @@ -106,6 +108,12 @@ public class ErrorCodeService {
106 }); 108 });
107 } 109 }
108 110
  111 + public CommonResult<Boolean> autoGenerateErrorCodes1(@Valid List<ErrorCodeAutoGenerateBO> autoGenerateBOs) {
  112 + autoGenerateErrorCodes(autoGenerateBOs);
  113 + return success(Boolean.TRUE);
  114 + }
  115 +
  116 +
109 /** 117 /**
110 * 删除错误码 118 * 删除错误码
111 * 119 *
@@ -180,5 +188,11 @@ public class ErrorCodeService { @@ -180,5 +188,11 @@ public class ErrorCodeService {
180 return ErrorCodeConvert.INSTANCE.convertList(errorCodeDOs); 188 return ErrorCodeConvert.INSTANCE.convertList(errorCodeDOs);
181 } 189 }
182 190
  191 + public CommonResult<List<ErrorCodeVO>> listErrorCodes1(String group, Date minUpdateTime) {
  192 + List<ErrorCodeDO> errorCodeDOs = errorCodeMapper.selectListByGroup(group, minUpdateTime);
  193 + final List<ErrorCodeBO> errorCodeBOS = ErrorCodeConvert.INSTANCE.convertList(errorCodeDOs);
  194 + return success(ErrorCodeConvert.INSTANCE.convertList02(errorCodeBOS));
  195 + }
  196 +
183 } 197 }
184 198