feat(web-admin): add plan draft save UI and drafting follow-status filters

Rename pending tab to 待安排/草稿, default-select drafting, and add 暂存 with saveMode.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-09-02 11:42:23 +08:00
1 parent ae91fbc63e
commit 3c7e3c69c5
4 files changed
+77 -9

No files matched your search

@@ -254,6 +254,13 @@
<el-button @click="innerVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button
v-if="showDraftButton"
:loading="submitLoading"
@click="handleSubmit('draft')"
>
<el-icon><Document /></el-icon>暂存
</el-button>
<el-button
v-if="showSaveButton"
:type="showSaveAndArrangeButton ? 'default' : 'primary'"
@@ -320,6 +327,7 @@
Check,
Close,
Delete,
Document,
DocumentCopy,
FolderOpened,
Plus,
@@ -482,6 +490,7 @@
/** 加载详情 / 重置时禁止计划产品 → 段产品自动对齐 */
const suppressStopProductSync = ref(false)
const loadedTransportStatus = ref('pending')
const loadedFollowStatus = ref('')
const loadForm = ref<PlanLoadForm>(createEmptyLoadForm())
const deliveryForms = ref<PlanDeliveryForm[]>([createEmptyDeliveryForm(1)])
const loadedPlanSnapshot = ref<Plan | null>(null)
@@ -489,6 +498,12 @@
/** 已安排:禁止仅「保存」,须走保存并安排/调整运输,避免计划与地磅等联动字段脱节 */
const showSaveButton = computed(() => loadedTransportStatus.value !== 'arranged')
const showDraftButton = computed(() => {
if (!isEdit.value) return true
return (
loadedFollowStatus.value === 'drafting' || loadedFollowStatus.value === 'pending_arrange'
)
})
const showSaveAndArrangeButton = computed(() => {
if (!isEdit.value) return true
if (props.openForArrange && loadedTransportStatus.value === 'arranged') return false
@@ -1577,6 +1592,7 @@
function resetForm() {
loadedTransportStatus.value = 'pending'
loadedFollowStatus.value = ''
loadedPlanSnapshot.value = null
vehicleBundle.value = null
selectedDriverId.value = ''
@@ -1669,6 +1685,7 @@
})
applyStopsFromPlan(data)
loadedTransportStatus.value = data.transportStatus || 'pending'
loadedFollowStatus.value = data.followStatus || ''
loadedPlanSnapshot.value = data
syncCommittedPartyIds()
@@ -1731,6 +1748,7 @@
products: row.products.map((product) => ({ ...product, planProductId: undefined }))
}))
loadedTransportStatus.value = 'pending'
loadedFollowStatus.value = ''
syncCommittedPartyIds()
formData.products = await enrichPlanProductLinesAlias(
@@ -1976,11 +1994,51 @@
return missing
}
async function handleSubmit(mode: 'save' | 'saveAndArrange' | 'rearrange' = 'save') {
async function handleSubmit(
mode: 'draft' | 'save' | 'saveAndArrange' | 'rearrange' = 'save'
) {
// 必须在 await validate 之前置位,避免连点并发多次 createFull
if (submitLoading.value) return
submitLoading.value = true
try {
if (mode === 'draft') {
const companyOk = !!(formData.belongsCompany || '').trim()
const dateOk = !!(formData.createDate || '').trim()
if (!companyOk || !dateOk) {
ElMessage.warning('暂存请至少填写归属公司和创建日期')
await basicFormRef.value
?.validateField?.(['belongsCompany', 'createDate'])
.catch(() => undefined)
return
}
mirrorPlanProductsFromLoad()
const draftPayload = {
...buildPlanCommonPayload({ allowClearTransport: isEdit.value }),
saveMode: 'draft' as const,
hasFreight: formData.hasFreight
}
let planId = props.planId || ''
if (isEdit.value) {
if (!props.planId) return
await planApi.update(props.planId, draftPayload)
planId = props.planId
} else {
const res = await planApi.createFull(
draftPayload as Parameters<typeof planApi.createFull>[0]
)
const created = pickBxData<Plan>(res)
planId = String(created?.id || '')
if (!planId) {
ElMessage.error('暂存成功但未返回计划 ID')
return
}
}
ElMessage.success('暂存成功')
innerVisible.value = false
emit('success', { planId, arranged: false })
return
}
const valid = await basicFormRef.value?.validate().catch(() => false)
if (!valid || !validateBusinessRules()) return
if (!validateSingleContractPerStop()) return
@@ -2000,7 +2058,10 @@
}
mirrorPlanProductsFromLoad()
const commonPayload = buildPlanCommonPayload({ allowClearTransport: isEdit.value })
const commonPayload = {
...buildPlanCommonPayload({ allowClearTransport: isEdit.value }),
saveMode: 'formal' as const
}
let planId = props.planId || ''
const wasCreate = !isEdit.value