This commit is contained in:
2026-10-20 11:54:36 +08:00
parent 836e210b09
commit 7005228b52
8 changed files with 64 additions and 31 deletions
@@ -12,7 +12,7 @@ import { availableTruckCommands, truckCommandHints, truckCommandLabels, type Tru
import type { LocalTransportDetail } from '../types'
const props = defineProps<{ detail: LocalTransportDetail }>()
const emit = defineEmits<{ updated: [detail: LocalTransportDetail] }>()
const emit = defineEmits<{ updated: [detail: LocalTransportDetail]; busy: [value: boolean] }>()
const access = useAccessPreviewStore()
const commands = computed(() => access.can(overseasBusinessPermissions.truckStatus) ? availableTruckCommands(props.detail) : [])
const open = ref(false), saving = ref(false)
@@ -23,7 +23,8 @@ const pending = ref<TruckOperation | null>(null)
const form = reactive({ decision: 'APPROVE' as 'APPROVE' | 'REJECT', actualPalletCount: 1, packageCount: undefined as number | undefined, palletIds: [] as string[], remark: '' })
const selectablePallets = computed(() => props.detail.pallets.filter(pallet => pallet.status === 'RECEIVED'))
const review = computed(() => active.value === 'review' || active.value === 'review-pallet-overage')
const { captureBaseline } = useUnsavedWorkRegistration({ key: 'truck-order-command', label: computed(() => active.value ? truckCommandLabels[active.value] : '卡车单据操作'), isOpen: open, model: form, requiredPermission: computed(() => overseasBusinessPermissions.truckStatus) })
const { captureBaseline } = useUnsavedWorkRegistration({ key: 'truck-order-command', label: computed(() => active.value ? truckCommandLabels[active.value] : '卡车单据操作'), isOpen: computed(() => open.value || !!pending.value), model: reactive({ form, pending }), requiredPermission: computed(() => overseasBusinessPermissions.truckStatus) })
watch(saving, value => emit('busy', value))
watch(() => [props.detail.customerId, props.detail.orderNo, props.detail.version], () => {
pending.value = null; open.value = false; active.value = null; error.value = null
@@ -42,7 +43,7 @@ function start(command: TruckCommand) {
function buildOperation(): TruckOperation | null {
if (!active.value) return null
const base = { version: props.detail.version, idempotencyKey: crypto.randomUUID(), remark: form.remark.trim() || undefined }
const base = { version: props.detail.version, idempotencyKey: globalThis.crypto?.randomUUID?.() || `truck-${Date.now()}-${Math.random().toString(36).slice(2)}`, remark: form.remark.trim() || undefined }
if ((active.value === 'cancel' || (review.value && form.decision === 'REJECT')) && !base.remark) {
validationError.value = '请填写拒绝或取消原因'; return null
}
@@ -57,8 +58,8 @@ function buildOperation(): TruckOperation | null {
}
return { command: active.value, payload: { ...base, actualPalletCount: form.actualPalletCount, ...(form.packageCount == null ? {} : { packageCount: form.packageCount }) } }
case 'allocate-pallets':
if (!form.palletIds.length || form.palletIds.some(id => !selectablePallets.value.some(pallet => pallet.id === id))) {
validationError.value = '请至少选择一个已实收且未分配的托盘'; return null
if (!form.palletIds.length || form.palletIds.length > 500 || form.palletIds.some(id => !selectablePallets.value.some(pallet => pallet.id === id))) {
validationError.value = '请选择本单已实收且未分配的托盘,每次最多分配 500 托'; return null
}
return { command: active.value, payload: { ...base, palletIds: [...form.palletIds] } }
case 'cancel': return { command: active.value, payload: { ...base, status: 'CANCELLED' } }
@@ -98,14 +99,14 @@ async function submit() {
<el-form :model="form" label-width="130px" :disabled="saving || !!pending" @submit.prevent="submit">
<el-form-item v-if="review" label="审核结果"><el-radio-group v-model="form.decision"><el-radio value="APPROVE">通过</el-radio><el-radio value="REJECT">拒绝</el-radio></el-radio-group></el-form-item>
<template v-if="active === 'receive-pallets'">
<el-form-item label="累计实收托数" required><el-input-number v-model="form.actualPalletCount" :min="Math.max(1, detail.receivedPalletCount)" :precision="0" /></el-form-item>
<el-form-item label="累计实收托数" required><el-input-number v-model="form.actualPalletCount" :min="Math.max(1, detail.receivedPalletCount)" :precision="0" placeholder="请输入累计实收托数" /></el-form-item>
<el-form-item label="实收件数"><el-input-number v-model="form.packageCount" :min="0" :precision="0" placeholder="选填" /></el-form-item>
</template>
<el-form-item v-if="active === 'allocate-pallets'" label="分配托盘" required>
<el-checkbox-group v-model="form.palletIds"><el-checkbox v-for="pallet in selectablePallets" :key="pallet.id" :value="pallet.id">{{ pallet.palletNo }}({{ pallet.packageCount ?? '未登记' }} 件)</el-checkbox></el-checkbox-group>
<p v-if="!selectablePallets.length">暂无可分配托盘,请刷新核对实收记录。</p>
</el-form-item>
<el-form-item :label="review ? '审核意见' : '操作说明'" :required="active === 'cancel' || (review && form.decision === 'REJECT')"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit /></el-form-item>
<el-form-item :label="review ? '审核意见' : '操作说明'" :required="active === 'cancel' || (review && form.decision === 'REJECT')"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" placeholder="请输入审核意见或操作说明,拒绝或取消时必填" show-word-limit /></el-form-item>
</el-form>
</template>
</AppDialog>