分类管理

  1. /**
  2. * 分类管理
  3. */
  4. // 分类禁用和启用
  5. $api->patch('category/{category}/status', [\App\Http\Controllers\Admin\CategoryController::class, 'status'])->name('category.status');
  6. // 分类管理资源路由
  7. $api->resource('category', \App\Http\Controllers\Admin\CategoryController::class, [
  8. 'except' => ['destroy']
  9. ]);

控制器

  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Http\Controllers\BaseController;
  4. use App\Models\Category;
  5. use Illuminate\Http\Request;
  6. class CategoryController extends BaseController
  7. {
  8. /**
  9. * 分类列表
  10. */
  11. public function index(Request $request)
  12. {
  13. $type = $request->input('type');
  14. if ($type == 'all') {
  15. return cache_category_all();
  16. } else {
  17. return cache_category();
  18. }
  19. }
  20. /**
  21. * 添加分类 最大2级分类
  22. */
  23. public function store(Request $request)
  24. {
  25. $insertData = $this->checkInput($request);
  26. if (!is_array($insertData)) return $insertData;
  27. Category::create($insertData);
  28. return $this->response->created();
  29. }
  30. /**
  31. * 分类详情
  32. */
  33. public function show(Category $category)
  34. {
  35. return $category;
  36. }
  37. /**
  38. * 更新分类
  39. */
  40. public function update(Request $request, Category $category)
  41. {
  42. if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');
  43. $updateData = $this->checkInput($request);
  44. if (!is_array($updateData)) return $updateData;
  45. $category->update($updateData);
  46. return $this->response->noContent();
  47. }
  48. /**
  49. * 验证提交的参数
  50. */
  51. protected function checkInput($request)
  52. {
  53. // 验证参数
  54. $request->validate([
  55. 'name' => 'required|max:16'
  56. ], [
  57. 'name.required' => '分类名称 不能为空'
  58. ]);
  59. // 获取分组
  60. $group = $request->input('group', 'goods');
  61. // 获取pid
  62. $pid = $request->input('pid', 0);
  63. // 计算level
  64. $level = $pid == 0 ? 1 : (Category::find($pid)->level + 1);
  65. // 不能超过3级分类
  66. if ($level > 2) {
  67. return $this->response->errorBadRequest('不能超过二级分类');
  68. }
  69. return [
  70. 'name' => $request->input('name'),
  71. 'pid' => $pid,
  72. 'level' => $level,
  73. 'group' => $group
  74. ];
  75. }
  76. /**
  77. * 状态禁用和启用
  78. */
  79. public function status(Category $category)
  80. {
  81. if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');
  82. $category->status = $category->status == 1 ? 0 : 1;
  83. $category->save();
  84. return $this->response->noContent();
  85. }
  86. }

Helpers.php

  1. /**
  2. * 缓存没被禁用的分类
  3. */
  4. if (!function_exists('cache_category')) {
  5. function cache_category ()
  6. {
  7. return cache()->rememberForever('cache_category', function () {
  8. return categoryTree('goods', 1);
  9. });
  10. }
  11. }
  12. /**
  13. * 缓存所有的分类
  14. */
  15. if (!function_exists('cache_category_all')) {
  16. function cache_category_all ()
  17. {
  18. return cache()->rememberForever('cache_category_all', function () {
  19. return categoryTree('goods');
  20. });
  21. }
  22. }
  1. /**
  2. * 清空分类缓存
  3. */
  4. if (!function_exists('forget_cache_category')) {
  5. function forget_cache_category ()
  6. {
  7. cache()->forget('cache_category');
  8. cache()->forget('cache_category_all');
  9. }
  10. }
  1. class CategoryTransformer extends TransformerAbstract
  2. {
  3. public function transform(Category $category)
  4. {
  5. return [
  6. 'id' => $category->id,
  7. 'pid' => $category->pid,
  8. 'name' => $category->name,
  9. ];
  10. }
  11. }

商品管理

