Bladeren bron

完成错误码

dylan 4 jaren geleden
bovenliggende
commit
4c3997b628
19 gewijzigde bestanden met toevoegingen van 964 en 0 verwijderingen
  1. 35 0
      src/main/java/cn/iocoder/dashboard/framework/validator/InEnum.java
  2. 44 0
      src/main/java/cn/iocoder/dashboard/framework/validator/InEnumValidator.java
  3. 133 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/ErrorCodeController.java
  4. 33 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeAutoGenerateDTO.java
  5. 45 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeCreateDTO.java
  6. 33 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodePageDTO.java
  7. 46 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeUpdateDTO.java
  8. 48 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/vo/ErrorCodeVO.java
  9. 49 0
      src/main/java/cn/iocoder/dashboard/modules/system/convert/errorcode/ErrorCodeConvert.java
  10. 45 0
      src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/errorcode/ErrorCodeDO.java
  11. 36 0
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/errorcode/ErrorCodeMapper.java
  12. 5 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java
  13. 38 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/errorcode/ErrorCodeTypeEnum.java
  14. 183 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/ErrorCodeService.java
  15. 33 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeAutoGenerateBO.java
  16. 48 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeBO.java
  17. 36 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeCreateBO.java
  18. 29 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodePageBO.java
  19. 45 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeUpdateBO.java

+ 35 - 0
src/main/java/cn/iocoder/dashboard/framework/validator/InEnum.java

@@ -0,0 +1,35 @@
+package cn.iocoder.dashboard.framework.validator;
+
+import cn.iocoder.dashboard.common.core.IntArrayValuable;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Target({
+        ElementType.METHOD,
+        ElementType.FIELD,
+        ElementType.ANNOTATION_TYPE,
+        ElementType.CONSTRUCTOR,
+        ElementType.PARAMETER,
+        ElementType.TYPE_USE
+})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(
+        validatedBy = InEnumValidator.class
+)
+public @interface InEnum {
+
+    /**
+     * @return 实现 EnumValuable 接口的
+     */
+    Class<? extends IntArrayValuable> value();
+
+    String message() default "必须在指定范围 {value}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+
+}

+ 44 - 0
src/main/java/cn/iocoder/dashboard/framework/validator/InEnumValidator.java

@@ -0,0 +1,44 @@
+package cn.iocoder.dashboard.framework.validator;
+
+import cn.iocoder.dashboard.common.core.IntArrayValuable;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class InEnumValidator implements ConstraintValidator<InEnum, Integer> {
+
+    private List<Integer> values;
+
+    @Override
+    public void initialize(InEnum annotation) {
+        IntArrayValuable[] values = annotation.value().getEnumConstants();
+        if (values.length == 0) {
+            this.values = Collections.emptyList();
+        } else {
+            this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList());
+        }
+    }
+
+    @Override
+    public boolean isValid(Integer value, ConstraintValidatorContext context) {
+        // 为空时,默认不校验,即认为通过
+        if (value == null) {
+            return true;
+        }
+        // 校验通过
+        if (values.contains(value)) {
+            return true;
+        }
+        // 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
+        context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
+        context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()
+                .replaceAll("\\{value}", values.toString())).addConstraintViolation(); // 重新添加错误提示语句
+        return false;
+    }
+
+}
+

+ 133 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/ErrorCodeController.java

