diff --git a/src/modules/first-leg/api/firstLeg.ts b/src/modules/first-leg/api/firstLeg.ts index dc0eab0..fd7885e 100644 --- a/src/modules/first-leg/api/firstLeg.ts +++ b/src/modules/first-leg/api/firstLeg.ts @@ -574,10 +574,11 @@ export function cancelMerchantFirstLegOrder(id: number | string, payload: { expe return apiRequest({ method: 'POST', url: `/merchant/v1/orders/first-leg/${id}/cancel`, data: payload, headers: { 'Idempotency-Key': idempotencyKey } }) } -export function submitMerchantFirstLegOrder(id: number | string, idempotencyKey: string) { +export function submitMerchantFirstLegOrder(id: number | string, payload: { expectedVersion: number }, idempotencyKey: string) { return apiRequest({ method: 'POST', url: `/merchant/v1/orders/first-leg/${id}/submit`, + data: payload, headers: { 'Idempotency-Key': idempotencyKey }, }) } diff --git a/src/modules/first-leg/store/firstLegDraftCommands.test.mjs b/src/modules/first-leg/store/firstLegDraftCommands.test.mjs index 3590799..9c7e901 100644 --- a/src/modules/first-leg/store/firstLegDraftCommands.test.mjs +++ b/src/modules/first-leg/store/firstLegDraftCommands.test.mjs @@ -23,7 +23,9 @@ function harness(t) { if (behavior.failRead) throw new Error('读取失败') return { order: { id: 'one', orderNo: 'FL-ONE', version: behavior.version, status: behavior.status, receivingWarehouseId: 'warehouse', destinationCountryCode: 'US' }, cargoes: [] } } - if (behavior.failWrite) throw new Error('响应丢失') + if (behavior.failWrite || (behavior.failSubmit && config.url.endsWith('/submit'))) throw new Error('响应丢失') + if (config.url.endsWith('/submit') && behavior.failSubmitRead) behavior.failRead = true + if (config.method === 'POST' && config.url === '/merchant/v1/orders/first-leg') return 'one' } } }) const module = compile('./firstLegOrders.ts', { vue, pinia, @@ -53,6 +55,23 @@ test('raw and unified cancelled detail remain CANCELLED even when unified mainSt assert.notEqual(unknown.status, 'CANCELLED', 'unknown summary must not be reclassified as cancellation') }) +test('fresh direct draft detail preserves raw DRAFT with null unified summary and opens an edit session', async t => { + const h = harness(t) + assert.equal(h.store.orders.length, 0) + const direct = await h.store.loadDetail('one') + assert.equal(direct.status, 'DRAFT') + assert.equal(h.store.beginDraftEdit(direct).expectedVersion, 9) + h.store.orders = [] + const refreshed = await h.store.loadDetail('one') + assert.equal(refreshed.status, 'DRAFT') + h.store.orders = [] + h.behavior.status = 'APPROVED' + const unknown = await h.store.loadDetail('one') + assert.notEqual(unknown.status, 'DRAFT') + assert.notEqual(unknown.status, 'CANCELLED') + assert.throws(() => h.store.beginDraftEdit(unknown), /重新打开/) +}) + test('cancelled detail summary has no pending overseas synchronization entries', () => { const source = readFileSync(new URL('../views/FirstLegOrdersView.vue', import.meta.url), 'utf8') const script = source.match(/