路由

  1. /**
  2. * 商品管理
  3. */
  4. // 是否上架
  5. $api->patch('goods/{good}/on', [\App\Http\Controllers\Admin\GoodsController::class, 'isOn'])->name('goods.on');
  6. // 是否推荐
  7. $api->patch('goods/{good}/recommend', [\App\Http\Controllers\Admin\GoodsController::class, 'isRecommend'])->name('goods.recommend');
  8. // 商品管理资源路由
  9. $api->resource('goods', \App\Http\Controllers\Admin\GoodsController::class, [
  10. 'except' => ['destroy']
  11. ]);

控制器

  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Http\Controllers\BaseController;
  4. use App\Http\Requests\Admin\GoodsRequest;
  5. use App\Models\Category;
  6. use App\Models\Good;
  7. use App\Transformers\GoodTransformer;
  8. use Illuminate\Http\Request;
  9. class GoodsController extends BaseController
  10. {
  11. /**
  12. * 商品列表
  13. */
  14. public function index(Request $request)
  15. {
  16. $title = $request->query('title');
  17. $category_id = $request->query('category_id');
  18. $is_on = $request->query('is_on', false);
  19. $is_recommend = $request->query('is_recommend', false);
  20. $goods = Good::when($title, function ($query) use ($title) {
  21. $query->where('title', 'like', "%$title%");
  22. })
  23. ->when($category_id, function ($query) use ($category_id) {
  24. $query->where('category_id', $category_id);
  25. })
  26. ->when($is_on !== false, function ($query) use ($is_on) {
  27. $query->where('is_on', $is_on);
  28. })
  29. ->when($is_recommend !== false, function ($query) use ($is_recommend) {
  30. $query->where('is_recommend', $is_recommend);
  31. })
  32. ->orderBy('updated_at', 'desc')
  33. ->paginate($request->query('pageSize', 10), ['*'], 'current');
  34. return $this->response->paginator($goods, new GoodTransformer());
  35. }
  36. /**
  37. * 添加商品
  38. */
  39. public function store(GoodsRequest $request)
  40. {
  41. // 对分类进行一下检查, 只能使用3级分类, 并且分类不能被禁用
  42. $catagory = Category::find($request->category_id);
  43. if (!$catagory) return $this->response->errorBadRequest('分类不存在');
  44. if ($catagory->status == 0) return $this->response->errorBadRequest('分类被禁用');
  45. if ($catagory->level != 2) return $this->response->errorBadRequest('只能向2级分类添加商品');
  46. $user_id = auth('api')->id();
  47. // 追加user_id字段
  48. // $insertData = $request->all();
  49. // $insertData['user_id'] = $user_id;
  50. // Good::create($insertData);
  51. // 追加user_id字段
  52. $request->offsetSet('user_id', $user_id);
  53. Good::create($request->all());
  54. return $this->response->created();
  55. }
  56. /**
  57. * 商品详情
  58. */
  59. public function show(Good $good)
  60. {
  61. return $this->response->item($good, new GoodTransformer());
  62. }
  63. /**
  64. * 更新商品
  65. */
  66. public function update(GoodsRequest $request, Good $good)
  67. {
  68. if ($good->id < 237) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');
  69. // 对分类进行一下检查, 只能使用3级分类, 并且分类不能被禁用
  70. $catagory = Category::find($request->category_id);
  71. if (!$catagory) return $this->response->errorBadRequest('分类不存在');
  72. // if ($catagory->status == 0) return $this->response->errorBadRequest('分类被禁用');
  73. if ($catagory->level != 2) return $this->response->errorBadRequest('只能向2级分类添加商品');
  74. $good->update($request->all());
  75. return $this->response->noContent();
  76. }
  77. /**
  78. * 是否上架
  79. */
  80. public function isOn(Good $good)
  81. {
  82. $good->is_on = $good->is_on == 0 ? 1 : 0;
  83. $good->save();
  84. return $this->response->noContent();
  85. }
  86. /**
  87. * 是否推荐
  88. */
  89. public function isRecommend(Good $good)
  90. {
  91. $good->is_recommend = $good->is_recommend == 0 ? 1 : 0;
  92. $good->save();
  93. return $this->response->noContent();
  94. }
  95. }
  1. <?php
  2. namespace App\Transformers;
  3. use App\Models\Category;
  4. use App\Models\Good;
  5. use League\Fractal\TransformerAbstract;
  6. class GoodTransformer extends TransformerAbstract
  7. {
  8. protected $availableIncludes = ['category', 'user', 'comments'];
  9. public function transform(Good $good)
  10. {
  11. $pics_url = [];
  12. if (!empty($good->pics)) {
  13. foreach ($good->pics as $p) {
  14. array_push($pics_url, oss_url($p));
  15. }
  16. }
  17. return [
  18. 'id' => $good->id,
  19. 'title' => $good->title,
  20. 'category_id' => $good->category_id,
  21. 'user_id' => $good->user_id,
  22. // 'category_name' => Category::find($good->category_id)->name,
  23. 'description' => $good->description,
  24. 'price' => $good->price,
  25. 'stock' => $good->stock,
  26. 'sales' => $good->sales,
  27. 'cover' => $good->cover,
  28. 'cover_url' => oss_url($good->cover),
  29. 'pics' => $good->pics,
  30. 'pics_url' => $pics_url,
  31. 'details' => $good->details,
  32. 'is_on' => $good->is_on,
  33. 'is_recommend' => $good->is_recommend,
  34. 'created_at' => empty($good->created_at) ? $good->created_at : $good->created_at->toDateTimeString(),
  35. 'updated_at' => empty($good->updated_at) ? $good->updated_at : $good->updated_at->toDateTimeString(),
  36. ];
  37. }
  38. /**
  39. * 额外的分类数据
  40. */
  41. public function includeCategory(Good $good)
  42. {
  43. return $this->item($good->category, new CategoryTransformer());
  44. }
  45. /**
  46. * 额外的用户数据
  47. */
  48. public function includeUser(Good $good)
  49. {
  50. return $this->item($good->user, new UserTransformer());
  51. }
  52. /**
  53. * 额外的评价数据
  54. */
  55. public function includeComments(Good $good)
  56. {
  57. return $this->collection($good->comments, new CommentTransformer());
  58. }
  59. }

