diff --git a/src/modules/first-leg/api/unifiedOrders.ts b/src/modules/first-leg/api/unifiedOrders.ts
index 8101851..d1e3d51 100644
--- a/src/modules/first-leg/api/unifiedOrders.ts
+++ b/src/modules/first-leg/api/unifiedOrders.ts
@@ -48,8 +48,14 @@ export interface MerchantUnifiedTransportSummary {
cabinetNo: string | null
vesselName: string | null
voyageNo: string | null
- sailingAt: string | null
- portArrivalAt: string | null
+ estimatedSailingAt: string | null
+ actualSailingAt: string | null
+ effectiveSailingAt: string | null
+ effectiveSailingAtEstimated: boolean | null
+ estimatedPortArrivalAt: string | null
+ actualPortArrivalAt: string | null
+ effectivePortArrivalAt: string | null
+ effectivePortArrivalAtEstimated: boolean | null
}
export interface MerchantUnifiedOrderRow {
diff --git a/src/modules/first-leg/store/firstLegOrders.test.mjs b/src/modules/first-leg/store/firstLegOrders.test.mjs
index 6f6c561..0985d23 100644
--- a/src/modules/first-leg/store/firstLegOrders.test.mjs
+++ b/src/modules/first-leg/store/firstLegOrders.test.mjs
@@ -1,11 +1,32 @@
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
+import { runInNewContext } from 'node:vm'
+import ts from 'typescript'
const storeSource = readFileSync(new URL('./firstLegOrders.ts', import.meta.url), 'utf8')
const apiSource = readFileSync(new URL('../api/firstLeg.ts', import.meta.url), 'utf8')
const unifiedApiSource = readFileSync(new URL('../api/unifiedOrders.ts', import.meta.url), 'utf8')
+test('renders estimated sailing from the current API without substituting actual departure', () => {
+ const mapper = storeSource.slice(storeSource.indexOf('function businessSummary('), storeSource.indexOf('\nconst unifiedActionLabels'))
+ const javascript = ts.transpileModule(mapper, { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText
+ const map = runInNewContext(`${javascript}; businessSummary`)
+ const transport = {
+ vesselName: 'REASSIGNED', voyageNo: 'V02',
+ estimatedSailingAt: '2026-10-07T08:00:00', actualSailingAt: '2026-10-08T09:00:00',
+ effectiveSailingAt: '2026-10-08T09:00:00', effectiveSailingAtEstimated: false,
+ estimatedPortArrivalAt: '2026-10-27T08:00:00', actualPortArrivalAt: null,
+ }
+ const mapped = map({ transport })
+ assert.equal(mapped.estimatedSailingAt, transport.estimatedSailingAt)
+ assert.equal(mapped.estimatedPortArrivalAt, transport.estimatedPortArrivalAt)
+ assert.equal(mapped.vesselName, 'REASSIGNED')
+ assert.equal(mapped.voyageNo, 'V02')
+ assert.equal(map().estimatedSailingAt, '')
+ assert.equal(map({ transport: null }).estimatedPortArrivalAt, '')
+})
+
test('maps the first-leg aggregate list fields without loading detail rows', () => {
assert.match(apiSource, /interface MerchantFirstLegOrderRow/)
assert.match(apiSource, /skuNos: string \| string\[\] \| null/)
diff --git a/src/modules/first-leg/store/firstLegOrders.ts b/src/modules/first-leg/store/firstLegOrders.ts
index 96ce9c5..edd4530 100644
--- a/src/modules/first-leg/store/firstLegOrders.ts
+++ b/src/modules/first-leg/store/firstLegOrders.ts
@@ -220,8 +220,8 @@ function businessSummary(summary?: MerchantUnifiedOrderRow): FirstLegOrder['busi
cabinetNo: summary?.transport?.cabinetNo ?? '',
vesselName: summary?.transport?.vesselName ?? '',
voyageNo: summary?.transport?.voyageNo ?? '',
- sailingAt: summary?.transport?.sailingAt ?? '',
- portArrivalAt: summary?.transport?.portArrivalAt ?? '',
+ estimatedSailingAt: summary?.transport?.estimatedSailingAt ?? '',
+ estimatedPortArrivalAt: summary?.transport?.estimatedPortArrivalAt ?? '',
inboundId: summary?.inboundId == null ? '' : String(summary.inboundId),
inboundVersion: summary?.inboundVersion ?? null,
inboundCode: summary?.inboundCode ?? '',
diff --git a/src/modules/first-leg/types/firstLegOrder.ts b/src/modules/first-leg/types/firstLegOrder.ts
index 3d7abce..21bf849 100644
--- a/src/modules/first-leg/types/firstLegOrder.ts
+++ b/src/modules/first-leg/types/firstLegOrder.ts
@@ -87,8 +87,8 @@ export interface FirstLegOrderBusinessSummary {
cabinetNo: string
vesselName: string
voyageNo: string
- sailingAt: string
- portArrivalAt: string
+ estimatedSailingAt: string
+ estimatedPortArrivalAt: string
inboundId: string
inboundVersion: number | null
inboundCode: string
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
index 7f227ab..5c6964e 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
+++ b/src/modules/first-leg/views/FirstLegOrdersView.test.mjs
@@ -729,7 +729,7 @@ test('shows authoritative warehouse, loading and sailing fields on desktop and n
}
assert.match(source, /businessSummary\.cabinetNo \|\| .*businessSummary\.containerNo/)
assert.match(source, /businessSummary\.vesselName.*businessSummary\.voyageNo/s)
- assert.match(source, /businessSummary\.sailingAt/)
+ assert.match(source, /businessSummary\.estimatedSailingAt/)
})
test('loads complete order detail before editing and rejects an unavailable historical warehouse', () => {
diff --git a/src/modules/first-leg/views/FirstLegOrdersView.vue b/src/modules/first-leg/views/FirstLegOrdersView.vue
index 5010781..af9dc8c 100644
--- a/src/modules/first-leg/views/FirstLegOrdersView.vue
+++ b/src/modules/first-leg/views/FirstLegOrdersView.vue
@@ -144,7 +144,7 @@ const selectableOrderColumns: DataTableColumn[] = [
{ key: 'expectedShipDate', label: '期望出运', width: 132, align: 'center', headerAlign: 'center', slotName: 'expectedShipDate' },
{ key: 'cabinetNo', label: '柜号 / 柜次', width: 150, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'cabinetNo' },
{ key: 'vesselVoyage', label: '船名 / 航次', width: 160, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'vesselVoyage' },
- { key: 'sailingAt', label: '预计船期', width: 164, align: 'center', headerAlign: 'center', slotName: 'sailingAt' },
+ { key: 'estimatedSailingAt', label: '预计船期', width: 164, align: 'center', headerAlign: 'center', slotName: 'estimatedSailingAt' },
{ key: 'createdAt', label: '创建时间', width: 164, align: 'center', headerAlign: 'center', slotName: 'createdAt' },
{ key: 'updatedAt', label: '更新时间', width: 164, align: 'center', headerAlign: 'center', slotName: 'updatedAt' },
]
@@ -572,7 +572,7 @@ const progressSummaryItems = computed(() => {
const cabinetProgressItems = computed(() => {
const summary = detailOrder.value?.businessSummary
if (!summary || (!summary.cabinetNo && !summary.containerNo)) return []
- return [{ cabinetId: summary.cabinetNo || summary.containerNo, cabinetNo: summary.cabinetNo || summary.containerNo, status: summary.loadingStatus || '待更新', vesselName: summary.vesselName, voyageNo: summary.voyageNo, sailingAt: summary.sailingAt }]
+ return [{ cabinetId: summary.cabinetNo || summary.containerNo, cabinetNo: summary.cabinetNo || summary.containerNo, status: summary.loadingStatus || '待更新', vesselName: summary.vesselName, voyageNo: summary.voyageNo, estimatedSailingAt: summary.estimatedSailingAt }]
})
const selectedWarehouse = computed(() => availableWarehouses.value.find((item) => item.id === form.receivingWarehouseId))
const selectedDestinationWarehouse = computed(() => store.warehouses.find((item) => item.id === form.destinationWarehouseId && item.warehouseType === form.destinationType))
@@ -2147,7 +2147,7 @@ async function searchOrders(model: QueryModel) {
{{ (row as FirstLegOrder).expectedDepartureDate ? formatDateTime((row as FirstLegOrder).expectedDepartureDate) : '-' }}
{{ displayListValue((row as FirstLegOrder).businessSummary.cabinetNo || (row as FirstLegOrder).businessSummary.containerNo) }}
{{ displayListValue([(row as FirstLegOrder).businessSummary.vesselName, (row as FirstLegOrder).businessSummary.voyageNo].filter(Boolean).join(' · ')) }}
- {{ (row as FirstLegOrder).businessSummary.sailingAt ? formatDateTime((row as FirstLegOrder).businessSummary.sailingAt) : '-' }}
+ {{ (row as FirstLegOrder).businessSummary.estimatedSailingAt ? formatDateTime((row as FirstLegOrder).businessSummary.estimatedSailingAt) : '-' }}
{{ formatDateTime((row as FirstLegOrder).createdAt) }}
{{ formatDateTime((row as FirstLegOrder).updatedAt) }}
@@ -2395,7 +2395,7 @@ async function searchOrders(model: QueryModel) {
{{ row.cabinetNo || '—' }}
{{ [row.vesselName, row.voyageNo].filter(Boolean).join(' · ') || '待更新' }}
- {{ row.sailingAt ? formatDateTime(row.sailingAt) : '待更新' }}
+ {{ row.estimatedSailingAt ? formatDateTime(row.estimatedSailingAt) : '待更新' }}
{{ row.status || '待更新' }}
尚未分配柜次,后续柜次节点将在这里同步。