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

7.1 KiB
Raw Blame History

🔧 最终权限修复说明

📋 明确的需求

用户需求:无论任何时候,用户只能显示被分配权限的量表或问卷。

已完成的修复

1. 统一的权限逻辑

简化后的逻辑

// 用户只能看到分配给自己的量表和问卷
if (scaleId != null && allowedScaleIds.contains(scaleId))
{
    filtered.add(scale);  // 有权限,添加
}
// 没有权限的,直接跳过

特殊情况

  • 管理员userId=1 或有管理权限):看到所有内容
  • 普通用户:只看到分配给自己的内容

2. 修改的文件

  1. PsyScaleController.java

    • filterScaleListByPermission() - 简化为单一判断
    • resolveAllowedScaleIdsForCurrentUser() - 添加日志输出
  2. PsyQuestionnaireController.java

    • filterQuestionnaireListByPermission() - 简化为单一判断
    • resolveAllowedScaleIdsForCurrentUser() - 添加日志输出

3. 添加的调试日志

// 会输出以下日志:
logger.info("用户 userId={} 的权限列表: {}", currentUserId, scaleIds);
logger.info("权限过滤结果: 总数={}, 过滤后={}, 用户权限数={}", ...);
logger.debug("权限过滤: 允许访问 scaleId={}, scaleName={}", ...);
logger.debug("权限过滤: 拒绝访问 scaleId={}, scaleName={}", ...);

🔍 排查"不能正常显示"的问题

可能的原因

原因 1: 权限数据不正确

问题:数据库中的权限记录可能有问题

检查方法

-- 查看用户的权限列表
SELECT * FROM psy_scale_permission 
WHERE user_id = 你的用户ID AND status = '0';

注意事项

  • 量表使用正数ID1, 2, 3
  • 问卷使用负数ID(如:-1, -2, -3

原因 2: 用户没有被分配权限

问题:用户在权限表中没有记录

解决方法:为用户分配权限

-- 为用户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

检查方法

-- 检查问卷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 权限,导致看到所有内容

检查方法

-- 检查用户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 中的查询:

-- 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. 后端日志

重新编译部署后,查看日志文件:

# 查找权限相关日志
tail -f logs/xinli.log | grep "权限"

# 应该看到类似输出:
# 用户 userId=2 的权限列表: [1, 3, -1, -2]
# 权限过滤结果: 总数=10, 过滤后=4, 用户权限数=4

🚀 部署步骤

1. 重新编译后端

cd c:\Users\Administrator\Desktop\Project\xinli
mvn clean package -DskipTests

2. 备份当前jar

# 备份当前运行的jar文件
copy ry-xinli-admin\target\ry-xinli-admin.jar ry-xinli-admin.jar.backup

3. 停止服务

# 根据你的部署方式停止服务
# systemctl stop xinli
# 或手动kill进程

4. 替换jar文件

# 将新编译的jar复制到部署目录

5. 启动服务

# 启动新服务
# systemctl start xinli

6. 查看日志

# 检查启动日志
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或是否有管理权限

SELECT user_id FROM sys_user WHERE user_name = 'admin';

Q2: 普通用户看到所有内容?

A: 可能被误判为管理员,检查权限配置

Q3: 用户看不到任何内容?

A: 检查权限表中是否有该用户的记录

SELECT COUNT(*) FROM psy_scale_permission 
WHERE user_id = X AND status = '0';

Q4: 数量不一致?

A:

  1. 检查前端是否缓存
  2. 检查后端日志中的过滤数量
  3. 对比数据库中的实际权限数

📊 数据一致性检查清单

  • 权限表中的 scale_id 正确(量表用正数,问卷用负数)
  • 用户有对应的权限记录
  • 权限记录的 status = '0'(启用状态)
  • 量表/问卷确实存在(没有孤立的权限记录)
  • 用户不是管理员(除非确实需要看所有内容)

🎯 快速诊断命令

-- 一键诊断用户权限(替换 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脚本检查数据