OSS 存储

接入阿里云OSS

  • 开通阿里云OSS
  • 购买资源包
  • 创建Bucket
  • 设置跨域规则

其他说明

安装oss组件:

  1. $ composer require "iidestiny/laravel-filesystem-oss"

OSS文档地址:

OSS文档

创建控制器

  1. php artisan make:controller Auth/OssController

添加路由

  1. $api->get('oss/token', [\App\Http\Controllers\Auth\OssController::class, 'token']);
  1. $disk = Storage::disk('oss');
  2. $config = $disk->signatureConfig($prefix = '/', $callBackUrl = '', $customData = [], $expire = 300);
  3. $configArr = json_decode($config, true);
  4. return $this->response->array($configArr);
  1. if (!function_exists('oss_url')) {
  2. function oss_url($key)
  3. {
  4. // 如果没有$key
  5. if (empty($key)) return '';
  6. // 如果$key包含了http等, 是一个完整的地址, 直接返回
  7. if (strpos($key, 'http://') !== false
  8. || strpos($key, 'https://') !== false
  9. || strpos($key, 'data:image') !== false) {
  10. return $key;
  11. }
  12. return config('filesystems')['disks']['oss']['bucket_url'] . '/' . $key;
  13. }
  14. }

什么是多用户角色

举个例子,例如我们平常使用的论坛

  • 站长 ——— 拥有最高权限,最主要的是能够对用户进行管理的权限

  • 管理员 ——- 对一些文章的管理,不会造成对网站有较大的影响

  • 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

laravel-permission 基于上面 的表情况,将用户与权限和角色相关联

1. 安装扩展包

通过 Composer 安装:

  1. $ composer require "spatie/laravel-permission"

生成数据库迁移文件:

php artisan vendor:publish —provider=”Spatie\Permission\PermissionServiceProvider”

