diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java index fedad8d8..ecc40f74 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java @@ -73,6 +73,56 @@ public class BfiProperties { */ private ClaimAnnounce claimAnnounce = new ClaimAnnounce(); + /** + * 付款结果定时回写配置(A103-2/A103-4,总开关同时控制应收勾稽、开票结果回写) + */ + private PayResult payResult = new PayResult(); + + /** + * 收票单结果定时回写开关(A801-3) + */ + private ReceivedInvoiceResult receivedInvoiceResult = new ReceivedInvoiceResult(); + + /** + * 收款认领推送配置(A301-3) + */ + private ReceiptClaimPush receiptClaimPush = new ReceiptClaimPush(); + + /** + * 全票池发票定时同步配置(A801-1) + */ + private InvoiceReceipt invoiceReceipt = new InvoiceReceipt(); + + /** + * 客商金蝶数据定时同步配置(A902-1/A902-2) + */ + private Customer customer = new Customer(); + + /** + * 金蝶黑名单查询配置 + */ + private Blacklist blacklist = new Blacklist(); + + /** + * 开票结果回写锁配置(A303-5) + */ + private InvoiceResult invoiceResult = new InvoiceResult(); + + /** + * 应收单勾稽回写锁配置(A302-4) + */ + private ArResult arResult = new ArResult(); + + /** + * 金蝶单据锁定补偿配置 + */ + private BillLock billLock = new BillLock(); + + /** + * 审批通过自动同步金蝶配置(结算单/付款申请/开票申请/收票登记) + */ + private AutoSync autoSync = new AutoSync(); + /** * 应付/应收/收票单分录物料映射配置(A102-2/A302-2/A303-2 共用): * 运输类按项目业务模式映射——国内运输按运单运输方式映射、国际运输映射国际货代服务; @@ -127,6 +177,21 @@ public class BfiProperties { * 真实物料口径与金蝶对齐后替换(与应收/应付联调临时值同源) */ private String materialNumber = "SP0324"; + + /** + * A801-3 推送幂等预检回看窗口天数(金蝶修改时间窗口,契约约束不超过 1 个月) + */ + private int queryWindowDays = 30; + + /** + * A801-3 定时回写轮询窗口天数(同样受金蝶 1 个月窗口约束) + */ + private int resultWindowDays = 30; + + /** + * A801-3 回写 single-flight 锁租约秒数,须大于最坏一轮耗时(批量远程查询 + 逐单回写) + */ + private long lockLeaseSeconds = 1800; } /** @@ -175,4 +240,174 @@ public class BfiProperties { private String loading = "XDWL11002004"; } + /** + * 付款结果回写配置项(A103-2/A103-4) + */ + @Data + public static class PayResult { + + /** + * 回写任务开关,代码默认关闭(安全兜底),由 Nacos 按环境显式开启 + */ + private boolean syncEnabled = false; + + /** + * 回写 single-flight 锁租约秒数,须大于最坏一轮耗时(分批远程查询 + 逐单回写) + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 收票单结果回写配置项(A801-3) + */ + @Data + public static class ReceivedInvoiceResult { + + /** + * 回写任务开关,默认关闭(联调稳定后开启) + */ + private boolean syncEnabled = false; + } + + /** + * 收款认领推送配置项(A301-3) + */ + @Data + public static class ReceiptClaimPush { + + /** + * 推送任务开关,默认关闭(联调稳定后开启) + */ + private boolean syncEnabled = false; + + /** + * 推送 single-flight 锁租约秒数,须大于最坏一轮耗时(逐认领人远程查公告 + 逐条推送) + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 全票池发票同步配置项(A801-1) + */ + @Data + public static class InvoiceReceipt { + + /** + * 同步任务开关,默认关闭(上线先手动跑一次全窗口铺底) + */ + private boolean syncEnabled = false; + + /** + * 增量窗口天数(按票池更新时间滚动) + */ + private int incrementDays = 30; + + /** + * 同步发票种类白名单(逗号分隔票易通编码,如 26,27 数电普票/专票),为空不限制 + */ + private String invoiceTypes = ""; + + /** + * 同步 single-flight 锁租约秒数,须大于最坏一轮耗时;进程异常退出时锁在租约到期后自动释放 + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 客商金蝶数据同步配置项(A902-1/A902-2) + */ + @Data + public static class Customer { + + /** + * 同步任务开关,默认关闭 + */ + private boolean syncEnabled = false; + + /** + * 同步 single-flight 锁租约秒数,须大于最坏一轮耗时(复查 + 批量推送 + 停用联动) + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 金蝶黑名单查询配置项 + */ + @Data + public static class Blacklist { + + /** + * 客商提审命中风险警示类(B)时是否一并拦截;默认 false 仅放行告警,禁止交易类(A)始终拦截 + */ + private boolean blockRiskWarning = false; + } + + /** + * 开票结果回写锁配置项(A303-5) + */ + @Data + public static class InvoiceResult { + + /** + * 回写 single-flight 锁租约秒数 + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 应收单勾稽回写锁配置项(A302-4) + */ + @Data + public static class ArResult { + + /** + * 勾稽 single-flight 锁租约秒数 + */ + private long lockLeaseSeconds = 1800; + } + + /** + * 金蝶单据锁定补偿配置项 + */ + @Data + public static class BillLock { + + /** + * 锁定补偿开关,默认关闭(安全兜底) + */ + private boolean retryEnabled = false; + } + + /** + * 审批通过自动同步金蝶配置项(结算单 A102-2/A302-2、付款申请 A103-1/A103-3、开票申请 A303-1、收票 A303-2+A302-6) + */ + @Data + public static class AutoSync { + + /** + * 结算单审批后自动推送开关 + */ + private boolean settlement = false; + + /** + * 付款申请审批后自动推送开关 + */ + private boolean payment = false; + + /** + * 开票申请审批后自动推送开关 + */ + private boolean invoiceApply = false; + + /** + * 收票登记审批后自动推送开关 + */ + private boolean receipt = false; + + /** + * failed 单据定时重推开关(仅重推生成失败,不扫 unsynced 存量) + */ + private boolean retryEnabled = false; + } + } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/listener/KingdeeApprovalSyncListener.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/listener/KingdeeApprovalSyncListener.java index 3ed81243..185a0c56 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/listener/KingdeeApprovalSyncListener.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/listener/KingdeeApprovalSyncListener.java @@ -21,12 +21,12 @@ package org.springblade.transport.listener; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springblade.transport.config.BfiProperties; import org.springblade.transport.event.KingdeeBillApprovedEvent; import org.springblade.transport.service.IFormalSettlementService; import org.springblade.transport.service.IInvoiceApplicationService; import org.springblade.transport.service.IInvoiceReceiptService; import org.springblade.transport.service.IPaymentApplicationService; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.transaction.event.TransactionPhase; import org.springframework.transaction.event.TransactionalEventListener; @@ -61,22 +61,7 @@ public class KingdeeApprovalSyncListener { private final IPaymentApplicationService paymentApplicationService; private final IInvoiceApplicationService invoiceApplicationService; private final IInvoiceReceiptService invoiceReceiptService; - - /** 结算单审批后自动推 A102-2/A302-2 开关,默认关闭 */ - @Value("${thirdParty.bfi.autoSync.settlement:false}") - private boolean settlementEnabled; - - /** 付款申请审批后自动推 A103-1/A103-3 开关,默认关闭 */ - @Value("${thirdParty.bfi.autoSync.payment:false}") - private boolean paymentEnabled; - - /** 开票申请审批后自动推 A303-1 开关,默认关闭 */ - @Value("${thirdParty.bfi.autoSync.invoiceApply:false}") - private boolean invoiceApplyEnabled; - - /** 收票登记审批后自动推 A303-2+A302-6 开关,默认关闭 */ - @Value("${thirdParty.bfi.autoSync.receipt:false}") - private boolean receiptEnabled; + private final BfiProperties bfiProperties; /** 当前审批请求线程的自动推送失败原因,供 Controller 取走提示前端(见类注释线程说明) */ private static final ThreadLocal SYNC_FAILURE = new ThreadLocal<>(); @@ -118,7 +103,7 @@ public class KingdeeApprovalSyncListener { } private void pushSettlement(Long id) { - if (!settlementEnabled) { + if (!bfiProperties.getAutoSync().isSettlement()) { return; } log.info("正式结算单[{}]审批通过自动同步金蝶开始", id); @@ -127,7 +112,7 @@ public class KingdeeApprovalSyncListener { } private void pushPayment(Long id) { - if (!paymentEnabled) { + if (!bfiProperties.getAutoSync().isPayment()) { return; } log.info("付款申请[{}]审批通过自动同步金蝶开始", id); @@ -136,7 +121,7 @@ public class KingdeeApprovalSyncListener { } private void pushInvoiceApply(Long id) { - if (!invoiceApplyEnabled) { + if (!bfiProperties.getAutoSync().isInvoiceApply()) { return; } log.info("开票申请[{}]审批通过自动同步金蝶开始", id); @@ -145,7 +130,7 @@ public class KingdeeApprovalSyncListener { } private void pushReceipt(Long id) { - if (!receiptEnabled) { + if (!bfiProperties.getAutoSync().isReceipt()) { return; } log.info("收票登记[{}]审批通过自动推送金蝶收票单开始", id); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java index 992297eb..a62aca07 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java @@ -52,6 +52,7 @@ import org.springblade.thirdparty.bfi.service.IBfiService; import org.springblade.thirdparty.bfi.util.BfiUtil; import org.springblade.system.cache.UserCache; import org.springblade.transport.excel.CustomerArchiveExcel; +import org.springblade.transport.config.BfiProperties; import org.springblade.transport.mapper.CreditRatingStandardMapper; import org.springblade.transport.mapper.CreditScoreCategoryMapper; import org.springblade.transport.mapper.CreditScoreItemMapper; @@ -92,7 +93,6 @@ import org.springblade.transport.pojo.vo.CustomerInvoiceInfoVO; import org.springblade.transport.pojo.vo.CustomerReceiptAccountVO; import org.springblade.transport.service.ICustomerArchiveService; import org.springblade.transport.support.KingdeeSyncLockSupport; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -219,24 +219,11 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl selectCustomerArchivePage(IPage page, CustomerArchiveVO customer) { List records = baseMapper.selectCustomerArchivePage(page, customer, currentScopeUserId()); @@ -647,7 +634,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl selectPage(IPage page, FormalSettlementVO query) { @@ -851,7 +845,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl selectPage(IPage page, InvoiceApplicationVO query) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() @@ -1135,7 +1127,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl selectPage(IPage page, InvoiceReceiptVO query) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() @@ -870,7 +848,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl rows = new LinkedHashMap<>(); LocalDateTime windowEnd = LocalDateTime.now(); - LocalDateTime windowStart = windowEnd.minusDays(Math.max(receivedQueryWindowDays, 1)); + LocalDateTime windowStart = windowEnd.minusDays(Math.max(bfiProperties.getReceivedInvoice().getQueryWindowDays(), 1)); for (Map.Entry> entry : invoiceNosByBuyer.entrySet()) { if (StringUtil.isBlank(entry.getKey())) { continue; @@ -939,7 +917,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl匹配与容错说明: * ① 匹配键为收票登记 id,与 A303-2 落库的 awrp_src_code 同源,按发票号匹配将永远查不到自推单据; - * ② 查询窗口为近 {@code receivedResultWindowDays} 天(至少 1 天),窗口内查不到不判为金蝶侧已删除 + * ② 查询窗口为近 {@code thirdparty.bfi.receivedInvoice.resultWindowDays} 配置天数(至少 1 天),窗口内查不到不判为金蝶侧已删除 * (金蝶修改时间延迟/滑窗),保持现状由人工重推兜底; * ③ 单笔回写异常仅记入失败明细不中断整轮,结束时汇总进执行摘要; * ④ 由 {@link #syncKingdeeReceivedInvoiceResult()} 在分布式锁保护下调用,防多实例并发重跑。 @@ -994,7 +972,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl new ArrayList<>()).add(receipt); } LocalDateTime windowEnd = LocalDateTime.now(); - LocalDateTime windowStart = windowEnd.minusDays(Math.max(receivedResultWindowDays, 1)); + LocalDateTime windowStart = windowEnd.minusDays(Math.max(bfiProperties.getReceivedInvoice().getResultWindowDays(), 1)); int recovered = 0; int reassigned = 0; int filled = 0; @@ -1248,14 +1226,10 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl invoiceTypes = this.poolInvoiceTypeCodes(); SyncStats stats = new SyncStats(); @@ -1296,10 +1270,10 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl poolInvoiceTypeCodes() { - if (StringUtil.isBlank(poolInvoiceTypes)) { + if (StringUtil.isBlank(bfiProperties.getInvoiceReceipt().getInvoiceTypes())) { return List.of(); } - return java.util.Arrays.stream(poolInvoiceTypes.split(",")) + return java.util.Arrays.stream(bfiProperties.getInvoiceReceipt().getInvoiceTypes().split(",")) .map(String::trim) .filter(StringUtil::isNotBlank) .distinct() diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java index e127dfc6..ccac6a62 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java @@ -103,7 +103,6 @@ import org.springblade.transport.support.KingdeeApBillSyncSupport; import org.springblade.transport.support.KingdeeAttachmentSyncSupport; import org.springblade.transport.support.KingdeeSyncLockSupport; import org.springblade.transport.wrapper.PaymentApplicationWrapper; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -169,13 +168,6 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl selectPage(IPage page, PaymentApplicationVO query) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() @@ -731,7 +723,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl selectPage(IPage page, ReceiptFlowVO query) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() @@ -712,7 +704,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl