import { getMerchantUnifiedOrders } from '../api/unifiedOrders' import { getMerchantCustomsForOrder, isMerchantCustomsUnavailable, type MerchantCustomsContainer } from '../api/customs' import { isCustomsOrderCandidate } from './customsEligibility' export interface CustomsDocumentRow { order: { id: string; orderNo: string | null; businessSummary: { inboundCode: string } } detail: MerchantCustomsContainer } // Isolated from the shared order store: scan sequential pages, with at most // four document requests in flight. Inconsistent pagination must be visible. export async function readCustomsDocuments() { const records: CustomsDocumentRow[] = [] const seen = new Set() let expectedTotal: number | undefined let failedCount = 0 const size = 200 for (let page = 1; ; page += 1) { const response = await getMerchantUnifiedOrders({ page, size, taxMode: 'TAX_REFUND', loaded: true }) const total = Number(response.total) const pages = Number(response.pages) if (!Number.isSafeInteger(total) || total < 0 || Number(response.page) !== page || Number(response.size) !== size || pages !== Math.ceil(total / size) || (expectedTotal !== undefined && total !== expectedTotal) || response.records.length !== Math.min(size, Math.max(0, total - (page - 1) * size))) { throw new Error('订单分页数据不完整或已变化,请重新加载报关资料') } expectedTotal = total for (const row of response.records) { const id = String(row.orderId) if (seen.has(id)) throw new Error('订单分页存在重复记录,请重新加载报关资料') seen.add(id) } const candidates = response.records.filter(row => isCustomsOrderCandidate({ status: row.mainStatus, taxMode: row.taxMode ?? 'BUY_DECLARATION' })) for (let offset = 0; offset < candidates.length; offset += 4) { const results = await Promise.all(candidates.slice(offset, offset + 4).map(async row => { const id = String(row.orderId) try { const detail = await getMerchantCustomsForOrder(id) if (!detail.inbounds.some(item => item.orderId === id && item.taxMode === 'TAX_REFUND')) return null return { order: { id, orderNo: row.orderNo, businessSummary: { inboundCode: row.inboundCode ?? '' } }, detail } } catch (error) { if (!isMerchantCustomsUnavailable(error)) failedCount += 1 return null } })) for (const result of results) if (result) records.push(result) } if (page >= pages) break } return { records, failedCount } }