feat: 客商风险每日定时刷新任务(C101-1风险等级与A801-5金蝶黑名单按200客商分批落库)

This commit is contained in:
刘泉佳
2026-10-30 11:33:15 +08:00
parent 91d94f7ac0
commit 2e650b84ff
5 changed files with 361 additions and 32 deletions
@@ -25,6 +25,8 @@
*/
package org.springblade.transport.constant;
import java.util.List;
/**
* HCS(合同合规系统)同步常量(TMS 业务侧)
* <p>
@@ -175,6 +177,26 @@ public final class HcsSyncConstant {
*/
public static final String CUSTOMER_KIND_INTERNAL = "internal";
/**
* 合同审核通过状态集合(首推/变更通过,客商风险定时刷新扫描口径与 HcsPushTask 一致)
*/
public static final List<String> CONTRACT_APPROVED_STATUSES = List.of("approved", "change_approved");
/**
* 合同已终止当前节点展示名(客商风险定时刷新排除已终止合同)
*/
public static final String CONTRACT_TERMINATED_NODE = "已终止";
/**
* 客商风险等级业务字典编码(dictKey=C101-1 风险等级 0/1/2,dictValue=低风险/中风险/高风险)
*/
public static final String RISK_LEVEL_DICT_CODE = "risk_level";
/**
* 客商风险定时刷新批量(200 客商/批:批内黑名单一次查询 + C101-1 逐个查询,查完立即提交数据库,批间互不影响)
*/
public static final int CUSTOMER_RISK_REFRESH_BATCH = 200;
/**
* 合同附件类型字段名(与前端附件元数据 fileType 字段对齐,值取业务字典 contract_attachment_type)
*/
@@ -26,6 +26,7 @@
package org.springblade.transport.support.hcs;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
@@ -40,6 +41,10 @@ import org.springblade.hcs.dto.HcsRiskQueryDTO;
import org.springblade.hcs.dto.HcsRiskVO;
import org.springblade.hcs.exception.HcsException;
import org.springblade.hcs.feign.IHcsClient;
import org.springblade.system.cache.DictBizCache;
import org.springblade.system.cache.DictCache;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBlacklistVO;
import org.springblade.thirdparty.bfi.service.IBfiService;
import org.springblade.transport.constant.HcsSyncConstant;
import org.springblade.transport.mapper.ContractManageMapper;
import org.springblade.transport.mapper.CustomerArchiveMapper;
@@ -52,11 +57,14 @@ import org.springblade.transport.pojo.vo.CustomerRiskVO;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
/**
* HCS 付款提交校验支撑组件(C101-1 客商风险 + C106-1 额度校验,设计文档 §5.4,D15/R2-Q3)
@@ -87,6 +95,7 @@ public class HcsCreditCheckSupport {
private final ContractManageMapper contractManageMapper;
private final CustomerArchiveMapper customerArchiveMapper;
private final HcsContractCheckLogMapper hcsContractCheckLogMapper;
private final IBfiService bfiService;
/**
* 付款提交同步校验入口(submit 事务内调用,校验结果字段随提交一并落库)
@@ -195,7 +204,7 @@ public class HcsCreditCheckSupport {
/**
* 客商风险查询(C101-1,展示与提交校验共用,前端接入设计 §3.3):
* 内部组织类型客商默认无风险(不调 C101-1);外部客商按编号查询风险等级与黑名单状态并留痕;
* 高风险/黑名单时组装风险提示文案(风险项明细 C101-1 未返回,固定文案展示)
* riskTip 经 {@link #buildRiskDetail} 统一组装(等级 + 金蝶黑名单失信类别/列入事由),与列表悬浮明细同口径
*
* @param customerCode 客商编号
* @return 风险展示信息(customerKind/fdBlackStatus/fdRiskLevel/risky/riskTip)
@@ -208,16 +217,43 @@ public class HcsCreditCheckSupport {
.eq(CustomerArchive::getCustomerCode, customerCode)
.eq(CustomerArchive::getIsDeleted, 0)
.last("limit 1"));
CustomerRiskVO riskVO = new CustomerRiskVO();
riskVO.setCustomerCode(customerCode);
riskVO.setCustomerName(customerArchive == null ? customerCode : customerArchive.getFullName());
String customerName = customerArchive == null ? customerCode : customerArchive.getFullName();
// 内部组织类型客商默认无风险;档案不存在按外部客商查询(不静默放行)
boolean internal = isInternalCustomer(customerArchive);
riskVO.setCustomerKind(internal ? HcsSyncConstant.CUSTOMER_KIND_INTERNAL : "external");
if (internal) {
if (isInternalCustomer(customerArchive)) {
CustomerRiskVO riskVO = new CustomerRiskVO();
riskVO.setCustomerCode(customerCode);
riskVO.setCustomerName(customerName);
riskVO.setCustomerKind(HcsSyncConstant.CUSTOMER_KIND_INTERNAL);
riskVO.setRisky(Boolean.FALSE);
return riskVO;
}
RelativeRiskResult fetch = this.fetchRelativeRisk(customerCode, customerName);
CustomerRiskVO riskVO = fetch.risk();
// 表单实时提示与列表明细统一组装口径:追加金蝶黑名单段(A801-5 按档案信用代码查询,失败静默缺失)
String creditCode = customerArchive == null ? null : customerArchive.getUnifiedCreditCode();
BfiBlacklistVO hit = StringUtil.isBlank(creditCode) ? null
: this.queryBlacklistByCodes(List.of(creditCode.trim().toUpperCase())).get(creditCode.trim().toUpperCase());
String blackCategory = hit == null ? null
: (Func.isEmpty(hit.getAwrpCombofieldTitle()) ? hit.getAwrpCombofield() : hit.getAwrpCombofieldTitle());
riskVO.setRiskTip(buildRiskDetail(customerName, BLACK_STATUS_YES.equalsIgnoreCase(riskVO.getFdBlackStatus()),
riskVO.getFdRiskLevel(), blackCategory, hit == null ? null : hit.getAwrpTextareafield()));
try {
hcsContractCheckLogMapper.insert(this.buildRiskCheckLog(customerCode, riskVO, fetch.traceId()));
} catch (Exception exception) {
log.error("HCS客商风险查询留痕写入失败:fdNumber={}", customerCode, exception);
}
return riskVO;
}
/**
* C101-1 单客商远程查询并组装展示信息(不查档案、不写留痕,供单查与定时批量刷新复用);
* riskTip 不在本方法组装,由调用方经 {@link #buildRiskDetail} 统一组装
*
* @param customerCode 客商编号
* @param customerName 客商名称(展示信息用)
* @return 风险展示信息 + 合规 traceId
*/
private RelativeRiskResult fetchRelativeRisk(String customerCode, String customerName) {
HcsRiskQueryDTO param = new HcsRiskQueryDTO();
// 【必填】客商编号(用哪个编码待联调,§9-U6)
param.setFdNumber(customerCode);
@@ -231,28 +267,36 @@ public class HcsCreditCheckSupport {
String blackStatus = risk == null ? null : risk.getFdBlackStatus();
String riskLevel = risk == null ? null : risk.getFdRiskLevel();
boolean risky = HcsSyncConstant.RISK_LEVEL_HIGH.equals(riskLevel) || BLACK_STATUS_YES.equalsIgnoreCase(blackStatus);
CustomerRiskVO riskVO = new CustomerRiskVO();
riskVO.setCustomerCode(customerCode);
riskVO.setCustomerName(customerName);
riskVO.setCustomerKind("external");
riskVO.setFdBlackStatus(blackStatus);
riskVO.setFdRiskLevel(riskLevel);
riskVO.setRiskLevelName(riskLevelName(blackStatus, riskLevel));
riskVO.setRisky(risky);
if (risky) {
// 风险提示固定短文案(C101-1 未返回风险项明细,不拼接枚举清单):黑名单与高风险区分表述
riskVO.setRiskTip("【" + riskVO.getCustomerName() + "】:"
+ (BLACK_STATUS_YES.equalsIgnoreCase(blackStatus) ? "被列入外部黑名单" : "为高风险客商"));
}
try {
HcsContractCheckLog checkLog = new HcsContractCheckLog();
checkLog.setBizType(HcsSyncConstant.BIZ_TYPE_CONTRACT);
checkLog.setCheckType(HcsSyncConstant.CHECK_TYPE_RISK);
checkLog.setResult(risky ? HcsSyncConstant.CHECK_RESULT_FAIL : HcsSyncConstant.CHECK_RESULT_PASS);
checkLog.setMsg("客商风险查询[" + customerCode + "]黑名单=" + blackStatus + ",风险等级=" + riskLevel + ",高风险/黑名单=" + risky);
checkLog.setTraceId(result.getTraceId());
checkLog.setCreateTime(LocalDateTime.now());
hcsContractCheckLogMapper.insert(checkLog);
} catch (Exception exception) {
log.error("HCS客商风险查询留痕写入失败:fdNumber={}", customerCode, exception);
}
return riskVO;
return new RelativeRiskResult(riskVO, result.getTraceId());
}
/**
* C101-1 单次远程查询结果(风险展示信息 + 合规 traceId,留痕与批量刷新共用)
*/
private record RelativeRiskResult(CustomerRiskVO risk, String traceId) {
}
/**
* 组装客商风险查询留痕(单查与定时批量刷新共用,msg 口径一致)
*/
private HcsContractCheckLog buildRiskCheckLog(String customerCode, CustomerRiskVO risk, String traceId) {
HcsContractCheckLog checkLog = new HcsContractCheckLog();
checkLog.setBizType(HcsSyncConstant.BIZ_TYPE_CONTRACT);
checkLog.setCheckType(HcsSyncConstant.CHECK_TYPE_RISK);
checkLog.setResult(Boolean.TRUE.equals(risk.getRisky()) ? HcsSyncConstant.CHECK_RESULT_FAIL : HcsSyncConstant.CHECK_RESULT_PASS);
checkLog.setMsg("客商风险查询[" + customerCode + "]黑名单=" + risk.getFdBlackStatus()
+ ",风险等级=" + risk.getFdRiskLevel() + ",高风险/黑名单=" + risk.getRisky());
checkLog.setTraceId(traceId);
checkLog.setCreateTime(LocalDateTime.now());
return checkLog;
}
/**
@@ -287,18 +331,67 @@ public class HcsCreditCheckSupport {
}
/**
* 风险等级转义(C101-1 枚举 0=低风险/1=中风险/2=高风险):黑名单状态优先展示,无等级返回空
* 风险等级转义:黑名单状态优先展示;等级走业务字典 risk_level 翻译({@link #resolveRiskLevelName}),无等级返回空
*/
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;
};
return resolveRiskLevelName(riskLevel);
}
/**
* 客商风险等级名称翻译(业务字典 risk_level,dictKey=C101-1 风险等级 0=低风险/1=中风险/2=高风险);
* 业务字典未命中兜底系统字典,仍未命中返回 null(明细不拼等级段);列表组装与展示链路统一复用本方法
*
* @param riskLevel C101-1 风险等级
* @return 等级名称,未命中返回 null
*/
public static String resolveRiskLevelName(String riskLevel) {
if (Func.isEmpty(riskLevel)) {
return null;
}
String levelName = DictBizCache.getValue(HcsSyncConstant.RISK_LEVEL_DICT_CODE, riskLevel);
if (StringUtil.isBlank(levelName)) {
levelName = DictCache.getValue(HcsSyncConstant.RISK_LEVEL_DICT_CODE, riskLevel);
}
return StringUtil.isBlank(levelName) ? null : levelName;
}
/**
* 组装客商风险明细文案(后台统一组装、前端只展示;列表悬浮明细与表单实时提示共用本方法,口径一致),
* 格式:【客商名称】:被列入外部黑名单(失信类别:xx);{列入事由};风险等级:xx,分段说明:
* ① 黑名单段:合同系统黑名单(blackStatusYes)或金蝶黑名单命中(类别/事由任一非空)→「被列入外部黑名单」,
* 失信类别(A801-5 awrp_combofield_title,缺失兜底 awrp_combofield)有值时括号展示区分禁止交易/风险警示类;
* ② 列入事由:金蝶 A801-5 awrp_textareafield 真实明细,非空时追加;
* ③ 等级段:C101-1 风险等级(risk_level 字典翻译,黑名单不转义、按实际等级展示),非空时追加
*
* @param customerName 客商名称
* @param blackStatusYes 合同系统黑名单状态(C101-1 fdBlackStatus=yes)
* @param riskLevel C101-1 风险等级(0/1/2)
* @param blackCategory 金蝶黑名单失信类别
* @param blackReason 金蝶黑名单列入事由
* @return 明细文案,无风险信息返回空字符串
*/
public static String buildRiskDetail(String customerName, boolean blackStatusYes, String riskLevel, String blackCategory, String blackReason) {
List<String> parts = new ArrayList<>();
boolean blacklist = blackStatusYes || Func.isNotEmpty(blackCategory) || Func.isNotEmpty(blackReason);
if (blacklist) {
parts.add(Func.isNotEmpty(blackCategory)
? "被列入外部黑名单(失信类别:" + blackCategory + ")"
: "被列入外部黑名单");
}
if (Func.isNotEmpty(blackReason)) {
parts.add(blackReason);
}
String levelName = resolveRiskLevelName(riskLevel);
if (StringUtil.isNotBlank(levelName)) {
parts.add("风险等级:" + levelName);
}
if (parts.isEmpty()) {
return "";
}
return "【" + customerName + "】:" + String.join(";", parts);
}
/**
@@ -324,6 +417,139 @@ public class HcsCreditCheckSupport {
return riskList;
}
/**
* 客商风险每日定时刷新(C101-1,客商档案列表展示与筛选数据源):
* ① 取合同期限内(正式/临时期限任一覆盖当天)审核通过且未终止合同的甲乙方名称;
* ② 按名称反查客商档案,内部组织客商默认无风险跳过;
* ③ 逐个查询 C101-1(接口仅支持单编号,属远程调用非数据库 N+1;复用 {@link #fetchRelativeRisk},不重复查档案),
* 单个失败记 error 日志不中断(失败原因备查);
* ④ 外部客商按 200/批切分,每批黑名单(A801-5)一次批量查询 + C101-1 逐个远程查询,失信类别/列入事由落原始字段
* (明细文案由列表查询统一组装);
* ⑤ 每批成功结果立即批量落库(Db.updateBatchById,仅提交 id + 风险列,不整行回写)+ 留痕批量写入(Db.saveBatch),
* 风险/黑名单批次互不影响,单批失败不中断其余批次,避免逐条操作数据库
*
* @return 结果汇总描述
*/
public String refreshCustomerRiskForActiveContracts() {
LocalDate today = LocalDate.now();
List<ContractManage> contractList = contractManageMapper.selectList(Wrappers.<ContractManage>lambdaQuery()
.select(ContractManage::getPartyA, ContractManage::getPartyB)
.in(ContractManage::getApprovalStatus, HcsSyncConstant.CONTRACT_APPROVED_STATUSES)
.ne(ContractManage::getCurrentNode, HcsSyncConstant.CONTRACT_TERMINATED_NODE)
.and(wrapper -> wrapper
.and(item -> item.le(ContractManage::getStartDate, today).ge(ContractManage::getEndDate, today))
.or(item -> item.le(ContractManage::getTemporaryStartDate, today).ge(ContractManage::getTemporaryEndDate, today))));
List<String> partyNames = contractList.stream()
.flatMap(contract -> Stream.of(contract.getPartyA(), contract.getPartyB()))
.filter(Func::isNotEmpty)
.map(String::trim)
.distinct()
.toList();
if (partyNames.isEmpty()) {
return "合同期限内无生效合同,未刷新客商风险";
}
List<CustomerArchive> archiveList = customerArchiveMapper.selectList(Wrappers.<CustomerArchive>lambdaQuery()
.in(CustomerArchive::getFullName, partyNames)
.eq(CustomerArchive::getIsDeleted, 0));
List<CustomerArchive> externalArchives = archiveList.stream()
.filter(customerArchive -> !isInternalCustomer(customerArchive))
.toList();
int internalCount = archiveList.size() - externalArchives.size();
int refreshCount = 0;
int failCount = 0;
// 外部客商按 200/批处理:每批黑名单一次批量查询 + C101-1 逐个远程查询(接口仅支持单编号,非数据库 N+1),
// 批内成功结果立即批量落库与留痕,风险/黑名单批次互不影响,单批失败不中断其余批次
for (int start = 0; start < externalArchives.size(); start += HcsSyncConstant.CUSTOMER_RISK_REFRESH_BATCH) {
List<CustomerArchive> batch = externalArchives.subList(start, Math.min(start + HcsSyncConstant.CUSTOMER_RISK_REFRESH_BATCH, externalArchives.size()));
Map<String, BfiBlacklistVO> blacklistMap = this.queryBlacklistByCodes(batch.stream()
.map(CustomerArchive::getUnifiedCreditCode)
.filter(Func::isNotEmpty)
.map(code -> code.trim().toUpperCase())
.distinct()
.toList());
List<CustomerArchive> batchRefreshList = new ArrayList<>();
List<HcsContractCheckLog> batchCheckLogs = new ArrayList<>();
for (CustomerArchive customerArchive : batch) {
try {
RelativeRiskResult fetch = this.fetchRelativeRisk(customerArchive.getCustomerCode(), customerArchive.getFullName());
CustomerRiskVO risk = fetch.risk();
// 仅提交风险列,避免整行回写覆盖刷新期间其它并发修改(审批状态/额度/金蝶推送等)
CustomerArchive riskPatch = new CustomerArchive();
riskPatch.setId(customerArchive.getId());
riskPatch.setHcsRiskLevel(risk.getFdRiskLevel());
riskPatch.setHcsBlackStatus(risk.getFdBlackStatus());
riskPatch.setHcsRiskTime(LocalDateTime.now());
// 金蝶黑名单命中落原始字段(失信类别/列入事由),明细文案由列表查询统一组装
BfiBlacklistVO hit = Func.isEmpty(customerArchive.getUnifiedCreditCode())
? null : blacklistMap.get(customerArchive.getUnifiedCreditCode().trim().toUpperCase());
if (hit != null) {
String category = Func.isEmpty(hit.getAwrpCombofieldTitle()) ? hit.getAwrpCombofield() : hit.getAwrpCombofieldTitle();
riskPatch.setKingdeeBlackCategory(category);
riskPatch.setKingdeeBlackReason(hit.getAwrpTextareafield());
}
batchCheckLogs.add(this.buildRiskCheckLog(customerArchive.getCustomerCode(), risk, fetch.traceId()));
batchRefreshList.add(riskPatch);
} catch (Exception exception) {
failCount++;
log.error("定时刷新客商风险失败:customerCode={},fullName={}",
customerArchive.getCustomerCode(), customerArchive.getFullName(), exception);
}
}
// 批内成功结果立即提交数据库,批间互不影响
if (!batchRefreshList.isEmpty()) {
Db.updateBatchById(batchRefreshList);
refreshCount += batchRefreshList.size();
}
this.saveRiskCheckLogs(batchCheckLogs);
}
String summary = String.format("生效合同 %d 份,覆盖客商 %d 个,刷新 %d 个,内部客商跳过 %d 个,失败 %d 个",
contractList.size(), archiveList.size(), refreshCount, internalCount, failCount);
if (failCount > 0) {
log.warn("定时刷新客商风险存在失败:{}", summary);
}
return summary;
}
/**
* 金蝶黑名单批量查询(A801-5,定时刷新专用,调用方按 200 客商/批切分保证入参 ≤200):
* 键为大写税号;失信类别取 awrp_combofield_title、缺失兜底 awrp_combofield(口径同提审校验 validateBlacklist);
* 查询异常不阻断刷新,记 error 日志备查后返回空 map(该批黑名单段缺失)
*
* @param creditCodes 统一社会信用代码集合(大写,≤200)
* @return 大写税号 -> 黑名单记录
*/
private Map<String, BfiBlacklistVO> queryBlacklistByCodes(List<String> creditCodes) {
if (creditCodes.isEmpty()) {
return Map.of();
}
try {
Map<String, BfiBlacklistVO> blacklistMap = new HashMap<>();
for (BfiBlacklistVO item : this.bfiService.queryBlacklist("1", creditCodes)) {
if (Func.isNotEmpty(item.getNumber())) {
blacklistMap.put(item.getNumber().trim().toUpperCase(), item);
}
}
return blacklistMap;
} catch (Exception exception) {
log.error("定时刷新客商风险批量查询金蝶黑名单失败:size={}", creditCodes.size(), exception);
return Map.of();
}
}
/**
* 客商风险留痕批量写入(Db.saveBatch,避免逐条 insert);失败记 error 日志备查,不阻断刷新结果
*/
private void saveRiskCheckLogs(List<HcsContractCheckLog> checkLogs) {
if (checkLogs.isEmpty()) {
return;
}
try {
Db.saveBatch(checkLogs);
} catch (Exception exception) {
log.error("定时刷新客商风险留痕批量写入失败:size={}", checkLogs.size(), exception);
}
}
/**
* 按名称反查客商档案(内部/外部类型判断与客商编码获取共用;查不到返回 null)
*/
@@ -0,0 +1,72 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.task;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.hcs.config.HcsProperties;
import org.springblade.transport.support.hcs.HcsCreditCheckSupport;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* 客商风险每日定时刷新任务(C101-1)
* <p>
* 合同期限范围内的生效合同,每日定时查询其甲乙方关联客商的风险等级/黑名单状态并落库
* (blade_customer_archive.hcs_risk_level/hcs_black_status/hcs_risk_time),
* 作为客商档案列表「客商风险」列展示与筛选的数据源;查询逐次留痕 blade_hcs_check_log,
* 单个失败记录失败原因日志备查。
* 业务逻辑收敛在 {@link HcsCreditCheckSupport#refreshCustomerRiskForActiveContracts()},便于手动触发联调。
* <p>
* 调度配置(Nacos thirdParty.hcs.risk.*):refreshEnabled 开关、refreshCron 表达式。
*
* @author Chill
*/
@Slf4j
@Component
@RefreshScope
@RequiredArgsConstructor
public class CustomerRiskRefreshTask {
private final HcsCreditCheckSupport hcsCreditCheckSupport;
private final HcsProperties hcsProperties;
/** 客商风险每日刷新调度,默认每天 02:30 执行(错开金蝶客商同步 02:00) */
@Scheduled(cron = "${thirdParty.hcs.risk.refreshCron:0 30 2 * * ?}")
public void refreshCustomerRisk() {
if (!hcsProperties.getRisk().isRefreshEnabled()) {
return;
}
try {
String summary = hcsCreditCheckSupport.refreshCustomerRiskForActiveContracts();
log.info("定时刷新客商风险:{}", summary);
} catch (Exception exception) {
log.error("定时刷新客商风险异常", exception);
}
}
}
@@ -252,6 +252,11 @@ public class HcsProperties {
* 付款提交前风险校验开关
*/
private boolean checkOnPayment = true;
/**
* 客商风险每日定时刷新开关(thirdParty.hcs.risk.refresh-enabled,默认关闭):
* 刷新合同期限内生效合同关联客商的风险等级/黑名单状态并落库,支撑列表展示与筛选
*/
private boolean refreshEnabled = false;
}
@Data
+4
View File
@@ -245,6 +245,10 @@ thirdParty:
risk:
check-on-contract: ${HCS_RISK_CHECK_ON_CONTRACT:true}
check-on-payment: ${HCS_RISK_CHECK_ON_PAYMENT:true}
# 客商风险每日定时刷新开关(刷新合同期限内生效合同关联客商并落库,支撑列表展示与筛选,默认关)
refresh-enabled: ${HCS_RISK_REFRESH_ENABLED:false}
# 客商风险刷新调度 cron,默认每天 02:30(错开金蝶客商同步 02:00)
refresh-cron: ${HCS_RISK_REFRESH_CRON:0 30 2 * * ?}
# 黑名单是否阻断(合同置 failed / 付款提交拦截)
# block-blacklist: ${HCS_RISK_BLOCK_BLACKLIST:true}
# 额度校验(C106-1,一期暂不对接)