diff --git a/src/modules/first-leg/components/FirstLegOrderEditorShell.vue b/src/modules/first-leg/components/FirstLegOrderEditorShell.vue
index d790f7b..faa6a22 100644
--- a/src/modules/first-leg/components/FirstLegOrderEditorShell.vue
+++ b/src/modules/first-leg/components/FirstLegOrderEditorShell.vue
@@ -42,14 +42,24 @@ const emit = defineEmits<{
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
index e973b3c..17584b8 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
+++ b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
@@ -358,7 +358,8 @@ test('shows a loading state before the list can create an order', () => {
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, /warehouse\.code\.toUpperCase\(\)\.includes\('YIWU'\)/)
+ assert.match(source, /warehouse\.name\.includes\('义乌'\)/)
assert.match(source, /availableDestinationWarehouses\.value\.length === 1/)
assert.match(source, /function createPickupPartySnapshot\(\)/)
assert.match(source, /contactName: tenantStore\.company\.contactName/)
@@ -422,6 +423,24 @@ test('distills order creation into the confirmed prototype sections with server
assert.doesNotMatch(source, /v-model="form\.(?:businessType|origin|destination|priority|tradeTerm)"/)
})
+test('matches the prototype two-column create layout and reset action', () => {
+ assert.match(source, /class="order-form-section prototype-section order-basic-section"/)
+ assert.match(source, /
客户下单<\/h3>
创建新订单<\/p>/)
+ assert.match(source, /\.is-create-route \.prototype-order-form \{[^}]*grid-template-columns: repeat\(2, minmax\(0, 1fr\)\)/)
+ assert.match(source, /\.is-create-route \.cargo-section, \.is-create-route \.cost-estimate-section \{ grid-column: 1 \/ -1; \}/)
+ assert.match(source, /\.is-create-route \.prototype-form-row :deep\(\.el-form-item__label\) \{[^}]*height: 40px[^}]*align-items: center[^}]*justify-content: flex-end/)
+ assert.match(source, /\.is-create-route \.compact-transport-grid > :deep\(\.el-form-item__label\) \{[^}]*align-items: center[^}]*text-align: right/)
+ assert.match(source, /async function resetCreateForm\(\)/)
+ assert.match(source, /确认清空当前填写的订单内容并恢复默认值/)
+ assert.match(source, /v-if="isCreatePage"[^>]*@click="resetCreateForm"[^>]*>]*\/>重置/)
+ assert.match(source, /class="submit-order-button"/)
+ assert.match(editorShellSource, /\.first-leg-editor-page \{[^}]*padding-bottom: 72px/)
+ assert.match(editorShellSource, /\.editor-page-footer \{[^}]*position: fixed[^}]*bottom: 0[^}]*left: 224px/)
+ assert.match(editorShellSource, /submit-gradient 5s ease-in-out infinite/)
+ assert.match(editorShellSource, /submit-shine 3\.2s ease-in-out infinite/)
+ assert.match(editorShellSource, /@media \(prefers-reduced-motion: reduce\)/)
+})
+
test('shows an optional LX inbound order number for one-click dropship orders', () => {
assert.match(source, /v-if="form\.fulfillmentType === 'ONE_CLICK_DROPSHIP'" label="LX入库单号" prop="lxCode"/)
assert.match(source, /v-model="form\.lxCode"[^>]*placeholder="请输入LX入库单号"/)
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.vue b/src/modules/first-leg/views/FirstLegOrdersView.vue
index 9b9082e..f7836c3 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.vue
+++ b/src/modules/first-leg/views/FirstLegOrdersView.vue
@@ -1262,8 +1262,12 @@ 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
+ if (!form.receivingWarehouseId) {
+ const yiwuWarehouse = availableWarehouses.value.find((warehouse) => warehouse.code.toUpperCase().includes('YIWU'))
+ ?? availableWarehouses.value.find((warehouse) => warehouse.name.includes('义乌'))
+ if (yiwuWarehouse) form.receivingWarehouseId = yiwuWarehouse.id
+ }
+ if (form.receivingWarehouseId) {
await loadSelectedWarehouse(form.receivingWarehouseId)
}
if (form.destinationType !== 'PRIVATE' && !form.destinationWarehouseId && availableDestinationWarehouses.value.length === 1) {
@@ -1485,6 +1489,27 @@ function closeEditor() {
})
}
+async function resetCreateForm() {
+ if (saving.value) return
+ if (editorDirty.value) {
+ try {
+ await ElMessageBox.confirm('确认清空当前填写的订单内容并恢复默认值?', '重置订单', {
+ type: 'warning',
+ confirmButtonText: '确认重置',
+ cancelButtonText: '继续填写',
+ })
+ } catch (error) {
+ if (error === 'cancel' || error === 'close') return
+ throw error
+ }
+ }
+ editingId.value = undefined
+ replaceForm(emptyDraft())
+ await autofillWarehouseSelections()
+ resetEditorValidation()
+ await router.replace({ name: 'first-leg-order-create' })
+}
+
function addCargoItem() {
form.items.push(createEmptyCargoItem(`new-cargo-${++cargoSequence}`))
resetEditorValidation()
@@ -2134,8 +2159,8 @@ async function searchOrders(model: QueryModel) {
-
- 返回保存草稿{{ companySubmissionBlocked ? '提交前需完成资料审核' : '提交订单' }}
+ 重置返回保存草稿{{ companySubmissionBlocked ? '提交前需完成资料审核' : '提交订单' }}
@@ -2528,8 +2553,23 @@ async function searchOrders(model: QueryModel) {
.is-create-route { gap: 0; }
.is-create-route .first-leg-editor-page { width: 100%; }
.is-create-route .supporting-data-error, .is-create-route > .el-alert { margin-bottom: 14px; }
-.is-create-route .prototype-order-form { width: 100%; margin: 0; padding: 0 0 16px; }
-.is-create-route .prototype-section:not(.cargo-section):not(.cost-estimate-section):not(.destination-section) { width: min(100%, 900px); }
+.is-create-route .prototype-order-form { display: grid; width: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; gap: 16px; margin: 0; padding: 0 0 16px; }
+.is-create-route .prototype-section { min-width: 0; margin: 0; padding: 0 24px 24px; border: 1px solid #dfe6ee; border-radius: 8px; background: #fff; }
+.is-create-route .prototype-section + .prototype-section { margin-top: 0; }
+.is-create-route .order-basic-section, .is-create-route .destination-section { height: 100%; }
+.is-create-route .cargo-section, .is-create-route .cost-estimate-section { grid-column: 1 / -1; }
+.is-create-route .order-section-heading { min-height: 66px; align-items: center; margin: 0 -24px 22px; padding: 15px 24px; border-bottom: 1px solid #e7ecf2; }
+.is-create-route .order-section-heading h3, .is-create-route .prototype-section:first-child > .order-section-heading h3 { margin: 0; color: var(--navy); font-size: 17px; font-weight: 700; }
+.is-create-route .order-section-heading p { margin-top: 4px; color: #8a98a8; }
+.is-create-route .prototype-form-flow, .is-create-route .destination-form-flow { width: 100%; max-width: none; }
+.is-create-route .prototype-form-row, .is-create-route .prototype-form-row--wide, .is-create-route .prototype-form-row--compact, .is-create-route .prototype-form-row--short, .is-create-route .prototype-form-row--tabs { grid-template-columns: 120px minmax(0, 1fr); }
+.is-create-route .prototype-form-row :deep(.el-form-item__label) { display: flex; height: 40px; min-height: 40px; align-items: center; justify-content: flex-end; padding: 0 18px 0 0; font-size: 13px; line-height: 1.35; text-align: right; }
+.is-create-route .segmented-options, .is-create-route .destination-type-options { width: 100%; max-width: 560px; background: #f3f6f9; }
+.is-create-route .compact-transport-grid { width: 100%; margin-top: 4px; }
+.is-create-route .compact-transport-grid > :deep(.el-form-item), .is-create-route .compact-transport-grid > :deep(.el-form-item:nth-child(1)), .is-create-route .compact-transport-grid > :deep(.el-form-item:nth-child(6)), .is-create-route .compact-transport-grid > :deep(.el-form-item:nth-child(7)) { grid-template-columns: 120px minmax(0, 1fr); }
+.is-create-route .compact-transport-grid > :deep(.el-form-item__label) { display: flex; height: 40px; min-height: 40px; align-items: center; justify-content: flex-end; padding: 0 18px 0 0; line-height: 1.35; text-align: right; }
+.is-create-route .selected-destination { width: auto; margin-left: 138px; }
+.is-create-route .cargo-table-heading, .is-create-route .cost-estimate-section .order-section-heading { margin-bottom: 16px; }
.order-form { width: min(100%, 1000px); margin: 0; padding: 0 0 12px; }
.order-form.is-dialog-order-form { width: 100%; max-width: none; }
.is-dialog-order-form > .cargo-section, .is-dialog-order-form > .cost-estimate-section { width: 100%; max-width: none; }
@@ -2604,6 +2644,7 @@ async function searchOrders(model: QueryModel) {
.compact-transport-grid :deep(.el-form-item__label) { color: #4d5a6c; font-size: 13px; }
.shipping-form-flow { max-width: 900px; }
.prototype-order-form > .prototype-section:first-child { width: 100%; }
+.is-create-route .prototype-order-form > .prototype-section:first-child > .order-section-heading { margin-top: 0; }
.shipping-form-flow .prototype-form-row { margin-bottom: 10px; }
.shipping-form-flow .prototype-form-row--tabs { margin-bottom: 12px; }
.compact-transport-grid { display: grid; width: 100%; grid-template-columns: 1fr; gap: 0; margin: 6px 0 0; }