一、用户角色
用户与角色之间的关系是多对多:
- 一个用户能够有多个角色;
- 一个角色能够被调配给多个角色。
二、后期筹备
(一)路由
// 查看用户角色Route::get('userroles/:id','UserAccess/read');// 调配角色给用户Route::post('userroles','UserAccess/save');// 删除用户的角色Route::post('userrole/delete','UserAccess/delete');
(二)控制器
应用命令
php think make:controller UserAccess
(三)表
1. 用户表
创立用户表的 SQL 语句:
CREATE TABLE `think_users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户编号', `name` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
用户表如下:
2. 角色表
创立角色表的 SQL 语句:
CREATE TABLE `think_role` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(255) DEFAULT NULL COMMENT '角色名称', `remark` varchar(255) DEFAULT NULL COMMENT '备注', `del_flag` tinyint(4) DEFAULT '0' COMMENT '0 示意失常,-1示意被删除', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
角色表如下:
3. 用户角色表(两头表)
创立用户角色表的 SQL 语句:
CREATE TABLE `think_user_role` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `user_id` int(11) NOT NULL COMMENT '用户ID', `role_id` int(11) NOT NULL COMMENT '角色ID', `create_by` varchar(255) DEFAULT NULL COMMENT '创建人', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4;
用户角色表如下:
(四)模型
1. 用户模型
应用命令:
php think make:model User
在用户模型中定义 roles
办法:
<?phpdeclare (strict_types = 1);namespace app\model;use think\Model;class User extends Model{ protected $name = 'think_users'; public function roles(){ return $this->belongsToMany(Role::class,'think_user_role','role_id','user_id'); }}
2. 角色模型
php think make:model Role
在角色模型中定义 users
办法:
<?phpdeclare (strict_types = 1);namespace app\model;use think\Model;class Role extends Model{ protected $name = 'think_role'; public function users(){ return $this->belongsToMany(User::class,'think_user_role','user_id','role_id'); }}
3. 用户角色模型
php think make:model Access
用户角色模型:
<?phpdeclare (strict_types = 1);namespace app\model;use think\Model;use think\model\Pivot;class Access extends Pivot{ protected $name = "think_user_role"; protected $autoWriteTimestamp = true; }
留神:两头表模型类必须继承 think\model\Pivot
。
三、批改控制器
<?phpdeclare (strict_types = 1);namespace app\controller;use think\Request;use app\model\User;class UserAccess{ /** * 调配角色给用户 * * @param \think\Request $request * @return \think\Response */ public function save(Request $request) { $params = $request->param(); $user_id = $params['user_id']; $role_id = $params['role_id']; $user = User::find($user_id); $roles = $user->roles; $role_ids = $this->collectionColumn($roles,'role_id'); if($this->isAssignRole($role_id,$role_ids)){ return $this->setJsonResult('error',40000,'已调配该角色,无需再次调配'); } if(isset($params['create_by']) && !empty($params['create_by'])){ // 传入两头表的额定属性 $user->roles()->attach($role_id,['create_by'=>$params['create_by']]); }else{ $user->roles()->attach($role_id); } return $this->setJsonResult('success',10000,'用户受权胜利',['user_id'=>$user_id,'role_id'=>$role_id]); } /** * 显示用户的角色 * * @param int $id * @return \think\Response */ public function read($id) { $user = User::find($id); $roles = $user->roles; // dump($roles); $role_name = []; foreach($roles as $role){ $role_name[] = $role->name; } return $this->setJsonResult('success',10000,'操作胜利',$role_name); } /** * 删除用户的角色 * * @param int $id * @return \think\Response */ public function delete(Request $request) { $params = $request->param(); $user_id = $params['user_id']; $user = User::find($user_id); $role_id = $params['role_id']; $user->roles()->detach($role_id); return $this->setJsonResult('success',10000,'删除用户权限胜利'); } public function setJsonResult($status,$code,$message='',$data=[]){ return json([ 'status' => $status, 'code' => $code, 'message' => $message, 'data' => $data ]); } /** * 获取数据汇合某个字段的值 * * @param object $collection, string $column * @return array */ public function collectionColumn($collection,$column){ $re = []; foreach($collection as $val){ $re[] = $val->pivot->$column; } return $re; } /** * 判断之前是否为该用户调配过 role_id 对应的角色 * * @param string $collection, array $role_ids * @return bool */ public function isAssignRole($role_id,$role_ids){ if(in_array($role_id,$role_ids)){ return true; } return false; }}
四、测试
在之前的测试中曾经为 id
为 1 的用户调配了角色,当初测试 2 号的用户角色的查看、调配与删除:
1. 查看 2 号用户的角色
调用查看用户角色的接口:
返回值的 data
属性为空。
2. 为用户调配角色
调用为用户调配角色的接口:
用户角色表如下:
再次调用查看用户角色的接口:
3. 删除用户的角色
调用删除用户角色的接口:
删除2号角色后的数据表: