Browse Source

更新错误码等

luoguangyi 3 years ago
parent
commit
aba9109ab2
27 changed files with 1079 additions and 618 deletions
  1. 336 0
      Nacos.md
  2. 2 0
      README.md
  3. 2 0
      iot-admin-server/pom.xml
  4. 10 1
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/enums/DigitalDataCategory.java
  5. 284 0
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/enums/ErrorCodeEnum.java
  6. 35 7
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/ErrorCode.java
  7. 6 6
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/ServiceException.java
  8. 300 0
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/ErrorCodeConstants.java
  9. 0 43
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/GlobalErrorCodeConstants.java
  10. 0 34
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/ServiceErrorCodeRange.java
  11. 9 9
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/util/ServiceExceptionUtil.java
  12. 46 14
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/pojo/CommonResult.java
  13. 1 1
      iot-framework/iot-common/src/main/java/com/yushu/framework/common/util/date/DateUtils.java
  14. 4 4
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/RequestLogAspect.java
  15. 0 39
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/config/ApiLogAutoConfiguration.java
  16. 0 111
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/filter/ApiAccessLogFilter.java
  17. 0 23
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiAccessLogFrameworkService.java
  18. 0 23
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiErrorLogFrameworkService.java
  19. 0 35
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiLogServiceImpl.java
  20. 0 85
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/dto/ApiAccessLogCreateDTO.java
  21. 0 109
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/dto/ApiErrorLogCreateDTO.java
  22. 14 0
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/spring/config.java
  23. 2 2
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/filter/DemoFilter.java
  24. 19 69
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/handler/GlobalExceptionHandler.java
  25. 0 2
      iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/handler/GlobalResponseBodyHandler.java
  26. 1 0
      iot-framework/pom.xml
  27. 8 1
      pom.xml

File diff suppressed because it is too large
+ 336 - 0
Nacos.md


+ 2 - 0
README.md

@@ -13,3 +13,5 @@
 ### 延伸阅读
 
 * Java工程脚手架: https://start.aliyun.com
+
+

+ 2 - 0
iot-admin-server/pom.xml

@@ -95,6 +95,8 @@
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot-maven-plugin.version}</version>
+
                 <configuration>
                     <fork>true</fork>
                 </configuration>

+ 10 - 1
iot-framework/iot-common/src/main/java/com/yushu/framework/common/enums/DigitalDataCategory.java

@@ -1,14 +1,17 @@
 package com.yushu.framework.common.enums;
 
+import com.yushu.framework.common.core.ObjectArrayValuable;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * 数据分类
  * @author Charlie Yu
  * @date 2021-06-25
  */
 @Getter
