:fix: 统一内部组织客商判定口径、精简高风险提示文案并移除mock控制器
This commit is contained in:
-123
@@ -1,123 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springblade.core.log.exception.ServiceException;
|
|
||||||
import org.springblade.core.tenant.annotation.TenantIgnore;
|
|
||||||
import org.springblade.core.tool.api.R;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HCS 合规回调 Mock 端点
|
|
||||||
* <p>
|
|
||||||
* 合同法务审批结果回调(D103)、付款法务审批结果回调(D104)、项目金蝶同步结果回调(D902)、
|
|
||||||
* 合同金蝶同步结果回传接收(D903)四个入站回调的纯 mock 实现:仅校验来源系统标识后返回固定结果,
|
|
||||||
* 不读写业务数据、不联动状态。真实处理逻辑保留在对应 Support 中,联调时把端点切回
|
|
||||||
* {@link } 并调用 Support 方法即可。
|
|
||||||
*
|
|
||||||
* @author Chill
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@TenantIgnore
|
|
||||||
@RequestMapping("hcs")
|
|
||||||
@Tag(name = "HCS合规回调Mock", description = "HCS合规回调Mock端点(仅自测,返回固定 mock 数据)")
|
|
||||||
public class HcsMockController {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 来源系统标识(合规方约定值,与 third-party.hcs.src-system 默认值一致)
|
|
||||||
*/
|
|
||||||
private static final String SOURCE_SYSTEM = "WLTMS";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 合同法务审批结果回调(D103)
|
|
||||||
*/
|
|
||||||
@PostMapping("/contractLegal/result")
|
|
||||||
@ApiOperationSupport(order = 15)
|
|
||||||
@Operation(summary = "合同法务审批结果回调Mock", description = "D103 合规推送合同特批(金蝶同步)结果,仅校验来源系统并返回 mock 数据")
|
|
||||||
public R<String> contractLegalResult(@RequestBody(required = false) Map<String, Object> param) {
|
|
||||||
this.checkSourceSystem("合同法务审批结果", param);
|
|
||||||
return R.data("mock特批结果已处理:approved");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 付款法务审批结果回调(D104)
|
|
||||||
*/
|
|
||||||
@PostMapping("/paymentLegal/result")
|
|
||||||
@ApiOperationSupport(order = 16)
|
|
||||||
@Operation(summary = "付款法务审批结果回调Mock", description = "D104 合规推送付款特批结果,仅校验来源系统并返回 mock 数据")
|
|
||||||
public R<String> paymentLegalResult(@RequestBody(required = false) Map<String, Object> param) {
|
|
||||||
this.checkSourceSystem("付款法务审批结果", param);
|
|
||||||
return R.data("mock付款特批结果接收已处理:approved");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目金蝶同步结果回调(D902)
|
|
||||||
*/
|
|
||||||
@PostMapping("/projectLegal/result")
|
|
||||||
@ApiOperationSupport(order = 18)
|
|
||||||
@Operation(summary = "项目金蝶同步结果回调Mock", description = "D902 合规推送项目金蝶同步结果,仅校验来源系统并返回 mock 数据")
|
|
||||||
public R<String> projectLegalResult(@RequestBody(required = false) Map<String, Object> param) {
|
|
||||||
this.checkSourceSystem("项目金蝶同步结果", param);
|
|
||||||
return R.data("mock项目金蝶同步结果接收已处理:approved");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 合同金蝶同步结果回传接收(D903)
|
|
||||||
*/
|
|
||||||
@PostMapping("/contractKingdee/result")
|
|
||||||
@ApiOperationSupport(order = 19)
|
|
||||||
@Operation(summary = "合同金蝶同步结果回传接收Mock", description = "D903 合规推送合同金蝶最终同步结果,仅校验来源系统并返回 mock 数据")
|
|
||||||
public R<String> contractKingdeeResult(@RequestBody(required = false) Map<String, Object> param) {
|
|
||||||
this.checkSourceSystem("合同金蝶同步结果", param);
|
|
||||||
return R.data("mock合同金蝶同步结果接收处理:approved");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 来源系统校验:仅接受合规方约定的来源标识,防伪造回传
|
|
||||||
*
|
|
||||||
* @param bizName 业务名称(日志用)
|
|
||||||
* @param param 回调报文
|
|
||||||
*/
|
|
||||||
private void checkSourceSystem(String bizName, Map<String, Object> param) {
|
|
||||||
String sourceSystem = param == null ? null : Objects.toString(param.get("sourceSystem"), null);
|
|
||||||
if (!StrUtil.equalsIgnoreCase(sourceSystem, SOURCE_SYSTEM)) {
|
|
||||||
log.warn("{}推送来源系统标识错误:sourceSystem={}", bizName, sourceSystem);
|
|
||||||
throw new ServiceException("来源系统标识错误");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+14
-24
@@ -337,22 +337,29 @@ public class HcsContractSyncSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询单方客商风险:按名称反查客商编号(§9-U6 编码体系联调确认),反查不到记 skip 留痕不阻断
|
* 查询单方客商风险:按名称反查客商档案(§9-U6 编码体系联调确认),反查不到记 skip 留痕不阻断;
|
||||||
|
* 内部组织客商默认无风险跳过(与展示/提交/付款链路口径一致,不调 C101-1)
|
||||||
*/
|
*/
|
||||||
private RiskResult queryRisk(ContractManage contractManage, String standing, String partyName) {
|
private RiskResult queryRisk(ContractManage contractManage, String standing, String partyName) {
|
||||||
String customerCode = queryCustomerCode(partyName);
|
CustomerArchive customerArchive = queryCustomerArchive(partyName);
|
||||||
if (StringUtil.isBlank(customerCode)) {
|
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(null, null, false);
|
||||||
}
|
}
|
||||||
|
// 内部组织类型客商默认无风险,不调 C101-1(与展示/提交/付款链路口径一致)
|
||||||
|
if (HcsCreditCheckSupport.isInternalCustomer(customerArchive)) {
|
||||||
|
writeCheckLog(contractManage, HcsSyncConstant.CHECK_RESULT_SKIP,
|
||||||
|
standing + "方[" + partyName + "]为内部组织客商,默认无风险跳过校验", null);
|
||||||
|
return new RiskResult(null, null, false);
|
||||||
|
}
|
||||||
HcsRiskQueryDTO param = new HcsRiskQueryDTO();
|
HcsRiskQueryDTO param = new HcsRiskQueryDTO();
|
||||||
// 【必填】客商编号:按甲乙方名称反查 CustomerArchive 客商编码(§9-U6)
|
// 【必填】客商编号:按甲乙方名称反查 CustomerArchive 客商编码(§9-U6)
|
||||||
param.setFdNumber(customerCode);
|
param.setFdNumber(customerArchive.getCustomerCode());
|
||||||
HcsResult<HcsRiskVO> result = hcsClient.getRelativeRisk(param);
|
HcsResult<HcsRiskVO> result = hcsClient.getRelativeRisk(param);
|
||||||
if (result == null || !result.isSuccess()) {
|
if (result == null || !result.isSuccess()) {
|
||||||
log.error("HCS客商风险查询失败响应:{},contractNo={},standing={},fdNumber={}",
|
log.error("HCS客商风险查询失败响应:{},contractNo={},standing={},fdNumber={}",
|
||||||
result == null ? "无响应" : String.format("msg=%s, traceId=%s", result.getMsg(), result.getTraceId()), contractManage.getContractNo(), standing, customerCode);
|
result == null ? "无响应" : String.format("msg=%s, traceId=%s", result.getMsg(), result.getTraceId()), contractManage.getContractNo(), standing, customerArchive.getCustomerCode());
|
||||||
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();
|
||||||
@@ -534,8 +541,8 @@ public class HcsContractSyncSupport {
|
|||||||
// 甲乙方各反查一次客商档案,编号与内部组织判定共用查询结果
|
// 甲乙方各反查一次客商档案,编号与内部组织判定共用查询结果
|
||||||
CustomerArchive partyAArchive = queryCustomerArchive(contractManage.getPartyA());
|
CustomerArchive partyAArchive = queryCustomerArchive(contractManage.getPartyA());
|
||||||
CustomerArchive partyBArchive = queryCustomerArchive(contractManage.getPartyB());
|
CustomerArchive partyBArchive = queryCustomerArchive(contractManage.getPartyB());
|
||||||
boolean partyAInternal = isInternalCustomer(partyAArchive);
|
boolean partyAInternal = HcsCreditCheckSupport.isInternalCustomer(partyAArchive);
|
||||||
boolean partyBInternal = isInternalCustomer(partyBArchive);
|
boolean partyBInternal = HcsCreditCheckSupport.isInternalCustomer(partyBArchive);
|
||||||
String partyAType;
|
String partyAType;
|
||||||
String partyBType;
|
String partyBType;
|
||||||
if (partyAInternal || partyBInternal) {
|
if (partyAInternal || partyBInternal) {
|
||||||
@@ -672,14 +679,6 @@ public class HcsContractSyncSupport {
|
|||||||
return templateId;
|
return templateId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 按名称反查客商编码(照 KingdeeApBillSyncSupport#queryCustomerCode 惯例,查不到返回 null)
|
|
||||||
*/
|
|
||||||
private String queryCustomerCode(String partyName) {
|
|
||||||
CustomerArchive customerArchive = queryCustomerArchive(partyName);
|
|
||||||
return customerArchive == null ? null : customerArchive.getCustomerCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按名称反查客商档案(全称或简称精确匹配,查不到返回 null)
|
* 按名称反查客商档案(全称或简称精确匹配,查不到返回 null)
|
||||||
*/
|
*/
|
||||||
@@ -693,15 +692,6 @@ public class HcsContractSyncSupport {
|
|||||||
.last("limit 1"));
|
.last("limit 1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 内部组织客商判定(集团内我方签约主体,档案登记 customerKind=internal/内部组织)
|
|
||||||
*/
|
|
||||||
private boolean isInternalCustomer(CustomerArchive customerArchive) {
|
|
||||||
return customerArchive != null
|
|
||||||
&& (HcsSyncConstant.CUSTOMER_KIND_INTERNAL.equals(customerArchive.getCustomerKind())
|
|
||||||
|| "内部组织".equals(customerArchive.getCustomerKind()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关联项目取值:合同所选项目对应合同系统项目ID(blade_project_apply.hcs_fd_id,C102-1 立项同步回填),
|
* 关联项目取值:合同所选项目对应合同系统项目ID(blade_project_apply.hcs_fd_id,C102-1 立项同步回填),
|
||||||
* 未选择项目、立项单不存在或未同步合规时返回 null 不传(fdProject 选填)
|
* 未选择项目、立项单不存在或未同步合规时返回 null 不传(fdProject 选填)
|
||||||
|
|||||||
+18
-3
@@ -118,7 +118,7 @@ public class HcsCreditCheckSupport {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 内部组织类型客商默认无风险,不查 C101-1(与 queryCustomerRisk 展示口径一致)
|
// 内部组织类型客商默认无风险,不查 C101-1(与 queryCustomerRisk 展示口径一致)
|
||||||
if (HcsSyncConstant.CUSTOMER_KIND_INTERNAL.equals(customerArchive.getCustomerKind())) {
|
if (isInternalCustomer(customerArchive)) {
|
||||||
writeCheckLog(payment, HcsSyncConstant.CHECK_TYPE_RISK, HcsSyncConstant.CHECK_RESULT_SKIP,
|
writeCheckLog(payment, HcsSyncConstant.CHECK_TYPE_RISK, HcsSyncConstant.CHECK_RESULT_SKIP,
|
||||||
"收款方[" + payment.getPayeeName() + "]为内部组织客商,默认无风险跳过校验", null);
|
"收款方[" + payment.getPayeeName() + "]为内部组织客商,默认无风险跳过校验", null);
|
||||||
return;
|
return;
|
||||||
@@ -212,7 +212,7 @@ public class HcsCreditCheckSupport {
|
|||||||
riskVO.setCustomerCode(customerCode);
|
riskVO.setCustomerCode(customerCode);
|
||||||
riskVO.setCustomerName(customerArchive == null ? customerCode : customerArchive.getFullName());
|
riskVO.setCustomerName(customerArchive == null ? customerCode : customerArchive.getFullName());
|
||||||
// 内部组织类型客商默认无风险;档案不存在按外部客商查询(不静默放行)
|
// 内部组织类型客商默认无风险;档案不存在按外部客商查询(不静默放行)
|
||||||
boolean internal = customerArchive != null && HcsSyncConstant.CUSTOMER_KIND_INTERNAL.equals(customerArchive.getCustomerKind());
|
boolean internal = isInternalCustomer(customerArchive);
|
||||||
riskVO.setCustomerKind(internal ? HcsSyncConstant.CUSTOMER_KIND_INTERNAL : "external");
|
riskVO.setCustomerKind(internal ? HcsSyncConstant.CUSTOMER_KIND_INTERNAL : "external");
|
||||||
if (internal) {
|
if (internal) {
|
||||||
riskVO.setRisky(Boolean.FALSE);
|
riskVO.setRisky(Boolean.FALSE);
|
||||||
@@ -236,7 +236,9 @@ public class HcsCreditCheckSupport {
|
|||||||
riskVO.setRiskLevelName(riskLevelName(blackStatus, riskLevel));
|
riskVO.setRiskLevelName(riskLevelName(blackStatus, riskLevel));
|
||||||
riskVO.setRisky(risky);
|
riskVO.setRisky(risky);
|
||||||
if (risky) {
|
if (risky) {
|
||||||
riskVO.setRiskTip("【" + riskVO.getCustomerName() + "】:被列入外部黑名单;涉贪污受贿裁判相关提及方(3年以上及其他);被执行人信息;买卖合同纠纷;劳动纠纷;重大纠纷");
|
// 风险提示固定短文案(C101-1 未返回风险项明细,不拼接枚举清单):黑名单与高风险区分表述
|
||||||
|
riskVO.setRiskTip("【" + riskVO.getCustomerName() + "】:"
|
||||||
|
+ (BLACK_STATUS_YES.equalsIgnoreCase(blackStatus) ? "被列入外部黑名单" : "为高风险客商"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
HcsContractCheckLog checkLog = new HcsContractCheckLog();
|
HcsContractCheckLog checkLog = new HcsContractCheckLog();
|
||||||
@@ -271,6 +273,19 @@ public class HcsCreditCheckSupport {
|
|||||||
return queryCustomerRisk(customerCode);
|
return queryCustomerRisk(customerCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内部组织客商判定(集团内我方签约主体,档案登记 customerKind=internal/内部组织);
|
||||||
|
* 展示、提交校验、付款校验、合同推送、signer 单位类型各链路统一复用本判定
|
||||||
|
*
|
||||||
|
* @param customerArchive 客商档案
|
||||||
|
* @return 是否内部组织客商
|
||||||
|
*/
|
||||||
|
public static boolean isInternalCustomer(CustomerArchive customerArchive) {
|
||||||
|
return customerArchive != null
|
||||||
|
&& (HcsSyncConstant.CUSTOMER_KIND_INTERNAL.equals(customerArchive.getCustomerKind())
|
||||||
|
|| "内部组织".equals(customerArchive.getCustomerKind()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 风险等级转义(C101-1 枚举 0=低风险/1=中风险/2=高风险):黑名单状态优先展示,无等级返回空
|
* 风险等级转义(C101-1 枚举 0=低风险/1=中风险/2=高风险):黑名单状态优先展示,无等级返回空
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user