From 7af1d0250bcadf39336b2eb097dd4985528ba216 Mon Sep 17 00:00:00 2001
From: ouyangxq <775153912@qq.com>
Date: Tue, 4 Aug 2026 12:58:04 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../views/FirstLegOrdersView.test.mjs | 16 +++-
.../first-leg/views/FirstLegOrdersView.vue | 96 ++++++++++++++-----
2 files changed, 84 insertions(+), 28 deletions(-)
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
index bfd5600..6fe32a9 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
+++ b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
@@ -120,6 +120,16 @@ test('selects platform destinations by type and caches private addresses per use
assert.match(source, /私人地址不能引用平台公共仓库|form\.destinationWarehouseId = ''/)
})
+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\)/)
+ assert.match(source, /availableWarehouses\.value\.length === 1/)
+ assert.match(source, /availableDestinationWarehouses\.value\.length === 1/)
+ assert.match(source, /function createPickupPartySnapshot\(\)/)
+ assert.match(source, /contactName: tenantStore\.company\.contactName/)
+ assert.match(source, /selectedDestinationWarehouse\.address/)
+})
+
test('collects the backend-required first-leg fields', () => {
for (const model of ['destinationCountryCode', 'destinationWarehouseName', 'channelCode', 'pickupMethod', 'taxMode', 'destinationType', 'packageType', 'upc']) {
assert.match(source, new RegExp(`v-model="(?:form|item)\\.${model}"`))
@@ -128,9 +138,11 @@ test('collects the backend-required first-leg fields', () => {
})
test('distills order creation into the confirmed prototype sections without fake pricing', () => {
- assert.match(source, /
下单信息<\/h3>/)
+ assert.match(source, /目的地信息<\/h3>/)
+ assert.match(source, /发货信息<\/h3>/)
assert.match(source, /货物明细<\/h3>/)
- assert.doesNotMatch(source, /发货信息<\/h3>|目的地信息<\/h3>/)
+ assert.ok(source.indexOf('发货信息
') < source.indexOf('目的地信息
'))
+ assert.ok(source.indexOf('目的地信息
') < source.indexOf('货物明细
'))
assert.match(source, /class="segmented-options"/)
assert.match(source, /class="prototype-form-row prototype-form-row--tabs"/)
assert.match(source, /class="cargo-primary-grid"/)
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.vue b/src/modules/first-leg/views/FirstLegOrdersView.vue
index a961dd1..41767a1 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.vue
+++ b/src/modules/first-leg/views/FirstLegOrdersView.vue
@@ -139,6 +139,16 @@ function createEmptyPartySnapshot(role: FirstLegPartyRole): FirstLegPartySnapsho
}
}
+function createPickupPartySnapshot(): FirstLegPartySnapshot {
+ return {
+ ...createEmptyPartySnapshot('SHIPPER'),
+ name: tenantStore.company.companyName,
+ contactName: tenantStore.company.contactName,
+ phone: tenantStore.company.contactPhone,
+ email: tenantStore.company.contactEmail,
+ }
+}
+
function requiredTextRules(message: string): FormItemRule[] {
return [{ required: true, message, trigger: 'blur' }]
}
@@ -226,6 +236,7 @@ const pagedOrders = computed(() => {
const detailOrder = computed(() => detailId.value ? store.getById(detailId.value) : undefined)
const detailSummary = computed(() => detailOrder.value ? summarizeFirstLegCargo(detailOrder.value.items) : null)
const selectedWarehouse = computed(() => availableWarehouses.value.find((item) => item.id === form.receivingWarehouseId))
+const selectedDestinationWarehouse = computed(() => store.warehouses.find((item) => item.id === form.destinationWarehouseId && item.warehouseType === form.destinationType))
const hasActiveFilters = computed(() => {
const values = appliedFilters.value
return Boolean(
@@ -255,6 +266,7 @@ async function loadPageData() {
}
if (ordersResult.status === 'rejected' && !store.loadError) supportingDataErrors.value.push(`订单加载失败:${errorMessage(ordersResult.reason)}`)
if (store.warehouseLoadError) supportingDataErrors.value.push(`公共仓库加载失败:${store.warehouseLoadError}`)
+ await autofillWarehouseSelections()
supportingDataLoading.value = false
}
@@ -348,7 +360,7 @@ function selectChannel(code: string) {
form.channelName = channel?.name ?? ''
}
-function selectDestinationWarehouse(id: string) {
+async function selectDestinationWarehouse(id: string) {
const warehouse = availableDestinationWarehouses.value.find((item) => item.id === id)
if (!warehouse) return
form.destinationWarehouseId = warehouse.id
@@ -356,9 +368,18 @@ function selectDestinationWarehouse(id: string) {
form.destinationCountryCode = warehouse.countryCode.toUpperCase()
form.destination = warehouse.name
form.amazonWarehouseCode = form.destinationType === 'FBA' ? warehouse.code : ''
+ try {
+ const detail = await store.loadWarehouseDetail(warehouse.id)
+ form.destinationWarehouseName = detail.name
+ form.destinationCountryCode = detail.countryCode.toUpperCase()
+ form.destination = detail.name
+ form.amazonWarehouseCode = form.destinationType === 'FBA' ? detail.code : ''
+ } catch (error) {
+ ElMessage.error(error instanceof Error ? error.message : '目的仓详情加载失败')
+ }
}
-function changeDestinationType() {
+async function changeDestinationType() {
form.destinationWarehouseId = ''
form.destinationWarehouseName = ''
form.destination = ''
@@ -367,12 +388,15 @@ function changeDestinationType() {
form.consigneePartyId = ''
form.consigneePartySnapshot = form.destinationType === 'PRIVATE' ? createEmptyPartySnapshot('CONSIGNEE') : null
form.consignee = ''
+ if (form.destinationType !== 'PRIVATE' && availableDestinationWarehouses.value.length === 1) {
+ await selectDestinationWarehouse(availableDestinationWarehouses.value[0].id)
+ }
resetEditorValidation()
}
function changePickupMethod() {
if (form.pickupMethod === 'PICKUP') {
- form.shipperPartySnapshot ??= createEmptyPartySnapshot('SHIPPER')
+ form.shipperPartySnapshot ??= createPickupPartySnapshot()
} else {
form.shipperPartyId = ''
form.shipperPartySnapshot = null
@@ -450,6 +474,18 @@ async function loadSelectedWarehouse(id: string | number | boolean | undefined)
}
}
+async function autofillWarehouseSelections() {
+ if (!isCreatePage.value || editingId.value) return
+ if (!form.receivingWarehouseId && availableWarehouses.value.length === 1) {
+ form.receivingWarehouseId = availableWarehouses.value[0].id
+ await loadSelectedWarehouse(form.receivingWarehouseId)
+ }
+ if (form.destinationType !== 'PRIVATE' && !form.destinationWarehouseId && availableDestinationWarehouses.value.length === 1) {
+ await selectDestinationWarehouse(availableDestinationWarehouses.value[0].id)
+ }
+ markEditorClean()
+}
+
async function openCreate() {
if (availableWarehouses.value.length === 0) {
ElMessage.warning('当前没有可用的平台收货仓,请联系平台维护仓库后再创建订单')
@@ -459,6 +495,7 @@ async function openCreate() {
replaceForm(emptyDraft())
resetEditorValidation()
await router.push({ name: 'first-leg-order-create' })
+ await autofillWarehouseSelections()
}
async function openEdit(order: FirstLegOrder) {
@@ -724,7 +761,31 @@ async function searchOrders(model: QueryModel) {
+
+
@@ -905,8 +946,11 @@ async function searchOrders(model: QueryModel) {
.address-book-control { display: grid; grid-template-columns: minmax(260px, 1fr) auto auto; gap: 10px; align-items: center; }
.address-book-control :deep(.el-button) { min-height: 40px; margin-left: 0; }
.field-guidance { display: block; margin-top: 5px; color: var(--muted); line-height: 1.45; }
-.selected-destination { display: flex; width: min(100%, 720px); align-items: center; gap: 9px; margin: -4px 0 18px 140px; padding: 10px 12px; background: #f2f7f6; color: var(--primary); }
+.selected-destination { display: flex; width: min(100%, 720px); align-items: flex-start; gap: 9px; margin: -4px 0 18px 140px; padding: 10px 12px; background: #f2f7f6; color: var(--primary); }
+.selected-destination svg { flex: 0 0 17px; margin-top: 2px; }
+.selected-destination div { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
.selected-destination span { color: var(--navy); font-size: 12px; font-weight: 600; }
+.selected-destination small { color: var(--muted); font-size: 11px; line-height: 1.5; }
.flow-divider { width: min(100%, 860px); margin: 4px 0 22px; border-top: 1px solid var(--border); }
.compact-transport-grid { margin-top: 18px; }
.cargo-entry { padding: 16px; border: 1px solid var(--border); background: #fbfcfc; }