157 lines
5.8 KiB
PHP
157 lines
5.8 KiB
PHP
<?php
|
||
|
||
namespace App\Filament\Pages;
|
||
|
||
use App\Models\SiteSetting;
|
||
use Filament\Forms\Components\FileUpload;
|
||
use Filament\Forms\Components\Section;
|
||
use Filament\Forms\Components\Textarea;
|
||
use Filament\Forms\Components\TextInput;
|
||
use Filament\Forms\Components\Toggle;
|
||
use Filament\Forms\Concerns\InteractsWithForms;
|
||
use Filament\Forms\Contracts\HasForms;
|
||
use Filament\Forms\Form;
|
||
use Filament\Notifications\Notification;
|
||
use Filament\Pages\Page;
|
||
|
||
class SiteSettings extends Page implements HasForms
|
||
{
|
||
use InteractsWithForms;
|
||
|
||
protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';
|
||
protected static ?string $navigationLabel = '站点配置';
|
||
protected static ?string $navigationGroup = '站点设置';
|
||
protected static string $view = 'filament.pages.site-settings';
|
||
|
||
public ?array $data = [];
|
||
|
||
public function mount(): void
|
||
{
|
||
$this->form->fill($this->getSettings());
|
||
}
|
||
|
||
public function form(Form $form): Form
|
||
{
|
||
return $form
|
||
->schema([
|
||
Section::make('站点信息')
|
||
->schema([
|
||
TextInput::make('site_title')->label('站点标题')->required(),
|
||
TextInput::make('site_description')->label('站点描述'),
|
||
FileUpload::make('site_logo')
|
||
->label('站点 Logo')
|
||
->disk('public')
|
||
->directory('site')
|
||
->image()
|
||
->imagePreviewHeight('80')
|
||
->nullable(),
|
||
Textarea::make('site_footer')
|
||
->label('页脚文案')
|
||
->rows(2),
|
||
])->columns(2),
|
||
Section::make('首页配置')
|
||
->schema([
|
||
TextInput::make('home_featured_limit')->label('热门推荐数量')->numeric()->required(),
|
||
TextInput::make('home_new_limit')->label('新增产品数量')->numeric()->required(),
|
||
TextInput::make('home_category_limit')->label('分类展示数量')->numeric()->required(),
|
||
])->columns(3),
|
||
Section::make('列表配置')
|
||
->schema([
|
||
TextInput::make('list_page_size')->label('产品列表分页数')->numeric()->required(),
|
||
TextInput::make('list_more_threshold')->label('更多阈值')->numeric()->required(),
|
||
TextInput::make('article_page_size')->label('文章列表分页数')->numeric()->required(),
|
||
])->columns(3),
|
||
Section::make('评论与推广')
|
||
->schema([
|
||
Toggle::make('comments_enabled')->label('启用评论'),
|
||
Toggle::make('show_sponsor_label')->label('显示推广标识'),
|
||
])->columns(2),
|
||
Section::make('热度权重')
|
||
->schema([
|
||
TextInput::make('hot_weight_view')->label('浏览权重')->numeric()->required(),
|
||
TextInput::make('hot_weight_click')->label('点击权重')->numeric()->required(),
|
||
])->columns(2),
|
||
Section::make('SEO 与统计')
|
||
->schema([
|
||
TextInput::make('ga_id')->label('GA4 测量 ID')->nullable(),
|
||
TextInput::make('icp_number')->label('备案号')->nullable(),
|
||
Textarea::make('social_links')
|
||
->label('社交链接(每行:名称|URL)')
|
||
->rows(3)
|
||
->nullable(),
|
||
Textarea::make('about_content')
|
||
->label('关于页内容(Markdown)')
|
||
->rows(4)
|
||
->nullable(),
|
||
])->columns(2),
|
||
])
|
||
->statePath('data');
|
||
}
|
||
|
||
public function save(): void
|
||
{
|
||
$data = $this->form->getState();
|
||
|
||
foreach ($data as $key => $value) {
|
||
$value = $this->normalizeValue($value);
|
||
SiteSetting::updateOrCreate(['key' => $key], ['value' => $value]);
|
||
}
|
||
|
||
Notification::make()
|
||
->title('保存成功')
|
||
->success()
|
||
->send();
|
||
}
|
||
|
||
private function getSettings(): array
|
||
{
|
||
$defaults = [
|
||
'site_title' => 'AI 工具导航',
|
||
'site_description' => '精选 AI 工具与产品导航',
|
||
'site_logo' => null,
|
||
'site_footer' => '',
|
||
'home_featured_limit' => '8',
|
||
'home_new_limit' => '8',
|
||
'home_category_limit' => '20',
|
||
'list_page_size' => '20',
|
||
'list_more_threshold' => '20',
|
||
'article_page_size' => '10',
|
||
'comments_enabled' => '1',
|
||
'show_sponsor_label' => '1',
|
||
'hot_weight_view' => '1',
|
||
'hot_weight_click' => '3',
|
||
'ga_id' => '',
|
||
'icp_number' => '',
|
||
'social_links' => '',
|
||
'about_content' => SiteSetting::value('about_content', ''),
|
||
];
|
||
|
||
$data = [];
|
||
foreach ($defaults as $key => $default) {
|
||
$data[$key] = SiteSetting::value($key, $default);
|
||
}
|
||
|
||
$data['comments_enabled'] = $data['comments_enabled'] === '1';
|
||
$data['show_sponsor_label'] = $data['show_sponsor_label'] === '1';
|
||
|
||
return $data;
|
||
}
|
||
|
||
private function normalizeValue($value): ?string
|
||
{
|
||
if (is_bool($value)) {
|
||
return $value ? '1' : '0';
|
||
}
|
||
|
||
if (is_array($value)) {
|
||
return json_encode($value, JSON_UNESCAPED_UNICODE);
|
||
}
|
||
|
||
if ($value === null) {
|
||
return null;
|
||
}
|
||
|
||
return (string) $value;
|
||
}
|
||
}
|