本文目录导读:

我来详细介绍ThinkPHP项目中角色与权限分配的实现方案,包括数据库设计、核心代码实现和完整示例。
数据库设计
数据表结构
-- 用户表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(255) NOT NULL COMMENT '密码', `email` varchar(100) DEFAULT NULL, `status` tinyint(1) DEFAULT '1' COMMENT '状态:1启用,0禁用', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 角色表 CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '角色名称', `description` varchar(255) DEFAULT NULL COMMENT '角色描述', `status` tinyint(1) DEFAULT '1' COMMENT '状态', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 权限表 CREATE TABLE `permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '权限名称', `code` varchar(100) NOT NULL COMMENT '权限代码', `type` tinyint(1) DEFAULT '1' COMMENT '类型:1菜单,2按钮', `parent_id` int(11) DEFAULT '0' COMMENT '父级ID', `route` varchar(255) DEFAULT NULL COMMENT '路由地址', `sort` int(11) DEFAULT '0' COMMENT '排序', `status` tinyint(1) DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `uk_code` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 用户-角色关联表 CREATE TABLE `user_role` ( `user_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 角色-权限关联表 CREATE TABLE `role_permission` ( `role_id` int(11) NOT NULL, `permission_id` int(11) NOT NULL, PRIMARY KEY (`role_id`,`permission_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
核心模型类
User模型
<?php
namespace app\common\model;
use think\Model;
use think\model\concern\SoftDelete;
class User extends Model
{
use SoftDelete;
protected $deleteTime = 'delete_time';
// 关联角色
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role', 'role_id', 'user_id');
}
// 获取用户所有权限
public function getPermissions()
{
$roles = $this->roles()->where('status', 1)->select();
$permissionIds = [];
foreach ($roles as $role) {
$permissionIds = array_merge(
$permissionIds,
$role->permissions()->column('id')
);
}
return array_unique($permissionIds);
}
// 检查是否有指定权限
public function hasPermission($permissionCode)
{
$permissionIds = $this->getPermissions();
if (empty($permissionIds)) {
return false;
}
return Permission::whereIn('id', $permissionIds)
->where('code', $permissionCode)
->count() > 0;
}
// 检查是否有指定角色
public function hasRole($roleName)
{
return $this->roles()
->where('name', $roleName)
->where('status', 1)
->count() > 0;
}
}
Role模型
<?php
namespace app\common\model;
use think\Model;
class Role extends Model
{
// 关联权限
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'permission_id', 'role_id');
}
// 关联用户
public function users()
{
return $this->belongsToMany(User::class, 'user_role', 'user_id', 'role_id');
}
// 给角色分配权限
public function assignPermissions(array $permissionIds)
{
return $this->permissions()->detach()
->then(function () use ($permissionIds) {
return $this->permissions()->attach($permissionIds);
});
}
}
Permission模型
<?php
namespace app\common\model;
use think\Model;
class Permission extends Model
{
// 获取权限树形结构
public static function getTree()
{
$permissions = self::order('sort', 'asc')->select()->toArray();
return self::buildTree($permissions);
}
// 构建树形结构
private static function buildTree(array $items, $parentId = 0)
{
$tree = [];
foreach ($items as $item) {
if ($item['parent_id'] == $parentId) {
$children = self::buildTree($items, $item['id']);
if ($children) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
}
鉴权中间件
权限检查中间件
<?php
namespace app\middleware;
use think\Request;
use think\Response;
use app\common\model\User;
class CheckPermission
{
public function handle(Request $request, \Closure $next, $permission = null)
{
// 获取当前登录用户
$userId = session('user_id');
if (!$userId) {
return redirect('/login');
}
$user = User::find($userId);
if (!$user || $user->status != 1) {
return redirect('/login');
}
// 超级管理员直接通过
if ($user->hasRole('admin')) {
return $next($request);
}
// 检查权限
if ($permission && !$user->hasPermission($permission)) {
if ($request->isAjax()) {
return json(['code' => 403, 'msg' => '没有权限操作']);
}
abort(403, '没有权限访问');
}
// 将用户对象绑定到请求
$request->user = $user;
return $next($request);
}
}
权限管理控制器
用户管理控制器
<?php
namespace app\admin\controller;
use think\Request;
use app\common\model\User;
use app\common\model\Role;
use app\common\model\UserRole;
class UserController extends BaseController
{
// 用户列表
public function index(Request $request)
{
$page = $request->param('page', 1);
$limit = $request->param('limit', 10);
$keyword = $request->param('keyword', '');
$query = User::with(['roles']);
if ($keyword) {
$query->where('username', 'like', "%{$keyword}%");
}
$list = $query->paginate([
'page' => $page,
'list_rows' => $limit
]);
return json([
'code' => 0,
'msg' => 'success',
'data' => $list->items(),
'count' => $list->total()
]);
}
// 创建用户
public function create(Request $request)
{
$data = $request->post();
$validate = new \app\admin\validate\UserValidate();
if (!$validate->scene('create')->check($data)) {
return json(['code' => 0, 'msg' => $validate->getError()]);
}
$user = new User();
$user->username = $data['username'];
$user->password = password_hash($data['password'], PASSWORD_DEFAULT);
$user->email = $data['email'] ?? '';
$user->status = $data['status'] ?? 1;
$user->save();
// 分配角色
if (isset($data['role_ids']) && is_array($data['role_ids'])) {
$user->roles()->attach($data['role_ids']);
}
return json(['code' => 1, 'msg' => '创建成功']);
}
// 更新用户
public function update(Request $request, $id)
{
$user = User::find($id);
if (!$user) {
return json(['code' => 0, 'msg' => '用户不存在']);
}
$data = $request->post();
if (isset($data['password']) && $data['password']) {
$user->password = password_hash($data['password'], PASSWORD_DEFAULT);
}
if (isset($data['email'])) {
$user->email = $data['email'];
}
if (isset($data['status'])) {
$user->status = $data['status'];
}
$user->save();
// 更新角色
if (isset($data['role_ids']) && is_array($data['role_ids'])) {
$user->roles()->detach();
$user->roles()->attach($data['role_ids']);
}
return json(['code' => 1, 'msg' => '更新成功']);
}
// 删除用户(软删除)
public function delete($id)
{
$user = User::find($id);
if (!$user) {
return json(['code' => 0, 'msg' => '用户不存在']);
}
$user->delete();
return json(['code' => 1, 'msg' => '删除成功']);
}
// 分配角色
public function assignRole(Request $request)
{
$userId = $request->post('user_id');
$roleIds = $request->post('role_ids', []);
$user = User::find($userId);
if (!$user) {
return json(['code' => 0, 'msg' => '用户不存在']);
}
$user->roles()->detach();
$user->roles()->attach($roleIds);
return json(['code' => 1, 'msg' => '角色分配成功']);
}
}
角色管理控制器
<?php
namespace app\admin\controller;
use think\Request;
use app\common\model\Role;
use app\common\model\Permission;
class RoleController extends BaseController
{
// 角色列表
public function index()
{
$roles = Role::with(['permissions'])->select();
return json(['code' => 0, 'data' => $roles]);
}
// 创建角色
public function create(Request $request)
{
$data = $request->post();
$role = new Role();
$role->name = $data['name'];
$role->description = $data['description'] ?? '';
$role->save();
// 分配权限
if (isset($data['permission_ids']) && is_array($data['permission_ids'])) {
$role->permissions()->attach($data['permission_ids']);
}
return json(['code' => 1, 'msg' => '角色创建成功']);
}
// 更新角色
public function update(Request $request, $id)
{
$role = Role::find($id);
if (!$role) {
return json(['code' => 0, 'msg' => '角色不存在']);
}
$data = $request->post();
if (isset($data['name'])) {
$role->name = $data['name'];
}
if (isset($data['description'])) {
$role->description = $data['description'];
}
$role->save();
// 更新权限
if (isset($data['permission_ids'])) {
$role->permissions()->detach();
$role->permissions()->attach($data['permission_ids']);
}
return json(['code' => 1, 'msg' => '角色更新成功']);
}
// 删除角色
public function delete($id)
{
$role = Role::find($id);
if (!$role) {
return json(['code' => 0, 'msg' => '角色不存在']);
}
// 检查是否有用户使用该角色
if ($role->users()->count() > 0) {
return json(['code' => 0, 'msg' => '该角色已被使用,无法删除']);
}
$role->delete();
$role->permissions()->detach();
return json(['code' => 1, 'msg' => '角色删除成功']);
}
// 分配权限
public function assignPermission(Request $request)
{
$roleId = $request->post('role_id');
$permissionIds = $request->post('permission_ids', []);
$role = Role::find($roleId);
if (!$role) {
return json(['code' => 0, 'msg' => '角色不存在']);
}
$role->permissions()->detach();
$role->permissions()->attach($permissionIds);
return json(['code' => 1, 'msg' => '权限分配成功']);
}
}
权限管理控制器
<?php
namespace app\admin\controller;
use think\Request;
use app\common\model\Permission;
use think\facade\Cache;
class PermissionController extends BaseController
{
// 权限列表(树形)
public function index()
{
$tree = Permission::getTree();
return json(['code' => 0, 'data' => $tree]);
}
// 创建权限
public function create(Request $request)
{
$data = $request->post();
$permission = new Permission();
$permission->name = $data['name'];
$permission->code = $data['code'];
$permission->type = $data['type'] ?? 1;
$permission->parent_id = $data['parent_id'] ?? 0;
$permission->route = $data['route'] ?? '';
$permission->sort = $data['sort'] ?? 0;
$permission->save();
$this->clearCache();
return json(['code' => 1, 'msg' => '权限创建成功']);
}
// 更新权限
public function update(Request $request, $id)
{
$permission = Permission::find($id);
if (!$permission) {
return json(['code' => 0, 'msg' => '权限不存在']);
}
$data = $request->post();
if (isset($data['name'])) {
$permission->name = $data['name'];
}
if (isset($data['code'])) {
$permission->code = $data['code'];
}
if (isset($data['route'])) {
$permission->route = $data['route'];
}
$permission->save();
$this->clearCache();
return json(['code' => 1, 'msg' => '权限更新成功']);
}
// 删除权限
public function delete($id)
{
$permission = Permission::find($id);
if (!$permission) {
return json(['code' => 0, 'msg' => '权限不存在']);
}
// 检查是否有子权限
$hasChildren = Permission::where('parent_id', $id)->count();
if ($hasChildren > 0) {
return json(['code' => 0, 'msg' => '存在子权限,无法删除']);
}
$permission->delete();
$this->clearCache();
return json(['code' => 1, 'msg' => '权限删除成功']);
}
// 清除缓存
private function clearCache()
{
Cache::delete('all_permissions');
}
}
路由配置
<?php
// route/app.php
use think\facade\Route;
// 用户管理
Route::group('admin/user', function () {
Route::get('index', 'admin.User/index');
Route::post('create', 'admin.User/create');
Route::put('update/:id', 'admin.User/update');
Route::delete('delete/:id', 'admin.User/delete');
Route::post('assign_role', 'admin.User/assignRole');
})->middleware([\app\middleware\CheckPermission::class]);
// 角色管理
Route::group('admin/role', function () {
Route::get('index', 'admin.Role/index');
Route::post('create', 'admin.Role/create');
Route::put('update/:id', 'admin.Role/update');
Route::delete('delete/:id', 'admin.Role/delete');
Route::post('assign_permission', 'admin.Role/assignPermission');
})->middleware([\app\middleware\CheckPermission::class]);
// 权限管理
Route::group('admin/permission', function () {
Route::get('index', 'admin.Permission/index');
Route::post('create', 'admin.Permission/create');
Route::put('update/:id', 'admin.Permission/update');
Route::delete('delete/:id', 'admin.Permission/delete');
})->middleware([\app\middleware\CheckPermission::class]);
模板示例
角色分配界面
<!-- role_assign.html -->
<div class="role-assign-form">
<form id="roleForm">
<div class="form-group">
<label>用户名</label>
<input type="text" name="username" value="{$user.username}" readonly>
</div>
<div class="form-group">
<label>分配角色</label>
<div class="checkbox-group">
{volist name="roles" id="role"}
<label class="checkbox-inline">
<input type="checkbox" name="role_ids[]"
value="{$role.id}"
{if in_array($role.id, $userRoleIds)}checked{/if}>
{$role.name}
</label>
{/volist}
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">保存</button>
</div>
</form>
</div>
<script>
$(function() {
$('#roleForm').on('submit', function(e) {
e.preventDefault();
var roleIds = [];
$('input[name="role_ids[]"]:checked').each(function() {
roleIds.push($(this).val());
});
$.ajax({
url: '/admin/user/assign_role',
type: 'POST',
data: {
user_id: {$user.id},
role_ids: roleIds
},
success: function(res) {
if (res.code === 1) {
layer.msg('分配成功');
location.reload();
} else {
layer.msg(res.msg);
}
}
});
});
});
</script>
权限树形选择
<!-- permission_tree.html -->
<div class="permission-tree">
<ul id="permissionTree" class="ztree"></ul>
</div>
<script>
var setting = {
check: {
enable: true,
chkboxType: {"Y": "ps", "N": "ps"}
},
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "parent_id",
rootPId: 0
}
}
};
function initPermissionTree() {
$.ajax({
url: '/admin/permission/index',
type: 'GET',
success: function(res) {
if (res.code === 0) {
var tree = [];
var permissions = res.data;
function flattenTree(data, parentId) {
$.each(data, function(index, item) {
tree.push({
id: item.id,
parent_id: parentId || 0,
name: item.name,
open: parentId === 0
});
if (item.children && item.children.length > 0) {
flattenTree(item.children, item.id);
}
});
}
flattenTree(permissions, 0);
$.fn.zTree.init($("#permissionTree"), setting, tree);
}
}
});
}
// 获取选中的权限ID
function getSelectedPermissionIds() {
var treeObj = $.fn.zTree.getZTreeObj("permissionTree");
var nodes = treeObj.getCheckedNodes(true);
return nodes.map(function(node) {
return node.id;
});
}
</script>
权限校验辅助类
<?php
namespace app\common\auth;
use app\common\model\User;
use think\facade\Cache;
use think\facade\Session;
class AuthHelper
{
// 获取用户权限标识符
public static function getUserPermissionCodes()
{
$userId = Session::get('user_id');
$cacheKey = 'user_permissions_' . $userId;
// 尝试从缓存获取
$permissions = Cache::get($cacheKey);
if ($permissions) {
return $permissions;
}
// 查询数据库
$user = User::find($userId);
if (!$user) {
return [];
}
$roleIds = $user->roles()->column('id');
$permissions = [];
if (!empty($roleIds)) {
$permissionCodes = \app\common\model\RolePermission::alias('rp')
->join('permission p', 'p.id = rp.permission_id')
->whereIn('rp.role_id', $roleIds)
->column('p.code');
$permissions = array_unique($permissionCodes);
}
// 缓存30分钟
Cache::set($cacheKey, $permissions, 1800);
return $permissions;
}
// 清除用户权限缓存
public static function clearUserPermission($userId = null)
{
if ($userId) {
Cache::delete('user_permissions_' . $userId);
} else {
Cache::delete('user_permissions_' . Session::get('user_id'));
}
}
// 生成权限菜单树
public static function getMenuTree()
{
$permissionCodes = self::getUserPermissionCodes();
$query = \app\common\model\Permission::where('type', 1)
->where('status', 1)
->order('sort', 'asc');
$permissions = $query->select()->toArray();
return self::buildMenuTree($permissions, 0, $permissionCodes);
}
// 构建菜单树
private static function buildMenuTree($permissions, $parentId, $userPermissions)
{
$tree = [];
foreach ($permissions as $permission) {
if ($permission['parent_id'] == $parentId) {
// 检查是否有权限
if (!in_array($permission['code'], $userPermissions)) {
continue;
}
$children = self::buildMenuTree($permissions, $permission['id'], $userPermissions);
if ($children || $permission['route']) {
$tree[] = [
'id' => $permission['id'],
'name' => $permission['name'],
'route' => $permission['route'],
'children' => $children
];
}
}
}
return $tree;
}
}
控制器基类
<?php
namespace app\admin\controller;
use app\common\auth\AuthHelper;
use think\Controller;
use think\facade\Session;
class BaseController extends Controller
{
protected $user;
protected function initialize()
{
parent::initialize();
// 用户登录检查
if (!Session::has('user_id')) {
$this->redirect('/login');
}
// 获取当前用户信息
$this->user = \app\common\model\User::find(Session::get('user_id'));
// 判断是否超级管理员
$isAdmin = $this->user->hasRole('admin');
$this->assign('isAdmin', $isAdmin);
// 获取并分配菜单
$menus = $isAdmin ? $this->getAllMenus() : AuthHelper::getMenuTree();
$this->assign('menus', $menus);
// 获取用户信息
$this->assign('user', $this->user);
}
// 获取所有菜单(管理员)
private function getAllMenus()
{
return \app\common\model\Permission::where('type', 1)
->where('status', 1)
->order('sort', 'asc')
->select()
->toArray();
}
}
使用示例
在控制器中使用权限检查
<?php
namespace app\admin\controller;
class OrderController extends BaseController
{
// 订单列表(需要权限)
public function index()
{
// 自定义权限检查
if (!$this->user->hasPermission('order_view')) {
return json(['code' => 403, 'msg' => '没有订单查看权限']);
}
// 处理业务逻辑...
return $this->fetch();
}
// 删除订单(需要权限)
public function delete($id)
{
if (!$this->user->hasPermission('order_delete')) {
return json(['code' => 403, 'msg' => '没有订单删除权限']);
}
// 处理删除逻辑...
return json(['code' => 1, 'msg' => '删除成功']);
}
}
初始化权限数据
<?php
// think 命令行工具创建初始化脚本
namespace app\common\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
class Init extends Command
{
protected function configure()
{
$this->setName('init')
->setDescription('初始化权限数据');
}
protected function execute(Input $input, Output $output)
{
// 创建超级管理员角色
$adminRole = new \app\common\model\Role();
$adminRole->name = 'admin';
$adminRole->description = '超级管理员';
$adminRole->id = 1;
$adminRole->save();
// 创建基础权限
$permissions = [
['name' => '用户管理', 'code' => 'user_manage', 'type' => 1, 'parent_id' => 0],
['name' => '用户列表', 'code' => 'user_list', 'type' => 2, 'parent_id' => 1],
['name' => '用户添加', 'code' => 'user_create', 'type' => 2, 'parent_id' => 1],
['name' => '用户编辑', 'code' => 'user_edit', 'type' => 2, 'parent_id' => 1],
['name' => '用户删除', 'code' => 'user_delete', 'type' => 2, 'parent_id' => 1],
['name' => '角色管理', 'code' => 'role_manage', 'type' => 1, 'parent_id' => 0],
['name' => '角色列表', 'code' => 'role_list', 'type' => 2, 'parent_id' => 6],
['name' => '权限管理', 'code' => 'permission_manage', 'type' => 1, 'parent_id' => 0],
];
$permissionIds = [];
foreach ($permissions as $item) {
$permission = new \app\common\model\Permission();
$permission->save($item);
$permissionIds[] = $permission->id;
}
// 给管理员分配所有权限
$adminRole->permissions()->attach($permissionIds);
// 创建管理员用户
$admin = new \app\common\model\User();
$admin->username = 'admin';
$admin->password = password_hash('admin123', PASSWORD_DEFAULT);
$admin->save();
// 给管理员分配角色
$admin->roles()->attach([1]);
$output->writeln('初始化完成');
}
}
这个完整的权限管理方案包含了:
- 数据库设计:用户、角色、权限表及关联表
- 模型层:核心模型的关联关系
- 中间件:权限校验
- 控制器:CRUD操作及权限分配
- 辅助类:权限缓存、菜单生成等
- 使用示例:控制器级权限控制、模板渲染等
你可以根据项目实际需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播