This commit is contained in:
2026-08-06 15:32:07 +08:00
parent e33d620d87
commit 9aa79bef6d
8 changed files with 101 additions and 22 deletions
@@ -29,7 +29,8 @@ test('exposes real list, draft, submit, and detail workflow entries without canc
assert.match(source, /function submitOrder\(\)/)
assert.match(source, /async function openDetail\(order: FirstLegOrder\)/)
assert.match(source, /Promise\.allSettled\(\[/)
assert.match(source, /Promise\.allSettled\(\[\s*store\.load\(\),\s*companyRequest/)
assert.match(source, /const orderPageRequest = isCreatePage\.value\s*\? store\.loadWarehouseType\('DOMESTIC', true\)\s*:\s*store\.load\(\)/)
assert.match(source, /Promise\.allSettled\(\[\s*orderPageRequest,\s*companyRequest/)
assert.match(source, /tenantStore\.loadCompanyContext\(\)/)
assert.match(source, /await store\.loadDetail\(order\.id\)/)
assert.doesNotMatch(source, /cancelOrder|取消订单/)
@@ -127,6 +128,11 @@ test('keeps desktop query actions on the first row and only shows the qualificat
assert.doesNotMatch(source, /order-eligibility\.is-approved/)
})
test('does not let order-list loading block the create form', () => {
assert.match(source, /v-loading="isCreatePage && supportingDataLoading"/)
assert.match(source, /const pageDataLoading = computed\(\(\) => supportingDataLoading\.value \|\| \(!isCreatePage\.value && store\.loading\)\)/)
})
test('does not expose arbitrary status mutation controls to customers', () => {
assert.doesNotMatch(source, /setStatusForPreview/)
assert.doesNotMatch(source, /状态更新|更新状态/)
@@ -160,6 +166,12 @@ test('selects platform destinations by type and caches private addresses per use
assert.match(source, /私人地址不能引用平台公共仓库|form\.destinationWarehouseId = ''/)
})
test('shows a recoverable destination warehouse error when list-to-create loading fails', () => {
assert.match(source, /await router\.push\(\{ name: 'first-leg-order-create' \}\)[\s\S]*?try \{[\s\S]*?await loadDestinationWarehouses\(form\.destinationType\)/)
assert.match(source, /supportingDataErrors\.value\.push\(message\)/)
assert.match(source, /目的仓数据加载失败,请点击页面提示重新加载/)
})
test('auto-fills trusted warehouse and company data instead of asking customers to repeat it', () => {
assert.match(source, /async function selectDestinationWarehouse\(id: string\)/)
assert.match(source, /await store\.loadWarehouseDetail\(warehouse\.id\)/)
@@ -82,6 +82,7 @@ const inboundBillingError = ref('')
const supportingDataLoading = ref(false)
const supportingDataErrors = ref<string[]>([])
const destinationWarehousesLoading = ref(false)
const pageDataLoading = computed(() => supportingDataLoading.value || (!isCreatePage.value && store.loading))
const editorBaseline = ref('')
let cargoSequence = 0
let inboundBillingRequestSequence = 0
@@ -296,8 +297,11 @@ async function loadPageData() {
const destinationRequest = isCreatePage.value && form.destinationType !== 'PRIVATE'
? loadDestinationWarehouses(form.destinationType)
: Promise.resolve()
const orderPageRequest = isCreatePage.value
? store.loadWarehouseType('DOMESTIC', true)
: store.load()
const [ordersResult, companyResult, destinationResult] = await Promise.allSettled([
store.load(),
orderPageRequest,
companyRequest,
destinationRequest,
])
@@ -306,7 +310,7 @@ async function loadPageData() {
} else if (companyResult.status === 'rejected') {
supportingDataErrors.value.push(`企业资料加载失败:${errorMessage(companyResult.reason)}`)
}
if (ordersResult.status === 'rejected' && !store.loadError) supportingDataErrors.value.push(`订单加载失败:${errorMessage(ordersResult.reason)}`)
if (!isCreatePage.value && ordersResult.status === 'rejected' && !store.loadError) supportingDataErrors.value.push(`订单加载失败:${errorMessage(ordersResult.reason)}`)
if (store.warehouseLoadError) supportingDataErrors.value.push(`公共仓库加载失败:${store.warehouseLoadError}`)
if (store.draftLoadError) supportingDataErrors.value.push(`订单草稿加载失败:${store.draftLoadError}`)
if (destinationResult.status === 'rejected') supportingDataErrors.value.push(`目的仓加载失败:${errorMessage(destinationResult.reason)}`)
@@ -554,8 +558,14 @@ async function openCreate() {
replaceForm(emptyDraft())
resetEditorValidation()
await router.push({ name: 'first-leg-order-create' })
await loadDestinationWarehouses(form.destinationType)
await autofillWarehouseSelections()
try {
await loadDestinationWarehouses(form.destinationType)
await autofillWarehouseSelections()
} catch (error) {
const message = `目的仓加载失败:${errorMessage(error)}`
if (!supportingDataErrors.value.includes(message)) supportingDataErrors.value.push(message)
ElMessage.error('目的仓数据加载失败,请点击页面提示重新加载')
}
}
async function openEdit(order: FirstLegOrder) {
@@ -877,12 +887,12 @@ async function searchOrders(model: QueryModel) {
<div v-if="isCreatePage && supportingDataErrors.length" class="supporting-data-error" role="alert">
<AlertTriangle :size="20" />
<div><strong>下单配套数据加载失败</strong><span v-for="message in supportingDataErrors" :key="message">{{ message }}</span></div>
<el-button :loading="supportingDataLoading || store.loading" @click="loadPageData">重新加载</el-button>
<el-button :loading="pageDataLoading" @click="loadPageData">重新加载</el-button>
</div>
<el-alert v-if="isCreatePage && !supportingDataLoading && availableWarehouses.length === 0" title="当前没有可用的平台收货仓" description="请联系平台维护并启用收货仓后再创建订单。" type="warning" :closable="false" show-icon />
<FirstLegOrderEditorShell v-model="editorOpen" :page="isCreatePage" :title="editingId ? '编辑订单草稿' : '创建订单'" :before-close="requestCloseEditor" @back="closeEditor">
<el-form ref="orderFormRef" v-loading="isCreatePage && (supportingDataLoading || store.loading)" :model="form" :rules="orderFormRules" label-position="top" class="order-form prototype-order-form" scroll-to-error>
<el-form ref="orderFormRef" v-loading="isCreatePage && supportingDataLoading" :model="form" :rules="orderFormRules" label-position="top" class="order-form prototype-order-form" scroll-to-error>
<section class="order-form-section prototype-section">
<div class="order-section-heading"><div><h3>发货信息</h3><p>先选择货物如何送到国内收货仓,并填写本次运输安排。</p></div></div>
<div class="prototype-form-flow shipping-form-flow">