39 lines
4.1 KiB
Vue
39 lines
4.1 KiB
Vue
<script setup lang="ts">
|
||
import { onBeforeUnmount, ref, watch } from 'vue'
|
||
import { getTransferPickupProgress, downloadTransferPickupEvidence, type PickupProgress } from '../api/transferPickups'
|
||
|
||
const props = defineProps<{ transferNo: string }>()
|
||
const progress = ref<PickupProgress | null>(null), error = ref(''), loading = ref(false)
|
||
const labels: Record<string, string> = { PENDING_REVIEW: '待审核', WAITING: '待安排取货', ASSIGNED: '已安排取货', PICKED: '已取货', ARRIVED: '已送仓' }
|
||
const time = (value: string | null) => value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '—'
|
||
let sequence = 0
|
||
/** 业务号变化后忽略旧响应,客户之间不复用取货数据。 */
|
||
async function load() {
|
||
const current = ++sequence; progress.value = null; error.value = ''; loading.value = true
|
||
try { const value = await getTransferPickupProgress(props.transferNo); if (current === sequence) progress.value = value }
|
||
catch (cause) { if (current === sequence) error.value = cause instanceof Error ? cause.message : '取货进度加载失败' }
|
||
finally { if (current === sequence) loading.value = false }
|
||
}
|
||
/** 凭证读取必须经过原单鉴权。 */
|
||
async function download(file: { fileId: string; fileName: string }) {
|
||
try { const blob = await downloadTransferPickupEvidence(props.transferNo, file.fileId); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = file.fileName; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000) }
|
||
catch (cause) { error.value = cause instanceof Error ? cause.message : '取货凭证下载失败' }
|
||
}
|
||
watch(() => props.transferNo, load, { immediate: true }); onBeforeUnmount(() => { sequence++ })
|
||
</script>
|
||
<template>
|
||
<section v-if="loading || progress || error" v-loading="loading" class="pickup-progress" aria-label="取货安排">
|
||
<div class="pickup-heading"><h3>取货安排</h3><el-button size="small" :disabled="loading" @click="load">刷新进度</el-button></div>
|
||
<el-alert v-if="error" :title="error" type="error" :closable="false" />
|
||
<dl v-if="progress" class="pickup-fields">
|
||
<div><dt>取货进度</dt><dd>{{ labels[progress.status] || progress.status }}</dd></div><div><dt>车次号</dt><dd>{{ progress.tripNo || '待安排' }}</dd></div>
|
||
<div><dt>车牌</dt><dd>{{ progress.vehiclePlate || '待分配' }}</dd></div><div><dt>司机</dt><dd>{{ progress.driverName || '待分配' }}</dd></div>
|
||
<div><dt>司机电话</dt><dd>{{ progress.driverPhone || '—' }}</dd></div><div><dt>计划取货发车</dt><dd>{{ time(progress.plannedDepartureAt) }}</dd></div>
|
||
<div><dt>实际取货数量(箱)</dt><dd>{{ progress.actualPackages ?? '待取货' }}</dd></div><div><dt>取货时间</dt><dd>{{ time(progress.pickedAt) }}</dd></div>
|
||
<div><dt>送仓时间</dt><dd>{{ time(progress.arrivedAt) }}</dd></div><div v-if="progress.remark"><dt>取货备注</dt><dd>{{ progress.remark }}</dd></div>
|
||
</dl>
|
||
<div v-if="progress?.evidence.length" class="pickup-files"><span>取货凭证</span><el-button v-for="file in progress.evidence" :key="file.fileId" link type="primary" @click="download(file)">{{ file.fileName }}</el-button></div>
|
||
</section>
|
||
</template>
|
||
<style scoped>.pickup-progress{padding:0 16px 10px;border:1px solid var(--border,#e5e7eb);border-radius:6px;margin:16px 0}.pickup-heading{display:flex;min-height:40px;justify-content:space-between;align-items:center}.pickup-heading h3{margin:0;font-size:14px}.pickup-fields{display:grid;max-width:1408px;grid-template-columns:repeat(4,minmax(0,1fr));gap:4px 18px;margin:8px 0 0}.pickup-fields>div{display:flex;min-height:24px;align-items:center;gap:8px;padding:1px 0}.pickup-fields dt{flex:0 0 84px;min-width:0;color:#8a95a5;font-size:12px}.pickup-fields dd{min-width:0;margin:0;overflow-wrap:anywhere;color:#334157;font-size:13px;font-weight:700}.pickup-files{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:8px}.pickup-files>span{color:#8a95a5;font-size:12px}@media(max-width:1100px){.pickup-fields{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:720px){.pickup-fields{grid-template-columns:1fr;gap:2px}}</style>
|