This commit is contained in:
2026-10-22 11:56:54 +08:00
parent 090431b409
commit 3e77c3976e
40 changed files with 976 additions and 241 deletions
+50
View File
@@ -0,0 +1,50 @@
import type { OceanBookingDetail, OceanBookingPrintType } from './types'
export interface OceanBookingWorkflowStep {
label: string
status: string
state: 'complete' | 'current' | 'pending'
}
export type OceanBookingPreviewSignatures = Partial<Record<OceanBookingPrintType, string>>
// 预览只对应其实际消费的数据;补录实值不会作废已经预览的托运单。
export function oceanBookingPrintSignature(detail: OceanBookingDetail, type: OceanBookingPrintType): string {
return JSON.stringify([
detail.id, detail.billOfLadingNo, detail.vesselName, detail.voyageNo, detail.estimatedSailingAt,
detail.shippingCompanyName, detail.bookingAgentName,
detail.departurePortCode, detail.departurePortName, detail.destinationPortCode, detail.destinationPortName,
detail.placeOfDelivery, detail.serviceTerm, detail.freightTerm, detail.packageUnit,
detail.cargoDescription, detail.marksAndNos, detail.remark,
detail.parties.map(party => [party.partyType, party.partyName, party.address, party.contactName, party.contactPhone, party.contactEmail, party.taxNo]).sort((a, b) => String(a[0]).localeCompare(String(b[0]))),
detail.containerRequirements.map(item => [item.containerType, item.containerKind, item.quantity]),
type === 'SHIPPING_INSTRUCTION'
? [detail.declaredPackageCount, detail.declaredGrossWeightKg, detail.declaredVolumeCbm]
: [detail.actualPackageCount, detail.actualGrossWeightKg, detail.actualVolumeCbm],
])
}
export function oceanBookingWorkflow(
detail: OceanBookingDetail | null,
draftDirty: boolean,
actualDirty: boolean,
previews: OceanBookingPreviewSignatures,
): OceanBookingWorkflowStep[] {
const saved = Boolean(detail && !draftDirty)
const released = detail?.status === 'RELEASED'
const actualComplete = Boolean(detail && [detail.actualPackageCount, detail.actualGrossWeightKg, detail.actualVolumeCbm]
.every(value => value != null && Number(value) > 0))
const previewed = (type: OceanBookingPrintType) => Boolean(detail && previews[type] === oceanBookingPrintSignature(detail, type))
const instructionPreviewed = saved && previewed('SHIPPING_INSTRUCTION')
const confirmationPreviewed = saved && released && actualComplete && !actualDirty && previewed('BILL_OF_LADING_CONFIRMATION')
const current = !saved ? 0 : !released ? instructionPreviewed ? 2 : 1 : confirmationPreviewed ? -1 : 3
const step = (index: number, label: string, complete: boolean, status: string): OceanBookingWorkflowStep => ({
label, status, state: complete ? 'complete' : current === index ? 'current' : 'pending',
})
return [
step(0, '填写并保存订舱信息', saved, saved ? '已保存' : detail ? '修改待保存' : '待填写并保存'),
step(1, '托运单预览 / 打印', instructionPreviewed, instructionPreviewed ? '已预览' : saved ? '可预览 / 打印' : '待保存资料'),
step(2, '补齐资料并确认放舱', released, released ? '已放舱' : saved ? '待确认放舱' : '待补齐资料'),
step(3, '补实并预览提单确认件', confirmationPreviewed, !released ? '待放舱' : actualDirty ? '实值待保存' : !actualComplete ? '待补齐实值' : confirmationPreviewed ? '已预览' : '可预览 / 打印'),
]
}