feat(pl): support copy-from plan prefill in plan form dialog

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-06 23:18:04 +08:00
1 parent 13115c8afd
commit d5bbe0d0b1
1 file changed
+93 -1
@@ -367,6 +367,8 @@ const planSelectableContractStatuses = ['approved', 'executing']
const props = defineProps<{
visible: boolean
planId?: string
/** 有值且无 planId 时:新增模式 + 从该计划预填(复制) */
copyFromPlanId?: string
}>()
const emit = defineEmits<{
@@ -405,6 +407,7 @@ function todayYmd(): string {
}
const isEdit = computed(() => !!props.planId)
const isCopy = computed(() => !props.planId && !!props.copyFromPlanId)
const dialogTitle = computed(() => (isEdit.value ? '编辑运输计划' : '新增运输计划'))
const showSaveAndArrange = computed(
() => !isEdit.value || loadedTransportStatus.value === 'pending'
@@ -621,6 +624,18 @@ function mapPlanProductToFormRow(item: PlanProduct, index: number): PlanFormProd
}
}
function mapPlanProductToCopyFormRow(item: PlanProduct, index: number): PlanFormProductRow {
const row = mapPlanProductToFormRow(item, index)
return {
...row,
id: undefined,
actualQty: 0,
purchaseCertUrl: undefined,
transportCertUrl: undefined,
legalUseCertUrl: undefined
}
}
function mapProductsToSubmitPayload() {
return formData.products.map(item => {
prepareLineAliasAndBrandForSubmit(item)
@@ -810,7 +825,7 @@ function resetForm() {
watch(
() => formData.planDate,
(next, prev) => {
if (isEdit.value) return
if (isEdit.value || isCopy.value) return
const nextVal = next || ''
const prevVal = prev || ''
if (!formData.pickupTime || formData.pickupTime === prevVal) {
@@ -826,6 +841,8 @@ function handleOpened() {
loadMasterData().then(async () => {
if (props.planId) {
await loadPlanForEdit(props.planId)
} else if (props.copyFromPlanId) {
await loadPlanForCopy(props.copyFromPlanId)
} else {
resetForm()
}
@@ -908,6 +925,81 @@ async function loadPlanForEdit(planId: string) {
}
}
async function loadPlanForCopy(planId: string) {
detailLoading.value = true
try {
resetForm()
const res = await planApi.get(planId)
const data = (res.data ?? res) as Plan
Object.assign(formData, {
createDate: todayYmd(),
planDate: data.planDate || '',
belongsCompany: data.belongsCompany,
planType: data.planType || '',
followUserId: resolveCurrentUserId(),
followUserName: resolveCurrentUserName(),
contractId: data.contractId || '',
contractNo: data.contractNo || '',
supplierId: data.supplierId || '',
supplierName: data.supplierName || '',
destinationId: data.destinationId || '',
destinationName: data.destinationName || '',
customerId: data.customerId || '',
customerName: data.customerName || '',
contactName: data.contactName || '',
contactPhone: data.contactPhone || '',
partyA: data.partyA || '',
partyB: data.partyB || '',
contractStartDate: data.contractStartDate || '',
contractEndDate: data.contractEndDate || '',
settlementMethod: data.settlementMethod || '',
hasFreight: data.hasFreight ?? 0,
pickupAddress: data.pickupAddress || '',
pickupLng: data.pickupLng != null ? Number(data.pickupLng) : null,
pickupLat: data.pickupLat != null ? Number(data.pickupLat) : null,
pickupTime: formatDate(data.pickupTime) || '',
pickupContact: data.pickupContact || '',
pickupNotes: data.pickupNotes || '',
destinationAddress: data.destinationAddress || '',
destinationLng: data.destinationLng != null ? Number(data.destinationLng) : null,
destinationLat: data.destinationLat != null ? Number(data.destinationLat) : null,
deliveryTime: formatDate(data.deliveryTime) || '',
deliveryContact: data.deliveryContact || '',
destinationNotes: data.destinationNotes || '',
remark: data.remark || '',
products: (data.products || []).map(mapPlanProductToCopyFormRow)
})
loadedTransportStatus.value = 'pending'
if (data.contractId) {
try {
const contractRes = await getContract(data.contractId)
contractSnapshot.value = (contractRes.data ?? contractRes) as ContractVO
} catch {
contractSnapshot.value = buildContractSnapshotFromPlan(data)
}
}
formData.products = await enrichPlanProductLinesAlias(
await enrichPlanProductsHazardFromCrm(
enrichProductsFromContract(formData.products, contractSnapshot.value)
)
)
await refreshContractProductRows()
formData.vehicleId = ''
formData.carrierId = ''
selectedDriverId.value = ''
vehicleBundle.value = null
freightCalc.resetFreightCalc()
} catch (e) {
const message = e instanceof Error ? e.message : '加载源计划失败'
ElMessage.error(message.includes('加载') ? message : `加载源计划失败:${message}`)
emit('update:visible', false)
} finally {
detailLoading.value = false
}
}
function buildContractSnapshotFromPlan(plan: Plan): ContractVO {
return {
id: plan.contractId || '',