-- 三期仓库常用系统角色:仓库操作员、仓库拣货员、仓库理货员。 -- 本脚本只组合已经存在的权限资源,需在三期 Firstleg/IAM 权限脚本之后执行,可重复部署。 USE baiyue_iam; SET NAMES utf8mb4; DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_ids_available; DELIMITER $$ CREATE PROCEDURE assert_phase3_warehouse_role_ids_available() BEGIN IF EXISTS ( SELECT 1 FROM iam_role WHERE (id = 4000004 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_OPERATOR')) OR (id = 4000005 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_PICKER')) OR (id = 4000006 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_TALLY')) OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_OPERATOR' AND id <> 4000004) OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_PICKER' AND id <> 4000005) OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_TALLY' AND id <> 4000006) ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:4000004-4000006 或角色编码已被占用'; END IF; IF EXISTS ( SELECT 1 FROM iam_data_scope WHERE (id = 6000004 AND role_id <> 4000004) OR (id = 6000005 AND role_id <> 4000005) OR (id = 6000006 AND role_id <> 4000006) OR (role_id = 4000004 AND id <> 6000004) OR (role_id = 4000005 AND id <> 6000005) OR (role_id = 4000006 AND id <> 6000006) ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:6000004-6000006 数据范围ID已被占用'; END IF; END$$ DELIMITER ; CALL assert_phase3_warehouse_role_ids_available(); DROP PROCEDURE assert_phase3_warehouse_role_ids_available; INSERT INTO iam_role ( id, tenant_id, app_code, role_code, role_name, role_type, status, description, deleted, version ) VALUES (4000004, 0, 'PLATFORM', 'WAREHOUSE_OPERATOR', '仓库操作员', 'SYSTEM', 'ACTIVE', '负责排柜、预装、任务分派、装柜完成和国内出仓确认', 0, 0), (4000005, 0, 'PLATFORM', 'WAREHOUSE_PICKER', '仓库拣货员', 'SYSTEM', 'ACTIVE', '负责使用PDA执行柜次拣货和现场拍照', 0, 0), (4000006, 0, 'PLATFORM', 'WAREHOUSE_TALLY', '仓库理货员', 'SYSTEM', 'ACTIVE', '负责入库测量、PDA复核和装柜证据维护', 0, 0) ON DUPLICATE KEY UPDATE role_name = VALUES(role_name), role_type = 'SYSTEM', status = 'ACTIVE', description = VALUES(description), deleted = 0; DROP TEMPORARY TABLE IF EXISTS tmp_phase3_warehouse_role_permission; CREATE TEMPORARY TABLE tmp_phase3_warehouse_role_permission ( role_code VARCHAR(64) NOT NULL, permission_code VARCHAR(128) NOT NULL, PRIMARY KEY (role_code, permission_code) ) ENGINE=MEMORY; -- 操作员:编排装柜并确认国内出仓,不授予财务、系统管理或出仓撤销权限。 INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VALUES ('WAREHOUSE_OPERATOR', 'platform:order'), ('WAREHOUSE_OPERATOR', 'platform:master-data'), ('WAREHOUSE_OPERATOR', 'platform:warehouse:list'), ('WAREHOUSE_OPERATOR', 'platform:pallet:list'), ('WAREHOUSE_OPERATOR', 'platform:location:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:container:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:container:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:container:create'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:container:edit'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:smart-loading:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:smart-loading:create'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:smart-loading:assign'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:smart-loading:delete'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:smart-loading:push'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:preload:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:preload:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:preload:edit'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:preload:complete'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:preload:confirm'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:loading-list:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:loading-list:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:pda:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:pda:assign'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:pda:review'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:edit'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:complete'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:picking:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:list'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:view'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:check'), ('WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:confirm'); -- 拣货员:只允许柜次查询、PDA作业、拣货记录及现场照片,不授予任务分派或复核权限。 INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VALUES ('WAREHOUSE_PICKER', 'platform:order'), ('WAREHOUSE_PICKER', 'platform:master-data'), ('WAREHOUSE_PICKER', 'platform:warehouse:list'), ('WAREHOUSE_PICKER', 'platform:pallet:list'), ('WAREHOUSE_PICKER', 'platform:location:list'), ('WAREHOUSE_PICKER', 'platform:firstleg:inbound:list'), ('WAREHOUSE_PICKER', 'platform:firstleg:inbound:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:container:list'), ('WAREHOUSE_PICKER', 'platform:firstleg:container:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:preload:list'), ('WAREHOUSE_PICKER', 'platform:firstleg:preload:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:loading-list:list'), ('WAREHOUSE_PICKER', 'platform:firstleg:loading-list:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:pda:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:pda:work'), ('WAREHOUSE_PICKER', 'platform:firstleg:inbound:loading:view'), ('WAREHOUSE_PICKER', 'platform:firstleg:inbound:picking:edit'), ('WAREHOUSE_PICKER', 'platform:firstleg:inbound:picking:view'); -- 理货员:负责到仓测量、装柜证据维护和PDA复核,不允许完成装柜或确认出仓。 INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VALUES ('WAREHOUSE_TALLY', 'platform:order'), ('WAREHOUSE_TALLY', 'platform:master-data'), ('WAREHOUSE_TALLY', 'platform:warehouse:list'), ('WAREHOUSE_TALLY', 'platform:pallet:list'), ('WAREHOUSE_TALLY', 'platform:location:list'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:list'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:measure:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:measure:edit'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:measure:submit'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:weight:edit'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:weight:confirm'), ('WAREHOUSE_TALLY', 'platform:firstleg:container:list'), ('WAREHOUSE_TALLY', 'platform:firstleg:container:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:preload:list'), ('WAREHOUSE_TALLY', 'platform:firstleg:preload:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:loading-list:list'), ('WAREHOUSE_TALLY', 'platform:firstleg:loading-list:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:pda:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:pda:review'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:view'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'), ('WAREHOUSE_TALLY', 'platform:firstleg:inbound:picking:view'); DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_permissions_available; DELIMITER $$ CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available() BEGIN IF (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission WHERE role_code = 'WAREHOUSE_OPERATOR') <> 34 OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission WHERE role_code = 'WAREHOUSE_PICKER') <> 18 OR (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission WHERE role_code = 'WAREHOUSE_TALLY') <> 23 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期'; END IF; IF EXISTS ( SELECT 1 FROM tmp_phase3_warehouse_role_permission expected LEFT JOIN iam_permission permission ON permission.tenant_id = 0 AND permission.app_code = 'PLATFORM' AND permission.permission_code = expected.permission_code AND permission.status = 'ACTIVE' AND permission.deleted = 0 WHERE permission.id IS NULL ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:依赖的三期平台权限尚未完整部署'; END IF; END$$ DELIMITER ; CALL assert_phase3_warehouse_role_permissions_available(); DROP PROCEDURE assert_phase3_warehouse_role_permissions_available; INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT role.id, permission.id, 0 FROM tmp_phase3_warehouse_role_permission expected JOIN iam_role role ON role.tenant_id = 0 AND role.app_code = 'PLATFORM' AND role.role_code = expected.role_code AND role.status = 'ACTIVE' AND role.deleted = 0 JOIN iam_permission permission ON permission.tenant_id = 0 AND permission.app_code = 'PLATFORM' AND permission.permission_code = expected.permission_code AND permission.status = 'ACTIVE' AND permission.deleted = 0; INSERT INTO iam_data_scope (id, role_id, tenant_id, scope_type, scope_expression) VALUES (6000004, 4000004, 0, 'TENANT', NULL), (6000005, 4000005, 0, 'TENANT', NULL), (6000006, 4000006, 0, 'TENANT', NULL) ON DUPLICATE KEY UPDATE tenant_id = 0, scope_type = 'TENANT', scope_expression = NULL; DROP PROCEDURE IF EXISTS assert_phase3_warehouse_roles_ready; DELIMITER $$ CREATE PROCEDURE assert_phase3_warehouse_roles_ready() BEGIN IF (SELECT COUNT(*) FROM iam_role WHERE tenant_id = 0 AND app_code = 'PLATFORM' AND role_type = 'SYSTEM' AND status = 'ACTIVE' AND deleted = 0 AND role_code IN ('WAREHOUSE_OPERATOR', 'WAREHOUSE_PICKER', 'WAREHOUSE_TALLY')) <> 3 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:系统角色未完整启用'; END IF; IF (SELECT COUNT(*) FROM tmp_phase3_warehouse_role_permission expected JOIN iam_role role ON role.tenant_id = 0 AND role.app_code = 'PLATFORM' AND role.role_code = expected.role_code JOIN iam_permission permission ON permission.tenant_id = 0 AND permission.app_code = 'PLATFORM' AND permission.permission_code = expected.permission_code JOIN iam_role_permission grant_row ON grant_row.role_id = role.id AND grant_row.permission_id = permission.id AND grant_row.tenant_id = 0) <> 75 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:最小权限授权未完整写入'; END IF; IF (SELECT COUNT(*) FROM iam_data_scope scope_row JOIN iam_role role ON role.id = scope_row.role_id WHERE role.tenant_id = 0 AND role.app_code = 'PLATFORM' AND role.role_code IN ('WAREHOUSE_OPERATOR', 'WAREHOUSE_PICKER', 'WAREHOUSE_TALLY') AND scope_row.tenant_id = 0 AND scope_row.scope_type = 'TENANT') <> 3 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '仓库角色初始化失败:数据范围未完整写入'; END IF; END$$ DELIMITER ; CALL assert_phase3_warehouse_roles_ready(); DROP PROCEDURE assert_phase3_warehouse_roles_ready; DROP TEMPORARY TABLE IF EXISTS tmp_phase3_warehouse_role_permission;