diff --git a/src/modules/first-leg/api/unifiedOrders.test.mjs b/src/modules/first-leg/api/unifiedOrders.test.mjs index 9e1ee43..2863941 100644 --- a/src/modules/first-leg/api/unifiedOrders.test.mjs +++ b/src/modules/first-leg/api/unifiedOrders.test.mjs @@ -1,9 +1,28 @@ import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' +import ts from 'typescript' const source = readFileSync(new URL('./unifiedOrders.ts', import.meta.url), 'utf8') +test('forwards optional tax mode and pagination through the current GET endpoint', async () => { + const calls = [] + const code = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText + const api = {} + new Function('require', 'exports', code)(id => { + assert.equal(id, '@/api/http') + return { apiRequest: async config => { calls.push(config); return { records: [] } } } + }, api) + await api.getMerchantUnifiedOrders({ page: 2, size: 200, taxMode: 'TAX_REFUND' }) + await api.getMerchantUnifiedOrders({ taxMode: 'BUY_DECLARATION' }) + await api.getMerchantUnifiedOrders() + assert.deepEqual(calls, [ + { method: 'GET', url: '/merchant/v1/orders', params: { page: 2, size: 200, taxMode: 'TAX_REFUND' } }, + { method: 'GET', url: '/merchant/v1/orders', params: { page: 1, size: 200, taxMode: 'BUY_DECLARATION' } }, + { method: 'GET', url: '/merchant/v1/orders', params: { page: 1, size: 200 } }, + ]) +}) + test('keeps the merchant unified-order boundary and one-click palletization status', () => { assert.match(source, /const unifiedOrderBaseUrl = '\/merchant\/v1\/orders'/) assert.match(source, /ApiUnifiedOrderMainStatus[\s\S]*?'WAIT_PALLETIZE'/) diff --git a/src/modules/first-leg/api/unifiedOrders.ts b/src/modules/first-leg/api/unifiedOrders.ts index 07464d0..a49ead1 100644 --- a/src/modules/first-leg/api/unifiedOrders.ts +++ b/src/modules/first-leg/api/unifiedOrders.ts @@ -141,6 +141,7 @@ export interface MerchantUnifiedOrderDetail { } export interface MerchantUnifiedOrderQuery { + taxMode?: ApiTaxMode keyword?: string fbaCode?: string orderNo?: string diff --git a/src/modules/first-leg/utils/customsDocumentsReader.ts b/src/modules/first-leg/utils/customsDocumentsReader.ts index 8e77b83..13bd447 100644 --- a/src/modules/first-leg/utils/customsDocumentsReader.ts +++ b/src/modules/first-leg/utils/customsDocumentsReader.ts @@ -16,7 +16,7 @@ export async function readCustomsDocuments() { let failedCount = 0 const size = 200 for (let page = 1; ; page += 1) { - const response = await getMerchantUnifiedOrders({ page, size }) + const response = await getMerchantUnifiedOrders({ page, size, taxMode: 'TAX_REFUND' }) const total = Number(response.total) const pages = Number(response.pages) if (!Number.isSafeInteger(total) || total < 0 || Number(response.page) !== page diff --git a/src/modules/first-leg/views/CustomsDocumentsView.test.mjs b/src/modules/first-leg/views/CustomsDocumentsView.test.mjs index 4f62422..2e9c295 100644 --- a/src/modules/first-leg/views/CustomsDocumentsView.test.mjs +++ b/src/modules/first-leg/views/CustomsDocumentsView.test.mjs @@ -18,14 +18,22 @@ const order = (id, status = 'LOADED', taxMode = 'TAX_REFUND') => ({ id, status, const detail = id => ({ status: 'COMPLETED', merchantStatus: 'CUSTOMS_COMPLETED', inbounds: [{ orderId: id, taxMode: 'TAX_REFUND' }] }) function harness(t, orders, getDetail = async id => detail(id)) { const store = { loadError: '', failPage: 0, transformPage: value => value }, calls = [], pageCalls = [] + const unifiedApi = evaluate(readFileSync(new URL('../api/unifiedOrders.ts', import.meta.url), 'utf8'), { + '@/api/http': { apiRequest: async ({ method, url, params: { page, size, taxMode } }) => { + assert.equal(method, 'GET') + assert.equal(url, '/merchant/v1/orders') + pageCalls.push({ page, size, taxMode }) + if (store.loadError || store.failPage === page) throw new Error(store.loadError || '第二页订单查询失败') + // Model server filtering BEFORE pagination and COUNT, using the actual + // request produced by the production API. Missing taxMode scans all rows. + const filtered = taxMode ? orders.filter(row => row.taxMode === taxMode) : orders + return store.transformPage({ page, size, total: filtered.length, pages: Math.ceil(filtered.length / size), + records: filtered.slice((page - 1) * size, page * size).map(row => ({ orderId: row.id, orderNo: row.orderNo, mainStatus: row.status, taxMode: row.taxMode, inboundCode: row.businessSummary.inboundCode })) }) + } }, + }) const reader = evaluate(readFileSync(new URL('../utils/customsDocumentsReader.ts', import.meta.url), 'utf8'), { './customsEligibility': eligibility, - '../api/unifiedOrders': { getMerchantUnifiedOrders: async ({ page, size }) => { - pageCalls.push({ page, size }) - if (store.loadError || store.failPage === page) throw new Error(store.loadError || '第二页订单查询失败') - return store.transformPage({ page, size, total: orders.length, pages: Math.ceil(orders.length / size), - records: orders.slice((page - 1) * size, page * size).map(row => ({ orderId: row.id, orderNo: row.orderNo, mainStatus: row.status, taxMode: row.taxMode, inboundCode: row.businessSummary.inboundCode })) }) - } }, + '../api/unifiedOrders': unifiedApi, '../api/customs': { getMerchantCustomsForOrder: id => { calls.push(id); return getDetail(id) }, isMerchantCustomsUnavailable: error => error?.code === 'A0404' }, }) const source = readFileSync(new URL('./CustomsDocumentsView.vue', import.meta.url), 'utf8').match(/