diff --git a/app/Admin/Components.php b/app/Admin/Components.php index cdb550f..de807e0 100644 --- a/app/Admin/Components.php +++ b/app/Admin/Components.php @@ -47,7 +47,7 @@ class Components extends BaseRenderer { /** * 富文本编辑器 */ - public function fuEditorControl($name ='content', $label = null, $height = 600) + public function fuEditorControl($name ='content', $label = null, $height = 530) { return WangEditor::make() ->name($name)->label($label ?? __('admin.components.content')) @@ -55,6 +55,9 @@ class Components extends BaseRenderer { ->excludeKeys(['group-video']); } + /** + * 开关 + */ public function enableControl($name = 'is_enable', $label= null, $mode = 'horizontal'){ return amisMake()->SwitchControl() ->name($name)->label($label ?? __('admin.components.status')) @@ -62,16 +65,47 @@ class Components extends BaseRenderer { ->onText(__('admin.components.status_map.enabled'))->offText(__('admin.components.status_map.disabled')); } + /** + * 图片上传 + */ + public function imageControl($name, $label){ + return amis()->ImageControl($name, $label) + ->autoUpload(true)->maxSize('5*1024*1024');//不能大于5M + } + + /** + * 图片上传,带裁剪 + */ + public function cropImageControl($name, $label, $aspectRatio = null){ + return amis()->ImageControl($name, $label) + ->crop([ + 'aspectRatio' => $aspectRatio ?? 1 + ])->autoUpload(true); + } + + /** + * 标签选择 + */ public function keywordsTagControl($name = 'tags', $label= null, $pKey = null){ return amisMake()->TagControl() ->name($name)->label($label ?? __('admin.components.tag')) ->maxTagLength(0) - ->options(Keyword::where('p_key', $pKey)->pluck('name', 'id')->toArray()); + ->options(Keyword::where('parent_key', $pKey)->pluck('name', 'id')->toArray()); } - public function keywordsTag($label = null){ - return amisMake()->Tag()->label($label ?? __('admin.components.tag')) + public function keywordsTag($label = null, $color = null){ + if($color){ + $tag = amisMake()->Tag()->label($label ?? __('admin.components.tag')) + ->displayMode('rounded')->style([ + 'color' => '#fff', + 'backgroundColor' =>$color, + 'borderColor' => $color + ]); + }else{ + $tag = amisMake()->Tag()->label($label ?? __('admin.components.tag')) ->displayMode('rounded')->color('inactive'); + } + return $tag; } /** diff --git a/app/Admin/Controllers/ArticleController.php b/app/Admin/Controllers/ArticleController.php index 26b4a2b..a08290d 100644 --- a/app/Admin/Controllers/ArticleController.php +++ b/app/Admin/Controllers/ArticleController.php @@ -2,10 +2,14 @@ namespace App\Admin\Controllers; +use App\Casts\Storage; +use Slowlyo\OwlAdmin\Admin; use Slowlyo\OwlAdmin\Renderers\Page; use Slowlyo\OwlAdmin\Renderers\Form; use Slowlyo\OwlAdmin\Controllers\AdminController; use App\Services\Admin\ArticleService; +use App\Admin\Components; +use App\Models\Keyword; class ArticleController extends AdminController { @@ -13,29 +17,49 @@ class ArticleController extends AdminController public function list():Page { - $crud = $this->baseCRUD() + $crud = $this->baseCRUD()->tableLayout('fixed') ->headerToolbar([ - $this->createButton(true), + $this->createButton(), ...$this->baseHeaderToolBar(), ]) ->filter($this->baseFilter()->body()) ->columns([ amis()->TableColumn('id', __('admin.id')), - amis()->TableColumn('title', __('admin.articles.title')), - amis()->TableColumn('category', __('admin.articles.category')), - amis()->TableColumn('t_ids', __('admin.articles.tags')), - amis()->TableColumn('cover', __('admin.articles.cover')), + amis()->TableColumn('title', __('admin.articles.title'))->width('300px'), + amis()->TableColumn('category', __('admin.articles.category'))->type('mapping') + ->map(Keyword::allChildrenOfKey('article_category')->pluck('name', 'key')->toArray()) + ->itemSchema(amis()->Tag()->label('${item}')->color(Admin::setting()->get('system_theme_setting')['theme_color'] ?? '#1677ff')), + amis()->TableColumn('tags', __('admin.articles.tags'))->type('mapping')->map(Keyword::tagsMap('article_tag')), + amis()->TableColumn('cover', __('admin.articles.cover'))->type('image')->height('50px')->width('50px')->enlargeAble(true), amis()->TableColumn('published_at', __('admin.articles.published_at')), - amis()->TableColumn('is_enable', __('admin.articles.is_enable')), + amis()->TableColumn('is_enable', __('admin.articles.is_enable'))->type('switch'), amis()->TableColumn('created_at', __('admin.created_at')), + amis()->Operation()->label(__('admin.actions'))->buttons([ + $this->rowEditButton(), + $this->rowDeleteButton(), + ]) ]); + return $this->baseList($crud); } public function form(): Form { - return $this->baseForm()->body([ - + return $this->baseForm()->panelClassName('px-0')->body([ + amis()->Grid()->columns([ + amis()->Wrapper()->body([ + amis()->TextControl('title', __('admin.articles.title'))->required(true), + Components::make()->parentControl(admin_url('api/keywords/tree-list?parent_name=article_category&has_owner=0'), 'category', __('admin.articles.category'), 'name', 'key'), + Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'), + Components::make()->cropImageControl('cover', __('admin.articles.cover')), + Components::make()->sortControl('sort', __('admin.articles.sort')), + amis()->DateTimeControl('published_at', __('admin.articles.published_at'))->value(now())->format('YYYY-MM-DD HH:mm:ss')->description('*不填写则默认为创建时间'), + amis()->SwitchControl('is_enable', __('admin.articles.is_enable'))->value(true), + ])->md(4), + amis()->Wrapper()->body([ + Components::make()->fuEditorControl('content', __('admin.articles.content')), + ])->md(8) + ]), ]); } diff --git a/app/Casts/Storage.php b/app/Casts/Storage.php new file mode 100644 index 0000000..c8b7c83 --- /dev/null +++ b/app/Casts/Storage.php @@ -0,0 +1,45 @@ +url($value)) : ''; + } + + /** + * Prepare the given value for storage. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param string $key + * @param array $value + * @param array $attributes + * @return string + */ + public function set($model, $key, $value, $attributes) + { + return $value; + } +} \ No newline at end of file diff --git a/app/Models/Article.php b/app/Models/Article.php index e2d1ef8..6480822 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -3,8 +3,10 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use EloquentFilter\Filterable; +use App\Casts\Storage; class Article extends Model { @@ -16,6 +18,17 @@ class Article extends Model return $date->format('Y-m-d H:i:s'); } + protected $appends = ['tags']; + + protected $casts = [ + 'created_at' => 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + 'published_at' => 'datetime:Y-m-d H:i:s', + 'is_enable' => 'boolean', + 'is_recommend' => 'boolean', + 'cover' => Storage::class, + ]; + protected $fillable = [ 'title', 'content', @@ -28,4 +41,11 @@ class Article extends Model 'sort', 'appendixes', ]; + + protected function tags():Attribute + { + return Attribute::make( + get: fn($value) => $this->t_ids ? explode(',', $this->t_ids) : [], + ); + } } diff --git a/app/Models/Filters/KeywordFilter.php b/app/Models/Filters/KeywordFilter.php index 498aaf9..caf1040 100644 --- a/app/Models/Filters/KeywordFilter.php +++ b/app/Models/Filters/KeywordFilter.php @@ -18,10 +18,14 @@ class KeywordFilter extends ModelFilter public function parentName($parent_name) { - return $this->where(function($q) use ($parent_name){ - $q->where('name','like', '%'.$parent_name.'%') - ->orWhere('key','like', '%'.$parent_name.'%'); - })->orWhere('parent_key', Keyword::where('name','like', '%'.$parent_name.'%') - ->orWhere('key','like', '%'.$parent_name.'%')->value('key') ?? ''); + 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') + . '-%' ?? ''); } } diff --git a/app/Models/Keyword.php b/app/Models/Keyword.php index df07701..4922134 100644 --- a/app/Models/Keyword.php +++ b/app/Models/Keyword.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use EloquentFilter\Filterable; +use App\Admin\Components; class Keyword extends Model { @@ -48,4 +49,20 @@ class Keyword extends Model { return $this->hasMany(static::class, 'parent_id'); } + + public function scopeAllChildrenOfKey($q, $parentKey) + { + $q->where('path','like', '%-'. + static::where('key', $parentKey)->value('id') + . '-%' ?? ''); + } + + public static function tagsMap(String $key) + { + $mapArr = []; + self::query()->where('parent_key', $key)->get()->map(function($item) use (&$mapArr){ + $mapArr[$item->id] = Components::make()->keywordsTag($item->name, $item->value); + }); + return $mapArr; + } }