This commit is contained in:
2026-10-29 13:36:38 +08:00
parent 353c86f4cf
commit 1b27d7e6c2
60 changed files with 1208 additions and 60 deletions
@@ -20,9 +20,10 @@ info:
RETURN_CARTON selections consume every SKU in the selected physical carton.
Candidates return cartons, cartonSelectionSupported and cartonSelectionBlockReason.
Stock without complete carton/pallet ownership remains available for full disposal only.
PDA tasks return scanMode PALLET or CARTON and the real cartonMarks for loose stock.
Bound pallets require their pallet number; loose stock requires every distinct carton mark scanned,
or confirmAllCartons=true. The loose group uses 散箱 as its API path key, never as a scan code.
PDA tasks with real cartonMarks use CARTON scanMode, including full bound-pallet tasks.
Every distinct selected carton mark must be scanned; confirmAllCartons cannot bypass this check.
Ordinary stock without carton marks uses PALLET mode and actual carton quantities.
The loose group uses 散箱 as its API path key, never as a scan code.
The application may select a subset of available cartons. PDA must finish every selected carton;
short actual quantities are rejected. At least one photo remains required.
Partial bound-pallet tasks use CARTON scanMode with the real palletNo and selected cartonMarks.
@@ -109,11 +110,12 @@ paths:
type: array
uniqueItems: true
items: { type: string }
description: All task cartonMarks must be scanned unless confirmAllCartons is true.
description: All task cartonMarks must be scanned exactly once, regardless of confirmAllCartons.
confirmAllCartons:
type: boolean
default: false
description: Explicitly confirm all loose cartons without individual scans; photos remain mandatory.
deprecated: true
description: Compatibility field only; does not bypass individual carton scans. Photos remain mandatory.
photoFileIds:
type: array
minItems: 1
@@ -42,7 +42,7 @@ paths:
- { name: number, in: path, required: true, schema: { type: string }, description: 真实PC排车业务号 }
get:
summary: 排车运输详情(list)
description: data包含dispatchNo、taskType(PICKUP/LOCAL_TRUCK)、execution(现有资源与执行详情)、customerId、orderNo、pickups、completionEvidence(已确认凭证)、dispatchRecordVersion(排车审核版本)、resources(取货车辆司机照片快照;其他类型为null)。resources.driver.evidence.masterLicenseFileId仅表示司机主档驾驶证来源,包含在fileIds内;其他fileIds属于本车补传。
description: data包含dispatchNo、taskType(PICKUP/LOCAL_TRUCK)、execution(现有资源与执行详情)、customerId、orderNo、pickups、completionEvidence(已确认凭证)、dispatchRecordVersion(排车审核版本)、resources(车辆司机照片快照)、cargo(本土卡车原始托数、箱数、重量kg、体积m³、起讫地地址及双方联系人电话;非本土卡车为null)。resources.driver.evidence.masterLicenseFileId仅表示司机主档驾驶证来源,包含在fileIds内;其他fileIds属于本车补传。
responses: *response
/{number}/{action}:
parameters:
@@ -28,6 +28,7 @@ paths:
- {name: region, in: query, schema: {type: string, enum: [DOMESTIC, OVERSEAS]}}
- {name: licenseState, in: query, schema: {type: string, enum: [MISSING, VALID, EXPIRING, EXPIRED]}, description: 仅驾驶证日期状态,与审核和附件状态分别展示}
- {name: expectedEnd, in: query, schema: {type: string, format: date-time}}
- {name: dispatchNo, in: query, schema: {type: string, maxLength: 64}, description: 排车候选上下文;在分页和统计前过滤其他车次占用,保留当前排车绑定司机}
responses:
'200':
description: 业务响应,分页数据
@@ -0,0 +1,56 @@
openapi: 3.0.3
info:
title: 海外客户下单预估资金校验
version: 1.0.0
description: Finance异步冻结成功后才能创建客户采购/本土卡车订单。余额优先、授信补足及不足判断由Finance原子执行;本服务不自行修改钱包。创建订单须使用相同幂等键、金额及币种。未绑定预占15分钟过期;订单终态释放,释放失败重试。预占独立于最终人工费用结算。
security:
- bearerAuth: []
paths:
/api/merchant/v1/last-leg/order-budgets/{kind}/{key}:
parameters:
- {name: kind, in: path, required: true, schema: {type: string, enum: [procurement, trucking]}}
- {name: key, in: path, required: true, schema: {type: string, minLength: 1, maxLength: 128}}
post:
summary: 发起冻结或读取原请求,失败后可用原键重试
description: 客户身份仅来自认证。procurement需要merchant:cross-border:procurement:create,trucking需要merchant:cross-border:domestic-trucking:create;权限不能交叉使用。采购金额是预算单价乘采购数量,免费样品零金额不发资金指令;卡车金额必须大于0。重试禁止更改金额或币种。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [amount, currency]
properties:
amount: {type: number, minimum: 0, multipleOf: 0.01}
currency: {type: string, enum: [CNY, USD]}
responses:
'200': {$ref: '#/components/responses/Result'}
'403': {description: 身份或业务创建权限不足}
get:
summary: 读取当前客户本次下单的权威资金回执
description: 与POST相同创建权限;只有usable=true才允许继续下单。FREEZE_PENDING处理期间应轮询,超时保留原键重试;失败显示Finance返回原因。
responses:
'200': {$ref: '#/components/responses/Result'}
'403': {description: 身份或业务创建权限不足}
components:
securitySchemes:
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
responses:
Result:
description: 统一业务响应;code为字符串200表示查询或发起成功,不等于资金冻结成功。
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
required: [status, amountCny, message, usable]
properties:
status: {type: string, enum: [FREEZE_PENDING, FROZEN, FAILED, RELEASE_PENDING, RELEASE_FAILED, RELEASED]}
amountCny: {type: number, minimum: 0}
message: {type: string}
orderNo: {type: string, nullable: true}
usable: {type: boolean}
@@ -5172,17 +5172,17 @@ components:
remark: { type: string, nullable: true, maxLength: 1000 }
TruckCreate:
type: object
required: [vehicleType, origin, destination, totalWeightKg, totalVolumeCbm, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, idempotencyKey]
required: [vehicleType, origin, destination, totalWeightKg, totalVolumeCbm, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, palletCount, budgetAmount, idempotencyKey]
properties:
vehicleType: { type: string, enum: [PALLET_15, PALLET_30], description: '15拖或30拖;拼车来源未知时为空' }
origin: { type: string, maxLength: 255 }
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
packageCount: { type: integer, nullable: true, minimum: 0 }
palletCount: { type: integer, minimum: 1, description: '下单预估托数' }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
budgetAmount: { type: number, minimum: 0, exclusiveMinimum: true }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
originContactName: { type: string, maxLength: 128 }
originContactPhone: { type: string, maxLength: 128 }
@@ -5194,7 +5194,7 @@ components:
idempotencyKey: { type: string, maxLength: 255 }
TruckUpdate:
type: object
required: [version, vehicleType, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt]
required: [version, vehicleType, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, palletCount, budgetAmount]
properties:
version: { type: integer, format: int64, minimum: 0 }
vehicleType: { type: string, enum: [PALLET_15, PALLET_30], description: '15拖或30拖;拼车来源未知时为空' }
@@ -5202,10 +5202,10 @@ components:
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
packageCount: { type: integer, minimum: 0 }
palletCount: { type: integer, minimum: 1, description: '下单预估托数' }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
budgetAmount: { type: number, minimum: 0, exclusiveMinimum: true }
currency: { type: string, minLength: 3, maxLength: 3 }
originContactName: { type: string, maxLength: 128 }
originContactPhone: { type: string, maxLength: 128 }
@@ -6,6 +6,33 @@ info:
security:
- bearerAuth: []
paths:
/api/merchant/v1/last-leg/overseas-procurements/{orderNo}/reject:
post:
summary: 客户驳回采购结果并填写原因
description: 仅当前认证客户,权限 merchant:cross-border:procurement:create。仅 WAIT_CUSTOMER_CONFIRM,成功回到 RECEIVING;保存原因及当前已上传照片快照,平台须重新上传各批收货照片才能再次提交确认。
parameters:
- $ref: '#/components/parameters/OrderNo'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/RejectionCommand' }
responses:
'200': { $ref: '#/components/responses/WorkflowResponse' }
/api/platform/v1/last-leg/overseas-procurements/{orderNo}/receipt-photos:
post:
summary: 驳回后替换指定批次的收货照片
description: 权限 platform:overseas-business:purchase:receive-overseas。仅客户驳回后的 RECEIVING;文件须为本单新上传图片,不接受驳回前的文件;仅替换照片,不改变实收数量及时间。
parameters:
- $ref: '#/components/parameters/OrderNo'
- $ref: '#/components/parameters/CustomerId'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ReceiptPhotosCommand' }
responses:
'200': { $ref: '#/components/responses/WorkflowResponse' }
/api/platform/v1/last-leg/overseas-procurements/{orderNo}/workflow:
get:
summary: 读取采购实收、库存和出库批次
@@ -43,7 +70,7 @@ paths:
/api/platform/v1/last-leg/overseas-procurements/{orderNo}/request-confirmation:
post:
summary: 采购完成并请求客户确认
description: 权限 platform:overseas-business:purchase:receive-overseas;仅平台主体,必须指定目标客户 customerId。仅 RECEIVING 且已有实收;提交后不再追加收货。
description: 权限 platform:overseas-business:purchase:receive-overseas;仅平台主体,必须指定目标客户 customerId。仅 RECEIVING 且已有实收;客户驳回后必须替换各批旧照片。提交后不再追加收货。
parameters:
- $ref: '#/components/parameters/OrderNo'
- $ref: '#/components/parameters/CustomerId'
@@ -265,6 +292,21 @@ components:
uniqueItems: true
items:
$ref: '#/components/schemas/Id'
RejectionCommand:
allOf:
- $ref: '#/components/schemas/Command'
- type: object
required: [reason]
properties:
reason: {type: string, minLength: 1, maxLength: 1000}
ReceiptPhotosCommand:
allOf:
- $ref: '#/components/schemas/Command'
- type: object
required: [receiptId, fileIds]
properties:
receiptId: { $ref: '#/components/schemas/Id' }
fileIds: { $ref: '#/components/schemas/FileIds' }
ReceiptCommand:
allOf:
- $ref: '#/components/schemas/Command'
@@ -331,6 +373,8 @@ components:
required: [orderNo, version, status, receivedQuantity, stockQuantity, reservedQuantity, availableQuantity, receipts, outbounds, files]
description: stockQuantity = receivedQuantity - 已完成出库数量;reservedQuantity 为未完成出库占用;availableQuantity = stockQuantity - reservedQuantity。主状态优先显示运输中批次,其次派送中;全部批次完成但仍有库存时回到已确认,无剩余库存才签收完成。
properties:
rejectionReason: {type: string, nullable: true, description: 客户驳回原因}
photosNeedUpdate: {type: boolean, description: 存在尚未替换的被驳回照片}
orderNo: {type: string}
version: {type: integer, format: int64, minimum: 0}
status:
@@ -211,7 +211,7 @@ components:
actualPackages: {type: integer, minimum: 0}
photoFileIds: {type: array, items: {type: string}}
scannedCartonMarks: {type: array, items: {type: string}}
confirmAllCartons: {type: boolean}
confirmAllCartons: {type: boolean, deprecated: true, description: 仅兼容旧请求,不能绕过逐箱扫码校验}
Preparation:
type: object
properties: