54 lines
4.5 KiB
Vue
54 lines
4.5 KiB
Vue
<script setup lang="ts">
|
||
import { ref, watch } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||
import { getDispatch, listLooseboardCargo, addLooseboardCargo, expandSelectionGroups, type Candidate, type DispatchDetail } from '@/modules/overseas-warehouse'
|
||
const open=defineModel<boolean>({default:false})
|
||
const props=defineProps<{dispatchNo:string}>()
|
||
const emit=defineEmits<{saved:[]}>()
|
||
const rows=ref<Candidate[]>([]), selected=ref<Candidate[]>([]), detail=ref<DispatchDetail|null>(null)
|
||
const page=ref(1), size=ref(20), total=ref(0), loading=ref(false), saving=ref(false), error=ref<ApiErrorDetails|null>(null)
|
||
const columns:DataTableColumn[]=[
|
||
{key:'selection',type:'selection',width:45}, {key:'orderNo',label:'订单号',minWidth:180},
|
||
{key:'customerName',label:'客户',minWidth:140}, {key:'inboundCode',label:'入仓号',minWidth:150},
|
||
{key:'sourceStage',label:'货物阶段',width:110,formatter:(row:Candidate)=>!row.selection.warehousePalletId ? '申报待到仓' : '已实收'}, {key:'palletNo',label:'计划 / 实物托盘',minWidth:150}, {key:'destination',label:'目的地',minWidth:180,formatter:(row:Candidate)=>row.destination.warehouseCode || row.destination.address || '—'},
|
||
{key:'availablePackages',label:'计划 / 可用箱数',width:100},
|
||
{key:'blockReasons',label:'资格',minWidth:200,formatter:(row:Candidate)=>row.blockReasons.length?row.blockReasons.join(';'):'可添加'},
|
||
]
|
||
let generation=0
|
||
async function load() {
|
||
const current=++generation;loading.value=true;error.value=null;selected.value=[];rows.value=[];detail.value=null
|
||
try {
|
||
const [dispatch,value]=await Promise.all([getDispatch(props.dispatchNo),listLooseboardCargo(props.dispatchNo,page.value,size.value)])
|
||
if(current!==generation)return
|
||
if(dispatch.dispatchNo!==props.dispatchNo)throw new Error('排车身份不一致,请重新打开')
|
||
detail.value=dispatch;rows.value=value.candidates;total.value=value.total
|
||
}catch(cause){if(current===generation)error.value=getApiErrorDetails(cause,'散板货物读取失败')}
|
||
finally{if(current===generation)loading.value=false}
|
||
}
|
||
async function submit(){
|
||
if(!detail.value || saving.value || !selected.value.length)return
|
||
saving.value=true;error.value=null
|
||
try{
|
||
if(selected.value.some(row=>row.blockReasons.length))throw new Error('所选货物存在阻断,请重新选择')
|
||
const cargo=expandSelectionGroups(selected.value)
|
||
// 完整组来源版本由后端复核;预约批次继续通过原排车预约工作台绑定。
|
||
await addLooseboardCargo(props.dispatchNo,{recordVersion:detail.value.recordVersion,idempotencyKey:crypto.randomUUID(),cargo,batchAllocations:[]})
|
||
ElMessage.success('散板货物已加入排车,请按当前货物重新审核');open.value=false;emit('saved')
|
||
}catch(cause){await load();error.value=getApiErrorDetails(cause,'添加货物失败')}
|
||
finally{saving.value=false}
|
||
}
|
||
watch(open,value=>{if(value){page.value=1;void load()}else generation++})
|
||
watch([page,size],()=>{if(open.value)void load()})
|
||
</script>
|
||
<template><AppDialog v-model="open" title="添加散板货物" width="1180px" class="admin-density-dialog admin-workbench" :confirm-loading="saving" :confirm-disabled="loading || !selected.length || !detail?.actions.ADD_CARGO?.allowed" lock-while-submitting @confirm="submit">
|
||
<LoadErrorState v-if="error" title="添加货物暂未完成" :message="error.message" @retry="load"><template #details><ApiErrorMeta :details="error" /></template></LoadErrorState>
|
||
<el-alert v-if="detail && !detail.actions.ADD_CARGO?.allowed" :title="detail.actions.ADD_CARGO?.blockReason || '当前排车不可加货,请先退回审核或重新排车'" type="warning" :closable="false" />
|
||
<el-alert title="申报货物可先加入排车;实际到仓后核对货量,完成实收后才能出库拣货。上门取货的凭证在对应取货排车节点上传。" type="info" :closable="false" />
|
||
<DataTable v-model:page="page" v-model:page-size="size" :data="rows" :columns="columns" :total="total" :loading="loading" row-key="sourceKey" :page-sizes="[10,20,50]" empty-text="暂无可添加的已审核散板货物" @selection-change="selected=$event" />
|
||
</AppDialog></template>
|