2026-08-15 12:33:29 +08:00
|
|
|
<script setup lang="ts">
|
2026-10-08 13:59:20 +08:00
|
|
|
import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
2026-08-15 12:33:29 +08:00
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
|
|
|
|
import AdminPage from '@/shared/components/AdminPage.vue'
|
|
|
|
|
import LoadingListDetailDrawer from '../components/LoadingListDetailDrawer.vue'
|
|
|
|
|
import {
|
|
|
|
|
getConfirmedLoadingList,
|
|
|
|
|
type ConfirmedSummary,
|
|
|
|
|
type LoadingDetail,
|
|
|
|
|
} from '../api/platformLoadingLists'
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const detail = ref<LoadingDetail<ConfirmedSummary> | null>(null)
|
|
|
|
|
const error = ref<ApiErrorDetails | null>(null)
|
2026-08-26 15:32:22 +08:00
|
|
|
let loadSequence = 0
|
2026-08-15 12:33:29 +08:00
|
|
|
const planId = computed(() => String(route.params.planId || ''))
|
|
|
|
|
const warehouseId = computed(() => typeof route.query.warehouseId === 'string' ? route.query.warehouseId : '')
|
|
|
|
|
|
|
|
|
|
async function loadDetail() {
|
2026-08-26 15:32:22 +08:00
|
|
|
const sequence = ++loadSequence
|
|
|
|
|
detail.value = null
|
2026-08-15 12:33:29 +08:00
|
|
|
if (!planId.value || !warehouseId.value) {
|
2026-08-26 15:32:22 +08:00
|
|
|
loading.value = false
|
2026-08-15 12:33:29 +08:00
|
|
|
error.value = { code: 'MISSING_WAREHOUSE_CONTEXT', message: '该清单缺少所属仓库信息,无法安全查询详情,请返回列表重新进入。' }
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
loading.value = true
|
|
|
|
|
error.value = null
|
|
|
|
|
try {
|
2026-08-28 16:54:02 +08:00
|
|
|
const result = await getConfirmedLoadingList(planId.value, warehouseId.value)
|
2026-08-26 15:32:22 +08:00
|
|
|
if (sequence !== loadSequence) return
|
2026-08-15 12:33:29 +08:00
|
|
|
if (result.summary.status !== 'COMPLETED') {
|
|
|
|
|
error.value = { code: 'MODE_STATUS_MISMATCH', message: '该计划尚未形成正式装柜清单,请从预装清单入口查看。' }
|
|
|
|
|
return
|
|
|
|
|
}
|
2026-08-28 16:54:02 +08:00
|
|
|
detail.value = result
|
2026-10-08 13:59:20 +08:00
|
|
|
loading.value = false
|
|
|
|
|
if (route.query.print === '1') {
|
|
|
|
|
await nextTick()
|
|
|
|
|
if (sequence !== loadSequence) return
|
|
|
|
|
window.print()
|
|
|
|
|
const { print: _print, ...query } = route.query
|
|
|
|
|
await router.replace({ name: 'loading-list-detail', params: { planId: planId.value }, query })
|
|
|
|
|
}
|
2026-08-15 12:33:29 +08:00
|
|
|
} catch (cause) {
|
2026-08-26 15:32:22 +08:00
|
|
|
if (sequence !== loadSequence) return
|
2026-08-15 12:33:29 +08:00
|
|
|
detail.value = null
|
|
|
|
|
error.value = getApiErrorDetails(cause, '装柜清单详情加载失败,请稍后重试')
|
|
|
|
|
} finally {
|
2026-08-26 15:32:22 +08:00
|
|
|
if (sequence === loadSequence) loading.value = false
|
2026-08-15 12:33:29 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function goBack() {
|
|
|
|
|
if (window.history.length > 1) router.back()
|
|
|
|
|
else void router.push({ name: 'loading-lists' })
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-08 13:59:20 +08:00
|
|
|
function printDetail() {
|
|
|
|
|
window.print()
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-15 12:33:29 +08:00
|
|
|
onMounted(() => void loadDetail())
|
2026-08-26 15:32:22 +08:00
|
|
|
watch([planId, warehouseId], () => void loadDetail())
|
2026-08-15 12:33:29 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<AdminPage>
|
|
|
|
|
<div class="confirmed-loading-detail-page">
|
2026-10-08 13:59:20 +08:00
|
|
|
<el-button v-if="detail" class="print-action" :disabled="loading" @click="printDetail">打印</el-button>
|
2026-08-15 12:33:29 +08:00
|
|
|
<LoadingListDetailDrawer
|
|
|
|
|
mode="confirmed"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
:detail="detail"
|
|
|
|
|
:error="error"
|
|
|
|
|
:can-edit="false"
|
2026-08-18 16:39:44 +08:00
|
|
|
@back="goBack"
|
2026-08-15 12:33:29 +08:00
|
|
|
@retry="loadDetail"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</AdminPage>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.confirmed-loading-detail-page { display: grid; min-width: 0; max-width: 1280px; gap: 16px; }
|
2026-10-08 13:59:20 +08:00
|
|
|
@media print { .print-action { display: none; } }
|
2026-08-17 19:13:25 +08:00
|
|
|
@media (min-width: 1920px) { .confirmed-loading-detail-page { width: 100%; max-width: none; gap: 12px; } }
|
2026-08-15 12:33:29 +08:00
|
|
|
</style>
|