From 639b1ae22cea984f417808df79f61d5acbff2ce1 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Fri, 9 Oct 2026 17:53:42 +0800 Subject: [PATCH] fix(client): preserve order category counts while refreshing --- src/modules/first-leg/store/firstLegOrders.ts | 5 ++- .../store/firstLegWorkbench.test.mjs | 37 +++++++++++++++++++ .../first-leg/views/FirstLegOrdersView.vue | 1 + .../FirstLegWorkbenchPagination.test.mjs | 10 +++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/modules/first-leg/store/firstLegOrders.ts b/src/modules/first-leg/store/firstLegOrders.ts index bce11ef..ef3d09d 100644 --- a/src/modules/first-leg/store/firstLegOrders.ts +++ b/src/modules/first-leg/store/firstLegOrders.ts @@ -454,7 +454,7 @@ export const useFirstLegOrdersStore = defineStore('client-first-leg-orders', () loadError.value = '' orders.value = [] total.value = 0 - queueCounts.value = { all: 0, fee: 0, customs: 0, draft: 0, loaded: 0, declared: 0, cleared: 0, scheduled: 0, delivering: 0, delivered: 0 } + // Keep the last confirmed category counts while refreshing; replace them only after validation. orderProgress.value = {} const [orderResult, warehouseResult] = await Promise.allSettled([ getMerchantOrderWorkbench(query), loadWarehouseType('DOMESTIC'), @@ -487,6 +487,9 @@ export const useFirstLegOrdersStore = defineStore('client-first-leg-orders', () } } catch { loadError.value = '订单分页数据不完整,请重新加载' } } else loadError.value = orderResult.reason instanceof Error ? orderResult.reason.message : '订单数据加载失败' + if (loadError.value) { + queueCounts.value = { all: 0, fee: 0, customs: 0, draft: 0, loaded: 0, declared: 0, cleared: 0, scheduled: 0, delivering: 0, delivered: 0 } + } loading.value = false return orders.value.length } diff --git a/src/modules/first-leg/store/firstLegWorkbench.test.mjs b/src/modules/first-leg/store/firstLegWorkbench.test.mjs index 4d0986f..3a7ecc0 100644 --- a/src/modules/first-leg/store/firstLegWorkbench.test.mjs +++ b/src/modules/first-leg/store/firstLegWorkbench.test.mjs @@ -131,3 +131,40 @@ test('retains server progress and rejects missing or foreign progress without in response = result(); delete response.queues.cleared await h.store.load(); assert.match(h.store.loadError, /分页数据不完整/) }) + + +test('category counts remain visible throughout refresh and update together after the response is validated', async t => { + const pending = deferred() + let refreshing = false + const h = harness(t, () => refreshing ? pending.promise : result()) + await h.store.load() + const counts = h.store.queueCounts + refreshing = true + const request = h.store.load({ queue: 'fee' }) + assert.equal(h.store.loading, true) + assert.equal(h.store.queueCounts, counts) + assert.equal(h.store.queueCounts.fee, 2) + const updated = result(1, 10, 3) + updated.queues = { ...updated.queues, all: 216, fee: 3 } + pending.resolve(updated) + await request + assert.equal(h.store.queueCounts.all, 216) + assert.equal(h.store.queueCounts.fee, 3) + assert.equal(h.store.loading, false) +}) + +test('rapid category switches preserve counts and ignore an older response while the newest request is pending', async t => { + const older = deferred(), latest = deferred() + const h = harness(t, q => q.queue === 'fee' ? older.promise : q.queue === 'customs' ? latest.promise : result()) + await h.store.load() + const oldRequest = h.store.load({ queue: 'fee' }) + const newRequest = h.store.load({ queue: 'customs' }) + const oldResult = result(1, 10, 2); oldResult.queues.all = 999 + older.resolve(oldResult); await oldRequest + assert.equal(h.store.queueCounts.all, 215) + assert.equal(h.store.loading, true) + const newResult = result(1, 10, 1); newResult.queues.all = 216 + latest.resolve(newResult); await newRequest + assert.equal(h.store.queueCounts.all, 216) + assert.equal(h.store.total, 1) +}) diff --git a/src/modules/first-leg/views/FirstLegOrdersView.vue b/src/modules/first-leg/views/FirstLegOrdersView.vue index a868dc1..f56abf9 100644 --- a/src/modules/first-leg/views/FirstLegOrdersView.vue +++ b/src/modules/first-leg/views/FirstLegOrdersView.vue @@ -507,6 +507,7 @@ const orderQueueCounts = computed(() => store.queueCounts) const pagedOrders = computed(() => store.orders) async function selectOrderQueue(queue: OrderQueue) { + if (activeOrderQueue.value === queue && !store.loadError) return activeOrderQueue.value = queue tablePage.value = 1 await loadOrderPage() diff --git a/src/modules/first-leg/views/FirstLegWorkbenchPagination.test.mjs b/src/modules/first-leg/views/FirstLegWorkbenchPagination.test.mjs index dbeb38d..a0b780a 100644 --- a/src/modules/first-leg/views/FirstLegWorkbenchPagination.test.mjs +++ b/src/modules/first-leg/views/FirstLegWorkbenchPagination.test.mjs @@ -49,3 +49,13 @@ test('old same-page response cannot clamp a newer query or clear its current sel assert.deepEqual(h.selectedOrders.value, ['new-selection']) assert.equal(h.orderTableVersion.value, 1) }) + + +test('clicking the current category does not reload or reset its page, but an error can be retried', async () => { + const h = harness(); h.tablePage.value = 3 + await h.selectOrderQueue('all') + assert.equal(h.calls.length, 0); assert.equal(h.tablePage.value, 3) + h.store.loadError = 'failed' + await h.selectOrderQueue('all') + assert.equal(h.calls.length, 1); assert.equal(h.tablePage.value, 1) +})