Compare commits
19 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
ee02f1b67d | |
|
|
38b3e1e1bb | |
|
|
66dba4bf19 | |
|
|
9183e81cc3 | |
|
|
bd03c095fc | |
|
|
158f3f9b58 | |
|
|
2ddbaff1b8 | |
|
|
361ff11542 | |
|
|
5f3683ec2b | |
|
|
6998832612 | |
|
|
8040f128f1 | |
|
|
0f60563460 | |
|
|
f45495b6fb | |
|
|
6ba5088785 | |
|
|
bc66a76cc8 | |
|
|
56ee1dcb4d | |
|
|
11bcca4213 | |
|
|
a32043e86a | |
|
|
b3418d033c |
70
README.md
70
README.md
|
|
@ -100,3 +100,73 @@ protected function renderBack()
|
|||
HTML;
|
||||
}
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
- config/app.php
|
||||
|
||||
```php
|
||||
return [
|
||||
'timezone' => env('TIMEZONE', 'Asia/Chongqing'),
|
||||
'locale' => 'zh_CN',
|
||||
];
|
||||
```
|
||||
|
||||
- config/auth.php
|
||||
|
||||
```php
|
||||
return [
|
||||
'api' => [
|
||||
'driver' => 'sanctum',
|
||||
'provider' => 'users',
|
||||
],
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => Peidikeji\User\Models\User::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
- app\Exceptions\Handler.php
|
||||
|
||||
```php
|
||||
public function register()
|
||||
{
|
||||
$this->renderable(function (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e, Request $request) {
|
||||
if ($request->ajax()) {
|
||||
return response()->json(['code' => 404, 'message' => $e->getMessage(), 'data' => null], 200);
|
||||
}
|
||||
});
|
||||
$this->renderable(function (\Illuminate\Validation\ValidationException $e, Request $request) {
|
||||
if ($request->ajax()) {
|
||||
$errors = $e->validator->errors();
|
||||
return response()->json(['code' => 422, 'message' => $errors->first(), 'data' => $errors], 200);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
- app\Http\Controllers\Controller.php
|
||||
|
||||
```php
|
||||
use Dcat\Admin\Traits\JsonResponse;
|
||||
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use JsonResponse;
|
||||
}
|
||||
```
|
||||
|
||||
- app\Providers\RouteServiceProvider.php
|
||||
|
||||
```php
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('sms', function (Request $request) {
|
||||
return Limit::perMinute(1)->by($request->input('phone'));
|
||||
});
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ return [
|
|||
| If your page is going to be accessed via https, set it to `true`.
|
||||
|
|
||||
*/
|
||||
'https' => env('ADMIN_HTTPS', false),
|
||||
'https' => \Illuminate\Support\Str::startsWith(env('APP_URL'), 'https://'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
.DS_Store
|
||||
phpunit.phar
|
||||
/vendor
|
||||
composer.phar
|
||||
composer.lock
|
||||
*.project
|
||||
.idea/
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Dcat Admin Extension
|
||||
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"name": "peidikeji/article",
|
||||
"alias": "文章管理",
|
||||
"description": "文章管理",
|
||||
"type": "library",
|
||||
"keywords": ["dcat-admin", "extension"],
|
||||
"homepage": "https://github.com/peidikeji/article",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "liutk",
|
||||
"email": "961510893@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Peidikeji\\Article\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"dcat-admin": "Peidikeji\\Article\\ArticleServiceProvider",
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Peidikeji\\Article\\ArticleServiceProvider"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'ArticleCategory' => '文章分类',
|
||||
'article-categories'=> '文章分类',
|
||||
],
|
||||
'fields' => [
|
||||
'parent_id' => '上级',
|
||||
'name' => '名称',
|
||||
'key' => 'KEY',
|
||||
'is_enable' => '可用状态',
|
||||
'is_recommend' => '推荐状态',
|
||||
'sort' => '排序',
|
||||
'remarks' => '备注'
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'Article' => '文章管理',
|
||||
'articles'=> '文章管理',
|
||||
],
|
||||
'fields' => [
|
||||
'title' => '标题',
|
||||
'sub_title' => '副标题',
|
||||
'author' => '作者',
|
||||
'author_name' => '作者',
|
||||
'category_id' => '分类',
|
||||
'category'=>[
|
||||
'name' => '分类',
|
||||
],
|
||||
'admin_user_id' => '创建人',
|
||||
'cover' => '封面',
|
||||
'media_path' => '媒体资源',
|
||||
'is_recommend' => '推荐状态',
|
||||
'content' => '内容',
|
||||
'is_enable' => '可用状态',
|
||||
'sort' => '排序',
|
||||
'published_at' => '发布时间',
|
||||
'remarks' => '备注',
|
||||
'like_nums' => '点赞数',
|
||||
'read_nums' => '浏览数'
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article;
|
||||
|
||||
use Dcat\Admin\Extend\ServiceProvider;
|
||||
use Dcat\Admin\Admin;
|
||||
|
||||
class ArticleServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
// public function settingForm()
|
||||
// {
|
||||
// return new Setting($this);
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article\Http\Controllers;
|
||||
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Admin;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Peidikeji\Article\Models\Article;
|
||||
use Dcat\Admin\Grid\Column as GridColumn;
|
||||
use Peidikeji\Article\Models\ArticleCategory;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
|
||||
class ArticleCategoryController extends AdminController
|
||||
{
|
||||
protected $translation = 'peidikeji.article::article-category';
|
||||
|
||||
protected $extDefaults = [];//例如:['key1'=>'']
|
||||
|
||||
public function grid(){
|
||||
return Grid::make(new ArticleCategory(), function ($grid) {
|
||||
$grid->disableRowSelector();
|
||||
|
||||
$grid->model()->sort();
|
||||
$grid->column('name')->tree(true, false);
|
||||
$grid->column('key');
|
||||
$grid->column('sort')->editable(['mask' => '{alias:\'numeric\',min:0,max:999}']);
|
||||
$grid->column('is_enable')->if(function(){
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.article_categories.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
$grid->column('is_recommend')
|
||||
->if(function(){
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.article_categories.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
|
||||
$grid->model()->orderBy('sort', 'desc');
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->setDialogFormDimensions('50%', '70%');
|
||||
$grid->disableCreateButton(!(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.article_categories.create')));
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView();
|
||||
$actions->disableEdit();
|
||||
$actions->quickEdit(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.article_categories.edit'));
|
||||
$actions->delete(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.article_categories.destroy'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->expand();
|
||||
$filter->like('name')->width(3);
|
||||
$filter->like('key')->width(3);
|
||||
$filter->equal('parent_id', '上级分类')->select(ArticleCategory::selectOptions())->width(3);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return Form::make(new ArticleCategory(), function (Form $form) {
|
||||
|
||||
$form->select('parent_id')->help('不选默认为顶级')->options(ArticleCategory::selectOptions())->default(0);
|
||||
$form->text('name')->required();
|
||||
$unique = Rule::unique((new ArticleCategory())->getTable(), 'key');
|
||||
if ($form->isCreating()) {
|
||||
$form->text('key')->help('不填则自动生成, 唯一')->rules([$unique]);
|
||||
} else {
|
||||
$form->text('key')->required()->help('唯一')->rules([$unique->ignore($form->getKey())]);
|
||||
}
|
||||
$form->number('sort')
|
||||
->min(0)
|
||||
->default(0)
|
||||
->help('数值越大, 越靠前');
|
||||
$form->switch('is_enable')->default(0);
|
||||
$form->switch('is_recommend')->default(0);
|
||||
$form->text('remarks');
|
||||
$form->hidden('level')->default(1);
|
||||
|
||||
$form->keyValue('ext', '扩展字段')->default($this->extDefaults)->setKeyLabel('键名')->setValueLabel('键值')
|
||||
->saving(function($v){
|
||||
return json_encode($v ?? []);
|
||||
});
|
||||
|
||||
$controller = $this;
|
||||
$form->saving(function (Form $form) use ($controller) {
|
||||
if ($form->isCreating() && !$form->key) {
|
||||
$form->key = $controller->generateKey();
|
||||
}
|
||||
});
|
||||
|
||||
$form->saved(function (Form $form) {
|
||||
if ($form->isEditing() && $form->input('is_enable') !== null && $form->input('is_enable') != $form->model()->is_enable) {
|
||||
//处理分类子级状态同步(层级)父级
|
||||
ArticleCategory::where('path', 'like', "%-".$form->model()->id."-%")->update(['is_enable' => $form->is_enable]);
|
||||
//处理父级状态
|
||||
if($form->is_enable){
|
||||
//如果状态是开启,判断(层级)父级是否开启
|
||||
$exPath = trim('-', $form->model()->path);
|
||||
$parentIds = $exPath ? explode('-', $exPath) : [];
|
||||
if($parentIds){
|
||||
ArticleCategory::whereIn('id', $parentIds)->update(['is_enable' => $form->is_enable]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$form->deleting(function (Form $form) {
|
||||
$hasArticles = Article::where('category_id', $form->getKey())->exists();
|
||||
if ($hasArticles) {
|
||||
return $form->response()->error('需要先删除该分类下的文章');
|
||||
}
|
||||
$hasChildren = ArticleCategory::where('parent_id', $form->getKey())->exists();
|
||||
if ($hasChildren) {
|
||||
return $form->response()->error('需要先删除该分类下的子级');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected function generateKey()
|
||||
{
|
||||
do {
|
||||
$id = ArticleCategory::max('id') + 1;
|
||||
$key = 'category-' . $id;
|
||||
} while (ArticleCategory::where('key', $key)->exists());
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Admin;
|
||||
use Peidikeji\Article\Models\Article;
|
||||
use Dcat\Admin\Grid\Column as GridColumn;
|
||||
use Peidikeji\Article\Models\ArticleCategory;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
|
||||
class ArticleController extends AdminController
|
||||
{
|
||||
protected $translation = 'peidikeji.article::article';
|
||||
|
||||
protected $extDefaults = [];//例如:['key1'=>'']
|
||||
|
||||
public function grid(){
|
||||
return Grid::make(Article::with(['category', 'adminUser']), function ($grid) {
|
||||
$grid->disableRowSelector();
|
||||
$grid->column('category.name')->label();
|
||||
$grid->column('title')->display(function ($v) {
|
||||
if (mb_strlen($v) > 20) {
|
||||
return mb_substr($v, 0, 17) . '...';
|
||||
} else {
|
||||
return $v;
|
||||
}
|
||||
});
|
||||
$grid->column('cover')->image(100, 100);
|
||||
$grid->column('author_name')->display(function (){
|
||||
return $this->author_name;
|
||||
});
|
||||
$grid->column('like_nums');
|
||||
$grid->column('read_nums');
|
||||
$grid->column('sort')->editable(['mask' => '{alias:\'numeric\',min:0,max:999}']);
|
||||
$grid->column('published_at');
|
||||
$grid->column('is_enable')->if(function(){
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.articles.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
$grid->column('is_recommend')->if(function(){
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.articles.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
|
||||
// $grid->column('remarks');
|
||||
|
||||
$grid->model()->orderBy('sort', 'desc');
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
|
||||
$grid->setDialogFormDimensions('50%', '70%');
|
||||
$grid->disableCreateButton(!(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.articles.create')));
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView();
|
||||
$actions->disableEdit();
|
||||
$actions->quickEdit(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.articles.edit'));
|
||||
$actions->delete(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.articles.destroy'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->expand();
|
||||
$filter->equal('category_id', '分类')->select(ArticleCategory::selectOptions())->width(3);
|
||||
$filter->like('title')->width(3);
|
||||
$filter->between('published_at')->datetime()->width(7);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return Form::make(new Article(), function($form){
|
||||
$form->select('category_id')->options(ArticleCategory::selectOptions(false));
|
||||
$form->text('title')->required();
|
||||
$form->text('sub_title');
|
||||
$form->image('cover')
|
||||
->uniqueName()
|
||||
->move('articles/'.Carbon::now()->toDateString())
|
||||
->saveFullUrl()
|
||||
->autoSave(false)
|
||||
->autoUpload()
|
||||
->removable(false)//禁止用户从页面点击删除服务器上的文件,可以实现图片覆盖上传效果
|
||||
->retainable();
|
||||
$form->text('author');
|
||||
$form->file('media_path')->chunked()
|
||||
->accept('mp4,mp3', 'mp4/*,mp3/*')
|
||||
->move('articles-media/'.Carbon::now()->toDateString())
|
||||
->maxSize(204800)//默认最大200M
|
||||
->saveFullUrl()
|
||||
->removable(false)
|
||||
->autoUpload()->autoSave(false);
|
||||
|
||||
$form->datetime('published_at');
|
||||
$form->switch('is_enable')->default(0);
|
||||
$form->switch('is_recommend')->default(0);
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
$form->text('remarks');
|
||||
|
||||
$form->keyValue('ext', '扩展字段')->default($this->extDefaults)->setKeyLabel('键名')->setValueLabel('键值')
|
||||
->saving(function($v){
|
||||
return json_encode($v ?? []);
|
||||
});
|
||||
|
||||
$form->editor('content')->options([
|
||||
'plugins' => [
|
||||
'image',
|
||||
'lists',
|
||||
'preview',
|
||||
'fullscreen',
|
||||
'table',
|
||||
],
|
||||
'toolbar' => [
|
||||
'undo redo | preview fullscreen | styleselect | fontsizeselect bold italic underline strikethrough forecolor backcolor | image blockquote removeformat codesample',
|
||||
'alignleft aligncenter alignright alignjustify| indent outdent bullist numlist table subscript superscript | code',
|
||||
]
|
||||
])->height('800');
|
||||
Admin::style(<<<css
|
||||
.tox.tox-silver-sink.tox-tinymce-aux{
|
||||
z-index:99999999;
|
||||
}
|
||||
css);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Peidikeji\Article\Http\Controllers;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
if(! Route::has('dcat.admin.article_categories.index')){
|
||||
Route::resource('article-categories', Controllers\ArticleCategoryController::class)->names('article_categories');
|
||||
}
|
||||
|
||||
if(! Route::has('dcat.admin.articles.index')){
|
||||
Route::resource('articles', Controllers\ArticleController::class);
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article\Models;
|
||||
|
||||
use Dcat\Admin\Admin;
|
||||
use EloquentFilter\Filterable;
|
||||
use Dcat\Admin\Models\Administrator;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* @method static \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
class Article extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = [
|
||||
'author', 'admin_user_id', 'title', 'sub_title', 'cover', 'content',
|
||||
'is_recommend', 'is_enable', 'sort', 'published_at',
|
||||
'remarks', 'category_id', 'category_path',
|
||||
'like_nums', 'read_nums', 'media_path'
|
||||
];
|
||||
|
||||
protected $dates = ['published_at'];
|
||||
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::saving(function ($model) {
|
||||
$model->admin_user_id = Admin::user()->id;
|
||||
// 添加/修改分类时, 更新 category_path
|
||||
if ($model->isDirty('category_id')) {
|
||||
$model->category_path = ArticleCategory::where('id', $model->category_id)->value('path') . $model->category_id . '-';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(ArticleCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
public function adminUser()
|
||||
{
|
||||
return $this->belongsTo(Administrator::class, 'admin_user_id');
|
||||
}
|
||||
|
||||
public function getAuthorNameAttribute()
|
||||
{
|
||||
return $this->attributes['author'] ?? ($this->attributes['admin_user_id'] ? (Administrator::find($this->attributes['admin_user_id'])?->name ?? '未知') : '未知');
|
||||
}
|
||||
|
||||
//public function image(): Attribute
|
||||
//{
|
||||
// return Attribute::make(
|
||||
// get: fn ($v) => $v ?: 'https://via.placeholder.com/640x480.png',
|
||||
// set: fn ($v) => $v ?: 'https://via.placeholder.com/640x480.png',
|
||||
// );
|
||||
//}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->orderBy('sort', 'desc')->latest('published_at')->latest('id');
|
||||
}
|
||||
|
||||
public function scopePublish($q)
|
||||
{
|
||||
return $q->where('published_at', '<=', now());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article\Models;
|
||||
|
||||
use Dcat\Admin\Traits\ModelTree;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ArticleCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use ModelTree;
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = ['key', 'name', 'is_recommend', 'is_enable', 'sort', 'level', 'path', 'parent_id', 'remarks'];
|
||||
|
||||
protected $titleColumn = 'name';
|
||||
protected $orderColumn = 'sort';
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::saving(function ($category) {
|
||||
// 如果创建的是一个根类目
|
||||
if (!$category->parent_id) {
|
||||
// 将层级设为 1
|
||||
$category->level = 1;
|
||||
// 将 path 设为 -
|
||||
$category->path = '-';
|
||||
} else {
|
||||
// 将层级设为父类目的层级 + 1
|
||||
$category->level = $category->parent->level + 1;
|
||||
// 将 path 值设为父类目的 path 追加父类目 ID 以及最后跟上一个 - 分隔符
|
||||
$category->path = $category->parent->path . $category->parent_id . '-';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function selectOptions($root = true)
|
||||
{
|
||||
$rootText = '顶级';
|
||||
|
||||
$options = (new static())->withQuery(function ($q) {
|
||||
return $q->sort();
|
||||
})->buildSelectOptions();
|
||||
|
||||
return collect($options)->when($root, fn ($c) => $c->prepend($rootText, 0))->all();
|
||||
}
|
||||
|
||||
public function articles()
|
||||
{
|
||||
return $this->hasMany(Article::class, 'category_id');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(static::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(static::class, 'parent_id')->sort();
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->orderBy('sort', 'desc')->orderBy('id');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Article;
|
||||
|
||||
use Dcat\Admin\Extend\Setting as Form;
|
||||
|
||||
class Setting extends Form
|
||||
{
|
||||
public function form()
|
||||
{
|
||||
$this->text('key1')->required();
|
||||
$this->text('key2')->required();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddMediaToArticleTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasTable('articles')) {
|
||||
Schema::table('articles', function (Blueprint $table) {
|
||||
$table->string('media_path')->nullable()->comment('资源地址');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('articles', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn('media_path');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddnumToArticleTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasTable('articles')) {
|
||||
Schema::table('articles', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('like_nums')->default(0)->comment('点赞数');
|
||||
$table->unsignedBigInteger('read_nums')->default(0)->comment('阅读数');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('articles', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['like_nums', 'read_nums']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Dcat\Admin\Models\Permission;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class ArticlePermissionSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$permissions = [
|
||||
'article_categories' => ['name' => '文章分类管理', 'curd' => true],
|
||||
'articles' => ['name' => '文章管理', 'curd' => true],
|
||||
];
|
||||
$this->createPermissionData($permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入权限
|
||||
*
|
||||
* @param array $permissions
|
||||
* @param string $key
|
||||
* @param integer $pId
|
||||
*/
|
||||
public function createPermissionData(array $permissions, string $key = '', int $pId = 0)
|
||||
{
|
||||
$curdArr = [
|
||||
'index' => '列表',
|
||||
'create' => '新增',
|
||||
'edit' => '修改',
|
||||
'destroy' => '删除',
|
||||
'show' => '详情',
|
||||
];
|
||||
foreach ($permissions as $slug => $permission) {
|
||||
//是否已存在该权限
|
||||
$slugKey = 'dcat.admin.' . ($key ? $key . '.' . $slug : $slug);
|
||||
|
||||
|
||||
$pper = Permission::updateOrCreate(['slug' => $slugKey], ['name' => is_string($permission) ? $permission : $permission['name'], 'parent_id' => $pId]);
|
||||
|
||||
if (!is_string($permission)) {
|
||||
if (!isset($permission['children'])) {
|
||||
$permission['children'] = [];
|
||||
}
|
||||
//判断是否默认插入curd权限
|
||||
if (isset($permission['curd']) && $permission['curd']) {
|
||||
if (is_array($permission['curd'])) {
|
||||
$permission['curd'] = array_reverse($permission['curd']);
|
||||
foreach ($permission['curd'] as $value) {
|
||||
$permission['children'] = array_merge([$value => $curdArr[$value]], $permission['children']);
|
||||
}
|
||||
} else {
|
||||
$permission['children'] = array_merge($curdArr, $permission['children']);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($permission['children']) > 0) {
|
||||
$_key = $permission['curd'] !== false ? ($key ? $key . '.' . $slug : $slug) : $key;
|
||||
$this->createPermissionData($permission['children'], $_key ?? $slug, $pper->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateArticleTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasTable('article_categories')) {
|
||||
Schema::create('article_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('名称');
|
||||
$table->string('key')->unique()->nullable()->comment('key');
|
||||
$table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐状态');
|
||||
$table->unsignedTinyInteger('is_enable')->default(1)->comment('可用状态');
|
||||
$table->unsignedBigInteger('parent_id')->default(0)->comment('上级ID');
|
||||
$table->unsignedInteger('level')->default(1)->comment('层级');
|
||||
$table->string('path')->default('-')->comment('所有的父级ID');
|
||||
$table->unsignedInteger('sort')->default(0)->comment('排序 desc');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
|
||||
$table->text('ext')->nullable()->comment('扩展字段,可用于SEO配置等');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
if (!Schema::hasTable('articles')) {
|
||||
Schema::create('articles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('category_id')->nullable()->comment('分类ID');
|
||||
$table->string('category_path')->default('-')->comment('分类 path');
|
||||
$table->unsignedBigInteger('admin_user_id')->comment('创建人');
|
||||
$table->string('title')->comment('文章标题');
|
||||
$table->string('sub_title')->nullable()->comment('副标题');
|
||||
$table->string('author')->nullable()->comment('作者');
|
||||
$table->string('cover')->nullable()->comment('封面');
|
||||
$table->longText('content')->nullable()->comment('文章内容');
|
||||
$table->timestamp('published_at')->nullable()->comment('发布时间');
|
||||
$table->unsignedInteger('sort')->default(1)->comment('排序 desc');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
|
||||
$table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐状态');
|
||||
$table->unsignedTinyInteger('is_enable')->default(1)->comment('可用状态');
|
||||
|
||||
$table->text('ext')->nullable()->comment('扩展字段,可用于SEO配置等');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('articles');
|
||||
Schema::dropIfExists('article_categories');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'1.0.0' => [
|
||||
'初始化文章管理',
|
||||
'CreateArticleTable.php',
|
||||
],
|
||||
'1.0.1' => [
|
||||
'文章添加点赞,浏览字段',
|
||||
'AddnumToArticleTable.php',
|
||||
],
|
||||
'1.0.2' => [
|
||||
'文章添加媒体内容',
|
||||
'AddMediaToArticleTable.php',
|
||||
],
|
||||
];
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
.DS_Store
|
||||
phpunit.phar
|
||||
/vendor
|
||||
composer.phar
|
||||
composer.lock
|
||||
*.project
|
||||
.idea/
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
# Dact-Admin Extension Banner
|
||||
|
||||
广告管理
|
||||
|
||||
## 权限
|
||||
|
||||
```php
|
||||
$permissions = [
|
||||
'image' => ['name' => '广告管理', 'curd' => false, 'children' => [
|
||||
'banner_ads' => ['name' => '广告位置', 'curd' => true],
|
||||
'banners' => ['name' => '广告内容', 'curd' => true],
|
||||
]],
|
||||
];
|
||||
```
|
||||
|
||||
## 菜单
|
||||
|
||||
```php
|
||||
$menus = [
|
||||
['title' => '广告管理', 'icon' => 'feather icon-image', 'uri' => '', 'permission' => ['banner_ads', 'banners'], 'children' => [
|
||||
['title' => '广告位置', 'icon' => '', 'uri' => '/banner-ads', 'permission' => 'banner_ads'],
|
||||
['title' => '广告内容', 'icon' => '', 'uri' => '/banners', 'permission' => 'banners'],
|
||||
]]
|
||||
];
|
||||
```
|
||||
|
||||
## 接口文档
|
||||
|
||||
[Apifox](https://www.apifox.cn/apidoc/shared-86eb60cb-ba8f-46c6-b718-f33f99de5e7d/api-39896291)
|
||||
|
||||
## 数据表
|
||||
|
||||
### 广告位: banner_ads
|
||||
|
||||
| column | type | nullable | default | comment |
|
||||
| - | - | - | - | - |
|
||||
| id | bigint | not null | - | 主键 |
|
||||
| name | varchar(100) | not null | - | 名称 |
|
||||
| key | varchar(100) | not null | - | 关键字(unique) |
|
||||
| width | integer | null | - | 建议尺寸 |
|
||||
| height | integer | null | - | 建议尺寸 |
|
||||
| is_enable | integer | not null | 1 | 是否可用 |
|
||||
| remarks | varchar(100) | null | - | 备注 |
|
||||
| created_at | timestamp | null | - | 创建时间 |
|
||||
| updated_at | timestamp | null | - | 更新时间 |
|
||||
|
||||
### 广告图: banner
|
||||
|
||||
| column | type | nullable | default | comment |
|
||||
| - | - | - | - | - |
|
||||
| id | bigint | not null | - | 主键 |
|
||||
| ad_id | bigint | not null | - | 位置 id |
|
||||
| path | varchar(191) | not null | - | 图片地址 |
|
||||
| name | varchar(191) | null | - | 名称 |
|
||||
| sort | integer | not null | 1 | 排序(asc) |
|
||||
| is_enable | integer | not null | 1 | 是否可用 |
|
||||
| ext | json | null | - | 其他配置 |
|
||||
| remarks | varchar(191) | null | - | 备注 |
|
||||
| created_at | timestamp | null | - | 创建时间 |
|
||||
| updated_at | timestamp | null | - | 更新时间 |
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"name": "peidikeji/banner",
|
||||
"alias": "广告管理",
|
||||
"description": "广告管理",
|
||||
"type": "library",
|
||||
"keywords": ["dcat-admin", "extension"],
|
||||
"homepage": "https://github.com/peidikeji/banner",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "liutk",
|
||||
"email": "961510893@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Peidikeji\\Banner\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"dcat-admin": "Peidikeji\\Banner\\BannerServiceProvider",
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Peidikeji\\Banner\\BannerServiceProvider"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'BannerAd' => '广告位管理',
|
||||
'banner-ads'=> '广告位管理',
|
||||
],
|
||||
'fields' => [
|
||||
'name' => '名称',
|
||||
'key' => 'key',
|
||||
'width' => '宽度',
|
||||
'height' => '高度',
|
||||
'is_enable' => '启用',
|
||||
'remarks' => '备注',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'Banner' => '广告图管理',
|
||||
'banners' => '广告图管理',
|
||||
],
|
||||
'fields' => [
|
||||
'ad_id'=>'广告位',
|
||||
'name'=>'名称',
|
||||
'path'=>'内容',
|
||||
'sort'=>'排序',
|
||||
'is_enable'=>'启用',
|
||||
'remarks'=> '备注',
|
||||
'ext'=>'扩展字段'
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner;
|
||||
|
||||
use Dcat\Admin\Extend\ServiceProvider;
|
||||
|
||||
class BannerServiceProvider extends ServiceProvider
|
||||
{
|
||||
// protected $menu = [
|
||||
// ['parent' => '', 'title' => '广告管理', 'icon' => 'feather icon-image', 'uri' => ''],
|
||||
// ['parent' => '广告管理', 'title' => '广告位置', 'icon' => '', 'uri' => 'banner-ads'],
|
||||
// ['parent' => '广告管理', 'title' => '广告内容', 'icon' => '', 'uri' => 'banners'],
|
||||
// ];
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Admin;
|
||||
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Admin;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Peidikeji\Banner\Models\Banner;
|
||||
use Peidikeji\Banner\Models\BannerAd;
|
||||
use Dcat\Admin\Grid\Column as GridColumn;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
|
||||
class BannerAdController extends AdminController
|
||||
{
|
||||
protected $translation = 'peidikeji.banner::banner-ad';
|
||||
|
||||
public function list(Request $request)
|
||||
{
|
||||
$query = BannerAd::filter($request->all());
|
||||
|
||||
$query->select(['id', 'name as text', 'width', 'height']);
|
||||
|
||||
if ($request->filled('_paginate')) {
|
||||
$list = $query->paginate();
|
||||
} else {
|
||||
$list = $query->get();
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new BannerAd(), function ($grid) {
|
||||
$grid->disableRowSelector();
|
||||
|
||||
$grid->column('name');
|
||||
$grid->column('key');
|
||||
$grid->column('width');
|
||||
$grid->column('height');
|
||||
$grid->column('is_enable')->if(function(){
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.banner_ads.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
$grid->column('remarks');
|
||||
$grid->disableCreateButton(!(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banner_ads.create')));
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView();
|
||||
$actions->disableEdit();
|
||||
$actions->quickEdit(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banner_ads.edit'));
|
||||
$actions->delete(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banner_ads.destroy'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->expand();
|
||||
$filter->like('name')->width(3);
|
||||
$filter->like('key')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new BannerAd(), function (Form $form) {
|
||||
$form->text('name')->required();
|
||||
$form->text('key')->required()->rules([Rule::unique((new BannerAd())->getTable())]);
|
||||
$form->number('width')->min(0);
|
||||
$form->number('height')->min(0);
|
||||
$form->switch('is_enable')->default(1);
|
||||
$form->text('remarks');
|
||||
});
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
//如果该广告位下还有内容,则一起删除
|
||||
Banner::where(['ad_id' => $id])->delete();
|
||||
|
||||
return parent::destroy($id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Admin;
|
||||
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Widgets\Card;
|
||||
use Peidikeji\Banner\Models\Banner;
|
||||
use Dcat\Admin\Grid\Column as GridColumn;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
|
||||
class BannerController extends AdminController
|
||||
{
|
||||
protected $translation = 'peidikeji.banner::banner';
|
||||
|
||||
protected $extDefaults = [];
|
||||
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new Banner(), function (Grid $grid) {
|
||||
$grid->model()->sort();
|
||||
|
||||
$grid->disableRowSelector();
|
||||
$grid->column('path')->image('', 50);
|
||||
$grid->column('name');
|
||||
$grid->column('sort');
|
||||
$grid->column('is_enable')->if(function () {
|
||||
return !config('admin.permission.enable') || Admin::user()->can('dcat.admin.banners.edit');
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->switch();
|
||||
})->else(function (GridColumn $column) {
|
||||
$column->bool();
|
||||
});
|
||||
$grid->column('ext')
|
||||
->if(function () {
|
||||
return $this->ext;
|
||||
})->then(function (GridColumn $column) {
|
||||
$column->display('展开')->expand(function () {
|
||||
// 返回显示的详情
|
||||
$card = new Card(null, sprintf('<pre class="dump">%s</pre>', json_encode($this->ext, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)));
|
||||
|
||||
return "<div style='padding:10px 10px 0'>$card</div>";
|
||||
});
|
||||
});
|
||||
|
||||
$grid->column('remarks');
|
||||
|
||||
$grid->setDialogFormDimensions('50%', '70%');
|
||||
$grid->disableCreateButton(!(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banners.create')));
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView();
|
||||
$actions->disableEdit();
|
||||
$actions->quickEdit(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banners.edit'));
|
||||
$actions->delete(!config('admin.permission.enable') || Admin::user()->can('dcat.admin.banners.destroy'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->expand();
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new Banner(), function (Form $form) {
|
||||
$form->select('ad_id')
|
||||
->options('api/banner-ads')
|
||||
->required();
|
||||
$form->text('name');
|
||||
$form->image('path')
|
||||
->uniqueName()
|
||||
->move('banner')
|
||||
->saveFullUrl()
|
||||
->autoSave(false)
|
||||
->autoUpload()
|
||||
->removable(false) //禁止用户从页面点击删除服务器上的文件,可以实现图片覆盖上传效果
|
||||
->retainable()
|
||||
->required()->help('建议尺寸:');
|
||||
Admin::script(
|
||||
<<<JS
|
||||
$('body').on('select2:select', 'select.field_ad_id', function(e){
|
||||
let url_path = '/admin/api/banner-ads?id=' + e.params.data.id
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
url: url_path,
|
||||
success: function(result){
|
||||
//异步渲染提示尺寸;
|
||||
let cicun = '未设置';
|
||||
if(result[0]){
|
||||
if(result[0].width || result[0].height){
|
||||
cicun = result[0].width + '*' + result[0].height;
|
||||
}
|
||||
}
|
||||
$('input[name=path]').parent().find('span.help-block').html('<i class="fa feather icon-help-circle"></i> 建议尺寸:'+ cicun);
|
||||
}
|
||||
});
|
||||
});
|
||||
JS
|
||||
);
|
||||
$form->number('sort')
|
||||
->min(0)
|
||||
->help('数值越小, 越靠前');
|
||||
$form->keyValue('ext')->default($this->extDefaults)->setKeyLabel('键名')->setValueLabel('键值');
|
||||
$form->switch('is_enable')->default(1);
|
||||
$form->text('remarks');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Peidikeji\Banner\Models\BannerAd;
|
||||
use Peidikeji\Banner\Http\Resources\BannerResource;
|
||||
|
||||
class BannerController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'key' => 'required'
|
||||
]);
|
||||
$keys = $request->input('key');
|
||||
$keys = is_array($keys) ? $keys : explode(',', $keys);
|
||||
|
||||
$ads = BannerAd::with([
|
||||
'banners' => function ($query) {
|
||||
$query->enable()->sort();
|
||||
},
|
||||
])->enable()->whereIn('key', $keys)->get();
|
||||
|
||||
$data = [];
|
||||
foreach ($keys as $key) {
|
||||
$ad = $ads->where('key', $key)->first();
|
||||
$data[$key] = $ad ? BannerResource::collection($ad->banners) : [];
|
||||
}
|
||||
|
||||
return $this->json($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class BannerResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'path' => $this->path,
|
||||
'ext' => $this->ext,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Admin;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
if(! Route::has('dcat.admin.api.banner_ads')){
|
||||
Route::get('api/banner-ads', [BannerAdController::class, 'list'])->name('api.banner_ads');
|
||||
}
|
||||
|
||||
if(! Route::has('dcat.admin.banner_ads.index')){
|
||||
Route::resource('banner-ads', BannerAdController::class)->names('banner_ads');
|
||||
}
|
||||
if(! Route::has('dcat.admin.banners.index')){
|
||||
Route::resource('banners', BannerController::class);
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Http\Api;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group(['middleware' => 'api', 'prefix' => 'api'], function () {
|
||||
Route::get('banner', [BannerController::class, 'index']);
|
||||
});
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Banner extends Model
|
||||
{
|
||||
use HasFactory, HasDateTimeFormatter;
|
||||
|
||||
protected $fillable = ['ad_id', 'path', 'name', 'sort', 'is_enable', 'ext', 'remarks'];
|
||||
|
||||
protected $casts = [
|
||||
'ext' => 'array'
|
||||
];
|
||||
|
||||
public function ad()
|
||||
{
|
||||
return $this->belongsTo(BannerAd::class, 'ad_id');
|
||||
}
|
||||
|
||||
public function scopeEnable($query)
|
||||
{
|
||||
return $query->where('is_enable', 1);
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->orderBy('sort');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Banner\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class BannerAd extends Model
|
||||
{
|
||||
use HasFactory, HasDateTimeFormatter;
|
||||
|
||||
protected $fillable = ['name', 'key', 'width', 'height', 'is_enable', 'remarks'];
|
||||
|
||||
public function banners()
|
||||
{
|
||||
return $this->hasMany(Banner::class, 'ad_id');
|
||||
}
|
||||
|
||||
public function scopeEnable($query){
|
||||
return $query->where('is_enable', 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBannerTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasTable('banner_ads')) {
|
||||
Schema::create('banner_ads', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('名称');
|
||||
$table->string('key')->unique()->comment('key');
|
||||
$table->unsignedInteger('width')->nullable()->comment('宽');
|
||||
$table->unsignedInteger('height')->nullable()->comment('高');
|
||||
$table->unsignedTinyInteger('is_enable')->default(1)->comment('可用状态');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
if (!Schema::hasTable('banners')) {
|
||||
Schema::create('banners', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('ad_id')->comment('位置ID');
|
||||
$table->string('path')->comment('地址');
|
||||
$table->string('name')->nullable()->comment('名称');
|
||||
$table->unsignedInteger('sort')->default(1)->comment('排序(asc)');
|
||||
$table->unsignedTinyInteger('is_enable')->default(1)->comment('可用状态');
|
||||
$table->text('ext')->nullable()->comment('扩展字段,可用于跳转配置等');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('banners');
|
||||
Schema::dropIfExists('banner_ads');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'1.0.0' => [
|
||||
'CreateBannerTable.php',
|
||||
],
|
||||
];
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Peidikeji\Keywords\Http\Admin;
|
||||
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
|
|
@ -30,13 +31,18 @@ class KeywordsController extends AdminController
|
|||
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new Keywords(), function ($grid) {
|
||||
return Grid::make(new Keywords(), function (Grid $grid) {
|
||||
$grid->column('name')->tree();
|
||||
$grid->column('key');
|
||||
$grid->column('value');
|
||||
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$user = Admin::user();
|
||||
$grid->showCreateButton($user->can('dcat.admin.keywords.create'));
|
||||
$grid->showEditButton($user->can('dcat.admin.keywords.edit'));
|
||||
$grid->showDeleteButton($user->can('dcat.admin.keywords.destroy'));
|
||||
|
||||
$grid->quickSearch(['name', 'type_key', 'key']);
|
||||
});
|
||||
}
|
||||
|
|
@ -80,6 +86,11 @@ class KeywordsController extends AdminController
|
|||
$form->hidden('type_key');
|
||||
$form->hidden('level')->default(1);
|
||||
|
||||
$form->disableCreatingCheck();
|
||||
$form->disableEditingCheck();
|
||||
$form->disableListButton();
|
||||
$form->disableDeleteButton();
|
||||
|
||||
$form->saving(function (Form $form) {
|
||||
if ($form->parent_id) {
|
||||
$parent = Keywords::findOrFail($form->parent_id);
|
||||
|
|
|
|||
|
|
@ -6,12 +6,18 @@ use Dcat\Admin\Extend\ServiceProvider;
|
|||
|
||||
class KeywordsServiceProvider extends ServiceProvider
|
||||
{
|
||||
// protected $menu = [
|
||||
// ['title' => 'Keywords', 'uri' => 'keywords', 'icon' => 'feather icon-list'],
|
||||
// ];
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
|
||||
protected function menu()
|
||||
{
|
||||
if (config('app.debug')) {
|
||||
return [
|
||||
['title' => 'Keywords', 'uri' => 'keywords', 'icon' => 'feather icon-list'],
|
||||
];
|
||||
}
|
||||
return $this->menu;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ class SettingController extends AdminController
|
|||
if ($form->isEditing()) {
|
||||
$unique->ignore($form->getKey(), 'slug');
|
||||
}
|
||||
$form->text('name')->required();
|
||||
$form->text('slug')->required()->help('不能重复')->rules([$unique]);
|
||||
$form->text('name')->required();
|
||||
$form->textarea('value')->required();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,16 +6,18 @@ use Dcat\Admin\Extend\ServiceProvider;
|
|||
|
||||
class SettingServiceProvider extends ServiceProvider
|
||||
{
|
||||
// protected $menu = [
|
||||
// ['title' => '配置管理', 'uri' => 'settings', 'icon' => 'fa fa-gear'],
|
||||
// ];
|
||||
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
|
||||
protected function menu()
|
||||
{
|
||||
if (config('app.debug')) {
|
||||
return [
|
||||
['title' => '配置管理', 'uri' => 'settings', 'icon' => 'fa fa-gear'],
|
||||
];
|
||||
}
|
||||
return $this->menu;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,103 @@
|
|||
<div class="{{$viewClass['form-group']}}">
|
||||
|
||||
<label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
|
||||
|
||||
<div class="{{$viewClass['field']}}">
|
||||
|
||||
@include('admin::form.error')
|
||||
|
||||
<div class="{{ $class }}" style="padding-left: 40px;" >
|
||||
<el-tree
|
||||
show-checkbox
|
||||
node-key="id"
|
||||
ref="tree"
|
||||
highlight-current
|
||||
:data="permissionNodes"
|
||||
:indent="25"
|
||||
:render-after-expand="false"
|
||||
:default-expand-all="true"
|
||||
:default-checked-keys="defaultKeys"
|
||||
:props="defaultProps" v-on:check-change="nodeChange">
|
||||
<span class="custom-tree-node" slot-scope="{ node, permissionNodes }" >
|
||||
<span v-on:click="getCheckedNode(node)">@{{ node.label }}</span>
|
||||
<template v-if="node.level==1">
|
||||
<span class="tran el-icon-arrow-right" :class="{isactive:node.expanded}"></span>
|
||||
</template>
|
||||
</span>
|
||||
</el-tree>
|
||||
|
||||
<input type="hidden" ref="format_attr_value" name="format_attr_value" value="{{ $value }}">
|
||||
<input type="hidden" name="{{ $name }}" :value="getCheck">
|
||||
</div>
|
||||
@include('admin::form.help-block')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script init="{!! $selector !!}">
|
||||
|
||||
var app = new Vue({
|
||||
el: '#' + id,
|
||||
data: {
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
},
|
||||
checkPermissions:[],
|
||||
defaultKeys:[],
|
||||
permissionNodes:[]
|
||||
},
|
||||
computed: {
|
||||
getCheck() {
|
||||
// console.log(this.checkPermissions);
|
||||
return JSON.stringify(this.checkPermissions);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.createStart()
|
||||
},
|
||||
methods:{
|
||||
createStart(){
|
||||
//初始化权限可选项;
|
||||
var url_path = "{{ admin_route('api.get_permissions') }}";
|
||||
var that = this;
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
url: url_path,
|
||||
success: function (result) {
|
||||
that.permissionNodes = result;
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(()=>{
|
||||
var formatAttrValue = this.$refs.format_attr_value.defaultValue
|
||||
//编辑时默认选中项
|
||||
if(formatAttrValue){
|
||||
formatAttrValue = JSON.parse(formatAttrValue)
|
||||
// console.log(formatAttrValue)
|
||||
//赋予defaultKeys值
|
||||
this.defaultKeys = formatAttrValue
|
||||
this.checkPermissions = formatAttrValue;
|
||||
}
|
||||
}, 100)
|
||||
},
|
||||
getCheckedNode(node){
|
||||
if(this.checkPermissions.indexOf(node.key) != -1){//如果该节点已存在,则取消选中
|
||||
this.$refs.tree.setChecked(node, false);
|
||||
}else{
|
||||
this.$refs.tree.setChecked(node, true);
|
||||
}
|
||||
},
|
||||
nodeChange(node, hasChecked, childrenNodes){
|
||||
if(node.children.length == 0){
|
||||
if(hasChecked){
|
||||
this.checkPermissions.push(node.id);
|
||||
}else{
|
||||
this.checkPermissions.splice(this.checkPermissions.indexOf(node.id), 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -22,5 +22,6 @@
|
|||
{!! $content !!}
|
||||
@endif
|
||||
@endif
|
||||
@include('admin::form.help-block')
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -588,6 +588,8 @@ class Admin
|
|||
if (config('admin.permission.enable')) {
|
||||
$router->resource('auth/roles', 'RoleController');
|
||||
$router->resource('auth/permissions', 'PermissionController');
|
||||
|
||||
$router->get('api/get-permissions', 'PermissionController@apiGetPermissions')->name('api.get_permissions');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
34
src/Form.php
34
src/Form.php
|
|
@ -3,31 +3,31 @@
|
|||
namespace Dcat\Admin;
|
||||
|
||||
use Closure;
|
||||
use Dcat\Admin\Actions\Action;
|
||||
use Dcat\Admin\Contracts\Repository;
|
||||
use Dcat\Admin\Form\AbstractTool;
|
||||
use Dcat\Admin\Form\Builder;
|
||||
use Dcat\Admin\Form\Concerns;
|
||||
use Dcat\Admin\Form\Condition;
|
||||
use Dcat\Admin\Form\Field;
|
||||
use Illuminate\Support\Arr;
|
||||
use Dcat\Admin\Form\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Dcat\Admin\Form\Concerns;
|
||||
use Dcat\Admin\Actions\Action;
|
||||
use Dcat\Admin\Form\Condition;
|
||||
use Dcat\Admin\Support\Helper;
|
||||
use Illuminate\Support\Fluent;
|
||||
use Dcat\Admin\Form\NestedForm;
|
||||
use Dcat\Admin\Form\AbstractTool;
|
||||
use Dcat\Admin\Form\ResolveField;
|
||||
use Dcat\Admin\Http\JsonResponse;
|
||||
use Dcat\Admin\Support\Helper;
|
||||
use Dcat\Admin\Traits\HasBuilderEvents;
|
||||
use Dcat\Admin\Traits\HasFormResponse;
|
||||
use Dcat\Admin\Widgets\DialogForm;
|
||||
use Illuminate\Contracts\Support\MessageProvider;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Fluent;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Dcat\Admin\Contracts\Repository;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Dcat\Admin\Traits\HasFormResponse;
|
||||
use Dcat\Admin\Traits\HasBuilderEvents;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Contracts\Support\MessageProvider;
|
||||
|
||||
/**
|
||||
* Class Form.
|
||||
|
|
@ -88,6 +88,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
* @method Field\MultipleSelectTable multipleSelectTable($column, $label = '')
|
||||
* @method Field\Button button(string $html = null)
|
||||
* @method Field\Autocomplete autocomplete($column, $label = '')
|
||||
* @method Field\PermissionSelect permissionSelect($column, $label = '')
|
||||
*/
|
||||
class Form implements Renderable
|
||||
{
|
||||
|
|
@ -172,6 +173,7 @@ class Form implements Renderable
|
|||
'selectTable' => Field\SelectTable::class,
|
||||
'multipleSelectTable' => Field\MultipleSelectTable::class,
|
||||
'autocomplete' => Field\Autocomplete::class,
|
||||
'permissionSelect' => Field\PermissionSelect::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Dcat\Admin\Form\Field;
|
||||
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form\Field;
|
||||
|
||||
class PermissionSelect extends Field
|
||||
{
|
||||
protected $view = 'admin::form.permission-select';
|
||||
|
||||
protected $listen = '';
|
||||
|
||||
protected static $css = [
|
||||
'@element',
|
||||
];
|
||||
|
||||
protected static $js = [
|
||||
'@vue',
|
||||
'@element',
|
||||
];
|
||||
|
||||
public function render()
|
||||
{
|
||||
Admin::style(
|
||||
<<<CSS
|
||||
.el-tree>.el-tree-node {
|
||||
border-top: 1px solid #EBEEF5 !important;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.el-tree-node__children .el-tree-node{
|
||||
display: flex !important;
|
||||
}
|
||||
.el-tree-node__children .el-tree-node .el-tree-node__children{
|
||||
display: flex !important;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
.el-tree-node__expand-icon{
|
||||
display: none !important;
|
||||
}
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 16px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.tran{
|
||||
transition: transform .3s;
|
||||
}
|
||||
.isactive{
|
||||
transform: rotate(90deg) ;
|
||||
}
|
||||
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
|
||||
background-color:transparent !important;
|
||||
}
|
||||
.el-tree-node__content:hover, .el-upload-list__item:hover{
|
||||
background-color:transparent !important;
|
||||
}
|
||||
CSS
|
||||
);
|
||||
|
||||
$this->addVariables(['listen' => $this->listen]);
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化渲染值
|
||||
*
|
||||
* @param [type] $value
|
||||
* @return void
|
||||
*/
|
||||
protected function formatFieldData($data)
|
||||
{
|
||||
$value = parent::formatFieldData($data);
|
||||
$hasChecked = [];
|
||||
foreach ($value ?? [] as $permission){
|
||||
$hasChecked[] = $permission['id'];
|
||||
}
|
||||
return json_encode($hasChecked);
|
||||
}
|
||||
|
||||
protected function prepareInputValue($value)
|
||||
{
|
||||
return json_decode($value);
|
||||
}
|
||||
}
|
||||
|
|
@ -86,18 +86,18 @@ class Permission
|
|||
*
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException
|
||||
*/
|
||||
public static function error()
|
||||
public static function error($ability = null)
|
||||
{
|
||||
if ($error = static::$errorHandler) {
|
||||
admin_exit($error());
|
||||
}
|
||||
|
||||
if (Helper::isAjaxRequest()) {
|
||||
abort(403, trans('admin.deny'));
|
||||
abort(403, trans('admin.deny') . ':' . $ability);
|
||||
}
|
||||
|
||||
admin_exit(
|
||||
Content::make()->withError(trans('admin.deny'))
|
||||
Content::make()->withError(trans('admin.deny') . ':' . $ability)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
namespace Dcat\Admin\Http\Controllers;
|
||||
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Http\Repositories\Permission;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Tree;
|
||||
use Dcat\Admin\Admin;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Http\Repositories\Permission;
|
||||
use Dcat\Admin\Models\Permission AS PermissionModel;
|
||||
|
||||
class PermissionController extends AdminController
|
||||
{
|
||||
|
|
@ -16,6 +18,38 @@ class PermissionController extends AdminController
|
|||
return trans('admin.permissions');
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过接口获取权限数据
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function apiGetPermissions(Request $request)
|
||||
{
|
||||
$permissions = (new PermissionModel())->toTree();
|
||||
|
||||
$permissionArr = $this->formatPermissionsTreeToArray($permissions);
|
||||
return response()->json($permissionArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化树
|
||||
*
|
||||
* @param array $permissions
|
||||
* @return void
|
||||
*/
|
||||
protected function formatPermissionsTreeToArray(array $permissions)
|
||||
{
|
||||
$res = [];
|
||||
foreach ($permissions as $permission) {
|
||||
$res[] = [
|
||||
'id' => $permission->id,
|
||||
'label' => $permission->name,
|
||||
'children' => $this->formatPermissionsTreeToArray($permission->children ?? []),
|
||||
];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function index(Content $content)
|
||||
{
|
||||
return $content
|
||||
|
|
|
|||
|
|
@ -96,38 +96,40 @@ class RoleController extends AdminController
|
|||
|
||||
$form->text('name', trans('admin.name'))->required();
|
||||
|
||||
$form->tree('permissions')
|
||||
->nodes(function () {
|
||||
$permissionModel = config('admin.database.permissions_model');
|
||||
$permissionModel = new $permissionModel();
|
||||
$form->permissionSelect('permissions');
|
||||
|
||||
return $permissionModel->allNodes();
|
||||
})
|
||||
->customFormat(function ($v) {
|
||||
if (! $v) {
|
||||
return [];
|
||||
}
|
||||
// $form->tree('permissions')
|
||||
// ->nodes(function () {
|
||||
// $permissionModel = config('admin.database.permissions_model');
|
||||
// $permissionModel = new $permissionModel();
|
||||
|
||||
return array_column($v, 'id');
|
||||
});
|
||||
// return $permissionModel->allNodes();
|
||||
// })
|
||||
// ->customFormat(function ($v) {
|
||||
// if (! $v) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
if ($bindMenu) {
|
||||
$form->tree('menus', trans('admin.menu'))
|
||||
->treeState(false)
|
||||
->setTitleColumn('title')
|
||||
->nodes(function () {
|
||||
$model = config('admin.database.menu_model');
|
||||
// return array_column($v, 'id');
|
||||
// });
|
||||
|
||||
return (new $model())->allNodes();
|
||||
})
|
||||
->customFormat(function ($v) {
|
||||
if (! $v) {
|
||||
return [];
|
||||
}
|
||||
// if ($bindMenu) {
|
||||
// $form->tree('menus', trans('admin.menu'))
|
||||
// ->treeState(false)
|
||||
// ->setTitleColumn('title')
|
||||
// ->nodes(function () {
|
||||
// $model = config('admin.database.menu_model');
|
||||
|
||||
return array_column($v, 'id');
|
||||
});
|
||||
}
|
||||
// return (new $model())->allNodes();
|
||||
// })
|
||||
// ->customFormat(function ($v) {
|
||||
// if (! $v) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// return array_column($v, 'id');
|
||||
// });
|
||||
// }
|
||||
|
||||
$form->display('created_at', trans('admin.created_at'));
|
||||
$form->display('updated_at', trans('admin.updated_at'));
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class Permission
|
|||
if (! $user->allPermissions()->first(function ($permission) use ($request) {
|
||||
return $permission->shouldPassThrough($request);
|
||||
})) {
|
||||
Checker::error();
|
||||
Checker::error($ability);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
|
|
|||
|
|
@ -180,6 +180,13 @@ class Asset
|
|||
'@autocomplete' => [
|
||||
'js' => '@admin/dcat/plugins/autocomplete/jquery.autocomplete.min.js',
|
||||
],
|
||||
'@element' => [
|
||||
'css' =>'@admin/element/v2.15.8/app.css',
|
||||
'js' => '@admin/element/v2.15.8/app.js',
|
||||
],
|
||||
'@vue' => [
|
||||
'js' => '@admin/vue/vue.js'
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ class Field implements Renderable
|
|||
*/
|
||||
protected $escape = true;
|
||||
|
||||
protected $help;
|
||||
|
||||
/**
|
||||
* Field value.
|
||||
*
|
||||
|
|
@ -702,6 +704,7 @@ HTML;
|
|||
return [
|
||||
'content' => $this->value,
|
||||
'escape' => $this->escape,
|
||||
'help' => $this->help,
|
||||
'label' => $this->getLabel(),
|
||||
'wrapped' => $this->border,
|
||||
'width' => $this->width,
|
||||
|
|
@ -772,4 +775,11 @@ HTML;
|
|||
return format_byte($value, $dec);
|
||||
});
|
||||
}
|
||||
|
||||
public function help($text = '', $icon = 'feather icon-help-circle')
|
||||
{
|
||||
$this->help = compact('text', 'icon');
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ trait ModelTree
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toTree(array $nodes = null)
|
||||
public function toTree($nodes = null)
|
||||
{
|
||||
if ($nodes === null) {
|
||||
$nodes = $this->allNodes();
|
||||
|
|
@ -304,7 +304,7 @@ trait ModelTree
|
|||
* @param string $space
|
||||
* @return array
|
||||
*/
|
||||
protected function buildSelectOptions(array $nodes = [], $parentId = 0, $prefix = '', $space = ' ')
|
||||
public function buildSelectOptions(array $nodes = [], $parentId = 0, $prefix = '', $space = ' ')
|
||||
{
|
||||
$d = '├─';
|
||||
$prefix = $prefix ?: $d.$space;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class Form implements Renderable
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $buttons = ['reset' => true, 'submit' => true];
|
||||
protected $buttons = ['reset' => true, 'submit' => true, 'back' => false];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
|
|
@ -489,6 +489,13 @@ class Form implements Renderable
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function backButton(bool $value = true)
|
||||
{
|
||||
$this->buttons['back'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable reset button.
|
||||
*
|
||||
|
|
@ -500,6 +507,11 @@ class Form implements Renderable
|
|||
return $this->resetButton(! $value);
|
||||
}
|
||||
|
||||
public function disableBackButton(bool $value = true)
|
||||
{
|
||||
return $this->backButton(! $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable submit button.
|
||||
*
|
||||
|
|
@ -623,7 +635,7 @@ class Form implements Renderable
|
|||
return <<<HTML
|
||||
<div class="box-footer row d-flex">
|
||||
<div class="col-md-2"> </div>
|
||||
<div class="col-md-8">{$this->renderResetButton()}{$this->renderSubmitButton()}</div>
|
||||
<div class="col-md-8">{$this->renderBackButton()}{$this->renderResetButton()}{$this->renderSubmitButton()}</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
|
@ -644,6 +656,15 @@ HTML;
|
|||
}
|
||||
}
|
||||
|
||||
protected function renderBackButton()
|
||||
{
|
||||
if (! empty($this->buttons['back'])) {
|
||||
$back = trans('admin.back');
|
||||
|
||||
return "<a href=\"javascript: window.history.back()\" class=\"btn btn-white pull-left\"><i class=\"feather icon-arrow-left\"></i> {$back}</a>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交按钮文本.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue