Fix dispatch review action refresh and definite rejection recovery

This commit is contained in:
2026-10-20 11:36:15 +08:00
parent f4224e5d3a
commit a0d8666d9f
10 changed files with 349 additions and 24 deletions
@@ -21,6 +21,7 @@ import { overseasWarehousePermissions as permission } from '../permissions'
const route = useRoute(), router = useRouter(), access = useAccessPreviewStore()
const dispatchNo = computed(() => String(route.params.dispatchNo || ''))
const detail = ref<DispatchDetail | null>(null), activeTab = ref('vehicle'), loading = ref(false), loadError = ref<ApiErrorDetails | null>(null)
const rejectionError = ref<ApiErrorDetails | null>(null)
const operation = ref<'ROUTE' | undefined>()
const action = ref<DispatchAction>('EDIT'), actionOpen = ref(false)
const detailActions: DispatchAction[] = ['EDIT', 'ADD_CARGO', 'REMOVE_CARGO', 'SUBMIT_REVIEW', 'DISPATCH_REVIEW', 'LOADING_REVIEW', 'RETURN_TO_REVIEW', 'LOADING_COMPLETE', 'ARRANGE_DELIVERY', 'DEPART', 'CANCEL']
@@ -65,13 +66,16 @@ async function load() {
finally { if (current === generation) loading.value = false }
}
function back() { void router.push(inquiryReturnTarget(route.query) || { name: 'overseas-dispatches' }) }
function openAction(value: DispatchAction, requestedOperation?: 'ROUTE') { if (!canDispatchAction(detail.value?.actions, value, access.can)) return; operation.value = requestedOperation; action.value = value; actionOpen.value = true }
function openAction(value: DispatchAction, requestedOperation?: 'ROUTE') { if (!canDispatchAction(detail.value?.actions, value, access.can)) return; rejectionError.value = null; operation.value = requestedOperation; action.value = value; actionOpen.value = true }
async function handleRejection(details: ApiErrorDetails) { rejectionError.value = details; await load() }
async function handleSaved() { rejectionError.value = null; await load() }
watch(dispatchNo, load, { immediate: true })
onBeforeUnmount(() => { generation++ })
</script>
<template>
<OverseasDetailShell class="admin-density" dense title="排车详情" reference-label="排车单号" :reference-value="detail?.dispatchNo || dispatchNo" :back-text="inquiryReturnTarget(route.query) ? '返回原拼车登记' : undefined" :back-label="inquiryReturnTarget(route.query) ? '返回原拼车登记' : '返回排车列表'" domain="排车详情" :pending="false" :status-text="detail ? detail.status === 'CANCELLED' ? '已取消' : stageLabel(detail.stage) : '加载中'" @back="back">
<LoadErrorState v-if="rejectionError" title="排车操作未完成" :message="rejectionError.message" :show-retry="false"><template #details><ApiErrorMeta :details="rejectionError" /></template></LoadErrorState>
<LoadErrorState v-if="loadError" title="排车详情加载失败" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState>
<div v-else v-loading="loading" class="dispatch-detail" :aria-busy="loading">
<section v-if="detail" class="detail-section" aria-label="排车操作"><div class="density-actions"><el-button v-for="value in visibleActions" :key="value" class="density-action" @click="openAction(value)">{{ dispatchActionLabels[value] }}</el-button><el-button v-if="canDispatchAction(detail?.actions, 'EDIT', access.can)" @click="openAction('EDIT', 'ROUTE')">调整卸货顺序</el-button></div></section>
@@ -85,7 +89,7 @@ onBeforeUnmount(() => { generation++ })
<el-tab-pane name="orders"><template #label><span class="density-tab-icon" aria-hidden="true">📦</span><span>关联订单明细</span></template><DataTable :data="relatedOrders" :columns="orderColumns" column-settings-mode="hide" row-key="sourceKey" empty-text="暂无关联订单明细" /></el-tab-pane>
</el-tabs>
</div>
<DispatchWorkflowDialog v-model="actionOpen" :dispatch-no="dispatchNo" :action="action" :operation="operation" @saved="load" />
<DispatchWorkflowDialog v-model="actionOpen" :dispatch-no="dispatchNo" :action="action" :operation="operation" @saved="handleSaved" @rejected="handleRejection" />
</OverseasDetailShell>
</template>