6.9 KiB
6.9 KiB
🔧 权限逻辑修复说明
📋 问题描述
用户反馈:
- ❌ 分配了权限的问卷/量表看不到
- ✅ 没有分配权限的问卷/量表却能看到
- 权限逻辑完全相反!
🔍 问题根源
原来的错误逻辑
// 错误逻辑(已修复)
if ("questionnaire".equalsIgnoreCase(sourceType))
{
boolean restricted = restrictedScaleIds != null && restrictedScaleIds.contains(scaleId);
if (!restricted) // 如果未配置权限,就显示 ❌
{
filtered.add(scale);
continue;
}
}
if (scaleId != null && allowedScaleIds.contains(scaleId)) // 如果有权限,才显示
{
filtered.add(scale);
}
问题:
- 未配置权限的问卷/量表 → 对所有人开放(错误!)
- 已配置权限的问卷/量表 → 只有授权用户能看到
- 结果:用户看到的都是"没分配权限"的内容
正确的逻辑
// 正确逻辑(已修复)
if (scaleId != null && allowedScaleIds.contains(scaleId))
{
filtered.add(scale);
}
修复后:
- ✅ 用户只能看到分配给自己的问卷/量表
- ❌ 未分配的问卷/量表完全看不到
✅ 已修复内容
修改文件
-
PsyQuestionnaireController.java
- 修改
filterQuestionnaireListByPermission()方法 - 移除错误的"公开未配置权限问卷"逻辑
- 改为:只显示用户有权限的问卷
- 修改
-
PsyScaleController.java
- 修改
filterScaleListByPermission()方法 - 统一量表和问卷的权限逻辑
- 移除
resolveRestrictedScaleIds()方法(不再需要)
- 修改
核心修改
修改前
// 如果该问卷未配置权限,对所有人开放 ❌
boolean restricted = restrictedScaleIds != null && restrictedScaleIds.contains(scaleId);
if (!restricted)
{
filtered.add(questionnaire);
continue;
}
// 如果配置了权限,检查用户是否有权限
if (allowedScaleIds.contains(scaleId))
{
filtered.add(questionnaire);
}
修改后
// 只显示用户有权限的问卷 ✅
if (allowedScaleIds.contains(scaleId))
{
filtered.add(questionnaire);
}
🎯 修复后的行为
场景 1: 管理员(userId = 1 或有管理权限)
- ✅ 看到所有问卷和量表
- 理由:
allowedScaleIds = null,不进行权限过滤
场景 2: 普通用户(student 角色)
假设:
- 系统中有 5 个问卷:A、B、C、D、E
- 用户被分配了问卷 A、B 的权限
修复前:
- ❌ 能看到:C、D、E(未分配权限的)
- ❌ 看不到:A、B(已分配权限的)
修复后:
- ✅ 能看到:A、B(已分配权限的)
- ✅ 看不到:C、D、E(未分配权限的)
📊 权限分配说明
如何为用户分配问卷权限
方法 1: 通过用户管理界面
- 进入 系统管理 → 用户管理
- 找到目标用户,点击 编辑
- 在"量表权限"选项卡中勾选该用户可访问的问卷
- 保存
方法 2: 通过 SQL 直接插入
-- 为用户分配问卷权限
-- 注意:问卷ID使用负数(-questionnaireId)
INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time)
VALUES
(用户ID, -问卷ID, '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());
-- 为用户ID=2 分配量表ID=3 的权限
INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time)
VALUES (2, 3, '0', 'admin', NOW());
问卷ID的特殊标识
重要:在权限表中,问卷使用负数ID!
- 量表:使用正数 ID (1, 2, 3, ...)
- 问卷:使用负数 ID (-1, -2, -3, ...)
原因:量表和问卷使用同一张权限表,用负数区分
示例:
问卷ID = 5 → 权限表中存储为 scale_id = -5
量表ID = 5 → 权限表中存储为 scale_id = 5
🧪 测试验证
测试步骤
准备数据
-- 1. 创建测试用户(假设ID=100)
INSERT INTO sys_user (user_name, nick_name, password, status)
VALUES ('test_user', '测试用户', '加密后的密码', '0');
-- 2. 分配学员角色
-- (根据你的系统具体操作)
-- 3. 分配权限:只分配问卷ID=1和问卷ID=2的权限
INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time)
VALUES
(100, -1, '0', 'admin', NOW()),
(100, -2, '0', 'admin', NOW());
测试登录
- 使用 test_user 登录系统
- 进入"心理测评"或"学员测试"页面
- 预期结果:
- ✅ 只能看到问卷1和问卷2
- ❌ 看不到其他问卷(3、4、5...)
测试管理员
- 使用管理员账号登录
- 进入"心理测评"页面
- 预期结果:
- ✅ 能看到所有问卷和量表
🚀 部署步骤
1. 重新编译后端
cd c:\Users\Administrator\Desktop\Project\xinli
mvn clean package -DskipTests
2. 部署新的 jar 文件
# 停止旧服务
# 根据你的部署方式(systemd、supervisor、手动等)
# 部署新 jar
# 位置:ry-xinli-admin/target/ry-xinli-admin.jar
# 启动新服务
3. 验证修复
- 清除浏览器缓存
- 使用普通用户登录
- 查看问卷列表
- 确认只能看到已分配权限的问卷
📝 注意事项
1. 前端无需修改
- ✅ 前端代码不需要改动
- ✅ 权限过滤在后端完成
- ✅ 前端调用 API 保持不变
2. 数据库无需修改
- ✅ 使用现有的
psy_scale_permission表 - ✅ 不需要执行 SQL 脚本
- ✅ 现有权限数据继续有效
3. 向后兼容性
- ⚠️ 行为变化:修复后,未分配权限的用户看不到任何问卷
- ⚠️ 需要为现有用户重新分配权限
- ⚠️ 建议先在测试环境验证
4. 批量分配权限
如果需要为多个用户批量分配权限:
-- 为所有学员角色的用户分配问卷1的权限
INSERT INTO psy_scale_permission (user_id, scale_id, status, create_by, create_time)
SELECT u.user_id, -1, '0', 'admin', NOW()
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
WHERE r.role_key = 'student'
AND NOT EXISTS (
SELECT 1 FROM psy_scale_permission p
WHERE p.user_id = u.user_id AND p.scale_id = -1
);
✅ 修复总结
| 项目 | 修复前 | 修复后 |
|---|---|---|
| 权限逻辑 | ❌ 相反 | ✅ 正确 |
| 用户看到的 | 未分配的内容 | 已分配的内容 |
| 管理员 | ✅ 看所有 | ✅ 看所有 |
| 普通用户 | ❌ 看错误内容 | ✅ 只看授权内容 |
| 代码复杂度 | 复杂(双重判断) | 简化(单一判断) |
修复时间:2024年12月2日
修复人员:Cascade AI
影响范围:问卷和量表列表的权限控制
部署状态:⏳ 待重新编译部署后端