# 🔧 最终权限修复说明 ## 📋 明确的需求 **用户需求**:无论任何时候,用户只能显示被分配权限的量表或问卷。 ## ✅ 已完成的修复 ### 1. 统一的权限逻辑 **简化后的逻辑**: ```java // 用户只能看到分配给自己的量表和问卷 if (scaleId != null && allowedScaleIds.contains(scaleId)) { filtered.add(scale); // 有权限,添加 } // 没有权限的,直接跳过 ``` **特殊情况**: - **管理员**(userId=1 或有管理权限):看到所有内容 - **普通用户**:只看到分配给自己的内容 ### 2. 修改的文件 1. **PsyScaleController.java** - `filterScaleListByPermission()` - 简化为单一判断 - `resolveAllowedScaleIdsForCurrentUser()` - 添加日志输出 2. **PsyQuestionnaireController.java** - `filterQuestionnaireListByPermission()` - 简化为单一判断 - `resolveAllowedScaleIdsForCurrentUser()` - 添加日志输出 ### 3. 添加的调试日志 ```java // 会输出以下日志: logger.info("用户 userId={} 的权限列表: {}", currentUserId, scaleIds); logger.info("权限过滤结果: 总数={}, 过滤后={}, 用户权限数={}", ...); logger.debug("权限过滤: 允许访问 scaleId={}, scaleName={}", ...); logger.debug("权限过滤: 拒绝访问 scaleId={}, scaleName={}", ...); ``` ## 🔍 排查"不能正常显示"的问题 ### 可能的原因 #### 原因 1: 权限数据不正确 **问题**:数据库中的权限记录可能有问题 **检查方法**: ```sql -- 查看用户的权限列表 SELECT * FROM psy_scale_permission WHERE user_id = 你的用户ID AND status = '0'; ``` **注意事项**: - 量表使用**正数ID**(如:1, 2, 3) - 问卷使用**负数ID**(如:-1, -2, -3) #### 原因 2: 用户没有被分配权限 **问题**:用户在权限表中没有记录 **解决方法**:为用户分配权限 ```sql -- 为用户ID=2分配量表ID=1的权限 INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time) VALUES (2, 1, '0', 'admin', NOW()); -- 为用户ID=2分配问卷ID=1的权限(注意使用负数) INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time) VALUES (2, -1, '0', 'admin', NOW()); ``` #### 原因 3: ID映射错误 **问题**:前端显示的问卷,在权限表中没有对应的负数ID **检查方法**: ```sql -- 检查问卷ID和权限表中的ID是否匹配 SELECT q.questionnaire_id, q.questionnaire_name, -q.questionnaire_id as 权限表应该用的ID, p.scale_id as 权限表实际的ID FROM psy_questionnaire q LEFT JOIN psy_scale_permission p ON -q.questionnaire_id = p.scale_id WHERE p.user_id = 你的用户ID; ``` #### 原因 4: 用户被识别为管理员 **问题**:用户ID=1 或有 `psychology:scale:list` 权限,导致看到所有内容 **检查方法**: ```sql -- 检查用户ID SELECT user_id FROM sys_user WHERE user_name = '你的用户名'; -- 检查用户权限 SELECT r.role_name, m.perms FROM sys_user u INNER JOIN sys_user_role ur ON u.user_id = ur.user_id INNER JOIN sys_role r ON ur.role_id = r.role_id LEFT JOIN sys_role_menu rm ON r.role_id = rm.role_id LEFT JOIN sys_menu m ON rm.menu_id = m.menu_id WHERE u.user_name = '你的用户名'; ``` ## 📝 使用提供的工具 ### 1. SQL检查脚本 运行 `检查权限数据.sql` 中的查询: ```sql -- 1. 查看用户权限数量 SELECT u.user_id, u.user_name, COUNT(*) FROM ... -- 2. 查看用户的详细权限 SELECT * FROM psy_scale_permission WHERE user_id = X ... -- 3. 查看量表权限分配情况 SELECT s.scale_id, s.scale_name, COUNT(*) FROM ... -- 10. 快速诊断 WITH user_permissions AS (...) ... ``` ### 2. 后端日志 重新编译部署后,查看日志文件: ```bash # 查找权限相关日志 tail -f logs/xinli.log | grep "权限" # 应该看到类似输出: # 用户 userId=2 的权限列表: [1, 3, -1, -2] # 权限过滤结果: 总数=10, 过滤后=4, 用户权限数=4 ``` ## 🚀 部署步骤 ### 1. 重新编译后端 ```bash cd c:\Users\Administrator\Desktop\Project\xinli mvn clean package -DskipTests ``` ### 2. 备份当前jar ```bash # 备份当前运行的jar文件 copy ry-xinli-admin\target\ry-xinli-admin.jar ry-xinli-admin.jar.backup ``` ### 3. 停止服务 ```bash # 根据你的部署方式停止服务 # systemctl stop xinli # 或手动kill进程 ``` ### 4. 替换jar文件 ```bash # 将新编译的jar复制到部署目录 ``` ### 5. 启动服务 ```bash # 启动新服务 # systemctl start xinli ``` ### 6. 查看日志 ```bash # 检查启动日志 tail -f logs/xinli.log ``` ## 🧪 测试验证 ### 测试步骤 1. **清除浏览器缓存** - 按 Ctrl+Shift+Delete - 清除所有缓存和Cookie 2. **使用普通用户登录** - 不要使用admin或管理员账号 3. **查看问卷/量表列表** - 记录看到的数量 4. **对比数据库** - 运行SQL检查脚本 - 对比数量是否一致 ### 预期结果 假设: - 数据库中有 10 个量表、8 个问卷 - 用户被分配了 3 个量表、2 个问卷的权限 **应该看到**: - 量表列表:3 个 - 问卷列表:2 个 - 合计列表(包含问卷):5 个 ## ❓ 常见问题 ### Q1: 管理员看不到所有内容? **A**: 检查用户ID是否为1,或是否有管理权限 ```sql SELECT user_id FROM sys_user WHERE user_name = 'admin'; ``` ### Q2: 普通用户看到所有内容? **A**: 可能被误判为管理员,检查权限配置 ### Q3: 用户看不到任何内容? **A**: 检查权限表中是否有该用户的记录 ```sql SELECT COUNT(*) FROM psy_scale_permission WHERE user_id = X AND status = '0'; ``` ### Q4: 数量不一致? **A**: 1. 检查前端是否缓存 2. 检查后端日志中的过滤数量 3. 对比数据库中的实际权限数 ## 📊 数据一致性检查清单 - [ ] 权限表中的 scale_id 正确(量表用正数,问卷用负数) - [ ] 用户有对应的权限记录 - [ ] 权限记录的 status = '0'(启用状态) - [ ] 量表/问卷确实存在(没有孤立的权限记录) - [ ] 用户不是管理员(除非确实需要看所有内容) ## 🎯 快速诊断命令 ```sql -- 一键诊断用户权限(替换 USER_ID) WITH user_info AS ( SELECT 2 as uid, -- 替换为实际用户ID (SELECT COUNT(*) FROM psy_scale_permission WHERE user_id = 2 AND status = '0') as perm_count ), expected AS ( SELECT COUNT(DISTINCT s.scale_id) as scale_count, COUNT(DISTINCT q.questionnaire_id) as quest_count FROM user_info ui CROSS JOIN psy_scale s INNER JOIN psy_scale_permission p1 ON s.scale_id = p1.scale_id AND p1.user_id = ui.uid CROSS JOIN psy_questionnaire q INNER JOIN psy_scale_permission p2 ON -q.questionnaire_id = p2.scale_id AND p2.user_id = ui.uid ) SELECT ui.uid as 用户ID, ui.perm_count as 总权限数, e.scale_count as 应看到量表数, e.quest_count as 应看到问卷数, (e.scale_count + e.quest_count) as 应看到总数 FROM user_info ui, expected e; ``` --- **修复完成时间**:2024年12月2日 **版本**:v3.0 - 最终简化版 **下一步**:重新编译部署 + 使用SQL脚本检查数据