This commit is contained in:
2026-08-18 16:09:52 +08:00
parent 82ee80226e
commit fa77170304
6 changed files with 92 additions and 82 deletions
@@ -2,7 +2,7 @@ const MODULE = 'manual-state-ocean-trucking'
const OPTIONS = { scenario: 'manual-ocean-trucking-state-matrix', deploymentBlocker: true }
const OCEAN_BASE = '/api/platform/v1/ocean-bookings'
const TRUCK_BASE = '/api/platform/v1/truck-appointments'
const OCEAN_LIST_STATUSES = ['CONFIRMED', 'CHANGE_PENDING', 'RELEASED', 'CANCELLED']
const OCEAN_LIST_STATUSES = ['DRAFT', 'RELEASED']
const OCEAN_STATUSES = [...OCEAN_LIST_STATUSES]
const TRUCK_STATUSES = ['DRAFT', 'PENDING_DISPATCH', 'DISPATCHED', 'PICKUP_IN_PROGRESS', 'ARRIVED_WAREHOUSE',
'LOADING', 'DEPARTED', 'COMPLETED', 'RESCHEDULED', 'EXCEPTION', 'CANCELLED']
@@ -36,20 +36,20 @@ function oceanPayload(context, template, index) {
remark: `${context.marker} 人工列表状态 ${index}`,
parties: template.parties.map(({ partyType, partyName, address, contactName, contactPhone }) =>
({ partyType, partyName, address, contactName, contactPhone })),
containers: template.containers.map(({ containerType, containerKind, capacityCbm, maxWeightKg }, containerIndex) =>
({ containerNo: `MAN-${suffix(context, index)}-${String(containerIndex + 1).padStart(2, '0')}`.slice(0, 64),
containerType, containerKind, capacityCbm, maxWeightKg })),
containerRequirements: template.containerRequirements.map(({ containerType, containerKind, quantity, capacityCbm, maxWeightKg }) =>
({ containerType, containerKind, quantity, capacityCbm, maxWeightKg })),
} }
}
async function createOcean(context, template, index) {
const response = await post(context, OCEAN_BASE, oceanPayload(context, template, index), `ocean-create-${index}`)
const value = context.apiSuccess(MODULE, `创建订舱状态样本 ${index}`, response, '', OPTIONS)
context.assert(MODULE, `订舱样本 ${index} 一次创建直接返回 CONFIRMED`, response,
Boolean(value?.oceanBooking?.id) && value?.oceanBooking?.status === 'CONFIRMED',
context.assert(MODULE, `订舱样本 ${index} 创建为 DRAFT 且无真实柜`, response,
Boolean(value?.oceanBooking?.id) && value?.oceanBooking?.status === 'DRAFT'
&& (!value?.containers || value.containers.length === 0),
`id=${id(value?.oceanBooking?.id) || 'missing'}, status=${value?.oceanBooking?.status || 'missing'}`, OPTIONS)
if (!value?.oceanBooking?.id || value?.oceanBooking?.status !== 'CONFIRMED') {
throw new Error(`创建订舱样本 ${index} 未直接进入 CONFIRMED`)
if (!value?.oceanBooking?.id || value?.oceanBooking?.status !== 'DRAFT') {
throw new Error(`创建订舱样本 ${index} 未进入 DRAFT`)
}
return value
}
@@ -64,15 +64,8 @@ async function oceanAction(context, value, endpoint, body = {}) {
async function buildOcean(context, template, status, index) {
let value = await createOcean(context, template, index)
if (status === 'CONFIRMED') return value
if (status === 'CANCELLED') return oceanAction(context, value, 'cancel')
if (status === 'CHANGE_PENDING') return oceanAction(context, value, 'change-request', {
vesselName: `变更轮-${suffix(context, index)}`, voyageNo: `CV${suffix(context, index)}`,
estimatedSailingAt: '2026-09-16T08:00:00', estimatedArrivalAt: '2026-10-16T08:00:00' })
if (status === 'RELEASED') return oceanAction(context, value, 'release', {
billOfLadingNo: value.oceanBooking.billOfLadingNo, vesselName: value.oceanBooking.vesselName,
voyageNo: value.oceanBooking.voyageNo, estimatedSailingAt: value.oceanBooking.estimatedSailingAt,
estimatedArrivalAt: value.oceanBooking.estimatedArrivalAt })
if (status === 'DRAFT') return value
if (status === 'RELEASED') return oceanAction(context, value, 'release')
throw new Error(`unsupported ocean status ${status}`)
}
@@ -139,8 +132,8 @@ export async function run(context, matrix = context.createdResources.manualState
if (!sourceOceanId) throw new Error('缺少现有订舱生命周期模块生成的模板资源')
const templateResponse = await context.request('GET', `${OCEAN_BASE}/${sourceOceanId}`)
const template = context.apiSuccess(MODULE, '读取订舱状态矩阵模板', templateResponse, '', OPTIONS)
if (!template?.oceanBooking || !template?.parties?.length || !template?.containers?.length) {
throw new Error('订舱模板缺少渠道、仓库、参与方或真实柜明细')
if (!template?.oceanBooking || !template?.parties?.length || !template?.containerRequirements?.length) {
throw new Error('订舱模板缺少渠道、仓库、参与方或柜型需求')
}
matrix.pages.oceanBookings = { requiredStatuses: OCEAN_LIST_STATUSES, fixtures: {} }
for (const [index, status] of OCEAN_STATUSES.entries()) {