fix: stabilize overseas initialization and PDA acceptance

This commit is contained in:
2026-09-10 10:25:16 +08:00
parent 37a28b9c11
commit e72e74b21e
12 changed files with 160 additions and 375 deletions
@@ -52,7 +52,7 @@ public interface PdaWarehouseMapper extends BaseMapper<PdaOperationHistory> {
"FROM ll_pda_operation_history h WHERE h.overseas_warehouse_id=#{warehouseId} AND h.operator_key=#{operatorKey} " +
"<if test='operationType != null and operationType != \"\"'>AND h.operation_type=#{operationType} </if>" +
"UNION ALL SELECT o.id,CONCAT('RECEIVING_',o.action),s.container_no,'COMPLETED'," +
"CONCAT('柜号作业 ',s.container_no),s.customer_id,o.created_at " +
"CONCAT('柜号作业 ',s.container_no),NULL customer_id,o.created_at " +
"FROM ll_receiving_container_operation o JOIN ll_receiving_container_session s ON s.id=o.session_id " +
"WHERE s.overseas_warehouse_id=#{warehouseId} AND o.operator_key=#{operatorKey} " +
"<if test='operationType != null and operationType != \"\"'>AND CONCAT('RECEIVING_',o.action)=#{operationType} </if>" +
@@ -15,6 +15,8 @@ public final class OverseasPermissions {
public static final String RELABEL_ORDER_LIST = "platform:overseas-warehouse:relabel-order:list";
public static final String RELABEL_ORDER_CREATE = "platform:overseas-warehouse:relabel-order:create";
public static final String RELABEL_ORDER_STATUS = "platform:overseas-warehouse:relabel-order:status";
public static final String RETURN_INVENTORY_LIST = "platform:overseas-warehouse:return-inventory:list";
public static final String RETURN_CARTONS_LIST = "platform:overseas-warehouse:return-cartons:list";
public static final String INVENTORY_LIST = "platform:overseas-warehouse:inventory:list";
public static final String INVENTORY_EXPORT = "platform:overseas-warehouse:inventory:export";
public static final String INVENTORY_EDIT = "platform:overseas-warehouse:inventory:edit";
@@ -952,7 +952,7 @@ CREATE TABLE IF NOT EXISTS ll_inbound_pallet_merge (
KEY idx_ll_inbound_merge_task (customer_id, task_id), KEY idx_ll_inbound_merge_group (merge_group_no)
) ENGINE=InnoDB COMMENT='入仓托盘合托记录';
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inbound_plan_line' AND column_name='fba_warehouse_code'), 'SELECT 1', 'ALTER TABLE ll_inbound_plan_line ADD COLUMN fba_warehouse_code VARCHAR(128) NULL AFTER inbound_code'));
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inbound_plan_line' AND column_name='fba_warehouse_code'), 'SELECT 1', 'ALTER TABLE ll_inbound_plan_line ADD COLUMN fba_warehouse_code VARCHAR(128) NULL COMMENT ''FBA仓库编码'' AFTER inbound_code'));
PREPARE inbound_schema_stmt FROM @ddl; EXECUTE inbound_schema_stmt; DEALLOCATE PREPARE inbound_schema_stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inbound_plan_line' AND column_name='customer_id'), 'SELECT 1', 'ALTER TABLE ll_inbound_plan_line ADD COLUMN customer_id VARCHAR(128) NOT NULL DEFAULT '''' COMMENT ''客户账号标识'' AFTER id'));
PREPARE receiving_container_line_stmt FROM @ddl; EXECUTE receiving_container_line_stmt; DEALLOCATE PREPARE receiving_container_line_stmt;
@@ -1356,7 +1356,7 @@ PREPARE dispatch_schema_stmt FROM @ddl; EXECUTE dispatch_schema_stmt; DEALLOCATE
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_dispatch_pallet_lock' AND column_name='dispatch_order_id' AND is_nullable='YES'), 'SELECT 1', 'ALTER TABLE ll_dispatch_pallet_lock MODIFY COLUMN dispatch_order_id BIGINT NULL COMMENT ''正式派车单ID,草稿锁阶段为空'''));
PREPARE dispatch_schema_stmt FROM @ddl; EXECUTE dispatch_schema_stmt; DEALLOCATE PREPARE dispatch_schema_stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_dispatch_item' AND column_name='order_refs'), 'SELECT 1', 'ALTER TABLE ll_dispatch_item ADD COLUMN order_refs VARCHAR(2000) NULL AFTER order_no'));
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_dispatch_item' AND column_name='order_refs'), 'SELECT 1', 'ALTER TABLE ll_dispatch_item ADD COLUMN order_refs VARCHAR(2000) NULL COMMENT ''关联订单信息'' AFTER order_no'));
PREPARE dispatch_schema_stmt FROM @ddl; EXECUTE dispatch_schema_stmt; DEALLOCATE PREPARE dispatch_schema_stmt;
CREATE TABLE IF NOT EXISTS ll_dispatch_pda_task (
@@ -2058,6 +2058,21 @@ CREATE TABLE IF NOT EXISTS ll_security_projection (
KEY idx_security_projection_permission (aggregate_id,permission_version)
) ENGINE=InnoDB COMMENT='海外IAM安全状态与权限版本投影';
-- 收敛尚未具备授权快照字段的开发/测试库,CREATE TABLE IF NOT EXISTS 不会补充已存在表的字段。
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
AND table_name='ll_security_projection' AND column_name='roles_json'), 'SELECT 1',
'ALTER TABLE ll_security_projection ADD COLUMN roles_json JSON NULL COMMENT ''IAM投影的当前角色快照'' AFTER permission_version'));
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
AND table_name='ll_security_projection' AND column_name='authorities_json'), 'SELECT 1',
'ALTER TABLE ll_security_projection ADD COLUMN authorities_json JSON NULL COMMENT ''IAM投影的当前海外权限快照'' AFTER roles_json'));
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
UPDATE ll_security_projection SET roles_json=JSON_ARRAY() WHERE roles_json IS NULL;
UPDATE ll_security_projection SET authorities_json=JSON_ARRAY() WHERE authorities_json IS NULL;
ALTER TABLE ll_security_projection
MODIFY COLUMN roles_json JSON NOT NULL COMMENT 'IAM投影的当前角色快照',
MODIFY COLUMN authorities_json JSON NOT NULL COMMENT 'IAM投影的当前海外权限快照';
-- 空库基线固定管理员必须携带当前海外授权快照;后续真实 IAM 事件从 aggregate_version=1 单调覆盖该 version=0 投影。
SET @platform_admin_overseas_roles = JSON_ARRAY('PLATFORM_ADMIN');
SET @platform_admin_overseas_authorities = JSON_ARRAY(
@@ -2121,9 +2136,6 @@ SET @platform_admin_overseas_authorities = JSON_ARRAY(
'platform:overseas-master-data:vehicle:export',
'platform:overseas-master-data:vehicle:list',
'platform:overseas-master-data:vehicle:status',
'platform:overseas-warehouse:carton:create',
'platform:overseas-warehouse:carton:edit',
'platform:overseas-warehouse:carton:list',
'platform:overseas-warehouse:customer-visit:edit',
'platform:overseas-warehouse:customer-visit:list',
'platform:overseas-warehouse:delivery:documents',
@@ -2160,12 +2172,11 @@ SET @platform_admin_overseas_authorities = JSON_ARRAY(
'platform:overseas-warehouse:pallet:delete',
'platform:overseas-warehouse:pallet:edit',
'platform:overseas-warehouse:pallet:list',
'platform:overseas-warehouse:product:create',
'platform:overseas-warehouse:product:edit',
'platform:overseas-warehouse:product:list',
'platform:overseas-warehouse:relabel-order:create',
'platform:overseas-warehouse:relabel-order:list',
'platform:overseas-warehouse:relabel-order:status',
'platform:overseas-warehouse:return-cartons:list',
'platform:overseas-warehouse:return-inventory:list',
'platform:overseas-warehouse:warehouse:create',
'platform:overseas-warehouse:warehouse:edit',
'platform:overseas-warehouse:warehouse:list',
@@ -64,7 +64,7 @@ class DeliverySchemaContractTest {
String overseas = Files.readString(Path.of("..", "deploy", "sql", "海外区域统一增量-MySQL8.sql"),
StandardCharsets.UTF_8).toLowerCase();
assertTrue(overseas.contains("空库先执行 lastleg-service/src/main/resources/db/lastleg.sql 基线"));
assertTrue(overseas.contains("begin inline empty-database baseline: lastleg"));
assertTrue(overseas.contains(createToken));
assertTrue(overseas.indexOf(createToken) < overseas.indexOf("assert_phase5_lastleg_identifiers_migratable"));
assertTrue(overseas.contains("alter table ll_delivery_order add column overseas_warehouse_name"));
@@ -60,6 +60,14 @@ class PdaWarehouseContractTest {
.contains("unique key uk_ll_pda_history_idempotency(operator_key,idempotency_key)");
}
@Test
void sharedContainerHistoryDoesNotReadRemovedCustomerScope() throws Exception {
String mapper = Files.readString(Path.of(
"src/main/java/com/baiyue/lastleg/pda/warehouse/mapper/PdaWarehouseMapper.java"));
assertThat(mapper).contains("NULL customer_id")
.doesNotContain("s.customer_id");
}
@Test
void openApiAndGatewayPublishOnlyStablePdaPaths() throws Exception {
String openapi = Files.readString(Path.of("src/main/resources/openapi/overseas-pda-operations-v1.yaml"));