优化
This commit is contained in:
Vendored
-2
@@ -23,8 +23,6 @@ declare module 'vue' {
|
|||||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||||
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
|
||||||
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||||
|
|||||||
@@ -48,6 +48,17 @@ test('exposes real list, draft, submit, and detail workflow entries without canc
|
|||||||
assert.doesNotMatch(source, /cancelOrder|取消订单/)
|
assert.doesNotMatch(source, /cancelOrder|取消订单/)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('copies an order into the dedicated create page without reusing order identity', () => {
|
||||||
|
assert.match(source, /key: 'copy', label: '一键复制'/)
|
||||||
|
assert.match(source, /name: 'first-leg-order-create'[\s\S]*copyFrom: order\.id/)
|
||||||
|
assert.match(source, /order\.status === 'DRAFT' \? \{ copyDraft: '1' \}/)
|
||||||
|
assert.match(source, /sourceIsDraft \? await store\.loadDraftDetail\(id\) : await store\.loadDetail\(id\)/)
|
||||||
|
assert.match(source, /const draft = draftFromOrder\(order\)[\s\S]*inboundCode: ''/)
|
||||||
|
assert.match(source, /id: `copied-cargo-\$\{\+\+cargoSequence\}`/)
|
||||||
|
assert.match(source, /editingId\.value = undefined/)
|
||||||
|
assert.match(source, /订单数据已复制,请核对后提交/)
|
||||||
|
})
|
||||||
|
|
||||||
test('keeps create-page support errors scoped to create-page requests', () => {
|
test('keeps create-page support errors scoped to create-page requests', () => {
|
||||||
assert.match(source, /if \(!isCreatePage\.value && store\.draftLoadError\)/)
|
assert.match(source, /if \(!isCreatePage\.value && store\.draftLoadError\)/)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ const isCreatePage = computed(() => props.createPage)
|
|||||||
const isDetailPage = computed(() => props.detailPage)
|
const isDetailPage = computed(() => props.detailPage)
|
||||||
const routeDraftId = computed(() => typeof route.params.draftId === 'string' ? route.params.draftId : '')
|
const routeDraftId = computed(() => typeof route.params.draftId === 'string' ? route.params.draftId : '')
|
||||||
const routeDetailId = computed(() => typeof route.params.orderId === 'string' ? route.params.orderId : '')
|
const routeDetailId = computed(() => typeof route.params.orderId === 'string' ? route.params.orderId : '')
|
||||||
|
const routeCopySourceId = computed(() => typeof route.query.copyFrom === 'string' ? route.query.copyFrom : '')
|
||||||
|
const routeCopySourceIsDraft = computed(() => route.query.copyDraft === '1')
|
||||||
const canViewCompanyProfile = computed(() => auth.hasPermission('company:profile:view'))
|
const canViewCompanyProfile = computed(() => auth.hasPermission('company:profile:view'))
|
||||||
const companyAuditLoaded = ref(false)
|
const companyAuditLoaded = ref(false)
|
||||||
const companySubmissionBlocked = computed(() => companyAuditLoaded.value && tenantStore.company.auditStatus !== 'ACTIVE')
|
const companySubmissionBlocked = computed(() => companyAuditLoaded.value && tenantStore.company.auditStatus !== 'ACTIVE')
|
||||||
@@ -197,6 +199,7 @@ const editorOpen = ref(false)
|
|||||||
const orderFormRef = ref<FormInstance>()
|
const orderFormRef = ref<FormInstance>()
|
||||||
const editingId = ref<string>()
|
const editingId = ref<string>()
|
||||||
const openingEditor = ref(false)
|
const openingEditor = ref(false)
|
||||||
|
const copyingOrderId = ref('')
|
||||||
const detailId = ref<string>()
|
const detailId = ref<string>()
|
||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const detailLoading = ref(false)
|
const detailLoading = ref(false)
|
||||||
@@ -616,6 +619,7 @@ async function loadPageData() {
|
|||||||
if (addressResult.status === 'rejected') supportingDataErrors.value.push(`企业地址簿加载失败:${errorMessage(addressResult.reason)}`)
|
if (addressResult.status === 'rejected') supportingDataErrors.value.push(`企业地址簿加载失败:${errorMessage(addressResult.reason)}`)
|
||||||
await autofillWarehouseSelections()
|
await autofillWarehouseSelections()
|
||||||
if (isCreatePage.value && routeDraftId.value) await loadRouteDraft(routeDraftId.value)
|
if (isCreatePage.value && routeDraftId.value) await loadRouteDraft(routeDraftId.value)
|
||||||
|
else if (isCreatePage.value && routeCopySourceId.value) await loadCopiedOrder(routeCopySourceId.value, routeCopySourceIsDraft.value)
|
||||||
if (isDetailPage.value && routeDetailId.value) await loadDetailPage(routeDetailId.value)
|
if (isDetailPage.value && routeDetailId.value) await loadDetailPage(routeDetailId.value)
|
||||||
supportingDataLoading.value = false
|
supportingDataLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -633,6 +637,39 @@ async function loadRouteDraft(id: string) {
|
|||||||
markEditorClean()
|
markEditorClean()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadCopiedOrder(id: string, sourceIsDraft: boolean) {
|
||||||
|
try {
|
||||||
|
const detailedOrder = sourceIsDraft ? await store.loadDraftDetail(id) : await store.loadDetail(id)
|
||||||
|
const draft = copyDraftFromOrder(detailedOrder)
|
||||||
|
if (draft.destinationType !== 'PRIVATE') await loadDestinationWarehouses(draft.destinationType)
|
||||||
|
|
||||||
|
const warehouseAvailable = availableWarehouses.value.some((item) => item.id === draft.receivingWarehouseId)
|
||||||
|
if (!warehouseAvailable) {
|
||||||
|
draft.receivingWarehouseId = ''
|
||||||
|
draft.channelCode = ''
|
||||||
|
draft.channelName = ''
|
||||||
|
}
|
||||||
|
if (draft.destinationType !== 'PRIVATE') {
|
||||||
|
const destinationAvailable = store.warehouses.some((item) => item.id === draft.destinationWarehouseId && item.warehouseType === draft.destinationType)
|
||||||
|
if (!destinationAvailable) {
|
||||||
|
draft.destinationWarehouseId = ''
|
||||||
|
draft.destinationWarehouseName = ''
|
||||||
|
draft.amazonWarehouseCode = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editingId.value = undefined
|
||||||
|
replaceForm(draft)
|
||||||
|
await Promise.all(form.items.map(ensureProductImagePreview))
|
||||||
|
if (warehouseAvailable) await loadSelectedWarehouse(draft.receivingWarehouseId)
|
||||||
|
resetEditorValidation()
|
||||||
|
markEditorClean()
|
||||||
|
ElMessage.success('订单数据已复制,请核对后提交')
|
||||||
|
} catch (error) {
|
||||||
|
supportingDataErrors.value.push(`复制订单数据失败:${errorMessage(error)}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function loadDestinationWarehouses(type: 'FBA' | 'OVERSEAS' | 'PRIVATE') {
|
async function loadDestinationWarehouses(type: 'FBA' | 'OVERSEAS' | 'PRIVATE') {
|
||||||
if (type === 'PRIVATE') return
|
if (type === 'PRIVATE') return
|
||||||
destinationWarehousesLoading.value = true
|
destinationWarehousesLoading.value = true
|
||||||
@@ -833,6 +870,21 @@ function draftFromOrder(order: FirstLegOrder): FirstLegOrderDraft {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyDraftFromOrder(order: FirstLegOrder): FirstLegOrderDraft {
|
||||||
|
const draft = draftFromOrder(order)
|
||||||
|
return {
|
||||||
|
...draft,
|
||||||
|
inboundCode: '',
|
||||||
|
items: draft.items.map((item) => ({
|
||||||
|
...item,
|
||||||
|
id: `copied-cargo-${++cargoSequence}`,
|
||||||
|
productImagePreviewUrl: '',
|
||||||
|
productImageUploading: false,
|
||||||
|
productImageError: '',
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function selectChannel(code: string) {
|
function selectChannel(code: string) {
|
||||||
const channel = channelOptions.value.find((item) => item.channelCode === code)
|
const channel = channelOptions.value.find((item) => item.channelCode === code)
|
||||||
form.channelName = channel?.channelName ?? ''
|
form.channelName = channel?.channelName ?? ''
|
||||||
@@ -1225,6 +1277,9 @@ function getOrderRowActions(row: object): TableAction[] {
|
|||||||
const actions: TableAction[] = [
|
const actions: TableAction[] = [
|
||||||
{ key: 'detail', label: '详情', run: () => openDetail(order) },
|
{ key: 'detail', label: '详情', run: () => openDetail(order) },
|
||||||
]
|
]
|
||||||
|
if (canCreateOrder.value) {
|
||||||
|
actions.push({ key: 'copy', label: '一键复制', loading: copyingOrderId.value === order.id, run: () => copyOrder(order) })
|
||||||
|
}
|
||||||
if (canConfirmInboundFee.value && order.businessSummary.customerFeeConfirmationRequired) {
|
if (canConfirmInboundFee.value && order.businessSummary.customerFeeConfirmationRequired) {
|
||||||
actions.push({ key: 'fee', label: '确认计费重', run: () => openFeeConfirmation(order) })
|
actions.push({ key: 'fee', label: '确认计费重', run: () => openFeeConfirmation(order) })
|
||||||
}
|
}
|
||||||
@@ -1237,6 +1292,22 @@ function getOrderRowActions(row: object): TableAction[] {
|
|||||||
return actions
|
return actions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyOrder(order: FirstLegOrder) {
|
||||||
|
if (copyingOrderId.value || !canCreateOrder.value) return
|
||||||
|
copyingOrderId.value = order.id
|
||||||
|
try {
|
||||||
|
await router.push({
|
||||||
|
name: 'first-leg-order-create',
|
||||||
|
query: {
|
||||||
|
copyFrom: order.id,
|
||||||
|
...(order.status === 'DRAFT' ? { copyDraft: '1' } : {}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
copyingOrderId.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function openCreate() {
|
async function openCreate() {
|
||||||
if (availableWarehouses.value.length === 0) {
|
if (availableWarehouses.value.length === 0) {
|
||||||
ElMessage.warning(supportingDataLoading.value
|
ElMessage.warning(supportingDataLoading.value
|
||||||
@@ -2061,7 +2132,7 @@ async function searchOrders(model: QueryModel) {
|
|||||||
</div>
|
</div>
|
||||||
<el-alert v-if="isCreatePage && !supportingDataLoading && availableWarehouses.length === 0" title="当前没有可用的平台收货仓" description="请联系平台维护并启用收货仓后再创建订单。" type="warning" :closable="false" show-icon />
|
<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">
|
<FirstLegOrderEditorShell v-model="editorOpen" :page="isCreatePage" :title="editingId ? '编辑订单草稿' : (routeCopySourceId ? '复制订单' : '创建订单')" :before-close="requestCloseEditor" @back="closeEditor">
|
||||||
<el-form ref="orderFormRef" v-loading="isCreatePage && supportingDataLoading" :model="form" :rules="orderFormRules" label-position="top" class="order-form prototype-order-form" :class="{ 'is-dialog-order-form': !isCreatePage }" scroll-to-error>
|
<el-form ref="orderFormRef" v-loading="isCreatePage && supportingDataLoading" :model="form" :rules="orderFormRules" label-position="top" class="order-form prototype-order-form" :class="{ 'is-dialog-order-form': !isCreatePage }" scroll-to-error>
|
||||||
<section class="order-form-section prototype-section">
|
<section class="order-form-section prototype-section">
|
||||||
<div class="order-section-heading"><div><h3>客户下单</h3><p>先选择货物如何送到国内收货仓,并填写本次运输安排。</p></div></div>
|
<div class="order-section-heading"><div><h3>客户下单</h3><p>先选择货物如何送到国内收货仓,并填写本次运输安排。</p></div></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user