在migration目录下可看到相关表信息,执行数据库迁移

  1. php artisan migrate

在User 模型下加载

  1. .....
  2. use Spatie\Permission\Traits\HasRoles; // use
  3. class User extends Authenticatable
  4. {
  5. use HasRoles; // 加载角色相关信息
  6. .....

修改迁移文件添加为权限和角色添加cn_name

  1. $table->string('cn_name');

// 创建数据填充

  1. php artisan make:seeder PermissionSeeder

修改DatabaseSeeder

  1. public function run()
  2. {
  3. $this->call(PermissionSeeder::class);
  4. }
  1. public function run()
  2. {
  3. // 清空缓存
  4. app()['cache']->forget('spatie.permission.cache');
  5. // 添加权限
  6. $permissions = [
  7. ['name' => 'users.index', 'cn_name' => '用户列表', 'guard_name' => 'api'],
  8. ['name' => 'users.show', 'cn_name' => '用户详情', 'guard_name' => 'api'],
  9. ['name' => 'users.lock', 'cn_name' => '用户禁用启用', 'guard_name' => 'api'],
  10. ];
  11. foreach ($permissions as $p) {
  12. Permission::create($p);
  13. }
  14. // 添加角色
  15. $role = Role::create(['name' => 'super-admin', 'cn_name' => '超级管理员', 'guard_name' => 'api']);
  16. // 为角色添加权限
  17. $role->givePermissionTo(Permission::all());
  18. }

执行dbseed

  1. php artisan db:seed --class PermissionSeeder

创建用户DBSEED

  1. php artisan make:seed UserSeeder
  1. <?php
  2. namespace Database\Seeders;
  3. use App\Models\User;
  4. use Illuminate\Database\Seeder;
  5. class UserSeeder extends Seeder
  6. {
  7. /**
  8. * Run the database seeds.
  9. *
  10. * @return void
  11. */
  12. public function run()
  13. {
  14. // 创建用户
  15. $user = User::create([
  16. 'name' => '超级管理员',
  17. 'email' => 'super@a.com',
  18. 'password' => bcrypt('123123')
  19. ]);
  20. // 给用户分配角色
  21. $user->assignRole('super-admin');
  22. }
  23. }

验证权限

创建一个中间件

  1. php artisan make:middleware CheckPermission
  1. /**
  2. * Handle an incoming request.
  3. *
  4. * @param \Illuminate\Http\Request $request
  5. * @param \Closure $next
  6. * @return mixed
  7. */
  8. public function handle(Request $request, Closure $next)
  9. {
  10. // 验证用户是否具有请求权限
  11. $user = auth('api')->user();
  12. if (!$user->can($request->route()->getName())) {
  13. abort(403);
  14. }
  15. return $next($request);
  16. }

app/Http/Kernel.php

  1. protected $routeMiddleware = [
  2. ....
  3. 'check.permission' => \App\Http\Middleware\CheckPermission::class
  4. ];

路由上添加中间件

  1. $api->group(['prefix' => 'admin','middleware' => ['api.auth','check.permission']], function ($api) {

使用

为用户添加权限

  1. $user->givePermissionTo('edit articles');

为用户添加角色

  1. $user->assignRole('writer');
  2. $user->assignRole(['writer', 'admin']);

给用户删除权限

  1. $user->revokePermissionTo('edit articles');

给角色添加权限

  1. $role->givePermissionTo('edit articles');

为角色添加权限

  1. $role->givePermissionTo('edit articles');

撤销一个权限 并且 添加一个新权限

  1. $user->syncPermissions(['edit articles', 'delete articles']);

获得当前用户的角色集合

  1. $user->getRoleNames();

将多个角色同步到权限

  1. $role->syncPermissions($permissions); // @param array $permissions
  2. $permission->syncRoles($roles);

从角色中删除权限

  1. $role->revokePermissionTo($permission);
  2. $permission->removeRole($role);

获取当前的用户的权限列表

  1. $permissions = $user->permissions;

获取用户的所有权限,或者直接权限 (odel_has_permissions),或者从角色获取,或者从两者获取

  1. $permissions = $user->getDirectPermissions();
  2. $permissions = $user->getPermissionsViaRoles();
  3. $permissions = $user->getAllPermissions();

获取用户的角色集合 collection

  1. $roles = $user->getRoleNames(); // Returns a collection

返回指定角色的用户 | Returns only users with the role ‘writer’

  1. $users = User::role('writer')->get(); //

返回指定权限的用户

  1. $users = User::permission('edit articles')->get();

用户有什么角色

  1. $user->hasRole('writer');

验证类

检查是否有某个权限

  1. $user->hasPermissionTo('edit articles');
  2. $user->can('edit articles');

检查是否有某个角色|或者列

  1. $user->hasRole('writer');
  2. $user->hasAnyRole(Role::all());
  3. $user->hasAllRoles(Role::all());

传递id值进行判断是否有某个权限

  1. $user->hasPermissionTo('1');
  2. $user->hasPermissionTo(Permission::find(1)->id);
  3. $user->hasPermissionTo($somePermission->id);

是否拥有一组权限

  1. $user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);

检查一个角色是否有某些权限 | 删除某些权限

  1. $role->hasPermissionTo('edit articles');
  2. $role->revokePermissionTo('edit articles'); // 删除

模板使用

  1. @role('writer')
  2. I am a writer!
  3. @else
  4. I am not a writer...
  5. @endrole
  6. ------------------------
  7. @hasrole('writer')
  8. I am a writer!
  9. @else
  10. I am not a writer...
  11. @endhasrole
  12. ------------------------
  13. @can('edit articles') // 拥有某个权限 可执行操作
  14. //
  15. @endcan

数据填充

  1. use Illuminate\Database\Seeder;
  2. use Spatie\Permission\Models\Role;
  3. use Spatie\Permission\Models\Permission;
  4. class RolesAndPermissionsSeeder extends Seeder
  5. {
  6. public function run()
  7. {
  8. // Reset cached roles and permissions
  9. app()['cache']->forget('spatie.permission.cache');
  10. // create permissions
  11. Permission::create(['name' => 'edit articles']);
  12. Permission::create(['name' => 'delete articles']);
  13. Permission::create(['name' => 'publish articles']);
  14. Permission::create(['name' => 'unpublish articles']);
  15. // create roles and assign created permissions
  16. $role = Role::create(['name' => 'writer']);
  17. $role->givePermissionTo('edit articles');
  18. $role = Role::create(['name' => 'moderator']);
  19. $role->givePermissionTo(['publish articles', 'unpublish articles']);
  20. $role = Role::create(['name' => 'super-admin']);
  21. $role->givePermissionTo(Permission::all());
  22. }
  23. }

提示:如果在数据库权限相关信息表的修改,必须掉用清除 缓存的方法

  1. // 命令删除
  2. php artisan cache:forget spatie.permission.cache


​ app()[‘cache’]->forget(‘spatie.permission.cache’);

更多相关文章

  1. Oracle的用户权限及其管理操作
  2. Linux-06关于sudo
  3. 6.【商城后台管理系统】基于TP6开发角色的权限分配递归生成无限
  4. 5.【商城后台管理系统】基于TP6开发RBAC角色权限管理权限分配等
  5. PHP:【商城后台管理系统】部署角色管理,角色添加,菜单权限,删除角色
  6. 封杀两年后,GitHub恢复伊朗开发者使用权限!
  7. 教你 Shiro + SpringBoot 整合 JWT
  8. 教你 Shiro 整合 SpringBoot,避开各种坑
  9. Linux_centos 搭建FTP服务器

随机推荐

  1. 从100PV到1亿级PV网站架构演变-知识结构
  2. 不同类型业务系统技术架构的差异化
  3. 程序员何苦为难程序员
  4. 推荐系统实战
  5. 程序员,你的一千万在哪里
  6. 图解HTTP(一)
  7. 推荐
  8. 《推荐系统实践》—— 读后总结
  9. 图解HTTP(二)
  10. 《Effective Java》—— 读后总结