fix(firstleg): require real container before pda push

This commit is contained in:
2026-08-14 22:03:21 +08:00
parent fdd011bc57
commit 010098c4af
7 changed files with 71 additions and 13 deletions
@@ -228,13 +228,16 @@ public class SmartLoadingService {
String key = trim(idempotencyKey);
if (!StringUtils.hasText(key) || key.length() > 128) throw new BizException(ResultCode.BAD_REQUEST, "必须提供有效 Idempotency-Key");
LoadingPlanEntity plan = repository.plan(planId); if (plan == null) throw new BizException(ResultCode.NOT_FOUND, "装柜计划不存在");
ContainerBookingEntity booking = requireBooking(plan.getContainerBookingId());
if (!StringUtils.hasText(booking.getContainerNo())) {
throw validation("录入真实柜号后才能推送预装清单并开启PDA作业");
}
if (key.equals(plan.getPushIdempotencyKey())) {
loadingPickService.beginIfReady(plan.getContainerBookingId(), operatorId, operatorName);
return view(plan, requireBooking(plan.getContainerBookingId()));
return view(plan, booking);
}
if (StringUtils.hasText(plan.getPushIdempotencyKey())) throw conflict("预装清单已推送,不能使用新的幂等键重复推送");
if (!"EDITING".equals(plan.getPlanStatus()) || !Objects.equals(plan.getVersion(), request.expectedVersion())) throw conflict("仅编辑中的计划可开始装柜且版本必须匹配");
ContainerBookingEntity booking = requireBooking(plan.getContainerBookingId());
List<LoadingPlanItemEntity> items = repository.items(planId);
if (items.isEmpty()) throw validation("装柜明细不能为空");
checkPlanCapacity(booking, items);
@@ -56,6 +56,11 @@ CREATE TABLE IF NOT EXISTS fl_ocean_booking (
OR pending_estimated_arrival_at >= pending_estimated_sailing_at)
) ENGINE=InnoDB COMMENT='独立海运订舱聚合;柜次仍由fl_container_booking承载';
-- CREATE TABLE IF NOT EXISTS does not reconcile a database initialized before customer became optional.
ALTER TABLE fl_ocean_booking
MODIFY COLUMN customer_id BIGINT UNSIGNED NULL COMMENT '可选客户ID快照',
MODIFY COLUMN customer_name VARCHAR(128) NULL COMMENT '可选客户名称快照';
CREATE TABLE IF NOT EXISTS fl_ocean_booking_party (
id BIGINT UNSIGNED NOT NULL COMMENT '订舱提单关系方ID',
ocean_booking_id BIGINT UNSIGNED NOT NULL COMMENT '所属海运订舱ID',
@@ -357,6 +357,21 @@ paths:
responses:
'200': {description: 成功、计划不存在或计划已进入预装流程}
'403': {description: 无智能装柜查询权限}
/api/platform/v1/first-leg/smart-loading/plans/{planId}/push-preload:
post:
summary: 推送智能装柜计划到预装清单
description: >-
需要 platform:firstleg:smart-loading:push 权限。真实柜号必须已录入,
否则不得推送预装清单或创建 PDA作业任务;计划必须处于 EDITING 且版本匹配。
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {$ref: '#/components/parameters/IdempotencyKey'}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingPushRequest'}}}
responses:
'200': {description: 推送成功或业务失败,按响应体 code 判断}
'403': {description: 无智能装柜推送权限}
/openapi/v1/inbound-measurements:
post:
summary: 提交一条第三方箱规测量结果和一张图片
@@ -1273,6 +1288,11 @@ components:
voyageNo: {type: string, maxLength: 64, nullable: true}
version: {type: integer, minimum: 0}
reason: {type: string, maxLength: 500}
SmartLoadingPushRequest:
type: object
required: [expectedVersion]
properties:
expectedVersion: {type: integer, minimum: 0}
ContainerDocumentAttachRequest:
type: object
required: [fileId, expectedVersion]