优化
This commit is contained in:
+3
-1
@@ -12,7 +12,8 @@
|
||||
|---|---|
|
||||
| 履约任务/分配 | `controller/PlatformFulfillmentAssignmentController.java`、`service/FulfillmentTaskService.java` |
|
||||
| 入库单查询/聚合 | `controller/PlatformInboundOrderController.java`、`service/InboundOrderQueryService.java` |
|
||||
| 测量/OCR/第三方回传 | `controller/PlatformInboundMeasurementController.java`、`OpenApiInboundMeasurementController.java`、`service/InboundMeasurementService.java` |
|
||||
| 平台测量/OCR | `controller/PlatformInboundMeasurementController.java`、`service/InboundMeasurementService.java`、`service/CartonMeasurementService.java` |
|
||||
| 墨家设备测量上传 | `controller/OpenApiInboundMeasurementController.java`、`dto/MojiaMeasurementDtos.java`、`service/MojiaMeasurementOpenApiService.java`、`security/MeasurementRequestAuthenticator.java`;接口契约见 `src/main/resources/openapi/firstleg-v1.yaml` 与 `../../docs/墨家设备测量上传接口说明-V3.md` |
|
||||
| 审核/自动完成 | `controller/PlatformInboundMeasurementReviewController.java`、`service/MeasurementReviewService.java`、`InboundCompletionOrchestrator.java` |
|
||||
| FBA 主数据/计费 | `controller/PlatformFbaMasterDataController.java`、`PlatformFbaPricingController.java`、`service/FbaPricingService.java` |
|
||||
| 客户费用查询 | `controller/MerchantInboundBillingController.java`、`service/MerchantInboundBillingService.java` |
|
||||
@@ -41,6 +42,7 @@
|
||||
## 三期装柜与 PDA 资源结算
|
||||
|
||||
- 智能装柜候选只能按同一国内中转仓合柜;推荐顺序按入库时间先进先出。装柜计划状态为 `EDITING -> LOADING -> COMPLETED`,PDA 全部明细处理完成后自动完成。
|
||||
- PDA 拣货以 `fl_inbound_carton_label.box_code` 对应的稳定箱唛箱码为扫描身份;一个有效且未重复的箱码扫描表示拣出一箱,不得以 SKU、商品件数或页面展示字段替代箱码。任务下发与提交契约见 `src/main/resources/openapi/phase3-pda-convergence-v1.yaml`。
|
||||
- PDA 部分拣货生成二级子入库单时,数量必须守恒:`已拣数量 + 子单数量 = 拣货前主单可用数量`。子单只允许一层,不能继续拆分。
|
||||
- `releaseMode=AUTO` 时,释放资源数为 `ceil(实际拣货箱数 × 原资源数 / 原可用箱数)`;`MANUAL` 按 `locationIds` 选择,空数组表示明确释放 0 个。未传模式时,`locationIds=null` 兼容为 AUTO。
|
||||
- 头程快照必须保存仓库 `reservation_id`。A0 是共享临时库位,多个托盘可具有相同 `location_id`,跨服务结算、转移、释放必须使用 `reservationId`,不得把 `locationId` 当作唯一资源标识。
|
||||
|
||||
@@ -98,7 +98,7 @@ public final class LoadingPickDtos {
|
||||
) {
|
||||
}
|
||||
|
||||
public record PickItem(Long id, Long loadingPlanItemId, Long inboundId, Long inboundDetailId,
|
||||
public record PickItem(Long id, Long loadingPlanItemId, Long tenantId, Long inboundId, Long inboundDetailId,
|
||||
String orderNo, String inboundCode, String cargoName, List<String> boxCodes,
|
||||
Integer plannedPackageCount, Integer pickedPackageCount,
|
||||
String itemStatus, Integer version) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface LoadingPickItemMapper extends BaseMapper<LoadingPickItemEntity> {
|
||||
@Select("""
|
||||
SELECT pick_item.id AS pickItemId, plan_item.order_no AS orderNo,
|
||||
SELECT pick_item.id AS pickItemId, plan_item.account_id AS tenantId, plan_item.order_no AS orderNo,
|
||||
plan_item.inbound_code AS inboundCode, label.cargo_name AS cargoName,
|
||||
label.box_code AS boxCode
|
||||
FROM fl_loading_pick_item pick_item
|
||||
@@ -27,6 +27,7 @@ public interface LoadingPickItemMapper extends BaseMapper<LoadingPickItemEntity>
|
||||
|
||||
interface CartonLabelRow {
|
||||
Long getPickItemId();
|
||||
Long getTenantId();
|
||||
String getOrderNo();
|
||||
String getInboundCode();
|
||||
String getCargoName();
|
||||
|
||||
@@ -491,7 +491,8 @@ public class LoadingPickService {
|
||||
List<PickItem> items = source.stream().map(item -> {
|
||||
List<CartonLabelRow> cartons = cartonsByItem.getOrDefault(item.getId(), List.of());
|
||||
CartonLabelRow first = cartons.isEmpty() ? null : cartons.get(0);
|
||||
return new PickItem(item.getId(), item.getLoadingPlanItemId(), item.getInboundId(),
|
||||
return new PickItem(item.getId(), item.getLoadingPlanItemId(), first == null ? null : first.getTenantId(),
|
||||
item.getInboundId(),
|
||||
item.getInboundDetailId(), first == null ? null : first.getOrderNo(),
|
||||
first == null ? null : first.getInboundCode(), first == null ? null : first.getCargoName(),
|
||||
cartons.stream().map(CartonLabelRow::getBoxCode).toList(), item.getPlannedPackageCount(),
|
||||
|
||||
@@ -10,7 +10,9 @@ paths:
|
||||
- {name: containerNo, in: query, required: true, schema: {type: string}}
|
||||
- {name: warehouseId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
responses:
|
||||
'200': {description: Task with assignment, review and item-level versions}
|
||||
'200':
|
||||
description: Task with assignment, review, stable carton codes and item-level versions
|
||||
content: {application/json: {schema: {$ref: '#/components/schemas/Task'}}}
|
||||
/api/platform/v1/first-leg/pda-loading/tasks/pending:
|
||||
get:
|
||||
summary: List active tasks available to the authenticated PDA operator
|
||||
@@ -98,6 +100,41 @@ components:
|
||||
TaskId: {name: taskId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
ItemId: {name: itemId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
schemas:
|
||||
Task:
|
||||
type: object
|
||||
required: [id, loadingPlanId, containerNo, taskStatus, workflowStatus, version, items]
|
||||
properties:
|
||||
id: {type: integer, format: int64}
|
||||
loadingPlanId: {type: integer, format: int64}
|
||||
containerNo: {type: string}
|
||||
taskStatus: {type: string, enum: [LOADING, COMPLETED]}
|
||||
workflowStatus: {type: string, enum: [UNASSIGNED, IN_PROGRESS, AWAITING_REVIEW, COMPLETED]}
|
||||
version: {type: integer, minimum: 0}
|
||||
assignment: {type: object, nullable: true}
|
||||
review: {type: object, nullable: true}
|
||||
items:
|
||||
type: array
|
||||
items: {$ref: '#/components/schemas/PickItem'}
|
||||
PickItem:
|
||||
type: object
|
||||
required: [id, loadingPlanItemId, tenantId, inboundId, inboundDetailId, boxCodes, plannedPackageCount, pickedPackageCount, itemStatus, version]
|
||||
properties:
|
||||
id: {type: integer, format: int64}
|
||||
loadingPlanItemId: {type: integer, format: int64}
|
||||
tenantId: {type: integer, format: int64, description: Hidden isolation key for subsequent PDA evidence calls}
|
||||
inboundId: {type: integer, format: int64}
|
||||
inboundDetailId: {type: integer, format: int64}
|
||||
orderNo: {type: string, nullable: true}
|
||||
inboundCode: {type: string, nullable: true}
|
||||
cargoName: {type: string, nullable: true}
|
||||
boxCodes:
|
||||
type: array
|
||||
description: Stable carton label codes; one successful scan represents one carton
|
||||
items: {type: string}
|
||||
plannedPackageCount: {type: integer, minimum: 1}
|
||||
pickedPackageCount: {type: integer, minimum: 0}
|
||||
itemStatus: {type: string, enum: [PENDING, PICKING, PICKED, PARTIAL, SKIPPED]}
|
||||
version: {type: integer, minimum: 0}
|
||||
PendingTask:
|
||||
type: object
|
||||
required: [taskId, loadingPlanId, containerNo, warehouseId, taskStatus, workflowStatus, version, assignmentVersion, itemCount, pendingItemCount]
|
||||
|
||||
Reference in New Issue
Block a user