From ad31828c5f2db2107fdebbb610d404a6d826decf Mon Sep 17 00:00:00 2001 From: Edward Yang Date: Mon, 1 Aug 2022 11:51:18 +0800 Subject: [PATCH] add spatie permission --- .../Http/Controllers/AdminUserController.php | 27 +++ .../Controllers/AdminUserGroupController.php | 27 +++ beike/Admin/Routes/admin.php | 3 + beike/Admin/View/Components/Sidebar.php | 3 +- beike/Models/AdminUser.php | 7 +- composer.json | 1 + composer.lock | 90 +++++++- config/permission.php | 161 +++++++++++++ ..._08_01_033755_create_permission_tables.php | 141 ++++++++++++ .../views/pages/admin_users/index.blade.php | 214 ++++++++++++++++++ 10 files changed, 669 insertions(+), 5 deletions(-) create mode 100644 beike/Admin/Http/Controllers/AdminUserController.php create mode 100644 beike/Admin/Http/Controllers/AdminUserGroupController.php create mode 100644 config/permission.php create mode 100644 database/migrations/2022_08_01_033755_create_permission_tables.php create mode 100644 resources/beike/admin/views/pages/admin_users/index.blade.php diff --git a/beike/Admin/Http/Controllers/AdminUserController.php b/beike/Admin/Http/Controllers/AdminUserController.php new file mode 100644 index 00000000..1278fb6d --- /dev/null +++ b/beike/Admin/Http/Controllers/AdminUserController.php @@ -0,0 +1,27 @@ + + * @created 2022-08-01 11:44:54 + * @modified 2022-08-01 11:44:54 + */ + +namespace Beike\Admin\Http\Controllers; + +use Beike\Models\AdminUser; + +class AdminUserController extends Controller +{ + public function index() + { + $data = [ + 'admin_users' => AdminUser::query()->get(), + 'admin_user_groups' => [], + ]; + + return view('admin::pages.admin_users.index', $data); + } +} diff --git a/beike/Admin/Http/Controllers/AdminUserGroupController.php b/beike/Admin/Http/Controllers/AdminUserGroupController.php new file mode 100644 index 00000000..2ed5a06b --- /dev/null +++ b/beike/Admin/Http/Controllers/AdminUserGroupController.php @@ -0,0 +1,27 @@ + + * @created 2022-08-01 11:44:54 + * @modified 2022-08-01 11:44:54 + */ + +namespace Beike\Admin\Http\Controllers; + +use Beike\Models\AdminUser; + +class AdminUserGroupController extends Controller +{ + public function index() + { + $data = [ + 'admin_users' => AdminUser::query()->get(), + 'admin_user_groups' => [], + ]; + + return view('admin::pages.admin_users.index', $data); + } +} diff --git a/beike/Admin/Routes/admin.php b/beike/Admin/Routes/admin.php index fc270a18..4f4b102b 100644 --- a/beike/Admin/Routes/admin.php +++ b/beike/Admin/Routes/admin.php @@ -75,5 +75,8 @@ Route::prefix($adminName) Route::resource('tax_classes', Controllers\TaxClassController::class); Route::resource('tax_rates', Controllers\TaxRateController::class); + + Route::resource('admin_users', Controllers\AdminUserController::class); + Route::resource('admin_user_groups', Controllers\AdminUserGroupController::class); }); }); diff --git a/beike/Admin/View/Components/Sidebar.php b/beike/Admin/View/Components/Sidebar.php index 7f5e8c62..80ce2494 100644 --- a/beike/Admin/View/Components/Sidebar.php +++ b/beike/Admin/View/Components/Sidebar.php @@ -59,8 +59,9 @@ class Sidebar extends Component $this->addLink('订单列表', admin_route('orders.index'), 'fa fa-tachometer-alt', $this->equalRoute('orders.index')); } - if (Str::startsWith($routeName, ['settings.', 'plugins.', 'tax_classes', 'tax_rates', 'regions'])) { + if (Str::startsWith($routeName, ['settings.', 'admin_users.', 'plugins.', 'tax_classes', 'tax_rates', 'regions'])) { $this->addLink('系统设置', admin_route('settings.index'), 'fa fa-tachometer-alt', $this->equalRoute('settings.index')); + $this->addLink('后台用户', admin_route('admin_users.index'), 'fa fa-tachometer-alt', $this->equalRoute('admin_users.index')); $this->addLink('插件列表', admin_route('plugins.index'), 'fa fa-tachometer-alt', $this->equalRoute('plugins.index')); $this->addLink('区域分组', admin_route('regions.index'), 'fa fa-tachometer-alt', $this->equalRoute('regions.index')); $this->addLink('税率设置', admin_route('tax_rates.index'), 'fa fa-tachometer-alt', $this->equalRoute('tax_rates.index')); diff --git a/beike/Models/AdminUser.php b/beike/Models/AdminUser.php index c33357d4..61397207 100644 --- a/beike/Models/AdminUser.php +++ b/beike/Models/AdminUser.php @@ -2,12 +2,13 @@ namespace Beike\Models; +use Spatie\Permission\Traits\HasRoles; +use Illuminate\Foundation\Auth\User as AuthUser; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Foundation\Auth\User as Authenticatable; -class AdminUser extends Authenticatable +class AdminUser extends AuthUser { - use HasFactory; + use HasFactory, HasRoles; const AUTH_GUARD = 'web_admin'; diff --git a/composer.json b/composer.json index 6cadfa2f..133f518c 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "intervention/image": "^2.7", "laravel/framework": "^8.65", "laravel/tinker": "^2.5", + "spatie/laravel-permission": "^5.5", "stripe/stripe-php": "^8.8", "tormjens/eventy": "^0.8.0", "zanysoft/laravel-zip": "^1.0" diff --git a/composer.lock b/composer.lock index 2af39ed0..b40e771c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a2f9810c5fd9c6583f1bf3fcbb73a7a7", + "content-hash": "aac8029e87eec53aba09f0246568e27b", "packages": [ { "name": "asm89/stack-cors", @@ -3234,6 +3234,94 @@ ], "time": "2021-09-25T23:10:38+00:00" }, + { + "name": "spatie/laravel-permission", + "version": "5.5.5", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-permission.git", + "reference": "f2303a70be60919811ca8afc313e8244fda00974" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/f2303a70be60919811ca8afc313e8244fda00974", + "reference": "f2303a70be60919811ca8afc313e8244fda00974", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "illuminate/auth": "^7.0|^8.0|^9.0", + "illuminate/container": "^7.0|^8.0|^9.0", + "illuminate/contracts": "^7.0|^8.0|^9.0", + "illuminate/database": "^7.0|^8.0|^9.0", + "php": "^7.3|^8.0|^8.1" + }, + "require-dev": { + "orchestra/testbench": "^5.0|^6.0|^7.0", + "phpunit/phpunit": "^9.4", + "predis/predis": "^1.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Permission\\PermissionServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "5.x-dev", + "dev-master": "5.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Permission\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Permission handling for Laravel 6.0 and up", + "homepage": "https://github.com/spatie/laravel-permission", + "keywords": [ + "acl", + "laravel", + "permission", + "permissions", + "rbac", + "roles", + "security", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-permission/issues", + "source": "https://github.com/spatie/laravel-permission/tree/5.5.5" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-06-29T23:11:42+00:00" + }, { "name": "stripe/stripe-php", "version": "v8.8.0", diff --git a/config/permission.php b/config/permission.php new file mode 100644 index 00000000..5b6e184c --- /dev/null +++ b/config/permission.php @@ -0,0 +1,161 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Spatie\Permission\Models\Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Spatie\Permission\Models\Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, //default 'role_id', + 'permission_pivot_key' => null, //default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false, if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true the package implements teams using the 'team_foreign_key'. If you want + * the migrations to register the 'team_foreign_key', you must set this to true + * before doing the migration. If you already did the migration then you must make a new + * migration to also add 'team_foreign_key' to 'roles', 'model_has_roles', and + * 'model_has_permissions'(view the latest version of package's migration file) + */ + + 'teams' => false, + + /* + * When set to true, the required permission names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + */ + + 'enable_wildcard_permission' => false, + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => \DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/database/migrations/2022_08_01_033755_create_permission_tables.php b/database/migrations/2022_08_01_033755_create_permission_tables.php new file mode 100644 index 00000000..04c3278b --- /dev/null +++ b/database/migrations/2022_08_01_033755_create_permission_tables.php @@ -0,0 +1,141 @@ +bigIncrements('id'); // permission id + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) { + $table->bigIncrements('id'); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + + }); + + Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $tableNames = config('permission.table_names'); + + if (empty($tableNames)) { + throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + } + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +} diff --git a/resources/beike/admin/views/pages/admin_users/index.blade.php b/resources/beike/admin/views/pages/admin_users/index.blade.php new file mode 100644 index 00000000..029d73d9 --- /dev/null +++ b/resources/beike/admin/views/pages/admin_users/index.blade.php @@ -0,0 +1,214 @@ +@extends('admin::layouts.master') + +@section('title', '后台用户') + +@section('content') + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
#名称描述创建时间修改时间操作
@{{ tax.id }}@{{ tax.name }}@{{ tax.email }}@{{ tax.created_at }}@{{ tax.updated_at }} + + +
+ + {{-- {{ $tax_classes->links('admin::vendor/pagination/bootstrap-4') }} --}} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
税率基于优先级
+ + + + + + + + + +
+ 添加规则 +
+ + 保存 + 取消 + +
+
+
+@endsection + +@push('footer') + +@endpush