diff --git a/src/modules/inbounds/components/InboundTaskList.test.ts b/src/modules/inbounds/components/InboundTaskList.test.ts index 647b3ca5..cc4b043d 100644 --- a/src/modules/inbounds/components/InboundTaskList.test.ts +++ b/src/modules/inbounds/components/InboundTaskList.test.ts @@ -108,6 +108,26 @@ describe('InboundTaskList measurement scope', () => { expect(source).not.toContain("name: 'inbound-order-detail', params: { inboundId: row.id }") }) + it('closes only after navigating an approved review to the measurement tab', () => { + const source = readFileSync(resolve('src/modules/inbounds/components/InboundTaskList.vue'), 'utf8') + const handler = source.slice(source.indexOf('async function handleTaskChanged'), source.indexOf('function handleReviewSelectionChange')) + + expect(handler).toContain("name: 'unified-order-detail-by-inbound-code'") + expect(handler).toContain('params: { inboundCode }') + expect(handler).toContain("query: { tab: 'measurement', from: 'measurement-review' }") + expect(handler).toContain('await router.push') + expect(handler.indexOf('await router.push')).toBeLessThan(handler.lastIndexOf('reviewDialogOpen.value = false')) + expect(handler).toContain("getApiErrorDetails(error, '订单详情打开失败,请重试')") + expect(handler).toContain("name: 'unified-order-detail'") + expect(handler).toContain("query: { tenantId: target.tenantId, tab: 'measurement', from: 'measurement-review' }") + expect(source).toContain(':post-approve-loading="reviewNavigationLoading"') + expect(source).toContain(':approval-completed="reviewApproved"') + expect(source).toContain(':close-on-click-modal="!reviewNavigationLoading"') + expect(source).toContain('reviewNavigationError') + expect(source).toContain('重新打开订单详情') + expect(source).not.toContain('params: { inboundId: target.id }') + }) + it('shows authoritative measurement totals with operation first and no internal IDs as primary columns', () => { const source = readFileSync(resolve('src/modules/inbounds/components/InboundTaskList.vue'), 'utf8') const columnsSource = source.slice(source.indexOf('const columns'), source.indexOf('function text')) diff --git a/src/modules/inbounds/components/InboundTaskList.vue b/src/modules/inbounds/components/InboundTaskList.vue index 0c5dfc0f..4d71147f 100644 --- a/src/modules/inbounds/components/InboundTaskList.vue +++ b/src/modules/inbounds/components/InboundTaskList.vue @@ -45,6 +45,9 @@ const warehouseOptions = ref>([]) const selectedInbound = ref(null) const measurementDialogOpen = ref(false) const reviewDialogOpen = ref(false) +const reviewNavigationLoading = ref(false) +const reviewApproved = ref(false) +const reviewNavigationError = ref(null) const relationshipDialogOpen = ref(false) const relationshipDialogInboundCode = ref('') const batchReviewLoading = ref(false) @@ -184,7 +187,11 @@ function resetFilters() { function openTask(row: InboundOrderSummary) { selectedInbound.value = row - if (isReview.value) reviewDialogOpen.value = true + if (isReview.value) { + reviewApproved.value = false + reviewNavigationError.value = null + reviewDialogOpen.value = true + } else measurementDialogOpen.value = true } @@ -200,10 +207,47 @@ function openRelationship(row: InboundOrderSummary) { relationshipDialogOpen.value = true } -function handleTaskChanged() { - reviewDialogOpen.value = false - selectedInbound.value = null - void loadTasks() +async function handleTaskChanged() { + const target = selectedInbound.value + if (!isReview.value) { + reviewDialogOpen.value = false + selectedInbound.value = null + void loadTasks() + return + } + if (!target || reviewNavigationLoading.value) return + reviewApproved.value = true + reviewNavigationError.value = null + + const inboundCode = target.inboundCode?.trim() + const orderId = target.orderId?.trim() + if (!inboundCode && !orderId) { + reviewNavigationError.value = { message: '审核已通过,但未找到对应订单,请关闭弹框后刷新列表重试' } + return + } + + reviewNavigationLoading.value = true + try { + if (inboundCode) { + await router.push({ + name: 'unified-order-detail-by-inbound-code', + params: { inboundCode }, + query: { tab: 'measurement', from: 'measurement-review' }, + }) + } else { + await router.push({ + name: 'unified-order-detail', + params: { orderId }, + query: { tenantId: target.tenantId, tab: 'measurement', from: 'measurement-review' }, + }) + } + reviewDialogOpen.value = false + selectedInbound.value = null + } catch (error) { + reviewNavigationError.value = getApiErrorDetails(error, '订单详情打开失败,请重试') + } finally { + reviewNavigationLoading.value = false + } } function handleReviewSelectionChange(rows: InboundOrderSummary[]) { @@ -266,6 +310,9 @@ function handleMeasurementSubmitted() { function clearSelectedInbound() { selectedInbound.value = null + reviewApproved.value = false + reviewNavigationError.value = null + reviewNavigationLoading.value = false } watch([page, pageSize], () => { void loadTasks() }) @@ -367,9 +414,16 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria top="4vh" destroy-on-close append-to-body + :close-on-click-modal="!reviewNavigationLoading" + :close-on-press-escape="!reviewNavigationLoading" class="inbound-task-dialog" @closed="clearSelectedInbound" > + + + + 重新打开订单详情 + { disposed = true; requestSerial += 1; optionsRequestSeria :customer-name="selectedInbound.customerName || selectedInbound.companyName" :channel-name="selectedInbound.channelName" :channel-code="selectedInbound.channelCode" + :post-approve-loading="reviewNavigationLoading" + :approval-completed="reviewApproved" @changed="handleTaskChanged" /> @@ -398,6 +454,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria