fix(sql): 菜单SQL 改用自增分配 id,修复主键冲突
CI/CD Deploy (Admin) / 构建后端镜像并部署 (push) Successful in 1m6s

实测执行时发现硬编码 id 会撞主键:
- t_sys_permission 自增起点 1000,但 t_sys_role_permission 已单独用到 1005
- 写死 1005/1006 插入关联表时触发 Duplicate entry '1005'

改动:
- add_tools_text_diff.sql 改用 LAST_INSERT_ID() 取自增 id
- 授权改为 INSERT...SELECT,覆盖全部有效角色,不再写死 role_id=1
- 清理语句用 JOIN 按 permission_code 定位,避免误删他人菜单
- init.sql 同步修正 id,并补上遗漏的 user:getUserInfo 权限点(id=8)
- 两文件均已实测通过(含连续执行两次的幂等验证)
This commit is contained in:
zhangjiaxun
2026-10-20 22:40:36 +08:00
parent 4aba70b047
commit bf3939c415
2 changed files with 64 additions and 36 deletions
+55 -32
View File
@@ -2,48 +2,71 @@
-- 工具列表菜单 + 文本比对页面
--
-- 与「系统管理」同级的顶级菜单,下挂「文本比对」
-- 菜单由t_sys_permission 表驱动,前端 formatMenuList() 会把 component
-- 菜单由 t_sys_permission 表驱动,前端 formatMenuList() 会把 component
-- 拼成 import('@/view' + component + '.vue'),因此 component 必须带前导斜杠,
-- 且要与 src/view/tools/text-diff.vue 对应
--
-- 幂等:可重复执行,已存在则跳过
-- 幂等:可重复执行,已存在则先清理再插入
-- 执行库:freedom_db
--
-- 注意:id 一律由数据库自增分配,不要硬编码。
-- t_sys_permission 自增起点为 1000,且t_sys_role_permission 已单独用到 1005,
-- 硬编码 1005/1006 会直接撞主键(实测已踩坑,事务回滚后才改用自增)。
-- ============================================================
-- ---------- 1. 清理历史遗留(如果之前插过) ----------
DELETE FROM `t_sys_role_permission` WHERE `permission_id` IN (
SELECT `id` FROM `t_sys_permission` WHERE `permission_code` IN ('tools', 'tools:text-diff')
);
-- ---------- 1. 清理历史遗留 ----------
-- 用 JOIN 按 permission_code 精确定位,避免误删他人菜单
DELETE rp
FROM `t_sys_role_permission` rp
JOIN `t_sys_permission` p ON p.id = rp.permission_id
WHERE p.permission_code IN ('tools', 'tools:text-diff');
DELETE FROM `t_sys_permission` WHERE `permission_code` IN ('tools', 'tools:text-diff');
-- ---------- 2. 插入菜单 ----------
-- 顶级菜单「工具列表」:url 与 component 留空,前端会挂载 Main 布局作为容器
-- 文本比对:component = /tools/text-diff,对应 src/view/tools/text-diff.vue
-- ---------- 2. 插入顶级菜单「工具列表」 ----------
-- url 与 component 留空,前端会挂载 Main 布局作为容器
-- icon 必须在 view-design 图标清单内(ios-apps 已从线上 CSS 校验存在)
INSERT INTO `t_sys_permission`
(`id`, `parent_id`, `permission_code`, `permission_name`, `permission_desc`, `level`,
(`parent_id`, `permission_code`, `permission_name`, `permission_desc`, `level`,
`icon`, `url`, `component`, `sort`, `create_by`, `create_date`, `del_flag`)
VALUES
(1005, 0, 'tools', '工具列表', '与系统管理同级的工具集合',
1, 'ios-apps', '', '', 20, 'admin', NOW(), 0),
(1006, 1005, 'tools:text-diff', '文本比对', '左右文本并排比对,支持字符级高亮、忽略空白与结果导出',
2, 'md-git-compare', '/tools/text-diff', '/tools/text-diff', 1, 'admin', NOW(), 0);
VALUES (0, 'tools', '工具列表', '与系统管理同级的工具集合',
1, 'ios-apps', '', '', 20, 'admin', NOW(), 0);
-- ---------- 3. 授权给超级管理员 ----------
-- 当前系统仅有「超级管理员」一个角色;若后续新增角色,按需补充同样的关联
INSERT INTO `t_sys_role_permission` (`id`, `role_id`, `permission_id`, `create_by`, `create_date`)
VALUES
(1005, 1, 1005, 'admin', NOW()),
(1006, 1, 1006, 'admin', NOW());
SET @tools_id = LAST_INSERT_ID();
-- ---------- 4. 校验 ----------
-- 预期返回 2 行:工具列表(id=1005, parent_id=0) 与 文本比对(id=1006, parent_id=1005)
SELECT `id`, `parent_id`, `permission_code`, `permission_name`, `level`, `icon`, `url`, `component`, `sort`
FROM `t_sys_permission`
WHERE `permission_code` IN ('tools', 'tools:text-diff')
ORDER BY `level`, `sort`;
-- ---------- 3. 插入子菜单「文本比对」 ----------
-- component 必须带前导斜杠且与磁盘文件对应:src/view/tools/text-diff.vue
INSERT INTO `t_sys_permission`
(`parent_id`, `permission_code`, `permission_name`, `permission_desc`, `level`,
`icon`, `url`, `component`, `sort`, `create_by`, `create_date`, `del_flag`)
VALUES (@tools_id, 'tools:text-diff', '文本比对',
'左右文本并排比对,支持字符级高亮、忽略空白与结果导出',
2, 'md-git-compare', '/tools/text-diff', '/tools/text-diff', 1, 'admin', NOW(), 0);
-- 预期返回 2 行:role_id=1 分别关联 permission_id 1005 / 1006
SELECT `id`, `role_id`, `permission_id`
FROM `t_sys_role_permission`
WHERE `permission_id` IN (1005, 1006)
ORDER BY `permission_id`;
SET @diff_id = LAST_INSERT_ID();
-- ---------- 4. 授权给全部有效角色 ----------
-- 不写死 role_id,将来新增角色后重跑本脚本即可自动补齐授权
INSERT INTO `t_sys_role_permission` (`role_id`, `permission_id`, `create_by`, `create_date`)
SELECT r.`id`, p.`pid`, 'admin', NOW()
FROM `t_sys_role` r
CROSS JOIN (SELECT @tools_id AS `pid`
UNION ALL
SELECT @diff_id) p
WHERE r.`del_flag` = 0;
-- ---------- 5. 校验 ----------
-- 预期 2 行:工具列表(parent_id=0, level=1) 与 文本比对(parent_id=工具列表id, level=2)
SELECT p.`id`, p.`parent_id`, p.`permission_code`, p.`permission_name`,
p.`level`, p.`icon`, p.`url`, p.`component`, p.`sort`
FROM `t_sys_permission` p
WHERE p.`permission_code` IN ('tools', 'tools:text-diff')
ORDER BY p.`level`, p.`sort`;
-- 预期:每个有效角色 2 条关联
SELECT rp.`id`, rp.`role_id`, r.`role_name`, rp.`permission_id`, p.`permission_name`
FROM `t_sys_role_permission` rp
JOIN `t_sys_role` r ON r.`id` = rp.`role_id`
JOIN `t_sys_permission` p ON p.`id` = rp.`permission_id`
WHERE p.`permission_code` IN ('tools', 'tools:text-diff')
ORDER BY rp.`role_id`, rp.`permission_id`;