4
0
Fork 0

添加dcat扩展包

master
vine_liutk 2022-07-27 14:46:34 +08:00
parent 5a3afa371f
commit b5444edf83
26 changed files with 790 additions and 8 deletions

View File

@ -0,0 +1,7 @@
.DS_Store
phpunit.phar
/vendor
composer.phar
composer.lock
*.project
.idea/

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 celaraze
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,55 @@
# Dcat Plus
为 DcatAdmin 后台添加增强配置的功能。修改过程利用 DcatAdmin 自带的 `admin_setting()` 方法实现,不会硬编码修改任何 config 文件或者 .env 文件。
## 安装方式
最新支持 Dcat Admin 2.0.24beta
`composer require celaraze/dcat-extension-plus`
或者在后台扩展中,直接上传本插件的 `.zip` 文件即可。
### 使用
在菜单 `扩展` 中启用扩展后,会自动添加名为 `增强配置` 的菜单。
### 功能
- 站点标题
- 站点 LOGO
- 站点微缩 LOGO
- 站点静态资源 URL
- 调试模式
- 语言切换
- 移除底部授权
- 主题色切换
- 菜单样式切换(默认、分离、水平)
- 表单行操作按钮固定最右
- 快速创建选项:表单可用 `selectCreate()` 字段类型,是 `select` 字段的增强,支持在右侧添加快速创建选项的按钮,异步添加值。
```PHP
$form->selectCreate('department','部门')
->options(Department::class)
->ajax('/api/departments') // 必须使用 api 方式取选项列表,格式同 select 字段的使用方法
->url('/departments/create') // 异步打开的页面,这里是部门创建的页面 url
->required();
```
- 表单详情扩展字段类型:`video`,视频,传入参数和 `image` 相同。
`$show->field('name')->video()`
## 开源协议
Dcat Plus 遵循 MIT 开源协议。

View File