@@ -0,0 +1,133 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode;
+
+import cn.iocoder.dashboard.common.pojo.CommonResult;
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeAutoGenerateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeCreateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodePageDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeUpdateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.vo.ErrorCodeVO;
+import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert;
+import cn.iocoder.dashboard.modules.system.service.errorcode.ErrorCodeService;
+import cn.iocoder.dashboard.modules.system.service.errorcode.bo.ErrorCodeBO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
+
+@Api(tags = "错误码")
+@RestController
+@RequestMapping("/system/error-code")
+public class ErrorCodeController {
+
+    @Resource
+    private ErrorCodeService errorCodeService;
+
+    /**
+     * 获得指定分组下的错误码列表
+     *
+     * @param group 错误码分组
+     * @param minUpdateTime 最小更新时间,允许为空。
+     *                      通过该参数,我们可以增量获取超过 minUpdateTime 时间的错误码
+     * @return 错误码列表
+     */
+    @ApiOperation("获取指定分组下的状态码")
+    @GetMapping("/list-group")
+    public CommonResult<List<ErrorCodeVO>> listErrorCodes(@NotNull(message = "错误码分组不能为空") String group, Date minUpdateTime) {
+        return success(ErrorCodeConvert.INSTANCE.convertList02(errorCodeService.listErrorCodes(group, minUpdateTime)));
+    }
+
+    /**
+     * 自动生成错误码
+     *
+     * @param autoGenerateDTOs 自动生成信息 DTO
+     */
+    @ApiOperation("自动生成错误码")
+    @PostMapping("/generate")
+    public CommonResult<Boolean> autoGenerateErrorCodes(List<ErrorCodeAutoGenerateDTO> autoGenerateDTOs) {
+        errorCodeService.autoGenerateErrorCodes(ErrorCodeConvert.INSTANCE.convertList03(autoGenerateDTOs));
+        return success(Boolean.TRUE);
+    }
+
+
+    /**
+     * 创建错误码
+     *
+     * @param createDTO 创建错误码 DTO
+     * @return 错误码编号
+     */
+    @ApiOperation("创建错误码")
+    @PostMapping("/create")
+    public CommonResult<Integer> createErrorCode(ErrorCodeCreateDTO createDTO) {
+        return success(errorCodeService.createErrorCode(ErrorCodeConvert.INSTANCE.convert(createDTO)).getId());
+    }
+
+    /**
+     * 更新错误码
+     *
+     * @param updateDTO 更新错误码 DTO
+     */
+    @ApiOperation("更新错误码")
+    @PatchMapping("/update")
+    public CommonResult<Boolean> updateErrorCode(ErrorCodeUpdateDTO updateDTO) {
+        errorCodeService.updateErrorCode(ErrorCodeConvert.INSTANCE.convert(updateDTO));
+        return success(Boolean.TRUE);
+    }
+
+    /**
+     * 删除错误码
+     *
+     * @param errorCodeId 错误码编号
+     */
+    @ApiOperation("删除错误码")
+    @DeleteMapping("delete")
+    public CommonResult<Boolean> deleteErrorCode(Integer errorCodeId) {
+        errorCodeService.deleteErrorCode(errorCodeId);
+        return success(Boolean.TRUE);
+    }
+
+    /**
+     * 获得错误码
+     *
+     * @param errorCodeId 错误码编号
+     * @return 错误码
+     */
+    @ApiOperation("获取错误码")
+    @GetMapping("/query")
+    public CommonResult<ErrorCodeVO> getErrorCode(Integer errorCodeId) {
+        return success(ErrorCodeConvert.INSTANCE.convert(errorCodeService.getErrorCode(errorCodeId)));
+    }
+
+    /**
+     * 获得错误码列表
+     *
+     * @param errorCodeIds 错误码编号列表
+     * @return 错误码列表
+     */
+    @ApiOperation("获取错误码列表")
+    @GetMapping("/query-ids")
+    public CommonResult<List<ErrorCodeVO>> listErrorCodes(List<Integer> errorCodeIds) {
+        return success(ErrorCodeConvert.INSTANCE.convertList02(errorCodeService.listErrorCodes(errorCodeIds)));
+    }
+
+    /**
+     * 获得错误码分页
+     *
+     * @param pageDTO 错误码分页查询
+     * @return 错误码分页结果
+     */
+    @ApiOperation("获取错误码分页列表")
+    @GetMapping("/page")
+    public CommonResult<PageResult<ErrorCodeVO>> pageErrorCode(ErrorCodePageDTO pageDTO) {
+        final PageResult<ErrorCodeBO> pageResult = errorCodeService.pageErrorCode(ErrorCodeConvert.INSTANCE.convert(pageDTO));
+        return success(ErrorCodeConvert.INSTANCE.convertPage(pageResult));
+    }
+
+
+}

+ 33 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeAutoGenerateDTO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 错误码自动生成 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeAutoGenerateDTO implements Serializable {
+
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    @NotEmpty(message = "错误码错误提示不能为空")
+    private String message;
+    /**
+     * 错误码分组
+     */
+    @NotNull(message = "错误码分组不能为空")
+    private String group;
+
+}

+ 45 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeCreateDTO.java

