liutk 2026-02-21 19:10:22 +08:00
parent 354f80d17f
commit 2be627dd8d
18 changed files with 917 additions and 19 deletions

View File

@ -61,9 +61,9 @@ class ArticleController extends AdminController
->columns([
amis()->TableColumn('id', __('admin.id'))->sortable(true),
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('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_url', __('admin.articles.cover'))->type('image')->height('50px')->width('50px')->enlargeAble(true),
amis()->TableColumn('published_at', __('admin.articles.published_at'))->remark(__('admin.articles.published_at_remark')),
@ -85,7 +85,7 @@ class ArticleController extends AdminController
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()->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')),

View File

@ -0,0 +1,90 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\ProjectArticleService;
use App\Traits\CustomActionTrait;
use App\Admin\Components;
use App\Models\{ProjectArticle,ProjectCate};
use Slowlyo\OwlAdmin\Admin;
/**
* 核心优势
*
* @property ProjectArticleService $service
*/
class ProjectAdvanceController extends AdminController
{
use CustomActionTrait;
protected string $serviceName = ProjectArticleService::class;
public function list(): Page
{
$crud = $this->baseCRUD()->tableLayout('fixed')
->headerToolbar([
$this->createTypeButton('drawer', 'md'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
// amis()->TextControl('id', __('admin.project_articles.id'))->columnRatio(3)
// ->placeholder(__('admin.id')),
amis()->TextControl('title', __('admin.project_articles.title'))->columnRatio(3)
->placeholder(__('admin.project_articles.title')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->columnRatio(3)
->placeholder(__('admin.project_articles.cate')),
]),
]))
->columns([
// amis()->TableColumn('id', __('admin.id'))->sortable(true)->width('50px'),
amis()->TableColumn('title', __('admin.project_articles.title'))->width('300px'),
amis()->TableColumn('cate', __('admin.project_articles.cate'))->type('mapping')
->map(ProjectCate::get()->pluck('title', 'id')->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_url', __('admin.project_articles.cover'))->type('image')->height('50px')->width('150px')->enlargeAble(true),
// amis()->TableColumn('published_at', __('admin.project_articles.published_at'))->remark(__('admin.project_articles.published_at_remark')),
amis()->TableColumn('is_enable', __('admin.project_articles.is_enable'))->type('switch'),
// amis()->TableColumn('is_recommend', __('admin.articles.is_recommend'))->type('switch'),
amis()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
amis()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditTypeButton('drawer', 'md'),
$this->rowDeleteButton(),
])
]);
return $this->baseList($crud);
}
public function form($isEdit = false): Form
{
return $this->baseForm()->panelClassName('px-0')->body([
amis()->Grid()->columns([
amis()->Wrapper()->body([
amis()->TextControl('title', __('admin.project_articles.title'))->required(true),
amis()->TextareaControl('description', __('admin.project_articles.description')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->required(true),
amis()->TextControl('type', __('admin.project_articles.type'))->value(ProjectArticle::TYPE_ADVANCE)->hidden(true),
// Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'),
Components::make()->cropImageControl('cover', __('admin.project_articles.cover'))->required(true),
Components::make()->sortControl('sort', __('admin.project_articles.sort')),
// amis()->DateTimeControl('published_at', __('admin.project_articles.published_at'))->format('YYYY-MM-DD HH:mm:ss')->description(__('admin.project_articles.published_at_remark')),
amis()->SwitchControl('is_enable', __('admin.project_articles.is_enable'))->value(false),
// amis()->SwitchControl('is_recommend', __('admin.project_articles.is_recommend'))->value(false),
// Components::make()->fileControl('appendixes', __('admin.articles.appendixes'), '.png,.jpg')->multiple(true),
])
// amis()->Wrapper()->body([
// Components::make()->fuEditorControl('content', __('admin.project_articles.content'))->required(true),
// ])->md(8)
]),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\ProjectArticleService;
use App\Traits\CustomActionTrait;
use App\Admin\Components;
use App\Models\{ProjectCate,ProjectArticle};
use Slowlyo\OwlAdmin\Admin;
/**
* 业务内容
*
* @property ProjectArticleService $service
*/
class ProjectArticleController extends AdminController
{
use CustomActionTrait;
protected string $serviceName = ProjectArticleService::class;
public function list(): Page
{
$crud = $this->baseCRUD()->tableLayout('fixed')
->headerToolbar([
$this->createTypeButton('drawer', 'xl'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
// amis()->TextControl('id', __('admin.project_articles.id'))->columnRatio(3)
// ->placeholder(__('admin.id')),
amis()->TextControl('title', __('admin.project_articles.title'))->columnRatio(3)
->placeholder(__('admin.project_articles.title')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->columnRatio(3)
->placeholder(__('admin.project_articles.cate')),
]),
]))
->columns([
// amis()->TableColumn('id', __('admin.id'))->sortable(true)->width('50px'),
amis()->TableColumn('title', __('admin.project_articles.title'))->width('300px'),
amis()->TableColumn('cate', __('admin.project_articles.cate'))->type('mapping')
->map(ProjectCate::get()->pluck('title', 'id')->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_url', __('admin.project_articles.cover'))->type('image')->height('50px')->width('150px')->enlargeAble(true),
// amis()->TableColumn('published_at', __('admin.project_articles.published_at'))->remark(__('admin.project_articles.published_at_remark')),
amis()->TableColumn('is_enable', __('admin.project_articles.is_enable'))->type('switch'),
// amis()->TableColumn('is_recommend', __('admin.articles.is_recommend'))->type('switch'),
amis()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
amis()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditTypeButton('drawer', 'xl'),
$this->rowDeleteButton(),
])
]);
return $this->baseList($crud);
}
public function form($isEdit = false): Form
{
return $this->baseForm()->panelClassName('px-0')->body([
amis()->Grid()->columns([
amis()->Wrapper()->body([
amis()->TextControl('title', __('admin.project_articles.title'))->required(true),
amis()->TextareaControl('description', __('admin.project_articles.description')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->required(true),
amis()->TextControl('type', __('admin.project_articles.type'))->value(ProjectArticle::TYPE_ARTICLE)->hidden(true),
// Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'),
Components::make()->cropImageControl('cover', __('admin.project_articles.cover'))->required(true),
Components::make()->sortControl('sort', __('admin.project_articles.sort')),
// amis()->DateTimeControl('published_at', __('admin.project_articles.published_at'))->format('YYYY-MM-DD HH:mm:ss')->description(__('admin.project_articles.published_at_remark')),
amis()->SwitchControl('is_enable', __('admin.project_articles.is_enable'))->value(false),
// amis()->SwitchControl('is_recommend', __('admin.project_articles.is_recommend'))->value(false),
// Components::make()->fileControl('appendixes', __('admin.articles.appendixes'), '.xsl,.xlsx,.txt,.doc,.docx,.pdf,.pptx'),
])->md(4),
amis()->Wrapper()->body([
Components::make()->fuEditorControl('content', __('admin.project_articles.content'))->required(true),
])->md(8)
]),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\ProjectCateService;
use App\Traits\CustomActionTrait;
use App\Admin\Components;
/**
* 业务范围
*
* @property ProjectCateService $service
*/
class ProjectCateController extends AdminController
{
use CustomActionTrait;
protected string $serviceName = ProjectCateService::class;
public function list(): Page
{
$crud = $this->baseCRUD()->tableLayout('fixed')
->headerToolbar([
$this->createTypeButton('drawer', 'md'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
// amis()->TextControl('id', __('admin.project_cates.id'))->columnRatio(3)
// ->placeholder(__('admin.id')),
amis()->TextControl('title', __('admin.project_cates.title'))->columnRatio(3)
->placeholder(__('admin.project_cates.title')),
]),
]))
->columns([
amis()->TableColumn('id', 'ID')->sortable()->width('50px'),
amis()->TableColumn('title', __('admin.project_cates.title')),
amis()->TableColumn('cover_url', __('admin.project_cates.cover'))->type('image')->height('50px')->width('250px')->enlargeAble(true),
// amis()->TableColumn('description', __('admin.project_cates.description')),
amis()->TableColumn('created_at', __('admin.created_at'))->set('type', 'datetime')->sortable()->width('150px'),
amis()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditTypeButton('drawer', 'md'),
$this->rowDeleteButton(),
])
]);
return $this->baseList($crud);
}
public function form($isEdit = false): Form
{
return $this->baseForm()->panelClassName('px-0')->body([
amis()->Grid()->columns([
amis()->Wrapper()->body([
amis()->TextControl('title', __('admin.project_cates.title'))->required(true),
Components::make()->cropImageControl('cover', __('admin.project_cates.cover'))->required(true),
amis()->TextareaControl('description', __('admin.project_cates.description')),
Components::make()->sortControl('sort', __('admin.project_cates.sort')),
])
]),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\ProjectArticleService;
use App\Traits\CustomActionTrait;
use App\Admin\Components;
use App\Models\{ProjectArticle,ProjectCate};
use Slowlyo\OwlAdmin\Admin;
/**
* 服务流程
*
* @property ProjectArticleService $service
*/
class ProjectFlowController extends AdminController
{
use CustomActionTrait;
protected string $serviceName = ProjectArticleService::class;
public function list(): Page
{
$crud = $this->baseCRUD()->tableLayout('fixed')
->headerToolbar([
$this->createTypeButton('drawer', 'md'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
// amis()->TextControl('id', __('admin.project_articles.id'))->columnRatio(3)
// ->placeholder(__('admin.id')),
amis()->TextControl('title', __('admin.project_articles.title'))->columnRatio(3)
->placeholder(__('admin.project_articles.title')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->columnRatio(3)
->placeholder(__('admin.project_articles.cate')),
]),
]))
->columns([
// amis()->TableColumn('id', __('admin.id'))->sortable(true)->width('50px'),
amis()->TableColumn('title', __('admin.project_articles.title'))->width('300px'),
amis()->TableColumn('cate', __('admin.project_articles.cate'))->type('mapping')
->map(ProjectCate::get()->pluck('title', 'id')->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_url', __('admin.project_articles.cover'))->type('image')->height('50px')->width('150px')->enlargeAble(true),
// amis()->TableColumn('published_at', __('admin.project_articles.published_at'))->remark(__('admin.project_articles.published_at_remark')),
amis()->TableColumn('is_enable', __('admin.project_articles.is_enable'))->type('switch'),
// amis()->TableColumn('is_recommend', __('admin.articles.is_recommend'))->type('switch'),
amis()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
amis()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditTypeButton('drawer', 'md'),
$this->rowDeleteButton(),
])
]);
return $this->baseList($crud);
}
public function form($isEdit = false): Form
{
return $this->baseForm()->panelClassName('px-0')->body([
amis()->Grid()->columns([
amis()->Wrapper()->body([
amis()->TextControl('title', __('admin.project_articles.title'))->required(true),
// amis()->TextareaControl('description', __('admin.project_articles.description')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->required(true),
amis()->TextControl('type', __('admin.project_articles.type'))->value(ProjectArticle::TYPE_FLOW)->hidden(true),
// Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'),
Components::make()->cropImageControl('cover', __('admin.project_articles.cover'))->required(true),
Components::make()->sortControl('sort', __('admin.project_articles.sort')),
// amis()->DateTimeControl('published_at', __('admin.project_articles.published_at'))->format('YYYY-MM-DD HH:mm:ss')->description(__('admin.project_articles.published_at_remark')),
amis()->SwitchControl('is_enable', __('admin.project_articles.is_enable'))->value(false),
// amis()->SwitchControl('is_recommend', __('admin.project_articles.is_recommend'))->value(false),
// Components::make()->fileControl('appendixes', __('admin.articles.appendixes'), '.xsl,.xlsx,.txt,.doc,.docx,.pdf,.pptx'),
])
// amis()->Wrapper()->body([
// Components::make()->fuEditorControl('content', __('admin.project_articles.content'))->required(true),
// ])->md(8)
]),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\ProjectArticleService;
use App\Traits\CustomActionTrait;
use App\Admin\Components;
use App\Models\{ProjectArticle,ProjectCate};
use Slowlyo\OwlAdmin\Admin;
/**
* 服务流程
*
* @property ProjectArticleService $service
*/
class ProjectPhotoController extends AdminController
{
use CustomActionTrait;
protected string $serviceName = ProjectArticleService::class;
public function list(): Page
{
$crud = $this->baseCRUD()->tableLayout('fixed')
->headerToolbar([
$this->createTypeButton('drawer', 'md'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
// amis()->TextControl('id', __('admin.project_articles.id'))->columnRatio(3)
// ->placeholder(__('admin.id')),
amis()->TextControl('title', __('admin.project_articles.title'))->columnRatio(3)
->placeholder(__('admin.project_articles.title')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->columnRatio(3)
->placeholder(__('admin.project_articles.cate')),
]),
]))
->columns([
// amis()->TableColumn('id', __('admin.id'))->sortable(true)->width('50px'),
amis()->TableColumn('title', __('admin.project_articles.title'))->width('300px'),
amis()->TableColumn('cate', __('admin.project_articles.cate'))->type('mapping')
->map(ProjectCate::get()->pluck('title', 'id')->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_url', __('admin.project_articles.cover'))->type('image')->height('50px')->width('150px')->enlargeAble(true),
// amis()->TableColumn('published_at', __('admin.project_articles.published_at'))->remark(__('admin.project_articles.published_at_remark')),
amis()->TableColumn('is_enable', __('admin.project_articles.is_enable'))->type('switch'),
// amis()->TableColumn('is_recommend', __('admin.articles.is_recommend'))->type('switch'),
amis()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true),
amis()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditTypeButton('drawer', 'md'),
$this->rowDeleteButton(),
])
]);
return $this->baseList($crud);
}
public function form($isEdit = false): Form
{
return $this->baseForm()->panelClassName('px-0')->body([
amis()->Grid()->columns([
amis()->Wrapper()->body([
amis()->TextControl('title', __('admin.project_articles.title'))->required(true),
// amis()->TextareaControl('description', __('admin.project_articles.description')),
amis()->selectControl('cate', __('admin.project_articles.cate'))->options(ProjectCate::get()->pluck('title', 'id'))->required(true),
amis()->TextControl('type', __('admin.project_articles.type'))->value(ProjectArticle::TYPE_PHOTO)->hidden(true),
// Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'),
Components::make()->cropImageControl('cover', __('admin.project_articles.cover'))->required(true),
Components::make()->sortControl('sort', __('admin.project_articles.sort')),
// amis()->DateTimeControl('published_at', __('admin.project_articles.published_at'))->format('YYYY-MM-DD HH:mm:ss')->description(__('admin.project_articles.published_at_remark')),
amis()->SwitchControl('is_enable', __('admin.project_articles.is_enable'))->value(false),
// amis()->SwitchControl('is_recommend', __('admin.project_articles.is_recommend'))->value(false),
// Components::make()->fileControl('appendixes', __('admin.articles.appendixes'), '.png,.jpg')->multiple(true),
])
// amis()->Wrapper()->body([
// Components::make()->fuEditorControl('content', __('admin.project_articles.content'))->required(true),
// ])->md(8)
]),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([]);
}
}

View File

@ -32,6 +32,13 @@ Route::group([
$router->resource('ads', \App\Admin\Controllers\AdController::class);
//新站调整;
$router->resource('project_cates', \App\Admin\Controllers\ProjectCateController::class);
$router->resource('project_articles', \App\Admin\Controllers\ProjectArticleController::class);
$router->resource('project_flows', \App\Admin\Controllers\ProjectFlowController::class);
$router->resource('project_photos', \App\Admin\Controllers\ProjectPhotoController::class);
$router->resource('project_advances', \App\Admin\Controllers\ProjectAdvanceController::class);
//修改上传
$router->post('upload_file', [\App\Admin\Controllers\IndexController::class, 'uploadFile']);
$router->post('upload_image', [\App\Admin\Controllers\IndexController::class, 'uploadImage']);

View File

@ -0,0 +1,32 @@
<?php
namespace App\Models\Filters;
use EloquentFilter\ModelFilter;
use Illuminate\Support\Arr;
class ProjectArticleFilter extends ModelFilter
{
/**
* 主键
*/
public function id($id)
{
return $this->where('id', $id);
}
/**
* 标题
*/
public function title($title)
{
return $this->where('title','like', '%'.$title.'%');
}
/**
* 类型
*/
public function type($type)
{
return $this->where('type', $type);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Models\Filters;
use EloquentFilter\ModelFilter;
use Illuminate\Support\Arr;
class ProjectCateFilter extends ModelFilter
{
/**
* 主键
*/
public function id($id)
{
return $this->where('id', $id);
}
/**
* 标题
*/
public function title($title)
{
return $this->where('title','like', '%'.$title.'%');
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Casts\Attribute;
class ProjectArticle extends Model
{
use HasFactory;
use Filterable;
public const TYPE_ARTICLE = 1; //服务子类
public const TYPE_FLOW = 2; //服务流程
public const TYPE_PHOTO = 3; //相关图片
public const TYPE_ADVANCE = 4; //核心优势
protected function serializeDate(\DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
protected $appends = ['tags', 'cover_url'];
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',
'appendixes' => 'array',
];
protected $fillable = [
'title',
'description',
'content',
'cover',
'cate',
'type',
't_ids',
'published_at',
'is_enable',
'is_recommend',
'sort',
'appendixes',
];
protected function coverUrl():Attribute {
return Attribute::make(
get: fn($value) => $this->cover ? (Str::startsWith($this->cover, ['http://', 'https://']) ? $this->cover : Storage::url($this->cover)) : null,
);
}
public function scopeRecommend($q){
$q->where('is_recommend', true);
}
public function scopeShow($q){
$q->where('is_enable', true)->where('published_at', '<=', now());
}
public function scopeSort($q)
{
$q->orderBy('is_recommend', 'desc')
->orderBy('sort', 'asc')
->orderBy('published_at', 'desc')
->orderBy('created_at', 'desc');
}
protected function tags():Attribute
{
return Attribute::make(
get: fn($value) => $this->t_ids ? explode(',', $this->t_ids) : [],
);
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
class ProjectCate extends Model
{
use HasFactory;
use Filterable;
protected $appends = ['cover_url'];
protected function serializeDate(\DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
protected $casts = [
'created_at' => 'datetime:Y-m-d H:i:s',
'updated_at' => 'datetime:Y-m-d H:i:s',
];
protected function coverUrl():Attribute {
return Attribute::make(
get: fn($value) => $this->cover ? (Str::startsWith($this->cover, ['http://', 'https://']) ? $this->cover : Storage::url($this->cover)) : null,
);
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace App\Services\Admin;
use App\Models\ProjectArticle;
use App\Models\Filters\ProjectArticleFilter;
use App\Traits\UploadTrait;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
/**
* @method ProjectArticle getModel()
* @method ProjectArticle|\Illuminate\Database\Query\Builder query()
*/
class ProjectArticleService extends BaseService
{
use UploadTrait;
protected string $modelName = ProjectArticle::class;
protected string $modelFilterName = ProjectArticleFilter::class;
public function listQuery()
{
$currentUrl = url()->current();
$query= parent::listQuery();
if(Str::contains($currentUrl, 'project_articles')){
$query->where('type', ProjectArticle::TYPE_ARTICLE);
}elseif(Str::contains($currentUrl, 'project_flows')){
$query->where('type', ProjectArticle::TYPE_FLOW);
}elseif(Str::contains($currentUrl, 'project_photos')){
$query->where('type', ProjectArticle::TYPE_PHOTO);
}elseif(Str::contains($currentUrl, 'project_advances')){
$query->where('type', ProjectArticle::TYPE_ADVANCE);
}
return $query;
}
public function store($data): bool
{
$columns = $this->getTableColumns();
$model = $this->getModel();
$isEnable = Arr::get($data, 'is_enabled');
$publishedAt = Arr::get($data, 'published_at');
if ($isEnable && empty($publishedAt)) {
$data['published_at'] = now();
}
$data['cover'] = $this->saveImage('cover', 'project_articles/cover')[0] ?? '';
$data['appendixes'] = $this->saveFile('appendixes', 'project_articles/appendixes');
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
public function update($primaryKey, $data): bool
{
$columns = $this->getTableColumns();
$model = $this->query()->whereKey($primaryKey)->first();
$isEnable = Arr::get($data, 'is_enable');
$publishedAt = Arr::get($data, 'published_at');
if ($isEnable && empty($publishedAt) && empty($model->published_at)) {
$data['published_at'] = now();
}
if(isset($data['cover'])){
$data['cover'] = $this->saveImage('cover', 'project_articles/covers')[0] ?? '';
}
if(isset($data['appendixes'])){
$data['appendixes'] = $this->saveFile('appendixes', 'project_articles/appendixes');
}
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace App\Services\Admin;
use App\Models\ProjectCate;
use App\Models\Filters\ProjectCateFilter;
use App\Traits\UploadTrait;
use Illuminate\Support\Arr;
/**
* @method ProjectCate getModel()
* @method ProjectCate|\Illuminate\Database\Query\Builder query()
*/
class ProjectCateService extends BaseService
{
use UploadTrait;
protected string $modelName = ProjectCate::class;
protected string $modelFilterName = ProjectCateFilter::class;
public function store($data): bool
{
$columns = $this->getTableColumns();
$model = $this->getModel();
$data['cover'] = $this->saveImage('cover', 'project_cates/cover')[0] ?? '';
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
public function update($primaryKey, $data): bool
{
$columns = $this->getTableColumns();
$model = $this->query()->whereKey($primaryKey)->first();
if(isset($data['cover'])){
$data['cover'] = $this->saveImage('cover', 'project_cates/cover')[0] ?? '';
}
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
}

View File

@ -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('project_cates', function (Blueprint $table) {
$table->id();
$table->string('title')->comment('标题');
$table->text('description')->nullable()->comment('简介');
$table->string('cover')->nullable()->comment('封面');
$table->unsignedInteger('sort')->default(0)->comment('排序');
$table->text('content')->nullable()->comment('内容');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('project_cates');
}
};

View File

@ -0,0 +1,43 @@
<?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('project_articles', function (Blueprint $table) {
$table->id();
$table->string('title')->comment('标题');
$table->text('description')->nullable()->comment('简介');
$table->text('content')->nullable()->comment('内容');
$table->string('cover')->nullable()->comment('封面');
$table->unsignedInteger('cate')->nullable()->comment('业务范围');
$table->unsignedTinyInteger('type')->nullable()->comment('分类:1业务子类2服务流程3相关图片4核心优势5服务案例');
$table->string('t_ids')->nullable()->comment('标签');
$table->timestamp('published_at')->nullable()->comment('发布时间');
$table->unsignedTinyInteger('is_enable')->default(1)->comment('显示开关');
$table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐开关');
$table->unsignedInteger('sort')->default(0)->comment('排序');
$table->text('appendixes')->nullable()->comment('附件');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('project_articles');
}
};

View File

@ -20,22 +20,43 @@ class AdminMenuSeeder extends Seeder
//
$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,
['title'=>'projects', 'icon'=>'ic:outline-article','url'=>'/projects', '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'=> 'project_cates', 'icon'=>'', 'url'=>'/project_cates', 'order'=>1, ],
['title'=> 'project_articles', 'icon'=>'', 'url'=>'/project_articles', 'order'=>2],
['title'=> 'project_flows', 'icon'=>'', 'url'=>'/project_flows', 'order'=>3],
['title'=> 'project_photos', 'icon'=>'', 'url'=>'/project_photos', 'order'=>4],
['title'=> 'project_advances', 'icon'=>'', 'url'=>'/project_advances', 'order'=>5],
]
],
['title' => 'web_content', 'icon' => 'ic:outline-collections-bookmark', 'url' => '/web_content', 'order'=>3,
'children' =>[
['title'=>'news', 'icon'=>'','url'=>'/articles', 'order'=>1],
['title'=>'ads', 'icon'=>'','url'=>'/ads', 'order'=>2],
]
],
['title' => 'admin_system', 'icon' => 'material-symbols:settings-outline', 'url' => '/system', 'order'=>4,
'children' => [
['title' => 'admin_users', 'icon' => '', 'url' => '/system/admin_users', 'order'=>1],
['title' => 'admin_roles', 'icon' => '', 'url' => '/system/admin_roles', 'order'=>2],
['title' => 'admin_permission', 'icon' => '', 'url' => '/system/admin_permissions', 'order'=>3],
['title' => 'admin_menu', 'icon' => '', 'url' => '/system/admin_menus', 'order'=>4],
['title' => 'admin_setting', 'icon' => '', 'url' => '/system/settings', 'order'=>5],
['title' => 'keywords', 'icon' => '', '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],
]
]
// ['title'=>'case_studies', 'icon'=>'lets-icons:img-box','url'=>'', 'order'=>2,
// 'children'=>[
// ['title'=> 'case_study_tags', 'icon'=>'lets-icons:img-box','url'=>'/case_study_tags', 'order'=>1 ],
// ['title'=> 'case_study_articles', 'icon'=>'lets-icons:img-box','url'=>'/case_study_articles', 'order'=>2 ],
// ]
// ],
// ['title'=> 'news', 'icon'=>'lets-icons:img-box','url'=>'/news', 'order'=>3],
// ['title'=> 'contacts', 'icon'=>'lets-icons:img-box','url'=>'/contacts', 'order'=>4],
// ['title'=> 'friend_links' , 'icon'=>'lets-icons:img-box','url'=>'/contacts', 'order'=>5]
];
DB::table('admin_menus')->truncate();
try {

View File

@ -303,5 +303,30 @@ return [
'mini_id' => '小程序ID',
'mini_link'=> '小程序路径'
],
]
],
'project_cates' => [
'id' => '主键ID',
'title' => '标题',
'description'=> '简介',
'content' => '内容',
'cover' =>'封面',
'sort' => '排序'
],
'project_articles' => [
'id' => '主键ID',
'title' => '标题',
'description'=> '简介',
'content' => '内容',
'cover' =>'封面',
'cate' => '业务范围',
'tags' => '标签',
't_ids' => '标签',
'published_at' => '定时发布',
'published_at_g' => '发布时间',
'is_enable' => '显示',
'is_recommend' => '推荐',
'sort' => '排序',
'appendixes' => '附件',
'published_at_remark' => '*若未设置发布时间且操作设置为显示,则默认生成发布时间',
],
];

View File

@ -13,4 +13,18 @@ return [
'web_content' => '内容管理',
'articles' => '文章管理',
'ads' => '广告管理',
'web_manager' => '网站管理',
'projects' => '主营业务',
'project_cates' => '业务范围',
'project_articles' => '服务子类',
'project_flows' => '服务流程',
'project_photos' => '相关图片',
'project_advances' => '核心优势',
'case_studies' => '服务案例',
'case_study_tags' => '案例标签',
'case_study_articles' => '案例内容',
'news' => '企业资讯',
'contacts' => '在线询价',
'friend_links' => '合作伙伴'
];