Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
2026-09-01 15:14:24 +08:00
138 changed files with 4762 additions and 1056 deletions
@@ -294,8 +294,8 @@ paths:
'403': {description: 无新增按钮权限}
/api/platform/v1/containers/{id}/ocean-booking-link:
post:
summary: 将内部模拟柜关联到已发布订舱需求并补录真实柜号
description: 需要 platform:firstleg:container:edit;请求指定 RELEASED oceanBookingId、未满配 requirementId 和港口提柜后取得的唯一 containerNo,服务端规范化并校验ISO 6346结构、设备类别和校验位。首次关联允许 WAIT_LOADING 或已有预排货的 EDITING 模拟柜,保留原 containerBookingId/cabinetNo/loadingPlanId/items,原子写入订舱、运输和范围快照并创建 allocation;不会创建或消费另一条真实柜记录。存在跨仓、跨渠道、柜型规格不一致、超量、重复柜号、PDA、有效装柜证据、业务单证或 LOADING/COMPLETED 等事实时拒绝。
summary: 将内部模拟柜关联到已发布订舱需求
description: 需要 platform:firstleg:container:edit;请求指定 RELEASED oceanBookingId 和未满配 requirementId,containerNo 可空。首次关联允许 WAIT_LOADING 或已有预排货的 EDITING 模拟柜,保留原 containerBookingId/cabinetNo/loadingPlanId/items,原子写入订舱、运输和范围快照并创建 allocation;提柜后由拖车链调用柜次服务原子补录真实柜号。若关联请求已提供 containerNo,服务端仍规范化并校验 ISO 6346 结构、设备类别、校验位和全局唯一性。存在跨仓、跨渠道、柜型规格不一致、超量、重复柜号、PDA、有效装柜证据、业务单证或 LOADING/COMPLETED 等事实时拒绝。
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerOceanBookingLinkRequest'}}}}
responses: {'200': {description: 关联后的同一模拟柜 containerBookingId/cabinetNo;列表仍只有这一条 ACTIVE 操作身份}}
@@ -1328,10 +1328,10 @@ components:
type: array
maxItems: 100
items: {$ref: '#/components/schemas/WeightPalletSnapshot'}
page: {type: integer, format: int64, minimum: 1}
size: {type: integer, format: int64, minimum: 1, maximum: 100}
total: {type: integer, format: int64, minimum: 0}
pages: {type: integer, format: int64, minimum: 0}
page: {oneOf: [{type: integer, format: int64, minimum: 1}, {type: string, pattern: '^[1-9][0-9]*$'}]}
size: {oneOf: [{type: integer, format: int64, minimum: 1, maximum: 100}, {type: string, pattern: '^(?:[1-9]|[1-9][0-9]|100)$'}]}
total: {oneOf: [{type: integer, format: int64, minimum: 0}, {type: string, pattern: '^(?:0|[1-9][0-9]*)$'}]}
pages: {oneOf: [{type: integer, format: int64, minimum: 0}, {type: string, pattern: '^(?:0|[1-9][0-9]*)$'}]}
CreateWeightResultRequest:
type: object
required: [fileId, palletId]
@@ -1957,11 +1957,11 @@ components:
maxWeightKg: {type: number, minimum: 0, exclusiveMinimum: true, description: 必须等于柜型固定限重}
ContainerOceanBookingLinkRequest:
type: object
required: [oceanBookingId, requirementId, containerNo, expectedVersion]
required: [oceanBookingId, requirementId, expectedVersion]
properties:
oceanBookingId: {type: integer, format: int64, minimum: 1, description: RELEASED订舱ID}
requirementId: {type: integer, format: int64, minimum: 1, description: 未满配的订舱柜型需求ID}
containerNo: {type: string, maxLength: 64, description: 港口提柜后取得的全局唯一真实集装箱号;服务端移除格式空白、转大写并校验ISO 6346结构、设备类别和校验位}
containerNo: {type: string, nullable: true, maxLength: 64, description: 可选;港口提柜后可由拖车链另行原子补录。非空时服务端移除格式空白、转大写并校验ISO 6346结构、设备类别、校验位和全局唯一性}
expectedVersion: {type: integer, minimum: 0}
ContainerFeeAdjustRequest:
type: object
@@ -21,6 +21,7 @@ paths:
records: {type: array, items: {$ref: '#/components/schemas/DetailStableReferences'}}
post:
summary: Create a truck appointment for a released booking and its allocated real container
description: If the real container already has a non-terminal appointment, the server returns A0409 with the existing appointment number and instructs the operator to continue editing. This duplicate guard runs before booking-document validation; the database unique key provides the same response for concurrent creates.
requestBody:
required: true
content:
@@ -28,6 +29,7 @@ paths:
schema: {$ref: '#/components/schemas/SaveRequest'}
responses:
'200': {description: 'Created appointment', content: {application/json: {schema: {$ref: '#/components/schemas/DetailEnvelope'}}}}
'409': {description: 'A0409 - this container already has a non-terminal appointment; message includes its appointment number and asks the operator to continue editing'}
/api/platform/v1/truck-appointments/{id}:
parameters: [{$ref: '#/components/parameters/AppointmentId'}]
get:
@@ -187,6 +189,8 @@ components:
carrierName: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint only; the persisted snapshot comes from Warehouse supplier master data.}
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint; the persisted snapshot is always frozen from the selected RELEASED booking.}
plannedLoadingAt: {type: string, format: date-time}
payableAmount: {type: number, format: double, minimum: 0, nullable: true, description: Amount payable to the trucking supplier.}
currency: {type: string, enum: [RMB, USD], default: RMB, description: Payable amount currency.}
expectedVersion: {type: integer, minimum: 0, description: Must be 0 on create; current version on edit.}
DetailStableReferences:
type: object
@@ -209,4 +213,6 @@ components:
carrierId: {type: integer, format: int64}
carrierName: {type: string}
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Frozen bill of lading snapshot used by dispatch readiness.}
payableAmount: {type: number, format: double, minimum: 0, nullable: true}
currency: {type: string, enum: [RMB, USD]}
attachmentCount: {type: integer, format: int64, minimum: 0, description: Number of attachment references owned by this appointment}