owl-admin-base/app/Admin/Controllers/System/AdminPermissionController.php

224 lines
8.0 KiB
PHP

<?php
namespace App\Admin\Controllers\System;
use App\Admin\Controllers\AdminController;
use App\Admin\Services\System\AdminMenuService;
use App\Admin\Services\System\AdminPermissionService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Slowlyo\OwlAdmin\Admin;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Tag;
/**
* @property AdminPermissionService $service
*/
class AdminPermissionController extends AdminController
{
protected string $serviceName = AdminPermissionService::class;
public function list(): Page
{
$crud = $this->baseCRUD()
->loadDataOnce()
->filterTogglable(false)
->footerToolbar([])
->headerToolbar([
$this->createTypeButton('drawer', 'lg')->visible(Admin::user()->can('admin.system.admin_permissions.create')),
...$this->baseHeaderToolBar(),
])
->bulkActions([
$this->bulkDeleteButton()->visible(Admin::user()->can('admin.system.admin_permissions.delete')),
])
->columns([
amis()->TableColumn('id', 'ID')->sortable(),
amis()->TableColumn('name', __('admin.admin_permission.name')),
amis()->TableColumn('slug', __('admin.admin_permission.slug')),
amis()->TableColumn('http_method', __('admin.admin_permission.http_method'))
->type('each')
->items(
Tag::make()->label('${item}')->className('my-1')
)
->placeholder(Tag::make()->label('ANY')),
amis()->TableColumn('http_path', __('admin.admin_permission.http_path'))
->type('each')
->items(
Tag::make()->label('${item}')->className('my-1')
),
$this->rowActions([
$this->rowEditTypeButton('drawer', 'lg')
->visible(Admin::user()->can('admin.system.admin_permissions.update')),
$this->rowDeleteButton()->visible(Admin::user()->can('admin.system.admin_permissions.delete')),
]),
]);
return $this->baseList($crud);
}
public function form(): Form
{
return $this->baseForm()->body([
amis()->TextControl('name', __('admin.admin_permission.name'))->required(),
amis()->TextControl('slug', __('admin.admin_permission.slug'))->required(),
amis()->TreeSelectControl('parent_id', __('admin.parent'))
->labelField('name')
->valueField('id')
->value(0)
->options($this->service->getTree()),
amis()->CheckboxesControl('http_method', __('admin.admin_permission.http_method'))
->options($this->getHttpMethods())
->description(__('admin.admin_permission.http_method_description'))
->joinValues(false)
->extractValue(),
amis()->NumberControl('order', __('admin.order'))
->required()
->labelRemark(__('admin.order_asc'))
->displayMode('enhance')
->min(0)
->value(0),
amis()->ArrayControl('http_path', __('admin.admin_permission.http_path'))
->items(amis()->TextControl()->options($this->getRoutes())->required()),
amis()->TreeSelectControl('menus', __('admin.menus'))
->searchable()
->multiple()
->showIcon(false)
->options(AdminMenuService::make()->getTree())
->labelField('title')
->valueField('id')
->autoCheckChildren(false)
->joinValues(false)
->extractValue(),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
private function getHttpMethods(): array
{
return collect(Admin::adminPermissionModel()::$httpMethods)->map(fn ($method) => [
'value' => $method,
'label' => $method,
])->toArray();
}
public function getRoutes(): array
{
$prefix = (string) Admin::config('admin.route.prefix');
$container = collect();
return collect(app('router')->getRoutes())->map(function ($route) use ($prefix, $container) {
if (! Str::startsWith($uri = $route->uri(), $prefix) && $prefix && $prefix !== '/') {
return null;
}
if (! Str::contains($uri, '{')) {
if ($prefix !== '/') {
$route = Str::replaceFirst($prefix, '', $uri.'*');
} else {
$route = $uri.'*';
}
$route !== '*' && $container->push($route);
}
$path = preg_replace('/{.*}+/', '*', $uri);
$prefix !== '/' && $path = Str::replaceFirst($prefix, '', $path);
return $path;
})->merge($container)->filter()->unique()->map(function ($method) {
return [
'value' => $method,
'label' => $method,
];
})->values()->all();
}
public function autoGenerate()
{
$menus = Admin::adminMenuModel()::query()->get()->toArray();
$slugMap = Admin::adminPermissionModel()::query()->get(['id', 'slug'])->keyBy('id')->toArray();
$slugCache = [];
$permissions = [];
foreach ($menus as $menu) {
$_httpPath =
$menu['url_type'] == Admin::adminMenuModel()::TYPE_ROUTE ? $this->getHttpPath($menu['url']) : '';
$menuTitle = $menu['title'];
// 避免名称重复
if (in_array($menuTitle, data_get($permissions, '*.name', []))) {
$menuTitle = sprintf('%s(%s)', $menuTitle, $menu['id']);
}
if ($_httpPath) {
$slug = Str::of(explode('?', $_httpPath)[0])->trim('/')->replace('/', '.')->replace('*', '')->value();
} else {
$slug = Str::uuid();
}
if (in_array($slug, $slugCache)) {
$slug = $slug.'.'.$menu['id'];
}
$slugCache[] = $slug;
$permissions[] = [
'id' => $menu['id'],
'name' => $menuTitle,
'slug' => data_get($slugMap, $menu['id'].'.slug') ?: $slug,
'http_path' => json_encode($_httpPath ? [$_httpPath] : ''),
'order' => $menu['order'],
'parent_id' => $menu['parent_id'],
'created_at' => $menu['created_at'],
'updated_at' => $menu['updated_at'],
];
}
Admin::adminPermissionModel()::query()->truncate();
Admin::adminPermissionModel()::query()->insert($permissions);
$permissionClass = Admin::adminPermissionModel();
$pivotTable = (new $permissionClass)->menus()->getTable();
DB::table($pivotTable)->truncate();
foreach ($permissions as $item) {
$query = DB::table($pivotTable);
$query->insert([
'permission_id' => $item['id'],
'menu_id' => $item['id'],
]);
$_id = $item['id'];
while ($item['parent_id'] != 0) {
$query->clone()->insert([
'permission_id' => $_id,
'menu_id' => $item['parent_id'],
]);
$item = Admin::adminMenuModel()::query()->find($item['parent_id']);
}
}
return $this->response()->successMessage(
__('admin.successfully_message', ['attribute' => __('admin.admin_permission.auto_generate')])
);
}
private function getHttpPath($uri)
{
$excepts = ['/', '', '-'];
if (in_array($uri, $excepts)) {
return '';
}
if (! str_starts_with($uri, '/')) {
$uri = '/'.$uri;
}
return $uri.'*';
}
}