diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsContractFieldConstant.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsContractFieldConstant.java
new file mode 100644
index 00000000..b937c7b7
--- /dev/null
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/HcsContractFieldConstant.java
@@ -0,0 +1,179 @@
+/**
+ * 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.transport.constant;
+
+/**
+ * HCS(合同合规系统)C103-1/C103-11 合同发起 xformFields 字段名常量
+ *
+ * 字段名取自 v4 接口文档「合同字段说明」,fdSepcailContract 为文档原文拼写(Special 笔误,必须沿用);
+ * 命名照 {@link HcsSyncConstant} 惯例。
+ *
+ * @author Chill
+ */
+public final class HcsContractFieldConstant {
+
+ // ==================== 合同发起 xformFields 字段名(fdXformField.name) ====================
+
+ /**
+ * 合同ID(更新时传 C103-1 返回的 fdContractId)
+ */
+ public static final String FIELD_FD_ID = "fdId";
+
+ /**
+ * 合同编号(fd 模板字段)
+ */
+ public static final String FIELD_FD_NUMBER = "fdNumber";
+
+ /**
+ * 合同编号(CONTRACT 模板字段)
+ */
+ public static final String FIELD_CONTRACT_NO = "CONTRACT_NO";
+
+ /**
+ * 合同标题(fd 模板字段)
+ */
+ public static final String FIELD_FD_SUBJECT = "fdSubject";
+
+ /**
+ * 合同名称(CONTRACT 模板字段)
+ */
+ public static final String FIELD_CONTRACT_NAME = "CONTRACT_NAME";
+
+ /**
+ * 合同金额(fd 模板字段)
+ */
+ public static final String FIELD_FD_AMOUNT = "fdAmount";
+
+ /**
+ * 合同金额(AMOUNT 模板字段)
+ */
+ public static final String FIELD_AMOUNT = "AMOUNT";
+
+ /**
+ * 币种(fd 模板字段)
+ */
+ public static final String FIELD_FD_CURRENCY_ID = "fdCurrencyId";
+
+ /**
+ * 币种(CURRENCY 模板字段)
+ */
+ public static final String FIELD_CURRENCY = "CURRENCY";
+
+ /**
+ * 合同结算类型:payment=付款,payment_collection=收支双向,collection=收款,none=不结算
+ */
+ public static final String FIELD_FD_SETTLEMENT_TYPE = "fdSettlementType";
+
+ /**
+ * 特批流程(文档原文拼写笔误,必须沿用)
+ */
+ public static final String FIELD_FD_SEPCAIL_CONTRACT = "fdSepcailContract";
+
+ /**
+ * 合同类型
+ */
+ public static final String FIELD_CONTRACT_TYPE = "CONTRACT_TYPE";
+
+ /**
+ * 甲方名称
+ */
+ public static final String FIELD_PARTY_A = "PARTY_A";
+
+ /**
+ * 乙方名称
+ */
+ public static final String FIELD_PARTY_B = "PARTY_B";
+
+ /**
+ * 签订日期(yyyy-MM-dd,fdType=timestamp)
+ */
+ public static final String FIELD_SIGN_DATE = "SIGN_DATE";
+
+ /**
+ * 预计开始时间(合同开始期限为指定日期时必填)
+ */
+ public static final String FIELD_FD_ESTIMATE_START_TIME = "fdEstimateStartTime";
+
+ /**
+ * 预计结束时间(合同结束期限为指定日期时必填)
+ */
+ public static final String FIELD_FD_ESTIMATE_END_TIME = "fdEstimateEndTime";
+
+ /**
+ * 合同开始期限:signDate=签订之日起算,specifiedDate=指定日期
+ */
+ public static final String FIELD_FD_START_TERM = "fdStartTerm";
+
+ /**
+ * 合同结束期限:signTerm=按签订后期限,specifiedDate=指定日期,noTerm=无固定期限
+ */
+ public static final String FIELD_FD_END_TERM = "fdEndTerm";
+
+ /**
+ * 创建时间(yyyy-MM-dd,fdType=timestamp)
+ */
+ public static final String FIELD_CREATE_TIME = "CREATE_TIME";
+
+ /**
+ * 创建时间(fd 模板字段,yyyy-MM-dd,fdType=timestamp)
+ */
+ public static final String FIELD_FD_CREATE_TIME = "fdCreateTime";
+
+ /**
+ * 同步时间(yyyy-MM-dd,fdType=timestamp)
+ */
+ public static final String FIELD_FD_SYN_TIME = "fd_syn_time";
+
+ /**
+ * 承办人名称
+ */
+ public static final String FIELD_CREATE_USER_NAME = "CREATE_USER_NAME";
+
+ /**
+ * 合同状态:draft/approving/approved 等(v4 必填)
+ */
+ public static final String FIELD_CONTRACT_STATUS = "CONTRACT_STATUS";
+
+ /**
+ * 合同份数(v4 必填)
+ */
+ public static final String FIELD_FD_SERVINGS = "fdServings";
+
+ /**
+ * 合同说明(选填)
+ */
+ public static final String FIELD_FD_DESC = "fdDesc";
+
+ // ==================== 期限枚举值 ====================
+
+ /**
+ * 期限取值:指定日期(fdStartTerm/fdEndTerm,TMS 固定按指定日期起算)
+ */
+ public static final String TERM_SPECIFIED_DATE = "specifiedDate";
+
+ private HcsContractFieldConstant() {
+ }
+}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsContractSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsContractSyncSupport.java
index 6ade9dc4..80667201 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsContractSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsContractSyncSupport.java
@@ -31,6 +31,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.hcs.config.HcsProperties;
+import org.springblade.hcs.dto.HcsAttachmentRefDTO;
import org.springblade.hcs.dto.HcsContractDraftDTO;
import org.springblade.hcs.dto.HcsContractDraftVO;
import org.springblade.hcs.dto.HcsContractFieldJsonDTO;
@@ -47,6 +48,7 @@ import org.springblade.hcs.exception.HcsException;
import org.springblade.hcs.feign.IHcsClient;
import org.springblade.system.cache.UserCache;
import org.springblade.system.pojo.entity.User;
+import org.springblade.transport.constant.HcsContractFieldConstant;
import org.springblade.transport.constant.HcsSyncConstant;
import org.springblade.transport.mapper.ContractManageMapper;
import org.springblade.transport.mapper.CustomerArchiveMapper;
@@ -68,7 +70,7 @@ import java.util.Objects;
/**
* HCS 合同同步支撑组件(C103-1 发起 / C103-11 更新,设计文档 §5.2)
*
- * 扫描任务按序执行:① 客商风险校验(可配开关,黑名单阻断)→ ② 附件转传(挂载点待 §9-U8 确认,先转传缓存)→
+ * 扫描任务按序执行:① 客商风险校验(可配开关,黑名单阻断)→ ② 附件转传(v4 挂载点 fdFieldJson.attachment,随 C103-1 挂载)→
* ③ C103-3 判重(§9-U4 查询能力联调确认)→ ④ C103-1 起草 / 变更单 C103-11 更新(§9-U5 定位方式待联调)→
* ⑤ 履约规则 C103-9 行级同步({@link HcsExeStageSyncSupport})。
* 结果留痕:风险校验写 blade_hcs_check_log 与合同 hcs_risk_* 字段;推送结果回填 hcs_fd_id/hcs_sync_status。
@@ -81,10 +83,9 @@ import java.util.Objects;
public class HcsContractSyncSupport {
/**
- * 合同金额等 xformFields 值一律字符串传值
+ * 合同金额等 xformFields 值一律字符串传值;时间字段 v4 要求 yyyy-MM-dd(fdType=timestamp)
*/
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* C101-1 黑名单状态取值(示例 no 表示非黑名单,§9-U3 字典值联调确认)
@@ -117,8 +118,8 @@ public class HcsContractSyncSupport {
return "高风险客商,合同已挂起待特批(C103-8)";
}
}
- // ② 附件转传(先转传并缓存合规附件ID,C103-1 挂载方式待 §9-U8 确认后接线)
- transferAttachmentsIfEnabled(contractManage);
+ // ② 附件转传(v4 已明确挂载点:C103-1 fdFieldJson.attachment,转传取得合规附件ID 后随发起报文挂载)
+ List attachmentFdIds = transferAttachmentsIfEnabled(contractManage);
// ③④ 首推判重后起草(C103-1);已有合规ID(变更单)走更新(C103-11)
String resultMessage;
if (StringUtil.isBlank(contractManage.getHcsFdId())) {
@@ -127,7 +128,7 @@ public class HcsContractSyncSupport {
markSynced(contractManage, existFdId, "判重命中,回填已有合规合同ID");
resultMessage = "判重命中,回填已有合规合同ID";
} else {
- String fdContractId = draftContract(contractManage);
+ String fdContractId = draftContract(contractManage, attachmentFdIds);
// 先持久化合规合同ID(调用方必须保存),履约规则同步失败时下轮凭其走更新补偿
markSynced(contractManage, fdContractId, "C103-1 合同发起成功");
resultMessage = "C103-1 合同发起成功";
@@ -232,19 +233,19 @@ public class HcsContractSyncSupport {
/**
* C103-1 合同发起,返回合规合同 fdContractId
*/
- private String draftContract(ContractManage contractManage) {
- HcsContractDraftDTO param = buildDraftParam(contractManage);
- log.info("HCS合同推送开始:{}(C103-1 发起)", contractManage.getContractNo());
+ private String draftContract(ContractManage contractManage, List attachmentFdIds) {
+ HcsContractDraftDTO param = buildDraftParam(contractManage, attachmentFdIds);
+ log.info("HCS合同推送开始:{}(C103-1 发起,挂载附件 {} 个)", contractManage.getContractNo(), attachmentFdIds.size());
HcsResult result = hcsClient.contractDraft(param);
return validateDraftResult(contractManage, result);
}
/**
- * C103-11 合同更新(入参同发起;TODO 待联调(§9-U5):HCS 侧如何定位已有合同 v4 未说明)
+ * C103-11 合同更新(入参同发起,v4 新增顶层 fdId 定位已有合同)
*/
private void updateContract(ContractManage contractManage) {
- HcsContractDraftDTO param = buildDraftParam(contractManage);
- log.info("HCS合同推送开始:{}(C103-11 更新,§9-U5 定位方式待联调)", contractManage.getContractNo());
+ HcsContractDraftDTO param = buildDraftParam(contractManage, null);
+ log.info("HCS合同推送开始:{}(C103-11 更新,附件不重复挂载待联调确认)", contractManage.getContractNo());
HcsResult result = hcsClient.contractUpdate(param);
if (result == null || !result.isSuccess()) {
log.error("HCS合同更新失败响应:{},contractNo={}", result == null ? "无响应" : String.format("msg=%s, traceId=%s", result.getMsg(), result.getTraceId()), contractManage.getContractNo());
@@ -253,10 +254,13 @@ public class HcsContractSyncSupport {
}
/**
- * 组装 C103-1/C103-11 入参(字段标注照 §3.4 规范,映射表见设计文档 §5.2)
+ * 组装 C103-1/C103-11 入参(字段标注照 §3.4 规范,映射表见设计文档 §5.2);
+ * attachmentFdIds 新建传合规附件ID 列表(必填,无附件传空列表),更新传 null 不挂载
*/
- private HcsContractDraftDTO buildDraftParam(ContractManage contractManage) {
+ private HcsContractDraftDTO buildDraftParam(ContractManage contractManage, List attachmentFdIds) {
HcsContractDraftDTO param = new HcsContractDraftDTO();
+ // 【必填】合同ID:C103-11 更新顶层必填(传 C103-1 返回的 fdContractId),C103-1 新建不传(v4 新增)
+ param.setFdId(contractManage.getHcsFdId());
// 【必填】合同模板ID:template-mapping[contractCategory](§9-U7 待合规方提供模板ID清单)
param.setFdTemplateId(requireTemplateId(contractManage));
// 【必填】外部系统标识:fd_sources,配置 thirdParty.hcs.src-system(D14)
@@ -269,54 +273,84 @@ public class HcsContractSyncSupport {
fieldJson.setXformFields(buildXformFields(contractManage));
// 相对方(签署方):甲方/乙方,编号按名称反查 CustomerArchive(§9-U6)
fieldJson.setSigner(buildSigners(contractManage));
+ // 【必填】附件数据:C103-1 必填(无附件传空列表),fdBindType=ADD;更新不挂载(传 null)
+ if (attachmentFdIds != null) {
+ fieldJson.setAttachment(attachmentFdIds.stream().map(fdId -> {
+ HcsAttachmentRefDTO attachment = new HcsAttachmentRefDTO();
+ // 【必填】附件ID(C103-2 转传返回)
+ attachment.setFdId(fdId);
+ // 【必填】操作类型:ADD 新增
+ attachment.setFdBindType("ADD");
+ return attachment;
+ }).toList());
+ }
param.setFdFieldJson(fieldJson);
return param;
}
/**
- * xformFields 模板字段(字段名/中文名取自《桂物合同集成接口逻辑梳理》§5.1 合同字段说明)
+ * xformFields 模板字段(字段名取 {@link HcsContractFieldConstant},中文名取自《桂物合同集成接口逻辑梳理》§5.1 合同字段说明)
*/
private List buildXformFields(ContractManage contractManage) {
List fields = new ArrayList<>();
+ // 【必填】合同ID:更新时传合同发起返回的 fdContractId 的值(v4 合同字段说明)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_ID, "合同ID", contractManage.getHcsFdId()));
// 【必填】合同编号:ContractManage.contractNo
- fields.add(field("fdNumber", "合同编号", contractManage.getContractNo()));
- fields.add(field("CONTRACT_NO", "合同编号", contractManage.getContractNo()));
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_NUMBER, "合同编号", contractManage.getContractNo()));
+ fields.add(field(HcsContractFieldConstant.FIELD_CONTRACT_NO, "合同编号", contractManage.getContractNo()));
// 【必填】合同标题:ContractManage.contractName
- fields.add(field("fdSubject", "合同标题", contractManage.getContractName()));
- fields.add(field("CONTRACT_NAME", "合同名称", contractManage.getContractName()));
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_SUBJECT, "合同标题", contractManage.getContractName()));
+ fields.add(field(HcsContractFieldConstant.FIELD_CONTRACT_NAME, "合同名称", contractManage.getContractName()));
// 【必填】合同金额:contractAmount(字符串传值)
- fields.add(field("fdAmount", "合同金额", toPlainString(contractManage.getContractAmount())));
- fields.add(field("AMOUNT", "合同金额", toPlainString(contractManage.getContractAmount())));
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_AMOUNT, "合同金额", toPlainString(contractManage.getContractAmount())));
+ fields.add(field(HcsContractFieldConstant.FIELD_AMOUNT, "合同金额", toPlainString(contractManage.getContractAmount())));
// 币种:TMS 结算币种经 currency-name-mapping 映射(默认 RMB→人民币,照金蝶惯例)
- fields.add(field("fdCurrencyId", "币种", mapCurrencyName(contractManage.getSettlementCurrency())));
- fields.add(field("CURRENCY", "币种", mapCurrencyName(contractManage.getSettlementCurrency())));
- // 合同结算类型:settlement-type-mapping[settlementMode](映射到"付款/收款"待联调,§9-U3,未配置不传)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_CURRENCY_ID, "币种", mapCurrencyName(contractManage.getSettlementCurrency())));
+ fields.add(field(HcsContractFieldConstant.FIELD_CURRENCY, "币种", mapCurrencyName(contractManage.getSettlementCurrency())));
+ // 合同结算类型:settlement-type-mapping[settlementMode](必填:payment/payment_collection/collection/none,映射到"付款/收款"待联调,§9-U3,未配置不传)
String settlementType = hcsProperties.getContract().getSettlementTypeMapping().get(contractManage.getSettlementMode());
if (StringUtil.isNotBlank(settlementType)) {
- fields.add(field("fdSettlementType", "合同结算类型", settlementType));
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_SETTLEMENT_TYPE, "合同结算类型", settlementType));
} else {
log.warn("HCS合同结算类型映射缺失:settlementMode=[{}] 不在 contract.settlement-type-mapping,fdSettlementType 不传(§9-U3)", contractManage.getSettlementMode());
}
// 特批流程:fdSepcailContract 固定 false(原文拼写笔误必须沿用,D15,配置项预留)
- fields.add(field("fdSepcailContract", "特批流程", hcsProperties.getContract().isSpecialContractEnabled() ? "true" : "false"));
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_SEPCAIL_CONTRACT, "特批流程", hcsProperties.getContract().isSpecialContractEnabled() ? "true" : "false"));
// 合同类型:ContractManage.contractCategory
- fields.add(field("CONTRACT_TYPE", "合同类型", contractManage.getContractCategory()));
+ fields.add(field(HcsContractFieldConstant.FIELD_CONTRACT_TYPE, "合同类型", contractManage.getContractCategory()));
// 甲方名称/乙方名称:TMS 存名称字符串
- fields.add(field("PARTY_A", "甲方名称", contractManage.getPartyA()));
- fields.add(field("PARTY_B", "乙方名称", contractManage.getPartyB()));
- // 【必填】签订日期:signDate(fdType=timestamp)
- fields.add(timestampField("SIGN_DATE", "签订日期", contractManage.getSignDate()));
- // 预计开始/结束时间:startDate/endDate(fdType=timestamp)
- fields.add(timestampField("fdEstimateStartTime", "预计开始时间", contractManage.getStartDate()));
- fields.add(timestampField("fdEstimateEndTime", "预计结束时间", contractManage.getEndDate()));
- // 创建时间:createTime(fdType=timestamp)
- fields.add(timestampField("CREATE_TIME", "创建时间", contractManage.getCreateTime()));
- fields.add(timestampField("fdCreateTime", "创建时间", contractManage.getCreateTime()));
- // 同步时间:推送时刻(fdType=timestamp)
- fields.add(timestampField("fd_syn_time", "同步时间", LocalDateTime.now()));
- // 承办人名称:handlerUserName
- fields.add(field("CREATE_USER_NAME", "承办人名称", contractManage.getHandlerUserName()));
- // TODO 待确认:合同状态 CONTRACT_STATUS,TMS 无直接对应,是否必传联调确认(§9-U3),一期不传
+ fields.add(field(HcsContractFieldConstant.FIELD_PARTY_A, "甲方名称", contractManage.getPartyA()));
+ fields.add(field(HcsContractFieldConstant.FIELD_PARTY_B, "乙方名称", contractManage.getPartyB()));
+ // 【必填】签订日期:signDate(yyyy-MM-dd,fdType=timestamp)
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_SIGN_DATE, "签订日期", contractManage.getSignDate()));
+ // 预计开始/结束时间:startDate/endDate(fdType=timestamp,期限为指定日期时必填)
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_FD_ESTIMATE_START_TIME, "预计开始时间", contractManage.getStartDate()));
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_FD_ESTIMATE_END_TIME, "预计结束时间", contractManage.getEndDate()));
+ // 【必填】合同开始期限:TMS 固定指定日期起算,日期取 fdEstimateStartTime(v4 合同字段说明)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_START_TERM, "合同开始期限", contractManage.getStartDate() == null ? null : HcsContractFieldConstant.TERM_SPECIFIED_DATE));
+ // 【必填】合同结束期限:TMS 固定指定日期,日期取 fdEstimateEndTime(v4 合同字段说明)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_END_TERM, "合同结束期限", contractManage.getEndDate() == null ? null : HcsContractFieldConstant.TERM_SPECIFIED_DATE));
+ // 【必填】创建时间:createTime(yyyy-MM-dd,fdType=timestamp)
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_CREATE_TIME, "创建时间", contractManage.getCreateTime()));
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_FD_CREATE_TIME, "创建时间", contractManage.getCreateTime()));
+ // 【必填】同步时间:推送时刻(yyyy-MM-dd,fdType=timestamp)
+ fields.add(timestampField(HcsContractFieldConstant.FIELD_FD_SYN_TIME, "同步时间", LocalDateTime.now()));
+ // 【必填】承办人名称:handlerUserName
+ fields.add(field(HcsContractFieldConstant.FIELD_CREATE_USER_NAME, "承办人名称", contractManage.getHandlerUserName()));
+ // 【必填】合同状态:status-mapping[approvalStatus](v4 必填,draft/approving/approved 等,§9-U3 待联调后配置,未配置不传)
+ String contractStatus = hcsProperties.getContract().getStatusMapping().get(contractManage.getApprovalStatus());
+ if (StringUtil.isNotBlank(contractStatus)) {
+ fields.add(field(HcsContractFieldConstant.FIELD_CONTRACT_STATUS, "合同状态", contractStatus));
+ } else {
+ log.warn("HCS合同状态映射缺失:approvalStatus=[{}] 不在 contract.status-mapping,CONTRACT_STATUS 不传(§9-U3)", contractManage.getApprovalStatus());
+ }
+ // 【必填】合同份数:copyCount(v4 合同字段说明)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_SERVINGS, "合同份数", contractManage.getCopyCount() == null ? null : String.valueOf(contractManage.getCopyCount())));
+ // 合同说明:remark(选填)
+ fields.add(field(HcsContractFieldConstant.FIELD_FD_DESC, "合同说明", contractManage.getRemark()));
+ // TODO 待联调(v4 选填字段,暂不传):fdCoTakers 协办人(TMS 无对应)、fdUnderTaker/fdUnderTakerDept 承办人及部门(组织架构对象传值方式待确认)、
+ // fdRelations 关联合同(数组)、fdProject 关联项目 {"fdId": 合规项目ID}(对象传值方式待确认,TMS projectId 可经立项 hcs_fd_id 关联)、
+ // fdContractGwNature 结算模式 open/close、fdContractAttribute 合同属性(枚举值文档未给出,TMS 无对应)、fdUrgencyLevel 紧急程度(TMS 无对应)
return fields;
}
@@ -347,16 +381,16 @@ public class HcsContractSyncSupport {
}
/**
- * 附件转传(可配开关):合同主文件 approved=true + 其它附件,合规附件ID 走映射缓存
+ * 附件转传(可配开关):合同主文件 approved=true + 其它附件,返回合规附件ID 列表(挂载 C103-1 fdFieldJson.attachment)
*/
- private void transferAttachmentsIfEnabled(ContractManage contractManage) {
+ private List transferAttachmentsIfEnabled(ContractManage contractManage) {
if (!hcsProperties.getAttachment().isTransferEnabled()) {
- return;
+ return List.of();
}
List attachmentFdIds = hcsAttachmentSupport.transferContractAttachments(
contractManage.getContractFileJson(), contractManage.getAttachmentsJson(), requireLoginName(contractManage));
- // TODO 待联调(§9-U8):C103-1 未定义附件字段,转传后的合规附件ID 暂存映射缓存,挂载方式确认后接线
- log.info("HCS合同附件转传完成:contractNo={},共 {} 个附件(挂载点待 §9-U8 确认)", contractManage.getContractNo(), attachmentFdIds.size());
+ log.info("HCS合同附件转传完成:contractNo={},共 {} 个附件(随 C103-1 挂载)", contractManage.getContractNo(), attachmentFdIds.size());
+ return attachmentFdIds;
}
/**
@@ -487,7 +521,7 @@ public class HcsContractSyncSupport {
}
/**
- * 时间模板字段(fdType=timestamp,日期传 yyyy-MM-dd,时间传 yyyy-MM-dd HH:mm:ss)
+ * 时间模板字段(fdType=timestamp,v4 要求传 yyyy-MM-dd)
*/
private HcsXformFieldDTO timestampField(String name, String label, Object value) {
if (value == null) {
@@ -497,11 +531,11 @@ public class HcsContractSyncSupport {
if (value instanceof LocalDate localDate) {
text = localDate.format(DATE_FORMATTER);
} else if (value instanceof LocalDateTime localDateTime) {
- text = localDateTime.format(DATETIME_FORMATTER);
+ text = localDateTime.format(DATE_FORMATTER);
} else {
// BaseEntity.createTime 为 Date 类型
- text = DATETIME_FORMATTER.format(((java.util.Date) value).toInstant()
- .atZone(java.time.ZoneId.systemDefault()).toLocalDateTime());
+ text = DATE_FORMATTER.format(((java.util.Date) value).toInstant()
+ .atZone(java.time.ZoneId.systemDefault()).toLocalDate());
}
HcsXformFieldDTO field = field(name, label, text);
// 时间字段需带 fdType=timestamp
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsExeStageSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsExeStageSyncSupport.java
index 9c1cbf6e..089bd915 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsExeStageSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsExeStageSyncSupport.java
@@ -133,15 +133,15 @@ public class HcsExeStageSyncSupport {
stage.setFdEopExeplanOperateType(row.getRowOp());
// 【必填】履约类型:payment=付款 / collection=收款
stage.setFdPerformType(row.getPerformType());
- // 款项性质:prepayment/progress/acceptance/retention
+ // 【必填】款项性质:prepayment/progress/acceptance/retention
stage.setFdFundNature(row.getFundNature());
- // 计划金额(元)
+ // 【必填】计划金额(元)
stage.setFdFundAmount(row.getFundAmount());
- // 资金日期(毫秒时间戳)
+ // 【必填】资金日期(毫秒时间戳)
stage.setFdFundDate(toMillis(row.getFundDate()));
- // 开票规则(如 payFirst)
+ // 【必填】开票规则:payFirst=先款后票 / invoiceFirst=先票后款
stage.setFdInvoiceRule(row.getInvoiceRule());
- // 账期
+ // 【必填】账期(天)
stage.setFdInvoiceCycle(row.getInvoiceCycle());
// 金额类型:行维护值,空取配置 thirdParty.hcs.exe-stage.fund-type(默认 byAmount)
stage.setFdFundType(StringUtil.isBlank(row.getFundType()) ? hcsProperties.getExeStage().getFundType() : row.getFundType());
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsInvoiceRegSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsInvoiceRegSyncSupport.java
index b130a851..59466cf8 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsInvoiceRegSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsInvoiceRegSyncSupport.java
@@ -38,6 +38,7 @@ import org.springblade.hcs.dto.HcsInvoiceRegUpdateDTO;
import org.springblade.hcs.dto.HcsPageQueryDTO;
import org.springblade.hcs.dto.HcsPageVO;
import org.springblade.hcs.dto.HcsInvoiceRegVO;
+import org.springblade.hcs.dto.HcsRefVO;
import org.springblade.hcs.dto.HcsResult;
import org.springblade.hcs.exception.HcsException;
import org.springblade.hcs.feign.IHcsClient;
@@ -47,10 +48,12 @@ import org.springblade.system.cache.UserCache;
import org.springblade.system.pojo.entity.Dept;
import org.springblade.system.pojo.entity.User;
import org.springblade.transport.constant.HcsSyncConstant;
+import org.springblade.transport.mapper.ContractManageMapper;
import org.springblade.transport.mapper.InvoiceApplicationInvoiceMapper;
import org.springblade.transport.mapper.InvoiceApplicationMapper;
import org.springblade.transport.mapper.InvoiceApplicationSettlementMapper;
import org.springblade.transport.mapper.FormalSettlementMapper;
+import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.FormalSettlement;
import org.springblade.transport.pojo.entity.InvoiceApplication;
import org.springblade.transport.pojo.entity.InvoiceApplicationInvoice;
@@ -83,6 +86,7 @@ public class HcsInvoiceRegSyncSupport {
private final InvoiceApplicationSettlementMapper invoiceApplicationSettlementMapper;
private final InvoiceApplicationInvoiceMapper invoiceApplicationInvoiceMapper;
private final FormalSettlementMapper formalSettlementMapper;
+ private final ContractManageMapper contractManageMapper;
private final HcsAttachmentSupport hcsAttachmentSupport;
/**
@@ -149,7 +153,10 @@ public class HcsInvoiceRegSyncSupport {
// 登记日期:applicationDate(毫秒时间戳)
param.setFdRegisterDate(toMillis(application.getApplicationDate()));
// 【必填】合同编号:经应收结算链路回溯(§9-U10 关联字段确认后细化)
- param.setFdContractNumber(requireContractNumber(application));
+ ContractRef contractRef = requireContractRef(application);
+ param.setFdContractNumber(contractRef.contractNo());
+ // 合同 {fdId, fdName}:fdId 传合规合同ID(未推送不传),名称取结算单合同名称(v4 新增)
+ param.setFdContract(contractRef.contract());
// 发票类型:invoice-type-mapping 字典映射(§9-U3,未配置不传)
param.setFdInvoiceType(hcsProperties.getInvoice().getInvoiceTypeMapping().get(application.getInvoiceType()));
if (param.getFdInvoiceType() == null) {
@@ -228,22 +235,37 @@ public class HcsInvoiceRegSyncSupport {
}
/**
- * 应收结算链路回溯合同编号:开票申请 → 应收结算关联 → 正式结算单合同编号(§9-U10)
+ * 应收结算链路回溯合同引用:开票申请 → 应收结算关联 → 正式结算单合同(§9-U10);
+ * fdContractNumber 必填,fdContract 随链路回填(fdId 为合规合同ID,未推送不传)
*/
- private String requireContractNumber(InvoiceApplication application) {
+ private ContractRef requireContractRef(InvoiceApplication application) {
InvoiceApplicationSettlement relation = invoiceApplicationSettlementMapper.selectOne(Wrappers.lambdaQuery()
.eq(InvoiceApplicationSettlement::getInvoiceApplicationId, application.getId())
.last("limit 1"));
if (relation != null && relation.getFormalSettlementId() != null) {
FormalSettlement settlement = formalSettlementMapper.selectById(relation.getFormalSettlementId());
if (settlement != null && StringUtil.isNotBlank(settlement.getContractNo())) {
- return settlement.getContractNo();
+ HcsRefVO contract = new HcsRefVO();
+ contract.setFdName(settlement.getContractName());
+ if (settlement.getContractId() != null) {
+ ContractManage contractManage = contractManageMapper.selectById(settlement.getContractId());
+ if (contractManage != null) {
+ contract.setFdId(contractManage.getHcsFdId());
+ }
+ }
+ return new ContractRef(settlement.getContractNo(), contract);
}
}
throw new HcsException("C111 开票登记推送失败,应收结算链路回溯不到合同编号(applicationNo=" + application.getApplicationNo()
+ ",§9-U10 待确认关联字段)");
}
+ /**
+ * 合同引用(fdContractNumber / fdContract)
+ */
+ private record ContractRef(String contractNo, HcsRefVO contract) {
+ }
+
/**
* 结算币种ID(currency-id-mapping,必填;TMS 无币种字段按 RMB 取映射)
*/
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsMasterDataSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsMasterDataSupport.java
index d09c6836..0c123fd8 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsMasterDataSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsMasterDataSupport.java
@@ -177,10 +177,11 @@ public class HcsMasterDataSupport {
}
/**
- * 分页查询基础参数(columns 必填)
+ * 分页查询基础参数(offset/pageSize 必填,columns 各主数据接口选填)
*/
private HcsPageQueryDTO baseQuery() {
HcsPageQueryDTO query = new HcsPageQueryDTO();
+ // 【必填】每页条数
query.setPageSize(PAGE_SIZE);
return query;
}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsPerfRecordSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsPerfRecordSyncSupport.java
index 0ed6a3b1..740cfbc7 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsPerfRecordSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsPerfRecordSyncSupport.java
@@ -122,8 +122,13 @@ public class HcsPerfRecordSyncSupport {
// 【必填】当前操作人 {fdLoginName}(付款申请创建人,§9-U2)
param.setCurUser(HcsUserRefVO.ofLoginName(operatorLoginName));
param.setFormData(buildFormData(payment));
- // 附件挂载:attachmentsJson 转传,fdEntityKey=fd_plan_att
- param.setMechanisms(buildMechanisms(payment, operatorLoginName));
+ // 【必填】机制数据(附件):C108-1 必填,无附件传空列表(附件转传开关关闭或无附件时)
+ HcsMechanismsDTO mechanisms = buildMechanisms(payment, operatorLoginName);
+ if (mechanisms == null) {
+ mechanisms = new HcsMechanismsDTO();
+ mechanisms.setAttachment(List.of());
+ }
+ param.setMechanisms(mechanisms);
return param;
}
@@ -152,9 +157,9 @@ public class HcsPerfRecordSyncSupport {
props.setFdApplyAmount(payment.getAppliedAmount() == null ? null : payment.getAppliedAmount().toPlainString());
// 实际金额:paidAmount(实际付款推进后更新)
props.setFdFactAmount(payment.getPaidAmount() == null ? null : payment.getPaidAmount().toPlainString());
- // 申请编号:付款申请单号(接口文档 §8.3 字段)
+ // 【必填】申请编号:付款申请单号
props.setFdApplyNo(payment.getPaymentNo());
- // 计划日期:applyDate(毫秒时间戳)
+ // 【必填】计划日期:applyDate(毫秒时间戳)
props.setFdPlanDate(toMillis(payment.getApplyDate()));
// 计划类型:paymentType(原文拼写 fd_paln_type 必须沿用)
props.setFdPalnType(payment.getPaymentType());
@@ -162,10 +167,17 @@ public class HcsPerfRecordSyncSupport {
props.setFdProperty(stageRow == null ? null : stageRow.getFundNature());
// 来源履约计划项ID:关联履约阶段 hcs_stage_fd_id(无关联则不传,§5.6)
props.setFdId(stageRow == null ? null : stageRow.getHcsStageFdId());
- // 合同ID:HCS 合同ID(合同未推送时不传)
+ // 【必填】合同ID:HCS 合同ID(合同未推送时为空,联调确认兜底口径)
props.setFdContractId(contractManage == null ? null : contractManage.getHcsFdId());
+ // 业务ID:TMS 付款申请单主键(方便溯源,v4 新增)
+ props.setFdBusinessId(payment.getId() == null ? null : String.valueOf(payment.getId()));
+ // 创建时间:createTime(毫秒时间戳,v4 新增)
+ props.setFdCreateTime(payment.getCreateTime() == null ? null : payment.getCreateTime().toInstant().toEpochMilli());
// 表单模板ID:配置 perf-record.xform-id(环境值,§9-U9,未配置不传)
- props.setFdXformId(StringUtil.isBlank(hcsProperties.getPerfRecord().getXformId()) ? null : hcsProperties.getPerfRecord().getXformId());
+ String xformId = StringUtil.isBlank(hcsProperties.getPerfRecord().getXformId()) ? null : hcsProperties.getPerfRecord().getXformId();
+ props.setFdXformId(xformId);
+ // 【必填】表单模板ID(formData 顶层 fd_xform_id,v4 必填)
+ formData.setFdXformId(xformId);
formData.setDynamicProps(props);
return formData;
}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsProjectSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsProjectSyncSupport.java
index dc18fad1..a946cbfe 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsProjectSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsProjectSyncSupport.java
@@ -45,8 +45,6 @@ import org.springblade.hcs.dto.HcsSaveOptionDTO;
import org.springblade.hcs.dto.HcsUserRefVO;
import org.springblade.hcs.exception.HcsException;
import org.springblade.hcs.feign.IHcsClient;
-import org.springblade.system.cache.UserCache;
-import org.springblade.system.pojo.entity.User;
import org.springblade.transport.constant.HcsSyncConstant;
import org.springblade.transport.mapper.ProjectApplyMapper;
import org.springblade.transport.pojo.entity.ProjectApply;
@@ -112,7 +110,7 @@ public class HcsProjectSyncSupport {
HcsProjectAddDTO param = new HcsProjectAddDTO();
HcsBpmOperationDTO bpmOperation = new HcsBpmOperationDTO();
- // 操作类型:固定 drafter_submit(以起草人身份直接提交流程)
+ // 【必填】操作类型:固定 drafter_submit(以起草人身份直接提交流程)
bpmOperation.setOperationType("drafter_submit");
// 【必填】立项表单模板编码:配置 thirdParty.hcs.project.template-code(环境值,§9-U9)
bpmOperation.setTemplateCode(requireTemplateCode());
@@ -123,7 +121,7 @@ public class HcsProjectSyncSupport {
param.setCurUser(HcsUserRefVO.ofLoginName(operatorLoginName));
param.setFormData(buildFormData(projectApply, null));
HcsSaveOptionDTO saveOption = new HcsSaveOptionDTO();
- // saveDraft=false 直接提交
+ // 【必填】是否保存草稿:saveDraft=false 直接提交
saveOption.setSaveDraft(false);
param.setSaveOption(saveOption);
@@ -176,8 +174,8 @@ public class HcsProjectSyncSupport {
props.setFdCreatorUnit(creatorUnit);
// 项目负责人:负责人登录名 {fdLoginName}(§9-U2)
props.setFdHead(resolveUserRef(projectApply.getPrincipalUserId()));
- // 承接部门:TMS 承接部门名称(同 fd_creator_unit 先传名称)
- props.setFdTakerDept(HcsRefVO.ofName(projectApply.getUndertakeDeptName()));
+ // 承接部门:与创建单位一致,取配置 thirdParty.hcs.creator-unit-id/name(测试线联调固定广西物产城矿发展有限公司)
+ props.setFdTakerDept(creatorUnit);
// 承接人:项目经办人登录名 {fdLoginName}
props.setFdTaker(resolveUserRef(projectApply.getHandlerUserId()));
// 付款额度:TMS fundLimit(万元)× 10000 转 HCS 元
@@ -186,7 +184,7 @@ public class HcsProjectSyncSupport {
props.setFdOutInvoiceLimit(toYuan(projectApply.getReceivableLimit()));
// 项目建设内容:ProjectApply.situationRemark
props.setFdProContent(projectApply.getSituationRemark());
- // 是否可用:固定 true
+ // 【必填】是否可用:固定 true
props.setFdIsAvailable(true);
// 可用单位列表:与创建单位一致(同走 creator-unit 配置)
props.setFdAvailUnits(List.of(creatorUnit));
@@ -199,7 +197,7 @@ public class HcsProjectSyncSupport {
// TODO 待确认:项目收入目标 fd_pro_income_goal,TMS 无直接对应字段,一期不传(§5.1)
// 金蝶同步状态:固定 "1"
props.setFdKingdeeSyncStatus("1");
- // 来源标识:fd_sources,配置 thirdParty.hcs.src-system(约定值 WLTMS,D14)
+ // 【必填】来源标识:fd_sources,配置 thirdParty.hcs.src-system(约定值 WLTMS,D14)
props.setFdSources(hcsProperties.getSrcSystem());
// 来源系统主键 ID:TMS 项目立项单主键(D14,对账/幂等候选键)
props.setFdKingdeeId(String.valueOf(projectApply.getId()));
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReceiptBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReceiptBillSyncSupport.java
index 143d94e8..af7cdf54 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReceiptBillSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReceiptBillSyncSupport.java
@@ -161,21 +161,21 @@ public class HcsReceiptBillSyncSupport {
param.setFdLoginName(operatorLoginName);
HcsReceiptBillFormDataDTO formData = new HcsReceiptBillFormDataDTO();
HcsReceiptBillPropsDTO props = new HcsReceiptBillPropsDTO();
- // 发票号码:invoiceNo
+ // 【必填】发票号码:invoiceNo
props.setFdInvoiceCode(invoiceReceipt.getInvoiceNo());
- // 开票/收票日期:invoiceDate(YYYY-MM-DD 字符串)
+ // 【必填】开票/收票日期:invoiceDate(YYYY-MM-DD 字符串)
props.setFdBillDate(formatBillDate(invoiceReceipt.getInvoiceDate()));
// 开票方(销方):issuerName
props.setFdInvoicer(invoiceReceipt.getIssuerName());
// 收票方(购方):receiverName
props.setFdBuyer(invoiceReceipt.getReceiverName());
- // 价税合计金额:invoiceAmount
+ // 【必填】价税合计金额:invoiceAmount
props.setFdInvoiceAmtTaxIncl(invoiceReceipt.getInvoiceAmount());
- // 税率(小数):TMS taxRate(如 13)÷ 100 → 0.13
+ // 【必填】税率(小数):TMS taxRate(如 13)÷ 100 → 0.13
props.setFdTaxRate(toTaxRate(invoiceReceipt.getTaxRate()));
- // 发票类型:receipt-bill.invoice-type-mapping 字典映射(§9-U3,未配置不传)
+ // 【必填】发票类型:receipt-bill.invoice-type-mapping 字典映射(§9-U3,未配置不传)
props.setFdInvoiceType(hcsProperties.getReceiptBill().getInvoiceTypeMapping().get(invoiceReceipt.getInvoiceType()));
- // 合同主题/编号:应付结算链路回溯,回溯不到取人工补录(D13)
+ // 【必填】合同主题/编号:应付结算链路回溯,回溯不到取人工补录(D13,均为空不传待联调兜底口径)
ContractReference contractReference = resolveContract(invoiceReceipt);
props.setFdContractSubject(contractReference.subject());
props.setFdContractNo(contractReference.contractNo());
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java
index 8b45eb5c..fdf1765b 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java
@@ -92,7 +92,7 @@ public class HcsReconSupport {
/**
* 合同详情回查(C103-4,fdId 与 fdNumber 二选一)
*
- * TODO 待联调确认:出参 data 结构 v4 未定义,原样返回实际响应(设计文档 §5.9)
+ * v4 已定义详情响应字段表(HcsContractDetailVO),级联/集合字段内部结构以实际返回为准(设计文档 §5.9)
*
* @param fdId 合同ID(可空)
* @param fdNumber 合同编号(可空)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsSpecPaySyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsSpecPaySyncSupport.java
index 98370a1d..40ea1383 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsSpecPaySyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsSpecPaySyncSupport.java
@@ -123,30 +123,30 @@ public class HcsSpecPaySyncSupport {
props.setFdContractName(requireContractFdId(payment, contractManage));
// 合同编号
props.setFdContractNo(payment.getContractNo());
- // 单据编号:付款申请单号(来源付款单标识)
+ // 【必填】单据编号:付款申请单号(来源付款单标识)
props.setFdDocNo(payment.getPaymentNo());
- // 单据主题:"结算付款特批-" + 付款单号
+ // 【必填】单据主题:"结算付款特批-" + 付款单号
props.setFdDocSubject("结算付款特批-" + payment.getPaymentNo());
// 来源付款单ID:付款申请单号(§5.5 映射表)
props.setFdId(payment.getPaymentNo());
- // 付款金额:appliedAmount
+ // 【必填】付款金额:appliedAmount
props.setFdPayAmount(payment.getAppliedAmount());
- // 合计金额:settlementAmount
+ // 【必填】合计金额:settlementAmount
props.setFdTotalAmount(payment.getSettlementAmount() == null ? BigDecimal.ZERO : payment.getSettlementAmount());
- // 付款人 / 收款人
+ // 【必填】付款人 / 收款方
props.setFdPayer(payment.getPayerName());
props.setFdPayee(payment.getPayeeName());
- // 收款账户名 / 收款账号 / 开户行
+ // 【必填】收款账户名 / 收款账号 / 开户行名称
props.setFdReceiveAccountName(payment.getReceiptAccountName());
props.setFdReceiveAccount(payment.getBankAccount());
props.setFdBankName(payment.getBankName());
- // 结算币种:TMS 无币种字段,按 currency-name-mapping 默认值(人民币)
+ // 【必填】结算币种:TMS 无币种字段,按 currency-name-mapping 默认值(人民币)
props.setFdSettleCurrency(hcsProperties.getContract().getCurrencyNameMapping().getOrDefault("RMB", "人民币"));
- // 付款用途 / 付款性质 / 付款类型:字典值配置(§9-U3 待联调后配置)
+ // 【必填】付款用途 / 款项性质 / 款项类型:字典值配置(§9-U3 待联调后配置)
props.setFdPaymentPurpose(hcsProperties.getSpecPay().getPaymentPurpose());
props.setFdPaymentNature(hcsProperties.getSpecPay().getPaymentNature());
props.setFdPaymentType(hcsProperties.getSpecPay().getPaymentType());
- // 事由 / 补充说明:remark
+ // 【必填】事由 / 补充说明:remark
props.setFdReason(payment.getRemark());
props.setFdSupplementNote(payment.getRemark());
// 单据状态:配置 spec-pay.doc-status(示例 10)
@@ -154,7 +154,7 @@ public class HcsSpecPaySyncSupport {
// 特批附件字段标识:固定 fd_spc_approval_attach
props.setFdSpcApprovalAttach(SPEC_ATTACH_ENTITY_KEY);
formData.setDynamicProps(props);
- // 表单层单据主题
+ // 【必填】表单层单据主题
formData.setFdDocSubject("结算付款特批-" + payment.getPaymentNo());
// 表单层单据状态:配置 spec-pay.doc-status
formData.setFdDocStatus(hcsProperties.getSpecPay().getDocStatus());
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/config/HcsProperties.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/config/HcsProperties.java
index 2bb06b09..72a3876b 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/config/HcsProperties.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/config/HcsProperties.java
@@ -165,6 +165,10 @@ public class HcsProperties {
* TMS 结算方式 -> 付款|收款(fdSettlementType,§9-U3 字典映射待联调)
*/
private Map settlementTypeMapping = new HashMap<>();
+ /**
+ * TMS 审核状态 -> HCS 合同状态(xformFields CONTRACT_STATUS 必填,draft/approving/approved 等,§9-U3 待联调后配置)
+ */
+ private Map statusMapping = new HashMap<>();
/**
* TMS 币种码 -> HCS 币种名称(照金蝶 RMB->CNY 映射惯例)
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCategoryVO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCategoryVO.java
index a477400e..e497b40c 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCategoryVO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCategoryVO.java
@@ -56,7 +56,23 @@ public class HcsCategoryVO implements Serializable {
*/
private HcsRefVO fdParent;
/**
- * 状态:enable / disable
+ * 状态:enable=启用 / disable=停用
*/
private String fdStatus;
+ /**
+ * 层级ID:由各级分类 fdId 以 x 包裹拼接(x+上级fdId+x+fdId+x,v4 新增)
+ */
+ private String fdHierarchyId;
+ /**
+ * 创建人
+ */
+ private HcsRefVO fdCreator;
+ /**
+ * 创建人部门
+ */
+ private HcsRefVO fdCreatorDept;
+ /**
+ * 创建时间(毫秒时间戳)
+ */
+ private Long fdCreateTime;
}
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDetailVO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDetailVO.java
new file mode 100644
index 00000000..6b841977
--- /dev/null
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDetailVO.java
@@ -0,0 +1,519 @@
+/**
+ * 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;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 合同合规系统(HCS)C103-4 合同详情出参(v4 字段表)
+ *
+ * 级联/集合类字段(对象/数组)内部结构 v4 标注以实际返回为准,暂以 Object/List<Object> 承接,
+ * 联调确认后细化。fdSepcailContract 为接口文档原文拼写(Special 笔误,必须沿用)。
+ *
+ * @author Chill
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class HcsContractDetailVO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 合同ID
+ */
+ private String fdId;
+ /**
+ * 租户ID
+ */
+ private String fdTenantId;
+ /**
+ * 可阅读标示
+ */
+ private String fdReaderFlag;
+ /**
+ * 不可阅读标记(可阅读者在文档发布前生效)
+ */
+ private String fdNotReaderFlag;
+ /**
+ * 可阅读者(在文档发布前生效)
+ */
+ private String fdRBPFlag;
+ /**
+ * 修改人
+ */
+ private String fdAlter;
+ /**
+ * 修改时间(毫秒时间戳)
+ */
+ private Long fdAlterTime;
+ /**
+ * 描述
+ */
+ private String fdDesc;
+ /**
+ * 是否隐藏
+ */
+ private Boolean fdIsHidden;
+ /**
+ * 最后修改时间(毫秒时间戳)
+ */
+ private Long fdLastModifiedTime;
+ /**
+ * 合同名称
+ */
+ private String fdSubject;
+ /**
+ * 合同分类(层级ID)
+ */
+ private String fdCateHierarchyId;
+ /**
+ * 编号
+ */
+ private String fdNumber;
+ /**
+ * 状态:draft=草稿; approving=审批中; approved=已审批; tosign=待签订; signing=签订中; signerror=签订异常; signed=已签订等
+ */
+ private String fdStatus;
+ /**
+ * 合同发起ID
+ */
+ private String fdDraftMainId;
+ /**
+ * 合同模板ID
+ */
+ private String fdTemplateId;
+ /**
+ * 审批状态:approving=审批中; approved=已审批; approvalinvalid=审批作废
+ */
+ private String fdApprovalStatus;
+ /**
+ * 签订状态:tosign=待签订; signing=签订中; signerror=签订异常; signed=已签订; signinvalid=签订作废
+ */
+ private String fdSignStatus;
+ /**
+ * 签订异常信息
+ */
+ private String fdSignErrorMsg;
+ /**
+ * 进入待签订时间(毫秒时间戳)
+ */
+ private Long fdToSignTime;
+ /**
+ * 签订发起时间(毫秒时间戳)
+ */
+ private Long fdSignCreateTime;
+ /**
+ * 完成签订时间(毫秒时间戳)
+ */
+ private Long fdSignedTime;
+ /**
+ * 归档状态:toarchive=待归档; archiving=归档中; archived=已归档; archiveerror=归档异常
+ */
+ private String fdArchiveStatus;
+ /**
+ * 变更状态:changing=变更中; changed=已变更; terminated=已终止
+ */
+ private String fdChangeStatus;
+ /**
+ * 履约状态:toplan=待履约; planing=履约中; planerror=履约异常; planed=已履约; planterminate=履约终止
+ */
+ private String fdPlanStatus;
+ /**
+ * 进入待履约时间(毫秒时间戳)
+ */
+ private Long fdToPlanTime;
+ /**
+ * 完成履约时间(毫秒时间戳)
+ */
+ private Long fdPlanedTime;
+ /**
+ * 关闭状态:toclose=待关闭; closing=关闭中; closed=已关闭
+ */
+ private String fdCloseStatus;
+ /**
+ * 进入待关闭时间(毫秒时间戳)
+ */
+ private Long fdToCloseTime;
+ /**
+ * 关闭时间(毫秒时间戳)
+ */
+ private Long fdClosedTime;
+ /**
+ * 签署提供者:psign=物理签署; esign=电子签署; qjsign=智能用印签署
+ */
+ private String fdSignProvider;
+ /**
+ * 签署实体ID
+ */
+ private String fdSignEntityId;
+ /**
+ * 归档方式:auto=一键申请; review=流程申请
+ */
+ private String fdFileWay;
+ /**
+ * 归档实体ID
+ */
+ private String fdArchiveEntityId;
+ /**
+ * 进入待归档时间(毫秒时间戳)
+ */
+ private Long fdToArchiveTime;
+ /**
+ * 完成归档时间(毫秒时间戳)
+ */
+ private Long fdArchivedTime;
+ /**
+ * 履约计划创建时机:draft=起草环节创建; toplan=履约环节创建
+ */
+ private String fdPlanCreateMoment;
+ /**
+ * 关闭方式:auto=一键关闭; review=流程关闭
+ */
+ private String fdCloseWay;
+ /**
+ * 关闭实体ID
+ */
+ private String fdCloseEntityId;
+ /**
+ * 是否锁定
+ */
+ private Boolean fdIsLocked;
+ /**
+ * 锁定原因:invalid=合同作废; change=合同变更; termination=合同终止
+ */
+ private String fdLockReason;
+ /**
+ * 合同作废实体ID
+ */
+ private String fdInvalidEntityId;
+ /**
+ * 上次合同变动发起实体ID
+ */
+ private String fdLastChangeEntityId;
+ /**
+ * 合同终止发起实体ID
+ */
+ private String fdTerminationEntityId;
+ /**
+ * 批量发起任务ID
+ */
+ private String fdBatchTaskId;
+ /**
+ * 是否关联交易
+ */
+ private Boolean fdIsRelaDeal;
+ /**
+ * 是否补录
+ */
+ private Boolean fdIsRecord;
+ /**
+ * 履约计划(级联字段,结构以实际返回为准)
+ */
+ private Object fdPlan;
+ /**
+ * 验收计划(级联字段,结构以实际返回为准)
+ */
+ private Object fdAcptPlan;
+ /**
+ * 外部合同数据(级联字段,结构以实际返回为准)
+ */
+ private Object fdOuterAttr;
+ /**
+ * 订单明细配置ID
+ */
+ private String fdOrderDetailConfigId;
+ /**
+ * 收付款进度(结构以实际返回为准)
+ */
+ private Object fdPayColProgress;
+ /**
+ * 开票进度(结构以实际返回为准)
+ */
+ private Object fdInvoiceProgress;
+ /**
+ * 履约状态(新):0=正常; 1=低风险; 2=中风险; 3=高风险
+ */
+ private Integer fdPlanStatusNew;
+ /**
+ * 是否冻结
+ */
+ private Boolean fdIsFreeze;
+ /**
+ * 解冻表单关联ID
+ */
+ private String fdUnfreezeFormId;
+ /**
+ * 合同履约流程状态:00/01/02/10/11/12/20/21/29/30/39
+ */
+ private String fdPlanFlowStatus;
+ /**
+ * 合同履约流程ID
+ */
+ private String fdPlanFlowId;
+ /**
+ * 是否评分
+ */
+ private Boolean fdRated;
+ /**
+ * 完成审批时间(毫秒时间戳)
+ */
+ private Long fdApprovedTime;
+ /**
+ * 是否同步金蝶
+ */
+ private Boolean fdIsSyncJd;
+ /**
+ * 同步金蝶状态:0/1/2
+ */
+ private Integer fdSyncJdStatus;
+ /**
+ * 特批合同(字段名原文拼写笔误,必须沿用)
+ */
+ private Boolean fdSepcailContract;
+ /**
+ * 合同结算模式:open=开口合同; close=闭口合同
+ */
+ private String fdContractGwNature;
+ /**
+ * 合同类型:standard=标准合同; halfstandard=半标准合同; notstandard=非标准合同
+ */
+ private String fdContractCharacter;
+ /**
+ * 合同性质:general=普通合同; framework=框架协议
+ */
+ private String fdContractNature;
+ /**
+ * 引用范本ID
+ */
+ private String fdModelId;
+ /**
+ * 合同属性:main=主合同; child=子合同; common=普通
+ */
+ private String fdContractAttribute;
+ /**
+ * 承办人
+ */
+ private HcsRefVO fdUnderTaker;
+ /**
+ * 承办人部门
+ */
+ private HcsRefVO fdUnderTakerDept;
+ /**
+ * 预计开始时间(毫秒时间戳)
+ */
+ private Long fdEstimateStartTime;
+ /**
+ * 预计结束时间(毫秒时间戳)
+ */
+ private Long fdEstimateEndTime;
+ /**
+ * 实际开始时间(毫秒时间戳)
+ */
+ private Long fdStartTime;
+ /**
+ * 实际结束时间(毫秒时间戳)
+ */
+ private Long fdEndTime;
+ /**
+ * 合同发起来源:inner=内部发起; outer=外部发起
+ */
+ private String fdContractSource;
+ /**
+ * 外部来源系统
+ */
+ private String fdOuterSystem;
+ /**
+ * 合同结算类型:payment=付款; payment_collection=收支双向; collection=收款; none=不结算
+ */
+ private String fdSettlementType;
+ /**
+ * 合同金额
+ */
+ private BigDecimal fdAmount;
+ /**
+ * 币种
+ */
+ private String fdCurrencyId;
+ /**
+ * 是否原始合同
+ */
+ private Boolean fdIsOrigin;
+ /**
+ * 原始合同ID
+ */
+ private String fdOriginContractId;
+ /**
+ * 合同变更类型:change=合同变更; termination=合同终止
+ */
+ private String fdChangeType;
+ /**
+ * 是否含税
+ */
+ private Boolean fdIncludeTax;
+ /**
+ * 是否引用范本
+ */
+ private Boolean fdUseModel;
+ /**
+ * 引用范本名称
+ */
+ private String fdModelName;
+ /**
+ * 引用范本版本
+ */
+ private String fdModelVersion;
+ /**
+ * 是否固定期限
+ */
+ private Boolean fdIsFixedTerm;
+ /**
+ * 合同开始期限
+ */
+ private String fdStartTerm;
+ /**
+ * 合同结束期限
+ */
+ private String fdEndTerm;
+ /**
+ * 有效期限
+ */
+ private String fdValidTerm;
+ /**
+ * 项目立项ID
+ */
+ private String fdProjectId;
+ /**
+ * 合同份数
+ */
+ private Integer fdServings;
+ /**
+ * 合同说明
+ */
+ private String fdContractDescription;
+ /**
+ * 合同的变更流程状态:changing=变更中; changed=已变更; noChangeProcess=无变更流程
+ */
+ private String fdChangeLbpmStatus;
+ /**
+ * 紧急程度:1=普通; 2=急件; 3=特急
+ */
+ private Integer fdUrgencyLevel;
+ /**
+ * 创建人
+ */
+ private HcsRefVO fdCreator;
+ /**
+ * 创建时间(毫秒时间戳)
+ */
+ private Long fdCreateTime;
+ /**
+ * 创建者部门
+ */
+ private HcsRefVO fdCreatorDept;
+ /**
+ * 权限(级联字段,结构以实际返回为准)
+ */
+ private Object fdPermissions;
+ /**
+ * 可阅读者(结构以实际返回为准)
+ */
+ private List fdReaders;
+ /**
+ * 所有可阅读者(结构以实际返回为准)
+ */
+ private List fdAllReaders;
+ /**
+ * 所有可阅读者ID(结构以实际返回为准)
+ */
+ private List fdAllReaderIds;
+ /**
+ * 可维护者(结构以实际返回为准)
+ */
+ private List fdEditors;
+ /**
+ * 所有可编辑者(结构以实际返回为准)
+ */
+ private List fdAllEditors;
+ /**
+ * 协办人(结构以实际返回为准)
+ */
+ private List fdCoTakers;
+ /**
+ * 合同时间线(结构以实际返回为准)
+ */
+ private List fdTimeLines;
+ /**
+ * 合同关联(结构以实际返回为准)
+ */
+ private List fdRelations;
+ /**
+ * 合同签约方及地位(结构以实际返回为准)
+ */
+ private List fdStandingSigners;
+ /**
+ * 签印文件(结构以实际返回为准)
+ */
+ private List fdSignFiles;
+ /**
+ * 业务明细(结构以实际返回为准)
+ */
+ private List fdBusinessDetails;
+ /**
+ * 付款记录(结构以实际返回为准)
+ */
+ private List fdPaymentRecords;
+ /**
+ * 收款记录(结构以实际返回为准)
+ */
+ private List fdCollectionRecords;
+ /**
+ * 收票记录(结构以实际返回为准)
+ */
+ private List fdInInvoices;
+ /**
+ * 开票记录(结构以实际返回为准)
+ */
+ private List fdOutInvoices;
+ /**
+ * 预填写物理签印信息(结构以实际返回为准)
+ */
+ private List fdPsignContents;
+ /**
+ * 审批人(结构以实际返回为准)
+ */
+ private List fdApprovers;
+ /**
+ * 履约规则(结构以实际返回为准)
+ */
+ private List fdExePlanRules;
+}
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDraftDTO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDraftDTO.java
index bad3366b..d105f8ba 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDraftDTO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractDraftDTO.java
@@ -43,6 +43,10 @@ import java.io.Serializable;
public class HcsContractDraftDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
+ /**
+ * 合同ID(C103-11 合同更新顶层必填,传 C103-1 返回的 fdContractId;C103-1 新建不传)
+ */
+ private String fdId;
/**
* 合同模板ID(C103-6 模板列表获取,配置 template-mapping,§9-U7)
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractFieldJsonDTO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractFieldJsonDTO.java
index 702bcbea..718c39b4 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractFieldJsonDTO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsContractFieldJsonDTO.java
@@ -36,7 +36,7 @@ import java.util.List;
/**
* 合同合规系统(HCS)C103-1 合同发起 fdFieldJson 节点(C103-1 新建 / C103-11 更新共用)
*
- * §9-U8 待联调确认:v4 未定义合同附件传递字段,附件挂载方式待合规方确认后补充。
+ * v4 文档已定义 attachment 附件挂载(fdId/fdBindType 必填,fdEntityKey 仅给出特批附件枚举 eopCdraftSpecial)。
*
* @author Chill
*/
@@ -54,4 +54,8 @@ public class HcsContractFieldJsonDTO implements Serializable {
* 签署方(相对方)列表
*/
private List signer;
+ /**
+ * 附件数据(C103-1 必填,C103-11 更新不传;fdEntityKey 普通附件枚举待合规方给出,暂不传)
+ */
+ private List attachment;
}
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCurrencyVO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCurrencyVO.java
index 09d2a3fe..f3f98a61 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCurrencyVO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsCurrencyVO.java
@@ -75,4 +75,12 @@ public class HcsCurrencyVO implements Serializable {
* 是否本位币
*/
private Boolean fdIsStandardCurrency;
+ /**
+ * 创建人
+ */
+ private HcsRefVO fdCreator;
+ /**
+ * 创建时间(毫秒时间戳)
+ */
+ private Long fdCreateTime;
}
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsInvoiceRegAddDTO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsInvoiceRegAddDTO.java
index e1d90bf1..705b5207 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsInvoiceRegAddDTO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsInvoiceRegAddDTO.java
@@ -60,6 +60,10 @@ public class HcsInvoiceRegAddDTO implements Serializable {
* 合同编号(必填,经应收结算链路回溯,§9-U10)
*/
private String fdContractNumber;
+ /**
+ * 合同 {fdId, fdName}(v4 新增,fdId 为合规合同ID,随编号一并回溯)
+ */
+ private HcsRefVO fdContract;
/**
* 发票类型(字典映射 invoice-type-mapping,§9-U3)
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsPerfRecordPropsDTO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsPerfRecordPropsDTO.java
index 799bb389..20fcbcf3 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsPerfRecordPropsDTO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsPerfRecordPropsDTO.java
@@ -97,6 +97,16 @@ public class HcsPerfRecordPropsDTO implements Serializable {
*/
@JsonProperty("fd_contract_id")
private String fdContractId;
+ /**
+ * 创建时间(毫秒时间戳,v4 新增)
+ */
+ @JsonProperty("fd_create_time")
+ private Long fdCreateTime;
+ /**
+ * 业务ID(方便溯源用,v4 新增,TMS 传付款申请单ID)
+ */
+ @JsonProperty("fd_business_id")
+ private String fdBusinessId;
/**
* 附件不可下载
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsTemplateVO.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsTemplateVO.java
index c0270741..8b738772 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsTemplateVO.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/dto/HcsTemplateVO.java
@@ -59,6 +59,10 @@ public class HcsTemplateVO implements Serializable {
* 合同性质(如 standard)
*/
private String fdContractCharacter;
+ /**
+ * 分类层级ID(v4 新增)
+ */
+ private String fdCateHierarchyId;
/**
* 创建时间(毫秒时间戳)
*/
@@ -71,6 +75,18 @@ public class HcsTemplateVO implements Serializable {
* 创建部门
*/
private HcsRefVO fdCreatorDept;
+ /**
+ * 是否禁止更新主数据权限
+ */
+ private Boolean fdDisableUpdateMainAuth;
+ /**
+ * 主数据授权时间点(如 afterapproved)
+ */
+ private String fdAuthToMainTime;
+ /**
+ * 是否强制自动编号
+ */
+ private Boolean fdForceAutoNumber;
/**
* 模板扩展属性(含中文名)
*/
diff --git a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/feign/IHcsClient.java b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/feign/IHcsClient.java
index e545d6ec..f3bee019 100644
--- a/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/feign/IHcsClient.java
+++ b/blade-third-party-api/blade-hcs-api/src/main/java/org/springblade/hcs/feign/IHcsClient.java
@@ -31,6 +31,7 @@ import org.springblade.hcs.dto.HcsAttachmentDownloadDTO;
import org.springblade.hcs.dto.HcsAttachmentVO;
import org.springblade.hcs.dto.HcsCategoryVO;
import org.springblade.hcs.dto.HcsContractDetailQueryDTO;
+import org.springblade.hcs.dto.HcsContractDetailVO;
import org.springblade.hcs.dto.HcsContractDraftDTO;
import org.springblade.hcs.dto.HcsContractDraftVO;
import org.springblade.hcs.dto.HcsContractVO;
@@ -173,13 +174,13 @@ public interface IHcsClient {
/**
* C103-4 合同详情(fdId 与 fdNumber 二选一)
*
- * TODO 待联调确认:出参 data 结构 v4 未定义,暂以对象承接,联调后补充(设计文档 §5.9)
+ * v4 已定义详情响应字段表({@link HcsContractDetailVO});级联/集合字段内部结构以实际返回为准。
*
* @param param 请求参数
- * @return 合同详情(结构待联调确认)
+ * @return 合同详情
*/
@PostMapping(CONTRACT_DETAIL_URL)
- HcsResult contractDetail(@RequestBody HcsContractDetailQueryDTO param);
+ HcsResult contractDetail(@RequestBody HcsContractDetailQueryDTO param);
/**
* C103-9(新) 合同履约规则同步(行级增删改,与废弃旧接口同路径不同入参,务必用本新版结构)