1
0
Fork 0

middleware AdminPermission

main
panliang 2024-07-08 01:02:27 +08:00
parent 8700ffd267
commit 2d25f38d12
10 changed files with 283 additions and 20 deletions

View File

@ -0,0 +1,62 @@
<?php
namespace App\Admin\Controllers;
use App\Services\KeywordService;
use Slowlyo\OwlAdmin\Admin;
use Slowlyo\OwlAdmin\Controllers\AdminController;
/**
* 字典管理
*
* @property KeywordService $service
*/
class KeywordController extends AdminController
{
protected string $serviceName = KeywordService::class;
public function list()
{
$user = Admin::user();
$crud = $this->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(),
]);
}
}

View File

@ -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);
});

View File

@ -0,0 +1,66 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Slowlyo\OwlAdmin\Admin;
use Symfony\Component\HttpFoundation\Response;
class AdminPermission
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, ...$args): Response
{
$name = Route::currentRouteName();
if (!$name) {
return $next($request);
}
if (Admin::config('admin.auth.permission') === false) {
return $next($request);
}
if ($request->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;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Models;
use Slowlyo\OwlAdmin\Models\BaseModel as Model;
/**
* 字典管理
*/
class Keyword extends Model
{
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Services;
use App\Models\Keyword;
use Slowlyo\OwlAdmin\Services\AdminService;
/**
* 字典管理
*
* @method Keyword getModel()
* @method Keyword|\Illuminate\Database\Query\Builder query()
*/
class KeywordService extends AdminService
{
protected string $modelName = Keyword::class;
}

View File

@ -1,5 +1,7 @@
<?php
use App\Http\Middleware\AdminPermission;
return [
// 应用名称
'name' => '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',

View File

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('keywords', function (Blueprint $table) {
$table->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');
}
};

View File

@ -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 [];
}
}

View File

@ -0,0 +1,17 @@
<?php
return [
'id' => 'ID',
'name' => '名称',
'key' => 'KEY',
'value' => '值',
'parent_id' => '上级',
'type_key' => '上级',
'path' => '上级',
'sort' => '排序(倒序)',
'level' => '层级',
'options' => '扩展',
'image' => '图片',
'description' => '描述',
'content' => '内容',
];

View File

@ -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);
}
}