This commit is contained in:
2026-09-03 11:47:32 +08:00
parent 246cbc115e
commit d8b59ecca5
11 changed files with 314 additions and 119 deletions
@@ -1,4 +1,4 @@
import ElementPlus, { ElInputNumber, ElMessage, ElMessageBox } from 'element-plus'
import ElementPlus, { ElCheckboxButton, ElInputNumber, ElMessage, ElMessageBox } from 'element-plus'
import { AxiosError } from 'axios'
import { createPinia, setActivePinia } from 'pinia'
import { flushPromises, mount } from '@vue/test-utils'
@@ -48,7 +48,7 @@ vi.mock('../smartLoadingPlanGroups', () => ({ loadSmartLoadingPlanCoLoadGroups:
const container = {
id: '9007199254740993', planId: '9007199254740994', bookingNo: 'BK-1', cabinetNo: 'CB-1', containerNo: 'MSCU-1',
warehouseId: '8', warehouseName: '义乌仓', channelCode: 'ZBYHK', channelName: '美森正班海卡包税', containerType: '40HC', planStatus: 'EDITING' as const, version: 1,
billOfLadingNo: null, vesselName: null, voyageNo: null, shippingCompanyId: null, shippingCompanyName: null,
billOfLadingNo: null, vesselName: null, voyageNo: null, shippingCompanyId: '31', shippingCompanyName: '美森轮船',
departurePortCode: null, departurePortName: null, destinationPortCode: null, destinationPortName: null,
destinationWarehouseCode: 'LAX9', destinationWarehouseName: 'LAX9', capacityCbm: 76, maxWeightKg: 28000,
terminalTruckingCompanyId: null, terminalTruckingCompany: null, loadingAt: null, estimatedSailingAt: null, actualSailingAt: null,
@@ -88,7 +88,7 @@ describe('GlobalSmartLoadingView', () => {
expect(listSmartLoadingCandidates).toHaveBeenCalledWith(container.id, container.warehouseId)
expect(wrapper.text()).toContain('候选装柜明细')
expect(wrapper.text()).toContain('美森正班')
expect(wrapper.findAll('.channel-tabs [role="tab"]')).toHaveLength(9)
expect(wrapper.findAll('.channel-tags .el-checkbox-button')).toHaveLength(9)
expect(wrapper.text()).not.toContain('美森正班海卡包税')
expect(wrapper.text()).toContain('另一企业')
expect(wrapper.text()).toContain('MSCU-1 装柜方案')
@@ -105,7 +105,7 @@ describe('GlobalSmartLoadingView', () => {
it('uses the top-level container channel snapshot without expecting a nested snapshot', async () => {
vi.mocked(listContainers).mockResolvedValue({
records: [{ ...container, channelCode: 'EXX_RAIL_NY', channelName: '纽约EXX海铁' }],
records: [{ ...container, shippingCompanyId: '32', shippingCompanyName: 'EXX', channelCode: 'EXX_RAIL_NY', channelName: '纽约EXX海铁' }],
page: 1,
size: 100,
total: 1,
@@ -167,7 +167,7 @@ describe('GlobalSmartLoadingView', () => {
expect(wrapper.text()).not.toContain('真实柜号')
})
it('groups containers by channel and reloads candidates when the channel changes', async () => {
it('keeps nine fixed channel tags and allows selecting multiple channels', async () => {
const other = {
...container,
id: '9007199254740998',
@@ -185,17 +185,19 @@ describe('GlobalSmartLoadingView', () => {
expect(wrapper.findAll('.container-option')).toHaveLength(1)
expect(wrapper.text()).toContain('MSCU-1')
expect(wrapper.text()).not.toContain('MSCU-2')
expect(wrapper.text()).not.toContain('个柜次')
expect(wrapper.text()).toContain('柜子数量1 个')
const tab = wrapper.findAll('[role="tab"]').find((item) => item.text() === '合德')
expect(tab).toBeDefined()
await tab!.trigger('click')
expect(wrapper.findAll('.channel-tags .el-checkbox-button').map((item) => item.text())).toEqual([
'美森正班', '美森加班', 'EXX', '合德', '洛杉矶普船', '芝加哥普船', '休斯顿普船', '萨凡纳普船', '纽约普船海卡',
])
const hedeChannel = wrapper.findAllComponents(ElCheckboxButton).find((item) => item.text() === '合德')!
await hedeChannel.find('input').setValue(true)
await flushPromises()
expect(wrapper.findAll('.container-option')).toHaveLength(1)
expect(wrapper.findAll('.container-option')).toHaveLength(2)
expect(wrapper.text()).toContain('MSCU-1')
expect(wrapper.text()).toContain('MSCU-2')
expect(wrapper.text()).not.toContain('MSCU-1')
expect(listSmartLoadingCandidates).toHaveBeenLastCalledWith(other.id, other.warehouseId)
expect(wrapper.text()).toContain('柜子数量2 个')
})
it('merges detailed pricing channels into the same confirmed display group', async () => {
@@ -219,7 +221,7 @@ describe('GlobalSmartLoadingView', () => {
expect(wrapper.text()).not.toContain('美森正班海派')
})
it('isolates Yiwu and Dongguan containers when the host changes the warehouse', async () => {
it('moves the shipping warehouse into the query filters', async () => {
const dongguanContainer = {
...container,
id: '9007199254740998',
@@ -235,9 +237,9 @@ describe('GlobalSmartLoadingView', () => {
await flushPromises()
expect(wrapper.text()).toContain('MSCU-1')
expect(wrapper.text()).not.toContain('MSCU-DG')
expect(wrapper.text()).toContain('MSCU-DG')
await (wrapper.vm as unknown as { selectWarehouse: (code: string) => Promise<void> }).selectWarehouse('DONGGUAN')
wrapper.findComponent(QueryToolbar).vm.$emit('search', { warehouseId: '18', customerId: '', inboundCode: '', expectedArrivalRange: [], orderStatus: '' })
await flushPromises()
expect(wrapper.text()).toContain('MSCU-DG')
@@ -261,10 +263,10 @@ describe('GlobalSmartLoadingView', () => {
const wrapper = mount(GlobalSmartLoadingView, { global: { plugins: [ElementPlus] } })
await flushPromises()
await (wrapper.vm as unknown as { selectWarehouse: (code: string) => Promise<void> }).selectWarehouse('DONGGUAN')
wrapper.findComponent(QueryToolbar).vm.$emit('search', { warehouseId: '18', customerId: '', inboundCode: '', expectedArrivalRange: [], orderStatus: '' })
await flushPromises()
expect(wrapper.get('.channel-tabs [role="tab"][aria-selected="true"]').text()).toBe('美森正班')
expect(wrapper.find('.channel-tags .el-checkbox-button.is-checked').text()).toBe('美森正班')
expect(wrapper.findAll('.container-option')).toHaveLength(0)
expect(wrapper.text()).not.toContain('MSCU-DG-MAX')
expect(listSmartLoadingCandidates).toHaveBeenCalledTimes(1)
@@ -391,7 +393,8 @@ describe('GlobalSmartLoadingView', () => {
await flushPromises()
const fields = wrapper.findComponent(QueryToolbar).props('fields') as Array<{ key: string; options?: Array<{ label: string; value: string }> }>
expect(fields.map((field) => field.key)).toEqual(['customerId', 'inboundCode', 'expectedArrivalRange', 'orderStatus'])
expect(fields.map((field) => field.key)).toEqual(['warehouseId', 'customerId', 'inboundCode', 'expectedArrivalRange', 'orderStatus'])
expect(fields.find((field) => field.key === 'warehouseId')?.options).toEqual([{ label: '义乌仓', value: '8' }])
expect(source).not.toContain('目的仓')
expect(wrapper.text()).not.toContain('税率')
@@ -659,20 +662,23 @@ describe('GlobalSmartLoadingView', () => {
expect(source).toContain(':page-sizes="[20, 50, 100]"')
})
it('uses overflow-aware channel tabs with a compact right-aligned summary', () => {
it('uses nine fixed multi-select channel tags with a compact right-aligned summary', () => {
const source = readFileSync(resolve(process.cwd(), 'src/modules/container-loading/pages/GlobalSmartLoadingView.vue'), 'utf8')
expect(source).toContain('<el-tabs :model-value="activeChannelCode"')
expect(source).toContain('<el-tab-pane v-for="channel in channelTabs"')
expect(source).toContain(':label="channel.name"')
expect(source).not.toContain('channel.containerCount')
expect(source).toContain('class="compact-summary" aria-label="当前渠道装柜统计"')
expect(source).toContain('<el-checkbox-group :model-value="selectedChannelCodes"')
expect(source).toContain('<el-checkbox-button v-for="channel in channelOptions"')
expect(source).toContain('{{ channel.name }}')
expect(source).toContain("ElMessage.warning('至少选择一个渠道')")
expect(source).toContain('class="compact-summary" aria-label="已选渠道装柜统计"')
expect(source).toContain('<dt>候选明细</dt>')
expect(source).toContain('<dt>柜次</dt>')
expect(source).toContain('<dt>柜子数量</dt>')
expect(source).toContain('<dt>已装</dt>')
expect(source).toContain('<dt>总重量</dt>')
expect(source).toContain('<dt>总体积</dt>')
expect(source).toContain('.channel-tabs :deep(.el-tabs__content) { display: none; }')
expect(source).toContain('.channel-tags :deep(.el-checkbox-button__inner)')
expect(source).toContain('flex-wrap: nowrap; gap: 6px;')
expect(source).toContain('height: 34px; padding: 0 10px;')
expect(source).toContain('font-size: 13px; line-height: 32px;')
expect(source).not.toContain('class="summary-band"')
expect(source).toContain('class="capacity-grid"')
expect(source).toContain('智能推荐')