diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java index 533394ae..16a09b7b 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java @@ -52,68 +52,68 @@ public class KingdeeReceiptFlow extends TenantEntity { private static final long serialVersionUID = 1L; /** - * 金蝶认领公告id(A301-2 返回 id,认领推送 A301-3 必填) + * 金蝶认领公告id(历史 A301-2 同步遗留,A301-1 口径不再使用,恒为空) */ @JsonSerialize(using = ToStringSerializer.class) private Long billId; /** - * 金蝶付款人id(A301-2 公告对应往来单位 id,认领推送 A301-3 用) + * 金蝶付款人id(历史 A301-2 同步遗留,A301-1 口径不再使用,恒为空) */ private String payerId; /** - * 公告认领状态(A301-2 claimstatus:0未认领/1已认领) + * 公告认领状态(历史 A301-2 同步遗留,A301-1 口径不再使用,恒为空) */ private String kingdeeClaimStatus; /** - * 我已认领(A301-2 claimme) + * 我已认领(历史 A301-2 同步遗留,A301-1 口径不再使用,恒为空) */ private Boolean claimMe; /** - * 未认领金额(A301-2 unclaimamount) + * 未匹配收款金额(A301-1 unmatchamountrec,认领上限口径) */ private BigDecimal unclaimedAmount; /** - * 手续费(A301-2 fee) + * 手续费(A301-1 fee) */ private BigDecimal fee; /** - * 收款人(A301-2 recpayee) + * 收款人(A301-1 收款公司名称 org_name) */ private String payeeName; /** - * 收款通知单号(A301-2 billno) + * 金蝶收款单号(A301-1 billno) */ private String receiptNoticeNo; /** - * 付款人名称(A301-2 recviewpayer) + * 付款人名称(A301-1 payername) */ private String payerName; /** - * 收款金额(A301-2 reamount) + * 收款金额(A301-1 流水分录 bei_creditamount,兜底主单 actrecamt) */ private BigDecimal receiptAmount; /** - * 对方单位名称(A301-2 oppunit) + * 对方单位名称(A301-1 付款人名称) */ private String counterpartyName; /** - * 对方银行账号(A301-2 oppbanknumber) + * 对方银行账号(A301-1 付款账户 payeracctbanknum) */ private String counterpartyAccount; /** - * 对方开户行(A301-2 oppbank) + * 对方开户行(A301-1 付款银行 payerbankname) */ private String counterpartyBank; /** - * 摘要(A301-2 description) + * 摘要(A301-1 txt_description) */ private String summary; /** - * 交易日期(A301-2 tradetime) + * 交易日期(A301-1 业务日期 bizdate) */ private LocalDateTime transactionTime; /** - * 明细流水号(A301-2 detailid,回退 tradedetailno / bankdetailno,幂等键) + * 明细流水号(A301-1 流水分录 bei_detailid,兜底 bei_bankdetailno,幂等键) */ private String detailSerialNo; /** @@ -125,27 +125,27 @@ public class KingdeeReceiptFlow extends TenantEntity { */ private String claimStatus; /** - * 推送状态(none未推送/pushed已推送/failed推送失败;已推送为终态闸门,不允许二次推送) + * 推送状态(none未推送/pushed已推送/failed推送失败;历史 A301-3 推送遗留,A301-1 口径下恒为 none,仅存量的已推送数据保留展示) */ private String pushStatus; /** - * 最近一次推送失败原因(成功后清空) + * 最近一次推送失败原因(历史 A301-3 推送遗留) */ private String pushFailReason; /** - * 首次推送金蝶成功时间 + * 首次推送金蝶成功时间(历史 A301-3 推送遗留) */ private LocalDateTime pushedTime; /** - * 金蝶推送来源单据编码(分摊结算单号下划线拼接,推送时生成落库;分摊不变则重试编码不变,A301-1 回写匹配键) + * 金蝶推送来源单据编码(历史 A301-3 推送遗留,A301-1 口径不再生成) */ private String awrpSrcCode; /** - * 金蝶收款单号(推送响应回填 / A301-1 回写推进) + * 金蝶收款单号(A301-1 同步落库 billno) */ private String kingdeeBillNo; /** - * 金蝶回写状态(none未推送/pushed已推送/approved审核通过/received已收款/failed失败) + * 金蝶单据状态(A301-1 billstatus 映射:none未推送/pushed已推送/approved审核通过/received已收款/failed失败,同步时随单据刷新) */ private String kingdeeBillStatus; /** 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 5fe089fe..0b579ecb 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 @@ -71,9 +71,9 @@ public class BfiProperties { private ReceivedInvoice receivedInvoice = new ReceivedInvoice(); /** - * 收款认领公告查询配置(A301-2) + * 收款流水同步配置(A301-1 收款单查询) */ - private ClaimAnnounce claimAnnounce = new ClaimAnnounce(); + private RecBillSync recBillSync = new RecBillSync(); /** * 付款结果定时回写配置(A103-2/A103-4,总开关同时控制应收勾稽、开票结果回写) @@ -85,11 +85,6 @@ public class BfiProperties { */ private ReceivedInvoiceResult receivedInvoiceResult = new ReceivedInvoiceResult(); - /** - * 收款认领推送配置(A301-3) - */ - private ReceiptClaimPush receiptClaimPush = new ReceiptClaimPush(); - /** * 全票池发票定时同步配置(A801-1) */ @@ -197,20 +192,15 @@ public class BfiProperties { } /** - * 收款认领公告查询配置项(A301-2) + * 收款流水同步配置项(A301-1 收款单查询) */ @Data - public static class ClaimAnnounce { + public static class RecBillSync { /** - * 查询时间窗口(月数),默认 6(近半年) + * 同步业务日期窗口天数,默认 30(A301-1 契约约束业务日期范围不可超过 1 个月) */ - private int months = 6; - - /** - * 认领人(claimusers):配置后公告查询固定使用该值,不再按当前登录用户姓名查询 - */ - private String claimusers; + private int days = 30; } /** @@ -271,23 +261,6 @@ public class BfiProperties { private boolean syncEnabled = false; } - /** - * 收款认领推送配置项(A301-3) - */ - @Data - public static class ReceiptClaimPush { - - /** - * 推送任务开关,默认关闭(联调稳定后开启) - */ - private boolean syncEnabled = false; - - /** - * 推送 single-flight 锁租约秒数,须大于最坏一轮耗时(逐认领人远程查公告 + 逐条推送) - */ - private long lockLeaseSeconds = 1800; - } - /** * 全票池发票同步配置项(A801-1) */ diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java index 1bbee361..b1fc3b21 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java @@ -35,7 +35,6 @@ import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.secure.annotation.PreAuth; import org.springblade.core.tool.api.R; -import org.springblade.transport.pojo.dto.ReceiptClaimPushResult; import org.springblade.transport.pojo.dto.ReceiptClaimRequest; import org.springblade.transport.pojo.vo.ReceiptFlowVO; import org.springblade.transport.service.IReceiptFlowService; @@ -95,16 +94,8 @@ public class ReceiptFlowController extends BladeController { @PostMapping("/sync") @ApiOperationSupport(order = 5) - @Operation(summary = "手动同步金蝶收款流水(A301-2 收款认领公告查询)") + @Operation(summary = "手动同步金蝶收款流水(A301-1 收款单查询)") public R sync() { return R.data(receiptFlowService.sync()); } - - @PostMapping("/push-kingdee") - @ApiOperationSupport(order = 6) - @Operation(summary = "推送金蝶收款认领(A301-3 收款认领结果推送,仅认领完成流水可推送)") - public R pushKingdee(@RequestParam Long flowId) { - ReceiptClaimPushResult result = receiptFlowService.pushClaimToKingdee(flowId); - return result.isSuccess() ? R.data(result) : R.fail(result.getMessage()); - } } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java index 89586f79..4985b5ba 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java @@ -27,7 +27,6 @@ package org.springblade.transport.service; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseService; -import org.springblade.transport.pojo.dto.ReceiptClaimPushResult; import org.springblade.transport.pojo.dto.ReceiptClaimRequest; import org.springblade.transport.pojo.entity.KingdeeReceiptFlow; import org.springblade.transport.pojo.vo.ReceiptFlowVO; @@ -53,25 +52,9 @@ public interface IReceiptFlowService extends BaseService { Long claim(ReceiptClaimRequest request); /** - * 手动同步金蝶收款流水:直连 A301-2 收款认领公告查询,按明细流水号幂等 upsert 收款流水表 + * 手动同步金蝶收款流水:直连 A301-1 收款单查询(收款处理查询),按流水分录明细流水号幂等 upsert 收款流水表 * * @return 本次同步条数 */ int sync(); - - /** - * 手动推送金蝶(A301-3 收款认领结果推送):认领完成且未推送过的流水才可推送, - * 推送前以当前用户姓名重查 A301-2 最新公告对账。与定时任务共用同一推送实现。 - * - * @param flowId 收款流水id - * @return 推送结果(失败不抛异常,原因随结果返回) - */ - ReceiptClaimPushResult pushClaimToKingdee(Long flowId); - - /** - * 定时推送金蝶:扫描认领完成且未推送过的流水,按认领人姓名分组重查 A301-2 最新公告后逐条推送。 - * - * @return 执行摘要 - */ - String pushClaimByTask(); } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java index 899315a4..b47b4fe3 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java @@ -38,12 +38,9 @@ import org.springblade.core.tool.utils.Func; import org.springblade.system.cache.SysCache; import org.springblade.system.cache.UserCache; import org.springblade.system.pojo.entity.Dept; -import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimAnnounceQueryDTO; -import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushDTO; -import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushEntryDTO; -import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultItemVO; -import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO; -import org.springblade.thirdparty.bfi.pojo.vo.BfiClaimAnnounceVO; +import org.springblade.thirdparty.bfi.pojo.dto.BfiRecBillQueryDTO; +import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillFlowVO; +import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillVO; import org.springblade.thirdparty.bfi.service.IBfiService; import org.springblade.thirdparty.bfi.util.BfiUtil; import org.springblade.transport.config.BfiProperties; @@ -53,7 +50,6 @@ import org.springblade.transport.mapper.KingdeeReceiptFlowMapper; import org.springblade.transport.mapper.ReceiptClaimMapper; import org.springblade.transport.mapper.ReceiptClaimSettlementMapper; import org.springblade.transport.mapper.ReceiptFlowRecordMapper; -import org.springblade.transport.pojo.dto.ReceiptClaimPushResult; import org.springblade.transport.pojo.dto.ReceiptClaimRequest; import org.springblade.transport.pojo.entity.FormalSettlement; import org.springblade.transport.pojo.entity.KingdeeReceiptFlow; @@ -63,13 +59,13 @@ import org.springblade.transport.pojo.entity.ReceiptFlowRecord; import org.springblade.transport.pojo.vo.ReceiptFlowVO; import org.springblade.transport.service.IFormalSettlementService; import org.springblade.transport.service.IReceiptFlowService; -import org.springblade.transport.support.KingdeeSyncLockSupport; import org.springblade.transport.support.TransportBusinessSupport; import org.springblade.transport.support.hcs.HcsClaimSyncSupport; import org.springblade.transport.wrapper.ReceiptFlowWrapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import java.math.BigDecimal; import java.math.RoundingMode; @@ -77,9 +73,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -109,18 +104,14 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl allocationMap = allocationMap(request.getSettlements()); // 结算单id列表(升序) @@ -347,9 +333,9 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl announces = queryClaimAnnounces(claimusers); + List recBills = queryRecBills(); - if (announces.isEmpty()) { + if (recBills.isEmpty()) { record(null, null, "sync", "手动同步流水", null, null, BigDecimal.ZERO, - "金蝶认领公告未查询到数据"); + "金蝶收款单未查询到数据"); return 0; } - // 同步口径:A301-2 按参与认领用户(当前登录用户真实姓名)拉取全量认领公告, + // 同步口径:A301-1 按业务日期窗口拉取金蝶收款单(收款处理),按流水分录展开, // 以金蝶明细流水号为幂等键 upsert 收款流水表;本地已认领金额/状态(claimedAmount/claimStatus) - // 由认领、作废驱动,不被公告顺带覆盖,公告侧状态单独存 kingdee_claim_status/unclaimed_amount。 + // 由认领、作废驱动,不被同步顺带覆盖,未匹配收款金额单独存 unclaimed_amount 作为认领上限。 - // 第一遍:数据校验与过滤,收集有效的 detailSerialNo - log.info("收款流水同步开始数据校验,共 {} 条认领公告", announces.size()); - Map validAnnounces = new LinkedHashMap<>(); + // 第一遍:数据校验与过滤,主单+流水分录展开为流水行,收集有效的 detailSerialNo + log.info("收款流水同步开始数据校验,共 {} 张收款单", recBills.size()); + Map validRows = new LinkedHashMap<>(); int skippedCount = 0; - for (BfiClaimAnnounceVO announce : announces) { - // 明细流水号优先级:detailid > tradedetailno > bankdetailno - String detailSerialNo = firstNonBlank(announce.getDetailid(), - announce.getTradedetailno(), announce.getBankdetailno()); - if (Func.isEmpty(detailSerialNo)) { - log.warn("收款流水同步跳过:认领公告[{}]缺少明细流水号", announce.getBillno()); + for (BfiRecBillVO recBill : recBills) { + List flowEntries = recBill.getInfoentry(); + if (Func.isEmpty(flowEntries)) { + log.warn("收款流水同步跳过:收款单[{}]无流水分录", recBill.getBillno()); skippedCount++; continue; } - detailSerialNo = detailSerialNo.trim(); - if (validAnnounces.containsKey(detailSerialNo)) { - throw new ServiceException("明细流水号" + detailSerialNo + "重复"); + for (BfiRecBillFlowVO flowEntry : flowEntries) { + // 明细流水号优先级:bei_detailid > bei_bankdetailno + String detailSerialNo = firstNonBlank(flowEntry.getBeiDetailid(), flowEntry.getBeiBankdetailno()); + if (Func.isEmpty(detailSerialNo)) { + log.warn("收款流水同步跳过:收款单[{}]流水分录缺少明细流水号", recBill.getBillno()); + skippedCount++; + continue; + } + detailSerialNo = detailSerialNo.trim(); + if (validRows.containsKey(detailSerialNo)) { + throw new ServiceException("明细流水号" + detailSerialNo + "重复"); + } + BigDecimal receiptAmount = parseEntryAmount(flowEntry.getBeiCreditamount(), recBill.getActrecamt()); + if (receiptAmount.compareTo(BigDecimal.ZERO) <= 0) { + log.warn("收款流水同步跳过:收款单[{}]流水分录收款金额为空或小于0", recBill.getBillno()); + skippedCount++; + continue; + } + validRows.put(detailSerialNo, new BfiRecBillRow(recBill, flowEntry, detailSerialNo, receiptAmount)); } - BigDecimal receiptAmount = money(announce.getReamount()); - if (receiptAmount.compareTo(BigDecimal.ZERO) <= 0) { - log.warn("收款流水同步跳过:认领公告[{}]收款金额为空或小于0", announce.getBillno()); - skippedCount++; - continue; - } - validAnnounces.put(detailSerialNo, announce); } - log.info("收款流水数据校验完成:有效 {} 条,跳过 {} 条", validAnnounces.size(), skippedCount); + log.info("收款流水数据校验完成:有效 {} 条,跳过 {} 条", validRows.size(), skippedCount); - if (validAnnounces.isEmpty()) { + if (validRows.isEmpty()) { log.info("收款流水同步无有效数据,记录操作日志后返回"); record(null, null, "sync", "手动同步流水", null, null, BigDecimal.ZERO, - "金蝶认领公告无有效数据"); + "金蝶收款单无有效数据"); return 0; } // 批量查询已存在的记录(FOR UPDATE 防并发) - log.info("收款流水同步开始批量查询已存在记录,查询条件:detailSerialNo IN {} 条", validAnnounces.size()); + log.info("收款流水同步开始批量查询已存在记录,查询条件:detailSerialNo IN {} 条", validRows.size()); List existingEntities = baseMapper.selectList( Wrappers.lambdaQuery() - .in(KingdeeReceiptFlow::getDetailSerialNo, validAnnounces.keySet()) + .in(KingdeeReceiptFlow::getDetailSerialNo, validRows.keySet()) .last("FOR UPDATE") ); Map existingMap = existingEntities.stream() .collect(Collectors.toMap(KingdeeReceiptFlow::getDetailSerialNo, e -> e)); log.info("收款流水批量查询完成:已存在 {} 条,待新增 {} 条", - existingEntities.size(), validAnnounces.size() - existingEntities.size()); + existingEntities.size(), validRows.size() - existingEntities.size()); // 第二遍:构建新增和更新列表 log.info("收款流水同步开始构建新增/更新列表"); @@ -512,10 +508,9 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl entry : validAnnounces.entrySet()) { + for (Map.Entry entry : validRows.entrySet()) { String detailSerialNo = entry.getKey(); - BfiClaimAnnounceVO announce = entry.getValue(); - BigDecimal receiptAmount = money(announce.getReamount()); + BfiRecBillRow row = entry.getValue(); // 判断是新增还是更新 KingdeeReceiptFlow existing = existingMap.get(detailSerialNo); @@ -532,8 +527,8 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl candidateRow(FormalSettlement settlement, BigDecimal claimedAmount) { BigDecimal settlementAmount = money(settlement.getSettlementAmount()); Map row = new LinkedHashMap<>(); @@ -724,8 +726,8 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl - * 仅认领完成且未推送过的流水可推送;推送前以当前用户姓名重查 A301-2 最新公告对账。 - * 推送失败不抛异常跨事务边界(保证失败状态落库),原因随结果对象返回。 + * A301-1 收款单查询:业务日期窗口全量翻页,窗口天数取 Nacos 配置(默认近30天,契约约束 ≤1 个月)。 + * 收款流水同步专用。 */ - @Override - public ReceiptClaimPushResult pushClaimToKingdee(Long flowId) { - if (flowId == null) { - throw new ServiceException("收款流水ID不能为空"); - } - KingdeeReceiptFlow flow = existing(flowId); - if (flow.getBillId() == null) { - return ReceiptClaimPushResult.fail("认领公告id缺失,请先手动同步金蝶收款流水"); - } - String claimusers = UserCache.getUserRealName(AuthUtil.getUserId()); - if (Func.isEmpty(claimusers)) { - throw new ServiceException("当前用户无姓名,无法推送金蝶收款认领"); - } - // 推送前对账:以当前用户身份重查 A301-2 拿最新公告(手动推送者须在公告认领范围内) - BfiClaimAnnounceVO announce = queryClaimAnnounces(claimusers).stream() - .filter(item -> flow.getBillId().equals(item.getId())) - .findFirst().orElse(null); - if (announce == null) { - return ReceiptClaimPushResult.fail("金蝶侧未查询到该认领公告,当前用户可能不在公告认领范围内,请重新同步后重试"); - } - return pushClaimLocked(flow.getId(), announce); - } - - /** - * 定时推送金蝶:扫描认领完成且未推送过的流水,按认领人姓名分组重查 A301-2 最新公告后逐条推送。 - * 多副本部署下由 single-flight 分布式锁保证同一轮全局最多一份在跑,已有轮次进行中则本轮跳过。 - * - * @return 执行摘要 - */ - @Override - public String pushClaimByTask() { - return kingdeeSyncLockSupport.runSingleFlight(RECEIPT_CLAIM_PUSH_LOCK_PREFIX, bfiProperties.getReceiptClaimPush().getLockLeaseSeconds(), - "定时推送收款认领", this::executeReceiptClaimPush); - } - - /** - * 定时推送收款认领主体:按认领人姓名串行处理—— - * 先重查该认领人的 A301-2 最新公告并推完其名下全部流水,再到下一个认领人。 - * A301-2 的 claimusers 必填且为单个用户姓名,定时任务无登录人上下文, - * 故按认领人逐人查询公告,按公告id(bill_id)匹配流水。 - * 单条流水推送失败独立消化,不影响同批其他流水。 - * - * @return 执行摘要 - */ - private String executeReceiptClaimPush() { - List candidates = list(Wrappers.lambdaQuery() - .isNotNull(KingdeeReceiptFlow::getBillId) - .in(KingdeeReceiptFlow::getPushStatus, List.of( - KingdeeBfiConstant.RECEIPT_CLAIM_PUSH_NONE, KingdeeBfiConstant.RECEIPT_CLAIM_PUSH_FAILED)) - .eq(KingdeeReceiptFlow::getClaimStatus, CLAIMED) - .eq(KingdeeReceiptFlow::getStatus, 1) - .orderByAsc(KingdeeReceiptFlow::getId)); - if (candidates.isEmpty()) { - return "无待推送流水"; - } - Map candidateById = candidates.stream() - .collect(Collectors.toMap(KingdeeReceiptFlow::getId, Function.identity(), - (first, second) -> first, LinkedHashMap::new)); - // 认领人 → 其有效认领的流水id - Map> claimedFlowIdsByClaimer = claimMapper.selectList( - Wrappers.lambdaQuery() - .in(ReceiptClaim::getReceiptFlowId, candidateById.keySet()) - .eq(ReceiptClaim::getClaimStatus, CLAIMED)).stream() - .filter(claim -> Func.isNotEmpty(claim.getClaimerName()) && claim.getReceiptFlowId() != null) - .collect(Collectors.groupingBy(ReceiptClaim::getClaimerName, - Collectors.mapping(ReceiptClaim::getReceiptFlowId, Collectors.toSet()))); - if (claimedFlowIdsByClaimer.isEmpty()) { - return "待推送流水 " + candidates.size() + " 条,但无有效认领人,跳过"; - } - int successCount = 0; - int failedCount = 0; - int skippedCount = 0; - // 本轮已推送成功的流水:同一流水被多个认领人认领时,只在首个覆盖它的认领人处推送一次 - Set pushedFlowIds = new HashSet<>(); - // 按认领人逐人串行:查该认领人公告 → 推完其名下流水 → 下一个认领人 - for (String claimerName : claimedFlowIdsByClaimer.keySet().stream().sorted().toList()) { - Set claimerFlowIds = claimedFlowIdsByClaimer.get(claimerName); - List claimerFlows = candidateById.values().stream() - .filter(flow -> claimerFlowIds.contains(flow.getId())) - .filter(flow -> !pushedFlowIds.contains(flow.getId())) - .toList(); - if (claimerFlows.isEmpty()) { - continue; - } - // 该认领人的公告一次查询,按公告id归集 - Map announceByBillId = new HashMap<>(); - try { - for (BfiClaimAnnounceVO announce : queryClaimAnnounces(claimerName)) { - if (announce.getId() != null) { - announceByBillId.putIfAbsent(announce.getId(), announce); - } - } - } catch (Exception exception) { - log.error("定时推送收款认领:认领人[{}]公告查询失败,其名下流水全部跳过", claimerName, exception); - skippedCount += claimerFlows.size(); - continue; - } - for (KingdeeReceiptFlow flow : claimerFlows) { - BfiClaimAnnounceVO announce = announceByBillId.get(flow.getBillId()); - if (announce == null) { - skippedCount++; - log.info("定时推送收款认领:认领人[{}]流水[{}]未在公告查询结果中命中,跳过", - claimerName, flow.getId()); - continue; - } - try { - ReceiptClaimPushResult result = pushClaimLocked(flow.getId(), announce); - if (result.isSuccess()) { - successCount++; - pushedFlowIds.add(flow.getId()); - } else { - failedCount++; - } - } catch (Exception exception) { - failedCount++; - log.error("定时推送收款认领:认领人[{}]流水[{}]推送异常", claimerName, flow.getId(), exception); - } - } - } - String summary = "扫描 " + candidates.size() + " 条,推送成功 " + successCount - + " 条,推送失败 " + failedCount + " 条,公告未命中跳过 " + skippedCount + " 条"; - log.info("定时推送收款认领完成:{}", summary); - return summary; - } - - /** - * 事务内推送:流水行锁覆盖闸门校验、对账、推送与状态落库全过程, - * 防定时任务与手动按钮并发对同一流水双推; - * 推送成功后触发合同合规认领链推送(C103-9/C107-1/C108-1,事务提交后执行,失败不影响金蝶推送结果) - */ - private ReceiptClaimPushResult pushClaimLocked(Long flowId, BfiClaimAnnounceVO announce) { - ReceiptClaimPushResult result = transactionTemplate.execute(status -> doPushClaimToKingdee(flowId, announce)); - if (result != null && result.isSuccess()) { - hcsClaimSyncSupport.pushClaimToHcs(flowId); - } - return result; - } - - /** - * 推送单条流水:静态闸门 → 最新公告对账 → 按流水归集分摊行推送 → 成败状态落库 - */ - private ReceiptClaimPushResult doPushClaimToKingdee(Long flowId, BfiClaimAnnounceVO announce) { - KingdeeReceiptFlow flow = lockedFlow(flowId); - if (flow.getBillId() == null) { - return ReceiptClaimPushResult.fail("认领公告id缺失,请先手动同步金蝶收款流水"); - } - // 终态闸门:已推送流水不允许二次推送(作废重认领使等式再满足也不推,金蝶侧人工处置) - if (KingdeeBfiConstant.RECEIPT_CLAIM_PUSH_PUSHED.equals(flow.getPushStatus())) { - return ReceiptClaimPushResult.fail("该流水已推送金蝶,不允许重复推送"); - } - // 推送前对账:以最新公告刷新公告侧未认领金额并重算认领状态(快照落库,页面口径同步修正) - flow.setUnclaimedAmount(money(announce.getUnclaimamount())); - flow.setKingdeeClaimStatus(trimToNull(announce.getClaimstatus())); - flow.setClaimMe(announce.getClaimme()); - BigDecimal claimedTotal = flowClaimedAmount(flow.getId()); - flow.setClaimedAmount(claimedTotal); - BigDecimal claimCeiling = claimCeiling(flow); - String claimStatus = amountClaimStatus(claimedTotal, claimCeiling); - flow.setClaimStatus(claimStatus); - updateById(flow); - if (!CLAIMED.equals(claimStatus)) { - return ReceiptClaimPushResult.fail("累计认领金额(" + claimedTotal + ")与可认领上限(" - + claimCeiling + ")不一致,不满足推送条件"); - } - // 分录取该流水全部有效分摊行(结算单id升序,跨认领主单归集) - List allocations = claimSettlementMapper.selectList( - Wrappers.lambdaQuery() - .eq(ReceiptClaimSettlement::getReceiptFlowId, flow.getId()) - .eq(ReceiptClaimSettlement::getStatus, 1) - .eq(ReceiptClaimSettlement::getIsDeleted, 0) - .orderByAsc(ReceiptClaimSettlement::getFormalSettlementId)); - if (allocations.isEmpty()) { - return ReceiptClaimPushResult.fail("该流水无有效认领分摊,无法推送"); - } - // 核心单据编号取第一张结算单同步金蝶回写的星瀚内码(应收/应付单金蝶id),TMS本地id金蝶无法识别 - FormalSettlement firstSettlement = formalSettlementMapper.selectById(allocations.get(0).getFormalSettlementId()); - if (firstSettlement == null || Func.isBlank(firstSettlement.getKingdeeBillId())) { - return ReceiptClaimPushResult.fail("结算单" + allocations.get(0).getFormalSettlementNo() - + "未同步金蝶(缺少金蝶单据id),不满足推送条件"); - } - // 推送来源编码:分摊结算单号下划线拼接(A301-3 契约口径;分摊不变则重试编码不变, - // 金蝶按 awrp_src_sys + awrp_src_code 幂等防重试双单) - String awrpSrcCode = allocations.stream() - .map(ReceiptClaimSettlement::getFormalSettlementNo) - .filter(Func::isNotEmpty) - .distinct() - .collect(Collectors.joining("_")); - flow.setAwrpSrcCode(awrpSrcCode); - - BfiClaimPushDTO param = buildClaimPushDTO(flow, claimedTotal, allocations, firstSettlement.getKingdeeBillId()); - log.info("调用BFI接口 收款认领结果推送开始 flowId:{},billId:{},awrpSrcCode:{},分摊明细 {} 行,认领金额 {}", - flow.getId(), flow.getBillId(), flow.getAwrpSrcCode(), allocations.size(), claimedTotal); - try { - BfiBillSaveResultVO result = bfiService.pushClaimResult(param); - return applyClaimPushSuccess(flow, extractClaimPushBillNo(result)); - } catch (Exception exception) { - return applyClaimPushFailure(flow, exception); - } - } - - /** - * A301-3 推送报文组装:billid=公告id,单条分录、金额=全部未推送金额(一笔流水一张金蝶收款单), - * 核心单据编号=第一张结算单的金蝶单据id(星瀚内码) - */ - private BfiClaimPushDTO buildClaimPushDTO(KingdeeReceiptFlow flow, BigDecimal claimedTotal, - List allocations, String coreBillId) { - BfiClaimPushDTO param = new BfiClaimPushDTO(); - // 【必填】认领公告id - param.setBillid(flow.getBillId()); - // 【必填】来源系统编码 - param.setAwrpSrcSys(bfiProperties.getSrcSys()); - // 【必填】来源系统单据编码(分摊结算单号下划线拼接) - param.setAwrpSrcCode(flow.getAwrpSrcCode()); - // 【必填】收款类型.编码 - param.setRecpaytypeNumber(KingdeeBfiConstant.BFI_CLAIM_REC_PAY_TYPE); - // 【必填】付款人类型 - param.setPaymenttype(KingdeeBfiConstant.BFI_CLAIM_PAYMENT_TYPE); - // 【必填】付款人名称 - param.setRecviewpayer(flow.getPayerName()); - // 【必填】付款人id - param.setRecpayer(flow.getPayerId()); - // 【必填】单据体分录:仅一条,应收金额=全部未推送金额(累计有效认领) - BfiClaimPushEntryDTO entry = new BfiClaimPushEntryDTO(); - // 【必填】应收金额(全部未推送金额) - entry.setEReceivableamt(claimedTotal); - // 分录行序号(第一张结算单id,分摊已按结算单id升序,多张取最小) - entry.setSeq(allocations.get(0).getFormalSettlementId()); - // 核心单据类型 - // entry.setECorebilltype(KingdeeBfiConstant.BFI_CLAIM_CORE_BILL_TYPE); - // 核心单据编号(第一张结算单的金蝶单据id,星瀚内码) - entry.setECorebillno(coreBillId); - param.setEntryentity(List.of(entry)); - return param; - } - - /** - * 解析 A301-3 推送结果:全项成功返回单据号,否则抛出汇总错误文本(由失败路径落库)。 - * 成功响应的 number 为空,金蝶收款单号取回执 keys 中的 awrp_src_code(来源编码)。 - */ - private String extractClaimPushBillNo(BfiBillSaveResultVO result) { - if (result == null || result.getResult() == null || result.getResult().isEmpty()) { - throw new ServiceException("金蝶认领结果推送失败,返回结果为空"); - } - List items = result.getResult(); - boolean allSuccess = items.stream().allMatch(item -> Boolean.TRUE.equals(item.getBillStatus())); - if (!allSuccess) { - String errorText = items.stream() - .map(BfiBillSaveResultItemVO::getErrorText) - .filter(text -> !text.isEmpty()) - .collect(Collectors.joining(";")); - throw new ServiceException("金蝶认领结果推送失败" - + (errorText.isEmpty() ? "" : ":" + errorText)); - } - return items.stream() - .map(this::claimPushBillNoOf) - .filter(Func::isNotEmpty) - .findFirst().orElse(null); - } - - /** - * 单项推送结果 → 单据号:A301-3 成功响应 number 为空,取回执键值中的 awrp_src_code - */ - private String claimPushBillNoOf(BfiBillSaveResultItemVO item) { - if (Func.isNotEmpty(item.getNumber())) { - return item.getNumber(); - } - return item.getKeys() == null ? null : item.getKeys().get("awrp_src_code"); - } - - /** - * 推送成功:流水置已推送并回填金蝶收款单号,级联刷新名下未作废认领主单的冗余展示字段 - */ - private ReceiptClaimPushResult applyClaimPushSuccess(KingdeeReceiptFlow flow, String kingdeeBillNo) { - log.info("调用BFI接口 收款认领结果推送成功 flowId:{},金蝶收款单号:{}", - flow.getId(), Func.isEmpty(kingdeeBillNo) ? "响应未返回" : kingdeeBillNo); - flow.setPushStatus(KingdeeBfiConstant.RECEIPT_CLAIM_PUSH_PUSHED); - flow.setPushedTime(LocalDateTime.now()); - flow.setKingdeeBillNo(kingdeeBillNo); - flow.setKingdeeBillStatus(KingdeeBfiConstant.KINGDEE_STATUS_PUSHED); - // 失败原因需显式置空(实体 update 忽略 null 字段,走 lambdaUpdate) - this.update(Wrappers.lambdaUpdate() - .eq(KingdeeReceiptFlow::getId, flow.getId()) - .set(KingdeeReceiptFlow::getPushStatus, flow.getPushStatus()) - .set(KingdeeReceiptFlow::getPushFailReason, null) - .set(KingdeeReceiptFlow::getPushedTime, flow.getPushedTime()) - .set(KingdeeReceiptFlow::getAwrpSrcCode, flow.getAwrpSrcCode()) - .set(KingdeeReceiptFlow::getKingdeeBillNo, kingdeeBillNo) - .set(KingdeeReceiptFlow::getKingdeeBillStatus, flow.getKingdeeBillStatus())); - // 级联刷新名下未作废认领主单的冗余展示字段 - claimMapper.update(null, Wrappers.lambdaUpdate() - .eq(ReceiptClaim::getReceiptFlowId, flow.getId()) - .eq(ReceiptClaim::getClaimStatus, CLAIMED) - .set(ReceiptClaim::getKingdeeBillNo, kingdeeBillNo) - .set(ReceiptClaim::getKingdeeBillStatus, KingdeeBfiConstant.KINGDEE_STATUS_PUSHED)); - record(flow.getId(), null, "push", "推送金蝶收款认领", CLAIMED, CLAIMED, flow.getClaimedAmount(), - "金蝶收款单号:" + (Func.isEmpty(kingdeeBillNo) ? "响应未返回" : kingdeeBillNo)); - return ReceiptClaimPushResult.success(kingdeeBillNo); - } - - /** - * 推送失败:流水置推送失败并记录原因,本地认领数据保留,可重新推送(重试复用同一来源编码) - */ - private ReceiptClaimPushResult applyClaimPushFailure(KingdeeReceiptFlow flow, Exception exception) { - String reason = Func.isEmpty(exception.getMessage()) - ? exception.getClass().getSimpleName() : exception.getMessage(); - reason = truncateText(reason, 1000); - log.error("调用BFI接口 收款认领结果推送失败 flowId:{},billId:{},awrpSrcCode:{}", - flow.getId(), flow.getBillId(), flow.getAwrpSrcCode(), exception); - this.update(Wrappers.lambdaUpdate() - .eq(KingdeeReceiptFlow::getId, flow.getId()) - .set(KingdeeReceiptFlow::getPushStatus, KingdeeBfiConstant.RECEIPT_CLAIM_PUSH_FAILED) - .set(KingdeeReceiptFlow::getPushFailReason, reason) - .set(KingdeeReceiptFlow::getAwrpSrcCode, flow.getAwrpSrcCode())); - record(flow.getId(), null, "push", "推送金蝶收款认领", CLAIMED, CLAIMED, flow.getClaimedAmount(), - "推送失败:" + truncateText(reason, 200)); - return ReceiptClaimPushResult.fail("金蝶认领结果推送失败:" + reason); - } - - /** - * A301-2 收款认领公告查询:按认领人姓名全量翻页,时间窗口取 Nacos 配置(默认近半年)。 - * 认领公告同步、手动推送对账与定时任务对账共用。 - */ - private List queryClaimAnnounces(String claimusers) { - int months = bfiProperties.getClaimAnnounce().getMonths(); - // 认领人直接取 Nacos 配置值 - String effectiveClaimusers = bfiProperties.getClaimAnnounce().getClaimusers(); - LocalDateTime endDate = LocalDateTime.now(); - LocalDateTime startDate = endDate.minusMonths(months); + private List queryRecBills() { + int days = bfiProperties.getRecBillSync().getDays(); + LocalDate endDate = LocalDate.now(); + LocalDate startDate = endDate.minusDays(days); + // 金蝶 A301-1 仅接受带时分秒的日期参数,传纯日期会报 bos.filterSqlBuilder 时区时间格式错误 + String beginBizdate = startDate.atStartOfDay().format(BFI_DATE_TIME_FORMATTER); + String endBizdate = endDate.atTime(23, 59, 59).format(BFI_DATE_TIME_FORMATTER); long start = System.currentTimeMillis(); - log.info("调用BFI接口 收款认领公告查询开始 claimusers:{},时间窗口:{} ~ {}(近{}个月)", - effectiveClaimusers, startDate.format(BFI_DATE_TIME_FORMATTER), endDate.format(BFI_DATE_TIME_FORMATTER), months); - BfiClaimAnnounceQueryDTO queryDTO = new BfiClaimAnnounceQueryDTO(); - queryDTO.setClaimusers(effectiveClaimusers); - queryDTO.setModifytimeS(startDate.format(BFI_DATE_TIME_FORMATTER)); - queryDTO.setModifytimeE(endDate.format(BFI_DATE_TIME_FORMATTER)); + log.info("调用BFI接口 收款单查询开始,业务日期窗口:{} ~ {}(近{}天)", beginBizdate, endBizdate, days); + BfiRecBillQueryDTO queryDTO = new BfiRecBillQueryDTO(); + queryDTO.setBeginBizdate(beginBizdate); + queryDTO.setEndBizdate(endBizdate); queryDTO.setPageSize(SYNC_PAGE_SIZE); - List announces = BfiUtil.queryAllPages(pageNo -> { + List recBills = BfiUtil.queryAllPages(pageNo -> { queryDTO.setPageNo(pageNo); - return bfiService.queryClaimAnnounce(queryDTO); + return bfiService.queryRecBill(queryDTO); }); - log.info("调用BFI接口 收款认领公告查询结束 claimusers:{},耗时:{}ms,拉取 {} 条", - effectiveClaimusers, System.currentTimeMillis() - start, announces.size()); - return announces; + log.info("调用BFI接口 收款单查询结束 耗时:{}ms,拉取 {} 条", System.currentTimeMillis() - start, recBills.size()); + return recBills; } /** - * A301-2 认领公告 → 收款流水表字段拷贝(仅覆盖金蝶侧来源字段,不覆盖本地认领金额与状态) + * A301-1 收款单 → 收款流水表字段拷贝(仅覆盖金蝶侧来源字段,不覆盖本地认领金额与状态)。 + * 认领上限口径:未匹配收款金额 unmatchamountrec 存 unclaimed_amount。 */ - private void copyAnnounceRow(KingdeeReceiptFlow target, BfiClaimAnnounceVO source, - String detailSerialNo, BigDecimal receiptAmount) { - // 金蝶认领公告id - target.setBillId(source.getId()); - // 收款通知单号 + private void copyRecBillRow(KingdeeReceiptFlow target, BfiRecBillRow row) { + BfiRecBillVO source = row.recBill(); + // 金蝶收款单号(既是收款通知单号也是金蝶单据号) target.setReceiptNoticeNo(trimToEmpty(source.getBillno())); - // 付款人名称(取自对方户名) - target.setPayerName(trimToEmpty(source.getOppunit())); - // 付款人id(取自对方账号) - target.setPayerId(trimToEmpty(source.getOppbanknumber())); - // 收款人 - target.setPayeeName(trimToNull(source.getRecpayee())); - // 收款金额 - target.setReceiptAmount(receiptAmount); - // 对方单位名称 - target.setCounterpartyName(trimToEmpty(source.getOppunit())); - // 对方银行账号 - target.setCounterpartyAccount(trimToEmpty(source.getOppbanknumber())); - // 对方开户行 - target.setCounterpartyBank(trimToEmpty(source.getOppbank())); + target.setKingdeeBillNo(trimToNull(source.getBillno())); + // 金蝶回写状态随单据状态同步刷新 + target.setKingdeeBillStatus(billStatusOf(source.getBillstatus())); + // 付款人名称 + target.setPayerName(trimToEmpty(source.getPayername())); + // 收款人(收款公司名称) + target.setPayeeName(trimToNull(source.getOrgName())); + // 收款金额(流水分录金额) + target.setReceiptAmount(row.receiptAmount()); + // 对方单位名称(取付款人名称) + target.setCounterpartyName(trimToEmpty(source.getPayername())); + // 对方银行账号(付款账户) + target.setCounterpartyAccount(trimToEmpty(source.getPayeracctbanknum())); + // 对方开户行(付款银行) + target.setCounterpartyBank(trimToEmpty(source.getPayerbankname())); // 摘要 - target.setSummary(trimToNull(source.getDescription())); - // 交易日期 - target.setTransactionTime(parseDateTime(source.getTradetime())); + target.setSummary(trimToNull(source.getTxtDescription())); + // 交易日期(业务日期) + target.setTransactionTime(parseDateTime(source.getBizdate())); // 明细流水号 - target.setDetailSerialNo(detailSerialNo); - // 未认领金额 - target.setUnclaimedAmount(money(source.getUnclaimamount())); + target.setDetailSerialNo(row.detailSerialNo()); + // 未匹配收款金额(认领上限口径) + target.setUnclaimedAmount(money(source.getUnmatchamountrec())); // 手续费 target.setFee(source.getFee() == null ? null : source.getFee().setScale(2, RoundingMode.HALF_UP)); - // 公告认领状态 - target.setKingdeeClaimStatus(trimToNull(source.getClaimstatus())); - // 我已认领 - target.setClaimMe(source.getClaimme()); // 来源更新时间 - target.setSourceUpdatedTime(target.getTransactionTime() == null - ? LocalDateTime.now() : target.getTransactionTime()); + target.setSourceUpdatedTime(LocalDateTime.now()); + } + + /** + * A301-1 单据状态 → 本地金蝶回写状态(同步时随单据刷新) + * + * @param billStatus 金蝶 billstatus(A暂存/B已提交/C已审核/D已收款/G已退单) + * @return 本地状态 + */ + private String billStatusOf(String billStatus) { + if ("D".equals(billStatus)) { + return KingdeeBfiConstant.KINGDEE_STATUS_RECEIVED; + } + if ("C".equals(billStatus)) { + return APPROVED; + } + if ("A".equals(billStatus) || "B".equals(billStatus)) { + return KingdeeBfiConstant.KINGDEE_STATUS_PUSHED; + } + // 其余状态(含 G 已退单/E 变更中)按处理失败记录,提示人工在金蝶核查 + log.warn("金蝶收款单单据状态[{}]未匹配映射,同步按 failed 处理", billStatus); + return KingdeeBfiConstant.KINGDEE_STATUS_FAILED; + } + + /** + * 流水分录收款金额解析:bei_creditamount 为字符串,空或非法时回退主单收款金额 + */ + private BigDecimal parseEntryAmount(String entryAmount, BigDecimal fallbackAmount) { + if (Func.isNotEmpty(entryAmount)) { + try { + return new BigDecimal(entryAmount.trim()); + } catch (NumberFormatException exception) { + log.warn("解析金蝶流水分录收款金额失败,原始值:{},回退主单收款金额", entryAmount); + } + } + return money(fallbackAmount); } private String firstNonBlank(String... values) { @@ -1237,13 +943,6 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl - * 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 - * is strictly prohibited. - *

- * 3. Licensees may copyright their own code but cannot use segments - * from this software for their own commercial purposes. - *

- * Using this software signifies agreement to this license agreement and terms of use, - * and you expressly agree to be bound by the terms of use of this software. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - *

- * Author: Chill Zhuang (bladejava@qq.com) - */ -package org.springblade.transport.task; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springblade.transport.config.BfiProperties; -import org.springblade.transport.service.IReceiptFlowService; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -/** - * 收款认领推送金蝶定时任务(A301-3 收款认领结果推送) - *

- * 认领动作只在本地登记,本任务扫描「认领完成且未推送过」的收款流水自动推送金蝶, - * 与收款流水页「推送金蝶」手动按钮共用同一服务方法(推送前按认领人重查 A301-2 最新公告对账)。 - * 单条流水推送失败独立消化、可重试,不影响同批其他流水。 - *

- * 调度配置(Nacos thirdParty.bfi.receiptClaimPush.*):syncEnabled 开关、cron 表达式。 - * - * @author Chill - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class ReceiptClaimPushTask { - - private final IReceiptFlowService receiptFlowService; - private final BfiProperties bfiProperties; - - /** 收款认领推送调度,默认每10分钟执行一次 */ - @Scheduled(cron = "${thirdParty.bfi.receiptClaimPush.cron:0 4/10 * * * ?}") - public void pushClaimToKingdee() { - if (!bfiProperties.getReceiptClaimPush().isSyncEnabled()) { - return; - } - try { - String summary = receiptFlowService.pushClaimByTask(); - log.info("定时推送收款认领:{}", summary); - } catch (Exception exception) { - log.error("定时推送收款认领异常", exception); - } - } -} diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiRecBillQueryDTO.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiRecBillQueryDTO.java index 90ed5056..db3ea4ca 100644 --- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiRecBillQueryDTO.java +++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiRecBillQueryDTO.java @@ -38,7 +38,7 @@ import java.util.List; *

* 请求示例: *

{@code
- * GET /ierp/kapi/v2/awrp/cas/cas_recbill/queryRecBill?begin_bizdate=2021-09-08&end_bizdate=2026-09-08&org_number=01.01.20.02.04.01&pageSize=10&pageNo=1
+ * GET /ierp/kapi/v2/awrp/cas/cas_recbill/queryRecBill?begin_bizdate=2021-09-08 00:00:00&end_bizdate=2026-09-08 23:59:59&org_number=01.01.20.02.04.01&pageSize=10&pageNo=1
  * }
* * @author Chill @@ -57,12 +57,13 @@ public class BfiRecBillQueryDTO implements Serializable { */ private Integer pageSize; /** - * 【必填】开始业务日期,格式:yyyy-MM-dd,限定时间范围不可超过1个月 + * 【必填】开始业务日期,格式:yyyy-MM-dd HH:mm:ss,限定时间范围不可超过1个月; + * 传纯日期 yyyy-MM-dd 会被金蝶拒绝(bos.filterSqlBuilder 时间格式错误) */ @JsonProperty("begin_bizdate") private String beginBizdate; /** - * 【必填】结束业务日期,格式:yyyy-MM-dd + * 【必填】结束业务日期,格式:yyyy-MM-dd HH:mm:ss */ @JsonProperty("end_bizdate") private String endBizdate; diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/IBfiService.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/IBfiService.java index a8ff0944..8837a6ee 100644 --- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/IBfiService.java +++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/IBfiService.java @@ -277,7 +277,7 @@ public interface IBfiService { /** * A301-1 收款单查询(收款处理查询) * - * @param param 查询参数,业务日期范围不可超过1个月 + * @param param 查询参数,业务日期格式 yyyy-MM-dd HH:mm:ss,范围不可超过1个月 * @return 收款处理分页数据 */ BfiPageVO queryRecBill(BfiRecBillQueryDTO param);