-public enum DigitalDataCategory {
+public enum DigitalDataCategory implements ObjectArrayValuable {
     /** 数据类型 */
     STATIC("STATIC", "静态量"),
     PULSE("PULSE", "脉冲量"),
@@ -22,4 +25,10 @@ public enum DigitalDataCategory {
         this.index = index;
         this.name = name;
     }
+    public static final Object[] ARRAYS = Arrays.stream(values()).map(DigitalDataCategory::getIndex).toArray();
+
+    @Override
+    public Object[] array() {
+        return ARRAYS;
+    }
 }

+ 284 - 0
iot-framework/iot-common/src/main/java/com/yushu/framework/common/enums/ErrorCodeEnum.java

@@ -0,0 +1,284 @@
+package com.yushu.framework.common.enums;
+
+
+/**
+ * 阿里巴巴Java开发手册-崇山版-2020.08.03 错误码整理
+ * 错误码:
+ * 1. 五位组成
+ * 2. A代表用户端错误
+ * 3. B代表当前系统异常
+ * 4. C代表第三方服务异常
+ * 4. 若无法确定具体错误,选择宏观错误
+ * 6. 大的错误类间的步长间距预留100
+ */
+public enum ErrorCodeEnum {
+
+    /**
+     * 成功
+     */
+    SUCCESS("00000", "成功"),
+    /**
+     * 一级宏观错误码
+     */
+    USER_ERROR_0001("A0001", "用户端错误"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0100("A0100", "用户注册错误"),
+    USER_ERROR_A0101("A0101", "用户未同意隐私协议"),
+    USER_ERROR_A0102("A0102", "注册国家或地区受限"),
+    USER_ERROR_A0110("A0110", "用户名校验失败"),
+    USER_ERROR_A0111("A0111", "用户名已存在"),
+    USER_ERROR_A0112("A0112", "用户名包含敏感词"),
+    USER_ERROR_A0113("A0113", "用户名包含特殊字符"),
+    USER_ERROR_A0120("A0120", "密码校验失败"),
+    USER_ERROR_A0121("A0121", "密码长度不够"),
+    USER_ERROR_A0122("A0122", "密码强度不够"),
+    USER_ERROR_A0130("A0130", "校验码输入错误"),
+    USER_ERROR_A0131("A0131", "短信校验码输入错误"),
+    USER_ERROR_A0132("A0132", "邮件校验码输入错误"),
+    USER_ERROR_A0133("A0133", "语音校验码输入错误"),
+    USER_ERROR_A0140("A0140", "用户证件异常"),
+    USER_ERROR_A0141("A0141", "用户证件类型未选择"),
+    USER_ERROR_A0142("A0142", "大陆身份证编号校验非法"),
+    USER_ERROR_A0143("A0143", "护照编号校验非法"),
+    USER_ERROR_A0144("A0144", "军官证编号校验非法"),
+    USER_ERROR_A0150("A0150", "用户基本信息校验失败"),
+    USER_ERROR_A0151("A0151", "手机格式校验失败"),
+    USER_ERROR_A0152("A0152", "地址格式校验失败"),
+    USER_ERROR_A0153("A0153", "邮箱格式校验失败"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0200("A0200", "用户登录异常"),
+    USER_ERROR_A0201("A0201", "用户账户不存在"),
+    USER_ERROR_A0202("A0202", "用户账户被冻结"),
+    USER_ERROR_A0203("A0203", "用户账户已作废"),
+    USER_ERROR_A0210("A0210", "用户密码错误"),
+    USER_ERROR_A0211("A0211", "用户输入密码错误次数超限"),
+    USER_ERROR_A0220("A0220", "用户身份校验失败"),
+    USER_ERROR_A0221("A0221", "用户指纹识别失败"),
+    USER_ERROR_A0222("A0222", "用户面容识别失败"),
+    USER_ERROR_A0223("A0223", "用户未获得第三方登录授权"),
+    USER_ERROR_A0230("A0230", "用户登录已过期"),
+    USER_ERROR_A0240("A0240", "用户验证码错误"),
+    USER_ERROR_A0241("A0241", "用户验证码尝试次数超限"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0300("A0300", "访问权限异常"),
+    USER_ERROR_A0301("A0301", "访问未授权"),
+    USER_ERROR_A0302("A0302", "正在授权中"),
+    USER_ERROR_A0303("A0303", "用户授权申请被拒绝"),
+    USER_ERROR_A0310("A0310", "因访问对象隐私设置被拦截"),
+    USER_ERROR_A0311("A0311", "授权已过期"),
+    USER_ERROR_A0312("A0312", "无权限使用 API"),
+    USER_ERROR_A0320("A0320", "用户访问被拦截"),
+    USER_ERROR_A0321("A0321", "黑名单用户"),
+    USER_ERROR_A0322("A0322", "账号被冻结"),
+    USER_ERROR_A0323("A0323", "非法 IP 地址"),
+    USER_ERROR_A0324("A0324", "网关访问受限"),
+    USER_ERROR_A0325("A0325", "地域黑名单"),
+    USER_ERROR_A0330("A0330", "服务已欠费"),
+    USER_ERROR_A0340("A0340", "用户签名异常"),
+    USER_ERROR_A0341("A0341", "RSA 签名错误"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0400("A0400", "用户请求参数错误"),
+    USER_ERROR_A0401("A0401", "包含非法恶意跳转链接"),
+    USER_ERROR_A0402("A0402", "无效的用户输入"),
+    USER_ERROR_A0405("A0405", "请求方法不正确"),
+    USER_ERROR_A0410("A0410", "请求必填参数为空"),
+    USER_ERROR_A0411("A0411", "用户订单号为空"),
+    USER_ERROR_A0412("A0412", "订购数量为空"),
+    USER_ERROR_A0413("A0413", "缺少时间戳参数"),
+    USER_ERROR_A0414("A0414", "非法的时间戳参数"),
+    USER_ERROR_A0420("A0420", "请求参数值超出允许的范围"),
+    USER_ERROR_A0421("A0421", "参数格式不匹配"),
+    USER_ERROR_A0422("A0422", "地址不在服务范围"),
+    USER_ERROR_A0423("A0423", "时间不在服务范围"),
+    USER_ERROR_A0424("A0424", "金额超出限制"),
+    USER_ERROR_A0425("A0425", "数量超出限制"),
+    USER_ERROR_A0426("A0426", "请求批量处理总个数超出限制"),
+    USER_ERROR_A0427("A0427", "请求 JSON 解析失败"),
+    USER_ERROR_A0430("A0430", "用户输入内容非法"),
+    USER_ERROR_A0431("A0431", "包含违禁敏感词"),
+    USER_ERROR_A0432("A0432", "图片包含违禁信息"),
+    USER_ERROR_A0433("A0433", "文件侵犯版权"),
+    USER_ERROR_A0440("A0440", "用户操作异常"),
+    USER_ERROR_A0441("A0441", "用户支付超时"),
+    USER_ERROR_A0442("A0442", "确认订单超时"),
+    USER_ERROR_A0443("A0443", "订单已关闭"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0500("A0500", "用户请求服务异常"),
+    USER_ERROR_A0501("A0501", "请求次数超出限制"),
+    USER_ERROR_A0502("A0502", "请求并发数超出限制"),
+    USER_ERROR_A0503("A0503", "用户操作请等待"),
+    USER_ERROR_A0504("A0504", "WebSocket 连接异常"),
+    USER_ERROR_A0505("A0505", "WebSocket 连接断开"),
+    USER_ERROR_A0506("A0506", "用户重复请求"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0600("A0600", "用户资源异常"),
+    USER_ERROR_A0601("A0601", "账户余额不足"),
+    USER_ERROR_A0602("A0602", "用户磁盘空间不足"),
+    USER_ERROR_A0603("A0603", "用户内存空间不足"),
+    USER_ERROR_A0604("A0604", "用户 OSS 容量不足"),
+    /**
+     * 例如:每天抽奖数
+     */
+    USER_ERROR_A0605("A0605", "用户配额已用光"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0700("A0700", "用户上传文件异常"),
+    USER_ERROR_A0701("A0701", "用户上传文件类型不匹配"),
+    USER_ERROR_A0702("A0702", "用户上传文件太大"),
+    USER_ERROR_A0703("A0703", "用户上传图片太大"),
+    USER_ERROR_A0704("A0704", "用户上传视频太大"),
+    USER_ERROR_A0705("A0705", "用户上传压缩文件太大"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0800("A0800", "用户当前版本异常"),
+    USER_ERROR_A0801("A0801", "用户安装版本与系统不匹配"),
+    USER_ERROR_A0802("A0802", "用户安装版本过低"),
+    USER_ERROR_A0803("A0803", "用户安装版本过高"),
+    USER_ERROR_A0804("A0804", "用户安装版本已过期"),
+    USER_ERROR_A0805("A0805", "用户 API 请求版本不匹配"),
+    USER_ERROR_A0806("A0806", "用户 API 请求版本过高"),
+    USER_ERROR_A0807("A0807", "用户 API 请求版本过低"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A0900("A0900", "用户隐私未授权"),
+    USER_ERROR_A0901("A0901", "用户隐私未签署"),
+    USER_ERROR_A0902("A0902", "用户摄像头未授权"),
+    USER_ERROR_A0903("A0903", "用户相机未授权"),
+    USER_ERROR_A0904("A0904", "用户图片库未授权"),
+    USER_ERROR_A0905("A0905", "用户文件未授权"),
+    USER_ERROR_A0906("A0906", "用户位置信息未授权"),
+    USER_ERROR_A0907("A0907", "用户通讯录未授权"),
+    /**
+     * 二级宏观错误码
+     */
+    USER_ERROR_A1000("A1000", "用户设备异常"),
+    USER_ERROR_A1001("A1001", "用户相机异常"),
+    USER_ERROR_A1002("A1002", "用户麦克风异常"),
+    USER_ERROR_A1003("A1003", "用户听筒异常"),
+    USER_ERROR_A1004("A1004", "用户扬声器异常"),
+    USER_ERROR_A1005("A1005", "用户 GPS 定位异常"),
+
+
+    /**
+     * 系统异常
+     * 一级宏观错误码
+     */
+    SYSTEM_ERROR_B0001("B0001", "系统执行出错"),
+    /**
+     * 二级宏观错误码
+     */
+    SYSTEM_ERROR_B0100("B0100", "系统执行超时"),
+    SYSTEM_ERROR_B0101("B0101", "系统订单处理超时"),
+    /**
+     * 二级宏观错误码
+     */
+    SYSTEM_ERROR_B0200("B0200", "系统容灾功能被触发"),
+    SYSTEM_ERROR_B0210("B0210", "系统限流"),
+    SYSTEM_ERROR_B0220("B0220", "系统功能降级"),
+    /**
+     * 二级宏观错误码
+     */
+    SYSTEM_ERROR_B0300("B0300", "系统资源异常"),
+    SYSTEM_ERROR_B0310("B0310", "系统资源耗尽"),
+    SYSTEM_ERROR_B0311("B0311", "系统磁盘空间耗尽"),
+    SYSTEM_ERROR_B0312("B0312", "系统内存耗尽"),
+    SYSTEM_ERROR_B0313("B0313", "文件句柄耗尽"),
+    SYSTEM_ERROR_B0314("B0314", "系统连接池耗尽"),
+    SYSTEM_ERROR_B0315("B0315", "系统线程池耗尽"),
+    SYSTEM_ERROR_B0320("B0320", "系统资源访问异常"),
+    SYSTEM_ERROR_B0321("B0321", "系统读取磁盘文件失败"),
+
+
+    /**
+     * 调用第三方服务
+     * 一级宏观错误码
+     */
+    SERVICE_ERROR_C0001("C0001", "调用第三方服务出错"),
+    /**
+     * 二级宏观错误码
+     */
+    SERVICE_ERROR_C0100("C0100", "中间件服务出错"),
+    SERVICE_ERROR_C0110("C0110", "RPC 服务出错"),
+    SERVICE_ERROR_C0111("C0111", "RPC 服务未找到"),
+    SERVICE_ERROR_C0112("C0112", "RPC 服务未注册"),
+    SERVICE_ERROR_C0113("C0113", "接口不存在"),
+    SERVICE_ERROR_C0120("C0120", "消息服务出错"),
+    SERVICE_ERROR_C0121("C0121", "消息投递出错"),
+    SERVICE_ERROR_C0122("C0122", "消息消费出错"),
+    SERVICE_ERROR_C0123("C0123", "消息订阅出错"),
+    SERVICE_ERROR_C0124("C0124", "消息分组未查到"),
+    SERVICE_ERROR_C0130("C0130", "缓存服务出错"),
+    SERVICE_ERROR_C0131("C0131", "key 长度超过限制"),
+    SERVICE_ERROR_C0132("C0132", "value 长度超过限制"),
+    SERVICE_ERROR_C0133("C0133", "存储容量已满"),
+    SERVICE_ERROR_C0134("C0134", "不支持的数据格式"),
+    SERVICE_ERROR_C0140("C0140", "配置服务出错"),
+    SERVICE_ERROR_C0150("C0150", "网络资源服务出错"),
+    SERVICE_ERROR_C0151("C0151", "VPN 服务出错"),
+    SERVICE_ERROR_C0152("C0152", "CDN 服务出错"),
+    SERVICE_ERROR_C0153("C0153", "域名解析服务出错"),
+    SERVICE_ERROR_C0154("C0154", "网关服务出错"),
+    /**
+     * 二级宏观错误码
+     */
+    SERVICE_ERROR_C0200("C0200", "第三方系统执行超时"),
+    SERVICE_ERROR_C0210("C0210", "RPC 执行超时"),
+    SERVICE_ERROR_C0220("C0220", "消息投递超时"),
+    SERVICE_ERROR_C0230("C0230", "缓存服务超时"),
+    SERVICE_ERROR_C0240("C0240", "配置服务超时"),
+    SERVICE_ERROR_C0250("C0250", "数据库服务超时"),
+    /**
+     * 二级宏观错误码
+     */
+    SERVICE_ERROR_C0300("C0300", "数据库服务出错"),
+    SERVICE_ERROR_C0311("C0311", "表不存在"),
+    SERVICE_ERROR_C0312("C0312", "列不存在"),
+    SERVICE_ERROR_C0321("C0321", "多表关联中存在多个相同名称的列"),
+    SERVICE_ERROR_C0331("C0331", "数据库死锁"),
+    SERVICE_ERROR_C0341("C0341", "主键冲突"),
+    /**
+     * 二级宏观错误码
+     */
+    SERVICE_ERROR_C0400("C0400", "第三方容灾系统被触发"),
+    SERVICE_ERROR_C0401("C0401", "第三方系统限流"),
+    SERVICE_ERROR_C0402("C0402", "第三方功能降级"),
+    /**
+     * 二级宏观错误码
+     */
+    SERVICE_ERROR_C0500("C0500", "通知服务出错"),
+    SERVICE_ERROR_C0501("C0501", "短信提醒服务失败"),
+    SERVICE_ERROR_C0502("C0502", "语音提醒服务失败"),
+    SERVICE_ERROR_C0503("C0503", "邮件提醒服务失败");
+
+    private final String code;
+
+    private final String description;
+
+    private ErrorCodeEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 35 - 7
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/ErrorCode.java

@@ -1,32 +1,60 @@
 package com.yushu.framework.common.exception;
 
-import com.yushu.framework.common.exception.enums.GlobalErrorCodeConstants;
-import com.yushu.framework.common.exception.enums.ServiceErrorCodeRange;
+import com.yushu.framework.common.exception.enums.ErrorCodeConstants;
 import lombok.Data;
 
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
 /**
  * 错误码对象
  * <p>
- * 全局错误码,占用 [0, 999], 参见 {@link GlobalErrorCodeConstants}
- * 业务异常错误码,占用 [1 000 000 000, +∞),参见 {@link ServiceErrorCodeRange}
+ * 全局错误码,参见 {@link ErrorCodeConstants}
+ * 错误码设计成对象的原因,为未来的 i18 国际化做准备
  * <p>
- * TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备
  */
 @Data
 public class ErrorCode {
-
+    /**
+     * 错误码的map
+     */
+    public static final ConcurrentMap<String, String> ERRORCODES = new ConcurrentHashMap<>(256);
     /**
      * 错误码
      */
-    private final Integer code;
+    private final String code;
     /**
      * 错误提示
      */
     private final String message;
 
     public ErrorCode(Integer code, String message) {
+        this.code = String.valueOf(code);
+        this.message = message;
+        ERRORCODES.put(this.code,this.message);
+    }
+
+    public ErrorCode(String code, String message) {
         this.code = code;
         this.message = message;
+        ERRORCODES.put(this.code,this.message);
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ErrorCode)) {
+            return false;
+        }
+        ErrorCode errorCode = (ErrorCode) o;
+        return code.equals(errorCode.code) && message.equals(errorCode.message);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(code, message);
+    }
 }

+ 6 - 6
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/ServiceException.java

@@ -1,6 +1,6 @@
 package com.yushu.framework.common.exception;
 
-import com.yushu.framework.common.exception.enums.ServiceErrorCodeRange;
+import com.yushu.framework.common.exception.enums.ErrorCodeConstants;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -14,9 +14,9 @@ public final class ServiceException extends RuntimeException {
     /**
      * 业务错误码
      *
-     * @see ServiceErrorCodeRange
+     * @see ErrorCodeConstants
      */
-    private Integer code;
+    private String code;
     /**
      * 错误提示
      */
@@ -33,16 +33,16 @@ public final class ServiceException extends RuntimeException {
         this.message = errorCode.getMessage();
     }
 
-    public ServiceException(Integer code, String message) {
+    public ServiceException(String code, String message) {
         this.code = code;
         this.message = message;
     }
 
-    public Integer getCode() {
+    public String getCode() {
         return code;
     }
 
-    public ServiceException setCode(Integer code) {
+    public ServiceException setCode(String code) {
         this.code = code;
         return this;
     }

+ 300 - 0
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/ErrorCodeConstants.java

@@ -0,0 +1,300 @@
+package com.yushu.framework.common.exception.enums;
+
+import com.yushu.framework.common.exception.ErrorCode;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 阿里巴巴Java开发手册-崇山版-2020.08.03 错误码整理
+ * 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
+ * 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
+ * 错误码:
+ * 1. 五位组成
+ * 2. A代表用户端错误
+ * 3. B代表当前系统异常
+ * 4. C代表第三方服务异常
+ * 4. 若无法确定具体错误,选择宏观错误
+ * 6. 大的错误类间的步长间距预留100
+ *  @author lgy
+ */
+public interface ErrorCodeConstants {
+
+
+    /**
+     * 成功
+     */
+    ErrorCode SUCCESS = new ErrorCode("00000", "成功");
+    /**
+     * 一级宏观错误码
+     */
+    ErrorCode USER_ERROR_0001 = new ErrorCode("A0001", "用户端错误");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0100 = new ErrorCode("A0100", "用户注册错误");
+    ErrorCode USER_ERROR_A0101 = new ErrorCode("A0101", "用户未同意隐私协议");
+    ErrorCode USER_ERROR_A0102 = new ErrorCode("A0102", "注册国家或地区受限");
+    ErrorCode USER_ERROR_A0110 = new ErrorCode("A0110", "用户名校验失败");
+    ErrorCode USER_ERROR_A0111 = new ErrorCode("A0111", "用户名已存在");
+    ErrorCode USER_ERROR_A0112 = new ErrorCode("A0112", "用户名包含敏感词");
+    ErrorCode USER_ERROR_A0113 = new ErrorCode("A0113", "用户名包含特殊字符");
+    ErrorCode USER_ERROR_A0120 = new ErrorCode("A0120", "密码校验失败");
+    ErrorCode USER_ERROR_A0121 = new ErrorCode("A0121", "密码长度不够");
+    ErrorCode USER_ERROR_A0122 = new ErrorCode("A0122", "密码强度不够");
+    ErrorCode USER_ERROR_A0130 = new ErrorCode("A0130", "校验码输入错误");
+    ErrorCode USER_ERROR_A0131 = new ErrorCode("A0131", "短信校验码输入错误");
+    ErrorCode USER_ERROR_A0132 = new ErrorCode("A0132", "邮件校验码输入错误");
+    ErrorCode USER_ERROR_A0133 = new ErrorCode("A0133", "语音校验码输入错误");
+    ErrorCode USER_ERROR_A0140 = new ErrorCode("A0140", "用户证件异常");
+    ErrorCode USER_ERROR_A0141 = new ErrorCode("A0141", "用户证件类型未选择");
+    ErrorCode USER_ERROR_A0142 = new ErrorCode("A0142", "大陆身份证编号校验非法");
+    ErrorCode USER_ERROR_A0143 = new ErrorCode("A0143", "护照编号校验非法");
+    ErrorCode USER_ERROR_A0144 = new ErrorCode("A0144", "军官证编号校验非法");
+    ErrorCode USER_ERROR_A0150 = new ErrorCode("A0150", "用户基本信息校验失败");
+    ErrorCode USER_ERROR_A0151 = new ErrorCode("A0151", "手机格式校验失败");
+    ErrorCode USER_ERROR_A0152 = new ErrorCode("A0152", "地址格式校验失败");
+    ErrorCode USER_ERROR_A0153 = new ErrorCode("A0153", "邮箱格式校验失败");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0200 = new ErrorCode("A0200", "用户登录异常");
+    ErrorCode USER_ERROR_A0201 = new ErrorCode("A0201", "用户账户不存在");
+    ErrorCode USER_ERROR_A0202 = new ErrorCode("A0202", "用户账户被冻结");
+    ErrorCode USER_ERROR_A0203 = new ErrorCode("A0203", "用户账户已作废");
+    ErrorCode USER_ERROR_A0210 = new ErrorCode("A0210", "用户密码错误");
+    ErrorCode USER_ERROR_A0211 = new ErrorCode("A0211", "用户输入密码错误次数超限");
+    ErrorCode USER_ERROR_A0220 = new ErrorCode("A0220", "用户身份校验失败");
+    ErrorCode USER_ERROR_A0221 = new ErrorCode("A0221", "用户指纹识别失败");
+    ErrorCode USER_ERROR_A0222 = new ErrorCode("A0222", "用户面容识别失败");
+    ErrorCode USER_ERROR_A0223 = new ErrorCode("A0223", "用户未获得第三方登录授权");
+    ErrorCode USER_ERROR_A0230 = new ErrorCode("A0230", "用户登录已过期");
+    ErrorCode USER_ERROR_A0240 = new ErrorCode("A0240", "用户验证码错误");
+    ErrorCode USER_ERROR_A0241 = new ErrorCode("A0241", "用户验证码尝试次数超限");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0300 = new ErrorCode("A0300", "访问权限异常");
+    ErrorCode USER_ERROR_A0301 = new ErrorCode("A0301", "访问未授权");
+    ErrorCode USER_ERROR_A0302 = new ErrorCode("A0302", "正在授权中");
+    ErrorCode USER_ERROR_A0303 = new ErrorCode("A0303", "用户授权申请被拒绝");
+    ErrorCode USER_ERROR_A0310 = new ErrorCode("A0310", "因访问对象隐私设置被拦截");
+    ErrorCode USER_ERROR_A0311 = new ErrorCode("A0311", "授权已过期");
+    ErrorCode USER_ERROR_A0312 = new ErrorCode("A0312", "无权限使用 API");
+    ErrorCode USER_ERROR_A0320 = new ErrorCode("A0320", "用户访问被拦截");
+    ErrorCode USER_ERROR_A0321 = new ErrorCode("A0321", "黑名单用户");
+    ErrorCode USER_ERROR_A0322 = new ErrorCode("A0322", "账号被冻结");
+    ErrorCode USER_ERROR_A0323 = new ErrorCode("A0323", "非法 IP 地址");
+    ErrorCode USER_ERROR_A0324 = new ErrorCode("A0324", "网关访问受限");
+    ErrorCode USER_ERROR_A0325 = new ErrorCode("A0325", "地域黑名单");
+    ErrorCode USER_ERROR_A0330 = new ErrorCode("A0330", "服务已欠费");
+    ErrorCode USER_ERROR_A0340 = new ErrorCode("A0340", "用户签名异常");
+    ErrorCode USER_ERROR_A0341 = new ErrorCode("A0341", "RSA 签名错误");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0400 = new ErrorCode("A0400", "用户请求参数错误");
+    ErrorCode USER_ERROR_A0405 = new ErrorCode("A0405", "请求方法不正确");
+    ErrorCode USER_ERROR_A0401 = new ErrorCode("A0401", "包含非法恶意跳转链接");
+    ErrorCode USER_ERROR_A0402 = new ErrorCode("A0402", "无效的用户输入");
+    ErrorCode USER_ERROR_A0410 = new ErrorCode("A0410", "请求必填参数为空");
+    ErrorCode USER_ERROR_A0411 = new ErrorCode("A0411", "用户订单号为空");
+    ErrorCode USER_ERROR_A0412 = new ErrorCode("A0412", "订购数量为空");
+    ErrorCode USER_ERROR_A0413 = new ErrorCode("A0413", "缺少时间戳参数");
+    ErrorCode USER_ERROR_A0414 = new ErrorCode("A0414", "非法的时间戳参数");
+    ErrorCode USER_ERROR_A0420 = new ErrorCode("A0420", "请求参数值超出允许的范围");
+    ErrorCode USER_ERROR_A0421 = new ErrorCode("A0421", "参数格式不匹配");
+    ErrorCode USER_ERROR_A0422 = new ErrorCode("A0422", "地址不在服务范围");
+    ErrorCode USER_ERROR_A0423 = new ErrorCode("A0423", "时间不在服务范围");
+    ErrorCode USER_ERROR_A0424 = new ErrorCode("A0424", "金额超出限制");
+    ErrorCode USER_ERROR_A0425 = new ErrorCode("A0425", "数量超出限制");
+    ErrorCode USER_ERROR_A0426 = new ErrorCode("A0426", "请求批量处理总个数超出限制");
+    ErrorCode USER_ERROR_A0427 = new ErrorCode("A0427", "请求 JSON 解析失败");
+    ErrorCode USER_ERROR_A0430 = new ErrorCode("A0430", "用户输入内容非法");
+    ErrorCode USER_ERROR_A0431 = new ErrorCode("A0431", "包含违禁敏感词");
+    ErrorCode USER_ERROR_A0432 = new ErrorCode("A0432", "图片包含违禁信息");
+    ErrorCode USER_ERROR_A0433 = new ErrorCode("A0433", "文件侵犯版权");
+    ErrorCode USER_ERROR_A0440 = new ErrorCode("A0440", "用户操作异常");
+    ErrorCode USER_ERROR_A0441 = new ErrorCode("A0441", "用户支付超时");
+    ErrorCode USER_ERROR_A0442 = new ErrorCode("A0442", "确认订单超时");
+    ErrorCode USER_ERROR_A0443 = new ErrorCode("A0443", "订单已关闭");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0500 = new ErrorCode("A0500", "用户请求服务异常");
+    ErrorCode USER_ERROR_A0501 = new ErrorCode("A0501", "请求次数超出限制");
+    ErrorCode USER_ERROR_A0502 = new ErrorCode("A0502", "请求并发数超出限制");
+    ErrorCode USER_ERROR_A0503 = new ErrorCode("A0503", "用户操作请等待");
+    ErrorCode USER_ERROR_A0504 = new ErrorCode("A0504", "WebSocket 连接异常");
+    ErrorCode USER_ERROR_A0505 = new ErrorCode("A0505", "WebSocket 连接断开");
+    ErrorCode USER_ERROR_A0506 = new ErrorCode("A0506", "用户重复请求");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0600 = new ErrorCode("A0600", "用户资源异常");
+    ErrorCode USER_ERROR_A0601 = new ErrorCode("A0601", "账户余额不足");
+    ErrorCode USER_ERROR_A0602 = new ErrorCode("A0602", "用户磁盘空间不足");
+    ErrorCode USER_ERROR_A0603 = new ErrorCode("A0603", "用户内存空间不足");
+    ErrorCode USER_ERROR_A0604 = new ErrorCode("A0604", "用户 OSS 容量不足");
+    /**
+     * 例如:每天抽奖数
+     */
+    ErrorCode USER_ERROR_A0605 = new ErrorCode("A0605", "用户配额已用光");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0700 = new ErrorCode("A0700", "用户上传文件异常");
+    ErrorCode USER_ERROR_A0701 = new ErrorCode("A0701", "用户上传文件类型不匹配");
+    ErrorCode USER_ERROR_A0702 = new ErrorCode("A0702", "用户上传文件太大");
+    ErrorCode USER_ERROR_A0703 = new ErrorCode("A0703", "用户上传图片太大");
+    ErrorCode USER_ERROR_A0704 = new ErrorCode("A0704", "用户上传视频太大");
+    ErrorCode USER_ERROR_A0705 = new ErrorCode("A0705", "用户上传压缩文件太大");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0800 = new ErrorCode("A0800", "用户当前版本异常");
+    ErrorCode USER_ERROR_A0801 = new ErrorCode("A0801", "用户安装版本与系统不匹配");
+    ErrorCode USER_ERROR_A0802 = new ErrorCode("A0802", "用户安装版本过低");
+    ErrorCode USER_ERROR_A0803 = new ErrorCode("A0803", "用户安装版本过高");
+    ErrorCode USER_ERROR_A0804 = new ErrorCode("A0804", "用户安装版本已过期");
+    ErrorCode USER_ERROR_A0805 = new ErrorCode("A0805", "用户 API 请求版本不匹配");
+    ErrorCode USER_ERROR_A0806 = new ErrorCode("A0806", "用户 API 请求版本过高");
+    ErrorCode USER_ERROR_A0807 = new ErrorCode("A0807", "用户 API 请求版本过低");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A0900 = new ErrorCode("A0900", "用户隐私未授权");
+    ErrorCode USER_ERROR_A0901 = new ErrorCode("A0901", "用户隐私未签署");
+    ErrorCode USER_ERROR_A0902 = new ErrorCode("A0902", "用户摄像头未授权");
+    ErrorCode USER_ERROR_A0903 = new ErrorCode("A0903", "用户相机未授权");
+    ErrorCode USER_ERROR_A0904 = new ErrorCode("A0904", "用户图片库未授权");
+    ErrorCode USER_ERROR_A0905 = new ErrorCode("A0905", "用户文件未授权");
+    ErrorCode USER_ERROR_A0906 = new ErrorCode("A0906", "用户位置信息未授权");
+    ErrorCode USER_ERROR_A0907 = new ErrorCode("A0907", "用户通讯录未授权");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode USER_ERROR_A1000 = new ErrorCode("A1000", "用户设备异常");
+    ErrorCode USER_ERROR_A1001 = new ErrorCode("A1001", "用户相机异常");
+    ErrorCode USER_ERROR_A1002 = new ErrorCode("A1002", "用户麦克风异常");
+    ErrorCode USER_ERROR_A1003 = new ErrorCode("A1003", "用户听筒异常");
+    ErrorCode USER_ERROR_A1004 = new ErrorCode("A1004", "用户扬声器异常");
+    ErrorCode USER_ERROR_A1005 = new ErrorCode("A1005", "用户 GPS 定位异常");
+
+
+    /**
+     * 系统异常
+     * 一级宏观错误码
+     */
+    ErrorCode SYSTEM_ERROR_B0001 = new ErrorCode("B0001", "系统执行出错");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SYSTEM_ERROR_B0100 = new ErrorCode("B0100", "系统执行超时");
+    ErrorCode SYSTEM_ERROR_B0101 = new ErrorCode("B0101", "系统订单处理超时");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SYSTEM_ERROR_B0200 = new ErrorCode("B0200", "系统容灾功能被触发");
+    ErrorCode SYSTEM_ERROR_B0210 = new ErrorCode("B0210", "系统限流");
+    ErrorCode SYSTEM_ERROR_B0220 = new ErrorCode("B0220", "系统功能降级");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SYSTEM_ERROR_B0300 = new ErrorCode("B0300", "系统资源异常");
+    ErrorCode SYSTEM_ERROR_B0310 = new ErrorCode("B0310", "系统资源耗尽");
+    ErrorCode SYSTEM_ERROR_B0311 = new ErrorCode("B0311", "系统磁盘空间耗尽");
+    ErrorCode SYSTEM_ERROR_B0312 = new ErrorCode("B0312", "系统内存耗尽");
+    ErrorCode SYSTEM_ERROR_B0313 = new ErrorCode("B0313", "文件句柄耗尽");
+    ErrorCode SYSTEM_ERROR_B0314 = new ErrorCode("B0314", "系统连接池耗尽");
+    ErrorCode SYSTEM_ERROR_B0315 = new ErrorCode("B0315", "系统线程池耗尽");
+    ErrorCode SYSTEM_ERROR_B0320 = new ErrorCode("B0320", "系统资源访问异常");
+    ErrorCode SYSTEM_ERROR_B0321 = new ErrorCode("B0321", "系统读取磁盘文件失败");
+
+
+    /**
+     * 调用第三方服务
+     * 一级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0001 = new ErrorCode("C0001", "调用第三方服务出错");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0100 = new ErrorCode("C0100", "中间件服务出错");
+    ErrorCode SERVICE_ERROR_C0110 = new ErrorCode("C0110", "RPC 服务出错");
+    ErrorCode SERVICE_ERROR_C0111 = new ErrorCode("C0111", "RPC 服务未找到");
+    ErrorCode SERVICE_ERROR_C0112 = new ErrorCode("C0112", "RPC 服务未注册");
+    ErrorCode SERVICE_ERROR_C0113 = new ErrorCode("C0113", "接口不存在");
+    ErrorCode SERVICE_ERROR_C0120 = new ErrorCode("C0120", "消息服务出错");
+    ErrorCode SERVICE_ERROR_C0121 = new ErrorCode("C0121", "消息投递出错");
+    ErrorCode SERVICE_ERROR_C0122 = new ErrorCode("C0122", "消息消费出错");
+    ErrorCode SERVICE_ERROR_C0123 = new ErrorCode("C0123", "消息订阅出错");
+    ErrorCode SERVICE_ERROR_C0124 = new ErrorCode("C0124", "消息分组未查到");
+    ErrorCode SERVICE_ERROR_C0130 = new ErrorCode("C0130", "缓存服务出错");
+    ErrorCode SERVICE_ERROR_C0131 = new ErrorCode("C0131", "key 长度超过限制");
+    ErrorCode SERVICE_ERROR_C0132 = new ErrorCode("C0132", "value 长度超过限制");
+    ErrorCode SERVICE_ERROR_C0133 = new ErrorCode("C0133", "存储容量已满");
+    ErrorCode SERVICE_ERROR_C0134 = new ErrorCode("C0134", "不支持的数据格式");
+    ErrorCode SERVICE_ERROR_C0140 = new ErrorCode("C0140", "配置服务出错");
+    ErrorCode SERVICE_ERROR_C0150 = new ErrorCode("C0150", "网络资源服务出错");
+    ErrorCode SERVICE_ERROR_C0151 = new ErrorCode("C0151", "VPN 服务出错");
+    ErrorCode SERVICE_ERROR_C0152 = new ErrorCode("C0152", "CDN 服务出错");
+    ErrorCode SERVICE_ERROR_C0153 = new ErrorCode("C0153", "域名解析服务出错");
+    ErrorCode SERVICE_ERROR_C0154 = new ErrorCode("C0154", "网关服务出错");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0200 = new ErrorCode("C0200", "第三方系统执行超时");
+    ErrorCode SERVICE_ERROR_C0210 = new ErrorCode("C0210", "RPC 执行超时");
+    ErrorCode SERVICE_ERROR_C0220 = new ErrorCode("C0220", "消息投递超时");
+    ErrorCode SERVICE_ERROR_C0230 = new ErrorCode("C0230", "缓存服务超时");
+    ErrorCode SERVICE_ERROR_C0240 = new ErrorCode("C0240", "配置服务超时");
+    ErrorCode SERVICE_ERROR_C0250 = new ErrorCode("C0250", "数据库服务超时");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0300 = new ErrorCode("C0300", "数据库服务出错");
+    ErrorCode SERVICE_ERROR_C0311 = new ErrorCode("C0311", "表不存在");
+    ErrorCode SERVICE_ERROR_C0312 = new ErrorCode("C0312", "列不存在");
+    ErrorCode SERVICE_ERROR_C0321 = new ErrorCode("C0321", "多表关联中存在多个相同名称的列");
+    ErrorCode SERVICE_ERROR_C0331 = new ErrorCode("C0331", "数据库死锁");
+    ErrorCode SERVICE_ERROR_C0341 = new ErrorCode("C0341", "主键冲突");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0400 = new ErrorCode("C0400", "第三方容灾系统被触发");
+    ErrorCode SERVICE_ERROR_C0401 = new ErrorCode("C0401", "第三方系统限流");
+    ErrorCode SERVICE_ERROR_C0402 = new ErrorCode("C0402", "第三方功能降级");
+    /**
+     * 二级宏观错误码
+     */
+    ErrorCode SERVICE_ERROR_C0500 = new ErrorCode("C0500", "通知服务出错");
+    ErrorCode SERVICE_ERROR_C0501 = new ErrorCode("C0501", "短信提醒服务失败");
+    ErrorCode SERVICE_ERROR_C0502 = new ErrorCode("C0502", "语音提醒服务失败");
+    ErrorCode SERVICE_ERROR_C0503 = new ErrorCode("C0503", "邮件提醒服务失败");
+    
+//
+//    // ========== 客户端错误段 ==========
+//
+//    ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
+//    ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
+//    ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
+
+//    ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
+
+//    ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
+//    ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
+//    ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
+//
+//    // ========== 服务端错误段 ==========
+//
+//    ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
+//
+//    // ========== 自定义错误段 ==========
+//    ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
+//    ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
+//
+//    ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
+
+
+}

+ 0 - 43
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/GlobalErrorCodeConstants.java

@@ -1,43 +0,0 @@
-package com.yushu.framework.common.exception.enums;
-
-import com.yushu.framework.common.exception.ErrorCode;
-
-/**
- * 全局错误码枚举
- * 0-999 系统异常编码保留
- * <p>
- * 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
- * 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
- *
- * @author
- */
-public interface GlobalErrorCodeConstants {
-
-    ErrorCode SUCCESS = new ErrorCode(200, "成功");
-
-    // ========== 客户端错误段 ==========
-
-    ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
-    ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
-    ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
-    ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
-    ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
-    ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
-    ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
-
-    // ========== 服务端错误段 ==========
-
-    ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
-
-    // ========== 自定义错误段 ==========
-    ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
-    ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
-
-    ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
-
-    static boolean isMatch(Integer code) {
-        return code != null
-                && code >= SUCCESS.getCode() && code <= UNKNOWN.getCode();
-    }
-
-}

+ 0 - 34
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/enums/ServiceErrorCodeRange.java

@@ -1,34 +0,0 @@
-package com.yushu.framework.common.exception.enums;
-
-/**
- * 业务异常的错误码区间,解决:解决各模块错误码定义,避免重复,在此只声明不做实际使用
- * <p>
- * 一共 10 位,分成四段
- * <p>
- * 第一段,1 位,类型
- * 1 - 业务级别异常
- * x - 预留
- * 第二段,3 位,系统类型
- * 001 - 用户系统
- * 002 - 商品系统
- * 003 - 订单系统
- * 004 - 支付系统
- * 005 - 优惠劵系统
- * ... - ...
- * 第三段,3 位,模块
- * 不限制规则。
- * 一般建议,每个系统里面,可能有多个模块,可以再去做分段。以用户系统为例子:
- * 001 - OAuth2 模块
- * 002 - User 模块
- * 003 - MobileCode 模块
- * 第四段,3 位,错误码
- * 不限制规则。
- * 一般建议,每个模块自增。
- *
- * @author
- */
-public class ServiceErrorCodeRange {
-
-    // 模块 system 错误码区间 [1-000-001-000 ~ 1-000-002-000]
-
-}

+ 9 - 9
iot-framework/iot-common/src/main/java/com/yushu/framework/common/exception/util/ServiceExceptionUtil.java

@@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentMap;
  * {@link ServiceException} 工具类
  * <p>
  * 目的在于,格式化异常信息提示。
- * 考虑到 String.format 在参数不正确时会报错,因此使用 {} 作为占位符,并使用 {@link #doFormat(int, String, Object...)} 方法来格式化
+ * 考虑到 String.format 在参数不正确时会报错,因此使用 {} 作为占位符,并使用 {@link #doFormat(String, String, Object...)} 方法来格式化
  * <p>
  * 因为 {@link #MESSAGES} 里面默认是没有异常信息提示的模板的,所以需要使用方自己初始化进去。目前想到的有几种方式:
  * <p>
@@ -28,17 +28,17 @@ public class ServiceExceptionUtil {
     /**
      * 错误码提示模板
      */
-    private static final ConcurrentMap<Integer, String> MESSAGES = new ConcurrentHashMap<>();
+    private static final ConcurrentMap<String, String> MESSAGES = new ConcurrentHashMap<>();
 
-    public static void putAll(Map<Integer, String> messages) {
+    public static void putAll(Map<String, String> messages) {
         ServiceExceptionUtil.MESSAGES.putAll(messages);
     }
 
-    public static void put(Integer code, String message) {
+    public static void put(String code, String message) {
         ServiceExceptionUtil.MESSAGES.put(code, message);
     }
 
-    public static void delete(Integer code, String message) {
+    public static void delete(String code, String message) {
         ServiceExceptionUtil.MESSAGES.remove(code, message);
     }
 
@@ -60,7 +60,7 @@ public class ServiceExceptionUtil {
      * @param code 编号
      * @return 异常
      */
-    public static ServiceException exception(Integer code) {
+    public static ServiceException exception(String code) {
         return exception0(code, MESSAGES.get(code));
     }
 
@@ -71,11 +71,11 @@ public class ServiceExceptionUtil {
      * @param params 消息提示的占位符对应的参数
      * @return 异常
      */
-    public static ServiceException exception(Integer code, Object... params) {
+    public static ServiceException exception(String code, Object... params) {
         return exception0(code, MESSAGES.get(code), params);
     }
 
-    public static ServiceException exception0(Integer code, String messagePattern, Object... params) {
+    public static ServiceException exception0(String code, String messagePattern, Object... params) {
         String message = doFormat(code, messagePattern, params);
         return new ServiceException(code, message);
     }
@@ -91,7 +91,7 @@ public class ServiceExceptionUtil {
      * @return 格式化后的提示
      */
     @VisibleForTesting
-    public static String doFormat(int code, String messagePattern, Object... params) {
+    public static String doFormat(String code, String messagePattern, Object... params) {
         StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
         int i = 0;
         int j;

+ 46 - 14
iot-framework/iot-common/src/main/java/com/yushu/framework/common/pojo/CommonResult.java

@@ -5,7 +5,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.yushu.framework.common.exception.ErrorCode;
 import com.yushu.framework.common.exception.ServiceException;
-import com.yushu.framework.common.exception.enums.GlobalErrorCodeConstants;
+import com.yushu.framework.common.exception.enums.ErrorCodeConstants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -13,6 +15,7 @@ import org.springframework.util.Assert;
 
 import java.io.Serializable;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -23,7 +26,9 @@ import java.util.Objects;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
+@ApiModel(value="接口返回对象", description="接口返回对象")
 public class CommonResult<T> implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 成功
      */
@@ -38,16 +43,19 @@ public class CommonResult<T> implements Serializable {
      *
      * @see ErrorCode#getCode()
      */
+    @ApiModelProperty(value = "结果代码")
     @JsonInclude(JsonInclude.Include.NON_NULL)
-    private Integer code;
+    private String code;
     /**
      * success、fail
      */
+    @ApiModelProperty(value = "结果标识:成功标识:success,失败标识:fail")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private String result;
     /**
      * 返回数据
      */
+    @ApiModelProperty(value = "响应数据")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private T data;
     /**
@@ -55,18 +63,42 @@ public class CommonResult<T> implements Serializable {
      *
      * @see ErrorCode#getMessage() ()
      */
+    @ApiModelProperty(value = "错误提示信息")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private String message;
     /**
      * 返回记录条数或者操作记录条数
      */
+    @ApiModelProperty(value = "返回记录条数或者操作记录条数")
     @JsonInclude(JsonInclude.Include.NON_NULL)
-    private Long count;
+    private Integer count;
     /**
      * 记录总条数
      */
+    @ApiModelProperty(value = "记录总条数")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private Long total;
+    /**
+     * 时间戳
+     */
+    @ApiModelProperty(value = "响应时间戳")
+    private long timestamp = System.currentTimeMillis();
+
+    /**
+     * 附加数据
+     */
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @ApiModelProperty(value = "附加数据")
+    private Map<Object, Object> extra;
+
+    /**
+     * 系统报错时,抛出的原生信息
+     */
+    @ApiModelProperty(value = "异常消息")
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private String cause;
+
+
 
 
     /**
@@ -82,30 +114,32 @@ public class CommonResult<T> implements Serializable {
         return error(result.getCode(), result.getMessage());
     }
 
-    public static <T> CommonResult<T> error(Integer code, String message) {
-        Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
+    public static <T> CommonResult<T> error(String code, String message,String cause) {
+        Assert.isTrue(!ErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
         CommonResult<T> result = new CommonResult<>();
         result.code = code;
         result.message = message;
+        result.cause = cause;
         result.result = FAIL;
         return result;
     }
-
+    public static <T> CommonResult<T> error(String code, String message) {
+        return error(code,message,null);
+    }
     public static <T> CommonResult<T> error(ErrorCode errorCode) {
         return error(errorCode.getCode(), errorCode.getMessage());
     }
 
     public static <T> CommonResult<T> success(T data) {
         CommonResult<T> result = new CommonResult<>();
-        result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
+        result.code = ErrorCodeConstants.SUCCESS.getCode();
         result.data = data;
         result.result = SUCCESS;
-        result.message = "";
         return result;
     }
 
-    public static boolean isSuccess(Integer code) {
-        return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
+    public static boolean isSuccess(String code) {
+        return Objects.equals(code, ErrorCodeConstants.SUCCESS.getCode());
     }
 
     public static <T> CommonResult<T> error(ServiceException serviceException) {
@@ -120,11 +154,9 @@ public class CommonResult<T> implements Serializable {
      * @param <T>
      * @return
      */
-    public static <T> CommonResult<List<T>> multi(List<T> records, long total) {
-        // 容错处理,出现总数比实际数少时,以实际数为准(page查询全部时,total为0)
-        int size = CollUtil.size(records);
+    public static <T> CommonResult<List<T>> multi(List<T> records, Long total) {
         CommonResult<List<T>> result = success(records);
-        result.setCount(Long.valueOf(CollUtil.size(records)));
+        result.setCount(CollUtil.size(records));
         result.setTotal(total);
         return result;
     }

+ 1 - 1
iot-framework/iot-common/src/main/java/com/yushu/framework/common/util/date/DateUtils.java

@@ -144,7 +144,7 @@ public class DateUtils extends DatePattern {
         try {
             return simpleDateFormatThreadLocal.get().parse(dateStr);
         } catch (ParseException e) {
-            throw new ServiceException(500,dateStr+"格式错误");
+            throw new ServiceException("500",dateStr+"格式错误");
         }
         //return localDateTime2Date(LocalDateTime.parse(dateStr, PURE_DATETIME_FORMAT));
     }

+ 4 - 4
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/RequestLogAspect.java

@@ -3,9 +3,9 @@ package com.yushu.framework.apilog;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.servlet.ServletUtil;
-import com.alibaba.fastjson.JSON;
 import com.yushu.framework.apilog.serializer.JacksonJsonSerializer;
 import com.yushu.framework.apilog.serializer.SerializerWrapper;
+import com.yushu.framework.common.util.json.JsonUtils;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -95,7 +95,7 @@ public class RequestLogAspect {
         try {
             result = proceedingJoinPoint.proceed();
         } catch (Throwable th) {
-            log.warn("Request warn : {}", JSON.toJSONString(requestInfo), th);
+            log.warn("Request warn : {}", JsonUtils.toJsonString(requestInfo), th);
             throw th;
         }
         // 配置明确指定为 true,才使用全返回值
@@ -104,7 +104,7 @@ public class RequestLogAspect {
         //		requestInfo.setRequestParams(getRequestParamsByProceedingJoinPoint(proceedingJoinPoint));
         //		requestInfo.setResult(result);
         requestInfo.setTimeCost(System.currentTimeMillis() - start);
-        log.info("Request Info : {}", JSON.toJSONString(requestInfo));
+        log.info("Request Info : {}", JsonUtils.toJsonString(requestInfo));
         return result;
     }
 
@@ -120,7 +120,7 @@ public class RequestLogAspect {
         requestErrorInfo.setRequestParams(getRequestParamsByJoinPoint(joinPoint));
         requestErrorInfo.setException(e);
         requestErrorInfo.setStacktrace(ExceptionUtil.stacktraceToString(e).split("\r\n\t"));
-        log.error("Request Error : {}", JSON.toJSONString(requestErrorInfo));
+        log.error("Request Error : {}", JsonUtils.toJsonString(requestErrorInfo));
     }
 
     /**

+ 0 - 39
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/config/ApiLogAutoConfiguration.java

@@ -1,39 +0,0 @@
-package com.yushu.framework.apilog.config;
-
-import com.yushu.framework.apilog.core.filter.ApiAccessLogFilter;
-import com.yushu.framework.apilog.core.service.ApiAccessLogFrameworkService;
-import com.yushu.framework.common.test.WebFilterOrderEnum;
-import com.yushu.framework.web.config.WebAutoConfiguration;
-import com.yushu.framework.web.config.WebProperties;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import javax.servlet.Filter;
-
-@Configuration
-@AutoConfigureAfter(WebAutoConfiguration.class)
-@ConditionalOnProperty(prefix = "api.access.log.filter", name = "enable", havingValue = "true", matchIfMissing = false)
-public class ApiLogAutoConfiguration {
-
-    private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
-        FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
-        bean.setOrder(order);
-        return bean;
-    }
-
-    /**
-     * 创建 ApiAccessLogFilter Bean,记录 API 请求日志
-     */
-    @Bean
-    public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
-                                                                         @Value("${spring.application.name}") String applicationName,
-                                                                         ApiAccessLogFrameworkService apiAccessLogFrameworkService) {
-        ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, apiAccessLogFrameworkService);
-        return createFilterBean(filter, WebFilterOrderEnum.API_ACCESS_LOG_FILTER);
-    }
-
-}

+ 0 - 111
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/filter/ApiAccessLogFilter.java

@@ -1,111 +0,0 @@
-package com.yushu.framework.apilog.core.filter;
-
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.extra.servlet.ServletUtil;
-import com.yushu.framework.apilog.core.service.ApiAccessLogFrameworkService;
-import com.yushu.framework.apilog.core.service.dto.ApiAccessLogCreateDTO;
-import com.yushu.framework.common.exception.enums.GlobalErrorCodeConstants;
-import com.yushu.framework.common.pojo.CommonResult;
-import com.yushu.framework.common.util.date.DateUtils;
-import com.yushu.framework.common.util.json.JsonUtils;
-import com.yushu.framework.common.util.monitor.TracerUtils;
-import com.yushu.framework.common.util.servlet.ServletUtils;
-import com.yushu.framework.web.config.WebProperties;
-import com.yushu.framework.web.core.util.WebFrameworkUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Date;
-import java.util.Map;
-
-/**
- * API 访问日志 Filter
- *
- * @author
- */
-@RequiredArgsConstructor
-@Slf4j
-public class ApiAccessLogFilter extends OncePerRequestFilter {
-
-    private final WebProperties webProperties;
-    private final String applicationName;
-
-    private final ApiAccessLogFrameworkService apiAccessLogFrameworkService;
-
-    @Override
-    protected boolean shouldNotFilter(HttpServletRequest request) {
-        // 只过滤 API 请求的地址
-        return !request.getRequestURI().startsWith(webProperties.getApiPrefix());
-    }
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-            throws ServletException, IOException {
-        // 获得开始时间
-        Date beginTim = new Date();
-        // 提前获得参数,避免 XssFilter 过滤处理
-        Map<String, String> queryString = ServletUtil.getParamMap(request);
-        String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtil.getBody(request) : null;
-
-        try {
-            // 继续过滤器
-            filterChain.doFilter(request, response);
-            // 正常执行,记录日志
-            createApiAccessLog(request, beginTim, queryString, requestBody, null);
-        } catch (Exception ex) {
-            // 异常执行,记录日志
-            createApiAccessLog(request, beginTim, queryString, requestBody, ex);
-            throw ex;
-        }
-    }
-
-    private void createApiAccessLog(HttpServletRequest request, Date beginTime,
-                                    Map<String, String> queryString, String requestBody, Exception ex) {
-        ApiAccessLogCreateDTO accessLog = new ApiAccessLogCreateDTO();
-        try {
-            this.buildApiAccessLogDTO(accessLog, request, beginTime, queryString, requestBody, ex);
-            apiAccessLogFrameworkService.createApiAccessLogAsync(accessLog);
-        } catch (Throwable th) {
-            log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), JsonUtils.toJsonString(accessLog), th);
-        }
-    }
-
-    private void buildApiAccessLogDTO(ApiAccessLogCreateDTO accessLog, HttpServletRequest request, Date beginTime,
-                                      Map<String, String> queryString, String requestBody, Exception ex) {
-        // 处理用户信息
-        accessLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
-        // 设置访问结果
-        CommonResult<?> result = WebFrameworkUtils.getCommonResult(request);
-        if (result != null) {
-            accessLog.setResultCode(result.getCode());
-            accessLog.setResultMsg(result.getMessage());
-        } else if (ex != null) {
-            accessLog.setResultCode(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode());
-            accessLog.setResultMsg(ExceptionUtil.getRootCauseMessage(ex));
-        } else {
-            accessLog.setResultCode(0);
-            accessLog.setResultMsg("");
-        }
-        // 设置其它字段
-        accessLog.setTraceId(TracerUtils.getTraceId());
-        accessLog.setApplicationName(applicationName);
-        accessLog.setRequestUrl(request.getRequestURI());
-        Map<String, Object> requestParams = MapUtil.<String, Object>builder().put("query", queryString).put("body", requestBody).build();
-        accessLog.setRequestParams(JsonUtils.toJsonString(requestParams));
-        accessLog.setRequestMethod(request.getMethod());
-        accessLog.setUserAgent(ServletUtils.getUserAgent(request));
-        accessLog.setUserIp(ServletUtil.getClientIP(request));
-        // 持续时间
-        accessLog.setBeginTime(beginTime);
-        accessLog.setEndTime(new Date());
-        accessLog.setDuration((int) DateUtils.diff(accessLog.getEndTime(), accessLog.getBeginTime()));
-    }
-
-}

+ 0 - 23
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiAccessLogFrameworkService.java

@@ -1,23 +0,0 @@
-package com.yushu.framework.apilog.core.service;
-
-import com.yushu.framework.apilog.core.service.dto.ApiAccessLogCreateDTO;
-
-import javax.validation.Valid;
-import java.util.concurrent.Future;
-
-/**
- * API 访问日志 Framework Service 接口
- *
- * @author
- */
-public interface ApiAccessLogFrameworkService {
-
-    /**
-     * 创建 API 访问日志
-     *
-     * @param createDTO 创建信息
-     * @return 是否创建成功
-     */
-    Future<Boolean> createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO);
-
-}

+ 0 - 23
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiErrorLogFrameworkService.java

@@ -1,23 +0,0 @@
-package com.yushu.framework.apilog.core.service;
-
-import com.yushu.framework.apilog.core.service.dto.ApiErrorLogCreateDTO;
-
-import javax.validation.Valid;
-import java.util.concurrent.Future;
-
-/**
- * API 错误日志 Framework Service 接口
- *
- * @author
- */
-public interface ApiErrorLogFrameworkService {
-
-    /**
-     * 创建 API 错误日志
-     *
-     * @param createDTO 创建信息
-     * @return 是否创建成功
-     */
-    Future<Boolean> createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO);
-
-}

+ 0 - 35
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/ApiLogServiceImpl.java

@@ -1,35 +0,0 @@
-package com.yushu.framework.apilog.core.service;
-
-import com.yushu.framework.apilog.core.service.dto.ApiAccessLogCreateDTO;
-import com.yushu.framework.apilog.core.service.dto.ApiErrorLogCreateDTO;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.AsyncResult;
-import org.springframework.stereotype.Service;
-import org.springframework.validation.annotation.Validated;
-
-import java.util.concurrent.Future;
-
-/**
- * API 访问日志 Service 实现类
- *
- * @author
- */
-@Service
-@Validated
-@Slf4j
-public class ApiLogServiceImpl implements ApiAccessLogFrameworkService, ApiErrorLogFrameworkService {
-
-    @Async
-    @Override
-    public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) {
-        log.info("访问日志:{}", createDTO);
-        return new AsyncResult<>(true);
-    }
-
-    @Override
-    public Future<Boolean> createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) {
-        log.error("错误日志:{}", createDTO);
-        return new AsyncResult<>(true);
-    }
-}

+ 0 - 85
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/dto/ApiAccessLogCreateDTO.java

@@ -1,85 +0,0 @@
-package com.yushu.framework.apilog.core.service.dto;
-
-import lombok.Data;
-
-import javax.validation.constraints.NotNull;
-import java.util.Date;
-
-/**
- * API 访问日志创建 DTO
- *
- * @author
- */
-@Data
-public class ApiAccessLogCreateDTO {
-
-    /**
-     * 链路追踪编号
-     */
-    private String traceId;
-    /**
-     * 用户编号
-     */
-    private Long userId;
-    /**
-     * 用户类型
-     */
-    private Integer userType;
-    /**
-     * 应用名
-     */
-    @NotNull(message = "应用名不能为空")
-    private String applicationName;
-
-    /**
-     * 请求方法名
-     */
-    @NotNull(message = "http 请求方法不能为空")
-    private String requestMethod;
-    /**
-     * 访问地址
-     */
-    @NotNull(message = "访问地址不能为空")
-    private String requestUrl;
-    /**
-     * 请求参数
-     */
-    @NotNull(message = "请求参数不能为空")
-    private String requestParams;
-    /**
-     * 用户 IP
-     */
-    @NotNull(message = "ip 不能为空")
-    private String userIp;
-    /**
-     * 浏览器 UA
-     */
-    @NotNull(message = "User-Agent 不能为空")
-    private String userAgent;
-
-    /**
-     * 开始请求时间
-     */
-    @NotNull(message = "开始请求时间不能为空")
-    private Date beginTime;
-    /**
-     * 结束请求时间
-     */
-    @NotNull(message = "结束请求时间不能为空")
-    private Date endTime;
-    /**
-     * 执行时长,单位:毫秒
-     */
-    @NotNull(message = "执行时长不能为空")
-    private Integer duration;
-    /**
-     * 结果码
-     */
-    @NotNull(message = "错误码不能为空")
-    private Integer resultCode;
-    /**
-     * 结果提示
-     */
-    private String resultMsg;
-
-}

+ 0 - 109
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/apilog/core/service/dto/ApiErrorLogCreateDTO.java

@@ -1,109 +0,0 @@
-package com.yushu.framework.apilog.core.service.dto;
-
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * API 错误日志创建 DTO
- *
- * @author
- */
-@Data
-@Accessors(chain = true)
-public class ApiErrorLogCreateDTO implements Serializable {
-
-    /**
-     * 链路编号
-     */
-    private String traceId;
-    /**
-     * 账号编号
-     */
-    private Long userId;
-    /**
-     * 用户类型
-     */
-    private Integer userType;
-    /**
-     * 应用名
-     */
-    @NotNull(message = "应用名不能为空")
-    private String applicationName;
-
-    /**
-     * 请求方法名
-     */
-    @NotNull(message = "http 请求方法不能为空")
-    private String requestMethod;
-    /**
-     * 访问地址
-     */
-    @NotNull(message = "访问地址不能为空")
-    private String requestUrl;
-    /**
-     * 请求参数
-     */
-    @NotNull(message = "请求参数不能为空")
-    private String requestParams;
-    /**
-     * 用户 IP
-     */
-    @NotNull(message = "ip 不能为空")
-    private String userIp;
-    /**
-     * 浏览器 UA
-     */
-    @NotNull(message = "User-Agent 不能为空")
-    private String userAgent;
-
-    /**
-     * 异常时间
-     */
-    @NotNull(message = "异常时间不能为空")
-    private Date exceptionTime;
-    /**
-     * 异常名
-     */
-    @NotNull(message = "异常名不能为空")
-    private String exceptionName;
-    /**
-     * 异常发生的类全名
-     */
-    @NotNull(message = "异常发生的类全名不能为空")
-    private String exceptionClassName;
-    /**
-     * 异常发生的类文件
-     */
-    @NotNull(message = "异常发生的类文件不能为空")
-    private String exceptionFileName;
-    /**
-     * 异常发生的方法名
-     */
-    @NotNull(message = "异常发生的方法名不能为空")
-    private String exceptionMethodName;
-    /**
-     * 异常发生的方法所在行
-     */
-    @NotNull(message = "异常发生的方法所在行不能为空")
-    private Integer exceptionLineNumber;
-    /**
-     * 异常的栈轨迹异常的栈轨迹
-     */
-    @NotNull(message = "异常的栈轨迹不能为空")
-    private String exceptionStackTrace;
-    /**
-     * 异常导致的根消息
-     */
-    @NotNull(message = "异常导致的根消息不能为空")
-    private String exceptionRootCauseMessage;
-    /**
-     * 异常导致的消息
-     */
-    @NotNull(message = "异常导致的消息不能为空")
-    private String exceptionMessage;
-
-}

+ 14 - 0
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/spring/config.java

@@ -0,0 +1,14 @@
+package com.yushu.framework.spring;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @description:注册SpringUtil
+ * @author:lgy
+ * @data:2021/12/20 19:48
+ */
+@Import(cn.hutool.extra.spring.SpringUtil.class)
+@Configuration
+public class config {
+}

+ 2 - 2
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/filter/DemoFilter.java

@@ -10,7 +10,7 @@ import javax.servlet.FilterChain;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import static com.yushu.framework.common.exception.enums.GlobalErrorCodeConstants.DEMO_DENY;
+import static com.yushu.framework.common.exception.enums.ErrorCodeConstants.USER_ERROR_A0300;
 
 /**
  * 演示 Filter,禁止用户发起写操作,避免影响测试数据
@@ -29,7 +29,7 @@ public class DemoFilter extends OncePerRequestFilter {
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
         // 直接返回 DEMO_DENY 的结果。即,请求不继续
-        ServletUtils.writeJSON(response, CommonResult.error(DEMO_DENY));
+        ServletUtils.writeJSON(response, CommonResult.error(USER_ERROR_A0300));
     }
 
 }

+ 19 - 69
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/handler/GlobalExceptionHandler.java

@@ -1,24 +1,13 @@
 package com.yushu.framework.web.core.handler;
 
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.servlet.ServletUtil;
-import com.yushu.framework.apilog.core.service.ApiErrorLogFrameworkService;
-import com.yushu.framework.apilog.core.service.dto.ApiErrorLogCreateDTO;
 import com.yushu.framework.common.exception.ServiceException;
 import com.yushu.framework.common.pojo.CommonResult;
-import com.yushu.framework.common.util.json.JsonUtils;
-import com.yushu.framework.common.util.monitor.TracerUtils;
-import com.yushu.framework.common.util.servlet.ServletUtils;
-import com.yushu.framework.web.core.util.WebFrameworkUtils;
 import lombok.AllArgsConstructor;
 import lombok.NoArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.util.Assert;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.BindException;
 import org.springframework.validation.FieldError;
 import org.springframework.validation.ObjectError;
@@ -26,6 +15,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
 import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.MissingServletRequestParameterException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
 import org.springframework.web.servlet.NoHandlerFoundException;
@@ -35,11 +25,9 @@ import javax.validation.ConstraintViolation;
 import javax.validation.ConstraintViolationException;
 import javax.validation.ValidationException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
-import static com.yushu.framework.common.exception.enums.GlobalErrorCodeConstants.*;
+import static com.yushu.framework.common.exception.enums.ErrorCodeConstants.*;
 
 /**
  * 全局异常处理器,将 Exception 翻译成 CommonResult + 对应的异常编号
@@ -56,8 +44,6 @@ public class GlobalExceptionHandler {
      */
     @Value("${spring.application.name}")
     private String applicationName;
-    @Autowired
-    private ApiErrorLogFrameworkService apiErrorLogFrameworkService;
 
 
     /**
@@ -107,18 +93,18 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(value = MissingServletRequestParameterException.class)
     public CommonResult<?> missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException ex) {
         log.warn("[missingServletRequestParameterExceptionHandler]", ex);
-        return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数缺失:%s", ex.getParameterName()));
+        return CommonResult.error(USER_ERROR_A0410.getCode(), String.format("请求参数缺失:%s", ex.getParameterName()));
     }
 
     /**
      * 处理 SpringMVC 请求参数类型错误
      * <p>
-     * 例如说,接口上设置了 @RequestParam("xx") 参数为 Integer,结果传递 xx 参数类型为 String
+     * 例如说,接口上设置了 @RequestParam("xx") 参数为 String,结果传递 xx 参数类型为 String
      */
     @ExceptionHandler(MethodArgumentTypeMismatchException.class)
     public CommonResult<?> methodArgumentTypeMismatchExceptionHandler(MethodArgumentTypeMismatchException ex) {
         log.warn("[missingServletRequestParameterExceptionHandler]", ex);
-        return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", ex.getMessage()));
+        return CommonResult.error(USER_ERROR_A0421.getCode(), String.format("请求参数类型错误:%s", ex.getMessage()));
     }
 
     /**
@@ -139,7 +125,7 @@ public class GlobalExceptionHandler {
             }
         }
         String errMsg = StrUtil.join(";", errorArr.toArray(new String[]{}));
-        return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", errMsg));
+        return CommonResult.error(USER_ERROR_A0400.getCode(), String.format("请求参数不正确:%s", errMsg));
     }
 
     /**
@@ -150,7 +136,7 @@ public class GlobalExceptionHandler {
         log.warn("[handleBindException]", ex);
         FieldError fieldError = ex.getFieldError();
         assert fieldError != null; // 断言,避免告警
-        return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", fieldError.getDefaultMessage()));
+        return CommonResult.error(USER_ERROR_A0400.getCode(), String.format("请求参数不正确:%s", fieldError.getDefaultMessage()));
     }
 
     /**
@@ -166,7 +152,7 @@ public class GlobalExceptionHandler {
         }
         ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
         String errMsg = StrUtil.join(";", errorArr.toArray(new String[]{}));
-        return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", errMsg));
+        return CommonResult.error(USER_ERROR_A0400.getCode(), String.format("请求参数不正确:%s", errMsg));
     }
 
     /**
@@ -176,7 +162,7 @@ public class GlobalExceptionHandler {
     public CommonResult<?> validationException(ValidationException ex) {
         log.warn("[constraintViolationExceptionHandler]", ex);
         // 无法拼接明细的错误信息,因为 Dubbo Consumer 抛出 ValidationException 异常时,是直接的字符串信息,且人类不可读
-        return CommonResult.error(BAD_REQUEST);
+        return CommonResult.error(USER_ERROR_A0400);
     }
 
     /**
@@ -189,7 +175,7 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(NoHandlerFoundException.class)
     public CommonResult<?> noHandlerFoundExceptionHandler(NoHandlerFoundException ex) {
         log.warn("[noHandlerFoundExceptionHandler]", ex);
-        return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL()));
+        return CommonResult.error(SERVICE_ERROR_C0113.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL()));
     }
 
     /**
@@ -200,7 +186,7 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
     public CommonResult<?> httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException ex) {
         log.warn("[httpRequestMethodNotSupportedExceptionHandler]", ex);
-        return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
+        return CommonResult.error(USER_ERROR_A0405.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
     }
 
     /**
@@ -220,52 +206,16 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(value = Exception.class)
     public CommonResult<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
         log.error("[defaultExceptionHandler]", ex);
-        // 插入异常日志
-        this.createExceptionLog(req, ex);
         // 返回 ERROR CommonResult
-        return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMessage());
+        return CommonResult.error(SYSTEM_ERROR_B0001);
     }
 
-    private void createExceptionLog(HttpServletRequest req, Throwable e) {
-        // 插入错误日志
-        ApiErrorLogCreateDTO errorLog = new ApiErrorLogCreateDTO();
-        try {
-            // 初始化 errorLog
-            initExceptionLog(errorLog, req, e);
-            // 执行插入 errorLog
-            apiErrorLogFrameworkService.createApiErrorLogAsync(errorLog);
-        } catch (Throwable th) {
-            log.error("[createExceptionLog][url({}) log({}) 发生异常]", req.getRequestURI(), JsonUtils.toJsonString(errorLog), th);
-        }
-    }
+//    @ResponseStatus(HttpStatus.NOT_FOUND)
+//    @ExceptionHandler(Exception.class)
+//    public CommonResult<?> handle404(HttpServletRequest req, Throwable ex) {
+//        log.info("[serviceExceptionHandler]", ex);
+//        return CommonResult.error(SERVICE_ERROR_C0113);
+//    }
 
-    private void initExceptionLog(ApiErrorLogCreateDTO errorLog, HttpServletRequest request, Throwable e) {
-        // 处理用户信息
-        errorLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
-        // 设置异常字段
-        errorLog.setExceptionName(e.getClass().getName());
-        errorLog.setExceptionMessage(ExceptionUtil.getMessage(e));
-        errorLog.setExceptionRootCauseMessage(ExceptionUtil.getRootCauseMessage(e));
-        errorLog.setExceptionStackTrace(ExceptionUtils.getStackTrace(e));
-        StackTraceElement[] stackTraceElements = e.getStackTrace();
-        Assert.notEmpty(stackTraceElements, "异常 stackTraceElements 不能为空");
-        StackTraceElement stackTraceElement = stackTraceElements[0];
-        errorLog.setExceptionClassName(stackTraceElement.getClassName());
-        errorLog.setExceptionFileName(stackTraceElement.getFileName());
-        errorLog.setExceptionMethodName(stackTraceElement.getMethodName());
-        errorLog.setExceptionLineNumber(stackTraceElement.getLineNumber());
-        // 设置其它字段
-        errorLog.setTraceId(TracerUtils.getTraceId());
-        errorLog.setApplicationName(applicationName);
-        errorLog.setRequestUrl(request.getRequestURI());
-        Map<String, Object> requestParams = MapUtil.<String, Object>builder()
-                .put("query", ServletUtil.getParamMap(request))
-                .put("body", ServletUtil.getBody(request)).build();
-        errorLog.setRequestParams(JsonUtils.toJsonString(requestParams));
-        errorLog.setRequestMethod(request.getMethod());
-        errorLog.setUserAgent(ServletUtils.getUserAgent(request));
-        errorLog.setUserIp(ServletUtil.getClientIP(request));
-        errorLog.setExceptionTime(new Date());
-    }
 
 }

+ 0 - 2
iot-framework/iot-spring-boot-starter-web/src/main/java/com/yushu/framework/web/core/handler/GlobalResponseBodyHandler.java

@@ -1,6 +1,5 @@
 package com.yushu.framework.web.core.handler;
 
-import com.yushu.framework.apilog.core.filter.ApiAccessLogFilter;
 import com.yushu.framework.common.pojo.CommonResult;
 import com.yushu.framework.web.core.util.WebFrameworkUtils;
 import org.springframework.core.MethodParameter;
@@ -19,7 +18,6 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
  * 原因是,GlobalResponseBodyHandler 本质上是 AOP,它不应该改变 Controller 返回的数据结构
  * <p>
  * 目前,GlobalResponseBodyHandler 的主要作用是,记录 Controller 的返回结果,
- * 方便 {@link ApiAccessLogFilter} 记录访问日志
  */
 @ControllerAdvice
 public class GlobalResponseBodyHandler implements ResponseBodyAdvice {

+ 1 - 0
iot-framework/pom.xml

@@ -28,6 +28,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-deploy-plugin</artifactId>
+                <version>${maven-deploy-plugin.version}</version>
                 <configuration>
                     <skip>true</skip>
                 </configuration>

+ 8 - 1
pom.xml

@@ -15,9 +15,16 @@
         <java.version>1.8</java.version>
         <maven.compiler.source>${java.version}</maven.compiler.source>
         <maven.compiler.target>${java.version}</maven.compiler.target>
-        <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <!-- Maven Plugin Versions -->
+        <spring-boot-maven-plugin.version>2.4.2</spring-boot-maven-plugin.version>
+        <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
+        <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
+        <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
+        <maven-source-plugin.version>2.2.1</maven-source-plugin.version>
+        <maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
+        <maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
     </properties>
 
     <modules>