生产更新:同步已提交的海外仓分析及业务修复(2026-10-16) #20
@@ -6,6 +6,7 @@ import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import {
|
||||
changeRelabelOrderStatus,
|
||||
createRelabelOrder,
|
||||
getRelabelOrder,
|
||||
listRelabelOrders,
|
||||
listRelabelWarehouseOptions,
|
||||
} from '../api/relabelOrders'
|
||||
@@ -18,6 +19,7 @@ vi.mock('@/modules/iam', () => ({ listPlatformTenants: vi.fn() }))
|
||||
vi.mock('../api/relabelOrders', () => ({
|
||||
changeRelabelOrderStatus: vi.fn(),
|
||||
createRelabelOrder: vi.fn(),
|
||||
getRelabelOrder: vi.fn(),
|
||||
listRelabelOrders: vi.fn(),
|
||||
listRelabelWarehouseOptions: vi.fn(),
|
||||
}))
|
||||
@@ -48,6 +50,7 @@ describe('RelabelOrdersView', () => {
|
||||
vi.mocked(listRelabelWarehouseOptions).mockReset()
|
||||
vi.mocked(createRelabelOrder).mockReset()
|
||||
vi.mocked(changeRelabelOrderStatus).mockReset()
|
||||
vi.mocked(getRelabelOrder).mockReset().mockResolvedValue({ application: { relabelNo: 'RL-1' }, items: [], history: [] } as never)
|
||||
})
|
||||
|
||||
it('loads shared receiving warehouse options independently from the selected customer', async () => {
|
||||
@@ -133,6 +136,27 @@ describe('RelabelOrdersView', () => {
|
||||
expect(labels).toEqual(['审核通过', '已驳回'])
|
||||
})
|
||||
|
||||
it('loads the full detail before opening audit so item fields are echoed', async () => {
|
||||
vi.mocked(listRelabelOrders).mockResolvedValueOnce({
|
||||
records: [{ id: '1', relabelNo: 'RL-1', customerOrderNo: 'CO-1', skuCodes: 'SKU-OLD', totalPackageCount: 2, chargeAmount: 0.01, status: 'PENDING_REVIEW' }],
|
||||
page: 1, size: 10, total: 1, pages: 1,
|
||||
})
|
||||
vi.mocked(getRelabelOrder).mockResolvedValueOnce({
|
||||
application: { relabelNo: 'RL-1', customerOrderNo: 'CO-1', chargeAmount: 12.5 },
|
||||
remark: '请按新标签处理',
|
||||
items: [{ skuCode: 'SKU-NEW', productNameZh: '中文商品', totalPackageCount: 3, shipmentNo: 'SHIP-9', newSkuCode: 'NEW-SKU-9', labelRequirement: '换箱唛和SKU标' }],
|
||||
history: [],
|
||||
} as never)
|
||||
const wrapper = mount(RelabelOrdersView, { attachTo: document.body, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
await wrapper.findAll('button').find((button) => button.text().trim() === '审核')!.trigger('click')
|
||||
await flushPromises()
|
||||
expect(formItem(wrapper, '商品SKU').findComponent({ name: 'ElInput' }).props('modelValue')).toBe('SKU-NEW')
|
||||
expect(formItem(wrapper, '中文品名').findComponent({ name: 'ElInput' }).props('modelValue')).toBe('中文商品')
|
||||
expect(formItem(wrapper, '货件号').findComponent({ name: 'ElInput' }).props('modelValue')).toBe('SHIP-9')
|
||||
expect(formItem(wrapper, '新SKU').findComponent({ name: 'ElInput' }).props('modelValue')).toBe('NEW-SKU-9')
|
||||
})
|
||||
|
||||
it('passes the relabel order number search to the backend', async () => {
|
||||
const wrapper = mount(RelabelOrdersView, { attachTo: document.body, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
|
||||
@@ -14,7 +14,7 @@ import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import { changeRelabelOrderStatus, createRelabelOrder, listRelabelOrders, listRelabelWarehouseOptions, type RelabelWarehouseOptionDto } from '../api/relabelOrders'
|
||||
import { changeRelabelOrderStatus, createRelabelOrder, getRelabelOrder, listRelabelOrders, listRelabelWarehouseOptions, type RelabelWarehouseOptionDto } from '../api/relabelOrders'
|
||||
import { overseasWarehousePermissions as permission } from '../permissions'
|
||||
import { formatOverseasDateTime, relabelBusinessStatusLabel } from '../lastMilePresentation'
|
||||
import type { RelabelOrderListItem } from '../types'
|
||||
@@ -55,6 +55,7 @@ const columns: DataTableColumn[] = [
|
||||
const dialogOpen = ref(false)
|
||||
const dialogMode = ref<'create' | 'edit'>('create')
|
||||
const submitting = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const editSourceStatus = ref('')
|
||||
const form = reactive({ orderNo: '', customerId: '', relatedOrderNo: '', sku: '', productName: '', cartons: undefined as number | undefined, budgetTotal: undefined as number | undefined, status: 'PENDING_PROCESSING', labelRequirement: '', relabelCost: undefined as number | undefined, remark: '', warehouseId: '', labelDeadline: '', contactName: '', contactPhone: '', shipmentNo: '', newSkuCode: '' })
|
||||
const createIdempotencyKey = ref('')
|
||||
@@ -73,7 +74,7 @@ function openPackingPlan() {
|
||||
if (customerIds.length > 1) { ElMessage.warning('合箱请选择同一客户的退货库存'); return }
|
||||
void router.push({ name: 'overseas-return-inventory', query: { packing: '1', ...(customerIds[0] ? { customerId: customerIds[0] } : {}) } })
|
||||
}
|
||||
function openForm(mode: 'create' | 'edit', source?: object) {
|
||||
async function openForm(mode: 'create' | 'edit', source?: object) {
|
||||
const row = source as RelabelOrderListItem | undefined
|
||||
dialogMode.value = mode
|
||||
Object.assign(form, { orderNo: '', customerId: '', relatedOrderNo: '', sku: '', productName: '', cartons: undefined, budgetTotal: undefined, status: 'PENDING_PROCESSING', labelRequirement: '', relabelCost: undefined, remark: '', warehouseId: '', labelDeadline: '', contactName: '', contactPhone: '', shipmentNo: '', newSkuCode: '' })
|
||||
@@ -89,6 +90,28 @@ function openForm(mode: 'create' | 'edit', source?: object) {
|
||||
void loadWarehouses()
|
||||
}
|
||||
dialogOpen.value = true
|
||||
if (mode === 'edit' && row?.orderNo) {
|
||||
detailLoading.value = true
|
||||
try {
|
||||
const detail = await getRelabelOrder(String(row.orderNo))
|
||||
const item = detail.items?.[0]
|
||||
Object.assign(form, {
|
||||
orderNo: String(detail.application?.relabelNo || row.orderNo || ''),
|
||||
relatedOrderNo: String(detail.application?.lastlegOrderNo || detail.application?.customerOrderNo || row.relatedOrderNo || ''),
|
||||
sku: String(item?.skuCode || row.sku || ''),
|
||||
productName: String(item?.productNameZh || row.productName || ''),
|
||||
cartons: optionalNumber(item?.totalPackageCount ?? detail.application?.totalPackageCount ?? row.cartons),
|
||||
labelRequirement: String(item?.labelRequirement || row.labelRequirement || ''),
|
||||
shipmentNo: String(item?.shipmentNo || ''),
|
||||
newSkuCode: String(item?.newSkuCode || ''),
|
||||
relabelCost: optionalNumber(detail.application?.chargeAmount ?? row.relabelCost),
|
||||
remark: String(detail.remark || detail.application?.reviewRemark || row.remark || ''),
|
||||
})
|
||||
} catch (error) {
|
||||
ElMessage.error(getApiErrorDetails(error, '换标单详情加载失败,请重试').message)
|
||||
dialogOpen.value = false
|
||||
} finally { detailLoading.value = false }
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCustomers() {
|
||||
@@ -212,7 +235,7 @@ watch(dialogOpen, (open) => { if (!open) createIdempotencyKey.value = '' })
|
||||
</DataTable></section>
|
||||
</ListPageLayout>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="dialogOpen" :title="dialogMode === 'create' ? '新增换标单' : '审核换标单'" width="min(760px, calc(100vw - 28px))" :confirm-text="dialogMode === 'create' ? '保存换标单' : '提交审核'" :confirm-loading="submitting" @confirm="submitForm">
|
||||
<AppDialog class="admin-density-dialog" v-model="dialogOpen" :title="dialogMode === 'create' ? '新增换标单' : '审核换标单'" width="min(760px, calc(100vw - 28px))" :confirm-text="dialogMode === 'create' ? '保存换标单' : '提交审核'" :confirm-loading="submitting || detailLoading" :confirm-disabled="detailLoading" @confirm="submitForm">
|
||||
<el-form class="density-form" label-position="top"><h3>订单信息</h3><el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="换标单号"><el-input :model-value="dialogMode === 'create' ? '系统自动生成' : form.orderNo || '—'" readonly /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联订单" required><el-input v-model="form.relatedOrderNo" :disabled="dialogMode === 'edit'" placeholder="请输入关联订单号" /></el-form-item></el-col>
|
||||
|
||||
Reference in New Issue
Block a user