Commit 8fb01d0cecfce63c1e8027309622c86a98ddfe8a
1 parent
62b86bda
支持程序启动时加载错误码
Showing
7 changed files
with
296 additions
and
1 deletions
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 | 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 | 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
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 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; |
| 5 | +import cn.iocoder.dashboard.common.pojo.CommonResult; | |
| 5 | 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 | 8 | import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert; |
| 8 | 9 | import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO; |
| 9 | 10 | import cn.iocoder.dashboard.modules.system.dal.mysql.errorcode.ErrorCodeMapper; |
| ... | ... | @@ -24,6 +25,7 @@ import java.util.Map; |
| 24 | 25 | |
| 25 | 26 | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_DUPLICATE; |
| 26 | 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 | 31 | * 错误码 Service |
| ... | ... | @@ -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 | 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 | ... | ... |