@@ -0,0 +1,45 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode.dto;
+
+import cn.iocoder.dashboard.framework.validator.InEnum;
+import cn.iocoder.dashboard.modules.system.enums.errorcode.ErrorCodeTypeEnum;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 错误码创建 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeCreateDTO implements Serializable {
+
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    @NotEmpty(message = "错误码错误提示不能为空")
+    private String message;
+    /**
+     * 错误码类型
+     */
+    @NotNull(message = "错误码类型不能为空")
+    @InEnum(value = ErrorCodeTypeEnum.class, message = "错误码类型必须是 {value}")
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    @NotNull(message = "错误码分组不能为空")
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+
+}

+ 33 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodePageDTO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode.dto;
+
+import cn.iocoder.dashboard.common.pojo.PageParam;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 错误码分页 DTO
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+public class ErrorCodePageDTO extends PageParam {
+
+    /**
+     * 错误码编码
+     */
+    private Integer code;
+    /**
+     * 错误码错误提示
+     *
+     * 模糊匹配
+     */
+    private String message;
+    /**
+     * 错误码分组
+     *
+     * 模糊匹配
+     */
+    private String group;
+
+}

+ 46 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/dto/ErrorCodeUpdateDTO.java

@@ -0,0 +1,46 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode.dto;
+
+import cn.iocoder.dashboard.framework.validator.InEnum;
+import cn.iocoder.dashboard.modules.system.enums.errorcode.ErrorCodeTypeEnum;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 错误码更新 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeUpdateDTO implements Serializable {
+
+    /**
+     * 错误码编号
+     */
+    @NotNull(message = "错误码编号不能为空")
+    private Integer id;
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    private String message;
+    /**
+     * 错误码类型
+     */
+    @InEnum(value = ErrorCodeTypeEnum.class, message = "错误码类型必须是 {value}")
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+
+}

+ 48 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/errorcode/vo/ErrorCodeVO.java

@@ -0,0 +1,48 @@
+package cn.iocoder.dashboard.modules.system.controller.errorcode.vo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 错误码
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeVO implements Serializable {
+
+    /**
+     * 错误码编号
+     */
+    private Integer id;
+    /**
+     * 错误码编码
+     */
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    private String message;
+    /**
+     * 错误码类型
+     */
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 最后更新时间
+     */
+    private Date updateTime;
+}

+ 49 - 0
src/main/java/cn/iocoder/dashboard/modules/system/convert/errorcode/ErrorCodeConvert.java

@@ -0,0 +1,49 @@
+package cn.iocoder.dashboard.modules.system.convert.errorcode;
+
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeAutoGenerateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeCreateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodePageDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.dto.ErrorCodeUpdateDTO;
+import cn.iocoder.dashboard.modules.system.controller.errorcode.vo.ErrorCodeVO;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO;
+import cn.iocoder.dashboard.modules.system.service.errorcode.bo.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface ErrorCodeConvert {
+
+    ErrorCodeConvert INSTANCE = Mappers.getMapper(ErrorCodeConvert.class);
+
+    ErrorCodeDO convert(ErrorCodeCreateBO bean);
+
+    ErrorCodeBO convert(ErrorCodeDO bean);
+
+    List<ErrorCodeBO> convertList(List<ErrorCodeDO> list);
+
+    @Mapping(source = "records", target = "list")
+    PageResult<ErrorCodeBO> convertPage(IPage<ErrorCodeDO> page);
+
+    ErrorCodeDO convert(ErrorCodeUpdateBO bean);
+
+    ErrorCodeCreateBO convert(ErrorCodeCreateDTO bean);
+
+    ErrorCodeUpdateBO convert(ErrorCodeUpdateDTO bean);
+
+    ErrorCodeVO convert(ErrorCodeBO bean);
+
+    List<ErrorCodeVO> convertList02(List<ErrorCodeBO> list);
+
+    PageResult<ErrorCodeVO> convertPage(PageResult<ErrorCodeBO> page);
+
+    ErrorCodePageBO convert(ErrorCodePageDTO bean);
+
+    ErrorCodeDO convert(ErrorCodeAutoGenerateBO bean);
+
+    List<ErrorCodeAutoGenerateBO> convertList03(List<ErrorCodeAutoGenerateDTO> list);
+}

+ 45 - 0
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/errorcode/ErrorCodeDO.java

