Compare commits
No commits in common. "panliang" and "main" have entirely different histories.
|
|
@ -7,7 +7,7 @@ use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
use Slowlyo\OwlAdmin\Renderers\Operation;
|
use Slowlyo\OwlAdmin\Renderers\Operation;
|
||||||
use App\Admin\Services\AdService;
|
use App\Services\Admin\AdService;
|
||||||
use App\Admin\Components;
|
use App\Admin\Components;
|
||||||
use App\Models\Keyword;
|
use App\Models\Keyword;
|
||||||
use App\Models\Ad;
|
use App\Models\Ad;
|
||||||
|
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Controllers;
|
|
||||||
|
|
||||||
use App\Traits\CustomActionTrait;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
use Slowlyo\OwlAdmin\Controllers\AdminController as Controller;
|
|
||||||
use Slowlyo\OwlAdmin\Exceptions\AdminException;
|
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property \App\Admin\Services\BaseService $service
|
|
||||||
*/
|
|
||||||
abstract class AdminController extends Controller
|
|
||||||
{
|
|
||||||
use CustomActionTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
DB::beginTransaction();
|
|
||||||
|
|
||||||
if ($this->actionOfQuickEdit()) {
|
|
||||||
$result = $this->service->quickEdit($request->all());
|
|
||||||
} elseif ($this->actionOfQuickEditItem()) {
|
|
||||||
$result = $this->service->quickEditItem($request->all());
|
|
||||||
} else {
|
|
||||||
$result = $this->service->store($request->all());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $result) {
|
|
||||||
admin_abort($this->service->getError() ?: __('admin.save').__('admin.failed'));
|
|
||||||
}
|
|
||||||
|
|
||||||
DB::commit();
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
DB::rollBack();
|
|
||||||
return $this->renderException($th);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response()->successMessage(__('admin.save').__('admin.successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function update(Request $request)
|
|
||||||
{
|
|
||||||
$input = Arr::except($request->all(), $this->service->primaryKey());
|
|
||||||
|
|
||||||
if ($request->filled('_fields')) {
|
|
||||||
$input = Arr::only($input, explode(',', $request->input('_fields')));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
DB::beginTransaction();
|
|
||||||
|
|
||||||
$result = $this->service->update($this->getPrimaryValue($request), $input);
|
|
||||||
|
|
||||||
if (! $result) {
|
|
||||||
admin_abort($this->service->getError() ?: __('admin.save').__('admin.failed'));
|
|
||||||
}
|
|
||||||
|
|
||||||
DB::commit();
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
DB::rollBack();
|
|
||||||
return $this->renderException($th);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response()->successMessage(__('admin.save').__('admin.successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function destroy($ids)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
DB::beginTransaction();
|
|
||||||
|
|
||||||
$result = $this->service->delete($ids);
|
|
||||||
if ($result === false) {
|
|
||||||
admin_abort($this->service->getError());
|
|
||||||
}
|
|
||||||
|
|
||||||
DB::commit();
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
DB::rollBack();
|
|
||||||
return $this->renderException($th);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response()->successMessage(__('admin.delete').__('admin.successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuickEditItemPath(array $fields = ['*'])
|
|
||||||
{
|
|
||||||
$path = $this->getUpdatePath();
|
|
||||||
|
|
||||||
if ($fields != ['*']) {
|
|
||||||
$path .= '?_fields='.implode(',', $fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderException(Throwable $e)
|
|
||||||
{
|
|
||||||
report($e);
|
|
||||||
|
|
||||||
if ($e instanceof AdminException) {
|
|
||||||
return $e->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = $e->getMessage();
|
|
||||||
|
|
||||||
if ($e instanceof ValidationException) {
|
|
||||||
$message = Arr::first($e->errors());
|
|
||||||
if (is_array($message)) {
|
|
||||||
$message = Arr::first($message) ?: '参数错误';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response()->fail($message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AdminRoleController as AdminRoleBaseController;
|
||||||
|
|
||||||
|
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,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Operation;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\SwitchControl;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
||||||
|
use App\Services\Admin\AdminUserService;
|
||||||
|
use Slowlyo\OwlAdmin\Services\AdminRoleService;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property AdminUserService $service
|
||||||
|
*/
|
||||||
|
class AdminUserController extends AdminController
|
||||||
|
{
|
||||||
|
protected string $serviceName = AdminUserService::class;
|
||||||
|
|
||||||
|
public function list(): Page
|
||||||
|
{
|
||||||
|
$crud = $this->baseCRUD()
|
||||||
|
->headerToolbar([
|
||||||
|
$this->createButton(true),
|
||||||
|
...$this->baseHeaderToolBar(),
|
||||||
|
])
|
||||||
|
->filter($this->baseFilter()->body(
|
||||||
|
amisMake()->TextControl('keyword', __('admin.keyword'))
|
||||||
|
->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(),
|
||||||
|
amisMake()->TableColumn('avatar', __('admin.admin_user.avatar'))->type('avatar')->src('${avatar}'),
|
||||||
|
amisMake()->TableColumn('username', __('admin.username')),
|
||||||
|
amisMake()->TableColumn('name', __('admin.admin_user.name')),
|
||||||
|
amisMake()->TableColumn('roles', __('admin.admin_user.roles'))->type('each')->items(
|
||||||
|
amisMake()->Tag()->label('${name}')->className('my-1')
|
||||||
|
),
|
||||||
|
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}'),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->baseList($crud);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form(): Form
|
||||||
|
{
|
||||||
|
return $this->baseForm()->body([
|
||||||
|
amisMake()->ImageControl('avatar', __('admin.admin_user.avatar'))->receiver($this->uploadImagePath()),
|
||||||
|
amisMake()->TextControl('name', __('admin.admin_user.name'))->required(),
|
||||||
|
amisMake()->TextControl('username', __('admin.username'))->required(),
|
||||||
|
amisMake()->TextControl('password', __('admin.password'))->type('input-password')->required()->validations(['minLength' => 6])->hiddenOn('${id > 0}'),
|
||||||
|
amisMake()->TextControl('confirm_password', __('admin.confirm_password'))->type('input-password')->required()->validations(['minLength' => 6])->hiddenOn('${id > 0}'),
|
||||||
|
amisMake()->SelectControl('roles', __('admin.admin_user.roles'))
|
||||||
|
->searchable()
|
||||||
|
->multiple()
|
||||||
|
->labelField('name')
|
||||||
|
->valueField('id')
|
||||||
|
->joinValues(false)
|
||||||
|
->extractValue()
|
||||||
|
->options(AdminRoleService::make()->query()->get(['id', 'name'])),
|
||||||
|
SwitchControl::make()->name('lock')->label(__('admin.admin_user.lock'))->value(false),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function detail(): Form
|
||||||
|
{
|
||||||
|
return $this->baseDetail()->body([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editPassword()
|
||||||
|
{
|
||||||
|
return amisMake()->DialogAction()->icon('fa-regular fa-lightbulb')->label(__('admin.admin_user.edit_password'))->level('link')->dialog(
|
||||||
|
amisMake()->Dialog()->title(__('admin.admin_user.edit_password'))->body([
|
||||||
|
amisMake()->Form()->title('')
|
||||||
|
->api([
|
||||||
|
'method'=>'PUT',
|
||||||
|
'url'=> admin_url('system/admin_users/$id')
|
||||||
|
])
|
||||||
|
->body([
|
||||||
|
amisMake()->TextControl('id')->value('${id}')->hidden(true),
|
||||||
|
amisMake()->TextControl('username')->value('${username}')->hidden(true),
|
||||||
|
amisMake()->TextControl('password', __('admin.password'))->type('input-password')->required()->validations(['minLength' => 6]),
|
||||||
|
amisMake()->TextControl('confirm_password', __('admin.confirm_password'))->type('input-password')->required()->validations(['minLength' => 6]),
|
||||||
|
]),
|
||||||
|
])->size('md')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ use Slowlyo\OwlAdmin\Admin;
|
||||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
use App\Admin\Services\ArticleService;
|
use App\Services\Admin\ArticleService;
|
||||||
use App\Admin\Components;
|
use App\Admin\Components;
|
||||||
use App\Models\Keyword;
|
use App\Models\Keyword;
|
||||||
use App\Traits\CustomActionTrait;
|
use App\Traits\CustomActionTrait;
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,20 @@
|
||||||
|
|
||||||
namespace App\Admin\Controllers;
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
use App\Admin\Services\System\AdminUserService;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
use Slowlyo\OwlAdmin\Admin;
|
||||||
use Slowlyo\OwlAdmin\Controllers\AuthController as AdminAuthController;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Slowlyo\OwlAdmin\Models\AdminUser;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AuthController as AdminAuthController;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class AuthController extends AdminAuthController
|
class AuthController extends AdminAuthController
|
||||||
{
|
{
|
||||||
protected string $serviceName = AdminUserService::class;
|
|
||||||
|
|
||||||
public function login(Request $request)
|
public function login(Request $request)
|
||||||
{
|
{
|
||||||
if (Admin::config('admin.auth.login_captcha')) {
|
if (Admin::config('admin.auth.login_captcha')) {
|
||||||
if (! $request->has('captcha')) {
|
if (!$request->has('captcha')) {
|
||||||
return $this->response()->fail(__('admin.required', ['attribute' => __('admin.captcha')]));
|
return $this->response()->fail(__('admin.required', ['attribute' => __('admin.captcha')]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,25 +29,22 @@ class AuthController extends AdminAuthController
|
||||||
'username' => 'required',
|
'username' => 'required',
|
||||||
'password' => 'required',
|
'password' => 'required',
|
||||||
], [
|
], [
|
||||||
'username'.'.required' => __('admin.required', ['attribute' => __('admin.username')]),
|
'username' . '.required' => __('admin.required', ['attribute' => __('admin.username')]),
|
||||||
'password.required' => __('admin.required', ['attribute' => __('admin.password')]),
|
'password.required' => __('admin.required', ['attribute' => __('admin.password')]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
abort(Response::HTTP_BAD_REQUEST, $validator->errors()->first());
|
abort(Response::HTTP_BAD_REQUEST, $validator->errors()->first());
|
||||||
}
|
}
|
||||||
|
$adminModel = Admin::config("admin.auth.model", AdminUser::class);
|
||||||
$adminModel = Admin::adminUserModel();
|
$user = $adminModel::query()->where('username', $request->username)->first();
|
||||||
$user = $adminModel::query()->where('username', $request->username)->first();
|
if($user && $user->lock){
|
||||||
|
|
||||||
if ($user && $user->lock) {
|
|
||||||
abort(Response::HTTP_BAD_REQUEST, '您的账号已被锁定,需要联系超级管理员解锁。');
|
abort(Response::HTTP_BAD_REQUEST, '您的账号已被锁定,需要联系超级管理员解锁。');
|
||||||
} else {
|
}else{
|
||||||
if ($user && Hash::check($request->password, $user->password)) {
|
if ($user && Hash::check($request->password, $user->password)) {
|
||||||
$module = Admin::currentModule(true);
|
$module = Admin::currentModule(true);
|
||||||
$prefix = $module ? $module.'.' : '';
|
$prefix = $module ? $module . '.' : '';
|
||||||
$token = $user->createToken($prefix.'admin')->plainTextToken;
|
$token = $user->createToken($prefix . 'admin')->plainTextToken;
|
||||||
|
|
||||||
return $this->response()->success(compact('token'), __('admin.login_successful'));
|
return $this->response()->success(compact('token'), __('admin.login_successful'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Admin\Controllers\System;
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
use App\Admin\Components;
|
|
||||||
use App\Admin\Controllers\AdminController;
|
|
||||||
use App\Admin\Services\System\KeywordService;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||||
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
||||||
use Slowlyo\OwlAdmin\Renderers\TextControl;
|
use Slowlyo\OwlAdmin\Renderers\TextControl;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
|
use App\Services\Admin\KeywordService;
|
||||||
|
use App\Admin\Components;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
/**
|
|
||||||
* @property KeywordService $service
|
|
||||||
*/
|
|
||||||
class KeywordController extends AdminController
|
class KeywordController extends AdminController
|
||||||
{
|
{
|
||||||
protected string $serviceName = KeywordService::class;
|
protected string $serviceName = KeywordService::class;
|
||||||
|
|
@ -27,26 +23,32 @@ class KeywordController extends AdminController
|
||||||
->footerToolbar([])
|
->footerToolbar([])
|
||||||
//去掉分页-end
|
//去掉分页-end
|
||||||
->headerToolbar([
|
->headerToolbar([
|
||||||
$this->createTypeButton('drawer', 'lg')->visible(Admin::user()->can('admin.system.keywords.create')),
|
$this->createButton(true),
|
||||||
$this->exportAction(),
|
$this->exportAction(),
|
||||||
...$this->baseHeaderToolBar(),
|
amis('reload')->align('right'),
|
||||||
|
amis('filter-toggler')->align('right'),
|
||||||
])
|
])
|
||||||
->bulkActions([])
|
|
||||||
->filter($this->baseFilter()->body([
|
->filter($this->baseFilter()->body([
|
||||||
amis()->TextControl('search', __('admin.keyword'))->placeholder(__('admin.keywords.search_name'))->size('md'),
|
amis()->TextControl('name', __('admin.keyword'))
|
||||||
]))
|
->size('md')
|
||||||
->filterDefaultVisible()
|
->placeholder(__('admin.keywords.search_name')),
|
||||||
|
amis()->TextControl('parent_name', __('admin.keywords.parent_keyword'))
|
||||||
|
->size('md')
|
||||||
|
->placeholder(__('admin.keywords.search_name'))
|
||||||
|
]
|
||||||
|
))
|
||||||
->columns([
|
->columns([
|
||||||
// TableColumn::make()->name('id')->label('ID')->sortable(true),
|
// TableColumn::make()->name('id')->label('ID')->sortable(true),
|
||||||
TableColumn::make()->name('name')->label('名称'),
|
TableColumn::make()->name('name')->label('名称'),
|
||||||
TableColumn::make()->name('key')->label('KEY')->copyable(true),
|
TableColumn::make()->name('key')->label('KEY')->copyable(true),
|
||||||
TableColumn::make()->name('value')->label('值'),
|
TableColumn::make()->name('value')->label('值'),
|
||||||
TableColumn::make()->name('sort')->label('排序'),
|
TableColumn::make()->name('sort')->label('排序'),
|
||||||
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
|
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
|
||||||
amis()->Operation()->label(__('admin.actions'))->buttons([
|
amisMake()->Operation()->label(__('admin.actions'))->buttons([
|
||||||
$this->rowEditTypeButton('drawer', 'lg')
|
//按钮权限示例;
|
||||||
->visible(Admin::user()->can('admin.system.keywords.update')),
|
// amis()->action()->label('判断权限')->permission('keywords.custom', amis()->TextControl()->hidden()),
|
||||||
$this->rowDeleteButton()->visible(Admin::user()->can('admin.system.keywords.delete')),
|
$this->rowEditButton(true),
|
||||||
|
$this->rowDeleteButton(),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -60,12 +62,11 @@ class KeywordController extends AdminController
|
||||||
TextControl::make()->name('name')->label('名称')->required(true),
|
TextControl::make()->name('name')->label('名称')->required(true),
|
||||||
TextControl::make()->name('key')->label('KEY')->required(true),
|
TextControl::make()->name('key')->label('KEY')->required(true),
|
||||||
TextControl::make()->name('value')->label('值'),
|
TextControl::make()->name('value')->label('值'),
|
||||||
amis()->NumberControl()->name('sort')->value(0)->min()->label('排序'),
|
amisMake()->NumberControl()->name('sort')->value(0)->min()->label('排序'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTreeList(Request $request)
|
public function getTreeList(Request $request){
|
||||||
{
|
return $this->service->getTree();
|
||||||
return $this->service->getTree();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Controllers\System;
|
|
||||||
|
|
||||||
use App\Admin\Controllers\AdminController;
|
|
||||||
use App\Admin\Services\System\AdminMenuService;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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->createTypeButton('drawer', '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->rowEditTypeButton('drawer', '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([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,223 +0,0 @@
|
||||||
<?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.'*';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,169 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Controllers\System;
|
|
||||||
|
|
||||||
use App\Admin\Controllers\AdminController;
|
|
||||||
use App\Admin\Services\System\AdminRoleService;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\DrawerAction;
|
|
||||||
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->createTypeButton('drawer', 'lg')
|
|
||||||
->visible(Admin::user()->can('admin.system.admin_roles.create')),
|
|
||||||
...$this->baseHeaderToolBar(),
|
|
||||||
])
|
|
||||||
->bulkActions([])
|
|
||||||
->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->rowSetMenuButton()
|
|
||||||
->visible(Admin::user()->can('admin.system.admin_roles.set_menus'))
|
|
||||||
->visibleOn('${slug != "administrator"}'),
|
|
||||||
$this->rowSetPermissionButton()
|
|
||||||
->visible(Admin::user()->can('admin.system.admin_roles.set_permissions'))
|
|
||||||
->visibleOn('${slug != "administrator"}'),
|
|
||||||
$this->rowEditTypeButton('drawer', 'lg')
|
|
||||||
->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 rowSetPermissionButton(): DrawerAction
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
->heightAuto()
|
|
||||||
->showIcon(false)
|
|
||||||
->initiallyOpen(false)
|
|
||||||
// ->size('full')
|
|
||||||
// ->className('h-full b-none')
|
|
||||||
// ->inputClassName('h-full tree-full')
|
|
||||||
->labelField('name')
|
|
||||||
->valueField('id'),
|
|
||||||
),
|
|
||||||
])->size('lg')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function savePermissions()
|
|
||||||
{
|
|
||||||
$this->service->savePermissions(request('id'), request('permissions'));
|
|
||||||
|
|
||||||
return $this->autoResponse('success', __('admin.save'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function rowSetMenuButton(): DrawerAction
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
->heightAuto()
|
|
||||||
->showIcon(false)
|
|
||||||
->initiallyOpen(false)
|
|
||||||
// ->size('full')
|
|
||||||
// ->className('h-full b-none')
|
|
||||||
// ->inputClassName('h-full tree-full')
|
|
||||||
->labelField('title')
|
|
||||||
->valueField('id')
|
|
||||||
),
|
|
||||||
])->size('lg')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,144 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Controllers\System;
|
|
||||||
|
|
||||||
use App\Admin\Controllers\AdminController;
|
|
||||||
use App\Admin\Services\System\AdminUserService;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\DrawerAction;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
|
||||||
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
|
||||||
use Slowlyo\OwlAdmin\Services\AdminRoleService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property AdminUserService $service
|
|
||||||
*/
|
|
||||||
class AdminUserController extends AdminController
|
|
||||||
{
|
|
||||||
protected string $serviceName = AdminUserService::class;
|
|
||||||
|
|
||||||
public function list(): Page
|
|
||||||
{
|
|
||||||
$crud = $this->baseCRUD()
|
|
||||||
->headerToolbar([
|
|
||||||
$this->createTypeButton('drawer', 'lg')->visible(Admin::user()->can('admin.system.admin_users.create')),
|
|
||||||
...$this->baseHeaderToolBar(),
|
|
||||||
])
|
|
||||||
->bulkActions([])
|
|
||||||
->filter($this->baseFilter()->body(
|
|
||||||
amis()->TextControl('keyword', __('admin.keyword'))
|
|
||||||
->size('md')
|
|
||||||
->placeholder(__('admin.admin_user.search_username'))
|
|
||||||
))
|
|
||||||
->filterDefaultVisible()
|
|
||||||
->quickSaveItemApi($this->getQuickEditItemPath(['lock']))
|
|
||||||
->itemCheckableOn('${id !== 1}')
|
|
||||||
->columns([
|
|
||||||
amis()->TableColumn('id', 'ID')->sortable(),
|
|
||||||
amis()->TableColumn('avatar', __('admin.admin_user.avatar'))->type('avatar')->src('${avatar}'),
|
|
||||||
amis()->TableColumn('username', __('admin.username')),
|
|
||||||
amis()->TableColumn('name', __('admin.admin_user.name')),
|
|
||||||
amis()->TableColumn('roles', __('admin.admin_user.roles'))->type('each')->items(
|
|
||||||
amis()->Tag()->label('${name}')->className('my-1')
|
|
||||||
),
|
|
||||||
tap(amis()->TableColumn('lock', __('admin.admin_user.lock')), function (TableColumn $column) {
|
|
||||||
if (Admin::user()->can('admin.system.admin_users.update')) {
|
|
||||||
return $column->quickEdit(
|
|
||||||
amis()->SwitchControl()->saveImmediately()->mode('inline')->disabledOn('${id === 1}')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $column->type('status')->source([
|
|
||||||
0 => ['label' => '未锁定', 'icon' => 'fa fa-times-circle', 'color' => '#30bf13'],
|
|
||||||
1 => ['label' => '已锁定', 'icon' => 'fa fa-check-circle', 'color' => '#f70e47'],
|
|
||||||
]);
|
|
||||||
}),
|
|
||||||
amis()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
|
|
||||||
$this->rowActions([
|
|
||||||
$this->rowChangePasswordButton()
|
|
||||||
->visible(Admin::user()->can('admin.system.admin_users.change_password'))
|
|
||||||
->visibleOn('${id != 1}'),
|
|
||||||
$this->rowEditTypeButton('drawer', 'lg')
|
|
||||||
->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}'),
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $this->baseList($crud);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function form(): Form
|
|
||||||
{
|
|
||||||
return $this->baseForm()->body([
|
|
||||||
amis()->ImageControl('avatar', __('admin.admin_user.avatar'))->receiver(admin_url('upload_image') . '?full-url=1'),
|
|
||||||
amis()->TextControl('name', __('admin.admin_user.name'))->required(),
|
|
||||||
amis()->TextControl('username', __('admin.username'))->required(),
|
|
||||||
amis()->TextControl('password', __('admin.password'))->type('input-password')->required()->validations(['minLength' => 6])->hiddenOn('${id > 0}'),
|
|
||||||
amis()->TextControl('confirm_password', __('admin.confirm_password'))->type('input-password')->required()->validations(['minLength' => 6])->hiddenOn('${id > 0}'),
|
|
||||||
amis()->SelectControl('roles', __('admin.admin_user.roles'))
|
|
||||||
->searchable()
|
|
||||||
->multiple()
|
|
||||||
->labelField('name')
|
|
||||||
->valueField('id')
|
|
||||||
->joinValues(false)
|
|
||||||
->extractValue()
|
|
||||||
->options(AdminRoleService::make()->query()->get(['id', 'name'])),
|
|
||||||
amis()->SwitchControl()->name('lock')->label(__('admin.admin_user.lock'))->value(false),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function detail(): Form
|
|
||||||
{
|
|
||||||
return $this->baseDetail()->body([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改密码
|
|
||||||
*/
|
|
||||||
public function changePassword($id, Request $request)
|
|
||||||
{
|
|
||||||
$validator = Validator::make(
|
|
||||||
data: $request->input(),
|
|
||||||
rules: [
|
|
||||||
'password' => ['bail', 'required', 'confirmed', 'min:6'],
|
|
||||||
],
|
|
||||||
attributes: [
|
|
||||||
'password' => '密码',
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
admin_abort($validator->errors()->first());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->service->update($id, $request->only(['password']));
|
|
||||||
|
|
||||||
return $this->autoResponse('success', __('admin.save'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改密码按钮
|
|
||||||
*/
|
|
||||||
protected function rowChangePasswordButton(): DrawerAction
|
|
||||||
{
|
|
||||||
return amis()->DrawerAction()->icon('fa-regular fa-lightbulb')->label(__('admin.admin_user.edit_password'))->level('link')->drawer(
|
|
||||||
amis()->Drawer()->title(__('admin.admin_user.edit_password'))->body([
|
|
||||||
amis()->Form()->title('')
|
|
||||||
->api([
|
|
||||||
'method' => 'POST',
|
|
||||||
'url' => admin_url('system/admin_users/$id/change-password'),
|
|
||||||
])
|
|
||||||
->body([
|
|
||||||
amis()->TextControl('password', __('admin.password'))->type('input-password')->required()->validations(['minLength' => 6]),
|
|
||||||
amis()->TextControl('password_confirmation', __('admin.confirm_password'))->type('input-password')->required()->validations(['minLength' => 6]),
|
|
||||||
]),
|
|
||||||
])->size('lg')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,195 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin;
|
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
|
|
||||||
class Menu
|
|
||||||
{
|
|
||||||
protected array $menus = [];
|
|
||||||
|
|
||||||
public function all()
|
|
||||||
{
|
|
||||||
$menus = $this->userMenus()
|
|
||||||
->push(...array_map(fn ($item) => $this->formatItem($item), $this->menus))
|
|
||||||
->sortBy('order')
|
|
||||||
->values()
|
|
||||||
->toArray();
|
|
||||||
|
|
||||||
return array_merge($this->list2Menu($menus), $this->extra());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function userMenus()
|
|
||||||
{
|
|
||||||
/** @var \App\Models\AdminUser */
|
|
||||||
$user = Admin::user();
|
|
||||||
|
|
||||||
return $user->allMenus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function list2Menu($list, $parentId = 0, $parentName = ''): array
|
|
||||||
{
|
|
||||||
$data = [];
|
|
||||||
foreach ($list as $key => $item) {
|
|
||||||
if ($item['parent_id'] == $parentId) {
|
|
||||||
$idStr = "[{$item['id']}]";
|
|
||||||
$_temp = [
|
|
||||||
'name' => $parentName ? $parentName.'-'.$idStr : $idStr,
|
|
||||||
'path' => $item['url'],
|
|
||||||
'component' => data_get($item, 'component') ?? 'amis',
|
|
||||||
'is_home' => $item['is_home'],
|
|
||||||
'is_full' => $item['is_full'] ?? 0,
|
|
||||||
'is_link' => $item['url_type'] == Admin::adminMenuModel()::TYPE_LINK,
|
|
||||||
'meta' => [
|
|
||||||
'title' => $item['title'],
|
|
||||||
'icon' => $item['icon'] ?? '-',
|
|
||||||
'hide' => $item['visible'] == 0,
|
|
||||||
'order' => $item['order'],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$children = $this->list2Menu($list, (int) $item['id'], $_temp['name']);
|
|
||||||
|
|
||||||
if (! empty($children)) {
|
|
||||||
$_temp['component'] = 'amis';
|
|
||||||
$_temp['children'] = $children;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data[] = $_temp;
|
|
||||||
if (! in_array($_temp['path'], Admin::config('admin.route.without_extra_routes'))) {
|
|
||||||
array_push($data, ...$this->generateRoute($_temp));
|
|
||||||
}
|
|
||||||
unset($list[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function generateRoute($item): array
|
|
||||||
{
|
|
||||||
$url = $item['path'] ?? '';
|
|
||||||
$url = preg_replace('/\?.*/', '', $url);
|
|
||||||
|
|
||||||
if (! $url || array_key_exists('children', $item)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$menu = fn ($action, $path) => [
|
|
||||||
'name' => $item['name'].'-'.$action,
|
|
||||||
'path' => $url.$path,
|
|
||||||
'component' => 'amis',
|
|
||||||
'meta' => [
|
|
||||||
'hide' => true,
|
|
||||||
'icon' => Arr::get($item, 'meta.icon'),
|
|
||||||
'title' => Arr::get($item, 'meta.title').' - '.__('admin.'.$action),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
return [
|
|
||||||
$menu('create', '/create'),
|
|
||||||
$menu('show', '/:id'),
|
|
||||||
$menu('edit', '/:id/edit'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add($menus)
|
|
||||||
{
|
|
||||||
$this->menus = array_merge($this->menus, $menus);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function formatItem($item)
|
|
||||||
{
|
|
||||||
return array_merge([
|
|
||||||
'title' => '',
|
|
||||||
'url' => '',
|
|
||||||
'url_type' => 1,
|
|
||||||
'icon' => '',
|
|
||||||
'parent_id' => 0,
|
|
||||||
'id' => 999,
|
|
||||||
'is_home' => 0,
|
|
||||||
'visible' => 1,
|
|
||||||
'order' => 99,
|
|
||||||
], $item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 额外菜单
|
|
||||||
*
|
|
||||||
* @return array|array[]
|
|
||||||
*/
|
|
||||||
private function extra()
|
|
||||||
{
|
|
||||||
$extraMenus = [
|
|
||||||
[
|
|
||||||
'name' => 'user_setting',
|
|
||||||
'path' => '/user_setting',
|
|
||||||
'component' => 'amis',
|
|
||||||
'meta' => [
|
|
||||||
'hide' => true,
|
|
||||||
'title' => __('admin.user_setting'),
|
|
||||||
'icon' => 'material-symbols:manage-accounts',
|
|
||||||
'singleLayout' => 'basic',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (Admin::config('admin.show_development_tools')) {
|
|
||||||
$extraMenus = array_merge($extraMenus, $this->devToolMenus());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $extraMenus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开发者工具菜单
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
private function devToolMenus()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
'name' => 'dev_tools',
|
|
||||||
'path' => '/dev_tools',
|
|
||||||
'component' => 'amis',
|
|
||||||
'meta' => [
|
|
||||||
'title' => __('admin.developer'),
|
|
||||||
'icon' => 'fluent:window-dev-tools-20-regular',
|
|
||||||
],
|
|
||||||
'children' => [
|
|
||||||
[
|
|
||||||
'name' => 'dev_tools_extensions',
|
|
||||||
'path' => '/dev_tools/extensions',
|
|
||||||
'component' => 'amis',
|
|
||||||
'meta' => [
|
|
||||||
'title' => __('admin.extensions.menu'),
|
|
||||||
'icon' => 'ion:extension-puzzle-outline',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'name' => 'dev_tools_code_generator',
|
|
||||||
'path' => '/dev_tools/code_generator',
|
|
||||||
'component' => 'amis',
|
|
||||||
'meta' => [
|
|
||||||
'title' => __('admin.code_generator'),
|
|
||||||
'icon' => 'ic:baseline-code',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'name' => 'dev_tools_editor',
|
|
||||||
'path' => '/dev_tools/editor',
|
|
||||||
'component' => 'editor',
|
|
||||||
'meta' => [
|
|
||||||
'title' => __('admin.visual_editor'),
|
|
||||||
'icon' => 'mdi:monitor-edit',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Middleware;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
|
|
||||||
class Authenticate
|
|
||||||
{
|
|
||||||
public function handle($request, Closure $next)
|
|
||||||
{
|
|
||||||
if (Admin::permission()->authIntercept($request)) {
|
|
||||||
return Admin::response()
|
|
||||||
->additional(['code' => Response::HTTP_UNAUTHORIZED])
|
|
||||||
->doNotDisplayToast()
|
|
||||||
->fail(__('admin.please_login'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Middleware;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Support\Cores\Permission;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class CheckPermission
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $exceptPaths = [
|
|
||||||
'/api/*',
|
|
||||||
'/start_chunk_upload_file',
|
|
||||||
'/save_chunk_upload_file',
|
|
||||||
'/finish_chunk_upload_file',
|
|
||||||
'/upload_file',
|
|
||||||
'/upload_image',
|
|
||||||
'/upload_rich'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $exceptRoutes = [
|
|
||||||
//
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle an incoming request.
|
|
||||||
*
|
|
||||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
|
||||||
*/
|
|
||||||
public function handle(Request $request, Closure $next): Response
|
|
||||||
{
|
|
||||||
if ($this->inExceptArray($request) || $this->checkRoutePermission($request)) {
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Admin::response()->fail(__('admin.unauthorized'), ['route' => $request->route()->getName()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function checkRoutePermission(Request $request): bool
|
|
||||||
{
|
|
||||||
if (is_null($user = Admin::user())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ability = $this->normalizeRouteAbility(
|
|
||||||
$original = $request->route()->getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
return collect($ability)
|
|
||||||
->when($ability !== $original, fn (Collection $collection) => $collection->push($original))
|
|
||||||
->contains(fn ($ability) => $user->can($ability));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function normalizeRouteAbility(string $ability)
|
|
||||||
{
|
|
||||||
foreach ($this->resourceAbilityMap() as $method => $map) {
|
|
||||||
if (str_ends_with($ability, ".{$method}")) {
|
|
||||||
return preg_replace("/(.*)\.{$method}$/", '${1}.'.$map, $ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ability;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function resourceAbilityMap(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'index' => 'list',
|
|
||||||
'show' => 'view',
|
|
||||||
'store' => 'create',
|
|
||||||
'edit' => 'update',
|
|
||||||
'destroy' => 'delete',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function inExceptArray(Request $request): bool
|
|
||||||
{
|
|
||||||
if (in_array($request->route()->getName(), $this->exceptRoutes)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$permission = Admin::permission();
|
|
||||||
|
|
||||||
return $request->is(
|
|
||||||
collect($this->exceptPaths)
|
|
||||||
->when(Admin::permission(), fn (Collection $collection, Permission $permission) => $collection->merge($permission->authExcept)->merge($permission->permissionExcept))
|
|
||||||
->map(function ($path) {
|
|
||||||
$path = trim((string) config('admin.route.prefix'), '/').'/'.trim((string) $path, '/');
|
|
||||||
|
|
||||||
return ltrim($path, '/');
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Services;
|
|
||||||
|
|
||||||
use Slowlyo\OwlAdmin\Services\AdminService;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @method Region getModel()
|
|
||||||
* @method Region|\Illuminate\Database\Query\Builder query()
|
|
||||||
*/
|
|
||||||
class BaseService extends AdminService
|
|
||||||
{
|
|
||||||
protected string $modelFilterName = '';
|
|
||||||
|
|
||||||
protected bool $modelSortAble = false;
|
|
||||||
|
|
||||||
protected Model $currentModel;
|
|
||||||
|
|
||||||
public function getCurrentModel()
|
|
||||||
{
|
|
||||||
return $this->currentModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sortColumn()
|
|
||||||
{
|
|
||||||
return 'id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTree()
|
|
||||||
{
|
|
||||||
$list = $this->query()->orderByDesc('sort')->get();
|
|
||||||
$minNum = $list->min('parent_id');
|
|
||||||
|
|
||||||
return array2tree($list->toArray(), $minNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function list()
|
|
||||||
{
|
|
||||||
$query = $this->listQuery();
|
|
||||||
if (request()->input('_all')) {
|
|
||||||
$list = (clone $query)->get();
|
|
||||||
$items = $list->all();
|
|
||||||
$total = $list->count();
|
|
||||||
} else {
|
|
||||||
$list = (clone $query)->paginate(request()->input('perPage', 20));
|
|
||||||
$items = $list->items();
|
|
||||||
$total = $list->total();
|
|
||||||
}
|
|
||||||
|
|
||||||
return compact('items', 'total');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getModelFilter()
|
|
||||||
{
|
|
||||||
return $this->modelFilterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function listQuery()
|
|
||||||
{
|
|
||||||
$query = $this->query();
|
|
||||||
|
|
||||||
$this->addRelations($query);
|
|
||||||
|
|
||||||
if ($filter = $this->getModelFilter()) {
|
|
||||||
$query->filter(request()->input(), $filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->modelSortAble) {
|
|
||||||
$query->sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sortable($query);
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store($data): bool
|
|
||||||
{
|
|
||||||
$data = $this->resloveData($data);
|
|
||||||
|
|
||||||
$validate = $this->validate($data);
|
|
||||||
if ($validate !== true) {
|
|
||||||
$this->setError($validate);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$model = $this->modelName::create($data);
|
|
||||||
$this->currentModel = $model;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($primaryKey, $data): bool
|
|
||||||
{
|
|
||||||
$model = $this->query()->whereKey($primaryKey)->firstOrFail();
|
|
||||||
$data = $this->resloveData($data, $model);
|
|
||||||
$validate = $this->validate($data, $model);
|
|
||||||
if ($validate !== true) {
|
|
||||||
$this->setError($validate);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$model->update($data);
|
|
||||||
$this->currentModel = $model;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete(string $ids): mixed
|
|
||||||
{
|
|
||||||
$this->preDelete(explode(',', $ids));
|
|
||||||
|
|
||||||
return parent::delete($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理表单数据
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @param Model $model 空 : 添加, 非空: 修改
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function resloveData($data, $model = null)
|
|
||||||
{
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单验证
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @param Model $model 空: 添加, 非空: 修改
|
|
||||||
* @return mixed true: 验证通过, string: 错误提示
|
|
||||||
*/
|
|
||||||
public function validate($data, $model = null)
|
|
||||||
{
|
|
||||||
// $createRules = [
|
|
||||||
// 'key' => ['required', Rule::unique('keywords', 'key')],
|
|
||||||
// 'name' => ['required'],
|
|
||||||
// ];
|
|
||||||
// $updateRules = [
|
|
||||||
// 'key' => [Rule::unique('keywords', 'key')->ignore($model->id)]
|
|
||||||
// ];
|
|
||||||
// $validator = Validator::make($data, $model ? $updateRules : $createRules, [
|
|
||||||
// 'key.unique' => ':input 已经存在'
|
|
||||||
// ]);
|
|
||||||
// if ($validator->fails()) {
|
|
||||||
// return $validator->errors()->first();
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除的前置方法
|
|
||||||
*
|
|
||||||
* @param array $ids 主键id
|
|
||||||
*/
|
|
||||||
public function preDelete(array $ids): void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Services\System;
|
|
||||||
|
|
||||||
use App\Admin\Services\BaseService;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Services\System;
|
|
||||||
|
|
||||||
use App\Admin\Services\BaseService;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Services\System;
|
|
||||||
|
|
||||||
use App\Admin\Services\BaseService;
|
|
||||||
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,161 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Admin\Services\System;
|
|
||||||
|
|
||||||
use App\Admin\Services\BaseService;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
|
|
||||||
class AdminUserService extends BaseService
|
|
||||||
{
|
|
||||||
protected string $modelName;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->modelName = Admin::adminUserModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEditData($id): Model|\Illuminate\Database\Eloquent\Collection|Builder|array|null
|
|
||||||
{
|
|
||||||
$adminUser = parent::getEditData($id)->makeHidden('password');
|
|
||||||
|
|
||||||
$adminUser->load('roles');
|
|
||||||
|
|
||||||
return $adminUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store($data): bool
|
|
||||||
{
|
|
||||||
if ($this->checkUsernameUnique($data['username'])) {
|
|
||||||
admin_abort(__('admin.admin_user.username_already_exists'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! data_get($data, 'password')) {
|
|
||||||
admin_abort(__('admin.required', ['attribute' => __('admin.password')]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('confirm_password', $data)) {
|
|
||||||
if ($data['password'] !== $data['confirm_password']) {
|
|
||||||
admin_abort(__('admin.admin_user.password_confirmation'));
|
|
||||||
}
|
|
||||||
unset($data['confirm_password']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Hash::needsRehash($data['password'])) {
|
|
||||||
$data['password'] = Hash::make($data['password']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model = $this->getModel();
|
|
||||||
$user = $model::create(Arr::except($data, ['roles']));
|
|
||||||
|
|
||||||
if (isset($data['roles'])) {
|
|
||||||
$user->roles()->attach($data['roles']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($primaryKey, $data): bool
|
|
||||||
{
|
|
||||||
if (isset($data['username']) && $this->checkUsernameUnique($data['username'], $primaryKey)) {
|
|
||||||
admin_abort(__('admin.admin_user.username_already_exists'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($data['password']) && Hash::needsRehash($data['password'])) {
|
|
||||||
$data['password'] = Hash::make($data['password']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $this->query()->whereKey($primaryKey)->firstOrFail();
|
|
||||||
|
|
||||||
foreach (['username', 'password', 'name', 'avatar', 'lock'] as $attribute) {
|
|
||||||
if (array_key_exists($attribute, $data)) {
|
|
||||||
$user->{$attribute} = $data[$attribute];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($user->isDirty('lock') && $user->lock != 1) {
|
|
||||||
$user->error_num = 0;
|
|
||||||
$user->last_error_at = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->save();
|
|
||||||
|
|
||||||
if (isset($data['roles'])) {
|
|
||||||
$roles = Arr::pull($data, 'roles');
|
|
||||||
$user->roles()->detach();
|
|
||||||
$user->roles()->attach(Arr::has($roles, '0.id') ? Arr::pluck($roles, 'id') : $roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkUsernameUnique($username, $id = 0): bool
|
|
||||||
{
|
|
||||||
return $this->query()
|
|
||||||
->where('username', $username)
|
|
||||||
->when($id, fn ($query) => $query->where('id', '<>', $id))
|
|
||||||
->exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateUserSetting($primaryKey, $data): bool
|
|
||||||
{
|
|
||||||
$this->passwordHandler($data, $primaryKey);
|
|
||||||
|
|
||||||
return parent::update($primaryKey, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function passwordHandler(&$data, $id = null)
|
|
||||||
{
|
|
||||||
$password = Arr::get($data, 'password');
|
|
||||||
|
|
||||||
if ($password) {
|
|
||||||
if ($password !== Arr::get($data, 'confirm_password')) {
|
|
||||||
admin_abort(__('admin.admin_user.password_confirmation'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen($password) < 6) {
|
|
||||||
admin_abort('密码长度至少6个字符');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($id) {
|
|
||||||
if (! Arr::get($data, 'old_password')) {
|
|
||||||
admin_abort(__('admin.admin_user.old_password_required'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$oldPassword = $this->query()->where('id', $id)->value('password');
|
|
||||||
|
|
||||||
if (! Hash::check($data['old_password'], $oldPassword)) {
|
|
||||||
admin_abort(__('admin.admin_user.old_password_error'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['password'] = bcrypt($password);
|
|
||||||
|
|
||||||
unset($data['confirm_password']);
|
|
||||||
unset($data['old_password']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function list()
|
|
||||||
{
|
|
||||||
$keyword = request()->keyword;
|
|
||||||
|
|
||||||
$query = $this
|
|
||||||
->query()
|
|
||||||
->with('roles')
|
|
||||||
->select(['id', 'name', 'username', 'avatar', 'created_at', 'lock'])
|
|
||||||
->when($keyword, function ($query) use ($keyword) {
|
|
||||||
$query->where('username', 'like', "%{$keyword}%")->orWhere('name', 'like', "%{$keyword}%");
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->sortable($query);
|
|
||||||
|
|
||||||
$items = (clone $query)->paginate(request()->input('perPage', 20))->items();
|
|
||||||
$total = (clone $query)->count();
|
|
||||||
|
|
||||||
return compact('items', 'total');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,8 +19,15 @@ Route::group([
|
||||||
|
|
||||||
$router->post('login', [App\Admin\Controllers\AuthController::class, 'login']);
|
$router->post('login', [App\Admin\Controllers\AuthController::class, 'login']);
|
||||||
|
|
||||||
|
$router->resource('system/admin_users', App\Admin\Controllers\AdminUserController::class);
|
||||||
|
$router->post('quick-edit/admin_users/{admin_user}',[\App\Admin\Controllers\AdminUserController::class, 'update']);
|
||||||
|
|
||||||
$router->get('system/admin_roles', [App\Admin\Controllers\AdminRoleController::class, 'index']);
|
$router->get('system/admin_roles', [App\Admin\Controllers\AdminRoleController::class, 'index']);
|
||||||
|
|
||||||
|
$router->resource('system/settings', \App\Admin\Controllers\SettingController::class);
|
||||||
|
|
||||||
|
$router->resource('system/keywords', \App\Admin\Controllers\KeywordController::class);
|
||||||
|
|
||||||
$router->resource('articles', \App\Admin\Controllers\ArticleController::class);
|
$router->resource('articles', \App\Admin\Controllers\ArticleController::class);
|
||||||
|
|
||||||
$router->resource('ads', \App\Admin\Controllers\AdController::class);
|
$router->resource('ads', \App\Admin\Controllers\AdController::class);
|
||||||
|
|
@ -33,26 +40,4 @@ Route::group([
|
||||||
$router->post('start_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'startChunk']);
|
$router->post('start_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'startChunk']);
|
||||||
$router->post('save_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'saveChunk']);
|
$router->post('save_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'saveChunk']);
|
||||||
$router->post('finish_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'finishChunk']);
|
$router->post('finish_chunk_upload_file', [\App\Admin\Controllers\IndexController::class, 'finishChunk']);
|
||||||
|
|
||||||
|
|
||||||
$router->group([
|
|
||||||
'prefix' => 'system',
|
|
||||||
'as' => 'system.',
|
|
||||||
], function (Router $router) {
|
|
||||||
// 账号管理
|
|
||||||
$router->resource('admin_users', App\Admin\Controllers\System\AdminUserController::class);
|
|
||||||
$router->post('/admin_users/{admin_user}/change-password', [App\Admin\Controllers\System\AdminUserController::class, 'changePassword'])->name('admin_users.change_password');
|
|
||||||
// 角色管理
|
|
||||||
$router->resource('admin_roles', App\Admin\Controllers\System\AdminRoleController::class);
|
|
||||||
$router->post('admin_roles/{admin_role}/menus', [App\Admin\Controllers\System\AdminRoleController::class, 'saveMenus'])->name('admin_roles.set_menus');
|
|
||||||
$router->post('admin_roles/{admin_role}/permissions', [App\Admin\Controllers\System\AdminRoleController::class, 'savePermissions'])->name('admin_roles.set_permissions');
|
|
||||||
// 权限管理
|
|
||||||
$router->resource('admin_permissions', App\Admin\Controllers\System\AdminPermissionController::class);
|
|
||||||
// 菜单管理
|
|
||||||
$router->resource('admin_menus', App\Admin\Controllers\System\AdminMenuController::class);
|
|
||||||
// 系统设置
|
|
||||||
$router->resource('settings', \App\Admin\Controllers\SettingController::class);
|
|
||||||
// 数据字典
|
|
||||||
$router->resource('keywords', App\Admin\Controllers\System\KeywordController::class);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\ModelFilters;
|
|
||||||
|
|
||||||
use EloquentFilter\ModelFilter;
|
|
||||||
|
|
||||||
class KeywordFilter extends ModelFilter
|
|
||||||
{
|
|
||||||
public function search($name)
|
|
||||||
{
|
|
||||||
return $this->where('name', 'like', '%'.$name.'%')->orWhere('key', 'like', '%'.$name.'%');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function parentKey($key)
|
|
||||||
{
|
|
||||||
return $this->where('parent_key', $key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Models\AdminRole as Model;
|
|
||||||
|
|
||||||
class AdminRole extends Model
|
|
||||||
{
|
|
||||||
protected static function boot(): void
|
|
||||||
{
|
|
||||||
parent::boot();
|
|
||||||
|
|
||||||
static::deleting(function (AdminRole $model) {
|
|
||||||
$model->menus()->detach();
|
|
||||||
$model->permissions()->detach();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function menus(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Admin::adminMenuModel(), 'admin_role_menus', 'role_id', 'menu_id');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
|
||||||
use Slowlyo\OwlAdmin\Models\AdminUser as Model;
|
|
||||||
|
|
||||||
class AdminUser extends Model
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Support\Collection
|
|
||||||
*/
|
|
||||||
protected $allAbilities;
|
|
||||||
|
|
||||||
|
|
||||||
public function roles(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Admin::adminRoleModel(), 'admin_role_users', 'user_id', 'role_id')->withTimestamps();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取此用户的全部能力
|
|
||||||
*/
|
|
||||||
public function allAbilities(): Collection
|
|
||||||
{
|
|
||||||
if ($this->allAbilities) {
|
|
||||||
return $this->allAbilities;
|
|
||||||
}
|
|
||||||
|
|
||||||
$model = Admin::adminPermissionModel();
|
|
||||||
$allPermissions = $model::all(['id', 'parent_id', 'slug'])->keyBy('id');
|
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection 此用户的所有角色的权限集合 */
|
|
||||||
$rolePermissions = $this->roles
|
|
||||||
->pluck('permissions')
|
|
||||||
->flatten()
|
|
||||||
->keyBy('id');
|
|
||||||
|
|
||||||
$abilities = $rolePermissions->map(fn ($permission) => $permission->slug);
|
|
||||||
|
|
||||||
foreach ($rolePermissions as $rolePermission) {
|
|
||||||
if (is_null($rolePermission->parent_id) || $abilities->has($rolePermission->parent_id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parent = $allPermissions->get($rolePermission->parent_id);
|
|
||||||
|
|
||||||
while ($parent) {
|
|
||||||
$abilities->put($parent->id, $parent->slug);
|
|
||||||
|
|
||||||
if (is_null($parent->parent_id)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parent = $allPermissions->get($parent->parent_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($allPermissions, $rolePermissions);
|
|
||||||
|
|
||||||
return $this->allAbilities = $abilities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function can($abilities, $arguments = []): bool
|
|
||||||
{
|
|
||||||
if (empty($abilities)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->isAdministrator()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return collect($abilities)->every(
|
|
||||||
fn ($ability) => $this->allAbilities()->contains($ability)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function allMenus(): Collection
|
|
||||||
{
|
|
||||||
$model = Admin::adminMenuModel();
|
|
||||||
$allMenus = $model::all()->keyBy($this->getKeyName());
|
|
||||||
|
|
||||||
if ($this->isAdministrator()) {
|
|
||||||
return $allMenus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection */
|
|
||||||
$roleMenus = $this->roles
|
|
||||||
->pluck('menus')
|
|
||||||
->flatten()
|
|
||||||
->keyBy($this->getKeyName());
|
|
||||||
|
|
||||||
$allRoleMenus = $roleMenus->collect();
|
|
||||||
|
|
||||||
foreach ($roleMenus as $roleMenu) {
|
|
||||||
if (is_null($roleMenu->parent_id) || $allRoleMenus->has($roleMenu->parent_id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parent = $allMenus->get($roleMenu->parent_id);
|
|
||||||
|
|
||||||
while ($parent) {
|
|
||||||
$allRoleMenus->put($parent->id, $parent);
|
|
||||||
|
|
||||||
if (is_null($parent->parent_id)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parent = $allMenus->get($parent->parent_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($allMenus, $roleMenus);
|
|
||||||
|
|
||||||
return $allRoleMenus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\ModelFilters;
|
namespace App\Models\Filters;
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use EloquentFilter\ModelFilter;
|
use EloquentFilter\ModelFilter;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\ModelFilters;
|
namespace App\Models\Filters;
|
||||||
|
|
||||||
use EloquentFilter\ModelFilter;
|
use EloquentFilter\ModelFilter;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Filters;
|
||||||
|
|
||||||
|
use EloquentFilter\ModelFilter;
|
||||||
|
use App\Models\Keyword;
|
||||||
|
|
||||||
|
class KeywordFilter extends ModelFilter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 关键字
|
||||||
|
*/
|
||||||
|
public function name($name)
|
||||||
|
{
|
||||||
|
return $this->where('name','like', '%'.$name.'%')
|
||||||
|
->orWhere('key','like', '%'.$name.'%');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parentName($parent_name)
|
||||||
|
{
|
||||||
|
if(request('has_owner', 1)){
|
||||||
|
$this->where(function($q) use ($parent_name){
|
||||||
|
$q->where('name','like', '%'.$parent_name.'%')
|
||||||
|
->orWhere('key','like', '%'.$parent_name.'%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return $this->orWhere('path','like', '%-'.
|
||||||
|
Keyword::where('name','like', '%'.$parent_name.'%')->orWhere('key','like', '%'.$parent_name.'%')->value('id')
|
||||||
|
. '-%' ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,21 +2,19 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Admin\Components;
|
|
||||||
use App\ModelFilters\KeywordFilter;
|
|
||||||
use EloquentFilter\Filterable;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use EloquentFilter\Filterable;
|
||||||
|
use App\Admin\Components;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Keyword extends Model
|
class Keyword extends Model
|
||||||
{
|
{
|
||||||
use Filterable;
|
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use Filterable;
|
||||||
|
|
||||||
protected $fillable = ['name', 'key', 'value', 'parent_id', 'parent_key', 'path', 'sort', 'lv'];
|
protected $fillable = ['name', 'key', 'value', 'parent_id', 'parent_key', 'path', 'sort', 'lv'];
|
||||||
|
|
||||||
protected function serializeDate(\DateTimeInterface $date)
|
protected function serializeDate(\DateTimeInterface $date)
|
||||||
{
|
{
|
||||||
return $date->format('Y-m-d H:i:s');
|
return $date->format('Y-m-d H:i:s');
|
||||||
|
|
@ -25,27 +23,26 @@ class Keyword extends Model
|
||||||
protected static function boot()
|
protected static function boot()
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
// 监听 Keyword 的创建事件,用于初始化 path 和 lv 字段值
|
// 监听 Keyword 的创建事件,用于初始化 path 和 lv 字段值
|
||||||
static::saving(function (Keyword $keyword) {
|
static::saving(function ($keyword) {
|
||||||
if (is_null($parent = $keyword->parent)) {
|
// 如果创建的是一个根类目
|
||||||
$keyword->forceFill([
|
if (! $keyword->parent_id) {
|
||||||
'path' => '-',
|
// 将层级设为 1
|
||||||
'lv' => 1,
|
$keyword->lv = 1;
|
||||||
]);
|
// 将 path 设为 -
|
||||||
|
$keyword->path = '-';
|
||||||
if ((string) $keyword->key === '') {
|
if(empty($keyword->key)){
|
||||||
$keyword->key = Str::random(16);
|
$keyword->key = Str::quickRandom($length = 16);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$keyword->forceFill([
|
// 将层级设为父类目的层级 + 1
|
||||||
'parent_key' => $parent->lv > 1 ? $parent->parent_key : $parent->key,
|
$keyword->lv = $keyword->parent->lv + 1;
|
||||||
'path' => $parent->full_path,
|
$keyword->parent_key = $keyword->parent->key;
|
||||||
'lv' => $parent->lv + 1,
|
// 将 path 值设为父类目的 path 追加父类目 ID 以及最后跟上一个 - 分隔符
|
||||||
]);
|
$keyword->path = $keyword->parent->path.$keyword->parent_id.'-';
|
||||||
|
//当前key是否为空
|
||||||
if ((string) $keyword->key === '') {
|
if(empty($keyword->key)){
|
||||||
$keyword->key = $parent->key.'_'.($parent->children()->count() + 1);
|
$keyword->key = $keyword->parent_key . '_' . (self::where('parent_key', $keyword->parent_key)->count() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -61,32 +58,19 @@ class Keyword extends Model
|
||||||
return $this->hasMany(static::class, 'parent_id');
|
return $this->hasMany(static::class, 'parent_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeSort($q)
|
|
||||||
{
|
|
||||||
return $q->orderBy('sort', 'asc');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function scopeAllChildrenOfKey($q, $parentKey)
|
public function scopeAllChildrenOfKey($q, $parentKey)
|
||||||
{
|
{
|
||||||
$q->where('path', 'like', '%-'.
|
$q->where('path','like', '%-'.
|
||||||
static::where('key', $parentKey)->value('id')
|
static::where('key', $parentKey)->value('id')
|
||||||
.'-%' ?? '');
|
. '-%' ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tagsMap(string $key)
|
public static function tagsMap(String $key)
|
||||||
{
|
{
|
||||||
$mapArr = [];
|
$mapArr = [];
|
||||||
self::query()->where('parent_key', $key)->get()->map(function ($item) use (&$mapArr) {
|
self::query()->where('parent_key', $key)->get()->map(function($item) use (&$mapArr){
|
||||||
$mapArr[$item->id] = Components::make()->keywordsTag($item->name, $item->value);
|
$mapArr[$item->id] = Components::make()->keywordsTag($item->name, $item->value);
|
||||||
});
|
});
|
||||||
|
|
||||||
return $mapArr;
|
return $mapArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function fullPath(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn (mixed $value, array $attributes) => $attributes['path'].$attributes['id'].'-',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
@ -14,7 +11,8 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->app->singleton('admin.menu', \App\Admin\Menu::class);
|
//
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -22,24 +20,6 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
JsonResource::withoutWrapping();
|
\Schema::defaultStringLength(191);
|
||||||
|
|
||||||
$this->definePolymorphicTypes();
|
|
||||||
|
|
||||||
Validator::extend('phone', function ($attribute, $value, $parameters, $validator) {
|
|
||||||
return preg_match('/^1[\d]{10}$/', $value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义多态类型
|
|
||||||
*/
|
|
||||||
protected function definePolymorphicTypes(): void
|
|
||||||
{
|
|
||||||
Relation::enforceMorphMap(
|
|
||||||
collect([
|
|
||||||
\App\Models\AdminUser::class,
|
|
||||||
])->mapWithKeys(fn ($model) => [(new $model)->getTable() => $model])->all()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Admin\Services;
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
use App\Models\Ad;
|
use App\Models\Ad;
|
||||||
use App\ModelFilters\AdFilter;
|
use App\Models\Filters\AdFilter;
|
||||||
use App\Traits\UploadTrait;
|
use App\Traits\UploadTrait;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Admin\Services;
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Slowlyo\OwlAdmin\Admin;
|
use Slowlyo\OwlAdmin\Admin;
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Admin\Services;
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
use App\Models\Article;
|
use App\Models\Article;
|
||||||
use App\ModelFilters\ArticleFilter;
|
use App\Models\Filters\ArticleFilter;
|
||||||
use App\Traits\UploadTrait;
|
use App\Traits\UploadTrait;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
|
use Slowlyo\OwlAdmin\Services\AdminService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method Region getModel()
|
||||||
|
* @method Region|\Illuminate\Database\Query\Builder query()
|
||||||
|
*/
|
||||||
|
class BaseService extends AdminService
|
||||||
|
{
|
||||||
|
protected array $withRelationships = [];
|
||||||
|
|
||||||
|
protected string $modelFilterName = '';
|
||||||
|
|
||||||
|
protected bool $modelSortAble = false;
|
||||||
|
|
||||||
|
public function getTree()
|
||||||
|
{
|
||||||
|
$list = $this->query()->orderByDesc('sort')->get();
|
||||||
|
$minNum = $list->min('parent_id');
|
||||||
|
return array2tree($list->toArray(), $minNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getModelFilter()
|
||||||
|
{
|
||||||
|
return $this->modelFilterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listQuery()
|
||||||
|
{
|
||||||
|
$model = $this->getModel();
|
||||||
|
$filter = $this->getModelFilter();
|
||||||
|
|
||||||
|
$query = $this->query();
|
||||||
|
if($this->withRelationships){
|
||||||
|
$query->with($this->withRelationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($filter) {
|
||||||
|
$query->filter(request()->input(), $filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->modelSortAble){
|
||||||
|
$query->sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sortable($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDetail($id)
|
||||||
|
{
|
||||||
|
return $this->query()->with($this->withRelationships)->find($id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Admin\Services\System;
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
use App\ModelFilters\KeywordFilter;
|
|
||||||
use App\Admin\Services\BaseService;
|
|
||||||
use App\Models\Keyword;
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
use App\Models\Keyword;
|
||||||
|
use App\Models\Filters\KeywordFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method Keyword getModel()
|
* @method Keyword getModel()
|
||||||
|
|
@ -14,15 +13,13 @@ use Illuminate\Support\Arr;
|
||||||
class KeywordService extends BaseService
|
class KeywordService extends BaseService
|
||||||
{
|
{
|
||||||
protected string $modelName = Keyword::class;
|
protected string $modelName = Keyword::class;
|
||||||
|
|
||||||
protected string $modelFilterName = KeywordFilter::class;
|
protected string $modelFilterName = KeywordFilter::class;
|
||||||
|
|
||||||
public function getTree()
|
public function getTree()
|
||||||
{
|
{
|
||||||
$list = $this->query()->sort()->filter(request()->all(), $this->modelFilterName)->get();
|
$list = $this->query()->filter(request()->all(), $this->modelFilterName)->orderByDesc('sort')->get();
|
||||||
$minNum = $list->min('parent_id');
|
$minNum = $list->min('parent_id');
|
||||||
|
return !$list->isEmpty() ? array2tree($list->toArray(), $minNum) :[];
|
||||||
return ! $list->isEmpty() ? array2tree($list->toArray(), $minNum) : [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parentIsChild($id, $pid): bool
|
public function parentIsChild($id, $pid): bool
|
||||||
|
|
@ -56,7 +53,7 @@ class KeywordService extends BaseService
|
||||||
$model = $this->getModel();
|
$model = $this->getModel();
|
||||||
|
|
||||||
foreach ($data as $k => $v) {
|
foreach ($data as $k => $v) {
|
||||||
if (! in_array($k, $columns)) {
|
if (!in_array($k, $columns)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +75,6 @@ class KeywordService extends BaseService
|
||||||
if ($pid != 0) {
|
if ($pid != 0) {
|
||||||
if ($this->parentIsChild($primaryKey, $pid)) {
|
if ($this->parentIsChild($primaryKey, $pid)) {
|
||||||
$this->setError('父级不允许设置为当前子权限');
|
$this->setError('父级不允许设置为当前子权限');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +82,7 @@ class KeywordService extends BaseService
|
||||||
$model = $this->query()->whereKey($primaryKey)->first();
|
$model = $this->query()->whereKey($primaryKey)->first();
|
||||||
|
|
||||||
foreach ($data as $k => $v) {
|
foreach ($data as $k => $v) {
|
||||||
if (! in_array($k, $columns)) {
|
if (!in_array($k, $columns)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,11 +94,10 @@ class KeywordService extends BaseService
|
||||||
|
|
||||||
public function hasRepeated($data, $id = 0): bool
|
public function hasRepeated($data, $id = 0): bool
|
||||||
{
|
{
|
||||||
$query = $this->query()->when($id, fn ($query) => $query->where('id', '<>', $id));
|
$query = $this->query()->when($id, fn($query) => $query->where('id', '<>', $id));
|
||||||
|
|
||||||
if ((clone $query)->where('key', $data['key'])->exists()) {
|
if ((clone $query)->where('key', $data['key'])->exists()) {
|
||||||
$this->setError('KEY重复');
|
$this->setError('KEY重复');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +107,7 @@ class KeywordService extends BaseService
|
||||||
public function delete(string $ids): mixed
|
public function delete(string $ids): mixed
|
||||||
{
|
{
|
||||||
$ids = explode(',', $ids);
|
$ids = explode(',', $ids);
|
||||||
if (count($ids) == 1) {
|
if(count($ids) == 1){
|
||||||
$this->query()->where('path', 'like', '%-'.$ids[0].'-%')->delete();
|
$this->query()->where('path', 'like', '%-'.$ids[0].'-%')->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,10 +63,6 @@ trait UploadTrait
|
||||||
|
|
||||||
$path = $file->store(Admin::config('admin.upload.tem_directory.' . $type).'/'.date('Y-m-d'), Admin::config('admin.upload.disk'));
|
$path = $file->store(Admin::config('admin.upload.tem_directory.' . $type).'/'.date('Y-m-d'), Admin::config('admin.upload.disk'));
|
||||||
|
|
||||||
if (request()->has('full-url')) {
|
|
||||||
$path = Storage::disk(Admin::config('admin.upload.disk'))->url($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response()->success(['value' => $path]);
|
return $this->response()->success(['value' => $path]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,26 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// 应用名称
|
// 应用名称
|
||||||
'name' => 'Owl Admin',
|
'name' => 'Owl Admin',
|
||||||
|
|
||||||
// 应用 logo
|
// 应用 logo
|
||||||
'logo' => '/admin-assets/logo.png',
|
'logo' => '/admin-assets/logo.png',
|
||||||
|
|
||||||
// 默认头像
|
// 默认头像
|
||||||
'default_avatar' => '/admin-assets/default-avatar.png',
|
'default_avatar' => '/admin-assets/default-avatar.png',
|
||||||
|
|
||||||
// 应用安装目录
|
// 应用安装目录
|
||||||
'directory' => app_path('Admin'),
|
'directory' => app_path('Admin'),
|
||||||
|
|
||||||
// 引导文件
|
// 引导文件
|
||||||
'bootstrap' => app_path('Admin/bootstrap.php'),
|
'bootstrap' => app_path('Admin/bootstrap.php'),
|
||||||
|
|
||||||
// 应用路由
|
// 应用路由
|
||||||
'route' => [
|
'route' => [
|
||||||
'prefix' => 'admin-api',
|
'prefix' => 'admin-api',
|
||||||
'domain' => null,
|
'domain' => null,
|
||||||
'namespace' => 'App\\Admin\\Controllers',
|
'namespace' => 'App\\Admin\\Controllers',
|
||||||
'middleware' => [
|
'middleware' => ['admin'],
|
||||||
\App\Admin\Middleware\Authenticate::class,
|
|
||||||
'admin.bootstrap',
|
|
||||||
\App\Admin\Middleware\CheckPermission::class,
|
|
||||||
'sanctum',
|
|
||||||
'substitute',
|
|
||||||
],
|
|
||||||
// 不包含额外路由, 配置后, 不会追加新增/详情/编辑页面路由
|
// 不包含额外路由, 配置后, 不会追加新增/详情/编辑页面路由
|
||||||
'without_extra_routes' => [
|
'without_extra_routes' => [
|
||||||
'/dashboard',
|
'/dashboard',
|
||||||
|
|
@ -36,69 +30,70 @@ return [
|
||||||
|
|
||||||
'auth' => [
|
'auth' => [
|
||||||
// 是否开启验证码
|
// 是否开启验证码
|
||||||
'login_captcha' => env('ADMIN_LOGIN_CAPTCHA', true),
|
'login_captcha' => env('ADMIN_LOGIN_CAPTCHA', true),
|
||||||
// 是否开启认证
|
// 是否开启认证
|
||||||
'enable' => true,
|
'enable' => true,
|
||||||
// 是否开启鉴权
|
// 是否开启鉴权
|
||||||
'permission' => true,
|
'permission' => true,
|
||||||
// token 有效期 (分钟), 为空则不会过期
|
// token 有效期 (分钟), 为空则不会过期
|
||||||
'token_expiration' => null,
|
'token_expiration' => null,
|
||||||
'guard' => 'admin',
|
'guard' => 'admin',
|
||||||
'guards' => [
|
'guards' => [
|
||||||
'admin' => [
|
'admin' => [
|
||||||
'driver' => 'sanctum',
|
'driver' => 'sanctum',
|
||||||
'provider' => 'admin',
|
'provider' => 'admin',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'providers' => [
|
'providers' => [
|
||||||
'admin' => [
|
'admin' => [
|
||||||
'driver' => 'eloquent',
|
'driver' => 'eloquent',
|
||||||
'model' => \App\Models\AdminUser::class,
|
'model' => \Slowlyo\OwlAdmin\Models\AdminUser::class,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'except' => [
|
'except' => [
|
||||||
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'upload' => [
|
'upload' => [
|
||||||
'disk' => env('FILESYSTEM_DISK', 'public'),
|
'disk' => env("FILESYSTEM_DISK", 'public'),
|
||||||
// 文件上传目录
|
// 文件上传目录
|
||||||
'directory' => [
|
'directory' => [
|
||||||
'image' => 'images',
|
'image' => 'images',
|
||||||
'file' => 'files',
|
'file' => 'files',
|
||||||
'rich' => 'rich',
|
'rich' => 'rich',
|
||||||
],
|
],
|
||||||
// 临时目录
|
// 临时目录
|
||||||
'tem_directory' => [
|
'tem_directory' => [
|
||||||
'image' => 'temporary/images',
|
'image' => 'temporary/images',
|
||||||
'file' => 'temporary/file',
|
'file' => 'temporary/file',
|
||||||
'rich' => 'temporary/rich',
|
'rich' => 'temporary/rich',
|
||||||
],
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
'https' => env('ADMIN_HTTPS', false),
|
'https' => env('ADMIN_HTTPS', false),
|
||||||
|
|
||||||
// 是否显示 [开发者工具]
|
// 是否显示 [开发者工具]
|
||||||
'show_development_tools' => env('ADMIN_SHOW_DEVELOPMENT_TOOLS', false),
|
'show_development_tools' => env('ADMIN_SHOW_DEVELOPMENT_TOOLS', true),
|
||||||
|
|
||||||
// 是否显示 [权限] 功能中的自动生成按钮
|
// 是否显示 [权限] 功能中的自动生成按钮
|
||||||
'show_auto_generate_permission_button' => env('ADMIN_SHOW_AUTO_GENERATE_PERMISSION_BUTTON', true),
|
'show_auto_generate_permission_button' => env('ADMIN_SHOW_AUTO_GENERATE_PERMISSION_BUTTON', true),
|
||||||
|
|
||||||
// 扩展
|
// 扩展
|
||||||
'extension' => [
|
'extension' => [
|
||||||
'dir' => base_path('extensions'),
|
'dir' => base_path('extensions'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'layout' => [
|
'layout' => [
|
||||||
// 浏览器标题, 功能名称使用 %title% 代替
|
// 浏览器标题, 功能名称使用 %title% 代替
|
||||||
'title' => '%title% | 门店助手-管理后台',
|
'title' => '%title% | OwlAdmin',
|
||||||
'header' => [
|
'header' => [
|
||||||
// 是否显示 [刷新] 按钮
|
// 是否显示 [刷新] 按钮
|
||||||
'refresh' => true,
|
'refresh' => true,
|
||||||
// 是否显示 [暗色模式] 按钮
|
// 是否显示 [暗色模式] 按钮
|
||||||
'dark' => true,
|
'dark' => true,
|
||||||
// 是否显示 [全屏] 按钮
|
// 是否显示 [全屏] 按钮
|
||||||
'full_screen' => true,
|
'full_screen' => true,
|
||||||
// 是否显示 [主题配置] 按钮
|
// 是否显示 [主题配置] 按钮
|
||||||
'theme_config' => true,
|
'theme_config' => true,
|
||||||
],
|
],
|
||||||
|
|
@ -113,17 +108,17 @@ return [
|
||||||
*/
|
*/
|
||||||
'keep_alive_exclude' => [],
|
'keep_alive_exclude' => [],
|
||||||
// 底部信息
|
// 底部信息
|
||||||
'footer' => '',
|
'footer' => '<a href="https://github.com/slowlyo/owl-admin" target="_blank">Owl Admin</a>',
|
||||||
],
|
],
|
||||||
|
|
||||||
'database' => [
|
'database' => [
|
||||||
'connection' => env('DB_CONNECTION', 'mysql'),
|
'connection' => env('ADMIN_DB_CONNECTION') ?? env('DB_CONNECTION', 'mysql'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'models' => [
|
'models' => [
|
||||||
'admin_user' => \App\Models\AdminUser::class,
|
'admin_user' => \Slowlyo\OwlAdmin\Models\AdminUser::class,
|
||||||
'admin_role' => \App\Models\AdminRole::class,
|
'admin_role' => \Slowlyo\OwlAdmin\Models\AdminRole::class,
|
||||||
'admin_menu' => \Slowlyo\OwlAdmin\Models\AdminMenu::class,
|
'admin_menu' => \Slowlyo\OwlAdmin\Models\AdminMenu::class,
|
||||||
'admin_permission' => \Slowlyo\OwlAdmin\Models\AdminPermission::class,
|
'admin_permission' => \Slowlyo\OwlAdmin\Models\AdminPermission::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?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('users', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('email')->unique();
|
||||||
|
$table->timestamp('email_verified_at')->nullable();
|
||||||
|
$table->string('password');
|
||||||
|
$table->rememberToken();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('users');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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('password_reset_tokens', function (Blueprint $table) {
|
||||||
|
$table->string('email')->primary();
|
||||||
|
$table->string('token');
|
||||||
|
$table->timestamp('created_at')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('password_reset_tokens');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?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('failed_jobs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('uuid')->unique();
|
||||||
|
$table->text('connection');
|
||||||
|
$table->text('queue');
|
||||||
|
$table->longText('payload');
|
||||||
|
$table->longText('exception');
|
||||||
|
$table->timestamp('failed_at')->useCurrent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('failed_jobs');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
<?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::table('admin_menus', function (Blueprint $table) {
|
|
||||||
$table->string('slug')->unique()->nullable();
|
|
||||||
});
|
|
||||||
Schema::table('admin_permissions', function (Blueprint $table) {
|
|
||||||
$table->dropUnique(['name']);
|
|
||||||
$table->string('slug')->change();
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::create('admin_role_menus', function (Blueprint $table) {
|
|
||||||
$table->integer('role_id');
|
|
||||||
$table->integer('menu_id');
|
|
||||||
$table->index(['role_id', 'menu_id']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::table('admin_menus', function (Blueprint $table) {
|
|
||||||
$table->dropColumn(['slug']);
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::table('admin_permissions', function (Blueprint $table) {
|
|
||||||
$table->unique(['name']);
|
|
||||||
$table->string('slug', 50)->change();
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::dropIfExists('admin_role_menus');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Slowlyo\OwlAdmin\Models\AdminMenu;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class AdminMenuSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
$menus = [
|
||||||
|
['title' => 'index', 'icon' => 'line-md:home-twotone-alt', 'url' => '/index', 'is_home'=>1, 'order'=>1],
|
||||||
|
['title' => 'admin_system', 'icon' => 'material-symbols:settings-outline', 'url' => '/system', 'order'=>2,
|
||||||
|
'children' => [
|
||||||
|
['title' => 'admin_users', 'icon' => 'ph:user-gear', 'url' => '/system/admin_users', 'order'=>1],
|
||||||
|
['title' => 'admin_roles', 'icon' => 'carbon:user-role', 'url' => '/system/admin_roles', 'order'=>2],
|
||||||
|
['title' => 'admin_permission', 'icon' => 'carbon:user-role', 'url' => '/system/admin_permissions', 'order'=>3],
|
||||||
|
['title' => 'admin_menu', 'icon' => 'fluent-mdl2:permissions', 'url' => '/system/admin_menus', 'order'=>4],
|
||||||
|
['title' => 'admin_setting', 'icon' => 'akar-icons:settings-horizontal', 'url' => '/system/settings', 'order'=>5],
|
||||||
|
['title' => 'keywords', 'icon' => 'ph:codesandbox-logo-light', 'url' => '/system/keywords', 'order'=>6]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['title' => 'web_content', 'icon' => 'ic:outline-collections-bookmark', 'url' => '', 'order'=>3,
|
||||||
|
'children' =>[
|
||||||
|
['title'=>'articles', 'icon'=>'ic:outline-article','url'=>'/articles', 'order'=>1],
|
||||||
|
['title'=>'ads', 'icon'=>'lets-icons:img-box','url'=>'/ads', 'order'=>2],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
DB::table('admin_menus')->truncate();
|
||||||
|
try {
|
||||||
|
DB::begintransaction();
|
||||||
|
$this->createMenus($menus);
|
||||||
|
DB::commit();
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
DB::rollBack();
|
||||||
|
report($th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createMenus(array $menus, $pid = 0)
|
||||||
|
{
|
||||||
|
foreach ($menus as $menu) {
|
||||||
|
$mm = AdminMenu::create([
|
||||||
|
'title' => $menu['title'],
|
||||||
|
'icon' => $menu['icon'],
|
||||||
|
'url' => $menu['url'],
|
||||||
|
'parent_id' => $pid,
|
||||||
|
'url_type' => $menu['url_type'] ?? 1,
|
||||||
|
'visible' => $menu['visible'] ?? 1,
|
||||||
|
'is_home' => $menu['is_home'] ?? 0,
|
||||||
|
'order' => $menu['order'] ?? 0,
|
||||||
|
'is_full' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isset($menu['children'])) {
|
||||||
|
$this->createMenus($menu['children'], $mm->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use Slowlyo\OwlAdmin\Models\AdminMenu;
|
|
||||||
use Slowlyo\OwlAdmin\Models\AdminPermission;
|
|
||||||
|
|
||||||
class AdminPermissionSeeder extends Seeder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the database seeds.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| 主页
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
'home' => [
|
|
||||||
'name' => '主页',
|
|
||||||
'icon' => 'line-md:home-twotone-alt',
|
|
||||||
'uri' => '/dashboard',
|
|
||||||
'is_home' => 1,
|
|
||||||
'children' => [],
|
|
||||||
'order' => 1,
|
|
||||||
],
|
|
||||||
|
|
||||||
'system' => [
|
|
||||||
'name' => '系统管理',
|
|
||||||
'icon' => 'material-symbols:settings-outline',
|
|
||||||
'uri' => '/system',
|
|
||||||
'children' => [
|
|
||||||
'admin_users' => [
|
|
||||||
'name' => '账号管理',
|
|
||||||
'icon' => 'ph:user-gear',
|
|
||||||
'uri' => '/system/admin_users',
|
|
||||||
'resource' => ['list', 'update'],
|
|
||||||
'children' => ['change_password' => '修改密码'],
|
|
||||||
],
|
|
||||||
'admin_roles' => [
|
|
||||||
'name' => '角色管理',
|
|
||||||
'icon' => 'carbon:user-role',
|
|
||||||
'uri' => '/system/admin_roles',
|
|
||||||
'resource' => ['list', 'create', 'update', 'delete'],
|
|
||||||
'children' => [
|
|
||||||
'set_menus' => '设置菜单',
|
|
||||||
'set_permissions' => '设置权限',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'admin_permissions' => [
|
|
||||||
'name' => '权限管理',
|
|
||||||
'icon' => 'fluent-mdl2:permissions',
|
|
||||||
'uri' => '/system/admin_permissions',
|
|
||||||
'resource' => ['list', 'create', 'update', 'delete'],
|
|
||||||
'children' => [],
|
|
||||||
],
|
|
||||||
'admin_menus' => [
|
|
||||||
'name' => '菜单管理',
|
|
||||||
'icon' => 'ant-design:menu-unfold-outlined',
|
|
||||||
'uri' => '/system/admin_menus',
|
|
||||||
'resource' => ['list', 'create', 'update', 'delete'],
|
|
||||||
'children' => [],
|
|
||||||
],
|
|
||||||
'settings' => [
|
|
||||||
'name' => '系统设置',
|
|
||||||
'icon' => 'akar-icons:settings-horizontal',
|
|
||||||
'uri' => '/system/settings',
|
|
||||||
'resource' => true,
|
|
||||||
'children' => [],
|
|
||||||
],
|
|
||||||
'keywords' => [
|
|
||||||
'name' => '数据字典',
|
|
||||||
'icon' => 'ph:codesandbox-logo-light',
|
|
||||||
'uri' => '/system/keywords',
|
|
||||||
'resource' => ['list', 'create', 'update', 'delete'],
|
|
||||||
'children' => [],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->handleAdminMenus($data);
|
|
||||||
$this->handleAdminPermissions($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleAdminMenus(array $data, ?AdminMenu $parent = null): void
|
|
||||||
{
|
|
||||||
$sort = 0;
|
|
||||||
foreach ($data as $slug => $node) {
|
|
||||||
if (! is_array($node) || ! array_key_exists('uri', $node)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$sort++;
|
|
||||||
/** @var \Slowlyo\OwlAdmin\Models\AdminMenu */
|
|
||||||
$menu = AdminMenu::updateOrCreate([
|
|
||||||
'slug' => ($parent->slug ?? 'admin').'.'.$slug,
|
|
||||||
], [
|
|
||||||
'parent_id' => $parent->id ?? 0,
|
|
||||||
'order' => $sort,
|
|
||||||
'title' => $node['name'],
|
|
||||||
'icon' => $node['icon'],
|
|
||||||
'url' => $node['uri'],
|
|
||||||
'url_type' => $node['uri_type'] ?? 1,
|
|
||||||
'visible' => $node['visible'] ?? 1,
|
|
||||||
'is_home' => $node['is_home'] ?? 0,
|
|
||||||
'is_full' => $node['is_full'] ?? 0,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->handleAdminMenus($node['children'] ?? [], $menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleAdminPermissions(array $data, ?AdminPermission $parent = null)
|
|
||||||
{
|
|
||||||
foreach ($data as $slug => $node) {
|
|
||||||
$permission = AdminPermission::updateOrCreate([
|
|
||||||
'slug' => ($parent->slug ?? 'admin').'.'.$slug,
|
|
||||||
], [
|
|
||||||
'parent_id' => $parent->id ?? 0,
|
|
||||||
'name' => is_array($node) ? $node['name'] : $node,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (! is_array($node)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 资源路由权限
|
|
||||||
if (array_key_exists('resource', $node)) {
|
|
||||||
$resourceAbilities = [];
|
|
||||||
|
|
||||||
if (is_array($node['resource'])) {
|
|
||||||
$resourceAbilities = $node['resource'];
|
|
||||||
} elseif ($node['resource'] === true) {
|
|
||||||
$resourceAbilities = array_keys($this->resourceAbilityMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($resourceAbilities as $resourceAbility) {
|
|
||||||
AdminPermission::updateOrCreate([
|
|
||||||
'slug' => $permission->slug.'.'.$resourceAbility,
|
|
||||||
], [
|
|
||||||
'parent_id' => $permission->id,
|
|
||||||
'name' => $this->resourceAbilityMap()[$resourceAbility],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->handleAdminPermissions($node['children'] ?? [], $permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function resourceAbilityMap(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'list' => '列表',
|
|
||||||
'create' => '新增',
|
|
||||||
'update' => '编辑',
|
|
||||||
'delete' => '删除',
|
|
||||||
'view' => '查看',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Slowlyo\OwlAdmin\Models\{AdminRole, AdminUser};
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class AdminSeeder extends Seeder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the database seeds.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
foreach ([
|
|
||||||
'admin_roles',
|
|
||||||
'admin_users',
|
|
||||||
'admin_role_users',
|
|
||||||
] as $table) {
|
|
||||||
DB::table($table)->truncate();
|
|
||||||
}
|
|
||||||
|
|
||||||
$roleAdministrator = AdminRole::create([
|
|
||||||
'name' => 'Administrator',
|
|
||||||
'slug' => 'administrator',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$admin = AdminUser::create([
|
|
||||||
'username' => 'admin',
|
|
||||||
'password' => bcrypt('admin'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$admin->roles()->saveMany([$roleAdministrator]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -12,8 +12,7 @@ class DatabaseSeeder extends Seeder
|
||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$this->call(AdminSeeder::class);
|
$this->call(AdminMenuSeeder::class);
|
||||||
$this->call(AdminPermissionSeeder::class);
|
|
||||||
$this->call(KeywordSeeder::class);
|
$this->call(KeywordSeeder::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,228 +1,231 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'remember_me' => '记住我',
|
'remember_me' => '记住我',
|
||||||
'login' => '登 录',
|
'login' => '登 录',
|
||||||
'logout' => '退出登录',
|
'logout' => '退出登录',
|
||||||
'username' => '用户名',
|
'username' => '用户名',
|
||||||
'password' => '密码',
|
'password' => '密码',
|
||||||
'old_password' => '旧密码',
|
'old_password' => '旧密码',
|
||||||
'confirm_password' => '确认密码',
|
'confirm_password' => '确认密码',
|
||||||
'captcha' => '验证码',
|
'captcha' => '验证码',
|
||||||
'captcha_error' => '验证码有误',
|
'captcha_error' => '验证码有误',
|
||||||
'required' => '请填写:attribute',
|
'required' => '请填写:attribute',
|
||||||
'login_successful' => '登录成功',
|
'login_successful' => '登录成功',
|
||||||
'login_failed' => '用户名或密码错误',
|
'login_failed' => '用户名或密码错误',
|
||||||
'user_setting' => '个人设置',
|
'user_setting' => '个人设置',
|
||||||
'created_at' => '创建时间',
|
'created_at' => '创建时间',
|
||||||
'updated_at' => '更新时间',
|
'updated_at' => '更新时间',
|
||||||
'deleted_at' => '删除时间',
|
'deleted_at' => '删除时间',
|
||||||
'actions' => '操作',
|
'actions' => '操作',
|
||||||
'create' => '新增',
|
'create' => '新增',
|
||||||
'edit' => '编辑',
|
'edit' => '编辑',
|
||||||
'show' => '查看',
|
'show' => '查看',
|
||||||
'delete' => '删除',
|
'delete' => '删除',
|
||||||
'copy' => '复制',
|
'copy' => '复制',
|
||||||
'confirm_delete' => '确认删除选中项?',
|
'confirm_delete' => '确认删除选中项?',
|
||||||
'confirm' => '是否确定?',
|
'back' => '返回',
|
||||||
'back' => '返回',
|
'reset' => '重置',
|
||||||
'reset' => '重置',
|
'search' => '搜索',
|
||||||
'search' => '搜索',
|
'list' => '列表',
|
||||||
'list' => '列表',
|
'add' => '新增',
|
||||||
'add' => '新增',
|
'save' => '保存',
|
||||||
'save' => '保存',
|
'detail' => '详情',
|
||||||
'detail' => '详情',
|
|
||||||
|
|
||||||
'developer' => '开发',
|
'developer' => '开发',
|
||||||
'code_generator' => '代码生成器',
|
'code_generator' => '代码生成器',
|
||||||
'visual_editor' => '可视化编辑器',
|
'visual_editor' => '可视化编辑器',
|
||||||
'terminal' => '终端',
|
'terminal' => '终端',
|
||||||
'administrator' => '管理员',
|
'administrator' => '管理员',
|
||||||
'soft_delete' => '软删除',
|
'soft_delete' => '软删除',
|
||||||
'keyword' => '关键字',
|
'keyword' => '关键字',
|
||||||
'unknown_error' => '未知错误',
|
'unknown_error' => '未知错误',
|
||||||
'upload_file_error' => '上传文件错误',
|
'upload_file_error' => '上传文件错误',
|
||||||
'parent' => '父级',
|
'parent' => '父级',
|
||||||
'order' => '排序',
|
'order' => '排序',
|
||||||
'order_desc' => '降序排序',
|
'order_desc' => '降序排序',
|
||||||
'order_asc' => '升序排序',
|
'order_asc' => '升序排序',
|
||||||
'menus' => '菜单',
|
'menus' => '菜单',
|
||||||
'successfully' => '成功',
|
'successfully' => '成功',
|
||||||
'failed' => '失败',
|
'failed' => '失败',
|
||||||
'successfully_message' => ':attribute成功',
|
'successfully_message' => ':attribute成功',
|
||||||
'failed_message' => ':attribute失败',
|
'failed_message' => ':attribute失败',
|
||||||
'action_success' => '操作成功',
|
'action_success' => '操作成功',
|
||||||
'action_failed' => '操作失败',
|
'action_failed' => '操作失败',
|
||||||
'save_success' => '保存成功',
|
'save_success' => '保存成功',
|
||||||
'save_failed' => '保存失败',
|
'save_failed' => '保存失败',
|
||||||
'yes' => '是',
|
'yes' => '是',
|
||||||
'no' => '否',
|
'no' => '否',
|
||||||
'need_start_with_slash' => '需要以 / 开头',
|
'need_start_with_slash' => '需要以 / 开头',
|
||||||
'cancel' => '取消',
|
'cancel' => '取消',
|
||||||
'please_login' => '请先登录',
|
'please_login' => '请先登录',
|
||||||
'unauthorized' => '无权访问',
|
'unauthorized' => '无权访问',
|
||||||
|
'user_disabled' => '用户已被禁用',
|
||||||
|
|
||||||
'code_generators' => [
|
'code_generators' => [
|
||||||
'remark1' => '额外参数请参考',
|
'remark1' => '额外参数请参考',
|
||||||
'remark2' => '数据库迁移',
|
'remark2' => '数据库迁移',
|
||||||
'remark3' => '多个参数使用英文逗号分割',
|
'remark3' => '多个参数使用英文逗号分割',
|
||||||
'table_name' => '表名',
|
'table_name' => '表名',
|
||||||
'model_name' => '模型',
|
'model_name' => '模型',
|
||||||
'controller_name' => '控制器',
|
'controller_name' => '控制器',
|
||||||
'service_name' => 'Service',
|
'service_name' => 'Service',
|
||||||
'primary_key' => '主键名称',
|
'primary_key' => '主键名称',
|
||||||
'primary_key_description' => '使用 increments 方法',
|
'primary_key_description' => '使用 increments 方法',
|
||||||
'options' => '可选项',
|
'options' => '可选项',
|
||||||
'create_database_migration' => '创建数据库迁移文件',
|
'create_database_migration' => '创建数据库迁移文件',
|
||||||
'create_table' => '创建数据表',
|
'create_table' => '创建数据表',
|
||||||
'create_model' => '创建模型',
|
'create_model' => '创建模型',
|
||||||
'create_controller' => '创建控制器',
|
'create_controller' => '创建控制器',
|
||||||
'create_service' => '创建Service',
|
'create_service' => '创建Service',
|
||||||
'app_title' => '功能名称',
|
'app_title' => '功能名称',
|
||||||
'column_name' => '字段名',
|
'column_name' => '字段名',
|
||||||
'type' => '类型',
|
'type' => '类型',
|
||||||
'extra_params' => '额外参数',
|
'extra_params' => '额外参数',
|
||||||
'nullable' => '允许空值',
|
'nullable' => '允许空值',
|
||||||
'index' => '索引',
|
'index' => '索引',
|
||||||
'default_value' => '默认值',
|
'default_value' => '默认值',
|
||||||
'comment' => '注释',
|
'comment' => '注释',
|
||||||
'exists_table' => '已有数据表',
|
'exists_table' => '已有数据表',
|
||||||
'generate_code' => '生成代码',
|
'generate_code' => '生成代码',
|
||||||
'expand_more_settings' => '更多设置',
|
'expand_more_settings' => '更多设置',
|
||||||
'collapse_settings' => '收起设置',
|
'collapse_settings' => '收起设置',
|
||||||
'confirm_generate_code' => '确认生成代码?',
|
'confirm_generate_code' => '确认生成代码?',
|
||||||
'preview' => '预览',
|
'preview' => '预览',
|
||||||
'base_info' => '基本信息',
|
'base_info' => '基本信息',
|
||||||
'column_info' => '字段信息',
|
'column_info' => '字段信息',
|
||||||
'route_config' => '路由配置',
|
'route_config' => '路由配置',
|
||||||
'page_config' => '页面配置',
|
'page_config' => '页面配置',
|
||||||
'gen_route_menu' => '生成路由&菜单',
|
'gen_route_menu' => '生成路由&菜单',
|
||||||
'route' => '路由',
|
'route' => '路由',
|
||||||
'menu_name' => '菜单名称',
|
'menu_name' => '菜单名称',
|
||||||
'parent_menu' => '父级菜单',
|
'parent_menu' => '父级菜单',
|
||||||
'menu_icon' => '菜单图标',
|
'menu_icon' => '菜单图标',
|
||||||
'name_label_desc' => 'name和label属性取字段名和注释',
|
'name_label_desc' => 'name和label属性取字段名和注释',
|
||||||
'column_warning' => '如果字段名存在 no、status 会导致 form 回显失败!',
|
'column_warning' => '如果字段名存在 no、status 会导致 form 回显失败!',
|
||||||
'add_column' => '添加字段',
|
'add_column' => '添加字段',
|
||||||
'scope' => '作用域',
|
'scope' => '作用域',
|
||||||
'list_component' => '列表组件',
|
'list_component' => '列表组件',
|
||||||
'list_component_desc' => '列表组件, 默认为 TableColumn',
|
'list_component_desc' => '列表组件, 默认为 TableColumn',
|
||||||
'form_component' => '表单组件',
|
'form_component' => '表单组件',
|
||||||
'form_component_desc' => '表单组件, 默认为 TextControl',
|
'form_component_desc' => '表单组件, 默认为 TextControl',
|
||||||
'detail_component' => '详情组件',
|
'detail_component' => '详情组件',
|
||||||
'detail_component_desc' => '详情组件, 默认为 TextControl',
|
'detail_component_desc' => '详情组件, 默认为 TextControl',
|
||||||
'model_config' => '模型配置',
|
'model_config' => '模型配置',
|
||||||
'file_column' => '文件字段',
|
'file_column' => '文件字段',
|
||||||
'file_column_desc' => '文件字段会自动在模型中添加 获取/修改器 方法',
|
'file_column_desc' => '文件字段会自动在模型中添加 获取/修改器 方法',
|
||||||
'preview_code' => '预览代码',
|
'preview_code' => '预览代码',
|
||||||
'property' => '属性',
|
'property' => '属性',
|
||||||
'property_name' => '属性名称',
|
'property_name' => '属性名称',
|
||||||
'value' => '值',
|
'value' => '值',
|
||||||
'dialog_form' => '弹窗表单',
|
'dialog_form' => '弹窗表单',
|
||||||
'dialog_size' => '弹窗大小',
|
'dialog_size' => '弹窗大小',
|
||||||
'copy_record' => '复制记录',
|
'copy_record' => '复制记录',
|
||||||
'copy_record_description' => '你可以复制后分享到 <a href="https://github.com/Slowlyo/owl-admin/discussions/categories/%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E8%AE%B0%E5%BD%95" target="_blank">Github</a>',
|
'copy_record_description' => '你可以复制后分享到 <a href="https://github.com/Slowlyo/owl-admin/discussions/categories/%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E8%AE%B0%E5%BD%95" target="_blank">Github</a>',
|
||||||
'import_record' => '导入记录',
|
'import_record' => '导入记录',
|
||||||
'import_record_placeholder' => '请输入导入的json记录',
|
'import_record_placeholder' => '请输入导入的json记录',
|
||||||
'import_record_desc' => '你可以在 <a href="https://github.com/Slowlyo/owl-admin/discussions/categories/%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E8%AE%B0%E5%BD%95" target="_blank">Github</a> 找到一些其他人分享的记录',
|
'import_record_desc' => '你可以在 <a href="https://github.com/Slowlyo/owl-admin/discussions/categories/%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E8%AE%B0%E5%BD%95" target="_blank">Github</a> 找到一些其他人分享的记录',
|
||||||
'load_config' => '加载配置',
|
'load_config' => '加载配置',
|
||||||
'load_component_config' => '加载 :c 配置',
|
'load_component_config' => '加载 :c 配置',
|
||||||
'fill' => '填充',
|
'fill' => '填充',
|
||||||
'save_current_config' => '保存当前配置',
|
'save_current_config' => '保存当前配置',
|
||||||
'input_config_name' => '请填写配置名称',
|
'input_config_name' => '请填写配置名称',
|
||||||
'same_name_tips' => '相同名称的配置将会被覆盖',
|
'same_name_tips' => '相同名称的配置将会被覆盖',
|
||||||
|
'save_path_dir' => '主应用',
|
||||||
|
'save_path_select' => '选择目录',
|
||||||
|
'save_path_select_tips' => '可选择项目根目录或插件根目录',
|
||||||
|
'save_path_label_prefix' => '插件 -> ',
|
||||||
],
|
],
|
||||||
|
|
||||||
'admin_users' => '管理员',
|
'admin_users' => '管理员',
|
||||||
'admin_user' => [
|
'admin_user' => [
|
||||||
'avatar' => '头像',
|
'avatar' => '头像',
|
||||||
'name' => '姓名',
|
'name' => '姓名',
|
||||||
'roles' => '角色',
|
'roles' => '角色',
|
||||||
'lock' => '锁定',
|
'search_username' => '搜索用户名/名称',
|
||||||
'edit_password' => '修改密码',
|
'password_confirmation' => '两次输入密码不一致',
|
||||||
'search_username' => '搜索用户名/姓名',
|
'old_password_required' => '请输入原密码',
|
||||||
'password_confirmation' => '两次输入密码不一致',
|
'old_password_error' => '原密码错误',
|
||||||
'old_password_required' => '请输入原密码',
|
|
||||||
'old_password_error' => '原密码错误',
|
|
||||||
'username_already_exists' => '用户名已存在',
|
'username_already_exists' => '用户名已存在',
|
||||||
|
'cannot_delete' => '不可删除超级管理员',
|
||||||
],
|
],
|
||||||
|
|
||||||
'admin_roles' => '角色',
|
'admin_roles' => '角色',
|
||||||
'admin_role' => [
|
'admin_role' => [
|
||||||
'name' => '名称',
|
'name' => '名称',
|
||||||
'slug' => '标识',
|
'slug' => '标识',
|
||||||
'permissions' => '权限',
|
'permissions' => '权限',
|
||||||
'slug_description' => '角色的唯一标识, 不可重复',
|
'slug_description' => '角色的唯一标识, 不可重复',
|
||||||
'name_already_exists' => '角色名称已存在',
|
'name_already_exists' => '角色名称已存在',
|
||||||
'slug_already_exists' => '角色标识已存在',
|
'slug_already_exists' => '角色标识已存在',
|
||||||
'set_permissions' => '设置权限',
|
'set_permissions' => '设置权限',
|
||||||
'set_menus' => '设置菜单',
|
'cannot_delete' => '不可删除超级管理员',
|
||||||
|
'used' => '不可删除正在使用的角色',
|
||||||
],
|
],
|
||||||
|
|
||||||
'admin_permissions' => '权限',
|
'admin_permissions' => '权限',
|
||||||
'admin_permission' => [
|
'admin_permission' => [
|
||||||
'name' => '名称',
|
'name' => '名称',
|
||||||
'slug' => '标识',
|
'slug' => '标识',
|
||||||
'http_method' => '请求方式',
|
'http_method' => '请求方式',
|
||||||
'http_method_description' => '不选则为ANY',
|
'http_method_description' => '不选则为ANY',
|
||||||
'http_path' => '路由',
|
'http_path' => '路由',
|
||||||
'auto_generate' => '自动生成',
|
'auto_generate' => '自动生成',
|
||||||
'auto_generate_confirm' => '权限信息会在 截断权限表&权限菜单关联表 后重新生成, 是否继续操作 ?',
|
'auto_generate_confirm' => '权限信息会在 截断权限表&权限菜单关联表 后重新生成, 是否继续操作 ?',
|
||||||
'parent_id_not_allow' => '父级不允许设置为当前子权限',
|
'parent_id_not_allow' => '父级不允许设置为当前子权限',
|
||||||
'name_already_exists' => '权限名称已存在',
|
'name_already_exists' => '权限名称已存在',
|
||||||
'slug_already_exists' => '权限标识已存在',
|
'slug_already_exists' => '权限标识已存在',
|
||||||
],
|
],
|
||||||
|
|
||||||
'admin_menus' => '菜单',
|
'admin_menus' => '菜单',
|
||||||
'admin_menu' => [
|
'admin_menu' => [
|
||||||
'parent_id' => '父级',
|
'parent_id' => '父级',
|
||||||
'order' => '排序',
|
'order' => '排序',
|
||||||
'title' => '名称',
|
'title' => '名称',
|
||||||
'icon' => '图标',
|
'icon' => '图标',
|
||||||
'icon_description' => '请参考',
|
'icon_description' => '请参考',
|
||||||
'url' => '链接',
|
'url' => '链接',
|
||||||
'visible' => '可见',
|
'visible' => '可见',
|
||||||
'type' => '类型',
|
'type' => '类型',
|
||||||
'api' => '页面Api',
|
'iframe' => 'Iframe',
|
||||||
'api_description' => 'schemaApi, 页面初始化请求的api, 需要与Controller中的queryPath一致',
|
'iframe_description' => '开启后页面将缓存,重新打开时不会重新加载',
|
||||||
'route' => '路由',
|
'api' => '页面Api',
|
||||||
'link' => '外链',
|
'api_description' => 'schemaApi, 页面初始化请求的api, 需要与Controller中的queryPath一致',
|
||||||
'class_name' => '类名',
|
'route' => '路由',
|
||||||
|
'keep_alive' => '缓存页面',
|
||||||
|
'link' => '外链',
|
||||||
|
'class_name' => '类名',
|
||||||
'class_name_description' => '菜单的CSS类名, 一般用于自定义样式',
|
'class_name_description' => '菜单的CSS类名, 一般用于自定义样式',
|
||||||
'show' => '可见',
|
'show' => '可见',
|
||||||
'hide' => '隐藏',
|
'hide' => '隐藏',
|
||||||
'is_home' => '首页',
|
'is_home' => '首页',
|
||||||
'is_home_description' => '在多页签卡模式下,页面标签将固定在左侧',
|
'is_home_description' => '在多页签卡模式下,页面标签将固定在左侧',
|
||||||
'is_full' => '全屏',
|
'is_full' => '全屏',
|
||||||
'is_full_description' => '开启后将隐藏该页面的菜单栏部分',
|
'is_full_description' => '开启后将隐藏该页面的菜单栏部分',
|
||||||
'parent_id_not_allow' => '父级菜单不允许设置为当前子菜单',
|
'parent_id_not_allow' => '父级菜单不允许设置为当前子菜单',
|
||||||
'component' => '组件',
|
'component' => '组件',
|
||||||
'component_desc' => '默认为 amis , 非自定义前端页面请勿修改',
|
'component_desc' => '默认为 amis , 非自定义前端页面请勿修改',
|
||||||
],
|
'url_exists' => '菜单路径重复',
|
||||||
|
|
||||||
'keywords' => [
|
|
||||||
'search_name' => '名称/KEY',
|
|
||||||
'parent_keyword' => '父级关键字',
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'extensions' => [
|
'extensions' => [
|
||||||
'name_invalid' => '无效的扩展名称',
|
'name_invalid' => '无效的扩展名称',
|
||||||
'exists' => '该扩展已存在:',
|
'exists' => '该扩展已存在:',
|
||||||
'menu' => '扩展',
|
'menu' => '扩展',
|
||||||
'page_title' => '扩展',
|
'page_title' => '扩展',
|
||||||
'create' => '创建',
|
'create' => '创建',
|
||||||
'install' => '安装',
|
'install' => '安装',
|
||||||
'create_extension' => '创建扩展',
|
'create_extension' => '创建扩展',
|
||||||
'create_tips' => '创建成功后会在<br><b>:dir</b><br>目录下创建基础的扩展目录结构',
|
'create_tips' => '创建成功后会在<br><b>:dir</b><br>目录下创建基础的扩展目录结构',
|
||||||
'local_install' => '本地安装',
|
'local_install' => '本地安装',
|
||||||
'more_extensions' => '更多扩展',
|
'more_extensions' => '更多扩展',
|
||||||
'setting' => '设置',
|
'setting' => '设置',
|
||||||
'enable' => '启用',
|
'enable' => '启用',
|
||||||
'enable_confirm' => '确定要启用该扩展吗?',
|
'enable_confirm' => '确定要启用该扩展吗?',
|
||||||
'disable' => '禁用',
|
'disable' => '禁用',
|
||||||
'disable_confirm' => '确定要禁用该扩展吗?',
|
'disable_confirm' => '确定要禁用该扩展吗?',
|
||||||
'uninstall' => '卸载',
|
'uninstall' => '卸载',
|
||||||
'uninstall_confirm' => '
|
'uninstall_confirm' => '
|
||||||
<div class="text-danger">
|
<div class="text-danger">
|
||||||
确认卸载该扩展?<br>
|
确认卸载该扩展?<br>
|
||||||
卸载将会删除启用扩展后发布的所有文件及数据库, 且不可找回!!!<br>
|
卸载将会删除启用扩展后发布的所有文件及数据库, 且不可找回!!!<br>
|
||||||
|
|
@ -231,34 +234,73 @@ return [
|
||||||
</div>
|
</div>
|
||||||
',
|
',
|
||||||
'filter_placeholder' => '输入扩展名称',
|
'filter_placeholder' => '输入扩展名称',
|
||||||
'form' => [
|
'form' => [
|
||||||
'create_extension' => '创建扩展',
|
'create_extension' => '创建扩展',
|
||||||
'name' => '名称',
|
'name' => '名称',
|
||||||
'namespace' => '命名空间',
|
'namespace' => '命名空间',
|
||||||
'create_description' => '创建成功后会在 :dir 目录下创建基础的扩展目录结构',
|
'create_description' => '创建成功后会在 :dir 目录下创建基础的扩展目录结构',
|
||||||
],
|
],
|
||||||
'card' => [
|
'card' => [
|
||||||
'author' => '作者',
|
'author' => '作者',
|
||||||
'version' => '版本',
|
'version' => '版本',
|
||||||
'homepage' => '主页',
|
'homepage' => '主页',
|
||||||
'status' => '状态',
|
'status' => '状态',
|
||||||
],
|
],
|
||||||
'status_map' => [
|
'status_map' => [
|
||||||
'enabled' => '已启用',
|
'enabled' => '已启用',
|
||||||
'disabled' => '已禁用',
|
'disabled' => '已禁用',
|
||||||
],
|
],
|
||||||
'validation' => [
|
'validation' => [
|
||||||
'file' => '请选择文件',
|
'file' => '请选择文件',
|
||||||
'invalid_package' => '无效的扩展包',
|
'invalid_package' => '无效的扩展包',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'export' => [
|
'export' => [
|
||||||
'title' => '导出',
|
'title' => '导出',
|
||||||
'all' => '全部',
|
'all' => '全部',
|
||||||
'page' => '本页',
|
'page' => '本页',
|
||||||
'selected_rows' => '选中行',
|
'selected_rows' => '选中行',
|
||||||
'page_no_data' => '本页无数据',
|
'page_no_data' => '本页无数据',
|
||||||
'selected_rows_no_data' => '请选择要导出的数据',
|
'selected_rows_no_data' => '请选择要导出的数据',
|
||||||
'please_install_laravel_excel' => '请先安装 laravel-excel 扩展',
|
'please_install_laravel_excel' => '请先安装 laravel-excel 扩展',
|
||||||
],
|
],
|
||||||
|
'keywords' => [
|
||||||
|
'search_name' => '名称/KEY',
|
||||||
|
'parent_keyword' => '父级关键字',
|
||||||
|
],
|
||||||
|
'articles' => [
|
||||||
|
'id' => '主键ID',
|
||||||
|
'title' => '标题',
|
||||||
|
'content' => '内容',
|
||||||
|
'cover' =>'封面',
|
||||||
|
'category' => '分类',
|
||||||
|
'tags' => '标签',
|
||||||
|
't_ids' => '标签',
|
||||||
|
'published_at' => '定时发布',
|
||||||
|
'published_at_g' => '发布时间',
|
||||||
|
'is_enable' => '显示',
|
||||||
|
'is_recommend' => '推荐',
|
||||||
|
'sort' => '排序',
|
||||||
|
'appendixes' => '附件',
|
||||||
|
'published_at_remark' => '*若未设置发布时间且操作设置为显示,则默认生成发布时间',
|
||||||
|
],
|
||||||
|
'ads' => [
|
||||||
|
'id' => 'ID',
|
||||||
|
'address' => '位置',
|
||||||
|
'resource' =>'内容',
|
||||||
|
'published_at' => '定时发布',
|
||||||
|
'published_at_g' => '发布时间',
|
||||||
|
'is_enable' => '显示',
|
||||||
|
'remark' => '备注',
|
||||||
|
'sort' => '排序',
|
||||||
|
'published_at_remark' => '*若未设置发布时间且操作设置为显示,则默认生成发布时间',
|
||||||
|
'jump_type' => '跳转类型',
|
||||||
|
'jump_config'=>'跳转配置',
|
||||||
|
'jump_config_arr'=>[
|
||||||
|
'web_link' => '网页地址',
|
||||||
|
'app_link' => '应用路径',
|
||||||
|
'mini_id' => '小程序ID',
|
||||||
|
'mini_link'=> '小程序路径'
|
||||||
|
],
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,6 @@ use Illuminate\Support\Facades\Route;
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::redirect('/', '/admin');
|
Route::get('/', function () {
|
||||||
|
return view('welcome');
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue