diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsFieldConstant.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsFieldConstant.java index bfe5b372..749aed1c 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsFieldConstant.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsFieldConstant.java @@ -29,7 +29,7 @@ package org.springblade.transport.constant; * HCS(合同合规系统)列表查询 / 回调字段名常量(TMS 业务侧) *
* 与 {@link HcsContractFieldConstant}(C103-1/C103-11 表单字段)区分; - * 项目立项查询用下划线字段名,合同/开票查询与 B103 回调用驼峰字段名,以实际接口为准。 + * 项目立项查询用下划线字段名,合同/开票查询用驼峰字段名,以实际接口为准。 * * @author Chill */ @@ -111,91 +111,6 @@ public final class HcsFieldConstant { */ public static final String INVOICE_FD_STATUS = "fdStatus"; - // ==================== B103 特批结果回调候选字段(报文未定稿,多候选解析,§6-U1) ==================== - - /** - * 合同编号(驼峰) - */ - public static final String SPEC_CB_FD_CONTRACT_NO = "fdContractNo"; - - /** - * 合同编号 - */ - public static final String SPEC_CB_CONTRACT_NO = "contractNo"; - - /** - * 合同编号(下划线) - */ - public static final String SPEC_CB_FD_CONTRACT_NO_SNAKE = "fd_contract_no"; - - /** - * 合同编号(fd 模板字段,照 C103-3 查询惯例) - */ - public static final String SPEC_CB_FD_NUMBER = "fdNumber"; - - /** - * 单据ID(驼峰) - */ - public static final String SPEC_CB_FD_ID = "fdId"; - - /** - * 特批流程ID(驼峰) - */ - public static final String SPEC_CB_FD_SPEC_ID = "fdSpecId"; - - /** - * 特批流程ID(下划线) - */ - public static final String SPEC_CB_FD_SPEC_ID_SNAKE = "fd_spec_id"; - - /** - * 特批流程ID(specFdId) - */ - public static final String SPEC_CB_SPEC_FD_ID = "specFdId"; - - /** - * 审批结果 - */ - public static final String SPEC_CB_RESULT = "result"; - - /** - * 审批结果(驼峰) - */ - public static final String SPEC_CB_FD_RESULT = "fdResult"; - - /** - * 审批结果(下划线) - */ - public static final String SPEC_CB_FD_RESULT_SNAKE = "fd_result"; - - /** - * 审批结果(approvalResult) - */ - public static final String SPEC_CB_APPROVAL_RESULT = "approvalResult"; - - /** - * 状态(兜底候选) - */ - public static final String SPEC_CB_STATUS = "status"; - - /** - * 合同编号候选键(依次取首个非空) - */ - public static final String[] SPEC_CB_CONTRACT_NO_KEYS = {SPEC_CB_FD_CONTRACT_NO, SPEC_CB_CONTRACT_NO, - SPEC_CB_FD_CONTRACT_NO_SNAKE, SPEC_CB_FD_NUMBER}; - - /** - * 特批流程ID候选键(依次取首个非空) - */ - public static final String[] SPEC_CB_SPEC_FD_ID_KEYS = {SPEC_CB_FD_ID, SPEC_CB_FD_SPEC_ID, - SPEC_CB_FD_SPEC_ID_SNAKE, SPEC_CB_SPEC_FD_ID}; - - /** - * 审批结果候选键(依次取首个非空) - */ - public static final String[] SPEC_CB_RESULT_KEYS = {SPEC_CB_RESULT, SPEC_CB_FD_RESULT, - SPEC_CB_FD_RESULT_SNAKE, SPEC_CB_APPROVAL_RESULT, SPEC_CB_STATUS}; - private HcsFieldConstant() { } } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsSyncConstant.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsSyncConstant.java index 3533f1fb..7eed4fed 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsSyncConstant.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsSyncConstant.java @@ -85,7 +85,7 @@ public final class HcsSyncConstant { public static final String CHECK_TYPE_CREDIT = "credit"; /** - * 校验类型:合同特批(C103-8 发起 / B103 结果回传留痕) + * 校验类型:合同特批(C103-8 发起 / 合规特批结果推送留痕) */ public static final String CHECK_TYPE_SPEC = "spec"; @@ -148,6 +148,16 @@ public final class HcsSyncConstant { */ public static final String SPEC_STATUS_REJECTED = "rejected"; + /** + * 合规侧特批结果回传状态:通过(contractLegal/paymentLegal result 接口 status,D15 回传机制) + */ + public static final String LEGAL_RESULT_APPROVED = "APPROVED"; + + /** + * 合规侧特批结果回传状态:驳回 + */ + public static final String LEGAL_RESULT_REJECTED = "REJECTED"; + // ==================== 客商风险(C101-1,外部客商高风险/黑名单管控) ==================== /** diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/HcsSyncController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/HcsSyncController.java index 63e1d77e..dd48c78c 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/HcsSyncController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/HcsSyncController.java @@ -40,6 +40,7 @@ import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.StringUtil; import org.springblade.hcs.dto.HcsAttachmentRefDTO; import org.springblade.hcs.dto.HcsCurrencyVO; +import org.springblade.hcs.dto.HcsLegalResultDTO; import org.springblade.hcs.dto.HcsTemplateVO; import org.springblade.transport.constant.HcsSyncConstant; import org.springblade.transport.pojo.vo.CustomerRiskVO; @@ -246,7 +247,7 @@ public class HcsSyncController { } /** - * 合同特批结果人工确认(§6-U1 过渡方案:B103 报文未到位前与回调等效) + * 合同特批结果人工确认(§6-U1 过渡方案:与合规推送等效) */ @PostMapping("/contract/spec/confirm") @ApiOperationSupport(order = 14) @@ -257,16 +258,31 @@ public class HcsSyncController { } /** - * B103 特批结果回传接收(合规系统→TMS 回调,公开端点 + 原文留痕,前端接入设计 §3.4) + * 合同特批结果回传接收(合规系统 contractLegal/result 推送,替代未建设的 B103,公开端点 + 原文留痕) *
- * TODO 待联调(§6-U1):B103 报文未定,当前按候选字段(contractNo/fdId/result 等)解析,
- * 解析失败仅留痕不置状态,报文口径确认后完善解析。
+ * iPaaS 网关注册映射:/gwzh/HTHG/contractLegal/result → /hcs/contractLegal/result;
+ * 报文 {sourceSystem, requestId=TMS合同ID, status=APPROVED/REJECTED, reason},
+ * approved 恢复流程展示,rejected 联动合同审批驳回。
*/
- @PostMapping("/callback/spec-result")
+ @PostMapping("/contractLegal/result")
@PreAuth(AuthConstant.PERMIT_ALL)
@ApiOperationSupport(order = 15)
- @Operation(summary = "B103特批结果回传", description = "合规系统回调:合同特批结果回传接收,原文留痕并回写合同特批状态")
- public R
+ * iPaaS 网关注册映射:/gwzh/HTHG/paymentLegal/result → /hcs/paymentLegal/result;
+ * 报文同合同接口(requestId=TMS付款申请ID),付款特批结果不联动付款审批状态(§4.4)。
+ */
+ @PostMapping("/paymentLegal/result")
+ @PreAuth(AuthConstant.PERMIT_ALL)
+ @ApiOperationSupport(order = 16)
+ @Operation(summary = "付款特批结果回传接收", description = "合规系统推送付款特批结果,按付款申请ID定位并回写特批状态")
+ public R
* 业务闭环:合同推送时 C101-1 风险校验发现黑名单 → 置 hcs_spec_status=need 挂起(推送链路门禁跳过)→
* 内部特批审批通过后,前端上传特批材料(C103-2 取合规附件ID)并发起 C103-8 → 状态 processing(流程挂起)→
- * 集团审批结果经 B103 回传 TMS → approved 后既有扫描任务自动恢复 C103-1 推送,rejected 可重新发起。
+ * 集团审批结果经合规 contractLegal/result 接口推送 TMS(替代未建设的 B103)→
+ * approved 恢复流程,rejected 可重新发起。
*
- * TODO 待联调确认(前端接入设计 §6-U1):C103-8 与 B103 报文 v4 均未提供,
- * C103-8 按 C106-3 模式预估(双层嵌套返回),B103 回调按候选字段解析、原文留痕 blade_hcs_check_log。
+ * TODO 待联调确认(前端接入设计 §6-U1):C103-8 报文 v4 未提供,按 C106-3 模式预估(双层嵌套返回);
+ * 结果推送报文 {sourceSystem, requestId=合同ID, status=APPROVED/REJECTED, reason},原文留痕 blade_hcs_check_log。
*
* @author Chill
*/
@@ -73,7 +72,7 @@ public class HcsContractSpecSyncSupport {
private static final String SPEC_ATTACH_ENTITY_KEY = "fd_spc_approval_attach";
/**
- * B103 原文留痕最大长度(blade_hcs_check_log.msg 为 varchar(512))
+ * 结果推送原文留痕最大长度(blade_hcs_check_log.msg 为 varchar(512))
*/
private static final int CALLBACK_MSG_MAX_LENGTH = 500;
@@ -130,7 +129,7 @@ public class HcsContractSpecSyncSupport {
}
/**
- * 特批结果人工确认(§6-U1 过渡方案:B103 报文未到位前,页面确认与回调等效)
+ * 特批结果人工确认(§6-U1 过渡方案:页面确认与合规推送等效)
*
* @param id 合同ID
* @param result approved/rejected
@@ -157,36 +156,40 @@ public class HcsContractSpecSyncSupport {
}
/**
- * B103 特批结果回传处理(回调端点入口):候选字段解析 + 原文留痕,
- * approved 恢复合同"审批通过"展示(C103-1 已起草完成,无需恢复推送);rejected 联动合同审批驳回
+ * 合同特批结果接收处理(合规 contractLegal/result 推送,替代未建设的 B103,D15 回传机制):
+ * requestId=TMS 合同ID、status=APPROVED/REJECTED,
+ * approved 恢复合同"审批通过"展示;rejected 联动合同审批驳回;原文全量留痕
*
- * @param body B103 回调报文(结构待联调,原文全量留痕)
+ * @param param 合规推送报文
* @return 处理结果描述
*/
- public String handleSpecCallback(Map
* 编排顺序:特批(额度超额标记 need 时发起)→ 履约记录(审批通过新建 / 实际付款推进更新)。
* 特批流程ID 与履约记录ID 在各自 Support 内即时持久化;整体同步状态(hcs_sync_status)由本组件统一回写。
@@ -136,6 +137,51 @@ public class HcsPaymentSyncSupport {
return "特批结果已确认:" + result;
}
+ /**
+ * 付款特批结果接收处理(合规 paymentLegal/result 推送,替代未建设的 B103,D15 回传机制):
+ * requestId=TMS 付款申请ID、status=APPROVED/REJECTED;
+ * 付款特批结果不联动付款审批状态(§4.4),仅回写 hcs_spec_status
+ *
+ * @param param 合规推送报文
+ * @return 处理结果描述
+ */
+ public String handleLegalResult(HcsLegalResultDTO param) {
+ String requestId = param == null ? null : param.getRequestId();
+ PaymentApplication payment = locatePayment(requestId);
+ if (payment == null) {
+ log.warn("付款特批结果推送未定位到付款申请:requestId={},reason={}", requestId, param == null ? null : param.getReason());
+ return "未定位到付款申请(requestId=" + requestId + ")";
+ }
+ String normalizedStatus = param.getStatus() == null ? "" : param.getStatus().trim();
+ String status;
+ if (HcsSyncConstant.LEGAL_RESULT_APPROVED.equalsIgnoreCase(normalizedStatus)) {
+ status = HcsSyncConstant.SPEC_STATUS_APPROVED;
+ } else if (HcsSyncConstant.LEGAL_RESULT_REJECTED.equalsIgnoreCase(normalizedStatus)) {
+ status = HcsSyncConstant.SPEC_STATUS_REJECTED;
+ } else {
+ log.warn("付款特批结果状态未识别:paymentNo={},status={},reason={}", payment.getPaymentNo(), param.getStatus(), param.getReason());
+ return "状态字段未识别(paymentNo=" + payment.getPaymentNo() + ")";
+ }
+ payment.setHcsSpecStatus(status);
+ paymentApplicationMapper.updateById(payment);
+ log.info("付款特批结果推送处理完成:paymentNo={},结果={},reason={}", payment.getPaymentNo(), status, param.getReason());
+ return "特批结果已处理:" + status;
+ }
+
+ /**
+ * 按 TMS 付款申请ID 定位付款申请(合规推送 requestId)
+ */
+ private PaymentApplication locatePayment(String requestId) {
+ if (StringUtil.isBlank(requestId)) {
+ return null;
+ }
+ try {
+ return paymentApplicationMapper.selectById(Long.valueOf(requestId.trim()));
+ } catch (NumberFormatException exception) {
+ return null;
+ }
+ }
+
/**
* 回填整体同步状态置 synced
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsLegalResultDTO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsLegalResultDTO.java
new file mode 100644
index 00000000..eb0604a2
--- /dev/null
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsLegalResultDTO.java
@@ -0,0 +1,65 @@
+/**
+ * BladeX Commercial License Agreement
+ * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
+ *
+ * Use of this software is governed by the Commercial License Agreement
+ * obtained after purchasing a license from BladeX.
+ *
+ * 1. This software is for development use only under a valid license
+ * from BladeX.
+ *
+ * 2. Redistribution of this software's source code to any third party
+ * without a commercial license is strictly prohibited.
+ *
+ * 3. Licensees may copyright their own code but cannot use segments
+ * from this software for such purposes. Copyright of this software
+ * remains with BladeX.
+ *
+ * Using this software signifies agreement to this License, and the software
+ * must not be used for illegal purposes.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
+ * not liable for any claims arising from secondary or illegal development.
+ *
+ * Author: Chill Zhuang (bladejava@qq.com)
+ */
+package org.springblade.hcs.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 合同合规系统(HCS)特批结果回传报文
+ *
+ * 合规系统审批完成后经 iPaaS 网关推送 TMS:合同走 /hcs/contractLegal/result,
+ * 付款走 /hcs/paymentLegal/result,通过 status=APPROVED、驳回 status=REJECTED,报文两接口共用。
+ *
+ * @author Chill
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class HcsLegalResultDTO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 来源系统标识(约定 WLTMS,配置 thirdParty.hcs.src-system)
+ */
+ private String sourceSystem;
+ /**
+ * 业务单据ID(合同特批=TMS 合同ID,付款特批=TMS 付款申请ID)
+ */
+ private String requestId;
+ /**
+ * 审批结果:APPROVED 通过 / REJECTED 驳回
+ */
+ private String status;
+ /**
+ * 结果说明(驳回原因等,非必传)
+ */
+ private String reason;
+}