一、用户角色

用户与角色之间的关系是多对多:

  • 一个用户能够有多个角色;
  • 一个角色能够被调配给多个角色。

二、后期筹备

(一)路由
// 查看用户角色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号角色后的数据表: