修复:保障菜单补丁原子执行
This commit is contained in:
@@ -496,6 +496,144 @@ from (
|
||||
|
||||
drop temporary table pallet_workflow_legacy_seed_guard;
|
||||
|
||||
-- 在任何永久 DML 前预检 64 个业务菜单固定 ID。ID 不存在时允许继续;已存在时,
|
||||
-- 只有全部稳定字段与期望 seed 一致才允许重跑。冲突会触发临时表主键错误并立即中止。
|
||||
drop temporary table if exists pallet_workflow_menu_seed_expected;
|
||||
create temporary table pallet_workflow_menu_seed_expected (
|
||||
menu_id bigint(20) not null,
|
||||
menu_name varchar(50) not null,
|
||||
parent_id bigint(20) not null,
|
||||
order_num int not null,
|
||||
path varchar(200),
|
||||
component varchar(255),
|
||||
query varchar(255),
|
||||
route_name varchar(50),
|
||||
is_frame int,
|
||||
is_cache int,
|
||||
menu_type char(1),
|
||||
visible char(1),
|
||||
status char(1),
|
||||
perms varchar(100),
|
||||
icon varchar(100),
|
||||
primary key (menu_id)
|
||||
);
|
||||
|
||||
insert into pallet_workflow_menu_seed_expected (
|
||||
menu_id, menu_name, parent_id, order_num, path, component, query, route_name,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon
|
||||
) values
|
||||
(121, '基础资料维护', 1, '10', 'businessMaster', null, '', '', 1, 0, 'M', '0', '0', '', '#'),
|
||||
(122, '业务管理', 1, '11', 'businessOperation', null, '', '', 1, 0, 'M', '0', '0', '', '#'),
|
||||
(123, '报表查询', 1, '12', 'businessReport', null, '', '', 1, 0, 'M', '0', '0', '', '#'),
|
||||
(502, '菌种资料', 121, '1', 'strain', 'master/strain/index', '', '', 1, 0, 'C', '0', '0', 'master:strain:list', '#'),
|
||||
(503, '客户资料', 121, '2', 'customer', 'master/customer/index', '', '', 1, 0, 'C', '0', '0', 'master:customer:list', '#'),
|
||||
(504, '客户现场', 121, '3', 'site', 'master/site/index', '', '', 1, 0, 'C', '0', '0', 'master:site:list', '#'),
|
||||
(505, '产线资料', 121, '4', 'line', 'master/line/index', '', '', 1, 0, 'C', '0', '0', 'master:line:list', '#'),
|
||||
(506, '仓库资料', 121, '5', 'warehouse', 'master/warehouse/index', '', '', 1, 0, 'C', '0', '0', 'master:warehouse:list', '#'),
|
||||
(507, '托盘资料', 121, '6', 'pallet', 'master/pallet/index', '', '', 1, 0, 'C', '0', '0', 'master:pallet:list', '#'),
|
||||
(508, '仓库入库', 122, '1', 'inbound', 'business/inbound/index', '', '', 1, 0, 'C', '0', '0', 'business:inbound:list', '#'),
|
||||
(509, '工厂装填', 122, '2', 'filling', 'business/filling/index', '', '', 1, 0, 'C', '0', '0', 'business:filling:list', '#'),
|
||||
(510, '发货出库', 122, '3', 'shipment', 'business/shipment/index', '', '', 1, 0, 'C', '0', '0', 'business:shipment:list', '#'),
|
||||
(511, '客户现场使用', 122, '4', 'usage', 'business/usage/index', '', '', 1, 0, 'C', '0', '0', 'business:usage:list', '#'),
|
||||
(512, '退回仓库', 122, '5', 'return', 'business/return/index', '', '', 1, 0, 'C', '0', '0', 'business:return:list', '#'),
|
||||
(513, '托盘库存', 123, '1', 'palletInventory', 'report/palletInventory/index', '', '', 1, 0, 'C', '0', '0', 'report:palletinventory:list', '#'),
|
||||
(514, '装填记录', 123, '2', 'reportFilling', 'report/filling/index', '', '', 1, 0, 'C', '0', '0', 'report:filling:list', '#'),
|
||||
(515, '发货出库', 123, '3', 'reportShipment', 'report/shipment/index', '', '', 1, 0, 'C', '0', '0', 'report:shipment:list', '#'),
|
||||
(516, '产线消耗', 123, '4', 'consumption', 'report/consumption/index', '', '', 1, 0, 'C', '0', '0', 'report:consumption:list', '#'),
|
||||
(517, '退回仓库', 123, '5', 'reportReturn', 'report/return/index', '', '', 1, 0, 'C', '0', '0', 'report:return:list', '#'),
|
||||
(518, '托盘追溯', 123, '6', 'palletTrace', 'report/palletTrace/index', '', '', 1, 0, 'C', '0', '0', 'report:pallettrace:list', '#'),
|
||||
(1065, '菌种查询', 502, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:query', '#'),
|
||||
(1066, '菌种新增', 502, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:add', '#'),
|
||||
(1067, '菌种修改', 502, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:edit', '#'),
|
||||
(1068, '菌种删除', 502, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:remove', '#'),
|
||||
(1069, '客户查询', 503, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:query', '#'),
|
||||
(1070, '客户新增', 503, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:add', '#'),
|
||||
(1071, '客户修改', 503, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:edit', '#'),
|
||||
(1072, '客户删除', 503, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:remove', '#'),
|
||||
(1073, '现场查询', 504, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:query', '#'),
|
||||
(1074, '现场新增', 504, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:add', '#'),
|
||||
(1075, '现场修改', 504, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:edit', '#'),
|
||||
(1076, '现场删除', 504, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:remove', '#'),
|
||||
(1077, '分配用户', 504, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:assign', '#'),
|
||||
(1078, '产线查询', 505, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:query', '#'),
|
||||
(1079, '产线新增', 505, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:add', '#'),
|
||||
(1080, '产线修改', 505, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:edit', '#'),
|
||||
(1081, '产线删除', 505, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:remove', '#'),
|
||||
(1082, '仓库查询', 506, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:query', '#'),
|
||||
(1083, '仓库新增', 506, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:add', '#'),
|
||||
(1084, '仓库修改', 506, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:edit', '#'),
|
||||
(1085, '仓库删除', 506, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:remove', '#'),
|
||||
(1086, '分配用户', 506, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:assign', '#'),
|
||||
(1087, '托盘查询', 507, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:query', '#'),
|
||||
(1088, '托盘新增', 507, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:add', '#'),
|
||||
(1089, '托盘修改', 507, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:edit', '#'),
|
||||
(1090, '托盘删除', 507, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:remove', '#'),
|
||||
(1091, '托盘打印', 507, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:print', '#'),
|
||||
(1092, '入库查询', 508, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:query', '#'),
|
||||
(1093, '入库新增', 508, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:add', '#'),
|
||||
(1094, '入库修改', 508, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:edit', '#'),
|
||||
(1095, '入库删除', 508, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:remove', '#'),
|
||||
(1096, '入库确认', 508, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:confirm', '#'),
|
||||
(1097, '装填查询', 509, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:query', '#'),
|
||||
(1098, '装填新增', 509, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:add', '#'),
|
||||
(1099, '发货查询', 510, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:query', '#'),
|
||||
(1100, '发货新增', 510, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:add', '#'),
|
||||
(1101, '发货修改', 510, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:edit', '#'),
|
||||
(1102, '发货删除', 510, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:remove', '#'),
|
||||
(1103, '发货确认', 510, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:confirm', '#'),
|
||||
(1104, '使用查询', 511, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:query', '#'),
|
||||
(1105, '使用新增', 511, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:add', '#'),
|
||||
(1106, '退回查询', 512, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:query', '#'),
|
||||
(1107, '退回申请', 512, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:request', '#'),
|
||||
(1108, '退回确认', 512, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:confirm', '#');
|
||||
|
||||
drop temporary table if exists pallet_workflow_menu_seed_guard;
|
||||
create temporary table pallet_workflow_menu_seed_guard (
|
||||
guard_token varchar(64) not null,
|
||||
primary key (guard_token)
|
||||
);
|
||||
|
||||
insert into pallet_workflow_menu_seed_guard (guard_token)
|
||||
select 'business-menu-seed-conflict' as guard_token
|
||||
union all
|
||||
select 'business-menu-seed-conflict' as guard_token
|
||||
where exists (
|
||||
select 1
|
||||
from sys_menu as actual
|
||||
join pallet_workflow_menu_seed_expected as expected
|
||||
on actual.menu_id = expected.menu_id
|
||||
where not (
|
||||
actual.menu_name <=> expected.menu_name
|
||||
and actual.parent_id <=> expected.parent_id
|
||||
and actual.order_num <=> expected.order_num
|
||||
and actual.path <=> expected.path
|
||||
and actual.component <=> expected.component
|
||||
and actual.query <=> expected.query
|
||||
and actual.route_name <=> expected.route_name
|
||||
and actual.is_frame <=> expected.is_frame
|
||||
and actual.is_cache <=> expected.is_cache
|
||||
and actual.menu_type <=> expected.menu_type
|
||||
and actual.visible <=> expected.visible
|
||||
and actual.status <=> expected.status
|
||||
and actual.perms <=> expected.perms
|
||||
and actual.icon <=> expected.icon
|
||||
)
|
||||
);
|
||||
|
||||
drop temporary table pallet_workflow_menu_seed_guard;
|
||||
drop temporary table pallet_workflow_menu_seed_expected;
|
||||
|
||||
-- 保存当前会话模式,再无空项、无重复地启用 STRICT_ALL_TABLES,确保菜单冲突按错误中止。
|
||||
set @pallet_workflow_original_sql_mode = @@session.sql_mode;
|
||||
set session sql_mode = concat_ws(',',
|
||||
nullif(@pallet_workflow_original_sql_mode, ''),
|
||||
if(find_in_set('STRICT_ALL_TABLES', @pallet_workflow_original_sql_mode) = 0,
|
||||
'STRICT_ALL_TABLES',
|
||||
null));
|
||||
|
||||
-- 临时期望表和 guard 已在事务外清理,避免临时表 DDL 影响永久 DML 的事务边界。
|
||||
start transaction;
|
||||
|
||||
-- 先解除所有待清理菜单的历史角色关联。
|
||||
delete from sys_role_menu
|
||||
where menu_id in (4, 99, 118, 119, 1061, 1062, 1063, 1064);
|
||||
@@ -522,14 +660,6 @@ where dict_type = 'ai_provider_type';
|
||||
delete from sys_menu
|
||||
where menu_id = 99;
|
||||
|
||||
-- 保存当前会话模式,再无空项、无重复地启用 STRICT_ALL_TABLES,确保菜单冲突按错误中止。
|
||||
set @pallet_workflow_original_sql_mode = @@session.sql_mode;
|
||||
set session sql_mode = concat_ws(',',
|
||||
nullif(@pallet_workflow_original_sql_mode, ''),
|
||||
if(find_in_set('STRICT_ALL_TABLES', @pallet_workflow_original_sql_mode) = 0,
|
||||
'STRICT_ALL_TABLES',
|
||||
null));
|
||||
|
||||
-- 固定 ID 已存在时,只有全部稳定字段一致才允许幂等空操作。
|
||||
-- 任一稳定字段冲突都会令 menu_name 为 NULL,触发 menu_name NOT NULL 约束并中止整条语句。
|
||||
-- 必须人工解决冲突;本补丁不会静默覆盖未知 ID。
|
||||
@@ -618,7 +748,9 @@ on duplicate key update
|
||||
null
|
||||
);
|
||||
|
||||
-- seed 成功后立即恢复原会话模式;后续仅执行只读人工核对,无需继续保持严格模式。
|
||||
commit;
|
||||
|
||||
-- 永久 DML 提交成功后立即恢复原会话模式;后续仅执行只读人工核对,无需继续保持严格模式。
|
||||
set session sql_mode = @pallet_workflow_original_sql_mode;
|
||||
|
||||
-- 人工核对业务菜单固定 ID;查询结果必须为 64 行,且各字段应与本补丁 seed 一致。
|
||||
|
||||
Reference in New Issue
Block a user