From 459d81872478321de949633c17e1c26c0babec0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Thu, 29 Oct 2026 12:53:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20BFI=E5=88=86=E9=A1=B5=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8C=89totalCount=E6=8E=A8=E5=AF=BC=E6=80=BB=E9=A1=B5?= =?UTF-8?q?=E6=95=B0=E7=9A=84=E7=BF=BB=E9=A1=B5=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=9B=BA=E5=AE=9A=E9=A1=B5=E6=95=B0=E6=88=AA?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ReceiptFlowServiceImpl.java | 3 +- .../thirdparty/bfi/util/BfiUtil.java | 81 +++++++++++++++++++ ...¹A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md | 2 +- 3 files changed, 84 insertions(+), 2 deletions(-) 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 04f8803c..f7ced5f8 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 @@ -777,6 +777,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl queryRecBills() { @@ -792,7 +793,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl recBills = BfiUtil.queryAllPages(pageNo -> { + List recBills = BfiUtil.queryAllPagesByTotal(pageNo -> { queryDTO.setPageNo(pageNo); return bfiService.queryRecBill(queryDTO); }); diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/util/BfiUtil.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/util/BfiUtil.java index ed603bb2..6eb35686 100644 --- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/util/BfiUtil.java +++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/util/BfiUtil.java @@ -25,6 +25,7 @@ */ package org.springblade.thirdparty.bfi.util; +import lombok.extern.slf4j.Slf4j; import org.springblade.core.tool.utils.DateUtil; import org.springblade.core.tool.utils.Func; import org.springblade.thirdparty.bfi.pojo.dto.BfiBaseDTO; @@ -44,6 +45,7 @@ import java.util.function.IntFunction; * * @author Chill */ +@Slf4j public class BfiUtil { /** @@ -56,6 +58,11 @@ public class BfiUtil { */ public static final int DEFAULT_MAX_PAGES = 50; + /** + * 按 totalCount 推导总页数时的兜底最大页数,仅防金蝶侧返回异常导致死循环 + */ + public static final int DEFAULT_TOTAL_MAX_PAGES = 500; + private BfiUtil() { } @@ -139,4 +146,78 @@ public class BfiUtil { } return rows; } + + /** + * BFI 分页查询通用翻页:按首页返回的 totalCount 推导总页数,自动翻页汇总全量数据行 + *

+ * 与 {@link #queryAllPages(IntFunction)} 的区别:总页数由 totalCount 决定,固定页数仅作兜底, + * 适合业务日期窗口较长、数据量可能超过固定页数上限的查询场景;达到兜底上限或未取满 totalCount 时打印告警,避免静默截断 + * + * @param pageFetcher 页码 -> 分页结果,lambda 内负责设置页码(必要时含页大小)并调用接口 + * @param 数据行类型 + * @return 全量数据行 + */ + public static List queryAllPagesByTotal(IntFunction> pageFetcher) { + return queryAllPagesByTotal(pageFetcher, DEFAULT_TOTAL_MAX_PAGES); + } + + /** + * BFI 分页查询通用翻页:按首页返回的 totalCount 推导总页数,自动翻页汇总全量数据行 + *

+ * 终止条件:返回页为空、数据行为空、lastPage=true、数据行不满一页(按返回 pageSize 判断)、取满推导出的总页数 + *

+ * totalCount 缺失或非正数时退化为 {@link #queryAllPages(IntFunction, int)} 的固定页数上限逻辑 + * + * @param pageFetcher 页码 -> 分页结果,lambda 内负责设置页码(必要时含页大小)并调用接口 + * @param maxPages 兜底最大页数,防止金蝶侧 totalCount/lastPage 返回异常时死循环 + * @param 数据行类型 + * @return 全量数据行 + */ + public static List queryAllPagesByTotal(IntFunction> pageFetcher, int maxPages) { + List rows = new ArrayList<>(); + int totalPages = maxPages; + Integer totalCount = null; + for (int pageNo = 1; pageNo <= totalPages; pageNo++) { + BfiPageVO page = pageFetcher.apply(pageNo); + if (page == null || Func.isEmpty(page.getRows())) { + return rows; + } + rows.addAll(page.getRows()); + if (pageNo == 1) { + totalCount = page.getTotalCount(); + totalPages = resolveTotalPages(page, maxPages); + } + if (Boolean.TRUE.equals(page.getLastPage())) { + return rows; + } + if (page.getPageSize() != null && page.getRows().size() < page.getPageSize()) { + return rows; + } + } + if (totalCount != null && rows.size() < totalCount) { + log.warn("BFI分页查询未取满,totalCount={},已汇总 {} 条,可能存在数据截断", totalCount, rows.size()); + } + return rows; + } + + /** + * 按首页 totalCount 与 pageSize 推导总页数,超过兜底上限时按上限截断并告警 + * + * @param page 首页分页结果 + * @param maxPages 兜底最大页数 + * @return 总页数 + */ + private static int resolveTotalPages(BfiPageVO page, int maxPages) { + Integer totalCount = page.getTotalCount(); + Integer pageSize = page.getPageSize(); + if (totalCount == null || totalCount <= 0 || pageSize == null || pageSize <= 0) { + return maxPages; + } + int totalPages = (totalCount + pageSize - 1) / pageSize; + if (totalPages > maxPages) { + log.warn("BFI分页查询需要 {} 页(totalCount={}),超过兜底上限 {} 页,超出部分将被截断", totalPages, totalCount, maxPages); + return maxPages; + } + return totalPages; + } } diff --git a/doc/docs/业务流程/2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md b/doc/docs/业务流程/2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md index 2f5346ab..a4bf4b55 100644 --- a/doc/docs/业务流程/2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md +++ b/doc/docs/业务流程/2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md @@ -65,7 +65,7 @@ A301-1 收款单查询(业务日期窗口取 `thirdParty.bfi.recBillSync.days` ### 3.2 收款流水同步:A301-2 → A301-1 -`ReceiptFlowServiceImpl#sync()` 重写,`BfiUtil.queryAllPages` + `bfiService.queryRecBill` 全量翻页(pageSize 200),请求参数 `begin_bizdate` / `end_bizdate`(窗口天数取 Nacos `thirdParty.bfi.recBillSync.days`,默认 60)。 +`ReceiptFlowServiceImpl#sync()` 重写,`BfiUtil.queryAllPagesByTotal`(按 totalCount 推导总页数,兜底 500 页)+ `bfiService.queryRecBill` 全量翻页(pageSize 200),请求参数 `begin_bizdate` / `end_bizdate`(窗口天数取 Nacos `thirdParty.bfi.recBillSync.days`,默认 60)。 **字段映射(A301-1 → blade_kingdee_receipt_flow)**: