用户端(APP / H5 / PC) ↓前端接口层(RESTful API / WebSocket) ↓后台业务服务层(PHP + ThinkPHP) ↓权限控制中间层(RBAC 扩展模型) ↓MySQL 数据层 + Redis 缓存层
graph TD A[管理员] -->|属于| B[角色] B -->|包含| C[权限组] C -->|包含| D[权限节点] D -->|映射| E[控制器方法] F[菜单] -->|绑定| D G[操作日志] -->|记录| A
// 在菜单配置中声明权限节点'menu' => [['title' => '赛事管理','route' => 'match/index','auth_node' => ['match_add' => '添加赛事','match_del' => '删除赛事','match_sync' => '同步API']]]// 自动注册到权限系统class AuthService {public function syncNodes() {foreach(config('menu') as $menu){foreach($menu['auth_node'] as $node=>$name){NodeModel::firstOrCreate(['node' => $menu['route'].'@'.$node,'name' => $name]);}}}}
// 角色权限模板配置'role_templates' => ['content_admin' => ['match/*','anchor/audit','post/delete'],'shop_admin' => ['goods/*','order/*']];// 角色创建时应用模板$role->applyTemplate('content_admin');
class AuthMiddleware {
public function handle($request, $next) {
$node = $request->module().'/'.
$request->controller().'@'.
$request->action();
if(!Auth::user()->can($node)){
return response('无权操作', 403);
}
return $next($request);
}}
// 数据库日志表结构Schema::create('admin_logs', function (Blueprint $table) {$table->id();$table->integer('admin_id');$table->string('module', 30);$table->string('action', 50);$table->text('before_data')->nullable();$table->text('after_data')->nullable();$table->string('ip', 45);$table->timestamps();});// 行为监听Event::listen('admin.operate', function($admin, $action, $data){AdminLog::create(['admin_id' => $admin->id,'module' => request()->module(),'action' => $action,'before_data' => json_encode($data['before']),'after_data' => json_encode($data['after']),'ip' => request()->ip()]);});
# 权限组配置- group: 内容管理 nodes: - match/add - match/delete - anchor/audit - post/delete menus: - 赛事管理 - 主播审核 - 社区管理
// 用户权限缓存结构$userPermissions = Redis::hGetAll("user:{$uid}:permissions");// 权限检查优化function checkPermission($node) {static $cache = [];if(!isset($cache[$node])){$cache[$node] = in_array($node,Redis::hGetAll("user:{$uid}:permissions"));}return $cache[$node];}
// 数据范围限制
class MatchController {
public function index() {
$query = Match::query();
// 添加数据范围过滤
if(!Auth::user()->can('match/all')){
$query->whereIn('id',
Auth::user()->getDataScope('match'));
}
return $query->paginate();
}
}
┌───────────────┐ │ CDN/OSS │ └──────┬───────┘ │ ┌─────────────▼─────────────┐ │ API Gateway │ │ (Nginx + Load Balancer) │ └───────┬─────────┬─────────┘ │ │ ┌─────────▼─┐ ┌───▼─────────┐ │ Web1 │ │ Web2 │ │(PHP-FPM) │ │(PHP-FPM) │ └────┬──────┘ └────┬───────┘ │ │ ┌─────▼──────────────▼─────┐ │ MySQL Cluster │ │ (Master-Slave + MHA) │ └──────────┬──────────────┘ │ ┌─────▼─────┐ │ Redis │ │ (Cluster)│ └───────────┘
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70044681/viewspace-3082207/ ,如需转载,请注明出处,否则将追究法律责任。