[开发]用户组与权限系统 — 实现计划

👑Lv.11 元老 🌞 骨干会员
2026-10-23 23:55:09

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:7月5日复制的资料/用户组权限计划.md。

用户组与权限系统 — 实现计划

目标:增加用户组功能,实现按版块控制浏览、发帖、回复权限


一、现状分析

项目当前状态
用户角色users.role → 'admin' / 'user'(硬编码)
权限控制Auth::isAdmin() 判断是否管理员,普通用户无差异
等级系统users.level + points,仅用于展示 badge,不影响权限
版块categories 表,无权限关联

二、设计方案

核心思路

用户 → 用户组(手动分配)→ 粗粒度权限:能浏览哪些版块、能否发帖/回复
     → 等级(自动升级)  → 细粒度限制:每日发帖上限、附件大小、免验证码

用户组管"能不能做某件事",等级管"能做多少"。两种权限叠加生效——用户先有用户组的发帖权限,才能谈等级带来的"每天能发几帖"。

数据模型

新增表 1:user_groups(用户组)

字段类型说明
idINT PK
nameVARCHAR(50)组名称,如"管理员"、"版主"、"VIP会员"、"普通会员"
colorVARCHAR(20)组名显示颜色
is_defaultTINYINT(1)新用户注册时默认分配到此组
created_atDATETIME

新增表 2:category_permissions(版块权限)

字段类型说明
idINT PK
category_idINT关联 categories.id
group_idINT关联 user_groups.id,0 表示未登录用户(游客)
can_viewTINYINT(1)是否允许浏览该版块
can_postTINYINT(1)是否允许在该版块发新帖
can_replyTINYINT(1)是否允许在该版块回复

修改表:users

字段变更说明
role保留仍用于 'admin'/'user' 基础区分
group_id新增 INT DEFAULT 1关联 user_groups.id

默认数据

用户组说明
管理员全部权限,无视版块限制
版主可管理指定版块
VIP 会员可浏览所有版块、发帖回复
普通会员可浏览公开版块、发帖回复
游客仅可浏览公开版块


三、涉及文件清单

3.1 数据库

文件改动
database/schema.sql新增 user_groups、category_permissions 建表语句

3.2 新增文件

文件说明
app/Helpers/Permission.php权限检查核心类(静态方法)
app/Models/UserGroup.php用户组 Model
app/Models/CategoryPermission.php版块权限 Model
app/Controllers/Admin/UserGroupController.php后台用户组管理
app/Controllers/Admin/PermissionController.php后台版块权限设置
app/Views/admin/user_groups.php用户组管理页面
app/Views/admin/category_permissions.php版块权限设置页面

3.3 修改文件

文件改动
app/Models/User.php新增 group_id 字段映射,新增 getGroup() 方法
app/Helpers/Auth.php新增 getGroupId()、hasPermission() 等
app/Helpers/Permission.php(新文件)权限检查:canView(), canPost(), canReply()
app/Controllers/ForumController.php浏览版块时加权限检查
app/Controllers/ThreadController.php查看帖子时加权限检查
app/Controllers/PostController.php发帖/回复时加权限检查
app/Controllers/AuthController.php注册时分配默认用户组
index.php注册后台路由
app/Views/admin/_sidebar.php加导航链接


四、实现步骤

第 1 步:建表 + 默认数据(0.5 天)

CREATE TABLE user_groups (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    color VARCHAR(20) DEFAULT '#666',
    is_default TINYINT(1) DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO user_groups (id, name, color, is_default) VALUES
(1, '普通会员', '#666', 1),
(2, 'VIP会员', '#f39c12', 0),
(3, '版主', '#27ae60', 0),
(4, '管理员', '#e74c3c', 0);

CREATE TABLE category_permissions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    category_id INT NOT NULL,
    group_id INT NOT NULL,
    can_view TINYINT(1) DEFAULT 1,
    can_post TINYINT(1) DEFAULT 1,
    can_reply TINYINT(1) DEFAULT 1,
    UNIQUE KEY uk_cat_group (category_id, group_id),
    FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE users ADD COLUMN group_id INT DEFAULT 1;

第 2 步:Permission Helper(0.5 天)

class Permission
{
    // 检查用户是否有权浏览版块
    public static function canView($categoryId, $userId = null): bool
    // 检查是否有权发帖
    public static function canPost($categoryId, $userId = null): bool
    // 检查是否有权回复
    public static function canReply($threadId, $userId = null): bool
    // 获取用户组信息
    public static function getUserGroup($userId): array
}

第 3 步:后台管理界面(1 天)

  • 用户组管理:CRUD 用户组、设置默认组
  • 版块权限设置:以版块为维度,勾选每个组的浏览/发帖/回复权限
  • 用户管理:编辑用户时可选择所属用户组

第 4 步:前端权限拦截(0.5 天)

  • ForumController::category() → 检查 canView()
  • ThreadController::show() → 检查 canView()
  • PostController::create() → 检查 canPost()
  • ThreadController::show() 的回复表单 → 检查 canReply()

第 5 步:现有等级系统的融合(已有,无需改动)

points 和 level 字段保持原样运行,与用户组互不干扰:

用户组 → 控制权限(能不能做某件事)
等级   → 展示 badge(做了事积累的荣誉)


五、后续可扩展

功能扩展方式
发帖审核category_permissions 加 need_approve 字段
附件权限加 can_upload_attachment 字段
可见版块列表首页/版块列表按权限过滤显示
积分购买 VIP 组Points::award() 达标后自动切换 group_id


六、工作量估计

步骤内容预估
1建表 + Model0.5 天
2Permission Helper0.5 天
3后台管理界面1 天
4前端权限拦截0.5 天
5数据迁移脚本0.5 天
合计约 3 天


七、我的想法

  1. 等级和权限分开是对的——等级是"荣誉",用户组是"权限",两者互不依赖。现在的 points/level 系统可以原封不动保留。
  1. 权限检查点要精准——只需拦截三个关键入口:浏览版块列表、点击发帖按钮、提交回复表单。不需要在 Model 层做权限检查,Controller 层拦截就够了。
  1. 默认权限宽松——新增版块时默认所有组都有全部权限,管理员只需针对需要限制的版块去关闭某些组的权限,减少配置负担。
  1. 管理员不受限制——group_id=4(管理员组)跳过所有权限检查,确保管理员不会把自己锁在外面。

要不要开始做?从第 1 步建表开始。

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 浏览 3 次 | 回复 0 次

全部回复 (0)

暂无回复

请 登录