diff --git a/app/Admin/Controllers/KeywordController.php b/app/Admin/Controllers/KeywordController.php new file mode 100644 index 0000000..29d127c --- /dev/null +++ b/app/Admin/Controllers/KeywordController.php @@ -0,0 +1,62 @@ +baseCRUD() + ->filterTogglable(false) + ->headerToolbar([ + $this->createButton()->visible($user->can('keywords.create')), + ...$this->baseHeaderToolBar(), + ]) + ->columns([ + amis()->TableColumn('id', 'ID')->sortable(), + amis()->TableColumn('key', 'KEY'), + amis()->TableColumn('name', '名称'), + amis()->TableColumn('value', '值'), + $this->rowActions([ + $this->rowShowButton()->visible($user->can('keywords.show')), + $this->rowEditButton()->visible($user->can('keywords.edit')), + $this->rowDeleteButton()->visible($user->can('keywords.delete')), + ]) + ]); + + return $this->baseList($crud); + } + + public function form($isEdit = false) + { + return $this->baseForm()->body([ + amis()->TextControl('key', 'KEY'), + amis()->TextControl('name', '名称'), + amis()->TextControl('value', '值'), + ]); + } + + public function detail() + { + return $this->baseDetail()->body([ + amis()->TextControl('id', 'ID')->static(), + amis()->TextControl('key', 'KEY')->static(), + amis()->TextControl('name', '名称')->static(), + amis()->TextControl('value', '值')->static(), + amis()->TextControl('created_at', admin_trans('admin.created_at'))->static(), + amis()->TextControl('updated_at', admin_trans('admin.updated_at'))->static(), + ]); + } +} \ No newline at end of file diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 69dce55..99a318f 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -10,9 +10,8 @@ Route::group([ 'prefix' => config('admin.route.prefix'), 'middleware' => config('admin.route.middleware'), ], function (Router $router) { - $router->resource('dashboard', \App\Admin\Controllers\HomeController::class); - $router->resource('system/settings', \App\Admin\Controllers\SettingController::class); + $router->get('dashboard', [\App\Admin\Controllers\HomeController::class, 'index'])->name('dashboard'); + $router->resource('system/settings', \App\Admin\Controllers\SettingController::class)->only(['index', 'store']); - // 字典管理 $router->resource('system/keywords', \App\Admin\Controllers\KeywordController::class); }); diff --git a/app/Http/Middleware/AdminPermission.php b/app/Http/Middleware/AdminPermission.php new file mode 100644 index 0000000..4d9cfb0 --- /dev/null +++ b/app/Http/Middleware/AdminPermission.php @@ -0,0 +1,66 @@ +path() == Admin::config('admin.route.prefix')) { + return $next($request); + } + + $excepted = collect(Admin::config('admin.auth.except', [])) + ->merge(Admin::config('admin.show_development_tools') ? ['/dev_tools*'] : []) + ->map(fn($path) => $this->pathFormatting($path)) + ->contains(fn($except) => $request->is($except == '/' ? $except : trim($except, '/'))); + + if ($excepted) { + return $next($request); + } + + $user = Admin::user(); + if (!$user) { + return $next($request); + } + if ($user->isAdministrator() || $user->can($name)) { + return $next($request); + } + + return Admin::response()->fail(admin_trans('admin.unauthorized')); + } + + private function pathFormatting($path) + { + $prefix = '/' . trim(Admin::config('admin.route.prefix'), '/'); + + $prefix = ($prefix === '/') ? '' : $prefix; + + $path = trim($path, '/'); + + if (is_null($path) || $path === '') { + return $prefix ?: '/'; + } + return $prefix . '/' . $path; + } +} diff --git a/app/Models/Keyword.php b/app/Models/Keyword.php new file mode 100644 index 0000000..4c2ed03 --- /dev/null +++ b/app/Models/Keyword.php @@ -0,0 +1,12 @@ + 'Owl Admin', @@ -21,7 +23,14 @@ return [ 'prefix' => 'admin-api', 'domain' => null, 'namespace' => 'App\\Admin\\Controllers', - 'middleware' => ['admin'], + 'middleware' => [ + 'admin.autoSetLocale', + 'admin.auth', + 'admin.bootstrap', + AdminPermission::class, + 'sanctum', + 'substitute', + ], // 不包含额外路由, 配置后, 不会追加新增/详情/编辑页面路由 'without_extra_routes' => [ '/dashboard', diff --git a/database/migrations/2024_07_07_090305_create_keywords_table.php b/database/migrations/2024_07_07_090305_create_keywords_table.php new file mode 100644 index 0000000..c9e3c45 --- /dev/null +++ b/database/migrations/2024_07_07_090305_create_keywords_table.php @@ -0,0 +1,39 @@ +id(); + $table->string('key')->unique(); + $table->string('name'); + $table->string('value')->nullable(); + $table->text('description')->nullable(); + $table->text('content')->nullable(); + $table->string('image')->nullable(); + $table->json('images')->nullable(); + $table->unsignedInteger('sort')->default(0)->comment('排序(正序)'); + $table->unsignedBigInteger('parent_id')->default(0)->comment('上级ID'); + $table->unsignedInteger('level')->default(1)->comment('层级'); + $table->string('path')->default('-')->comment('所有的父级ID'); + $table->json('options')->nullable()->comment('扩展'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('keywords'); + } +}; diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php index ce3e99b..f9e17cb 100644 --- a/database/seeders/AdminPermissionSeeder.php +++ b/database/seeders/AdminPermissionSeeder.php @@ -4,6 +4,7 @@ namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; use Slowlyo\OwlAdmin\Models\{AdminMenu, AdminPermission}; use Slowlyo\OwlAdmin\Support\Cores\Database; @@ -41,19 +42,22 @@ class AdminPermissionSeeder extends Seeder foreach($list as $item) { $parent_permission_id = data_get($parent, 'permission', 0); $parent_menu_id = data_get($parent, 'menu', 0); - $permission = $this->createPermission($item, $parent_permission_id); $menu = $this->createMenu($item, $parent_menu_id); - - $menu_has_permissions = [ - ['permission_id' => $permission->id, 'menu_id' => $menu->id] - ]; - if ($parent_menu_id) { - array_push($menu_has_permissions, ['permission_id' => $permission->id,'menu_id' => $parent_menu_id]); - } - DB::table('admin_permission_menu')->insert($menu_has_permissions); + $permission = $this->createPermission($item, $parent_permission_id, $menu); if (isset($item['children'])) { $this->createByTree($item['children'], ['permission' => $permission->id, 'menu' => $menu->id]); } + $resource_permissions = data_get($item, 'permissions', []); + if (isset($item['resource'])) { + $resource_permissions = array_merge($resource_permissions, $this->getResourcePermissions($item['resource'])); + } + foreach($resource_permissions as $key => $name) { + $this->createPermission([ + 'name' => $name, + 'slug' => $item['slug'].'.'.$key, + 'url' => null + ], $permission->id, $menu); + } } } @@ -69,15 +73,50 @@ class AdminPermissionSeeder extends Seeder ]); } - protected function createPermission($item, $pid = 0) + protected function createPermission($item, $pid = 0, $menu = null) { + $slug = data_get($item, 'slug'); $url = data_get($item, 'url'); - return AdminPermission::create([ + $permission = AdminPermission::create([ 'parent_id' => $pid, 'custom_order' => data_get($item, 'custom_order', 0), 'name' => data_get($item, 'name'), - 'slug' => data_get($item, 'slug'), - 'http_path' => $url ? [$url . '*'] : null, + 'slug' => $slug, + 'http_path' => $slug, ]); + if ($menu) { + $menu_has_permissions = [ + ['permission_id' => $permission->id, 'menu_id' => $menu->id] + ]; + + $parent_menu = $menu->parent; + do { + if ($parent_menu) { + array_push($menu_has_permissions, ['permission_id' => $permission->id, 'menu_id' => $parent_menu->id]); + $parent_menu = $parent_menu->parent; + } + }while($parent_menu); + DB::table('admin_permission_menu')->insert($menu_has_permissions); + } + return $permission; + } + + protected function getResourcePermissions($resource) + { + $maps = [ + 'index' => '列表', + 'create' => '添加', + 'edit' => '修改', + 'show' => '详细', + 'delete' => '删除' + ]; + if ($resource == true) { + return $maps; + } + else if (is_array($resource)) { + return Arr::only($maps, $resource); + } + + return []; } } diff --git a/lang/zh_CN/keywords.php b/lang/zh_CN/keywords.php new file mode 100644 index 0000000..85c2ad8 --- /dev/null +++ b/lang/zh_CN/keywords.php @@ -0,0 +1,17 @@ + 'ID', + 'name' => '名称', + 'key' => 'KEY', + 'value' => '值', + 'parent_id' => '上级', + 'type_key' => '上级', + 'path' => '上级', + 'sort' => '排序(倒序)', + 'level' => '层级', + 'options' => '扩展', + 'image' => '图片', + 'description' => '描述', + 'content' => '内容', +]; diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 8364a84..c14d65f 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -12,8 +12,11 @@ class ExampleTest extends TestCase */ public function test_the_application_returns_a_successful_response(): void { - $response = $this->get('/'); - - $response->assertStatus(200); + $arr = ['a' => 1, 'b' => 2]; + $b = [ + ...$arr, + 'a' => 'A' + ]; + dump($b); } }