批改状态:合格
老师批语:
/*** 分类管理*/// 分类禁用和启用$api->patch('category/{category}/status', [\App\Http\Controllers\Admin\CategoryController::class, 'status'])->name('category.status');// 分类管理资源路由$api->resource('category', \App\Http\Controllers\Admin\CategoryController::class, ['except' => ['destroy']]);
控制器
<?phpnamespace App\Http\Controllers\Admin;use App\Http\Controllers\BaseController;use App\Models\Category;use Illuminate\Http\Request;class CategoryController extends BaseController{/*** 分类列表*/public function index(Request $request){$type = $request->input('type');if ($type == 'all') {return cache_category_all();} else {return cache_category();}}/*** 添加分类 最大2级分类*/public function store(Request $request){$insertData = $this->checkInput($request);if (!is_array($insertData)) return $insertData;Category::create($insertData);return $this->response->created();}/*** 分类详情*/public function show(Category $category){return $category;}/*** 更新分类*/public function update(Request $request, Category $category){if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');$updateData = $this->checkInput($request);if (!is_array($updateData)) return $updateData;$category->update($updateData);return $this->response->noContent();}/*** 验证提交的参数*/protected function checkInput($request){// 验证参数$request->validate(['name' => 'required|max:16'], ['name.required' => '分类名称 不能为空']);// 获取分组$group = $request->input('group', 'goods');// 获取pid$pid = $request->input('pid', 0);// 计算level$level = $pid == 0 ? 1 : (Category::find($pid)->level + 1);// 不能超过3级分类if ($level > 2) {return $this->response->errorBadRequest('不能超过二级分类');}return ['name' => $request->input('name'),'pid' => $pid,'level' => $level,'group' => $group];}/*** 状态禁用和启用*/public function status(Category $category){if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');$category->status = $category->status == 1 ? 0 : 1;$category->save();return $this->response->noContent();}}
Helpers.php
/*** 缓存没被禁用的分类*/if (!function_exists('cache_category')) {function cache_category (){return cache()->rememberForever('cache_category', function () {return categoryTree('goods', 1);});}}/*** 缓存所有的分类*/if (!function_exists('cache_category_all')) {function cache_category_all (){return cache()->rememberForever('cache_category_all', function () {return categoryTree('goods');});}}
/*** 清空分类缓存*/if (!function_exists('forget_cache_category')) {function forget_cache_category (){cache()->forget('cache_category');cache()->forget('cache_category_all');}}
class CategoryTransformer extends TransformerAbstract{public function transform(Category $category){return ['id' => $category->id,'pid' => $category->pid,'name' => $category->name,];}}
路由
/*** 商品管理*/// 是否上架$api->patch('goods/{good}/on', [\App\Http\Controllers\Admin\GoodsController::class, 'isOn'])->name('goods.on');// 是否推荐$api->patch('goods/{good}/recommend', [\App\Http\Controllers\Admin\GoodsController::class, 'isRecommend'])->name('goods.recommend');// 商品管理资源路由$api->resource('goods', \App\Http\Controllers\Admin\GoodsController::class, ['except' => ['destroy']]);
控制器
<?phpnamespace App\Http\Controllers\Admin;use App\Http\Controllers\BaseController;use App\Http\Requests\Admin\GoodsRequest;use App\Models\Category;use App\Models\Good;use App\Transformers\GoodTransformer;use Illuminate\Http\Request;class GoodsController extends BaseController{/*** 商品列表*/public function index(Request $request){$title = $request->query('title');$category_id = $request->query('category_id');$is_on = $request->query('is_on', false);$is_recommend = $request->query('is_recommend', false);$goods = Good::when($title, function ($query) use ($title) {$query->where('title', 'like', "%$title%");})->when($category_id, function ($query) use ($category_id) {$query->where('category_id', $category_id);})->when($is_on !== false, function ($query) use ($is_on) {$query->where('is_on', $is_on);})->when($is_recommend !== false, function ($query) use ($is_recommend) {$query->where('is_recommend', $is_recommend);})->orderBy('updated_at', 'desc')->paginate($request->query('pageSize', 10), ['*'], 'current');return $this->response->paginator($goods, new GoodTransformer());}/*** 添加商品*/public function store(GoodsRequest $request){// 对分类进行一下检查, 只能使用3级分类, 并且分类不能被禁用$catagory = Category::find($request->category_id);if (!$catagory) return $this->response->errorBadRequest('分类不存在');if ($catagory->status == 0) return $this->response->errorBadRequest('分类被禁用');if ($catagory->level != 2) return $this->response->errorBadRequest('只能向2级分类添加商品');$user_id = auth('api')->id();// 追加user_id字段// $insertData = $request->all();// $insertData['user_id'] = $user_id;// Good::create($insertData);// 追加user_id字段$request->offsetSet('user_id', $user_id);Good::create($request->all());return $this->response->created();}/*** 商品详情*/public function show(Good $good){return $this->response->item($good, new GoodTransformer());}/*** 更新商品*/public function update(GoodsRequest $request, Good $good){if ($good->id < 237) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');// 对分类进行一下检查, 只能使用3级分类, 并且分类不能被禁用$catagory = Category::find($request->category_id);if (!$catagory) return $this->response->errorBadRequest('分类不存在');// if ($catagory->status == 0) return $this->response->errorBadRequest('分类被禁用');if ($catagory->level != 2) return $this->response->errorBadRequest('只能向2级分类添加商品');$good->update($request->all());return $this->response->noContent();}/*** 是否上架*/public function isOn(Good $good){$good->is_on = $good->is_on == 0 ? 1 : 0;$good->save();return $this->response->noContent();}/*** 是否推荐*/public function isRecommend(Good $good){$good->is_recommend = $good->is_recommend == 0 ? 1 : 0;$good->save();return $this->response->noContent();}}
<?phpnamespace App\Transformers;use App\Models\Category;use App\Models\Good;use League\Fractal\TransformerAbstract;class GoodTransformer extends TransformerAbstract{protected $availableIncludes = ['category', 'user', 'comments'];public function transform(Good $good){$pics_url = [];if (!empty($good->pics)) {foreach ($good->pics as $p) {array_push($pics_url, oss_url($p));}}return ['id' => $good->id,'title' => $good->title,'category_id' => $good->category_id,'user_id' => $good->user_id,// 'category_name' => Category::find($good->category_id)->name,'description' => $good->description,'price' => $good->price,'stock' => $good->stock,'sales' => $good->sales,'cover' => $good->cover,'cover_url' => oss_url($good->cover),'pics' => $good->pics,'pics_url' => $pics_url,'details' => $good->details,'is_on' => $good->is_on,'is_recommend' => $good->is_recommend,'created_at' => empty($good->created_at) ? $good->created_at : $good->created_at->toDateTimeString(),'updated_at' => empty($good->updated_at) ? $good->updated_at : $good->updated_at->toDateTimeString(),];}/*** 额外的分类数据*/public function includeCategory(Good $good){return $this->item($good->category, new CategoryTransformer());}/*** 额外的用户数据*/public function includeUser(Good $good){return $this->item($good->user, new UserTransformer());}/*** 额外的评价数据*/public function includeComments(Good $good){return $this->collection($good->comments, new CommentTransformer());}}
安装oss组件:
$ composer require "iidestiny/laravel-filesystem-oss"
OSS文档地址:
创建控制器
php artisan make:controller Auth/OssController
添加路由
$api->get('oss/token', [\App\Http\Controllers\Auth\OssController::class, 'token']);
$disk = Storage::disk('oss');$config = $disk->signatureConfig($prefix = '/', $callBackUrl = '', $customData = [], $expire = 300);$configArr = json_decode($config, true);return $this->response->array($configArr);
if (!function_exists('oss_url')) {function oss_url($key){// 如果没有$keyif (empty($key)) return '';// 如果$key包含了http等, 是一个完整的地址, 直接返回if (strpos($key, 'http://') !== false|| strpos($key, 'https://') !== false|| strpos($key, 'data:image') !== false) {return $key;}return config('filesystems')['disks']['oss']['bucket_url'] . '/' . $key;}}
举个例子,例如我们平常使用的论坛
站长 ——— 拥有最高权限,最主要的是能够对用户进行管理的权限
管理员 ——- 对一些文章的管理,不会造成对网站有较大的影响
vip ——- 对一些资源有下载权限
普通用户 —— 只能够进行简单的对自己文章的增删改、评论等
游客 —— 只能进行基本的浏览

roles ———- 角色信息:站长等
permissions ———- 权限信息:管理内容等
model_has_roles ———- 模型对应角色 = 用户对应的角色
role_has_permissions ———- 角色对应权限 = 角色有什么权限
model_has_permissions ———- 模型对应权限 = 用户有权限
我们来梳理一下关联关系
权限(permissions)与 角色(roles) ,一个 权限 可能被多个 角色 拥有,一个 角色 可能有多个 权限,关联关系:多对多(role_has_permissions)
用户 与 权限 一对多(model_has_permissions)
用户 与 角色 一对多(model_has_roles)
由次来说,关系明确了,当用户有什么角色 或者 有什么权限,即执行相应的操作
laravel-permission 基于上面 的表情况,将用户与权限和角色相关联
通过 Composer 安装:
$ composer require "spatie/laravel-permission"
生成数据库迁移文件:
php artisan vendor:publish —provider=”Spatie\Permission\PermissionServiceProvider”
在migration目录下可看到相关表信息,执行数据库迁移
php artisan migrate
在User 模型下加载
.....use Spatie\Permission\Traits\HasRoles; // useclass User extends Authenticatable{use HasRoles; // 加载角色相关信息.....
修改迁移文件添加为权限和角色添加cn_name
$table->string('cn_name');
// 创建数据填充
php artisan make:seeder PermissionSeeder
修改DatabaseSeeder
public function run(){$this->call(PermissionSeeder::class);}
public function run(){// 清空缓存app()['cache']->forget('spatie.permission.cache');// 添加权限$permissions = [['name' => 'users.index', 'cn_name' => '用户列表', 'guard_name' => 'api'],['name' => 'users.show', 'cn_name' => '用户详情', 'guard_name' => 'api'],['name' => 'users.lock', 'cn_name' => '用户禁用启用', 'guard_name' => 'api'],];foreach ($permissions as $p) {Permission::create($p);}// 添加角色$role = Role::create(['name' => 'super-admin', 'cn_name' => '超级管理员', 'guard_name' => 'api']);// 为角色添加权限$role->givePermissionTo(Permission::all());}
执行dbseed
php artisan db:seed --class PermissionSeeder
创建用户DBSEED
php artisan make:seed UserSeeder
<?phpnamespace Database\Seeders;use App\Models\User;use Illuminate\Database\Seeder;class UserSeeder extends Seeder{/*** Run the database seeds.** @return void*/public function run(){// 创建用户$user = User::create(['name' => '超级管理员','email' => 'super@a.com','password' => bcrypt('123123')]);// 给用户分配角色$user->assignRole('super-admin');}}
创建一个中间件
php artisan make:middleware CheckPermission
/*** Handle an incoming request.** @param \Illuminate\Http\Request $request* @param \Closure $next* @return mixed*/public function handle(Request $request, Closure $next){// 验证用户是否具有请求权限$user = auth('api')->user();if (!$user->can($request->route()->getName())) {abort(403);}return $next($request);}
app/Http/Kernel.php
protected $routeMiddleware = [....'check.permission' => \App\Http\Middleware\CheckPermission::class];
路由上添加中间件
$api->group(['prefix' => 'admin','middleware' => ['api.auth','check.permission']], function ($api) {
为用户添加权限
$user->givePermissionTo('edit articles');
为用户添加角色
$user->assignRole('writer');$user->assignRole(['writer', 'admin']);
给用户删除权限
$user->revokePermissionTo('edit articles');
给角色添加权限
$role->givePermissionTo('edit articles');
为角色添加权限
$role->givePermissionTo('edit articles');
撤销一个权限 并且 添加一个新权限
$user->syncPermissions(['edit articles', 'delete articles']);
获得当前用户的角色集合
$user->getRoleNames();
将多个角色同步到权限
$role->syncPermissions($permissions); // @param array $permissions$permission->syncRoles($roles);
从角色中删除权限
$role->revokePermissionTo($permission);$permission->removeRole($role);
获取当前的用户的权限列表
$permissions = $user->permissions;
获取用户的所有权限,或者直接权限 (odel_has_permissions),或者从角色获取,或者从两者获取
$permissions = $user->getDirectPermissions();$permissions = $user->getPermissionsViaRoles();$permissions = $user->getAllPermissions();
获取用户的角色集合 collection
$roles = $user->getRoleNames(); // Returns a collection
返回指定角色的用户 | Returns only users with the role ‘writer’
$users = User::role('writer')->get(); //
返回指定权限的用户
$users = User::permission('edit articles')->get();
用户有什么角色
$user->hasRole('writer');
检查是否有某个权限
$user->hasPermissionTo('edit articles');$user->can('edit articles');
检查是否有某个角色|或者列
$user->hasRole('writer');$user->hasAnyRole(Role::all());$user->hasAllRoles(Role::all());
传递id值进行判断是否有某个权限
$user->hasPermissionTo('1');$user->hasPermissionTo(Permission::find(1)->id);$user->hasPermissionTo($somePermission->id);
是否拥有一组权限
$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);
检查一个角色是否有某些权限 | 删除某些权限
$role->hasPermissionTo('edit articles');$role->revokePermissionTo('edit articles'); // 删除
@role('writer')I am a writer!@elseI am not a writer...@endrole------------------------@hasrole('writer')I am a writer!@elseI am not a writer...@endhasrole------------------------@can('edit articles') // 拥有某个权限 可执行操作//@endcan
use Illuminate\Database\Seeder;use Spatie\Permission\Models\Role;use Spatie\Permission\Models\Permission;class RolesAndPermissionsSeeder extends Seeder{public function run(){// Reset cached roles and permissionsapp()['cache']->forget('spatie.permission.cache');// create permissionsPermission::create(['name' => 'edit articles']);Permission::create(['name' => 'delete articles']);Permission::create(['name' => 'publish articles']);Permission::create(['name' => 'unpublish articles']);// create roles and assign created permissions$role = Role::create(['name' => 'writer']);$role->givePermissionTo('edit articles');$role = Role::create(['name' => 'moderator']);$role->givePermissionTo(['publish articles', 'unpublish articles']);$role = Role::create(['name' => 'super-admin']);$role->givePermissionTo(Permission::all());}}
// 命令删除php artisan cache:forget spatie.permission.cache
app()[‘cache’]->forget(‘spatie.permission.cache’);
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号