From 62917c6864fd33bf4349c9549d853ba2937606ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Mon, 28 Sep 2026 00:03:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20HCS=E5=AF=B9=E8=B4=A6=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=AB=AF=E7=82=B9=EF=BC=88=E9=A1=B9=E7=9B=AE=E7=AB=8B=E9=A1=B9?= =?UTF-8?q?/=E5=90=88=E5=90=8C/=E5=90=88=E5=90=8C=E8=AF=A6=E6=83=85/?= =?UTF-8?q?=E5=BC=80=E7=A5=A8=E7=99=BB=E8=AE=B0=E6=8C=89=E7=BC=96=E5=8F=B7?= =?UTF-8?q?=E5=9B=9E=E6=9F=A5=E5=90=88=E8=A7=84=E4=BE=A7=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/HcsSyncController.java | 44 ++++++ .../support/hcs/HcsReconSupport.java | 142 ++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java 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 0363060f..10c8f586 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 @@ -37,9 +37,11 @@ import org.springblade.transport.support.hcs.HcsContractSyncSupport; import org.springblade.transport.support.hcs.HcsInvoiceRegSyncSupport; import org.springblade.transport.support.hcs.HcsPaymentSyncSupport; import org.springblade.transport.support.hcs.HcsReceiptBillSyncSupport; +import org.springblade.transport.support.hcs.HcsReconSupport; import org.springblade.transport.support.hcs.HcsMasterDataSupport; import org.springblade.transport.support.hcs.HcsProjectSyncSupport; import org.springblade.transport.task.HcsPushTask; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -69,6 +71,7 @@ public class HcsSyncController { private final HcsInvoiceRegSyncSupport hcsInvoiceRegSyncSupport; private final HcsReceiptBillSyncSupport hcsReceiptBillSyncSupport; private final HcsMasterDataSupport hcsMasterDataSupport; + private final HcsReconSupport hcsReconSupport; /** * 单条重推(bizType:project=项目立项 / contract=合同 / payment=付款申请 / invoice-application=开票申请 / invoice-receipt=收票单) @@ -127,4 +130,45 @@ public class HcsSyncController { public R refreshMasterData() { return R.data(hcsMasterDataSupport.refreshAll()); } + + /** + * 对账查询:按项目编号回查 HCS 项目立项(C102-3) + */ + @GetMapping("/recon/project") + @ApiOperationSupport(order = 5) + @Operation(summary = "项目立项对账查询", description = "按项目编号回查合规侧项目立项数据") + public R reconProject(@Parameter(description = "项目编号", required = true) @RequestParam String projectCode) { + return R.data(hcsReconSupport.reconProject(projectCode)); + } + + /** + * 对账查询:按合同编号回查 HCS 合同(C103-3) + */ + @GetMapping("/recon/contract") + @ApiOperationSupport(order = 6) + @Operation(summary = "合同对账查询", description = "按合同编号回查合规侧合同数据") + public R reconContract(@Parameter(description = "合同编号", required = true) @RequestParam String contractNo) { + return R.data(hcsReconSupport.reconContract(contractNo)); + } + + /** + * 对账查询:合同详情(C103-4,fdId 与 fdNumber 二选一) + */ + @GetMapping("/recon/contract/detail") + @ApiOperationSupport(order = 7) + @Operation(summary = "合同详情对账查询", description = "按合规合同ID或合同编号回查合规侧合同详情") + public R reconContractDetail(@Parameter(description = "合规合同ID") @RequestParam(required = false) String fdId, + @Parameter(description = "合同编号") @RequestParam(required = false) String fdNumber) { + return R.data(hcsReconSupport.reconContractDetail(fdId, fdNumber)); + } + + /** + * 对账查询:按申请单号回查 HCS 开票登记(C111-1) + */ + @GetMapping("/recon/invoice-registration") + @ApiOperationSupport(order = 8) + @Operation(summary = "开票登记对账查询", description = "按开票申请单号回查合规侧开票登记数据") + public R reconInvoiceRegistration(@Parameter(description = "开票申请单号", required = true) @RequestParam String applicationNo) { + return R.data(hcsReconSupport.reconInvoiceRegistration(applicationNo)); + } } 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 new file mode 100644 index 00000000..8b45eb5c --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/hcs/HcsReconSupport.java @@ -0,0 +1,142 @@ +/** + * 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.support.hcs; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.hcs.dto.HcsContractDetailQueryDTO; +import org.springblade.hcs.dto.HcsPageQueryDTO; +import org.springblade.hcs.dto.HcsResult; +import org.springblade.hcs.exception.HcsException; +import org.springblade.hcs.feign.IHcsClient; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * HCS 对账查询支撑组件(设计文档 §5.9/§8-P5,运维收尾) + *

+ * 按来源单据编号回查 HCS 侧数据(项目立项/合同/合同详情/开票登记), + * 供对账查询页与人工排查使用;返回 HCS 原始数据结构。 + * + * @author Chill + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class HcsReconSupport { + + private final IHcsClient hcsClient; + + /** + * 按项目编号回查 HCS 项目立项(C102-3) + * + * @param projectCode 项目编号 + * @return HCS 项目立项列表 + */ + public HcsResult reconProject(String projectCode) { + HcsPageQueryDTO query = new HcsPageQueryDTO(); + // C102-3 入参 columns 用下划线字段名 + query.setColumns(List.of("fd_id", "fd_num", "fd_pro_name")); + // 项目编号精确匹配 + query.setConditions(Map.of("fd_num", Objects.toString(projectCode, ""))); + query.setOffset(0); + query.setPageSize(50); + HcsResult result = hcsClient.projectList(query); + return requireSuccess("项目立项对账", result); + } + + /** + * 按合同编号回查 HCS 合同(C103-3) + * + * @param contractNo 合同编号 + * @return HCS 合同列表 + */ + public HcsResult reconContract(String contractNo) { + HcsPageQueryDTO query = new HcsPageQueryDTO(); + query.setColumns(List.of("fdId", "fdSubject", "fdNumber", "fdCateHierarchyId")); + // 合同编号精确匹配(§9-U4 查询能力联调确认) + query.setConditions(Map.of("fdNumber", Objects.toString(contractNo, ""))); + query.setOffset(0); + query.setPageSize(50); + HcsResult result = hcsClient.contractList(query); + return requireSuccess("合同对账", result); + } + + /** + * 合同详情回查(C103-4,fdId 与 fdNumber 二选一) + *

+ * TODO 待联调确认:出参 data 结构 v4 未定义,原样返回实际响应(设计文档 §5.9) + * + * @param fdId 合同ID(可空) + * @param fdNumber 合同编号(可空) + * @return HCS 合同详情 + */ + public HcsResult reconContractDetail(String fdId, String fdNumber) { + if (StringUtil.isBlank(fdId) && StringUtil.isBlank(fdNumber)) { + throw new HcsException("合同详情对账失败,fdId 与 fdNumber 至少传一项"); + } + HcsContractDetailQueryDTO query = new HcsContractDetailQueryDTO(); + // 合同ID(与编号二选一) + query.setFdId(fdId); + // 合同编号(与ID二选一) + query.setFdNumber(fdNumber); + HcsResult result = hcsClient.contractDetail(query); + return requireSuccess("合同详情对账", result); + } + + /** + * 按申请单号回查 HCS 开票登记(C111-1) + * + * @param applicationNo 开票申请单号 + * @return HCS 开票登记列表 + */ + public HcsResult reconInvoiceRegistration(String applicationNo) { + HcsPageQueryDTO query = new HcsPageQueryDTO(); + query.setColumns(List.of("fdId", "fdNumber", "fdBillDate", "fdContractNumber", "fdInvoiceAmount", "fdStatus")); + // 单据编号精确匹配(§9-U4 查询能力联调确认) + query.setConditions(Map.of("fdNumber", Objects.toString(applicationNo, ""))); + query.setOffset(0); + query.setPageSize(50); + HcsResult result = hcsClient.invoiceRegistrationList(query); + return requireSuccess("开票登记对账", result); + } + + /** + * 校验查询结果并返回 + */ + private HcsResult requireSuccess(String scene, HcsResult result) { + if (result == null || !result.isSuccess()) { + log.error("HCS{}查询失败响应:{}", scene, result == null ? "无响应" + : String.format("msg=%s, traceId=%s", result.getMsg(), result.getTraceId())); + throw new HcsException("HCS" + scene + "失败:" + (result == null ? "响应为空" : result.getMsg())); + } + return result; + } +}