This commit is contained in:
2026-08-11 19:35:28 +08:00
parent 886c7d3529
commit c690a30422
48 changed files with 935 additions and 171 deletions
@@ -7,6 +7,7 @@ import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.v
import DetailPageLayout from '@/shared/components/DetailPageLayout.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import StatusBadge from '@/shared/components/StatusBadge.vue'
import { loadingListStatusLabel } from '../status'
import type { ApiErrorDetails } from '@/shared/api/http'
import type { LoadingDetail, LoadingListMode, LoadingListSummary, PreloadSummary } from '../api/platformLoadingLists'
@@ -50,10 +51,6 @@ const title = computed(() => {
return `${props.mode === 'preload' ? '预装清单' : '装柜清单'} · ${number}`
})
function statusLabel(status?: string | null) {
return ({ WAIT_LOADING: '待装柜', EDITING: '预装柜中', LOADING: '拣货中', COMPLETED: '装柜完成' } as Record<string, string>)[status || ''] || status || '—'
}
function actionLabel(action: string) {
return ({
CREATE: '创建计划', ASSIGN: '分配货物', ADJUST: '调整货物', DELETE: '移除货物',
@@ -92,7 +89,7 @@ function formatNumber(value?: number | null, digits = 3) {
<div><span>仓库</span><strong>{{ summary.warehouseName || '—' }}</strong></div>
<div><span>集装箱号</span><strong>{{ summary.containerNo || '—' }}</strong></div>
<div><span>柜号</span><strong>{{ summary.internalContainerNo || '—' }}</strong></div>
<div><span>状态</span><StatusBadge :status="statusLabel(summary.status)" /></div>
<div><span>状态</span><StatusBadge :status="loadingListStatusLabel(summary.status)" /></div>
<template v-if="preloadSummary">
<div><span>船名 / 航次</span><strong>{{ preloadSummary.vesselName || '—' }} / {{ preloadSummary.voyageNo || '—' }}</strong></div>
<div><span>箱型</span><strong>{{ preloadSummary.containerType || '—' }}</strong></div>
@@ -132,7 +129,7 @@ function formatNumber(value?: number | null, digits = 3) {
<el-timeline-item v-for="history in detail.histories" :key="history.historyId" :timestamp="formatDateTime(history.occurredAt)" placement="top">
<div class="history-entry">
<strong>{{ actionLabel(history.actionType) }}</strong>
<span v-if="history.fromStatus || history.toStatus">{{ statusLabel(history.fromStatus) }} → {{ statusLabel(history.toStatus) }}</span>
<span v-if="history.fromStatus || history.toStatus">{{ loadingListStatusLabel(history.fromStatus) }} → {{ loadingListStatusLabel(history.toStatus) }}</span>
<p>{{ history.operatorName || history.operatorId }}<template v-if="history.operationReason"> · {{ history.operationReason }}</template></p>
</div>
</el-timeline-item>
@@ -40,11 +40,8 @@ describe('LoadingListsView', () => {
})
it('renders business labels instead of raw loading-plan status codes', () => {
expect(source).toContain("LOADING: '拣货中'")
expect(source).toContain("COMPLETED: '装柜完成'")
expect(source).toContain(':status="statusLabel(row.status)"')
expect(detailSource).toContain("EDITING: '预装柜中'")
expect(detailSource).toContain(':status="statusLabel(summary.status)"')
expect(source).toContain(':status="loadingListStatusLabel(row.status)"')
expect(detailSource).toContain(':status="loadingListStatusLabel(summary.status)"')
expect(detailSource).not.toContain(':status="summary.status"')
expect(source).not.toContain('仅装柜中允许修改')
})
@@ -70,8 +67,8 @@ describe('LoadingListsView', () => {
})
it('passes translated status text directly to the badge', () => {
expect(source).toContain('<StatusBadge :status="statusLabel(row.status)" />')
expect(source).toContain('<StatusBadge :status="loadingListStatusLabel(row.status)" />')
expect(source).not.toContain('<StatusBadge :status="row.status" />')
expect(detailSource).toContain('<StatusBadge :status="statusLabel(summary.status)" />')
expect(detailSource).toContain('<StatusBadge :status="loadingListStatusLabel(summary.status)" />')
})
})
@@ -13,6 +13,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 StatusBadge from '@/shared/components/StatusBadge.vue'
import { loadingListStatusLabel } from '../status'
import LoadingListDetailDrawer from './LoadingListDetailDrawer.vue'
import {
getConfirmedLoadingList,
@@ -110,10 +111,6 @@ function formatNumber(value?: number | null, digits = 3) {
return Number(value).toLocaleString('zh-CN', { maximumFractionDigits: digits })
}
function statusLabel(status?: string | null) {
return ({ WAIT_LOADING: '待装柜', EDITING: '预装柜中', LOADING: '拣货中', COMPLETED: '装柜完成' } as Record<string, string>)[status || ''] || status || '—'
}
function queryId(value: unknown) {
return typeof value === 'string' && /^[1-9]\d*$/.test(value) ? value : ''
}
@@ -310,7 +307,7 @@ onMounted(() => {
</template>
<template #customers="{ row }">{{ (row as PreloadSummary).customers.map((item) => item.customerName || item.accountId).join('、') || '—' }}</template>
<template #vesselVoyage="{ row }">{{ (row as PreloadSummary).vesselName || '—' }} / {{ (row as PreloadSummary).voyageNo || '—' }}</template>
<template #status="{ row }"><StatusBadge :status="statusLabel(row.status)" /></template>
<template #status="{ row }"><StatusBadge :status="loadingListStatusLabel(row.status)" /></template>
<template #grossWeight="{ row }">{{ formatNumber(row.totalGrossWeightKg) }}</template>
<template #netWeight="{ row }">{{ formatNumber((row as ConfirmedSummary).totalNetWeightKg) }}</template>
<template #volume="{ row }">{{ formatNumber(row.totalVolumeCbm) }}</template>
+1
View File
@@ -1,2 +1,3 @@
export * from './api/platformLoadingLists'
export { loadingListRoutes } from './routes'
export { loadingListStatusLabel } from './status'
+11
View File
@@ -0,0 +1,11 @@
import { describe, expect, it } from 'vitest'
import { loadingListStatusLabel } from './status'
describe('loading list status labels', () => {
it('translates known states and hides unknown backend enums', () => {
expect(loadingListStatusLabel('EDITING')).toBe('预装柜中')
expect(loadingListStatusLabel('COMPLETED')).toBe('装柜完成')
expect(loadingListStatusLabel('NEW_LOADING_STATE')).toBe('未知状态')
expect(loadingListStatusLabel(null)).toBe('—')
})
})
+11
View File
@@ -0,0 +1,11 @@
const loadingListStatusLabels: Record<string, string> = {
WAIT_LOADING: '待装柜',
EDITING: '预装柜中',
LOADING: '拣货中',
COMPLETED: '装柜完成',
}
export function loadingListStatusLabel(status: string | null | undefined) {
if (!status) return '—'
return loadingListStatusLabels[status] || '未知状态'
}