Files
his/迁移记录-DB变更记录/菜单路由地址重复问题修复指南.md
chenqi 0c35044231 feat(menu): 优化菜单路径唯一性校验并更新前端界面
- 在SysLoginController中添加optionMap数据返回
- 添加JSQLParser依赖支持MyBatis Plus功能
- 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验
- 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑
- 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询
- 在前端路由中注释患者管理相关路由配置
- 在用户store中添加optionMap配置项并优先从optionMap获取医院名称
- 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计
- 更新检查项目设置页面的导航栏样式和交互体验
- 优化门诊记录页面的搜索条件和表格展示功能
- 添加性别和状态筛选条件并改进数据加载逻辑
2026-01-03 23:47:09 +08:00

141 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 菜单路由地址重复问题修复指南
## 问题描述
在菜单管理中,修改菜单时即使不做任何修改直接点确定,仍然提示"路由地址已存在"。
## 问题原因
数据库中 `sys_menu` 表存在多条记录使用了相同的 `path` 值,导致校验逻辑误判。
## 解决步骤
### 步骤1查找重复的 path
在数据库中执行以下SQL查询
**PostgreSQL 版本(当前使用):**
```sql
-- 查找所有重复的 path
SELECT
path,
COUNT(*) as count,
STRING_AGG(CAST(menu_id AS TEXT), ', ') as menu_ids,
STRING_AGG(menu_name, ', ') as menu_names
FROM sys_menu
GROUP BY path
HAVING COUNT(*) > 1;
```
**MySQL 版本:**
```sql
-- 查找所有重复的 path
SELECT
path,
COUNT(*) as count,
GROUP_CONCAT(menu_id) as menu_ids,
GROUP_CONCAT(menu_name) as menu_names
FROM sys_menu
GROUP BY path
HAVING COUNT(*) > 1;
```
### 步骤2查看具体重复记录的详细信息
将上面的查询结果中的 path 值替换到下面的SQL中
```sql
-- 查看某个重复 path 的详细信息
SELECT * FROM sys_menu
WHERE path = 'your_duplicate_path_value'
ORDER BY menu_id;
```
### 步骤3删除重复记录保留 menu_id 最小的记录)
```sql
DELETE FROM sys_menu
WHERE menu_id IN (
SELECT menu_id FROM (
SELECT menu_id,
ROW_NUMBER() OVER (PARTITION BY path ORDER BY menu_id) as rn
FROM sys_menu
) t
WHERE rn > 1
);
```
### 步骤4验证修复结果
```sql
-- 验证是否还有重复的 path
SELECT
path,
COUNT(*) as count
FROM sys_menu
GROUP BY path
HAVING COUNT(*) > 1;
```
如果没有查询结果,说明重复数据已经清理完毕。
## 代码修改
### 已完成的代码修改:
1. **SysMenuMapper.java** - 新增方法
```java
public SysMenu selectMenuByPathExcludeId(@Param("path") String path, @Param("menuId") Long menuId);
```
2. **SysMenuMapper.xml** - 新增查询
```xml
<select id="selectMenuByPathExcludeId" resultMap="SysMenuResult">
<include refid="selectMenuVo"/>
where path = #{path} and menu_id != #{menuId}
</select>
```
3. **SysMenuServiceImpl.java** - 修改校验逻辑
```java
@Override
public int updateMenu(SysMenu menu) {
//路径Path唯一性判断排除当前菜单本身
String path = menu.getPath();
if (StringUtils.isNotBlank(path)) {
SysMenu sysMenu = menuMapper.selectMenuByPathExcludeId(menu.getPath(), menu.getMenuId());
if (sysMenu != null) {
log.warn("路由地址已存在 - menuId: {}, path: {}, 存在的menuId: {}",
menu.getMenuId(), menu.getPath(), sysMenu.getMenuId());
return -1; // 路由地址已存在
}
}
// 执行更新
return menuMapper.updateMenu(menu);
}
```
## 调试信息
当系统提示"路由地址已存在"时,请查看后端日志,会输出类似以下信息:
```
路由地址已存在 - menuId: 123, path: 'some/path', 存在的menuId: 456
```
这可以帮助您快速定位是哪两个菜单发生了冲突。
## 注意事项
1. 在删除重复记录前,请先备份数据库
2. 建议在测试环境先验证,确认无误后再在生产环境执行
3. 如果某个 path 确实需要被多个菜单使用,需要修改业务逻辑
## 预防措施
建议在数据库中为 `path` 字段添加唯一索引,从数据库层面防止重复:
**PostgreSQL 版本:**
```sql
-- 注意:执行前需要先清理重复数据
CREATE UNIQUE INDEX uk_path ON sys_menu(path);
```
**MySQL 版本:**
```sql
-- 注意:执行前需要先清理重复数据
ALTER TABLE sys_menu ADD UNIQUE KEY uk_path (path);
```