fix(iam): 修复仓库角色统一迁移执行
This commit is contained in:
@@ -8713,15 +8713,28 @@ DELIMITER ;
|
|||||||
CALL assert_phase3_final_schema();
|
CALL assert_phase3_final_schema();
|
||||||
DROP PROCEDURE IF EXISTS assert_phase3_final_schema;
|
DROP PROCEDURE IF EXISTS assert_phase3_final_schema;
|
||||||
|
|
||||||
-- 二、三期对外统一使用 INBOUNDED;历史 WAIT_SPLIT 仅由查询适配为 INBOUNDED,统一迁移不改写主表或历史状态。
|
|
||||||
SELECT 'PASS' AS migration_status,
|
|
||||||
'统一增量全部执行完成;箱号映射、单箱测量、三期订舱、拖车预约、出仓、报关、船期、装柜模型桥接、PDA收敛、费用、公共资源及可靠审计结构校验通过' AS message;
|
|
||||||
|
|
||||||
-- PDA 部分拣货释放策略:NULL/AUTO 按比例释放,MANUAL + [] 表示人工明确不释放。
|
-- PDA 部分拣货释放策略:NULL/AUTO 按比例释放,MANUAL + [] 表示人工明确不释放。
|
||||||
USE baiyue_firstleg;
|
USE baiyue_firstleg;
|
||||||
ALTER TABLE fl_loading_pick_item
|
DROP PROCEDURE IF EXISTS phase3_pda_add_column;
|
||||||
ADD COLUMN IF NOT EXISTS release_mode VARCHAR(10) NULL COMMENT 'AUTO按比例释放,MANUAL按人工选择释放' AFTER item_status,
|
DELIMITER $$
|
||||||
ADD COLUMN IF NOT EXISTS release_location_ids JSON NULL COMMENT '人工选择释放库位ID;空数组表示明确释放0个' AFTER release_mode;
|
CREATE PROCEDURE phase3_pda_add_column(IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_ddl TEXT)
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = DATABASE() AND table_name = p_table AND column_name = p_column
|
||||||
|
) THEN
|
||||||
|
SET @phase3_pda_ddl = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN ', p_ddl);
|
||||||
|
PREPARE phase3_pda_stmt FROM @phase3_pda_ddl;
|
||||||
|
EXECUTE phase3_pda_stmt;
|
||||||
|
DEALLOCATE PREPARE phase3_pda_stmt;
|
||||||
|
END IF;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL phase3_pda_add_column('fl_loading_pick_item', 'release_mode',
|
||||||
|
'`release_mode` VARCHAR(10) NULL COMMENT ''AUTO按比例释放,MANUAL按人工选择释放'' AFTER `item_status`');
|
||||||
|
CALL phase3_pda_add_column('fl_loading_pick_item', 'release_location_ids',
|
||||||
|
'`release_location_ids` JSON NULL COMMENT ''人工选择释放库位ID;空数组表示明确释放0个'' AFTER `release_mode`');
|
||||||
-- PDA 多人协作:领取粒度由整柜任务下沉为单条拣货明细。
|
-- PDA 多人协作:领取粒度由整柜任务下沉为单条拣货明细。
|
||||||
CREATE TABLE IF NOT EXISTS fl_loading_pick_item_assignment (
|
CREATE TABLE IF NOT EXISTS fl_loading_pick_item_assignment (
|
||||||
pick_item_id BIGINT UNSIGNED NOT NULL,
|
pick_item_id BIGINT UNSIGNED NOT NULL,
|
||||||
@@ -8739,10 +8752,21 @@ CREATE TABLE IF NOT EXISTS fl_loading_pick_item_assignment (
|
|||||||
CONSTRAINT chk_loading_pick_item_assignment_type CHECK (assignment_type IN ('CLAIMED', 'ASSIGNED'))
|
CONSTRAINT chk_loading_pick_item_assignment_type CHECK (assignment_type IN ('CLAIMED', 'ASSIGNED'))
|
||||||
) ENGINE=InnoDB COMMENT='PDA拣货明细领取与作业员分配';
|
) ENGINE=InnoDB COMMENT='PDA拣货明细领取与作业员分配';
|
||||||
|
|
||||||
|
SET @phase3_pda_check_ddl = IF(
|
||||||
|
EXISTS (SELECT 1 FROM information_schema.table_constraints
|
||||||
|
WHERE constraint_schema = DATABASE()
|
||||||
|
AND table_name = 'fl_loading_pick_operation'
|
||||||
|
AND constraint_name = 'chk_loading_pick_operation_action'
|
||||||
|
AND constraint_type = 'CHECK'),
|
||||||
|
'ALTER TABLE fl_loading_pick_operation DROP CHECK chk_loading_pick_operation_action',
|
||||||
|
'SELECT 1');
|
||||||
|
PREPARE phase3_pda_check_stmt FROM @phase3_pda_check_ddl;
|
||||||
|
EXECUTE phase3_pda_check_stmt;
|
||||||
|
DEALLOCATE PREPARE phase3_pda_check_stmt;
|
||||||
|
|
||||||
ALTER TABLE fl_loading_pick_operation
|
ALTER TABLE fl_loading_pick_operation
|
||||||
DROP CHECK IF EXISTS chk_loading_pick_operation_action,
|
|
||||||
ADD CONSTRAINT chk_loading_pick_operation_action
|
ADD CONSTRAINT chk_loading_pick_operation_action
|
||||||
CHECK (action_type IN ('CLAIM', 'ASSIGN', 'ITEM_CLAIM', 'ITEM_ASSIGN', 'REVIEW'));
|
CHECK (action_type IN ('CLAIM', 'ASSIGN', 'ITEM_CLAIM', 'ITEM_ASSIGN', 'REVIEW'));
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS assert_phase3_pda_item_assignment_schema;
|
DROP PROCEDURE IF EXISTS assert_phase3_pda_item_assignment_schema;
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
@@ -8763,8 +8787,20 @@ DELIMITER ;
|
|||||||
CALL assert_phase3_pda_item_assignment_schema();
|
CALL assert_phase3_pda_item_assignment_schema();
|
||||||
DROP PROCEDURE IF EXISTS assert_phase3_pda_item_assignment_schema;
|
DROP PROCEDURE IF EXISTS assert_phase3_pda_item_assignment_schema;
|
||||||
|
|
||||||
ALTER TABLE fl_inbound_pallet_allocation
|
CALL phase3_pda_add_column('fl_inbound_pallet_allocation', 'reservation_id',
|
||||||
ADD COLUMN IF NOT EXISTS reservation_id BIGINT UNSIGNED NULL COMMENT '仓库预占资源唯一ID,A0共享场景用于区分托盘' AFTER location_code;
|
'`reservation_id` BIGINT UNSIGNED NULL COMMENT ''仓库预占资源唯一ID,A0共享场景用于区分托盘'' AFTER `location_code`');
|
||||||
|
|
||||||
|
SET @phase3_pda_index_ddl = IF(
|
||||||
|
EXISTS (SELECT 1 FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_pallet_allocation'
|
||||||
|
AND index_name = 'idx_allocation_reservation'),
|
||||||
|
'SELECT 1',
|
||||||
|
'ALTER TABLE fl_inbound_pallet_allocation ADD INDEX idx_allocation_reservation (reservation_id)');
|
||||||
|
PREPARE phase3_pda_index_stmt FROM @phase3_pda_index_ddl;
|
||||||
|
EXECUTE phase3_pda_index_stmt;
|
||||||
|
DEALLOCATE PREPARE phase3_pda_index_stmt;
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS phase3_pda_add_column;
|
||||||
|
|
||||||
/* Phase 3: six-carrier schedule query tasks, truthful manual fallback and three-day rate limit. */
|
/* Phase 3: six-carrier schedule query tasks, truthful manual fallback and three-day rate limit. */
|
||||||
USE baiyue_firstleg;
|
USE baiyue_firstleg;
|
||||||
@@ -9080,19 +9116,23 @@ INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VA
|
|||||||
('WAREHOUSE_TALLY', 'platform:firstleg:pda:view'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:pda:view'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:pda:review'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:pda:review'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:view'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:view'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit');
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:picking:view');
|
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_permissions_available;
|
DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_permissions_available;
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available()
|
CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available()
|
||||||
BEGIN
|
BEGIN
|
||||||
IF (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
DECLARE operator_permission_count INT DEFAULT 0;
|
||||||
WHERE role_code = 'WAREHOUSE_OPERATOR') <> 5
|
DECLARE picker_permission_count INT DEFAULT 0;
|
||||||
OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
DECLARE tally_permission_count INT DEFAULT 0;
|
||||||
WHERE role_code = 'WAREHOUSE_PICKER') <> 2
|
SELECT COALESCE(SUM(role_code = 'WAREHOUSE_OPERATOR'), 0),
|
||||||
OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
COALESCE(SUM(role_code = 'WAREHOUSE_PICKER'), 0),
|
||||||
WHERE role_code = 'WAREHOUSE_TALLY') <> 12 THEN
|
COALESCE(SUM(role_code = 'WAREHOUSE_TALLY'), 0)
|
||||||
|
INTO operator_permission_count, picker_permission_count, tally_permission_count
|
||||||
|
FROM tmp_phase3_warehouse_role_permission;
|
||||||
|
IF operator_permission_count <> 5
|
||||||
|
OR picker_permission_count <> 2
|
||||||
|
OR tally_permission_count <> 12 THEN
|
||||||
SIGNAL SQLSTATE '45000'
|
SIGNAL SQLSTATE '45000'
|
||||||
SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期';
|
SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期';
|
||||||
END IF;
|
END IF;
|
||||||
@@ -9205,3 +9245,8 @@ CALL assert_phase3_warehouse_roles_ready();
|
|||||||
DROP PROCEDURE assert_phase3_warehouse_roles_ready;
|
DROP PROCEDURE assert_phase3_warehouse_roles_ready;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp_phase3_warehouse_role_permission;
|
DROP TEMPORARY TABLE IF EXISTS tmp_phase3_warehouse_role_permission;
|
||||||
|
|
||||||
|
-- 二、三期对外统一使用 INBOUNDED;历史 WAIT_SPLIT 仅由查询适配为 INBOUNDED,统一迁移不改写主表或历史状态。
|
||||||
|
-- 必须保持为整份脚本最后一个结果,避免后续增量失败却被部署端误判为成功。
|
||||||
|
SELECT 'PASS' AS migration_status,
|
||||||
|
'统一增量全部执行完成;PDA多人协作、船司查询和仓库角色最小权限等全部增量及断言通过' AS message;
|
||||||
|
|||||||
@@ -85,19 +85,23 @@ INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VA
|
|||||||
('WAREHOUSE_TALLY', 'platform:firstleg:pda:view'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:pda:view'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:pda:review'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:pda:review'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:view'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:view'),
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'),
|
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit');
|
||||||
('WAREHOUSE_TALLY', 'platform:firstleg:inbound:picking:view');
|
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_permissions_available;
|
DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_permissions_available;
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available()
|
CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available()
|
||||||
BEGIN
|
BEGIN
|
||||||
IF (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
DECLARE operator_permission_count INT DEFAULT 0;
|
||||||
WHERE role_code = 'WAREHOUSE_OPERATOR') <> 5
|
DECLARE picker_permission_count INT DEFAULT 0;
|
||||||
OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
DECLARE tally_permission_count INT DEFAULT 0;
|
||||||
WHERE role_code = 'WAREHOUSE_PICKER') <> 2
|
SELECT COALESCE(SUM(role_code = 'WAREHOUSE_OPERATOR'), 0),
|
||||||
OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission
|
COALESCE(SUM(role_code = 'WAREHOUSE_PICKER'), 0),
|
||||||
WHERE role_code = 'WAREHOUSE_TALLY') <> 12 THEN
|
COALESCE(SUM(role_code = 'WAREHOUSE_TALLY'), 0)
|
||||||
|
INTO operator_permission_count, picker_permission_count, tally_permission_count
|
||||||
|
FROM tmp_phase3_warehouse_role_permission;
|
||||||
|
IF operator_permission_count <> 5
|
||||||
|
OR picker_permission_count <> 2
|
||||||
|
OR tally_permission_count <> 12 THEN
|
||||||
SIGNAL SQLSTATE '45000'
|
SIGNAL SQLSTATE '45000'
|
||||||
SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期';
|
SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期';
|
||||||
END IF;
|
END IF;
|
||||||
|
|||||||
@@ -17,7 +17,14 @@ class WarehouseRoleSqlContractTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void unifiedDeploymentContainsTheSameWarehouseRoleContract() throws Exception {
|
void unifiedDeploymentContainsTheSameWarehouseRoleContract() throws Exception {
|
||||||
assertWarehouseRoleContract(unifiedSql());
|
String sql = unifiedSql();
|
||||||
|
assertWarehouseRoleContract(sql);
|
||||||
|
assertThat(sql)
|
||||||
|
.doesNotContain("\n ADD COLUMN IF NOT EXISTS")
|
||||||
|
.doesNotContain("DROP CHECK IF EXISTS");
|
||||||
|
assertThat(sql.lastIndexOf("SELECT 'PASS' AS migration_status"))
|
||||||
|
.isGreaterThan(sql.indexOf("CALL assert_phase3_warehouse_roles_ready()"));
|
||||||
|
assertThat(sql.trim()).endsWith("AS message;");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertWarehouseRoleContract(String sql) {
|
private static void assertWarehouseRoleContract(String sql) {
|
||||||
@@ -32,9 +39,9 @@ class WarehouseRoleSqlContractTest {
|
|||||||
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:pda:review'")
|
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:pda:review'")
|
||||||
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'")
|
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'")
|
||||||
.contains("'WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:edit'")
|
.contains("'WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:edit'")
|
||||||
.contains("WHERE role_code = 'WAREHOUSE_OPERATOR') <> 5")
|
.contains("operator_permission_count <> 5")
|
||||||
.contains("WHERE role_code = 'WAREHOUSE_PICKER') <> 2")
|
.contains("picker_permission_count <> 2")
|
||||||
.contains("WHERE role_code = 'WAREHOUSE_TALLY') <> 12")
|
.contains("tally_permission_count <> 12")
|
||||||
.contains("依赖的三期平台权限尚未完整部署")
|
.contains("依赖的三期平台权限尚未完整部署")
|
||||||
.contains("DELETE role_permission")
|
.contains("DELETE role_permission")
|
||||||
.contains("expected.permission_code IS NULL")
|
.contains("expected.permission_code IS NULL")
|
||||||
@@ -61,6 +68,7 @@ class WarehouseRoleSqlContractTest {
|
|||||||
.doesNotContain("platform:firstleg:outbound-dispatch:confirm");
|
.doesNotContain("platform:firstleg:outbound-dispatch:confirm");
|
||||||
assertThat(roleGrantBlock(sql, "WAREHOUSE_TALLY"))
|
assertThat(roleGrantBlock(sql, "WAREHOUSE_TALLY"))
|
||||||
.doesNotContain("platform:firstleg:inbound:loading:complete")
|
.doesNotContain("platform:firstleg:inbound:loading:complete")
|
||||||
|
.doesNotContain("platform:firstleg:inbound:picking:view")
|
||||||
.doesNotContain("platform:firstleg:outbound-dispatch:confirm");
|
.doesNotContain("platform:firstleg:outbound-dispatch:confirm");
|
||||||
assertThat(sql)
|
assertThat(sql)
|
||||||
.doesNotContain("'WAREHOUSE_OPERATOR', 'platform:firstleg:pda:assign'")
|
.doesNotContain("'WAREHOUSE_OPERATOR', 'platform:firstleg:pda:assign'")
|
||||||
|
|||||||
Reference in New Issue
Block a user