This commit is contained in:
2026-10-08 20:25:25 +08:00
parent 115461683b
commit c90a191d83
2 changed files with 32 additions and 2 deletions
@@ -2,6 +2,7 @@ import ElementPlus, { ElCheckbox, ElInput, ElPagination, ElSelect } from 'elemen
import { flushPromises, mount, type VueWrapper } from '@vue/test-utils' import { flushPromises, mount, type VueWrapper } from '@vue/test-utils'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import OutboundsView from './OutboundsView.vue' import OutboundsView from './OutboundsView.vue'
import { listPlatformTenants } from '@/modules/iam'
const api = vi.hoisted(() => ({ candidates: vi.fn(), create: vi.fn(), warehouses: vi.fn() })) const api = vi.hoisted(() => ({ candidates: vi.fn(), create: vi.fn(), warehouses: vi.fn() }))
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => true }) })) vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => true }) }))
@@ -48,6 +49,7 @@ async function selectBothPages() {
describe('outbound candidate search and selection', () => { describe('outbound candidate search and selection', () => {
beforeEach(() => { beforeEach(() => {
vi.mocked(listPlatformTenants).mockReset().mockResolvedValue({ records: [], page: 1, size: 200, total: 0, pages: 0 })
vi.stubGlobal('ResizeObserver', class { observe() {} unobserve() {} disconnect() {} }) vi.stubGlobal('ResizeObserver', class { observe() {} unobserve() {} disconnect() {} })
vi.stubGlobal('localStorage', { getItem: () => null, setItem: () => undefined, removeItem: () => undefined }) vi.stubGlobal('localStorage', { getItem: () => null, setItem: () => undefined, removeItem: () => undefined })
api.candidates.mockReset().mockResolvedValue(fixtures.map(item => ({ ...item }))) api.candidates.mockReset().mockResolvedValue(fixtures.map(item => ({ ...item })))
@@ -59,6 +61,24 @@ describe('outbound candidate search and selection', () => {
}) })
afterEach(() => { wrapper?.unmount(); vi.unstubAllGlobals() }) afterEach(() => { wrapper?.unmount(); vi.unstubAllGlobals() })
it('offers enabled customers from later pages when creating a return outbound', async () => {
vi.mocked(listPlatformTenants)
.mockResolvedValueOnce({ records: [{ id: 'customer-a', tenantName: '柏悦物流demo2', status: 'ACTIVE' }], page: 1, size: 200, total: 201, pages: 2 } as Awaited<ReturnType<typeof listPlatformTenants>>)
.mockResolvedValueOnce({ records: [{ id: 'customer-b', tenantName: '柏悦物流', status: 'ACTIVE' }], page: 2, size: 200, total: 201, pages: 2 } as Awaited<ReturnType<typeof listPlatformTenants>>)
await openCreate()
expect(listPlatformTenants).toHaveBeenNthCalledWith(1, { page: 1, size: 200, status: 'ACTIVE' })
expect(listPlatformTenants).toHaveBeenNthCalledWith(2, { page: 2, size: 200, status: 'ACTIVE' })
const type = wrapper.findComponent({ name: 'ElRadioGroup' })
type.vm.$emit('update:modelValue', 'RETURN_OUTBOUND')
type.vm.$emit('change', 'RETURN_OUTBOUND')
await flushPromises()
const customer = wrapper.findAllComponents(ElSelect).find(select => select.props('placeholder') === '请选择客户')!
expect(customer.findAllComponents({ name: 'ElOption' }).map(option => option.props('label'))).toEqual(['柏悦物流demo2', '柏悦物流'])
customer.vm.$emit('update:modelValue', 'customer-b')
await flushPromises()
expect(customer.props('modelValue')).toBe('customer-b')
})
it('selects and deselects the current page while preserving other pages, then submits all selected quantities', async () => { it('selects and deselects the current page while preserving other pages, then submits all selected quantities', async () => {
await openCreate() await openCreate()
expect(wrapper.text()).toContain('可出毛重(kg)') expect(wrapper.text()).toContain('可出毛重(kg)')
@@ -102,15 +102,25 @@ const fields: QueryField[] = [{ key: 'documentNo', type: 'input', label: '出库
async function load(model: QueryModel = filters.value) { Object.assign(filters.value, model); loading.value = true; error.value = null; try { const result = await listOutbounds({ page: page.value, size: pageSize.value, documentNo: String(filters.value.documentNo || '').trim() || undefined, lxCode: String(filters.value.lxCode || '').trim() || undefined, warehouseId: String(filters.value.warehouseId || '').trim() || undefined, status: String(filters.value.status || '').trim() || undefined, outboundType: String(filters.value.outboundType || '').trim() || undefined }); rows.value = result.records.map((row) => ({ ...row, createdAt: formatOverseasDateTime(row.createdAt) })); total.value = result.total } catch (cause) { error.value = getApiErrorDetails(cause, '出库单列表加载失败') } finally { loading.value = false } } async function load(model: QueryModel = filters.value) { Object.assign(filters.value, model); loading.value = true; error.value = null; try { const result = await listOutbounds({ page: page.value, size: pageSize.value, documentNo: String(filters.value.documentNo || '').trim() || undefined, lxCode: String(filters.value.lxCode || '').trim() || undefined, warehouseId: String(filters.value.warehouseId || '').trim() || undefined, status: String(filters.value.status || '').trim() || undefined, outboundType: String(filters.value.outboundType || '').trim() || undefined }); rows.value = result.records.map((row) => ({ ...row, createdAt: formatOverseasDateTime(row.createdAt) })); total.value = result.total } catch (cause) { error.value = getApiErrorDetails(cause, '出库单列表加载失败') } finally { loading.value = false } }
function outboundTypeLabel(value?: string | null) { return value === 'WAREHOUSE_TRANSFER_OUTBOUND' ? '仓储转运出库' : value === 'ONE_CLICK_DROPSHIP' ? '一件代发出库' : value === 'RETURN_OUTBOUND' ? '退货出库' : value === 'DISPATCH_DELIVERY' ? '派送出库' : value || '—' } function outboundTypeLabel(value?: string | null) { return value === 'WAREHOUSE_TRANSFER_OUTBOUND' ? '仓储转运出库' : value === 'ONE_CLICK_DROPSHIP' ? '一件代发出库' : value === 'RETURN_OUTBOUND' ? '退货出库' : value === 'DISPATCH_DELIVERY' ? '派送出库' : value || '—' }
async function loadCustomerOptions() {
const records: PlatformTenantResource[] = []
let page = 1
while (true) {
const result = await listPlatformTenants({ page, size: 200, status: 'ACTIVE' })
records.push(...result.records)
if (page >= result.pages || !result.records.length) return records
page += 1
}
}
async function loadInventoryOptions() { async function loadInventoryOptions() {
inventoryLoading.value = true inventoryLoading.value = true
try { try {
const [tenants, warehouses, fbaWarehouses] = await Promise.allSettled([ const [tenants, warehouses, fbaWarehouses] = await Promise.allSettled([
listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' }), loadCustomerOptions(),
listPlatformWarehouses({ page: 1, size: 200, warehouseType: 'OVERSEAS', status: 'ACTIVE' }), listPlatformWarehouses({ page: 1, size: 200, warehouseType: 'OVERSEAS', status: 'ACTIVE' }),
listPlatformWarehouses({ page: 1, size: 200, warehouseType: 'FBA', status: 'ACTIVE' }), listPlatformWarehouses({ page: 1, size: 200, warehouseType: 'FBA', status: 'ACTIVE' }),
]) ])
if (tenants.status === 'fulfilled') tenantOptions.value = tenants.value.records if (tenants.status === 'fulfilled') tenantOptions.value = tenants.value
else ElMessage.error(getApiErrorDetails(tenants.reason, '客户列表加载失败').message) else ElMessage.error(getApiErrorDetails(tenants.reason, '客户列表加载失败').message)
if (warehouses.status === 'fulfilled') { if (warehouses.status === 'fulfilled') {
warehouseOptionsSource.value = warehouses.value.records warehouseOptionsSource.value = warehouses.value.records