2026-10-15 17:11:03 +08:00
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { computed, onMounted, ref } from 'vue'
|
|
|
|
|
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
|
|
|
|
|
import { getDispatch, type DispatchSummaryDto } from '@/modules/overseas-warehouse'
|
|
|
|
|
|
import { TripPreparationDialog } from '@/modules/overseas-master-data'
|
|
|
|
|
|
import { ApiResponseError, getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
|
|
|
|
|
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
|
|
|
|
|
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
|
|
|
|
|
const props = defineProps<{ dispatches: Array<{ batchKey: string; dispatchNo: string }>; canWrite: boolean }>()
|
|
|
|
|
|
const emit = defineEmits<{ updated: []; external: [path: string] }>()
|
|
|
|
|
|
const access = useAccessPreviewStore(), rows = ref<DispatchSummaryDto[]>([]), loading = ref(false), error = ref<ApiErrorDetails | null>(null)
|
|
|
|
|
|
const selected = ref<DispatchSummaryDto | null>(null), prepareOpen = ref(false)
|
|
|
|
|
|
const readable = computed(() => access.can('platform:overseas-warehouse:dispatch:list'))
|
|
|
|
|
|
const writable = computed(() => props.canWrite && readable.value && access.can('platform:fleet:trip:list') && access.can('platform:fleet:trip:edit'))
|
|
|
|
|
|
async function load() {
|
|
|
|
|
|
if (!readable.value) return
|
|
|
|
|
|
loading.value = true; error.value = null
|
|
|
|
|
|
try {
|
|
|
|
|
|
rows.value = await Promise.all(props.dispatches.map(async reference => {
|
|
|
|
|
|
const row = await getDispatch(reference.dispatchNo)
|
|
|
|
|
|
if (`DISPATCH:${row.id}` !== reference.batchKey || row.dispatchNo !== reference.dispatchNo) throw new ApiResponseError('排车单与工作批次关联不一致,请刷新核对', 'WORK_DISPATCH_MISMATCH')
|
|
|
|
|
|
return row
|
|
|
|
|
|
}))
|
|
|
|
|
|
} catch (cause) { error.value = getApiErrorDetails(cause, '原排车单读取失败') }
|
|
|
|
|
|
finally { loading.value = false }
|
|
|
|
|
|
}
|
|
|
|
|
|
function prepare(row: DispatchSummaryDto) { if (writable.value && !loading.value && !error.value && row.status === 'PENDING_DEPARTURE' && !row.workflow && row.overseasWarehouseId) { selected.value = row; prepareOpen.value = true } }
|
|
|
|
|
|
function saved(value: { trip: { tripNo: string } }) { prepareOpen.value = false; emit('updated'); emit('external', `/overseas-master-data/trips/${encodeURIComponent(value.trip.tripNo)}`) }
|
|
|
|
|
|
onMounted(load)
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<section aria-label="原排车单安排用车"><h3>原排车单安排用车</h3><p>客户仓批次沿用已选实物和原排车单,确认起运仓后安排车次、车辆与司机。</p>
|
|
|
|
|
|
<p v-if="!readable">查看原排车单需要排车列表权限。</p><p v-if="loading">正在核对原排车单与批次…</p>
|
|
|
|
|
|
<LoadErrorState v-if="error" title="原排车单读取失败" :message="error.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="error" /></template></LoadErrorState>
|
2026-10-16 15:41:56 +08:00
|
|
|
|
<table v-if="!loading && !error && readable" class="density-table"><thead><tr><th>操作</th><th>排车单号</th><th>起运仓</th><th>箱数</th><th>车次</th></tr></thead><tbody><tr v-for="row in rows" :key="row.dispatchNo"><td><el-button v-if="!row.workflow" :disabled="!writable || row.status !== 'PENDING_DEPARTURE' || !row.overseasWarehouseId" @click="prepare(row)">继续安排本批车辆</el-button><el-button @click="emit('external', `/overseas-warehouse/dispatches?dispatchNo=${encodeURIComponent(row.dispatchNo)}`)">查看原排车单</el-button></td><td>{{ row.dispatchNo }}</td><td>{{ row.overseasWarehouseName || '起运仓待核实' }}</td><td>{{ row.packageCount ?? '待核实' }}</td><td><el-button v-if="row.workflow?.tripNo && access.can('platform:fleet:trip:list')" @click="emit('external', `/overseas-master-data/trips/${encodeURIComponent(row.workflow.tripNo)}`)">{{ row.workflow.tripNo }}</el-button><span v-else>尚未关联车次</span></td></tr></tbody></table>
|
2026-10-15 17:11:03 +08:00
|
|
|
|
<TripPreparationDialog v-if="selected?.overseasWarehouseId" v-model="prepareOpen" :warehouse-id="selected.overseasWarehouseId" :warehouse-name="selected.overseasWarehouseName || '起运仓待核实'" :dispatch-nos="[selected.dispatchNo]" @saved="saved" />
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</template>
|