xinli/权限逻辑修复说明.md
2025-12-02 15:12:55 +08:00

262 lines
6.9 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.

# 🔧 权限逻辑修复说明
## 📋 问题描述
**用户反馈**
- ❌ 分配了权限的问卷/量表**看不到**
- ✅ 没有分配权限的问卷/量表**却能看到**
- 权限逻辑完全相反!
## 🔍 问题根源
### 原来的错误逻辑
```java
// 错误逻辑(已修复)
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);
}
```
**问题**
1. 未配置权限的问卷/量表 → 对所有人开放(错误!)
2. 已配置权限的问卷/量表 → 只有授权用户能看到
3. 结果:用户看到的都是"没分配权限"的内容
### 正确的逻辑
```java
// 正确逻辑(已修复)
if (scaleId != null && allowedScaleIds.contains(scaleId))
{
filtered.add(scale);
}
```
**修复后**
- ✅ 用户只能看到**分配给自己**的问卷/量表
- ❌ 未分配的问卷/量表**完全看不到**
## ✅ 已修复内容
### 修改文件
1. **PsyQuestionnaireController.java**
- 修改 `filterQuestionnaireListByPermission()` 方法
- 移除错误的"公开未配置权限问卷"逻辑
- 改为:只显示用户有权限的问卷
2. **PsyScaleController.java**
- 修改 `filterScaleListByPermission()` 方法
- 统一量表和问卷的权限逻辑
- 移除 `resolveRestrictedScaleIds()` 方法(不再需要)
### 核心修改
#### 修改前
```java
// 如果该问卷未配置权限,对所有人开放 ❌
boolean restricted = restrictedScaleIds != null && restrictedScaleIds.contains(scaleId);
if (!restricted)
{
filtered.add(questionnaire);
continue;
}
// 如果配置了权限,检查用户是否有权限
if (allowedScaleIds.contains(scaleId))
{
filtered.add(questionnaire);
}
```
#### 修改后
```java
// 只显示用户有权限的问卷 ✅
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: 通过用户管理界面
1. 进入 **系统管理****用户管理**
2. 找到目标用户,点击 **编辑**
3. 在"量表权限"选项卡中勾选该用户可访问的问卷
4. 保存
#### 方法 2: 通过 SQL 直接插入
```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
```
## 🧪 测试验证
### 测试步骤
#### 准备数据
```sql
-- 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());
```
#### 测试登录
1. 使用 test_user 登录系统
2. 进入"心理测评"或"学员测试"页面
3. **预期结果**
- ✅ 只能看到问卷1和问卷2
- ❌ 看不到其他问卷3、4、5...
#### 测试管理员
1. 使用管理员账号登录
2. 进入"心理测评"页面
3. **预期结果**
- ✅ 能看到所有问卷和量表
## 🚀 部署步骤
### 1. 重新编译后端
```bash
cd c:\Users\Administrator\Desktop\Project\xinli
mvn clean package -DskipTests
```
### 2. 部署新的 jar 文件
```bash
# 停止旧服务
# 根据你的部署方式systemd、supervisor、手动等
# 部署新 jar
# 位置ry-xinli-admin/target/ry-xinli-admin.jar
# 启动新服务
```
### 3. 验证修复
1. 清除浏览器缓存
2. 使用普通用户登录
3. 查看问卷列表
4. 确认只能看到已分配权限的问卷
## 📝 注意事项
### 1. 前端无需修改
- ✅ 前端代码不需要改动
- ✅ 权限过滤在后端完成
- ✅ 前端调用 API 保持不变
### 2. 数据库无需修改
- ✅ 使用现有的 `psy_scale_permission`
- ✅ 不需要执行 SQL 脚本
- ✅ 现有权限数据继续有效
### 3. 向后兼容性
- ⚠️ **行为变化**:修复后,未分配权限的用户看不到任何问卷
- ⚠️ 需要为现有用户重新分配权限
- ⚠️ 建议先在测试环境验证
### 4. 批量分配权限
如果需要为多个用户批量分配权限:
```sql
-- 为所有学员角色的用户分配问卷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
**影响范围**:问卷和量表列表的权限控制
**部署状态**:⏳ 待重新编译部署后端