fix(appointments): ignore stale impact history responses

This commit is contained in:
2026-10-11 21:09:30 +08:00
parent 43611ecc55
commit 20b4d1425b
2 changed files with 53 additions and 6 deletions
@@ -12,14 +12,16 @@ const router = useRouter(), detail = ref<ImpactDetail | null>(null), loading = r
const error = ref<ApiErrorDetails | null>(null), pending = ref<ImpactCommand | null>(null)
const form = reactive({ result: '', nextAction: '', followupDate: '' })
const actions: Record<string, string> = { OBSERVED: '船期核对', CLAIM: '认领', RECORD: '记录处理', RESOLVE: '完成核对' }
let loadGeneration = 0
async function load() {
const generation = ++loadGeneration
loading.value = true; error.value = null
try { detail.value = await getImpact(props.containerId, historyPage.value) }
catch (cause) { error.value = getApiErrorDetails(cause, '影响详情加载失败') }
finally { loading.value = false }
try { const result = await getImpact(props.containerId, historyPage.value); if (generation === loadGeneration) detail.value = result }
catch (cause) { if (generation === loadGeneration) error.value = getApiErrorDetails(cause, '影响详情加载失败') }
finally { if (generation === loadGeneration) loading.value = false }
}
async function save(action: ImpactCommand['action']) {
if (!detail.value || saving.value || !props.canWrite) return
if (!detail.value || loading.value || saving.value || !props.canWrite) return
if (!pending.value && action !== 'CLAIM' && !form.result.trim()) { ElMessage.warning('请填写实际处理结果'); return }
pending.value ||= { expectedVersion: detail.value.impact.version, forecastToken: detail.value.impact.forecastToken, idempotencyKey: crypto.randomUUID(), action, result: form.result.trim() || null, nextAction: form.nextAction.trim() || null, followupDate: form.followupDate || null }
saving.value = true; error.value = null
@@ -33,7 +35,7 @@ function beforeClose(done: () => void) { if (canLeave()) done() }
function openTrip(tripNo: string) { if (canLeave()) void router.push(`/overseas-master-data/trips/${encodeURIComponent(tripNo)}`) }
const register = inject<((guard: () => boolean) => () => void) | undefined>('appointment-register-leave-guard', undefined)
const unregister = register?.(canLeave)
onBeforeUnmount(() => unregister?.())
onBeforeUnmount(() => { ++loadGeneration; unregister?.() })
onBeforeRouteLeave(canLeave)
onBeforeRouteUpdate(canLeave)
onMounted(load)
@@ -65,7 +67,7 @@ onMounted(load)
<el-button v-if="!pending" type="primary" :disabled="saving || loading" @click="save('RESOLVE')">完成本次核对</el-button>
<el-button v-else type="primary" :loading="saving" @click="save(pending.action)">重试本次处理</el-button>
</div>
<details><summary>观察及处理历史({{ detail.history.total }} 条)</summary><div class="impact-list"><p v-for="row in detail.history.records" :key="row.version">{{ actions[row.action] || '核对记录' }} · {{ row.operatorName || '—' }} · {{ row.createdAt }} UTC<br>{{ row.result || '记录来源观察' }} · {{ row.nextAction || '—' }} · {{ row.followupDate || '—' }}</p></div><el-pagination v-model:current-page="historyPage" :page-size="20" :total="detail.history.total" layout="prev, pager, next" :disabled="saving || !!pending" @current-change="load" /></details>
<details><summary>观察及处理历史({{ detail.history.total }} 条)</summary><div class="impact-list"><p v-for="row in detail.history.records" :key="row.version">{{ actions[row.action] || '核对记录' }} · {{ row.operatorName || '—' }} · {{ row.createdAt }} UTC<br>{{ row.result || '记录来源观察' }} · {{ row.nextAction || '—' }} · {{ row.followupDate || '—' }}</p></div><el-pagination v-model:current-page="historyPage" :page-size="20" :total="detail.history.total" layout="prev, pager, next" :disabled="loading || saving || !!pending" @current-change="load" /></details>
</template>
</AppDialog>
</template>