From 137512b735fc6169a5f7e895653453e60f7a7072 Mon Sep 17 00:00:00 2001 From: liutk <961510893@qq.com> Date: Sun, 22 Feb 2026 23:01:55 +0800 Subject: [PATCH] 0.7 --- app/Admin/Controllers/ArticleController.php | 12 +-- app/Admin/Controllers/HonorController.php | 95 +++++++++++++++++++ app/Admin/Controllers/TimelineController.php | 72 ++++++++++++++ app/Admin/routes.php | 2 + app/Models/Filters/HonorFilter.php | 40 ++++++++ app/Models/Filters/TimelineFilter.php | 29 ++++++ app/Models/Honor.php | 42 ++++++++ app/Models/Timeline.php | 38 ++++++++ app/Services/Admin/HonorService.php | 61 ++++++++++++ app/Services/Admin/TimelineService.php | 61 ++++++++++++ .../2026_02_22_212125_create_honors_table.php | 37 ++++++++ ...26_02_22_225324_create_timelines_table.php | 34 +++++++ database/seeders/AdminMenuSeeder.php | 10 +- database/seeders/KeywordSeeder.php | 12 ++- lang/zh_CN/admin.php | 22 ++++- lang/zh_CN/menu.php | 4 +- 16 files changed, 553 insertions(+), 18 deletions(-) create mode 100644 app/Admin/Controllers/HonorController.php create mode 100644 app/Admin/Controllers/TimelineController.php create mode 100644 app/Models/Filters/HonorFilter.php create mode 100644 app/Models/Filters/TimelineFilter.php create mode 100644 app/Models/Honor.php create mode 100644 app/Models/Timeline.php create mode 100644 app/Services/Admin/HonorService.php create mode 100644 app/Services/Admin/TimelineService.php create mode 100644 database/migrations/2026_02_22_212125_create_honors_table.php create mode 100644 database/migrations/2026_02_22_225324_create_timelines_table.php diff --git a/app/Admin/Controllers/ArticleController.php b/app/Admin/Controllers/ArticleController.php index 84e5b71..82e9b1a 100644 --- a/app/Admin/Controllers/ArticleController.php +++ b/app/Admin/Controllers/ArticleController.php @@ -30,10 +30,8 @@ class ArticleController extends AdminController ->placeholder(__('admin.id')), amis()->TextControl('title', __('admin.articles.title')) ->placeholder(__('admin.articles.title')), - 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'), - ]), - amis()->GroupControl()->mode('horizontal')->body([ + // 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'), amis()->SelectControl('enable', __('admin.articles.is_enable')) ->columnRatio(3) ->options([ @@ -44,10 +42,10 @@ class ArticleController extends AdminController ->options([ 1=>'开启',0=>'关闭' ]), - amis()->InputDatetimeRange()->label(__('admin.articles.published_at'))->name('published_at'), ]), - amis()->GroupControl()->mode('horizontal')->body([ - amis()->InputDatetimeRange()->label(__('admin.created_at'))->name('created_at')->columnRatio(6), + amis()->GroupControl()->mode('horizontal')->body([ + amis()->InputDatetimeRange()->label(__('admin.articles.published_at'))->name('published_at'), + amis()->InputDatetimeRange()->label(__('admin.created_at'))->name('created_at'), ]), ])) ->itemBadge([//行角标 diff --git a/app/Admin/Controllers/HonorController.php b/app/Admin/Controllers/HonorController.php new file mode 100644 index 0000000..a2dc572 --- /dev/null +++ b/app/Admin/Controllers/HonorController.php @@ -0,0 +1,95 @@ +baseCRUD()->tableLayout('fixed') + ->headerToolbar([ + $this->createTypeButton('drawer', 'md'), + ...$this->baseHeaderToolBar(), + ]) + ->filter($this->baseFilter()->body([ + amis()->GroupControl()->mode('horizontal')->body([ + amis()->TextControl('title', __('admin.honors.title')) + ->placeholder(__('admin.honors.title')), + amis()->selectControl('cate', __('admin.honors.category'))->options(Keyword::allChildrenOfKey('honors')->pluck('name', 'id')) + ->placeholder(__('admin.honors.category')), + amis()->SelectControl('enable', __('admin.honors.is_enable')) + ->columnRatio(3) + ->options([ + 1=>'开启',0=>'关闭' + ]), + amis()->SelectControl('recommend', __('admin.honors.is_recommend')) + ->columnRatio(3) + ->options([ + 1=>'开启',0=>'关闭' + ]), + ]), + ])) + ->itemBadge([//行角标 + 'text' => __('admin.honors.is_recommend'), + 'mode' => 'ribbon', + 'position' => 'top-left', + 'badgeLevel' => 'danger', + 'visibleOn' => '${is_recommend > 0}', + 'size' => 15 + ]) + ->columns([ + amis()->TableColumn('id', __('admin.id'))->sortable(true), + amis()->TableColumn('title', __('admin.honors.title'))->width('300px'), + amis()->TableColumn('category', __('admin.honors.category'))->type('mapping') + ->map(Keyword::allChildrenOfKey('honors')->pluck('name', 'id')->toArray()) + ->itemSchema(amis()->Tag()->label('${item}')->color(Admin::setting()->get('system_theme_setting')['theme_color'] ?? '#1677ff')), + amis()->TableColumn('cover_url', __('admin.articles.cover'))->type('image')->height('50px')->width('50px')->enlargeAble(true), + amis()->TableColumn('awarded_date', __('admin.honors.awarded_date')), + amis()->TableColumn('is_enable', __('admin.honors.is_enable'))->type('switch'), + amis()->TableColumn('is_recommend', __('admin.honors.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(): Form + { + return $this->baseForm()->panelClassName('px-0')->body([ + amis()->Grid()->columns([ + amis()->Wrapper()->body([ + amis()->TextControl('title', __('admin.honors.title'))->required(true), + amis()->selectControl('cate', __('admin.honors.category'))->options(Keyword::allChildrenOfKey('honors')->pluck('name', 'id'))->required(true), + Components::make()->cropImageControl('cover', __('admin.honors.cover'))->required(true), + amis()->DateControl('awarded_date', __('admin.honors.awarded_date'))->format('YYYY-MM-DD')->required(true), + Components::make()->sortControl('sort', __('admin.honors.sort')), + amis()->SwitchControl('is_enable', __('admin.honors.is_enable'))->value(false), + amis()->SwitchControl('is_recommend', __('admin.honors.is_recommend'))->value(false), + ]), + ]), + ]); + } + + public function detail(): Form + { + return $this->baseDetail()->body([]); + } + +} \ No newline at end of file diff --git a/app/Admin/Controllers/TimelineController.php b/app/Admin/Controllers/TimelineController.php new file mode 100644 index 0000000..69fc1bc --- /dev/null +++ b/app/Admin/Controllers/TimelineController.php @@ -0,0 +1,72 @@ +baseCRUD()->tableLayout('fixed') + ->headerToolbar([ + $this->createTypeButton('drawer', 'md'), + ...$this->baseHeaderToolBar(), + ]) + ->filter($this->baseFilter()->body([ + amis()->GroupControl()->mode('horizontal')->body([ + amis()->TextControl('title', __('admin.timelines.title'))->columnRatio(3) + ->placeholder(__('admin.timelines.title')), + ]), + ])) + ->columns([ + // amis()->TableColumn('id', __('admin.id'))->sortable(true)->width('50px'), + amis()->TableColumn('title', __('admin.timelines.title'))->width('300px'), + amis()->TableColumn('cover_url', __('admin.timelines.cover'))->type('image')->height('50px')->width('150px')->enlargeAble(true), + amis()->TableColumn('awarded_date', __('admin.timelines.awarded_date')), + amis()->TableColumn('is_enable', __('admin.timelines.is_enable'))->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.timelines.title'))->required(true), + amis()->TextareaControl('description', __('admin.timelines.description')), + Components::make()->cropImageControl('cover', __('admin.timelines.cover')), + amis()->DateControl('awarded_date', __('admin.timelines.awarded_date'))->format('YYYY-MM-DD')->required(true), + Components::make()->sortControl('sort', __('admin.timelines.sort')), + amis()->SwitchControl('is_enable', __('admin.timelines.is_enable'))->value(false), + ]) + ]), + ]); + } + + public function detail(): Form + { + return $this->baseDetail()->body([]); + } +} diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 3f1462f..ba0c507 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -40,6 +40,8 @@ Route::group([ $router->resource('project_advances', \App\Admin\Controllers\ProjectAdvanceController::class); $router->resource('case_studies', \App\Admin\Controllers\CaseStudyController::class); $router->resource('friend_links', \App\Admin\Controllers\FriendLinkController::class); + $router->resource('honors', \App\Admin\Controllers\HonorController::class); + $router->resource('timelines', \App\Admin\Controllers\TimelineController::class); //修改上传 $router->post('upload_file', [\App\Admin\Controllers\IndexController::class, 'uploadFile']); diff --git a/app/Models/Filters/HonorFilter.php b/app/Models/Filters/HonorFilter.php new file mode 100644 index 0000000..5845782 --- /dev/null +++ b/app/Models/Filters/HonorFilter.php @@ -0,0 +1,40 @@ +where('id', $id); + } + /** + * 标题 + */ + public function title($title) + { + return $this->where('title','like', '%'.$title.'%'); + } + + /** + * 获取分类下的荣誉 + */ + public function category($category) + { + return $this->where('category', $category); + } + + public function enable($enable){ + return $this->where('is_enable', $enable); + } + + public function recommend($recommend){ + return $this->where('is_recommend', $recommend); + } +} diff --git a/app/Models/Filters/TimelineFilter.php b/app/Models/Filters/TimelineFilter.php new file mode 100644 index 0000000..6e7fb60 --- /dev/null +++ b/app/Models/Filters/TimelineFilter.php @@ -0,0 +1,29 @@ +where('id', $id); + } + /** + * 标题 + */ + public function title($title) + { + return $this->where('title','like', '%'.$title.'%'); + } + + public function enable($enable){ + return $this->where('is_enable', $enable); + } + +} diff --git a/app/Models/Honor.php b/app/Models/Honor.php new file mode 100644 index 0000000..fc702d2 --- /dev/null +++ b/app/Models/Honor.php @@ -0,0 +1,42 @@ +format('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, + ); + } + + public function scopeRecommend($q){ + $q->where('is_recommend', true); + } + + public function scopeShow($q){ + $q->where('is_enable', true); + } + + public function scopeSort($q) + { + $q->orderBy('awarded_date', 'desc') + ->orderBy('sort', 'asc') + ->orderBy('created_at', 'desc'); + } +} diff --git a/app/Models/Timeline.php b/app/Models/Timeline.php new file mode 100644 index 0000000..16ca08c --- /dev/null +++ b/app/Models/Timeline.php @@ -0,0 +1,38 @@ +format('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, + ); + } + + public function scopeShow($q){ + $q->where('is_enable', true); + } + + public function scopeSort($q) + { + $q->orderBy('awarded_date', 'desc') + ->orderBy('sort', 'asc') + ->orderBy('created_at', 'desc'); + } +} diff --git a/app/Services/Admin/HonorService.php b/app/Services/Admin/HonorService.php new file mode 100644 index 0000000..cbdb65e --- /dev/null +++ b/app/Services/Admin/HonorService.php @@ -0,0 +1,61 @@ +getTableColumns(); + $model = $this->getModel(); + + $data['cover'] = $this->saveImage('cover', 'honors/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', 'honors/cover')[0] ?? ''; + } + + foreach ($data as $k => $v) { + if (!in_array($k, $columns)) { + continue; + } + + $model->setAttribute($k, $v); + } + + return $model->save(); + } +} \ No newline at end of file diff --git a/app/Services/Admin/TimelineService.php b/app/Services/Admin/TimelineService.php new file mode 100644 index 0000000..a4eed79 --- /dev/null +++ b/app/Services/Admin/TimelineService.php @@ -0,0 +1,61 @@ +getTableColumns(); + $model = $this->getModel(); + + $data['cover'] = $this->saveImage('cover', 'honors/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', 'honors/cover')[0] ?? ''; + } + + foreach ($data as $k => $v) { + if (!in_array($k, $columns)) { + continue; + } + + $model->setAttribute($k, $v); + } + + return $model->save(); + } +} \ No newline at end of file diff --git a/database/migrations/2026_02_22_212125_create_honors_table.php b/database/migrations/2026_02_22_212125_create_honors_table.php new file mode 100644 index 0000000..a66e3cb --- /dev/null +++ b/database/migrations/2026_02_22_212125_create_honors_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('title')->comment('标题'); + $table->string('cover')->nullable()->comment('封面'); + + $table->unsignedInteger('category')->nullable()->comment('分类'); + + $table->date('awarded_date')->nullable()->comment('获得日期'); + $table->unsignedTinyInteger('is_enable')->default(1)->comment('显示开关'); + + $table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐开关'); + $table->unsignedInteger('sort')->default(0)->comment('排序'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('honors'); + } +}; diff --git a/database/migrations/2026_02_22_225324_create_timelines_table.php b/database/migrations/2026_02_22_225324_create_timelines_table.php new file mode 100644 index 0000000..bcaa9c2 --- /dev/null +++ b/database/migrations/2026_02_22_225324_create_timelines_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('title')->comment('标题'); + $table->text('description')->nullable()->comment('简介'); + $table->string('cover')->nullable()->comment('封面'); + $table->date('awarded_date')->nullable()->comment('日期'); + $table->unsignedTinyInteger('is_enable')->default(1)->comment('显示开关'); + + $table->unsignedInteger('sort')->default(0)->comment('排序'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('timelines'); + } +}; diff --git a/database/seeders/AdminMenuSeeder.php b/database/seeders/AdminMenuSeeder.php index 84117ec..73bea8e 100644 --- a/database/seeders/AdminMenuSeeder.php +++ b/database/seeders/AdminMenuSeeder.php @@ -29,11 +29,14 @@ class AdminMenuSeeder extends Seeder ['title'=> 'project_advances', 'icon'=>'', 'url'=>'/project_advances', 'order'=>5], ] ], - ['title'=>'case_studies', 'icon'=>'carbon:cloud-satellite-services','url'=>'/case_studies', 'order'=>3], + // ['title'=>'case_studies', 'icon'=>'carbon:cloud-satellite-services','url'=>'/case_studies', 'order'=>3], ['title' => 'web_content', 'icon' => 'ic:outline-collections-bookmark', 'url' => '/web_content', 'order'=>4, 'children' =>[ ['title'=>'news', 'icon'=>'','url'=>'/articles', 'order'=>1], - ['title'=>'ads', 'icon'=>'','url'=>'/ads', 'order'=>2], + ['title'=>'honors', 'icon'=>'','url'=>'/honors', 'order'=>2], + ['title'=>'case_studies', 'icon'=>'','url'=>'/case_studies', 'order'=>3], + ['title'=>'timelines', 'icon'=>'','url'=>'/timelines', 'order'=>4], + ['title'=>'ads', 'icon'=>'','url'=>'/ads', 'order'=>5], ] ], ['title'=> 'contacts', 'icon'=>'fluent-mdl2:chat-invite-friend','url'=>'/contacts', 'order'=>5], @@ -48,9 +51,6 @@ class AdminMenuSeeder extends Seeder ['title' => 'keywords', 'icon' => '', 'url' => '/system/keywords', 'order'=>6] ], ], - - - ]; DB::table('admin_menus')->truncate(); try { diff --git a/database/seeders/KeywordSeeder.php b/database/seeders/KeywordSeeder.php index 08dcd33..78c1c87 100644 --- a/database/seeders/KeywordSeeder.php +++ b/database/seeders/KeywordSeeder.php @@ -18,14 +18,18 @@ class KeywordSeeder extends Seeder Keyword::truncate(); $list = [ // ['key' => 'article_category', 'name' => '文章分类', 'list' => [ - // 'examples'=>'案例', 'services' =>'服务', 'news'=> '资讯动态' + // 'news'=> '企业资讯', 'honors'=>'资质荣誉', // ]], - ['key' => 'case_study_tag', 'name' => '服务案例标签', 'list' => [//标签value填写色号,指定标签颜色 - - ]], + ['key' => 'banner_address', 'name' => '广告位置', 'list' => [ 'index-top'=>'首页', 'companny-top' =>'关于我们', 'project-top'=>'业务范围', 'examples-top'=> '案例展示', 'news-top'=>'资讯动态','contactus-top'=>'联系我们' ]], + ['key' => 'honors', 'name' => '资质荣誉', 'list' => [ + + ]], + ['key' => 'case_study_tag', 'name' => '服务案例标签', 'list' => [//标签value填写色号,指定标签颜色 + + ]], ]; foreach ($list as $item) { diff --git a/lang/zh_CN/admin.php b/lang/zh_CN/admin.php index d0183db..1cf8e6c 100644 --- a/lang/zh_CN/admin.php +++ b/lang/zh_CN/admin.php @@ -353,5 +353,25 @@ return [ 'sort' => '排序', 'is_enable' => '显示', 'link'=>'链接地址' - ] + ], + 'honors' => [ + 'id' => '主键ID', + 'title' => '标题', + 'cover' =>'封面', + 'category' => '分类', + 'awarded_date' => '获奖日期', + 'is_enable' => '显示', + 'is_recommend' => '推荐', + 'sort' => '排序', + ], + 'timelines' => [ + 'id' => '主键ID', + 'title' => '标题', + 'description'=> '简介', + 'cover' =>'封面', + 'awarded_date' => '日期', + 'is_enable' => '显示', + 'is_recommend' => '推荐', + 'sort' => '排序', + ], ]; diff --git a/lang/zh_CN/menu.php b/lang/zh_CN/menu.php index 3b8358d..b663e37 100644 --- a/lang/zh_CN/menu.php +++ b/lang/zh_CN/menu.php @@ -12,7 +12,7 @@ return [ 'keywords' => '数据字典', 'web_content' => '内容管理', 'articles' => '文章管理', - 'ads' => '广告管理', + 'ads' => 'Banner管理', 'web_manager' => '网站管理', 'projects' => '主营业务', @@ -24,6 +24,8 @@ return [ 'case_studies' => '服务案例', 'case_study_tags' => '案例标签', 'case_study_articles' => '案例内容', + 'honors' => '荣誉资质', + 'timelines' => '发展历程', 'news' => '企业资讯', 'contacts' => '在线询价', 'friend_links' => '合作伙伴'