This commit is contained in:
2026-09-01 14:27:22 +08:00
parent e42d765f5c
commit 76604da31b
9 changed files with 33 additions and 9 deletions
@@ -3,6 +3,10 @@ import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
const source = readFileSync(resolve(process.cwd(), 'src/modules/customs/pages/CustomsCasesView.vue'), 'utf8')
describe('CustomsCasesView', () => {
it('uses a wide customer filter and compact status filter', () => {
expect(source).toContain("key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220")
expect(source).toContain("key: 'status', type: 'select', label: '状态', width: 160")
})
it('uses shared list and dialog components', () => { expect(source).toContain('QueryToolbar'); expect(source).toContain('DataTable'); expect(source).toContain('AppDialog'); expect(source).toContain("fixed: 'left'") })
it('supports detail, history and agent submission', () => { expect(source).toContain('getCustomsCase'); expect(source).toContain('submitCustomsCase'); expect(source).toContain('detail.history') })
it('selects an active customs supplier and submits its stable identity and name snapshot', () => {
@@ -23,7 +23,7 @@ const customers = ref<PlatformTenantResource[]>([]); const customersLoading = re
const customsAgents = ref<Supplier[]>([]); const customsAgentsLoading = ref(false); const customsAgentsError = ref('')
const filters = ref<QueryModel>({ customerId: '', status: '' }); const fields = computed<QueryField[]>(() => [
{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220, options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customer.tenantName, value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } },
{ key: 'status', type: 'select', label: '状态', options: customsCaseStatusOptions.map((option) => ({ ...option })) },
{ key: 'status', type: 'select', label: '状态', width: 160, options: customsCaseStatusOptions.map((option) => ({ ...option })) },
])
const columns = [{ key: 'actions', label: '操作', fixed: 'left', width: 175, slotName: 'actions', hideable: false, movable: false }, { prop: 'customsNo', label: '报关编号', minWidth: 145 }, { key: 'orderLink', label: '订单关联', minWidth: 120, formatter: (row: CustomsCaseResource) => associationLabel(row.orderId) }, { key: 'inboundLink', label: '入库单关联', minWidth: 120, formatter: (row: CustomsCaseResource) => associationLabel(row.inboundId) }, { prop: 'checklistCode', label: '资料清单', minWidth: 125 }, { prop: 'checklistVersionNo', label: '版本', width: 90 }, { prop: 'status', label: '状态', width: 110, slotName: 'status' }, { prop: 'updatedAt', label: '更新时间', minWidth: 160 }]
function associationLabel(value: string | null | undefined) { return value ? '已关联' : '未关联' }
@@ -82,4 +82,10 @@ describe('OceanBookingsView', () => {
expect(source).not.toContain('customer.tenantCode')
expect(source).toContain('@media(max-width:420px)')
})
it('keeps desktop filter widths proportional instead of stretching short status fields', () => {
expect(source).toContain("key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220")
expect(source).toContain("key: 'keyword', type: 'input', label: '关键词', placeholder: '订舱号/提单号/船名/航次', width: 260")
expect(source).toContain("key: 'status', type: 'select', label: '状态', width: 160")
})
})
@@ -36,7 +36,7 @@ const printBooking = ref<{ id: string; bookingNo?: string | null } | null>(null)
const fields = computed<QueryField[]>(() => [
{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220, options: activeCustomers.value.map((customer) => ({ label: customer.tenantName, value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } },
{ key: 'keyword', type: 'input', label: '关键词', placeholder: '订舱号/提单号/船名/航次', width: 260 },
{ key: 'status', type: 'select', label: '状态', options: oceanBookingStatusOptions },
{ key: 'status', type: 'select', label: '状态', width: 160, options: oceanBookingStatusOptions },
])
const columns = [
{ key: 'actions', label: '操作', fixed: 'left', width: 196, slotName: 'actions', hideable: false, movable: false },
@@ -3,6 +3,11 @@ import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
const source = readFileSync(resolve(process.cwd(), 'src/modules/port-schedules/pages/PortSchedulesView.vue'), 'utf8')
describe('PortSchedulesView', () => {
it('uses calibrated desktop widths for customer, composite keyword and validity', () => {
expect(source).toContain("key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220")
expect(source).toContain("key: 'keyword', type: 'input', label: '关键词', placeholder: '船期号/船名/航次/港口', width: 260")
expect(source).toContain("key: 'expired', type: 'select', label: '有效性', width: 160")
})
it('uses standard list components and a left action column', () => {
expect(source).toContain('QueryToolbar')
expect(source).toContain('DataTable')
@@ -21,7 +21,7 @@ const access = useAccessPreviewStore()
const rows = ref<PortScheduleView[]>([]); const loading = ref(false); const error = ref<ApiErrorDetails | null>(null)
const page = ref(1); const pageSize = ref(20); const total = ref(0)
const query = reactive<QueryModel>({ customerId: '', keyword: '', expired: '' })
const fields = computed<QueryField[]>(() => [{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220, options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customerLabel(customer), value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } }, { key: 'keyword', type: 'input', label: '关键词', placeholder: '船期号/船名/航次/港口', width: 230 }, { key: 'expired', type: 'select', label: '有效性', options: [{ label: '有效', value: 'false' }, { label: '已过期', value: 'true' }] }])
const fields = computed<QueryField[]>(() => [{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220, options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customerLabel(customer), value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } }, { key: 'keyword', type: 'input', label: '关键词', placeholder: '船期号/船名/航次/港口', width: 260 }, { key: 'expired', type: 'select', label: '有效性', width: 160, options: [{ label: '有效', value: 'false' }, { label: '已过期', value: 'true' }] }])
const columns = [
{ key: 'actions', label: '操作', fixed: 'left', width: 165, slotName: 'actions', hideable: false, movable: false },
{ prop: 'schedule.scheduleNo', label: '船期编号', minWidth: 145 }, { prop: 'schedule.sourceName', label: '信息来源', minWidth: 130 },
@@ -145,4 +145,10 @@ describe('TruckAppointmentsView', () => {
expect(source).not.toContain("truck-appointment:view')\" link")
expect(source).toContain(':total="total" stripe preference-key="trucking-appointments"')
})
it('uses compact status/type filters and a wider composite keyword field', () => {
expect(source).toContain("key: 'keyword', type: 'input', label: '关键词', placeholder: '派车单号、车牌号、运输公司', width: 280")
expect(source).toContain("key: 'status', type: 'select', label: '状态', placeholder: '全部状态', width: 160")
expect(source).toContain("key: 'containerType', type: 'select', label: '柜型', placeholder: '全部柜型', width: 160")
})
})
@@ -18,9 +18,9 @@ const router = useRouter(); const rows = ref<TruckAppointmentResource[]>([]); co
const access = useAccessPreviewStore()
const filters = ref({ keyword: '', status: '' as TruckAppointmentStatus | '', containerBookingId: '', containerType: '' }); const applied = ref({ ...filters.value })
const fields = computed<QueryField[]>(() => [
{ key: 'keyword', type: 'input', label: '关键词', placeholder: '派车单号、车牌号、运输公司' },
{ key: 'status', type: 'select', label: '状态', placeholder: '全部状态', options: TRUCK_APPOINTMENT_STATUSES.map((value) => ({ value, label: truckAppointmentStatusLabels[value] })) },
{ key: 'containerType', type: 'select', label: '柜型', placeholder: '全部柜型', options: [
{ key: 'keyword', type: 'input', label: '关键词', placeholder: '派车单号、车牌号、运输公司', width: 280 },
{ key: 'status', type: 'select', label: '状态', placeholder: '全部状态', width: 160, options: TRUCK_APPOINTMENT_STATUSES.map((value) => ({ value, label: truckAppointmentStatusLabels[value] })) },
{ key: 'containerType', type: 'select', label: '柜型', placeholder: '全部柜型', width: 160, options: [
{ value: '20GP', label: '20GP' }, { value: '40GP', label: '40GP' }, { value: '40HC', label: '40HC' },
] },
])