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

This commit is contained in:
2026-09-08 20:22:49 +08:00
81 changed files with 2343 additions and 361 deletions
@@ -406,25 +406,6 @@ paths:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无分配权限}
/api/platform/v1/containers:
get:
summary: 分页查询平台货柜
description: 需要 platform:firstleg:container:list 权限;货柜为平台级数据,不传 tenant/account
parameters:
- {$ref: '#/components/parameters/Page'}
- {$ref: '#/components/parameters/Size'}
- {name: keyword, in: query, schema: {type: string, maxLength: 128}}
- {name: customerId, in: query, description: 仅返回包含该客户货物的柜次, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: containerNo, in: query, schema: {type: string, maxLength: 64}}
- {name: cabinetNo, in: query, schema: {type: string, maxLength: 64}}
- {name: warehouseId, in: query, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: status, in: query, schema: {type: string, enum: [WAIT_LOADING, EDITING, LOADING, COMPLETED]}}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema: {$ref: '#/components/schemas/ContainerBookingPageEnvelope'}
'403': {description: 无货柜查询权限}
post:
summary: 新增内部模拟柜
description: 需要 platform:firstleg:container:create 权限;服务端生成稳定 containerBookingId/cabinetNo,不要求真实柜号或订舱
@@ -436,6 +417,43 @@ paths:
responses:
'200': {description: 成功或重复号、参数校验等业务失败}
'403': {description: 无新增按钮权限}
/api/platform/v1/containers/domestic:
get:
summary: 分页查询国内货柜工作台
description: 需要 platform:firstleg:container:list;ACTIVE仅真实国内离仓前,HISTORY仅已真实离仓
parameters: &ContainerWorkbenchQueryParameters
- {$ref: '#/components/parameters/Page'}
- {$ref: '#/components/parameters/Size'}
- {name: scope, in: query, required: true, schema: {type: string, enum: [ACTIVE, HISTORY]}}
- {name: keyword, in: query, schema: {type: string, maxLength: 128}}
- {name: customerId, in: query, description: 仅返回包含该客户货物的柜次, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: containerNo, in: query, schema: {type: string, maxLength: 64}}
- {name: cabinetNo, in: query, schema: {type: string, maxLength: 64}}
- {name: warehouseId, in: query, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: status, in: query, description: 仅筛选装柜子状态,不作为出仓或船节点状态, schema: {type: string, enum: [WAIT_LOADING, EDITING, LOADING, COMPLETED]}}
responses:
'200': {description: 成功, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerWorkbenchPageEnvelope'}}}}
'403': {description: 无国内货柜查询权限}
/api/platform/v1/containers/overseas:
get:
summary: 分页查询国外货柜工作台
description: 需要 platform:firstleg:terminal-drayage:list;ACTIVE从真实DEPARTED_WAREHOUSE至EMPTY_RETURNED前,HISTORY仅已还空柜
parameters: *ContainerWorkbenchQueryParameters
responses:
'200': {description: 成功, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerWorkbenchPageEnvelope'}}}}
'403': {description: 无国外货柜查询权限}
/api/platform/v1/containers/domestic/{id}:
get:
summary: 查询国内货柜工作台详情
description: 需要 platform:firstleg:container:list;装柜清单只返回唯一loadingPlanId/planNo/planStatus关联
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
responses: {'200': {description: 成功, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerWorkbenchEnvelope'}}}}}
/api/platform/v1/containers/overseas/{id}:
get:
summary: 查询国外货柜工作台详情
description: 需要 platform:firstleg:terminal-drayage:list;同一containerBookingId只读聚合柜内组成和海外履约
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
responses: {'200': {description: 成功, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerWorkbenchEnvelope'}}}}}
/api/platform/v1/containers/{id}/ocean-booking-link:
post:
summary: 将内部模拟柜关联到已发布订舱需求
@@ -444,14 +462,6 @@ paths:
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerOceanBookingLinkRequest'}}}}
responses: {'200': {description: 关联后的同一模拟柜 containerBookingId/cabinetNo;列表仍只有这一条 ACTIVE 操作身份}}
/api/platform/v1/containers/{id}:
get:
summary: 查询平台货柜详情
description: 需要 platform:firstleg:container:list 权限
parameters:
- {$ref: '#/components/parameters/ContainerBookingId'}
responses:
'200': {description: 成功或货柜不存在}
'403': {description: 无货柜查询权限}
put:
summary: 草稿阶段编辑货柜基础资料
description: 需要 platform:firstleg:container:edit 权限;仅待装柜或计划为 EDITING 时允许;请求不包含 containerNo/cabinetNo,不形成真实柜号或内部柜次号写入口
@@ -465,16 +475,23 @@ paths:
responses:
'200': {description: 成功或状态、版本、重复号冲突}
'403': {description: 无货柜编辑权限}
/api/platform/v1/containers/{id}/pickup-code:
put:
summary: 填写或更新PU码
description: 需要 platform:firstleg:terminal-drayage:document:edit 权限;仅国外工作台货柜;PU资料为1至64位数字码,按字符串保存以保留前导零
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerPickupCodeRequest'}}}}
responses: {'200': {description: 返回最新货柜履约概览}, '403': {description: 无货柜编辑权限}}
/api/platform/v1/containers/{id}/clearance:
get:
summary: 查询货柜目的港清关资料
description: 需要 platform:firstleg:customs:manage 权限
description: 需要 platform:firstleg:terminal-drayage:list 权限;仅国外工作台货柜
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
responses: {'200': {description: 成功或货柜不存在}}
/api/platform/v1/containers/{id}/clearance/document:
post:
summary: 上传或替换货柜目的港清关资料
description: 需要 platform:firstleg:customs:manage 权限,fileId 必须严格绑定当前货柜
description: 需要 platform:firstleg:terminal-drayage:document:edit 权限,fileId 必须严格绑定当前货柜
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
@@ -483,7 +500,7 @@ paths:
/api/platform/v1/containers/{id}/clearance/document/{fileId}/download:
get:
summary: 下载货柜目的港清关附件
description: 需要 platform:firstleg:customs:manage 权限;服务端校验当前 DESTINATION_CLEARANCE fileId 及 File 业务归属,完成态仍可下载,响应禁止缓存
description: 需要 platform:firstleg:terminal-drayage:list 权限;服务端校验当前 DESTINATION_CLEARANCE fileId 及 File 业务归属,完成态仍可下载,响应禁止缓存
parameters:
- {$ref: '#/components/parameters/ContainerBookingId'}
- {name: fileId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
@@ -493,7 +510,7 @@ paths:
/api/platform/v1/containers/{id}/clearance/document/upload:
post:
summary: 直接选择文件上传或替换货柜目的港清关资料
description: Firstleg 使用内部服务令牌上传 File,浏览器不得传递 fileId 或内部令牌;旧 JSON document 接口仅兼容存量调用。
description: 需要 platform:firstleg:terminal-drayage:document:edit;Firstleg 使用内部服务令牌上传 File,浏览器不得传递 fileId 或内部令牌。
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
@@ -504,7 +521,7 @@ paths:
/api/platform/v1/containers/{id}/clearance/complete:
post:
summary: 点击完成目的港清关
description: 需要 platform:firstleg:customs:manage 权限
description: 需要 platform:firstleg:terminal-drayage:document:edit 权限
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
@@ -1987,7 +2004,7 @@ components:
publicRemark: {type: string, nullable: true}
expressCompanyName: {type: string, nullable: true}
expressTrackingNo: {type: string, nullable: true}
ContainerBookingPageEnvelope:
ContainerWorkbenchPageEnvelope:
type: object
properties:
code: {type: string, example: '200'}
@@ -1995,14 +2012,78 @@ components:
data:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/ContainerBooking'}}
records: {type: array, items: {$ref: '#/components/schemas/ContainerWorkbenchItem'}}
page: {type: string, pattern: '^[1-9][0-9]*$'}
size: {type: string, pattern: '^[1-9][0-9]*$'}
total: {type: string, pattern: '^[0-9]+$'}
pages: {type: string, pattern: '^[0-9]+$'}
ContainerWorkbenchEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data: {$ref: '#/components/schemas/ContainerWorkbenchItem'}
ContainerWorkbenchItem:
type: object
required: [container, workbenchStage, statusSummary, allowedActions]
properties:
container: {$ref: '#/components/schemas/ContainerBooking'}
workbenchStage: {type: string, enum: [WAIT_LOADING, LOADING, WAIT_CUSTOMS, WAIT_OUTBOUND, DEPARTED_WAREHOUSE, IN_TRANSIT, ARRIVED_DESTINATION_PORT, PICKUP_READY, PICKED_UP, UNLOADED, EMPTY_RETURNED]}
statusSummary: {$ref: '#/components/schemas/ContainerWorkbenchStatusSummary'}
allowedActions:
type: array
description: 已同时按真实业务状态与当前用户权限裁剪
items: {type: string, enum: [EDIT_CONTAINER, MANAGE_CUSTOMS, CONFIRM_OUTBOUND, MANAGE_DESTINATION_DOCUMENTS, SELECT_FLEET, SCHEDULE_PICKUP, RECORD_PICKUP, RECORD_EMPTY_RETURN]}
actualFacts: {$ref: '#/components/schemas/ContainerActualFacts'}
terminalDrayage: {$ref: '#/components/schemas/ContainerTerminalDrayage'}
ContainerWorkbenchStatusSummary:
type: object
properties:
loadingStatus: {type: string, nullable: true}
customsStatus: {type: string, nullable: true}
outboundStatus: {type: string, nullable: true}
destinationClearanceStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
deliveryOrderStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
pickupCodeStatus: {type: string, enum: [MISSING, UPLOADED]}
latestActualNode: {type: string, nullable: true}
latestActualAt: {type: string, format: date-time, nullable: true}
terminalDrayageStatus: {type: string, nullable: true}
emptyReturnWarningStatus: {type: string, enum: [NOT_APPLICABLE, PENDING, OVERDUE, RESOLVED], nullable: true}
ContainerActualFacts:
type: object
nullable: true
description: 仅来自最新船节点任务的actual_at;无任务时为null,不用预计时间推断
properties:
containerBookingId: {type: string, pattern: '^[1-9][0-9]*$'}
queryId: {type: string, pattern: '^[1-9][0-9]*$'}
queryVersion: {type: integer, minimum: 0}
queryStatus: {type: string}
latestActualNode: {type: string, nullable: true}
latestActualAt: {type: string, format: date-time, nullable: true}
departedWarehouseAt: {type: string, format: date-time, nullable: true}
departedOriginPortAt: {type: string, format: date-time, nullable: true}
arrivedDestinationPortAt: {type: string, format: date-time, nullable: true}
pickupReadyAt: {type: string, format: date-time, nullable: true}
pickedUpAt: {type: string, format: date-time, nullable: true}
emptyReturnedAt: {type: string, format: date-time, nullable: true}
ContainerTerminalDrayage:
type: object
nullable: true
properties:
status: {type: string, enum: [WAITING_FOR_ARRIVAL, ARRIVED, PICKUP_SCHEDULED, PICKED_UP, UNLOADED, EMPTY_RETURNED]}
version: {type: integer, minimum: 0}
fleetSupplierId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
fleetSupplierName: {type: string, nullable: true}
pickupAppointmentAt: {type: string, format: date-time, nullable: true}
actualPickupAt: {type: string, format: date-time, nullable: true}
estimatedEmptyReturnAt: {type: string, format: date-time, nullable: true, description: unloadingCompletedAt加72小时}
actualEmptyReturnAt: {type: string, format: date-time, nullable: true}
unloadingCompletedAt: {type: string, format: date-time, nullable: true}
emptyReturnWarning: {type: object, nullable: true}
allowedActions: {type: array, items: {type: string, enum: [SELECT_FLEET, SCHEDULE_PICKUP, RECORD_PICKUP, RECORD_EMPTY_RETURN]}}
ContainerBooking:
type: object
required: [id, bookingNo, cabinetNo, sourceType, recordStatus, warehouseId, warehouseName, containerType, capacityCbm, maxWeightKg, planStatus, exceptionActive, destinationClearanceDocumentStatus, customsDeclarationDocumentStatus, deliveryOrderDocumentStatus, pickupOrderDocumentStatus, version]
required: [id, bookingNo, cabinetNo, sourceType, recordStatus, warehouseId, warehouseName, containerType, capacityCbm, maxWeightKg, planStatus, exceptionActive, destinationClearanceDocumentStatus, customsDeclarationDocumentStatus, deliveryOrderDocumentStatus, version]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
planId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 关联智能装柜计划ID;未创建计划时为空}
@@ -2044,7 +2125,7 @@ components:
actualWarehouseArrivalAt: {type: string, format: date-time, nullable: true}
unloadingCompletedAt: {type: string, format: date-time, nullable: true, description: 海外仓卸柜完成时间}
unloadingPhotoUploadedAt: {type: string, format: date-time, nullable: true, description: 海外仓卸柜照片上传成功时间}
estimatedEmptyReportedAt: {type: string, format: date-time, nullable: true, description: 预计报空时间,由卸柜照片上传成功时间加两天计算}
estimatedEmptyReportedAt: {type: string, format: date-time, nullable: true, description: 预计还空时间,统一按卸柜完成时间加72小时计算}
actualEmptyReportedAt: {type: string, format: date-time, nullable: true, description: 实际报空时间}
emptyReportSourceVersion: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 海外货柜事件聚合版本}
planStatus: {type: string, enum: [WAIT_LOADING, EDITING, LOADING, COMPLETED]}
@@ -2052,12 +2133,17 @@ components:
destinationClearanceDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
customsDeclarationDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
deliveryOrderDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
pickupOrderDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
outboundDispatchStatus: {type: string, nullable: true, description: 国内出仓聚合状态,不使用planStatus推断}
outboundConfirmedAt: {type: string, format: date-time, nullable: true, description: 真实国内离仓确认时间}
pickupCode: {type: string, pattern: '^[0-9]{1,64}$', nullable: true, description: PU数字码;字符串保存以保留前导零}
pickupCodeUpdatedBy: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
pickupCodeUpdatedByName: {type: string, nullable: true}
pickupCodeUpdatedAt: {type: string, format: date-time, nullable: true}
version: {type: integer, minimum: 0}
ContainerDocumentStatus:
type: string
enum: [MISSING, UPLOADED, COMPLETED]
description: 单证聚合状态;DO/PU 无完成动作,因此只返回 MISSING 或 UPLOADED
description: 单证聚合状态;DO 无完成动作,因此只返回 MISSING 或 UPLOADED
ContainerSaveRequest:
type: object
required: [warehouseId, warehouseName, containerType, capacityCbm, maxWeightKg]
@@ -2367,6 +2453,12 @@ components:
file: {type: string, format: binary, description: 用户直接选择的清关资料}
expectedVersion: {type: integer, minimum: 0, description: 当前文档乐观锁版本,首次上传为 0}
operationReason: {type: string, maxLength: 500, nullable: true}
ContainerPickupCodeRequest:
type: object
required: [pickupCode, expectedVersion]
properties:
pickupCode: {type: string, pattern: '^[0-9]{1,64}$'}
expectedVersion: {type: integer, minimum: 0}
MerchantInboundBillingEnvelope:
type: object
properties: