diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/FormalSettlementServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/FormalSettlementServiceImpl.java index dc5d3b30..164f7ac2 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/FormalSettlementServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/FormalSettlementServiceImpl.java @@ -25,6 +25,7 @@ import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDTO; import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDataDTO; import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolItemVO; import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolVO; +import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO; import org.springblade.thirdparty.bfi.service.IBfiService; import org.springblade.transport.mapper.FormalSettlementDetailMapper; import org.springblade.transport.mapper.FormalSettlementDetailFeeMapper; @@ -1387,16 +1388,19 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl invoicePoolQuery(FormalSettlementInvoicePoolQueryDTO query) { long pageNo = Math.max(query.getCurrent() == null ? 1 : query.getCurrent(), 1); - long pageSize = Math.min(Math.max(query.getSize() == null ? 10 : query.getSize(), 1), 500); + // 上限 499:预留 1 条给 hasMore 探测,单次远程请求不超过 rim 契约 pageSize 上限 500 + long pageSize = Math.min(Math.max(query.getSize() == null ? 10 : query.getSize(), 1), 499); String invoiceNo = query.getInvoiceNo(); String invoiceDateStart = query.getInvoiceDateStart(); String invoiceDateEnd = query.getInvoiceDateEnd(); String salerTaxNo = query.getSalerTaxNo(); String buyerTaxNo = query.getBuyerTaxNo(); String expenseStatus = query.getExpenseStatus(); - // A801-1 不返回总数:单次按最大页大小全量翻页拉取后,在内存中做精确分页 + // A801-1 rim 契约不支持全量且不返回总数:透传 pageNo/pageSize 单页查询, + // 多取 1 条探测是否还有下一页,total 合成为当前已知的最小精确值供前端分页器翻页 BfiInvoicePoolQueryDataDTO data = new BfiInvoicePoolQueryDataDTO(); - data.setPageSize((int) pageSize); + data.setPageNo((int) pageNo); + data.setPageSize((int) pageSize + 1); if (StringUtil.isNotBlank(invoiceNo)) { data.setInvoiceNo(invoiceNo.trim()); } @@ -1417,20 +1421,19 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl poolInvoices = bfiService.queryInvoicePool(param); - List invoices = poolInvoices.stream() - .filter(poolInvoice -> !"1".equals(poolInvoice.getDelete())) + BfiPageVO poolPage = bfiService.queryInvoicePool(param); + List invoices = poolPage.getRows() == null ? List.of() + : poolPage.getRows().stream() .map(this::toInvoicePoolVO) .toList(); - log.info("正式结算单认领查询 全票池原始 {} 条,过滤作废后 {} 条,返回第 {} 页 {} 条/页", - poolInvoices.size(), invoices.size(), pageNo, pageSize); - // 内存精确分页:total 为过滤后精确总数,请求页超出范围时返回空records - int from = (int) ((pageNo - 1) * pageSize); - int to = (int) Math.min(from + pageSize, invoices.size()); - List records = from >= invoices.size() ? List.of() : invoices.subList(from, to); + // 多取的 1 条仅用于 hasMore 判断,不返回给前端 + boolean hasMore = invoices.size() > pageSize; + List records = hasMore ? invoices.subList(0, (int) pageSize) : invoices; + long total = hasMore ? pageNo * pageSize + 1 : (pageNo - 1) * pageSize + records.size(); + log.info("正式结算单认领查询 全票池第 {} 页 {} 条/页,返回 {} 条,hasMore:{}", pageNo, pageSize, records.size(), hasMore); Page page = new Page<>(pageNo, pageSize); page.setRecords(records); - page.setTotal(invoices.size()); + page.setTotal(total); return page; } 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 0aadab51..7b2ddf9f 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 @@ -278,12 +278,12 @@ public interface IBfiService { BfiBillSaveResultVO pushClaimResult(BfiClaimPushDTO param); /** - * A801-1 查询全票池发票数据(自动翻页汇总全量) + * A801-1 查询全票池发票数据(单页查询) * - * @param param 查询参数,messageType/messageId 由服务端填充;data.pageSize 必填,作为单页大小与翻页终止依据 - * @return 票池发票数据全量列表 + * @param param 查询参数,messageType/messageId 由服务端填充;queryParam.pageNo/pageSize 必填 + * @return 当前页票池发票数据,rim 契约不返回总数与末页标识 */ - List queryInvoicePool(BfiInvoicePoolQueryDTO param); + BfiPageVO queryInvoicePool(BfiInvoicePoolQueryDTO param); /** * A801-2 进项发票下载(文件下载) diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/impl/BfiServiceImpl.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/impl/BfiServiceImpl.java index 76f5b01b..69533637 100644 --- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/impl/BfiServiceImpl.java +++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/service/impl/BfiServiceImpl.java @@ -484,30 +484,28 @@ public class BfiServiceImpl implements IBfiService { } @Override - public List queryInvoicePool(BfiInvoicePoolQueryDTO param) { + public BfiPageVO queryInvoicePool(BfiInvoicePoolQueryDTO param) { if (param == null || param.getQueryParam() == null) { throw new BfiException("查询BFI全票池发票失败,查询参数不能为空"); } - param.setMessageType(BfiConstant.MESSAGE_TYPE_INVOICE_QUERY); - // A801-1 rim 契约仅返回当前页数据且无总数,统一通过通用翻页工具取全量,由调用方自行分页 BfiInvoicePoolQueryDataDTO data = param.getQueryParam(); + if (data.getPageNo() == null || data.getPageSize() == null) { + throw new BfiException("查询BFI全票池发票失败,pageNo与pageSize不能为空"); + } + param.setMessageType(BfiConstant.MESSAGE_TYPE_INVOICE_QUERY); + // rim 契约要求每次请求携带唯一 messageId + param.setMessageId(UUID.randomUUID().toString()); long start = System.currentTimeMillis(); - log.info("调用BFI接口 全票池发票查询开始 pageSize:{}", data.getPageSize()); - List invoices = BfiUtil.queryAllPages(pageNo -> { - // 翻页工具逐页注入页码;rim 契约要求每次请求携带唯一 messageId - data.setPageNo(pageNo); - param.setMessageId(UUID.randomUUID().toString()); - BfiResultVO> result = commonRimCall("全票池发票查询", - () -> client.invoicePoolQuery(getAccessToken(), param)); - List rows = result.getData() != null ? result.getData() : List.of(); - // rim 契约无 lastPage,包装为 BfiPageVO 借助"数据不满一页即末页"规则终止翻页 - BfiPageVO page = new BfiPageVO<>(); - page.setRows(rows); - page.setPageSize(data.getPageSize()); - return page; - }); - log.info("调用BFI接口 全票池发票查询结束 耗时:{}ms,全量 {} 条", System.currentTimeMillis() - start, invoices.size()); - return invoices; + log.info("调用BFI接口 全票池发票查询开始 pageNo:{},pageSize:{}", data.getPageNo(), data.getPageSize()); + BfiResultVO> result = commonRimCall("全票池发票查询", + () -> client.invoicePoolQuery(getAccessToken(), param)); + List rows = result.getData() != null ? result.getData() : List.of(); + BfiPageVO page = new BfiPageVO<>(); + page.setPageNo(data.getPageNo()); + page.setPageSize(data.getPageSize()); + page.setRows(rows); + log.info("调用BFI接口 全票池发票查询结束 耗时:{}ms,本页 {} 条", System.currentTimeMillis() - start, rows.size()); + return page; } @Override diff --git a/blade-third-party-api/blade-bfi-api/src/test/java/org/springblade/thirdparty/bfi/service/BfiServiceImplTest.java b/blade-third-party-api/blade-bfi-api/src/test/java/org/springblade/thirdparty/bfi/service/BfiServiceImplTest.java index 78a60659..0d03dcdc 100644 --- a/blade-third-party-api/blade-bfi-api/src/test/java/org/springblade/thirdparty/bfi/service/BfiServiceImplTest.java +++ b/blade-third-party-api/blade-bfi-api/src/test/java/org/springblade/thirdparty/bfi/service/BfiServiceImplTest.java @@ -520,6 +520,9 @@ class BfiServiceImplTest { @Test void queryInvoicePoolShouldValidateQueryParam() { assertThrows(BfiException.class, () -> service.queryInvoicePool(new BfiInvoicePoolQueryDTO())); + BfiInvoicePoolQueryDTO param = new BfiInvoicePoolQueryDTO(); + param.setQueryParam(new BfiInvoicePoolQueryDataDTO()); + assertThrows(BfiException.class, () -> service.queryInvoicePool(param)); verifyNoInteractions(client); } @@ -531,11 +534,14 @@ class BfiServiceImplTest { .thenReturn(success(List.of(invoice))); BfiInvoicePoolQueryDataDTO data = new BfiInvoicePoolQueryDataDTO(); data.setInvoiceNo("25532000000044538098"); + data.setPageNo(1); data.setPageSize(500); BfiInvoicePoolQueryDTO param = new BfiInvoicePoolQueryDTO(); param.setQueryParam(data); - List rows = service.queryInvoicePool(param); - assertEquals(1, rows.size()); + BfiPageVO page = service.queryInvoicePool(param); + assertEquals(1, page.getRows().size()); + assertEquals(1, page.getPageNo()); + assertEquals(500, page.getPageSize()); } @Test diff --git a/doc/docs/业务流程/2026-09-17-BFI分页查询通用翻页工具(BfiUtil-queryAllPages)技术文档.md b/doc/docs/业务流程/2026-09-17-BFI分页查询通用翻页工具(BfiUtil-queryAllPages)技术文档.md index 0a4a36e4..485b2e77 100644 --- a/doc/docs/业务流程/2026-09-17-BFI分页查询通用翻页工具(BfiUtil-queryAllPages)技术文档.md +++ b/doc/docs/业务流程/2026-09-17-BFI分页查询通用翻页工具(BfiUtil-queryAllPages)技术文档.md @@ -31,7 +31,7 @@ | A301-1 | 收款单查询 | `queryRecBill` | `BfiPageVO` | | A301-2 | 收款认领公告查询 | `queryClaimAnnounce` | `BfiPageVO` | -不适用:`queryInvoicePool`(A801-1,直接返回 List)、`queryExchangeRate`(A801-4,单页调用由 `BfiServiceImpl` 内部处理)。 +不适用:`queryInvoicePool`(A801-1,rim 契约限制不能全量查询,已改为 pageNo/pageSize 单页透传,由 `BfiServiceImpl` 直接单次调用)、`queryExchangeRate`(A801-4,单页调用由 `BfiServiceImpl` 内部处理)。 ## 3. API 定义 @@ -98,4 +98,4 @@ lambda 内通过闭包复用同一参数对象,仅需覆盖 `pageNo`;请求 | 内容 | 位置 | | --- | --- | | 工具类 | `blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/util/BfiUtil.java` | -| 当前唯一使用方 | `blade-service/blade-transport/.../service/impl/PaymentApplicationServiceImpl.java`(queryPayApplyPages / queryPayBillPages) | +| 使用方 | `blade-service/blade-transport/.../service/impl/PaymentApplicationServiceImpl.java`(付款结果回写)、`KingdeeApBillSyncSupport.java`(应付单同步)、`CustomerArchiveServiceImpl.java`(客户档案同步) |