feat: 合同推送黑名单判定复用HcsCreditCheckSupport金蝶命中公共方法(不再取C101-1黑名单状态)

This commit is contained in:
刘泉佳
2026-10-30 14:21:33 +08:00
parent 6f941697e9
commit f42987e6c5
2 changed files with 31 additions and 14 deletions
@@ -112,6 +112,7 @@ public class HcsContractSyncSupport {
private final HcsAttachmentSupport hcsAttachmentSupport; private final HcsAttachmentSupport hcsAttachmentSupport;
private final HcsExeStageSyncSupport hcsExeStageSyncSupport; private final HcsExeStageSyncSupport hcsExeStageSyncSupport;
private final HcsContractSpecSyncSupport hcsContractSpecSyncSupport; private final HcsContractSpecSyncSupport hcsContractSpecSyncSupport;
private final HcsCreditCheckSupport hcsCreditCheckSupport;
/** /**
* 合同金蝶同步结果接收处理(合规 contractKingdee/result 推送,D903,投送人/钢厂/结算中心合同共用): * 合同金蝶同步结果接收处理(合规 contractKingdee/result 推送,D903,投送人/钢厂/结算中心合同共用):
@@ -279,16 +280,16 @@ public class HcsContractSyncSupport {
RiskResult riskPartyB = queryRisk(contractManage, "乙方", contractManage.getPartyB()); RiskResult riskPartyB = queryRisk(contractManage, "乙方", contractManage.getPartyB());
// 风险等级:甲乙双方取先查到的非空值(无法量化比较,留痕双方原始值,联调后细化) // 风险等级:甲乙双方取先查到的非空值(无法量化比较,留痕双方原始值,联调后细化)
String riskLevel = StringUtil.isNotBlank(riskPartyA.riskLevel()) ? riskPartyA.riskLevel() : riskPartyB.riskLevel(); String riskLevel = StringUtil.isNotBlank(riskPartyA.riskLevel()) ? riskPartyA.riskLevel() : riskPartyB.riskLevel();
// 黑名单状态:任一方黑名单即为是 // 黑名单状态:任一方金蝶黑名单(A801-5)命中即为是(复用 HcsCreditCheckSupport.isKingdeeBlacklistHit 公共口径)
boolean blacklist = riskPartyA.blacklist() || riskPartyB.blacklist(); boolean blacklist = riskPartyA.kingdeeHit() || riskPartyB.kingdeeHit();
contractManage.setHcsRiskLevel(riskLevel); contractManage.setHcsRiskLevel(riskLevel);
contractManage.setKingdeeBlackStatus(blacklist ? BLACK_STATUS_YES : "no"); contractManage.setKingdeeBlackStatus(blacklist ? BLACK_STATUS_YES : "no");
contractManage.setHcsRiskTime(LocalDateTime.now()); contractManage.setHcsRiskTime(LocalDateTime.now());
contractManageMapper.updateById(contractManage); contractManageMapper.updateById(contractManage);
boolean risky = HcsSyncConstant.RISK_LEVEL_HIGH.equals(riskLevel) || blacklist; boolean risky = HcsSyncConstant.RISK_LEVEL_HIGH.equals(riskLevel) || blacklist;
log.info("HCS合同风险校验完成:contractNo={},甲方[{}={}/{}],乙方[{}={}/{}],高风险/黑名单={}", log.info("HCS合同风险校验完成:contractNo={},甲方[金蝶黑名单={},等级={}],乙方[金蝶黑名单={},等级={}],高风险/黑名单={}",
contractManage.getContractNo(), contractManage.getPartyA(), riskPartyA.blackStatus(), riskPartyA.riskLevel(), contractManage.getContractNo(), riskPartyA.kingdeeHit(), riskPartyA.riskLevel(),
contractManage.getPartyB(), riskPartyB.blackStatus(), riskPartyB.riskLevel(), risky); riskPartyB.kingdeeHit(), riskPartyB.riskLevel(), risky);
return risky; return risky;
} }
@@ -346,13 +347,13 @@ public class HcsContractSyncSupport {
if (customerArchive == null) { if (customerArchive == null) {
writeCheckLog(contractManage, HcsSyncConstant.CHECK_RESULT_SKIP, writeCheckLog(contractManage, HcsSyncConstant.CHECK_RESULT_SKIP,
standing + "方[" + partyName + "]反查不到客商编号,跳过风险校验(§9-U6)", null); standing + "方[" + partyName + "]反查不到客商编号,跳过风险校验(§9-U6)", null);
return new RiskResult(null, null, false); return new RiskResult(false, null);
} }
// 内部组织类型客商默认无风险,不调 C101-1(与展示/提交/付款链路口径一致) // 内部组织类型客商默认无风险,不调 C101-1(与展示/提交/付款链路口径一致)
if (HcsCreditCheckSupport.isInternalCustomer(customerArchive)) { if (HcsCreditCheckSupport.isInternalCustomer(customerArchive)) {
writeCheckLog(contractManage, HcsSyncConstant.CHECK_RESULT_SKIP, writeCheckLog(contractManage, HcsSyncConstant.CHECK_RESULT_SKIP,
standing + "方[" + partyName + "]为内部组织客商,默认无风险跳过校验", null); standing + "方[" + partyName + "]为内部组织客商,默认无风险跳过校验", null);
return new RiskResult(null, null, false); return new RiskResult(false, null);
} }
HcsRiskQueryDTO param = new HcsRiskQueryDTO(); HcsRiskQueryDTO param = new HcsRiskQueryDTO();
// 【必填】客商编号:按甲乙方名称反查 CustomerArchive 客商编码(§9-U6) // 【必填】客商编号:按甲乙方名称反查 CustomerArchive 客商编码(§9-U6)
@@ -364,12 +365,12 @@ public class HcsContractSyncSupport {
throw new HcsException("C101-1 客商风险查询失败:" + (result == null ? "响应为空" : result.getMsg())); throw new HcsException("C101-1 客商风险查询失败:" + (result == null ? "响应为空" : result.getMsg()));
} }
HcsRiskVO risk = result.getData(); HcsRiskVO risk = result.getData();
String blackStatus = risk == null ? null : risk.getFdBlackStatus();
String riskLevel = risk == null ? null : risk.getFdRiskLevel(); String riskLevel = risk == null ? null : risk.getFdRiskLevel();
boolean blacklist = BLACK_STATUS_YES.equalsIgnoreCase(blackStatus); // 黑名单判定复用公共方法:仅以金蝶黑名单(A801-5)命中为准,C101-1 黑名单状态不参与
writeCheckLog(contractManage, blacklist ? HcsSyncConstant.CHECK_RESULT_FAIL : HcsSyncConstant.CHECK_RESULT_PASS, boolean kingdeeHit = hcsCreditCheckSupport.isKingdeeBlacklistHit(customerArchive.getUnifiedCreditCode());
standing + "方[" + partyName + "]黑名单=" + blackStatus + ",风险等级=" + riskLevel, result.getTraceId()); writeCheckLog(contractManage, kingdeeHit ? HcsSyncConstant.CHECK_RESULT_FAIL : HcsSyncConstant.CHECK_RESULT_PASS,
return new RiskResult(blackStatus, riskLevel, blacklist); standing + "方[" + partyName + "]金蝶黑名单=" + kingdeeHit + ",风险等级=" + riskLevel, result.getTraceId());
return new RiskResult(kingdeeHit, riskLevel);
} }
/** /**
@@ -780,8 +781,8 @@ public class HcsContractSyncSupport {
} }
/** /**
* 单方风险查询结果 * 单方风险查询结果(kingdeeHit=金蝶黑名单 A801-5 是否命中,公共口径见 {@link HcsCreditCheckSupport#isKingdeeBlacklistHit})
*/ */
private record RiskResult(String blackStatus, String riskLevel, boolean blacklist) { private record RiskResult(boolean kingdeeHit, String riskLevel) {
} }
} }
@@ -358,6 +358,22 @@ public class HcsCreditCheckSupport {
return StringUtil.isBlank(levelName) ? null : levelName; return StringUtil.isBlank(levelName) ? null : levelName;
} }
/**
* 金蝶黑名单命中判定(A801-5,公共方法):按统一社会信用代码/税号查询,
* 黑名单记录存在即命中;查询失败静默返回 false(queryBlacklistByCodes 内记 error 日志备查)。
* 展示组装(buildRiskDetail)、列表筛选、合同推送链路(checkRelativeRisk)统一复用本方法口径
*
* @param creditCode 统一社会信用代码/税号
* @return 是否命中金蝶黑名单
*/
public boolean isKingdeeBlacklistHit(String creditCode) {
if (StringUtil.isBlank(creditCode)) {
return false;
}
String code = creditCode.trim().toUpperCase();
return this.queryBlacklistByCodes(List.of(code)).get(code) != null;
}
/** /**
* 组装客商风险明细文案(后台统一组装、前端只展示;列表悬浮明细与表单实时提示共用本方法,口径一致), * 组装客商风险明细文案(后台统一组装、前端只展示;列表悬浮明细与表单实时提示共用本方法,口径一致),
* 格式:【客商名称】:被列入外部黑名单(失信类别:xx);{列入事由};风险等级:xx,分段说明: * 格式:【客商名称】:被列入外部黑名单(失信类别:xx);{列入事由};风险等级:xx,分段说明: