openapi: 3.0.3 info: title: 车辆在途交接 version: 1.0.0 description: 从不可变DEPART及真实派送终态核对剩余货物。交接不重新出库或收费,不重写原始发车。旧车辆和司机分别确认实际任务结束后释放。 security: - bearerAuth: [] paths: /api/pda/v1/last-leg/dispatches/{dispatchNo}/handover-status: get: description: lastleg:pda:operate及ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR;只读,仓库来自Token。只返回所选排车的原发车资源、逐派送当前资源及涉及该排车的最近交接,不返回其他客户货物或内部ID。不提供PDA交接确认写接口。 parameters: - { name: dispatchNo, in: path, required: true, schema: { type: string } } responses: '200': description: 当前排车运输及交接状态 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: type: object properties: dispatchNo: { type: string } tripNo: { type: string } tripStatus: { type: string, enum: [IN_TRANSIT, COMPLETED] } tripRecordVersion: { type: string } originalDeparture: { $ref: '#/components/schemas/Transport' } deliveries: type: array items: type: object properties: deliveryNo: { type: string } status: { type: string } packages: { type: integer } remainingPackages: { type: integer, minimum: 0, description: 原运输尚未签收且尚未实际退回的箱数 } terminalAt: { type: string, format: date-time, nullable: true } transport: { $ref: '#/components/schemas/Transport' } latestHandover: type: object nullable: true properties: handoverNo: { type: string } handedOverAt: { type: string, format: date-time } location: { type: string } previous: { $ref: '#/components/schemas/Transport' } replacement: { $ref: '#/components/schemas/Transport' } /api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers: parameters: - $ref: '#/components/parameters/TripNo' get: description: platform:fleet:trip:list;按车次分页读取交接及原资源任务结束记录。 parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } } responses: '200': description: 业务响应 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: type: object required: [records, page, size, total, pages] properties: records: { type: array, items: { $ref: '#/components/schemas/Handover' } } page: { type: integer } size: { type: integer } total: { type: integer, format: int64 } pages: { type: integer } post: description: platform:fleet:trip:handover;同车次请求键唯一,异内容拒绝;先锁车次及新资源,再锁原客户执行单复核。原资源仍占用,车次保持IN_TRANSIT,仅未完成派送更新资源。失败整体回滚。 requestBody: required: true content: application/json: schema: type: object required: [selection, cargoHash, location, idempotencyKey] properties: selection: { $ref: '#/components/schemas/Selection' } cargoHash: { type: string, pattern: '^[0-9a-f]{64}$' } location: { type: string, minLength: 1, maxLength: 500 } reason: { type: string, maxLength: 1000 } idempotencyKey: { type: string, minLength: 8, maxLength: 128 } responses: '200': { $ref: '#/components/responses/Handover' } /api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers/preview: parameters: - $ref: '#/components/parameters/TripNo' post: description: platform:fleet:trip:list;只核对不写入。资格、容量、占用和派送事实变化使cargoHash失效。已签收后另退货使用原签收事实,未签收退回必须有RETURN_COMPLETED证据。部分同托仍用原整托实测,不按箱数比例猜重量体积。 requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/Selection' } responses: '200': description: 交接预览 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: type: object required: [tripNo, recordVersion, cargoHash, previous, replacement, capacity, cargo, driverQualification] properties: tripNo: { type: string } recordVersion: { type: integer, format: int64 } cargoHash: { type: string } previous: { $ref: '#/components/schemas/Resource' } replacement: { $ref: '#/components/schemas/Resource' } capacity: { $ref: '#/components/schemas/Load' } cargo: { $ref: '#/components/schemas/Inspection' } driverQualification: type: object properties: canDispatch: { type: boolean } expiringSoon: { type: boolean } reason: { type: string } licenseExpiresOn: { type: string, format: date, nullable: true } /api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers/{handoverNo}/resources/release: parameters: - $ref: '#/components/parameters/TripNo' - { name: handoverNo, in: path, required: true, schema: { type: string } } post: description: platform:fleet:trip:release;分别结束被接替车辆或司机任务,可早于整车货物结案。未变化资源仍由原车次结案后释放。原请求重放不操作后续占用,车辆状态与结束记录同事务提交。 requestBody: required: true content: application/json: schema: type: object required: [recordVersion, resourceKind, actualEndAt, location, idempotencyKey] properties: recordVersion: { type: integer, format: int64, minimum: 0, description: 交接记录版本 } resourceKind: { type: string, enum: [VEHICLE, DRIVER] } actualEndAt: { type: string, format: date-time } location: { type: string, minLength: 1, maxLength: 500 } vehicleStatus: { type: string, nullable: true, enum: [IN_SERVICE, MAINTENANCE, INACTIVE, RETURNED], description: 结束原车辆必填;司机不得提交 } idempotencyKey: { type: string, minLength: 8, maxLength: 128 } responses: '200': { $ref: '#/components/responses/Handover' } components: securitySchemes: bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT } parameters: TripNo: { name: tripNo, in: path, required: true, schema: { type: string } } responses: Handover: description: 已保存的交接事实及资源结束状态 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: { $ref: '#/components/schemas/Handover' } schemas: Transport: type: object properties: vehiclePlate: { type: string, nullable: true } driverName: { type: string, nullable: true } driverPhone: { type: string, nullable: true } Envelope: type: object required: [code] properties: code: { type: string, example: '200' } message: { type: string } Selection: type: object required: [recordVersion, vehicleId, driverId, expectedDriverEndAt, handedOverAt] properties: recordVersion: { type: integer, format: int64, minimum: 0 } vehicleId: { type: string, pattern: '^[1-9][0-9]*$' } driverId: { type: string, pattern: '^[1-9][0-9]*$' } expectedDriverEndAt: { type: string, format: date-time } handedOverAt: { type: string, format: date-time } Resource: type: object properties: vehicleId: { type: string } vehiclePlate: { type: string, nullable: true } driverId: { type: string } driverName: { type: string, nullable: true } driverPhone: { type: string, nullable: true } Load: type: object properties: palletSpaces: { type: integer } weightKg: { type: number } volumeCbm: { type: number } Cargo: type: object properties: customerId: { type: string, description: 隔离键,不作客户名称展示 } dispatchNo: { type: string } itemId: { type: string, description: 内部核对键,不作业务编号展示 } palletId: { type: string, description: 内部核对键,不作托盘码展示 } destinationKey: { type: string, description: 匹配键,私人地址摘要不可作地址展示 } packages: { type: integer } Delivery: type: object properties: customerId: { type: string } dispatchNo: { type: string } deliveryNo: { type: string } destinationKey: { type: string } packages: { type: integer } terminalAt: { type: string, format: date-time, nullable: true } returnedCargo: type: array description: 由实际退回入账流水映射到原发运明细;部分退回按此扣减箱数,未清空实托保留原测量载荷。 items: type: object properties: itemId: { type: string } palletId: { type: string } packages: { type: integer, minimum: 1 } receivedAt: { type: string, format: date-time } Inspection: type: object properties: remainingCargo: { type: array, items: { $ref: '#/components/schemas/Cargo' } } completedDeliveries: { type: array, items: { $ref: '#/components/schemas/Delivery' } } remainingPalletIds: { type: array, uniqueItems: true, items: { type: string } } occupied: { $ref: '#/components/schemas/Load' } Snapshot: type: object properties: previous: { $ref: '#/components/schemas/Resource' } replacement: { $ref: '#/components/schemas/Resource' } handedOverAt: { type: string, format: date-time } location: { type: string } reason: { type: string } expectedDriverEndAt: { type: string, format: date-time } capacity: { $ref: '#/components/schemas/Load' } cargo: { $ref: '#/components/schemas/Inspection' } executionEvidence: type: array items: type: object properties: dispatchNo: { type: string } customerId: { type: string } warehouseId: { type: string } shippedPackages: { type: integer } deliveries: type: array items: type: object properties: cargo: { $ref: '#/components/schemas/Delivery' } status: { type: string } recordVersion: { type: integer, format: int64 } transport: { $ref: '#/components/schemas/Transport' } operatorId: { type: string, description: 审计身份,不作姓名展示 } carriedDeliveries: type: array description: 当次实际交接的未完成派送身份,用于车辆运输区段查询 items: type: object properties: customerId: { type: string } deliveryNo: { type: string } recordedAt: { type: string, format: date-time } Released: type: object nullable: true properties: idempotencyKey: { type: string } requestHash: { type: string } actualEndAt: { type: string, format: date-time } location: { type: string } vehicleStatus: { type: string, nullable: true } operatorId: { type: string } recordedAt: { type: string, format: date-time } Handover: type: object properties: handoverNo: { type: string } tripNo: { type: string } recordVersion: { type: integer, format: int64 } snapshot: { $ref: '#/components/schemas/Snapshot' } vehicleRelease: { $ref: '#/components/schemas/Released' } driverRelease: { $ref: '#/components/schemas/Released' }