Blogger Information
Blog 40
fans 0
comment 0
visits 27769
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
商品和oss
初见
Original
572 people have browsed it

分类管理

  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’);

Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post