@ -0,0 +1,35 @@
{
"name": "celaraze/dcat-extension-plus",
"description": "增强 DcatAdmin 的使用体验。",
"alias": "Dcat 增强工具",
"type": "library",
"keywords": [
"dcat-admin",
"extension"
],
"homepage": "https://github.com/celaraze/dcat-extension-plus",
"license": "MIT",
"authors": [
{
"name": "Celaraze",
"email": "celaraze@qq.com"
}
],
"require": {
"php": ">=7.3.0",
"dcat/laravel-admin": "~2.0"
},
"autoload": {
"psr-4": {
"Celaraze\\DcatPlus\\": "src/"
}
},
"extra": {
"dcat-admin": "Celaraze\\DcatPlus\\ServiceProvider",
"laravel": {
"providers": [
"Celaraze\\DcatPlus\\ServiceProvider"
]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,15 @@
<?php
return [
'site_url' => '站点域名',
'site_title' => '站点标题',
'site_logo_text' => 'LOGO文字',
'site_logo' => 'LOGO',
'site_logo_mini' => 'LOGO微缩',
'site_debug' => '调试模式',
'footer_remove' => '移除底部授权',
'select_create' => '快速创建选项',
'theme_color' => '主题色',
'sidebar_style' => '菜单样式',
'site_lang' => '语言',
'grid_row_actions_right' => '表单行操作按钮最右'
];

View File

@ -0,0 +1,5 @@
<?php
return [
'dcat_plus' => '增强配置'
];

View File

@ -0,0 +1,42 @@
<div class="{{$viewClass['form-group']}}">
<div class="{{ $viewClass['label'] }} control-label">
<span>{!! $label !!}</span>
</div>
<div class="{{$viewClass['field']}}">
<div class="input-group">
@include('admin::form.error')
<input type="hidden" name="{{$name}}"/>
<select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}" {!! $attributes !!} >
<option value=""></option>
@if($groups)
@foreach($groups as $group)
<optgroup label="{{ $group['label'] }}">
@foreach($group['options'] as $select => $option)
<option value="{{$select}}" {{ $select == $value ?'selected':'' }}>{{$option}}</option>
@endforeach
</optgroup>
@endforeach
@else
@foreach($options as $select => $option)
<option
value="{{$select}}" {{ Dcat\Admin\Support\Helper::equal($select, $value) ?'selected':'' }}>{{$option}}</option>
@endforeach
@endif
</select>
<div class="input-group-append">
{!! $createDialog !!}
</div>
</div>
@include('admin::form.help-block')
</div>
</div>
@include('admin::form.select-script')

View File

@ -0,0 +1,64 @@
<?php
namespace Celaraze\DcatPlus\Extensions\Form;
use Celaraze\DcatPlus\Support;
use Dcat\Admin\Form;
use Dcat\Admin\Form\Field\Select;
use Dcat\Admin\Support\Helper;
class SelectCreate extends Select
{
protected $view = 'celaraze.dcat-extension-plus::select_create';
protected $url = null;
/**
* {@inheritdoc}
*/
public function render()
{
$this->addDefaultConfig([
'allowClear' => true,
'placeholder' => [
'id' => '',
'text' => $this->placeholder(),
],
]);
$this->formatOptions();
$this->addVariables([
'options' => $this->options,
'groups' => $this->groups,
'configs' => $this->config,
'cascadeScript' => $this->getCascadeScript(),
'createDialog' => $this->build()
]);
$this->attribute('data-value', implode(',', Helper::array($this->value())));
return parent::render();
}
protected function build(): string
{
Form::dialog(Support::trans('main.select_create'))
->click('.create-form')
->url($this->url)
->width('1200px')
->height('800px');
$text = Support::trans('main.select_create');
return "<span class='btn btn-primary create-form' data-url='$this->url'> $text </span>";
}
public function url($url): SelectCreate
{
$this->url = $url;
return $this;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Celaraze\DcatPlus\Extensions\Show;
use Dcat\Admin\Show\AbstractField;
use Illuminate\Support\Facades\Storage;
class Video extends AbstractField
{
public function render($server = '', $width = 200, $height = 200)
{
$items = json_decode($this->value, true);
$return = '';
foreach ($items as $item) {
if (url()->isValidUrl($item)) {
$src = $item;
} elseif ($server) {
$src = rtrim($server, '/') . '/' . ltrim($item, '/');
} else {
$disk = config('admin.upload.disk');
if (config("filesystems.disks.{$disk}")) {
$src = Storage::disk($disk)->url($item);
} else {
return '';
}
}
$return .= "<video src='$src' autoplay loop style='max-width:{$width}px;max-height:{$height}px'></video> &nbsp;";
}
return $return;
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace Celaraze\DcatPlus\Forms;
use Celaraze\DcatPlus\Support;
use Dcat\Admin\Widgets\Form;
class DcatPlusSiteForm extends Form
{
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
admin_setting($input);
return $this
->response()
->success('站点配置更新成功!')
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->url('site_url', Support::trans('main.site_url'))
->help('站点域名决定了静态资源(头像、图片等)的显示路径,可以包含端口号,例如 http://chemex.it:8000 。')
->default(admin_setting('site_url'));
$this->text('site_title', Support::trans('main.site_title'))
->default(admin_setting('site_title'));
$this->text('site_logo_text', Support::trans('main.site_logo_text'))
->help('文本LOGO显示的优先度低于图片当没有上传图片作为LOGO时此项将生效。')
->default(admin_setting('site_logo_text'));
$this->image('site_logo', Support::trans('main.site_logo'))
->autoUpload()
->uniqueName()
->default(admin_setting('site_logo'));
$this->image('site_logo_mini', Support::trans('main.site_logo_mini'))
->autoUpload()
->uniqueName()
->default(admin_setting('site_logo_mini'));
$this->switch('site_debug', Support::trans('main.site_debug'))
->help('开启 debug 模式后将会显示异常捕获信息,关闭则只返回 500 状态码。')
->default(admin_setting('site_debug'));
$this->radio('site_lang', Support::trans('main.site_lang'))
->options([
'zh_CN' => '中文(简体)',
'en' => 'English'
])
->default(admin_setting('site_lang'));
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Celaraze\DcatPlus\Forms;
use Celaraze\DcatPlus\ServiceProvider;
use Celaraze\DcatPlus\Support;
use Dcat\Admin\Widgets\Form;
class DcatPlusUIForm extends Form
{
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
admin_setting($input);
return $this
->response()
->success('站点配置更新成功!')
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->switch('footer_remove', Support::trans('main.footer_remove'))
->default(admin_setting('footer_remove'));
$defaultColors = [
'default' => '墨蓝',
'blue' => '蓝',
'blue-light' => '亮蓝',
'green' => '墨绿',
];
foreach (explode(",", ServiceProvider::setting('additional_theme_colors')) as $value) {
if (!empty($value)) {
[$k, $v] = explode(":", $value);
$defaultColors[$k] = $v;
}
}
$this->radio('theme_color', Support::trans('main.theme_color'))
->options($defaultColors)
->default(admin_setting('theme_color'));
$this->radio('sidebar_style', Support::trans('main.sidebar_style'))
->options([
'default' => '默认',
'sidebar-separate' => '菜单分离',
'horizontal_menu' => '水平菜单'
])
->default(admin_setting('sidebar_style'));
$this->switch('grid_row_actions_right', Support::trans('main.grid_row_actions_right'))
->help('启用后表格行操作按钮将永远贴着最右侧。')
->default(admin_setting('grid_row_actions_right'));
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Celaraze\DcatPlus\Http\Controllers;
use Celaraze\DcatPlus\Forms\DcatPlusSiteForm;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Widgets\Tab;
use Illuminate\Routing\Controller;
class DcatPlusSiteController extends Controller
{
public function index(Content $content): Content
{
return $content->header('增强配置')
->description('提供了一些对站点增强的配置')
->body(function (Row $row) {
$tab = new Tab();
$tab->add('站点配置', new DcatPlusSiteForm(), true);
$tab->addLink('UI优化', admin_route('dcat-plus.ui.index'));
$row->column(12, $tab->withCard());
});
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Celaraze\DcatPlus\Http\Controllers;
use Celaraze\DcatPlus\Forms\DcatPlusUIForm;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Widgets\Tab;
use Illuminate\Routing\Controller;
class DcatPlusUIController extends Controller
{
public function index(Content $content): Content
{
return $content->header('增强配置')
->description('提供了一些对站点增强的配置')
->body(function (Row $row) {
$tab = new Tab();
$tab->addLink('站点配置', admin_route('dcat-plus.site.index'));
$tab->add('UI优化', new DcatPlusUIForm(), true);
$row->column(12, $tab->withCard());
});
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Celaraze\DcatPlus\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
/**
* Class AfterInjectDcatPlus
* @package Celaraze\DcatPlus\Http\Middleware
*/
class AfterInjectDcatPlus
{
/**
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
return $next($request);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Celaraze\DcatPlus\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
/**
* Class BeforeInjectDcatPlus
* @package Celaraze\DcatPlus\Http\Middleware
*/
class BeforeInjectDcatPlus
{
/**
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
return $next($request);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Celaraze\DcatPlus\Http\Middleware;
use Celaraze\DcatPlus\Support;
use Closure;
use Illuminate\Http\Request;
class MiddleInjectDcatPlus
{
public function handle(Request $request, Closure $next)
{
$support = new Support();
$support->initConfig();
$support->gridRowActionsRight();
$support->injectFields();
$support->footerRemove();
return $next($request);
}
}

View File

@ -0,0 +1,16 @@
<?php
use Celaraze\DcatPlus\Http\Controllers\DcatPlusSiteController;
use Celaraze\DcatPlus\Http\Controllers\DcatPlusUIController;
use Illuminate\Support\Facades\Route;
Route::get('/dcat-plus/site', [DcatPlusSiteController::class, 'index'])
->name('dcat-plus.site.index');
Route::get('/dcat-plus/ui', [DcatPlusUIController::class, 'index'])
->name('dcat-plus.ui.index');

View File

@ -0,0 +1,56 @@
<?php
namespace Celaraze\DcatPlus;
use Celaraze\DcatPlus\Http\Middleware\AfterInjectDcatPlus;
use Celaraze\DcatPlus\Http\Middleware\BeforeInjectDcatPlus;
use Celaraze\DcatPlus\Http\Middleware\MiddleInjectDcatPlus;
use Dcat\Admin\Extend\ServiceProvider as BaseServiceProvider;
/**
* Class ServiceProvider
* @package Celaraze\DcatPlus
*/
class ServiceProvider extends BaseServiceProvider
{
protected $js = [
'js/index.js',
];
protected $css = [
'css/index.css',
];
protected $middleware = [
'before' => [
BeforeInjectDcatPlus::class,
],
'middle' => [
MiddleInjectDcatPlus::class,
],
'after' => [
AfterInjectDcatPlus::class,
]
];
protected $menu = [
[
'title' => 'Dcat Plus',
'uri' => 'dcat-plus/site',
'icon' => 'feather icon-settings'
]
];
public function register()
{
//
}
public function settingForm()
{
return new Setting($this);
}
public function init()
{
parent::init();
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Celaraze\DcatPlus;
use Dcat\Admin\Extend\Setting as Form;
class Setting extends Form
{
public function form()
{
$this->text('additional_theme_colors', 'Additional Theme Colors')
->help("cssname1:Title1,cssname2:Title2");
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace Celaraze\DcatPlus;
use App\Admin\Extensions\Form\SelectCreate;
use Celaraze\DcatPlus\Extensions\Show\Video;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Show;
use Illuminate\Support\Facades\Storage;
class Support
{
/**
* 快速翻译(为了缩短代码量)
* @param $string
* @return array|string|null
*/
public static function trans($string)
{
return ServiceProvider::trans($string);
}
/**
* 初始化配置注入
*/
public function initConfig()
{
/**
* 处理站点LOGO自定义
*/
if (empty(admin_setting('site_logo'))) {
$logo = admin_setting('site_logo_text');
} else {
$logo = Storage::disk(config('admin.upload.disk'))->url(admin_setting('site_logo'));
$logo = "<img src='$logo'>";
}
/**
* 处理站点LOGO-MINI自定义
*/
if (empty(admin_setting('site_logo_mini'))) {
$logo_mini = admin_setting('site_logo_text');
} else {
$logo_mini = Storage::disk(config('admin.upload.disk'))->url(admin_setting('site_logo_mini'));
$logo_mini = "<img src='$logo_mini'>";
}
/**
* 处理站点名称
*/
$horizontal_menu = false;
if (empty(admin_setting('site_url'))) {
$site_url = 'http://localhost';
} else {
$site_url = admin_setting('site_url');
}
if (empty(admin_setting('site_debug'))) {
$site_debug = true;
} else {
$site_debug = admin_setting('site_debug');
}
if (empty(admin_setting('theme_color'))) {
$theme_color = 'blue-light';
} else {
$theme_color = admin_setting('theme_color');
}
if (empty(admin_setting('sidebar_style'))) {
$sidebar_style = 'default';
} else {
$sidebar_style = admin_setting('sidebar_style');
if ($sidebar_style == 'horizontal_menu') {
$horizontal_menu = true;
}
}
/**
* 复写admin站点配置
*/
config([
'app.url' => $site_url,
'app.debug' => (bool)$site_debug,
'app.locale' => admin_setting('site_lang'),
'app.fallback_locale' => admin_setting('site_lang'),
'admin.title' => admin_setting('site_title'),
'admin.logo' => $logo,
'admin.logo-mini' => $logo_mini,
'admin.layout.color' => $theme_color,
'admin.layout.body_class' => $sidebar_style,
'admin.layout.horizontal_menu' => $horizontal_menu
]);
}
/**
* 注入字段.
*/
public function injectFields()
{
Form::extend('selectCreate', SelectCreate::class);
Show\Field::extend('video', Video::class);
}
/**
* 底部授权移除.
*/
public function footerRemove()
{
if (admin_setting('footer_remove')) {
Admin::style(
<<<'CSS'
.main-footer {
display: none;
}
CSS
);
}
}
/**
* 行操作按钮最右.
*/
public function gridRowActionsRight()
{
if (admin_setting('grid_row_actions_right')) {
Admin::style(
<<<CSS
.grid__actions__{
width: 20%;
text-align: right;
}
CSS
);
}
}
}

View File

@ -0,0 +1,47 @@
<?php
return [
'1.0.0' => [
'原始版本发布',
],
'1.0.1' => [
'增加调试模式开关 & 侧栏子菜单缩进增加',
],
'1.0.2' => [
'扩展表单字段 selectCreate 为 select 字段的升级版,支持快速创建。',
],
'1.0.3' => [
'增加扩展图标和别名。',
],
'1.0.4' => [
'增加表单提交预处理过滤防止XSS攻击。',
],
'1.0.5' => [
'优化表单提交预处理过滤,不再依赖第三方包。',
],
'1.0.6' => [
'selectCreate组件的颜色改为主题色。',
'UI增加表格行操作按钮紧贴最右侧。'
],
'1.0.7' => [
'支持DcatAdmin 2.0.18beta。',
'暂时移除侧栏菜单子菜单缩进(不兼容)。',
'增加水平菜单选项。',
'原先的头部块状显示改为边距优化'
],
'1.0.8' => [
'提供了自定义颜色的支持入口',
],
'1.0.9' => [
'移除HTML、JS过滤',
'移除部分UI优化'
],
'1.1.0' => [
'修复debug配置无效的问题',
'自动注入扩展字段',
'移除了一些无用的配置'
],
'1.1.1' => [
'增加详情页视频扩展字段',
],
];

View File

@ -542,7 +542,7 @@ class Admin
$jsVariables['pjax_container_selector'] = $pjaxId ? ('#'.$pjaxId) : '';
$jsVariables['token'] = csrf_token();
$jsVariables['lang'] = ($lang = __('admin.client')) ? array_merge($lang, $jsVariables['lang'] ?? []) : [];
$jsVariables['lang'] = ($lang = is_array(__('admin.client')) ? __('admin.client'): []) ? array_merge($lang, $jsVariables['lang'] ?? []) : [];
$jsVariables['colors'] = static::color()->all();
$jsVariables['dark_mode'] = static::isDarkMode();
$jsVariables['sidebar_dark'] = config('admin.layout.sidebar_dark') || ($sidebarStyle === 'dark');

View File

@ -391,13 +391,13 @@ abstract class ServiceProvider extends LaravelServiceProvider
*/
public function registerRoutes($callback)
{
$this->loadRoutesFrom($callback);
// Admin::app()->routes(function ($router) use ($callback) {
// $router->group([
// 'prefix' => config('admin.route.prefix'),
// 'middleware' => config('admin.route.middleware'),
// ], $callback);
// });
// $this->loadRoutesFrom($callback);
Admin::app()->routes(function ($router) use ($callback) {
$router->group([
'prefix' => config('admin.route.prefix'),
'middleware' => config('admin.route.middleware'),
], $callback);
});
}
/**