feat: 新增履约记录通用C108-1推送支撑组件

This commit is contained in:
刘泉佳
2026-10-28 19:30:43 +08:00
parent 47fd0298db
commit 73be998f66
@@ -0,0 +1,134 @@
/**
* 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.support.hcs;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.hcs.config.HcsProperties;
import org.springblade.hcs.dto.HcsFormSaveVO;
import org.springblade.hcs.dto.HcsMechanismsDTO;
import org.springblade.hcs.dto.HcsPerfRecordFormDataDTO;
import org.springblade.hcs.dto.HcsPerfRecordPropsDTO;
import org.springblade.hcs.dto.HcsPerfRecordSaveDTO;
import org.springblade.hcs.dto.HcsResult;
import org.springblade.hcs.dto.HcsUserRefVO;
import org.springblade.hcs.exception.HcsException;
import org.springblade.hcs.feign.IHcsClient;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.HcsContractExeStage;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
/**
* HCS 履约记录通用新建支撑组件(C108-1,收款/开票/收票场景共用)
* <p>
* 付款申请场景因含 C108-2 实际金额推进与附件转传,仍走 {@link HcsPerfRecordSyncSupport};
* 本组件收敛其余场景的 C108-1 组装与推送:申请金额=实际金额、履约计划id 取已同步履约计划行合规阶段ID(必填)、
* 机制数据传空列表(无附件)、履约记录ID 由调用方按各自粒度持久化。
*
* @author Chill
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class HcsPerfRecordAddSupport {
private final IHcsClient hcsClient;
private final HcsProperties hcsProperties;
/**
* C108-1 新建履约记录(通用)
*
* @param contractManage 合同(须已推送合规,hcsFdId 必有)
* @param stageRow 已同步履约计划行(fd_plan_id 必填,无已同步计划行时抛出由调用方重试)
* @param applyNo 申请编号(收款=通知单号 / 开票=发票号 / 收票=发票号)
* @param amount 申请金额(=实际金额)
* @param perfDateMillis 履约日期(毫秒时间戳:收款=交易日期 / 开票=发票完成开票日期 / 收票=发票日期)
* @param planType 履约类型:payment 付款 / collection 收款
* @param jdDocNo 金蝶单据号(溯源)
* @param businessId TMS 业务ID(溯源)
* @param title 履约记录标题
* @return 推送结果描述
*/
public String pushPerfRecordAdd(ContractManage contractManage, HcsContractExeStage stageRow, String applyNo,
BigDecimal amount, Long perfDateMillis, String planType,
String jdDocNo, Long businessId, String title) {
// 【必填】fd_plan_id 履约计划id:无已同步计划行时无值可传,抛出由调用方置重试(合同链路首推后自愈)
if (stageRow == null || StringUtil.isBlank(stageRow.getHcsStageFdId())) {
throw new HcsException("C108 履约记录未匹配到已同步履约计划行,fd_plan_id 必传:applyNo=" + applyNo);
}
if (StringUtil.isBlank(contractManage.getHcsFdId())) {
throw new HcsException("C108 履约记录推送失败,合同尚未推送合规:contractNo=" + contractManage.getContractNo());
}
// 表单模板ID(配置 perf-record.xform-id,环境值 §9-U9,未配置不传)
String xformId = StringUtil.isBlank(hcsProperties.getPerfRecord().getXformId()) ? null : hcsProperties.getPerfRecord().getXformId();
HcsPerfRecordPropsDTO props = new HcsPerfRecordPropsDTO();
// 申请金额 / 实际金额:接口按字符串传值
props.setFdApplyAmount(amount == null ? null : amount.toPlainString());
props.setFdFactAmount(amount == null ? null : amount.toPlainString());
// 【必填】申请编号
props.setFdApplyNo(applyNo);
// 【必填】履约日期(毫秒时间戳)
props.setFdPlanDate(perfDateMillis);
// 履约类型(原文拼写 fd_paln_type 必须沿用)
props.setFdPalnType(planType);
// 性质:取关联履约计划行的款项性质
props.setFdProperty(stageRow.getFundNature());
// 履约计划id / 来源履约计划项ID:履约计划行合规阶段ID(HCS 只认自己的阶段ID)
props.setFdId(stageRow.getHcsStageFdId());
props.setFdPlanId(stageRow.getHcsStageFdId());
// 金蝶单据号(溯源用)
props.setFdJdDocNo(jdDocNo);
// 【必填】合同ID:HCS 合同ID
props.setFdContractId(contractManage.getHcsFdId());
// 业务ID / 创建时间(溯源)
props.setFdBusinessId(businessId == null ? null : String.valueOf(businessId));
props.setFdCreateTime(System.currentTimeMillis());
props.setFdXformId(xformId);
HcsPerfRecordFormDataDTO formData = new HcsPerfRecordFormDataDTO();
formData.setFdXformId(xformId);
formData.setFdDocSubject(title);
formData.setDynamicProps(props);
// 机制数据(C108-1 必填):无附件传空列表
HcsMechanismsDTO mechanisms = new HcsMechanismsDTO();
mechanisms.setAttachment(List.of());
HcsPerfRecordSaveDTO param = new HcsPerfRecordSaveDTO();
param.setCurUser(HcsUserRefVO.ofLoginName(hcsProperties.getOperatorLoginName()));
param.setFormData(formData);
param.setMechanisms(mechanisms);
log.info("HCS履约记录新建开始:title={},applyNo={},金额={}", title, applyNo, amount);
HcsResult<HcsFormSaveVO> result = hcsClient.perfRecordAdd(param);
if (result == null || !result.isSuccess() || result.getData() == null || StringUtil.isBlank(result.getData().getFdId())) {
log.error("HCS履约记录新建失败响应:{},title={},applyNo={}", result == null ? "无响应" : String.format("msg=%s, traceId=%s", result.getMsg(), result.getTraceId()), title, applyNo);
throw new HcsException("C108-1 履约记录新建失败:" + (result == null ? "响应为空" : result.getMsg()));
}
log.info("HCS履约记录新建成功:title={},applyNo={},perfFdId={}", title, applyNo, result.getData().getFdId());
return result.getData().getFdId();
}
}