@@ -0,0 +1,45 @@
+package cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode;
+
+import cn.iocoder.dashboard.modules.system.enums.errorcode.ErrorCodeTypeEnum;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName(value = "system_error_code")
+@EqualsAndHashCode()
+@Accessors(chain = true)
+public class ErrorCodeDO {
+
+    /**
+     * 错误码编号
+     */
+    private Integer id;
+    /**
+     * 错误码编码
+     */
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    private String message;
+    /**
+     * 错误码类型
+     *
+     * 外键 {@link ErrorCodeTypeEnum}
+     */
+    private Integer type;
+    /**
+     * 错误码分组
+     *
+     * 一般情况下,可以采用应用名
+     */
+    @TableField("`group`") // 避免和数据库关键字冲突
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+}

+ 36 - 0
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/errorcode/ErrorCodeMapper.java

@@ -0,0 +1,36 @@
+package cn.iocoder.dashboard.modules.system.dal.mysql.errorcode;
+
+import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO;
+import cn.iocoder.dashboard.modules.system.service.errorcode.bo.ErrorCodePageBO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface ErrorCodeMapper extends BaseMapper<ErrorCodeDO> {
+    default IPage<ErrorCodeDO> selectPage(ErrorCodePageBO pageBO) {
+        return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()),
+                new QueryWrapperX<ErrorCodeDO>().likeIfPresent("`group`", pageBO.getGroup())
+                        .eqIfPresent("code", pageBO.getCode()).likeIfPresent("message", pageBO.getMessage()));
+    }
+
+    default List<ErrorCodeDO> selectListByCodes(Collection<Integer> codes) {
+        return selectList(new QueryWrapper<ErrorCodeDO>().in("code", codes));
+    }
+
+    default ErrorCodeDO selectByCode(Integer code) {
+        return selectOne(new QueryWrapper<ErrorCodeDO>().eq("code", code));
+    }
+
+    default List<ErrorCodeDO> selectListByGroup(String group, Date minUpdateTime) {
+        return selectList(new QueryWrapperX<ErrorCodeDO>().eq("`group`", group)
+                .gtIfPresent("update_time", minUpdateTime));
+    }
+}

+ 5 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java

@@ -75,4 +75,9 @@ public interface SysErrorCodeConstants {
     // ========== 文件 1002009000 ==========
     ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在");
 
+    // ========== 错误码模块 1002009000 ==========
+    ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002009000, "错误码不存在");
+    ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002009001, "已经存在编码为【{}}】的错误码");
+    ErrorCode ERROR_CAN_NOT_UPDATE_SYSTEM_TYPE_ERROR = new ErrorCode(1002004003, "不能修改类型为系统内置的错误码");
+
 }

+ 38 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/errorcode/ErrorCodeTypeEnum.java

@@ -0,0 +1,38 @@
+package cn.iocoder.dashboard.modules.system.enums.errorcode;
+
+import cn.iocoder.dashboard.common.core.IntArrayValuable;
+
+import java.util.Arrays;
+
+/**
+ * @author dylan
+ */
+
+public enum ErrorCodeTypeEnum implements IntArrayValuable {
+
+    /**
+     * 自动生成
+     */
+    AUTO_GENERATION(1),
+    /**
+     * 手动编辑
+     */
+    MANUAL_OPERATION(2);
+
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErrorCodeTypeEnum::getType).toArray();
+
+    private final Integer type;
+
+    ErrorCodeTypeEnum(Integer type) {
+        this.type = type;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+}

+ 183 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/ErrorCodeService.java

