feat: complete overseas pda warehouse operations
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Lastleg Overseas PDA Warehouse Operations API
|
||||
version: 1.0.0
|
||||
description: 海外仓PDA盘点、同仓整托移库、托盘作业与换标现场作业;全部范围从PDA Token解析。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/pda/v1/last-leg/stocktakes:
|
||||
get:
|
||||
summary: 查询Token绑定仓盘点任务
|
||||
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 } }
|
||||
- { name: status, in: query, schema: { type: string, enum: [IN_PROGRESS, SUBMITTED] } }
|
||||
responses: { '200': { description: 盘点任务分页 } }
|
||||
post:
|
||||
summary: 按库位或托盘创建盘点任务
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/StocktakeCreate' } } } }
|
||||
responses: { '200': { description: 创建后的完整盘点任务 } }
|
||||
/api/pda/v1/last-leg/stocktakes/{taskNo}:
|
||||
get:
|
||||
summary: 查询盘点任务详情
|
||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||
responses: { '200': { description: 盘点任务及冻结库存位置 } }
|
||||
/api/pda/v1/last-leg/stocktakes/{taskNo}/counts:
|
||||
post:
|
||||
summary: 提交一个库存位置的实盘箱数
|
||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/StocktakeCount' } } } }
|
||||
responses: { '200': { description: 已计数明细 }, '409': { description: 版本或幂等冲突 } }
|
||||
/api/pda/v1/last-leg/stocktakes/{taskNo}/submit:
|
||||
post:
|
||||
summary: 提交盘点并按差异调整库存
|
||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/StocktakeSubmit' } } } }
|
||||
responses: { '200': { description: 已提交盘点任务 }, '409': { description: 未全盘、库存版本变化或负库存风险 } }
|
||||
/api/pda/v1/last-leg/inventory-moves:
|
||||
post:
|
||||
summary: 同仓整托移库
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/InventoryMove' } } } }
|
||||
responses: { '200': { description: 移库结果 }, '409': { description: 跨仓、资源或库存版本冲突 } }
|
||||
/api/pda/v1/last-leg/pallet-operations/pallets/resolve:
|
||||
post:
|
||||
summary: 扫码查询托盘及库存内容
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ScanCode' } } } }
|
||||
responses: { '200': { description: Token绑定仓托盘内容 } }
|
||||
/api/pda/v1/last-leg/pallet-operations/assemble:
|
||||
post:
|
||||
summary: 将多个来源托盘的指定库存行组到目标托盘
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PalletAssemble' } } } }
|
||||
responses: { '200': { description: 组托及实物托盘状态结果 }, '409': { description: 目的仓、库存或资源版本冲突 } }
|
||||
/api/pda/v1/last-leg/pallet-operations/disassemble:
|
||||
post:
|
||||
summary: 将来源托盘库存拆到一个或多个目标托盘
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PalletDisassemble' } } } }
|
||||
responses: { '200': { description: 拆托结果 }, '409': { description: 库存或资源版本冲突 } }
|
||||
/api/pda/v1/last-leg/pallet-operations/swap:
|
||||
post:
|
||||
summary: 将整托库存更换到空目标托盘
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PalletSwap' } } } }
|
||||
responses: { '200': { description: 换托结果 }, '409': { description: 目标托盘非空或版本冲突 } }
|
||||
/api/pda/v1/last-leg/pallet-operations/unbind:
|
||||
post:
|
||||
summary: 解除整托库存与实物托盘绑定
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PalletUnbind' } } } }
|
||||
responses: { '200': { description: 解绑结果 }, '409': { description: 库存或资源版本冲突 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/candidates:
|
||||
get:
|
||||
summary: 查询Token绑定仓可执行换标任务
|
||||
responses: { '200': { description: 待认领、处理中或待复核换标任务 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}:
|
||||
get:
|
||||
summary: 查询换标现场任务详情
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
responses: { '200': { description: 申请明细、逐件事实、照片与历史 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/claim:
|
||||
post:
|
||||
summary: 认领换标任务并推进申请至处理中
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IdempotentAction' } } } }
|
||||
responses: { '200': { description: 已认领任务 }, '409': { description: 仓库、状态或幂等冲突 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/units:
|
||||
post:
|
||||
summary: 登记一件正常换标事实
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelUnit' } } } }
|
||||
responses: { '200': { description: 更新后的任务 }, '409': { description: 旧标重复、新标不符或版本冲突 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/units/skip:
|
||||
post:
|
||||
summary: 登记一件有原因的跳过事实
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelSkip' } } } }
|
||||
responses: { '200': { description: 更新后的任务 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/exceptions:
|
||||
post:
|
||||
summary: 登记一件换标异常事实
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelException' } } } }
|
||||
responses: { '200': { description: 更新后的任务 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/photos/files:
|
||||
post:
|
||||
summary: 上传换标完成现场照片
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } }
|
||||
responses: { '200': { description: OVERSEAS_RELABEL_PHOTO文件元数据 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/complete:
|
||||
post:
|
||||
summary: 提交现场任务等待复核,不提前完成申请
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelComplete' } } } }
|
||||
responses: { '200': { description: WAIT_REVIEW任务 }, '409': { description: 箱数未核平、照片或版本冲突 } }
|
||||
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/review:
|
||||
post:
|
||||
summary: 现场复核;APPROVE才完成既有换标申请,REWORK退回处理
|
||||
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelReview' } } } }
|
||||
responses: { '200': { description: COMPLETED或PROCESSING任务 }, '409': { description: 状态或版本冲突 } }
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
|
||||
schemas:
|
||||
ScanCode:
|
||||
type: object
|
||||
required: [code]
|
||||
properties: { code: { type: string, minLength: 1, maxLength: 128 } }
|
||||
IdempotentAction:
|
||||
type: object
|
||||
required: [idempotencyKey]
|
||||
properties: { idempotencyKey: { type: string, minLength: 1, maxLength: 255 } }
|
||||
StocktakeCreate:
|
||||
type: object
|
||||
required: [scopeType, scopeCode, idempotencyKey]
|
||||
properties:
|
||||
scopeType: { type: string, enum: [LOCATION, PALLET] }
|
||||
scopeCode: { type: string, maxLength: 128 }
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
StocktakeCount:
|
||||
type: object
|
||||
required: [positionId, actualPackages, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
positionId: { type: string, pattern: '^[0-9]+$' }
|
||||
actualPackages: { type: integer, format: int64, minimum: 0 }
|
||||
expectedVersion: { type: integer, format: int64, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
StocktakeSubmit:
|
||||
type: object
|
||||
required: [expectedVersion, reason, idempotencyKey]
|
||||
properties:
|
||||
expectedVersion: { type: integer, format: int64, minimum: 0 }
|
||||
reason: { type: string, minLength: 1, maxLength: 500 }
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
InventoryMove:
|
||||
type: object
|
||||
required: [sourcePalletCode, targetLocationCode, expectedPalletVersion, idempotencyKey, reason]
|
||||
properties:
|
||||
sourcePalletCode: { type: string, maxLength: 128 }
|
||||
targetLocationCode: { type: string, maxLength: 128 }
|
||||
expectedPalletVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
reason: { type: string, minLength: 1, maxLength: 500 }
|
||||
PalletExpectation:
|
||||
type: object
|
||||
required: [palletCode, expectedVersion]
|
||||
properties:
|
||||
palletCode: { type: string, maxLength: 128 }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
PalletMoveLine:
|
||||
type: object
|
||||
required: [positionId, packages, expectedPositionVersion]
|
||||
properties:
|
||||
positionId: { type: string, pattern: '^[0-9]+$' }
|
||||
packages: { type: integer, format: int64, minimum: 1 }
|
||||
expectedPositionVersion: { type: integer, format: int64, minimum: 0 }
|
||||
PalletAssemble:
|
||||
type: object
|
||||
required: [idempotencyKey, target, sources, lines]
|
||||
properties:
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
target: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
sources: { type: array, minItems: 1, maxItems: 20, items: { $ref: '#/components/schemas/PalletExpectation' } }
|
||||
lines: { type: array, minItems: 1, maxItems: 200, items: { $ref: '#/components/schemas/PalletMoveLine' } }
|
||||
reason: { type: string, maxLength: 500 }
|
||||
PalletTargetMove:
|
||||
type: object
|
||||
required: [target, lines]
|
||||
properties:
|
||||
target: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
lines: { type: array, minItems: 1, maxItems: 200, items: { $ref: '#/components/schemas/PalletMoveLine' } }
|
||||
PalletDisassemble:
|
||||
type: object
|
||||
required: [idempotencyKey, source, targets]
|
||||
properties:
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
source: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
targets: { type: array, minItems: 1, maxItems: 20, items: { $ref: '#/components/schemas/PalletTargetMove' } }
|
||||
reason: { type: string, maxLength: 500 }
|
||||
PalletSwap:
|
||||
type: object
|
||||
required: [idempotencyKey, source, target]
|
||||
properties:
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
source: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
target: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
reason: { type: string, maxLength: 500 }
|
||||
PalletUnbind:
|
||||
type: object
|
||||
required: [idempotencyKey, source]
|
||||
properties:
|
||||
idempotencyKey: { type: string, maxLength: 128 }
|
||||
source: { $ref: '#/components/schemas/PalletExpectation' }
|
||||
reason: { type: string, maxLength: 500 }
|
||||
RelabelUnit:
|
||||
type: object
|
||||
required: [itemId, oldLabel, newLabel, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
itemId: { type: string, pattern: '^[0-9]+$' }
|
||||
oldLabel: { type: string, maxLength: 255 }
|
||||
newLabel: { type: string, maxLength: 255 }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 255 }
|
||||
RelabelSkip:
|
||||
type: object
|
||||
required: [itemId, oldLabel, reason, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
itemId: { type: string, pattern: '^[0-9]+$' }
|
||||
oldLabel: { type: string, maxLength: 255 }
|
||||
reason: { type: string, maxLength: 1000 }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 255 }
|
||||
RelabelException:
|
||||
type: object
|
||||
required: [itemId, exceptionCode, reason, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
itemId: { type: string, pattern: '^[0-9]+$' }
|
||||
oldLabel: { type: string, maxLength: 255, nullable: true }
|
||||
exceptionCode: { type: string, enum: [DAMAGED, MISSING_LABEL, LABEL_MISMATCH, UNREADABLE, OTHER] }
|
||||
reason: { type: string, maxLength: 1000 }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 255 }
|
||||
RelabelComplete:
|
||||
type: object
|
||||
required: [photoFileIds, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
photoFileIds: { type: array, minItems: 1, maxItems: 20, items: { type: string, pattern: '^[0-9]+$' } }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 255 }
|
||||
remark: { type: string, maxLength: 1000, nullable: true }
|
||||
RelabelReview:
|
||||
type: object
|
||||
required: [decision, expectedVersion, idempotencyKey]
|
||||
properties:
|
||||
decision: { type: string, enum: [APPROVE, REWORK] }
|
||||
expectedVersion: { type: integer, minimum: 0 }
|
||||
idempotencyKey: { type: string, maxLength: 255 }
|
||||
remark: { type: string, maxLength: 1000, nullable: true }
|
||||
Reference in New Issue
Block a user