diff --git a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/handler/GlobalExceptionHandler.java b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/handler/GlobalExceptionHandler.java index f686e6d..28210f9 100644 --- a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/handler/GlobalExceptionHandler.java +++ b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/handler/GlobalExceptionHandler.java @@ -73,13 +73,58 @@ public class GlobalExceptionHandler { message("request.invalid", exception.getMessage())); } + @ExceptionHandler(com.alibaba.cola.exception.BizException.class) + public ResponseEntity> handleColaBizException( + com.alibaba.cola.exception.BizException exception) { + LOGGER.warn("COLA BizException caught: {}", exception.getMessage()); + String msg = exception.getMessage(); + if (msg == null || msg.isEmpty()) { + msg = "业务处理异常"; + } + return response(HttpStatus.OK, SYSTEM_ERROR_CODE, msg); + } + @ExceptionHandler(Exception.class) public ResponseEntity> handleUnexpectedException(Exception exception) { + // 尝试从 cause 中提取有意义的错误信息 + Throwable cause = findBizExceptionCause(exception); + if (cause instanceof BizException) { + BizException bizEx = (BizException) cause; + String message = message("error." + bizEx.getCode(), bizEx.getMessage()); + LOGGER.warn("Unwrapped BizException from controller exception: {}", message); + return response(HttpStatus.OK, bizEx.getCode(), message); + } + if (cause instanceof com.alibaba.cola.exception.BizException) { + com.alibaba.cola.exception.BizException colaBizEx = + (com.alibaba.cola.exception.BizException) cause; + LOGGER.warn("Unwrapped COLA BizException from controller exception: {}", + colaBizEx.getMessage()); + String msg = colaBizEx.getMessage(); + if (msg == null || msg.isEmpty()) { + msg = "业务处理异常"; + } + return response(HttpStatus.OK, SYSTEM_ERROR_CODE, msg); + } LOGGER.error("Unhandled controller exception", exception); return response(HttpStatus.OK, SYSTEM_ERROR_CODE, message("system.error", "Internal server error")); } + /** + * 递归查找异常链中的 BizException 类型异常(项目自定义或 COLA) + */ + private Throwable findBizExceptionCause(Throwable exception) { + Throwable cause = exception.getCause(); + while (cause != null) { + if (cause instanceof BizException + || cause instanceof com.alibaba.cola.exception.BizException) { + return cause; + } + cause = cause.getCause(); + } + return null; + } + private ResponseEntity> response(HttpStatus status, String code, String message) { return ResponseEntity.status(status).body(SingleResponse.error(code, message)); } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java index 300c3f5..d2ee5cc 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java @@ -77,7 +77,14 @@ public class OrgPersonnelExecutor implements OrgPersonnelApi { userAddCmd.setName(result.getUserName()); String encrypt = Sm2Util.encryptHex(MD5.md5(defPassword), publicKey); userAddCmd.setPassword(encrypt); - gbsUserFacadeClient.add(userAddCmd); + try { + gbsUserFacadeClient.add(userAddCmd); + } catch (RuntimeException ex) { + LOGGER.warn("GBS user sync failed while adding personnel", ex); + if (gbsUserSyncFailFast) { + throw ex; + } + } return SingleResponse.success(co); } diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelAddCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelAddCmd.java index ba0fb6d..1ba7c13 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelAddCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelAddCmd.java @@ -2,6 +2,8 @@ package org.qinan.safetyeval.client.dto; import io.swagger.annotations.ApiModelProperty; import java.time.LocalDate; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import lombok.Data; /** @@ -12,93 +14,121 @@ import lombok.Data; @Data public class OrgPersonnelAddCmd { + @Size(max = 50, message = "姓名长度不能超过50个字符") @ApiModelProperty(value = "用户名称/姓名") private String userName; + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "账号格式不正确,请输入11位手机号") + @Size(max = 50, message = "账号长度不能超过50个字符") @ApiModelProperty(value = "账号") private String account; @ApiModelProperty(value = "性别编码(1男2女)") private Integer genderCode; + @Size(max = 10, message = "性别名称长度不能超过10个字符") @ApiModelProperty(value = "性别名称") private String genderName; @ApiModelProperty(value = "出生日期") private LocalDate birthDate; + @Pattern(regexp = "^\\d{17}[\\dXx]$", message = "身份证号格式不正确") + @Size(max = 18, message = "身份证号长度不能超过18个字符") @ApiModelProperty(value = "身份证号") private String idCardNo; + @Size(max = 500, message = "现住地址长度不能超过500个字符") @ApiModelProperty(value = "现住地址") private String currentAddress; + @Size(max = 500, message = "办公地址长度不能超过500个字符") @ApiModelProperty(value = "办公地址") private String officeAddress; + @Size(max = 32, message = "学历编码长度不能超过32个字符") @ApiModelProperty(value = "学历编码") private String educationCode; + @Size(max = 50, message = "学历名称长度不能超过50个字符") @ApiModelProperty(value = "学历名称") private String educationName; + @Size(max = 200, message = "毕业院校长度不能超过200个字符") @ApiModelProperty(value = "毕业院校") private String graduateSchool; + @Size(max = 100, message = "专业长度不能超过100个字符") @ApiModelProperty(value = "专业") private String major; @ApiModelProperty(value = "就职状态编码(1在职2离职)") private Integer employmentStatusCode; + @Size(max = 50, message = "就职状态名称长度不能超过50个字符") @ApiModelProperty(value = "就职状态名称") private String employmentStatusName; + @Size(max = 32, message = "人员类型编码长度不能超过32个字符") @ApiModelProperty(value = "人员类型编码(1基础人员2专职评价师)") private String personTypeCode; + @Size(max = 50, message = "人员类型名称长度不能超过50个字符") @ApiModelProperty(value = "人员类型名称") private String personTypeName; + @Size(max = 500, message = "资质范围长度不能超过500个字符") @ApiModelProperty(value = "资质范围") private String qualScope; + @Size(max = 32, message = "职业等级编码长度不能超过32个字符") @ApiModelProperty(value = "职业等级编码") private String professionalLevelCode; + @Size(max = 200, message = "职业等级名称长度不能超过200个字符") @ApiModelProperty(value = "职业等级名称") private String professionalLevelName; + @Size(max = 100, message = "证书编号长度不能超过100个字符") @ApiModelProperty(value = "安全评价师证书编号") private String evaluatorCertNo; + @Size(max = 32, message = "学历类型编码长度不能超过32个字符") @ApiModelProperty(value = "学历类型编码(全日制/在职教育)") private String educationTypeCode; + @Size(max = 50, message = "学历类型名称长度不能超过50个字符") @ApiModelProperty(value = "学历类型名称") private String educationTypeName; + @Size(max = 32, message = "学历层次编码长度不能超过32个字符") @ApiModelProperty(value = "学历层次编码(专科/本科/硕士/博士)") private String educationLevelCode; + @Size(max = 50, message = "学历层次名称长度不能超过50个字符") @ApiModelProperty(value = "学历层次名称") private String educationLevelName; + @Size(max = 50, message = "职称长度不能超过50个字符") @ApiModelProperty(value = "职称") private String titleName; @ApiModelProperty(value = "是否注册安全工程师(1是2否)") private Integer registerEngineerFlag; + @Size(max = 1000, message = "出版学术专著等长度不能超过1000个字符") @ApiModelProperty(value = "出版学术专著专利获奖论文等") private String publications; + @Size(max = 1000, message = "专业能力及认定方式长度不能超过1000个字符") @ApiModelProperty(value = "自我申报的专业能力及认定方式") private String abilityDeclaration; + @Size(max = 65535, message = "工作经历长度不能超过65535个字符") @ApiModelProperty(value = "主要学习工作经历") private String workExperience; + @Size(max = 2000, message = "证明材料地址长度不能超过2000个字符") @ApiModelProperty(value = "申报专业能力证明材料地址") private String proofMaterialUrl; diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertAddCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertAddCmd.java index b45cfd4..d67ab21 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertAddCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertAddCmd.java @@ -2,6 +2,7 @@ package org.qinan.safetyeval.client.dto; import io.swagger.annotations.ApiModelProperty; import java.time.LocalDate; +import javax.validation.constraints.Size; import lombok.Data; /** @@ -13,30 +14,39 @@ import lombok.Data; public class OrgPersonnelCertAddCmd { @ApiModelProperty(value = "证照名称") + @Size(max = 200, message = "证照名称不能超过200个字符") private String certName; @ApiModelProperty(value = "证书类型编码") + @Size(max = 32, message = "证书类型编码不能超过32个字符") private String certTypeCode; @ApiModelProperty(value = "证书类型名称") + @Size(max = 50, message = "证书类型名称不能超过50个字符") private String certTypeName; @ApiModelProperty(value = "证书类别编码") + @Size(max = 32, message = "证书类别编码不能超过32个字符") private String certCategoryCode; @ApiModelProperty(value = "证书类别名称") + @Size(max = 50, message = "证书类别名称不能超过50个字符") private String certCategoryName; @ApiModelProperty(value = "证书作业类别编码") + @Size(max = 32, message = "证书作业类别编码不能超过32个字符") private String operationCategoryCode; @ApiModelProperty(value = "证书作业类别名称") + @Size(max = 50, message = "证书作业类别名称不能超过50个字符") private String operationCategoryName; @ApiModelProperty(value = "证书编号") + @Size(max = 100, message = "证书编号不能超过100个字符") private String certNo; @ApiModelProperty(value = "发证机关") + @Size(max = 200, message = "发证机关不能超过200个字符") private String issueOrg; @ApiModelProperty(value = "证书有效开始日期") @@ -49,6 +59,7 @@ public class OrgPersonnelCertAddCmd { private LocalDate reviewDate; @ApiModelProperty(value = "证书附件地址") + @Size(max = 500, message = "证书附件地址不能超过500个字符") private String certAttachmentUrl; @ApiModelProperty(value = "人员id") diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertModifyCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertModifyCmd.java index 1b91357..5084839 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertModifyCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelCertModifyCmd.java @@ -2,6 +2,7 @@ package org.qinan.safetyeval.client.dto; import io.swagger.annotations.ApiModelProperty; import java.time.LocalDate; +import javax.validation.constraints.Size; import lombok.Data; /** @@ -16,30 +17,39 @@ public class OrgPersonnelCertModifyCmd { private Long id; @ApiModelProperty(value = "证照名称") + @Size(max = 200, message = "证照名称不能超过200个字符") private String certName; @ApiModelProperty(value = "证书类型编码") + @Size(max = 32, message = "证书类型编码不能超过32个字符") private String certTypeCode; @ApiModelProperty(value = "证书类型名称") + @Size(max = 50, message = "证书类型名称不能超过50个字符") private String certTypeName; @ApiModelProperty(value = "证书类别编码") + @Size(max = 32, message = "证书类别编码不能超过32个字符") private String certCategoryCode; @ApiModelProperty(value = "证书类别名称") + @Size(max = 50, message = "证书类别名称不能超过50个字符") private String certCategoryName; @ApiModelProperty(value = "证书作业类别编码") + @Size(max = 32, message = "证书作业类别编码不能超过32个字符") private String operationCategoryCode; @ApiModelProperty(value = "证书作业类别名称") + @Size(max = 50, message = "证书作业类别名称不能超过50个字符") private String operationCategoryName; @ApiModelProperty(value = "证书编号") + @Size(max = 100, message = "证书编号不能超过100个字符") private String certNo; @ApiModelProperty(value = "发证机关") + @Size(max = 200, message = "发证机关不能超过200个字符") private String issueOrg; @ApiModelProperty(value = "证书有效开始日期") @@ -52,6 +62,7 @@ public class OrgPersonnelCertModifyCmd { private LocalDate reviewDate; @ApiModelProperty(value = "证书附件地址") + @Size(max = 500, message = "证书附件地址不能超过500个字符") private String certAttachmentUrl; @ApiModelProperty(value = "人员id") diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelModifyCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelModifyCmd.java index 67250b6..41118b1 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelModifyCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/dto/OrgPersonnelModifyCmd.java @@ -2,6 +2,8 @@ package org.qinan.safetyeval.client.dto; import io.swagger.annotations.ApiModelProperty; import java.time.LocalDate; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import lombok.Data; /** @@ -15,93 +17,121 @@ public class OrgPersonnelModifyCmd { @ApiModelProperty(value = "主键ID") private Long id; + @Size(max = 50, message = "姓名长度不能超过50个字符") @ApiModelProperty(value = "用户名称/姓名") private String userName; + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "账号格式不正确,请输入11位手机号") + @Size(max = 50, message = "账号长度不能超过50个字符") @ApiModelProperty(value = "账号") private String account; @ApiModelProperty(value = "性别编码(1男2女)") private Integer genderCode; + @Size(max = 10, message = "性别名称长度不能超过10个字符") @ApiModelProperty(value = "性别名称") private String genderName; @ApiModelProperty(value = "出生日期") private LocalDate birthDate; + @Pattern(regexp = "^\\d{17}[\\dXx]$", message = "身份证号格式不正确") + @Size(max = 18, message = "身份证号长度不能超过18个字符") @ApiModelProperty(value = "身份证号") private String idCardNo; + @Size(max = 500, message = "现住地址长度不能超过500个字符") @ApiModelProperty(value = "现住地址") private String currentAddress; + @Size(max = 500, message = "办公地址长度不能超过500个字符") @ApiModelProperty(value = "办公地址") private String officeAddress; + @Size(max = 32, message = "学历编码长度不能超过32个字符") @ApiModelProperty(value = "学历编码") private String educationCode; + @Size(max = 50, message = "学历名称长度不能超过50个字符") @ApiModelProperty(value = "学历名称") private String educationName; + @Size(max = 200, message = "毕业院校长度不能超过200个字符") @ApiModelProperty(value = "毕业院校") private String graduateSchool; + @Size(max = 100, message = "专业长度不能超过100个字符") @ApiModelProperty(value = "专业") private String major; @ApiModelProperty(value = "就职状态编码(1在职2离职)") private Integer employmentStatusCode; + @Size(max = 50, message = "就职状态名称长度不能超过50个字符") @ApiModelProperty(value = "就职状态名称") private String employmentStatusName; + @Size(max = 32, message = "人员类型编码长度不能超过32个字符") @ApiModelProperty(value = "人员类型编码(1基础人员2专职评价师)") private String personTypeCode; + @Size(max = 50, message = "人员类型名称长度不能超过50个字符") @ApiModelProperty(value = "人员类型名称") private String personTypeName; + @Size(max = 500, message = "资质范围长度不能超过500个字符") @ApiModelProperty(value = "资质范围") private String qualScope; + @Size(max = 32, message = "职业等级编码长度不能超过32个字符") @ApiModelProperty(value = "职业等级编码") private String professionalLevelCode; + @Size(max = 200, message = "职业等级名称长度不能超过200个字符") @ApiModelProperty(value = "职业等级名称") private String professionalLevelName; + @Size(max = 100, message = "证书编号长度不能超过100个字符") @ApiModelProperty(value = "安全评价师证书编号") private String evaluatorCertNo; + @Size(max = 32, message = "学历类型编码长度不能超过32个字符") @ApiModelProperty(value = "学历类型编码(全日制/在职教育)") private String educationTypeCode; + @Size(max = 50, message = "学历类型名称长度不能超过50个字符") @ApiModelProperty(value = "学历类型名称") private String educationTypeName; + @Size(max = 32, message = "学历层次编码长度不能超过32个字符") @ApiModelProperty(value = "学历层次编码(专科/本科/硕士/博士)") private String educationLevelCode; + @Size(max = 50, message = "学历层次名称长度不能超过50个字符") @ApiModelProperty(value = "学历层次名称") private String educationLevelName; + @Size(max = 50, message = "职称长度不能超过50个字符") @ApiModelProperty(value = "职称") private String titleName; @ApiModelProperty(value = "是否注册安全工程师(1是2否)") private Integer registerEngineerFlag; + @Size(max = 1000, message = "出版学术专著等长度不能超过1000个字符") @ApiModelProperty(value = "出版学术专著专利获奖论文等") private String publications; + @Size(max = 1000, message = "专业能力及认定方式长度不能超过1000个字符") @ApiModelProperty(value = "自我申报的专业能力及认定方式") private String abilityDeclaration; + @Size(max = 65535, message = "工作经历长度不能超过65535个字符") @ApiModelProperty(value = "主要学习工作经历") private String workExperience; + @Size(max = 2000, message = "证明材料地址长度不能超过2000个字符") @ApiModelProperty(value = "申报专业能力证明材料地址") private String proofMaterialUrl;