@@ -0,0 +1,183 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.modules.system.convert.errorcode.ErrorCodeConvert;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.errorcode.ErrorCodeDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.errorcode.ErrorCodeMapper;
+import cn.iocoder.dashboard.modules.system.enums.errorcode.ErrorCodeTypeEnum;
+import cn.iocoder.dashboard.modules.system.service.errorcode.bo.*;
+import cn.iocoder.dashboard.util.collection.CollectionUtils;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_DUPLICATE;
+import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.ERROR_CODE_NOT_EXISTS;
+
+/**
+ * 错误码 Service
+ */
+@Slf4j
+@Validated
+@Service
+public class ErrorCodeService {
+
+    @Autowired
+    ErrorCodeMapper errorCodeMapper;
+
+    /**
+     * 创建错误码
+     *
+     * @param createBO 创建错误码 BO
+     * @return 错误码
+     */
+    public ErrorCodeBO createErrorCode(@Valid ErrorCodeCreateBO createBO) {
+        checkDuplicateErrorCode(createBO.getCode(), null);
+        // 插入到数据库
+        ErrorCodeDO errorCodeDO = ErrorCodeConvert.INSTANCE.convert(createBO);
+        errorCodeMapper.insert(errorCodeDO);
+        // 返回
+        return ErrorCodeConvert.INSTANCE.convert(errorCodeDO);
+    }
+
+    /**
+     * 更新错误码
+     *
+     * @param updateBO 更新错误码 BO
+     */
+    public void updateErrorCode(@Valid ErrorCodeUpdateBO updateBO) {
+        checkDuplicateErrorCode(updateBO.getCode(), updateBO.getId());
+        // 校验更新的错误码是否存在
+        if (errorCodeMapper.selectById(updateBO.getId()) == null) {
+            throw ServiceExceptionUtil.exception(ERROR_CODE_NOT_EXISTS);
+        }
+        // 更新到数据库
+        ErrorCodeDO updateObject = ErrorCodeConvert.INSTANCE.convert(updateBO);
+        errorCodeMapper.updateById(updateObject);
+    }
+
+    @Transactional
+    public void autoGenerateErrorCodes(@Valid List<ErrorCodeAutoGenerateBO> autoGenerateBOs) {
+        if (CollUtil.isEmpty(autoGenerateBOs)) {
+            return;
+        }
+        List<ErrorCodeDO> errorCodeDOs = errorCodeMapper.selectListByCodes(
+                CollectionUtils.convertSet(autoGenerateBOs, ErrorCodeAutoGenerateBO::getCode));
+        Map<Integer, ErrorCodeDO> errorCodeDOMap = CollectionUtils.convertMap(errorCodeDOs, ErrorCodeDO::getCode);
+        // 遍历 autoGenerateBOs 数组,逐个插入或更新。考虑到每次量级不大,就不走批量了
+        autoGenerateBOs.forEach(autoGenerateBO -> {
+            ErrorCodeDO errorCodeDO = errorCodeDOMap.get(autoGenerateBO.getCode());
+            // 不存在,则进行新增
+            if (errorCodeDO == null) {
+                errorCodeDO = ErrorCodeConvert.INSTANCE.convert(autoGenerateBO)
+                        .setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType());
+                errorCodeMapper.insert(errorCodeDO);
+                return;
+            }
+            // 存在,则进行更新。更新有三个前置条件:
+            // 条件 1. 只更新自动生成的错误码,即 Type 为 ErrorCodeTypeEnum.AUTO_GENERATION
+            if (!ErrorCodeTypeEnum.AUTO_GENERATION.getType().equals(errorCodeDO.getType())) {
+                return;
+            }
+            // 条件 2. 分组 group 必须匹配,避免存在错误码冲突的情况
+            if (!autoGenerateBO.getGroup().equals(errorCodeDO.getGroup())) {
+                log.error("[autoGenerateErrorCodes][自动创建({}/{}) 错误码失败,数据库中已经存在({}/{})]",
+                        autoGenerateBO.getCode(), autoGenerateBO.getGroup(),
+                        errorCodeDO.getCode(), errorCodeDO.getGroup());
+                return;
+            }
+            // 条件 3. 错误提示语存在差异
+            if (autoGenerateBO.getMessage().equals(errorCodeDO.getMessage())) {
+                return;
+            }
+            // 最终匹配,进行更新
+            errorCodeMapper.updateById(new ErrorCodeDO().setId(errorCodeDO.getId()).setMessage(autoGenerateBO.getMessage()));
+        });
+    }
+
+    /**
+     * 删除错误码
+     *
+     * @param errorCodeId 错误码编号
+     */
+    public void deleteErrorCode(Integer errorCodeId) {
+        // 校验删除的错误码是否存在
+        if (errorCodeMapper.selectById(errorCodeId) == null) {
+            throw ServiceExceptionUtil.exception(ERROR_CODE_NOT_EXISTS);
+        }
+        // 标记删除
+        errorCodeMapper.deleteById(errorCodeId);
+    }
+
+    /**
+     * 获得错误码
+     *
+     * @param errorCodeId 错误码编号
+     * @return 错误码
+     */
+    public ErrorCodeBO getErrorCode(Integer errorCodeId) {
+        ErrorCodeDO errorCodeDO = errorCodeMapper.selectById(errorCodeId);
+        return ErrorCodeConvert.INSTANCE.convert(errorCodeDO);
+    }
+
+    /**
+     * 获得错误码列表
+     *
+     * @param errorCodeIds 错误码编号列表
+     * @return 错误码列表
+     */
+    public List<ErrorCodeBO> listErrorCodes(List<Integer> errorCodeIds) {
+        List<ErrorCodeDO> errorCodeDOs = errorCodeMapper.selectBatchIds(errorCodeIds);
+        return ErrorCodeConvert.INSTANCE.convertList(errorCodeDOs);
+    }
+
+    /**
+     * 获得错误码分页
+     *
+     * @param pageBO 错误码分页查询
+     * @return 错误码分页结果
+     */
+    public PageResult<ErrorCodeBO> pageErrorCode(ErrorCodePageBO pageBO) {
+        IPage<ErrorCodeDO> errorCodeDOPage = errorCodeMapper.selectPage(pageBO);
+        return ErrorCodeConvert.INSTANCE.convertPage(errorCodeDOPage);
+    }
+
+    /**
+     * 校验错误码的唯一字段是否重复
+     *
+     * 是否存在相同编码的错误码
+     *
+     * @param code 错误码编码
+     * @param id 错误码编号
+     */
+    private void checkDuplicateErrorCode(Integer code, Integer id) {
+        ErrorCodeDO errorCodeDO = errorCodeMapper.selectByCode(code);
+        if (errorCodeDO == null) {
+            return;
+        }
+        // 如果 id 为空,说明不用比较是否为相同 id 的错误码
+        if (id == null) {
+            throw ServiceExceptionUtil.exception(ERROR_CODE_DUPLICATE);
+        }
+        if (!errorCodeDO.getId().equals(id)) {
+            throw ServiceExceptionUtil.exception(ERROR_CODE_DUPLICATE);
+        }
+    }
+
+    public List<ErrorCodeBO> listErrorCodes(String group, Date minUpdateTime) {
+        List<ErrorCodeDO> errorCodeDOs = errorCodeMapper.selectListByGroup(group, minUpdateTime);
+        return ErrorCodeConvert.INSTANCE.convertList(errorCodeDOs);
+    }
+
+}
+

