generated from liutk/owl-admin-base
基础权限控制
parent
970cef0c32
commit
1200bfb1bf
|
|
@ -14,7 +14,7 @@ class Components extends BaseRenderer
|
|||
public function parentControl($apiUrl = null, $name = 'parent_id', $label = null, $labelField = 'name', $valueField = 'id')
|
||||
{
|
||||
return amisMake()->TreeSelectControl()->source($apiUrl)
|
||||
->name($name)->label($label ?? __('admin.components.parent_select'))
|
||||
->name($name)->label($label ?? __('admin.parent'))
|
||||
->showIcon(false)
|
||||
->labelField($labelField)
|
||||
->valueField($valueField);
|
||||
|
|
@ -135,10 +135,10 @@ class Components extends BaseRenderer
|
|||
if ($color) {
|
||||
$tag = amisMake()->Tag()->label($label ?? __('admin.components.tag'))
|
||||
->displayMode('rounded')->style([
|
||||
'color' => '#fff',
|
||||
'backgroundColor' => $color,
|
||||
'borderColor' => $color,
|
||||
]);
|
||||
'color' => '#fff',
|
||||
'backgroundColor' => $color,
|
||||
'borderColor' => $color,
|
||||
]);
|
||||
} else {
|
||||
$tag = amisMake()->Tag()->label($label ?? __('admin.components.tag'))
|
||||
->displayMode('rounded')->color('inactive');
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminRoleController as AdminRoleBaseController;
|
||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
|
||||
class AdminRoleController extends AdminRoleBaseController
|
||||
{
|
||||
public function list(): Page
|
||||
{
|
||||
$crud = $this->baseCRUD()
|
||||
->headerToolbar([
|
||||
$this->createButton(true),
|
||||
...$this->baseHeaderToolBar(),
|
||||
])
|
||||
->filterTogglable(false)
|
||||
->itemCheckableOn('${id !== 1}')
|
||||
->columns([
|
||||
amis()->TableColumn()->label('ID')->name('id')->sortable(),
|
||||
amis()->TableColumn()->label(__('admin.admin_role.name'))->name('name'),
|
||||
amis()->TableColumn()->label(__('admin.admin_role.slug'))->name('slug')->type('tag'),
|
||||
amis()->TableColumn()
|
||||
->label(__('admin.created_at'))
|
||||
->name('created_at')
|
||||
->type('datetime')
|
||||
->sortable(true),
|
||||
amis()->TableColumn()
|
||||
->label(__('admin.updated_at'))
|
||||
->name('updated_at')
|
||||
->type('datetime')
|
||||
->sortable(true),
|
||||
amis()->Operation()->label(__('admin.actions'))->buttons([
|
||||
$this->setPermission()->visibleOn('${slug != "administrator"}'),
|
||||
$this->rowEditButton(true)->visibleOn('${slug != "administrator"}'),
|
||||
$this->rowDeleteButton()->visibleOn('${slug != "administrator"}'),
|
||||
]),
|
||||
]);
|
||||
|
||||
return $this->baseList($crud)->css([
|
||||
'.tree-full' => [
|
||||
'overflow' => 'hidden !important',
|
||||
],
|
||||
'.cxd-TreeControl > .cxd-Tree' => [
|
||||
'height' => '100% !important',
|
||||
'max-height' => '100% !important',
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\System;
|
||||
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
use Slowlyo\OwlAdmin\Services\AdminMenuService;
|
||||
|
||||
/**
|
||||
* @property AdminMenuService $service
|
||||
*/
|
||||
class AdminMenuController extends AdminController
|
||||
{
|
||||
protected string $serviceName = AdminMenuService::class;
|
||||
|
||||
public function list(): Page
|
||||
{
|
||||
$crud = $this->baseCRUD()
|
||||
->loadDataOnce()
|
||||
->syncLocation(false)
|
||||
->footerToolbar([])
|
||||
->headerToolbar([
|
||||
$this->createButton(true, 'lg')->visible(Admin::user()->can('admin.system.admin_menus.create')),
|
||||
...$this->baseHeaderToolBar(),
|
||||
])
|
||||
->filterTogglable(false)
|
||||
->footerToolbar(['statistics'])
|
||||
->bulkActions([
|
||||
$this->bulkDeleteButton()->reload('window')->visible(Admin::user()->can('admin.system.admin_menus.delete')),
|
||||
])
|
||||
->columns([
|
||||
amis()->TableColumn('id', 'ID')->sortable(),
|
||||
amis()->TableColumn('title', __('admin.admin_menu.title')),
|
||||
amis()->TableColumn('icon', __('admin.admin_menu.icon'))
|
||||
->type('flex')
|
||||
->justify('start')
|
||||
->items([
|
||||
amis()->SvgIcon()->icon('${icon}')->className('mr-2 text-lg'),
|
||||
'${icon}',
|
||||
]),
|
||||
amis()->TableColumn('url', __('admin.admin_menu.url')),
|
||||
amis()->TableColumn('order', __('admin.admin_menu.order'))->quickEdit(
|
||||
amis()->NumberControl()->min(0)->saveImmediately(true)
|
||||
),
|
||||
amis()->TableColumn('visible', __('admin.admin_menu.visible'))->quickEdit(
|
||||
amis()->SwitchControl()->mode('inline')->saveImmediately(true)
|
||||
),
|
||||
amis()->TableColumn('is_home', __('admin.admin_menu.is_home'))->quickEdit(
|
||||
amis()->SwitchControl()->mode('inline')->saveImmediately(true)
|
||||
),
|
||||
$this->rowActions([
|
||||
$this->rowEditButton(true, 'lg')->visible(Admin::user()->can('admin.system.admin_menus.update')),
|
||||
$this->rowDeleteButton()->visible(Admin::user()->can('admin.system.admin_menus.delete')),
|
||||
]),
|
||||
]);
|
||||
|
||||
return $this->baseList($crud);
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return $this->baseForm()->body([
|
||||
amis()->GroupControl()->body([
|
||||
amis()->TextControl('title', __('admin.admin_menu.title'))->required(),
|
||||
amis()->TextControl('icon', __('admin.admin_menu.icon'))
|
||||
->description(
|
||||
__('admin.admin_menu.icon_description').
|
||||
'<a href="https://icones.js.org/collection/all" target="_blank"> https://icones.js.org</a>'
|
||||
),
|
||||
]),
|
||||
amis()->GroupControl()->body([
|
||||
amis()->TreeSelectControl('parent_id', __('admin.admin_menu.parent_id'))
|
||||
->labelField('title')
|
||||
->valueField('id')
|
||||
->showIcon(false)
|
||||
->value(0)
|
||||
->source('/system/admin_menus?_action=getData'),
|
||||
amis()
|
||||
->TextControl('component', __('admin.admin_menu.component'))
|
||||
->description(__('admin.admin_menu.component_desc'))
|
||||
->value('amis'),
|
||||
]),
|
||||
amis()->TextControl('url', __('admin.admin_menu.url'))
|
||||
->required()
|
||||
->validateOnChange()
|
||||
->validations(['matchRegexp' => '/^(http(s)?\:\/)?(\/)+/'])
|
||||
->validationErrors(['matchRegexp' => __('admin.need_start_with_slash')])
|
||||
->placeholder('eg: /admin_menus'),
|
||||
amis()->NumberControl('order', __('admin.admin_menu.order'))
|
||||
->required()
|
||||
->displayMode('enhance')
|
||||
->description(__('admin.order_asc'))
|
||||
->min(0)
|
||||
->value(0),
|
||||
amis()->ListControl('url_type', __('admin.admin_menu.type'))
|
||||
->options(Admin::adminMenuModel()::getType())
|
||||
->value(Admin::adminMenuModel()::TYPE_ROUTE),
|
||||
amis()->SwitchControl('visible', __('admin.admin_menu.visible'))
|
||||
->onText(__('admin.admin_menu.show'))
|
||||
->offText(__('admin.admin_menu.hide'))
|
||||
->value(1),
|
||||
amis()->SwitchControl('is_home', __('admin.admin_menu.is_home'))
|
||||
->onText(__('admin.yes'))
|
||||
->offText(__('admin.no'))
|
||||
->description(__('admin.admin_menu.is_home_description'))
|
||||
->value(0),
|
||||
amis()->SwitchControl('is_full', __('admin.admin_menu.is_full'))
|
||||
->onText(__('admin.yes'))
|
||||
->offText(__('admin.no'))
|
||||
->description(__('admin.admin_menu.is_full_description'))
|
||||
->value(0),
|
||||
])->onEvent([
|
||||
'submitSucc' => [
|
||||
'actions' => [
|
||||
'actionType' => 'custom',
|
||||
'script' => 'window.location.reload()',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function detail(): Form
|
||||
{
|
||||
return $this->baseDetail()->body([]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\System;
|
||||
|
||||
use App\Admin\Services\AdminMenuService;
|
||||
use App\Admin\Services\AdminPermissionService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
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->createButton(true, 'lg')->visible(Admin::user()->can('admin.system.admin_permissions.create')),
|
||||
'bulkActions',
|
||||
amis('reload')->align('right'),
|
||||
amis('filter-toggler')->align('right'),
|
||||
])
|
||||
->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->rowEditButton(true, '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.'*';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\System;
|
||||
|
||||
use App\Admin\Services\AdminRoleService;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
use Slowlyo\OwlAdmin\Services\AdminMenuService;
|
||||
use Slowlyo\OwlAdmin\Services\AdminPermissionService;
|
||||
|
||||
/**
|
||||
* @property AdminRoleService $service
|
||||
*/
|
||||
class AdminRoleController extends AdminController
|
||||
{
|
||||
protected string $serviceName = AdminRoleService::class;
|
||||
|
||||
public function list(): Page
|
||||
{
|
||||
$crud = $this->baseCRUD()
|
||||
->headerToolbar([
|
||||
$this->createButton(true)
|
||||
->visible(Admin::user()->can('admin.system.admin_roles.create')),
|
||||
amis('reload')->align('right'),
|
||||
amis('filter-toggler')->align('right'),
|
||||
])
|
||||
->filterTogglable(false)
|
||||
->itemCheckableOn('${id !== 1}')
|
||||
->columns([
|
||||
amis()->TableColumn()->label('ID')->name('id')->sortable(),
|
||||
amis()->TableColumn()->label(__('admin.admin_role.name'))->name('name'),
|
||||
amis()->TableColumn()->label(__('admin.admin_role.slug'))->name('slug')->type('tag'),
|
||||
amis()->TableColumn()
|
||||
->label(__('admin.created_at'))
|
||||
->name('created_at')
|
||||
->type('datetime')
|
||||
->sortable(true),
|
||||
amis()->TableColumn()
|
||||
->label(__('admin.updated_at'))
|
||||
->name('updated_at')
|
||||
->type('datetime')
|
||||
->sortable(true),
|
||||
amis()->Operation()->label(__('admin.actions'))->buttons([
|
||||
$this->setMenu()
|
||||
->visible(Admin::user()->can('admin.system.admin_roles.set_menus'))
|
||||
->visibleOn('${slug != "administrator"}'),
|
||||
$this->setPermission()
|
||||
->visible(Admin::user()->can('admin.system.admin_roles.set_permissions'))
|
||||
->visibleOn('${slug != "administrator"}'),
|
||||
$this->rowEditButton(true)
|
||||
->visible(Admin::user()->can('admin.system.admin_roles.update'))
|
||||
->visibleOn('${slug != "administrator"}'),
|
||||
$this->rowDeleteButton()
|
||||
->visible(Admin::user()->can('admin.system.admin_roles.delete'))
|
||||
->visibleOn('${slug != "administrator"}'),
|
||||
]),
|
||||
]);
|
||||
|
||||
return $this->baseList($crud)->css([
|
||||
'.tree-full' => [
|
||||
'overflow' => 'hidden !important',
|
||||
],
|
||||
'.cxd-TreeControl > .cxd-Tree' => [
|
||||
'height' => '100% !important',
|
||||
'max-height' => '100% !important',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function setPermission()
|
||||
{
|
||||
return amis()->DrawerAction()->label(__('admin.admin_role.set_permissions'))->icon('fa-solid fa-gear')->level('link')->drawer(
|
||||
amis()->Drawer()->title(__('admin.admin_role.set_permissions'))->resizable()->closeOnOutside()->closeOnEsc()->body([
|
||||
amis()
|
||||
->Form()
|
||||
->api(admin_url('system/admin_roles/${id}/permissions'))
|
||||
->mode('normal')
|
||||
->data(['id' => '${id}'])
|
||||
->body([
|
||||
amis()->TreeControl()
|
||||
->name('permissions')
|
||||
->label()
|
||||
->multiple()
|
||||
->options(AdminPermissionService::make()->getTree())
|
||||
->searchable()
|
||||
->cascade()
|
||||
->value('${permission_ids}')
|
||||
|
||||
->joinValues(false)
|
||||
->extractValue()
|
||||
->size('full')
|
||||
->className('h-full b-none')
|
||||
->inputClassName('h-full tree-full')
|
||||
->labelField('name')
|
||||
->valueField('id'),
|
||||
]),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function savePermissions()
|
||||
{
|
||||
$this->service->savePermissions(request('id'), request('permissions'));
|
||||
|
||||
return $this->autoResponse('success', __('admin.save'));
|
||||
}
|
||||
|
||||
protected function setMenu()
|
||||
{
|
||||
return amis()->DrawerAction()->label(__('admin.admin_role.set_menus'))->icon('fa-solid fa-gear')->level('link')->drawer(
|
||||
amis()->Drawer()->title(__('admin.admin_role.set_menus'))->resizable()->closeOnOutside()->closeOnEsc()->body([
|
||||
amis()
|
||||
->Form()
|
||||
->api(admin_url(admin_url('system/admin_roles/${id}/menus')))
|
||||
->mode('normal')
|
||||
->data(['id' => '${id}'])
|
||||
->body([
|
||||
amis()->TreeControl()
|
||||
->name('menus')
|
||||
->label()
|
||||
->multiple()
|
||||
->options(AdminMenuService::make()->getTree())
|
||||
->searchable()
|
||||
->cascade()
|
||||
->value('${menu_ids}')
|
||||
|
||||
->joinValues(false)
|
||||
->extractValue()
|
||||
->size('full')
|
||||
->className('h-full b-none')
|
||||
->inputClassName('h-full tree-full')
|
||||
->labelField('title')
|
||||
->valueField('id'),
|
||||
]),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function saveMenus()
|
||||
{
|
||||
$this->service->saveMenus(request('id'), request('menus'));
|
||||
|
||||
return $this->autoResponse('success', __('admin.save'));
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return $this->baseForm()->body([
|
||||
amis()->TextControl()->label(__('admin.admin_role.name'))->name('name')->required(),
|
||||
amis()->TextControl()
|
||||
->label(__('admin.admin_role.slug'))
|
||||
->name('slug')
|
||||
->description(__('admin.admin_role.slug_description'))
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function detail(): Form
|
||||
{
|
||||
return $this->baseDetail()->body([]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
namespace App\Admin\Controllers\System;
|
||||
|
||||
use App\Admin\Services\AdminUserService;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||
use Slowlyo\OwlAdmin\Renderers\Operation;
|
||||
|
|
@ -21,7 +22,7 @@ class AdminUserController extends AdminController
|
|||
{
|
||||
$crud = $this->baseCRUD()
|
||||
->headerToolbar([
|
||||
$this->createButton(true),
|
||||
$this->createButton(true)->visible(Admin::user()->can('admin.system.admin_users.create')),
|
||||
...$this->baseHeaderToolBar(),
|
||||
])
|
||||
->filter($this->baseFilter()->body(
|
||||
|
|
@ -29,7 +30,6 @@ class AdminUserController extends AdminController
|
|||
->size('md')
|
||||
->placeholder(__('admin.admin_user.search_username'))
|
||||
))
|
||||
->quickSaveItemApi(admin_url('quick-edit/admin_users/$id'))
|
||||
->itemCheckableOn('${id !== 1}')
|
||||
->columns([
|
||||
amisMake()->TableColumn('id', 'ID')->sortable(),
|
||||
|
|
@ -42,10 +42,15 @@ class AdminUserController extends AdminController
|
|||
amisMake()->TableColumn('lock', __('admin.admin_user.lock'))->quickEdit(SwitchControl::make()->saveImmediately(true)->mode('inline')->disabledOn('${id === 1}')),
|
||||
amisMake()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
|
||||
Operation::make()->label(__('admin.actions'))->buttons([
|
||||
$this->rowEditButton(true)->visibleOn('${id != 1}'),
|
||||
//单独修改密码
|
||||
$this->editPassword()->visibleOn('${id != 1}'),
|
||||
$this->rowDeleteButton()->visibleOn('${id != 1}'),
|
||||
$this->editPassword()
|
||||
->visible(Admin::user()->can('admin.system.admin_users.change_password'))
|
||||
->visibleOn('${id != 1}'),
|
||||
$this->rowEditButton(true)
|
||||
->visible(Admin::user()->can('admin.system.admin_users.update'))
|
||||
->visibleOn('${id != 1}'),
|
||||
$this->rowDeleteButton()
|
||||
->visible(Admin::user()->can('admin.system.admin_users.delete'))
|
||||
->visibleOn('${id != 1}'),
|
||||
]),
|
||||
]);
|
||||
|
||||
|
|
@ -1,16 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
namespace App\Admin\Controllers\System;
|
||||
|
||||
use App\Admin\Components;
|
||||
use App\Admin\Services\KeywordService;
|
||||
use Illuminate\Http\Request;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
||||
use Slowlyo\OwlAdmin\Renderers\TextControl;
|
||||
|
||||
/**
|
||||
* @property KeywordService $service
|
||||
*/
|
||||
class KeywordController extends AdminController
|
||||
{
|
||||
protected string $serviceName = KeywordService::class;
|
||||
|
|
@ -23,7 +27,7 @@ class KeywordController extends AdminController
|
|||
->footerToolbar([])
|
||||
//去掉分页-end
|
||||
->headerToolbar([
|
||||
$this->createButton(true),
|
||||
$this->createButton(true)->visible(Admin::user()->can('admin.system.keywords.create')),
|
||||
amis('reload')->align('right'),
|
||||
amis('filter-toggler')->align('right'),
|
||||
])
|
||||
|
|
@ -44,8 +48,8 @@ class KeywordController extends AdminController
|
|||
TableColumn::make()->name('sort')->label('排序'),
|
||||
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
|
||||
amisMake()->Operation()->label(__('admin.actions'))->buttons([
|
||||
$this->rowEditButton(true),
|
||||
$this->rowDeleteButton(),
|
||||
$this->rowEditButton(true)->visible(Admin::user()->can('admin.system.keywords.update')),
|
||||
$this->rowDeleteButton()->visible(Admin::user()->can('admin.system.keywords.delete')),
|
||||
]),
|
||||
]);
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Models\AdminMenu;
|
||||
|
||||
/**
|
||||
* @method AdminMenu getModel()
|
||||
* @method AdminMenu|Builder query()
|
||||
*/
|
||||
class AdminMenuService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->modelName = Admin::adminMenuModel();
|
||||
}
|
||||
|
||||
public function getTree(): array
|
||||
{
|
||||
$list = $this->query()->orderBy('order')->get()->toArray();
|
||||
|
||||
return array2tree($list);
|
||||
}
|
||||
|
||||
public function parentIsChild($id, $parent_id): bool
|
||||
{
|
||||
$parent = $this->query()->find($parent_id);
|
||||
|
||||
do {
|
||||
if ($parent->parent_id == $id) {
|
||||
return true;
|
||||
}
|
||||
// 如果没有parent 则为顶级菜单 退出循环
|
||||
$parent = $parent->parent;
|
||||
} while ($parent);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update($primaryKey, $data): bool
|
||||
{
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$parent_id = Arr::get($data, 'parent_id');
|
||||
if ($parent_id != 0) {
|
||||
amis_abort_if($this->parentIsChild($primaryKey, $parent_id), __('admin.admin_menu.parent_id_not_allow'));
|
||||
}
|
||||
|
||||
$model = $this->query()->whereKey($primaryKey)->first();
|
||||
|
||||
return $this->saveData($data, $columns, $model);
|
||||
}
|
||||
|
||||
public function store($data): bool
|
||||
{
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$model = $this->getModel();
|
||||
|
||||
return $this->saveData($data, $columns, $model);
|
||||
}
|
||||
|
||||
public function changeHomePage($excludeId = 0)
|
||||
{
|
||||
$this->query()->when($excludeId, fn ($query) => $query->where('id', '<>', $excludeId))->update(['is_home' => 0]);
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
return ['items' => $this->getTree()];
|
||||
}
|
||||
|
||||
protected function saveData($data, array $columns, AdminMenu $model): bool
|
||||
{
|
||||
foreach ($data as $k => $v) {
|
||||
if (! in_array($k, $columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$v = $k == 'parent_id' ? intval($v) : $v;
|
||||
|
||||
$model->setAttribute($k, $v);
|
||||
|
||||
if ($k == 'is_home' && $v == 1) {
|
||||
$this->changeHomePage($model->getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return $model->save();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
use Slowlyo\OwlAdmin\Models\AdminPermission;
|
||||
|
||||
/**
|
||||
* @method AdminPermission getModel()
|
||||
* @method AdminPermission|Builder query()
|
||||
*/
|
||||
class AdminPermissionService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->modelName = Admin::adminPermissionModel();
|
||||
}
|
||||
|
||||
public function getTree(): array
|
||||
{
|
||||
$list = $this->query()->orderBy('order')->get()->toArray();
|
||||
|
||||
return array2tree($list);
|
||||
}
|
||||
|
||||
public function parentIsChild($id, $parent_id): bool
|
||||
{
|
||||
$parent = $this->query()->find($parent_id);
|
||||
|
||||
do {
|
||||
if ($parent->parent_id == $id) {
|
||||
return true;
|
||||
}
|
||||
// 如果没有parent 则为顶级 退出循环
|
||||
$parent = $parent->parent;
|
||||
} while ($parent);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEditData($id): Model|\Illuminate\Database\Eloquent\Collection|Builder|array|null
|
||||
{
|
||||
$permission = parent::getEditData($id);
|
||||
|
||||
$permission->load(['menus']);
|
||||
|
||||
return $permission;
|
||||
}
|
||||
|
||||
public function store($data): bool
|
||||
{
|
||||
$this->checkRepeated($data);
|
||||
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$model = $this->getModel();
|
||||
|
||||
return $this->saveData($data, $columns, $model);
|
||||
}
|
||||
|
||||
public function update($primaryKey, $data): bool
|
||||
{
|
||||
$this->checkRepeated($data, $primaryKey);
|
||||
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$parent_id = Arr::get($data, 'parent_id');
|
||||
if ($parent_id != 0) {
|
||||
amis_abort_if($this->parentIsChild($primaryKey, $parent_id), __('admin.admin_permission.parent_id_not_allow'));
|
||||
}
|
||||
|
||||
$model = $this->query()->whereKey($primaryKey)->first();
|
||||
|
||||
return $this->saveData($data, $columns, $model);
|
||||
}
|
||||
|
||||
public function checkRepeated($data, $id = 0)
|
||||
{
|
||||
$query = $this->query()->when($id, fn ($query) => $query->where('id', '<>', $id));
|
||||
|
||||
amis_abort_if($query->clone()->where('name', $data['name'])
|
||||
->exists(), __('admin.admin_permission.name_already_exists'));
|
||||
|
||||
amis_abort_if($query->clone()->where('slug', $data['slug'])
|
||||
->exists(), __('admin.admin_permission.slug_already_exists'));
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
return ['items' => $this->getTree()];
|
||||
}
|
||||
|
||||
protected function saveData($data, array $columns, AdminPermission $model): bool
|
||||
{
|
||||
$menus = Arr::pull($data, 'menus');
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (! in_array($k, $columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$model->setAttribute($k, $v);
|
||||
}
|
||||
|
||||
if ($model->save()) {
|
||||
$model->menus()->sync(Arr::has($menus, '0.id') ? Arr::pluck($menus, 'id') : $menus);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use Slowlyo\OwlAdmin\Admin;
|
||||
|
||||
class AdminRoleService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->modelName = Admin::adminRoleModel();
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
$query = $this->listQuery();
|
||||
|
||||
/** @var \Illuminate\Pagination\LengthAwarePaginator */
|
||||
$list = $query->with(['menus', 'permissions'])->paginate(request()->input('perPage', 20));
|
||||
$list->through(function ($item) {
|
||||
$instance = $item->withoutRelations();
|
||||
$instance->setAttribute('menu_ids', $item->menus->pluck('id'));
|
||||
$instance->setAttribute('permission_ids', $item->permissions->pluck('id'));
|
||||
|
||||
return $instance;
|
||||
});
|
||||
$items = $list->items();
|
||||
$total = $list->total();
|
||||
|
||||
return compact('items', 'total');
|
||||
}
|
||||
|
||||
public function store($data): bool
|
||||
{
|
||||
$this->checkRepeated($data);
|
||||
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$model = $this->getModel();
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (! in_array($k, $columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$model->setAttribute($k, $v);
|
||||
}
|
||||
|
||||
return $model->save();
|
||||
}
|
||||
|
||||
public function update($primaryKey, $data): bool
|
||||
{
|
||||
$this->checkRepeated($data, $primaryKey);
|
||||
|
||||
$columns = $this->getTableColumns();
|
||||
|
||||
$model = $this->query()->whereKey($primaryKey)->first();
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (! in_array($k, $columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$model->setAttribute($k, $v);
|
||||
}
|
||||
|
||||
return $model->save();
|
||||
}
|
||||
|
||||
public function checkRepeated($data, $id = 0)
|
||||
{
|
||||
$query = $this->query()->when($id, fn ($query) => $query->where('id', '<>', $id));
|
||||
|
||||
amis_abort_if($query->clone()
|
||||
->where('name', $data['name'])
|
||||
->exists(), __('admin.admin_role.name_already_exists'));
|
||||
|
||||
amis_abort_if($query->clone()
|
||||
->where('slug', $data['slug'])
|
||||
->exists(), __('admin.admin_role.slug_already_exists'));
|
||||
}
|
||||
|
||||
public function savePermissions($primaryKey, $permissions): void
|
||||
{
|
||||
$model = $this->query()->whereKey($primaryKey)->first();
|
||||
|
||||
$model->permissions()->detach();
|
||||
$model->permissions()->attach($permissions);
|
||||
}
|
||||
|
||||
public function saveMenus($primaryKey, $menus): void
|
||||
{
|
||||
$model = $this->query()->whereKey($primaryKey)->first();
|
||||
|
||||
$model->menus()->detach();
|
||||
$model->menus()->attach($menus);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
<?php
|
||||
|
||||
use App\Admin\Controllers\System\AdminMenuController;
|
||||
use App\Admin\Controllers\System\AdminPermissionController;
|
||||
use App\Admin\Controllers\System\AdminRoleController;
|
||||
use App\Admin\Controllers\System\AdminUserController;
|
||||
use App\Admin\Controllers\System\KeywordController;
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
|
@ -40,11 +45,25 @@ Route::group([
|
|||
| 系统管理
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$router->resource('system/admin_users', App\Admin\Controllers\AdminUserController::class);
|
||||
$router->get('system/admin_roles', [App\Admin\Controllers\AdminRoleController::class, 'index'])->name('admin_roles.index');
|
||||
$router->resource('system/settings', \App\Admin\Controllers\SettingController::class);
|
||||
$router->resource('system/keywords', \App\Admin\Controllers\KeywordController::class);
|
||||
$router->post('quick-edit/admin_users/{admin_user}', [\App\Admin\Controllers\AdminUserController::class, 'update']);
|
||||
$router->group([
|
||||
'prefix' => 'system',
|
||||
'as' => 'system.',
|
||||
], function (Router $router) {
|
||||
// 账号管理
|
||||
$router->resource('admin_users', AdminUserController::class);
|
||||
// 角色管理
|
||||
$router->resource('admin_roles', AdminRoleController::class);
|
||||
$router->post('admin_roles/{admin_role}/menus', [AdminRoleController::class, 'saveMenus'])->name('admin_roles.set_menus');
|
||||
$router->post('admin_roles/{admin_role}/permissions', [AdminRoleController::class, 'savePermissions'])->name('admin_roles.set_permissions');
|
||||
// 权限管理
|
||||
$router->resource('admin_permissions', AdminPermissionController::class);
|
||||
// 菜单管理
|
||||
$router->resource('admin_menus', AdminMenuController::class);
|
||||
// 系统设置
|
||||
$router->resource('settings', \App\Admin\Controllers\SettingController::class);
|
||||
// 数据字典
|
||||
$router->resource('keywords', KeywordController::class);
|
||||
});
|
||||
|
||||
$router->resource('articles', \App\Admin\Controllers\ArticleController::class);
|
||||
|
||||
|
|
@ -62,6 +81,6 @@ Route::group([
|
|||
$router->group([
|
||||
'prefix' => 'api',
|
||||
], function (Router $router) {
|
||||
$router->get('keywords/tree-list', [\App\Admin\Controllers\KeywordController::class, 'getTreeList'])->name('api.keywords.tree-list');
|
||||
$router->get('keywords/tree-list', [KeywordController::class, 'getTreeList'])->name('api.keywords.tree-list');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@ class AdminRole extends Model
|
|||
|
||||
public function menus(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Admin::adminMenuModel()::class, 'admin_role_menus', 'role_id', 'menu_id');
|
||||
return $this->belongsToMany(Admin::adminMenuModel(), 'admin_role_menus', 'role_id', 'menu_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ return [
|
|||
'avatar' => '头像',
|
||||
'name' => '姓名',
|
||||
'roles' => '角色',
|
||||
'lock' => '锁定',
|
||||
'edit_password' => '修改密码',
|
||||
'search_username' => '搜索用户名/名称',
|
||||
'password_confirmation' => '两次输入密码不一致',
|
||||
'old_password_required' => '请输入原密码',
|
||||
|
|
@ -153,6 +155,7 @@ return [
|
|||
'name_already_exists' => '角色名称已存在',
|
||||
'slug_already_exists' => '角色标识已存在',
|
||||
'set_permissions' => '设置权限',
|
||||
'set_menus' => '设置菜单',
|
||||
],
|
||||
|
||||
'admin_permissions' => '权限',
|
||||
|
|
|
|||
Loading…
Reference in New Issue