feat: 新增客商风险批量与按名查询接口及风险等级转义

C101-1 展示链路:/hcs/risk/batch 批量查询(单失败跳过)、/hcs/risk/by-name 按名称查询(反查编号不阻断);CustomerRiskVO 回填 customerCode 并新增 riskLevelName 服务端转义(黑名单优先,0=低/1=中/2=高风险)
This commit is contained in:
刘泉佳
2026-10-21 17:37:48 +08:00
parent 41ee328455
commit 26c9a32c6b
3 changed files with 59 additions and 0 deletions
@@ -45,6 +45,9 @@ public class CustomerRiskVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "客商编号")
private String customerCode;
@Schema(description = "客商类型:internal内部组织(默认无风险)/external外部客商")
private String customerKind;
@@ -57,6 +60,9 @@ public class CustomerRiskVO implements Serializable {
@Schema(description = "风险等级:0=低风险,1=中风险,2=高风险")
private String fdRiskLevel;
@Schema(description = "风险等级名称(服务端转义:黑名单/高风险/中风险/低风险,黑名单优先;无等级为空)")
private String riskLevelName;
@Schema(description = "是否高风险/黑名单客商(外部客商专用,内部组织恒为 false)")
private Boolean risky;
@@ -235,6 +235,17 @@ public class HcsSyncController {
return R.data(hcsCreditCheckSupport.queryCustomerRiskBatch(Func.toStrList(customerCodes)));
}
/**
* 客商风险按名称查询(C101-1,客商档案表单展示用,前端接入设计 §3.3):
* 按名称反查客商编号后口径同 /risk;反查不到客商编号不阻断(risky=false,§9-U6)
*/
@GetMapping("/risk/by-name")
@ApiOperationSupport(order = 14)
@Operation(summary = "客商风险按名称查询", description = "C101-1 按客商名称查询风险(展示用),名称反查编号后口径同编号查询,反查不到默认无风险")
public R<CustomerRiskVO> riskByName(@Parameter(description = "客商名称", required = true) @RequestParam String customerName) {
return R.data(hcsCreditCheckSupport.queryCustomerRiskByName(customerName));
}
/**
* 附件上传到合同系统(C103-2 代理,前端接入设计 §3.2),返回合规附件ID
*/
@@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.hcs.config.HcsProperties;
import org.springblade.hcs.dto.HcsCreditCheckDTO;
@@ -52,6 +53,7 @@ import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -207,6 +209,7 @@ public class HcsCreditCheckSupport {
.eq(CustomerArchive::getIsDeleted, 0)
.last("limit 1"));
CustomerRiskVO riskVO = new CustomerRiskVO();
riskVO.setCustomerCode(customerCode);
riskVO.setCustomerName(customerArchive == null ? customerCode : customerArchive.getFullName());
// 内部组织类型客商默认无风险;档案不存在按外部客商查询(不静默放行)
boolean internal = customerArchive != null && HcsSyncConstant.CUSTOMER_KIND_INTERNAL.equals(customerArchive.getCustomerKind());
@@ -230,6 +233,7 @@ public class HcsCreditCheckSupport {
boolean risky = HcsSyncConstant.RISK_LEVEL_HIGH.equals(riskLevel) || BLACK_STATUS_YES.equalsIgnoreCase(blackStatus);
riskVO.setFdBlackStatus(blackStatus);
riskVO.setFdRiskLevel(riskLevel);
riskVO.setRiskLevelName(riskLevelName(blackStatus, riskLevel));
riskVO.setRisky(risky);
if (risky) {
riskVO.setRiskTip("【" + riskVO.getCustomerName() + "】:被列入外部黑名单;涉贪污受贿裁判相关提及方(3年以上及其他);被执行人信息;买卖合同纠纷;劳动纠纷;重大纠纷");
@@ -267,6 +271,44 @@ public class HcsCreditCheckSupport {
return queryCustomerRisk(customerCode);
}
/**
* 风险等级转义(C101-1 枚举 0=低风险/1=中风险/2=高风险):黑名单状态优先展示,无等级返回空
*/
private String riskLevelName(String blackStatus, String riskLevel) {
if (BLACK_STATUS_YES.equalsIgnoreCase(blackStatus)) {
return "黑名单";
}
return switch (Objects.toString(riskLevel, "")) {
case "2" -> "高风险";
case "1" -> "中风险";
case "0" -> "低风险";
default -> null;
};
}
/**
* 客商风险批量查询(C101-1,客商列表页展示用,前端接入设计 §3.3):
* 逐个复用 {@link #queryCustomerRisk}(内部客商默认无风险,外部客商查 C101-1,与付款页面展示口径一致);
* C101-1 仅支持单编号查询,逐个串行调用;展示场景单个失败跳过不阻断整页(强制校验仍在合同/付款链路)
*
* @param customerCodes 客商编号集合
* @return 风险展示信息列表(查询失败的客商不在结果中)
*/
public List<CustomerRiskVO> queryCustomerRiskBatch(List<String> customerCodes) {
List<CustomerRiskVO> riskList = new ArrayList<>();
if (Func.isEmpty(customerCodes)) {
return riskList;
}
for (String customerCode : customerCodes) {
try {
riskList.add(this.queryCustomerRisk(customerCode));
} catch (Exception exception) {
log.error("客商风险批量查询单个失败,跳过:customerCode={}", customerCode, exception);
}
}
return riskList;
}
/**
* 按名称反查客商档案(内部/外部类型判断与客商编码获取共用;查不到返回 null)
*/