+ 33 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeAutoGenerateBO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 错误码自动生成 BO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeAutoGenerateBO implements Serializable {
+
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    @NotEmpty(message = "错误码错误提示不能为空")
+    private String message;
+    /**
+     * 错误码分组
+     */
+    @NotNull(message = "错误码分组不能为空")
+    private String group;
+
+}

+ 48 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeBO.java

@@ -0,0 +1,48 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 错误码 BO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeBO {
+
+    /**
+     * 错误码编号
+     */
+    private Integer id;
+    /**
+     * 错误码编码
+     */
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    private String message;
+    /**
+     * 错误码类型
+     */
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 最后更新时间
+     */
+    private Date updateTime;
+
+}

+ 36 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeCreateBO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Data
+@Accessors(chain = true)
+public class ErrorCodeCreateBO {
+
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    @NotEmpty(message = "错误码错误提示不能为空")
+    private String message;
+    /**
+     * 错误码类型
+     */
+    @NotNull(message = "错误码类型不能为空")
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+}

+ 29 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodePageBO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode.bo;
+
+import cn.iocoder.dashboard.common.pojo.PageParam;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 错误码分页 BO
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+public class ErrorCodePageBO extends PageParam {
+
+    /**
+     * 错误码编码
+     */
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    private String message;
+    /**
+     * 错误码分组
+     */
+    private String group;
+
+}

+ 45 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/errorcode/bo/ErrorCodeUpdateBO.java

@@ -0,0 +1,45 @@
+package cn.iocoder.dashboard.modules.system.service.errorcode.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 错误码更新 BO
+ */
+@Data
+@Accessors(chain = true)
+public class ErrorCodeUpdateBO {
+
+    /**
+     * 错误码编号
+     */
+    @NotNull(message = "错误码编号不能为空")
+    private Integer id;
+    /**
+     * 错误码编码
+     */
+    @NotNull(message = "错误码编码不能为空")
+    private Integer code;
+    /**
+     * 错误码错误提示
+     */
+    @NotEmpty(message = "错误码错误提示不能为空")
+    private String message;
+    /**
+     * 错误码类型
+     */
+    @NotNull(message = "错误码类型不能为空")
+    private Integer type;
+    /**
+     * 错误码分组
+     */
+    private String group;
+    /**
+     * 错误码备注
+     */
+    private String memo;
+
+}