Files
KnowledgeBase/app/Filament/Pages/ManageSystemSettings.php
lizhuoran 752dd908f0 feat: 实现系统设置管理界面
- SystemSettingResource: Filament 资源类
  - 使用 Tabs 组件按 group 分组显示配置
  - 使用 KeyValue 组件编辑 JSON 配置
  - 支持筛选、排序、搜索功能
  - 配置彩色徽章显示分组

- ManageSystemSettings: 系统设置管理页面
  - 按配置类型分组(嵌入模型/分块参数/系统配置/搜索配置)
  - 完整的表单验证规则
  - 保存和重置功能
  - 集成 SystemSettingService

- 创建对应的 Blade 视图和页面类
2026-03-09 10:08:17 +08:00

304 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Filament\Pages;
use App\Models\SystemSetting;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Pages\Page;
use Filament\Notifications\Notification;
class ManageSystemSettings extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';
protected static string $view = 'filament.pages.manage-system-settings';
protected static ?string $navigationLabel = '系统设置';
protected static ?string $title = '系统设置';
protected static ?int $navigationSort = 1;
public ?array $data = [];
public function mount(): void
{
$this->form->fill($this->getSettingsData());
}
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Tabs::make('配置分组')
->tabs([
// 嵌入模型配置
Forms\Components\Tabs\Tab::make('嵌入模型配置')
->icon('heroicon-o-cpu-chip')
->schema([
Forms\Components\Section::make('模型基础配置')
->description('配置嵌入模型的基本参数')
->schema([
Forms\Components\TextInput::make('embedding.model_name')
->label('模型名称')
->helperText('例如: text-embedding-3-small, text-embedding-ada-002')
->required()
->maxLength(255)
->minLength(3),
Forms\Components\TextInput::make('embedding.api_key')
->label('API 密钥')
->password()
->revealable()
->required()
->helperText('OpenAI API 密钥(敏感信息)')
->maxLength(255)
->minLength(20),
Forms\Components\TextInput::make('embedding.endpoint_url')
->label('API 端点 URL')
->url()
->helperText('嵌入模型的 API 端点地址')
->required()
->maxLength(500)
->prefix('https://'),
])
->columns(1),
Forms\Components\Section::make('模型参数配置')
->description('配置嵌入模型的高级参数')
->schema([
Forms\Components\TextInput::make('embedding.dimensions')
->label('向量维度')
->numeric()
->minValue(1)
->maxValue(4096)
->helperText('嵌入向量的维度大小')
->required(),
Forms\Components\TextInput::make('embedding.batch_size')
->label('批量处理大小')
->numeric()
->minValue(1)
->maxValue(1000)
->helperText('批量处理文档的数量')
->required(),
])
->columns(2),
]),
// 分块参数配置
Forms\Components\Tabs\Tab::make('分块参数配置')
->icon('heroicon-o-scissors')
->schema([
Forms\Components\Section::make('分块基础参数')
->description('配置文档分块的基本参数')
->schema([
Forms\Components\TextInput::make('chunking.chunk_size')
->label('分块大小')
->numeric()
->minValue(100)
->maxValue(10000)
->helperText('每个文档块的字符数')
->required()
->suffix('字符')
->default(1000),
Forms\Components\TextInput::make('chunking.chunk_overlap')
->label('分块重叠大小')
->numeric()
->minValue(0)
->maxValue(1000)
->helperText('相邻块之间的重叠字符数')
->required()
->suffix('字符')
->default(200),
Forms\Components\TextInput::make('chunking.min_chunk_size')
->label('最小分块大小')
->numeric()
->minValue(10)
->maxValue(1000)
->helperText('允许的最小块大小')
->required()
->suffix('字符')
->default(100),
])
->columns(3),
Forms\Components\Section::make('分块高级参数')
->description('配置文档分块的高级参数')
->schema([
Forms\Components\Textarea::make('chunking.separator')
->label('分块分隔符')
->helperText('用于分割文档的分隔符(支持转义字符如 \\n')
->rows(2)
->maxLength(100),
])
->columns(1),
]),
// 系统全局配置
Forms\Components\Tabs\Tab::make('系统全局配置')
->icon('heroicon-o-globe-alt')
->schema([
Forms\Components\Section::make('系统基础信息')
->description('配置系统的基本信息')
->schema([
Forms\Components\TextInput::make('system.name')
->label('系统名称')
->helperText('显示在系统界面上的名称')
->required()
->maxLength(255)
->default('知识库管理系统'),
])
->columns(1),
Forms\Components\Section::make('系统运行参数')
->description('配置系统的运行参数')
->schema([
Forms\Components\TextInput::make('system.timeout')
->label('请求超时时间')
->numeric()
->minValue(10)
->maxValue(300)
->helperText('API 请求的超时时间建议值60秒')
->required()
->suffix('秒')
->default(60),
Forms\Components\TextInput::make('system.max_retries')
->label('最大重试次数')
->numeric()
->minValue(0)
->maxValue(10)
->helperText('API 请求失败时的最大重试次数建议值3次')
->required()
->default(3),
])
->columns(2),
Forms\Components\Section::make('文件上传配置')
->description('配置文件上传的限制')
->schema([
Forms\Components\TextInput::make('system.max_upload_size')
->label('最大上传大小')
->numeric()
->minValue(1048576)
->maxValue(104857600)
->helperText('最大文件上传大小字节1MB = 104857610MB = 10485760100MB = 104857600')
->required()
->suffix('字节')
->default(10485760),
Forms\Components\TagsInput::make('system.allowed_file_types')
->label('允许的文件类型')
->helperText('允许上传的文件扩展名例如pdf, docx, txt, md')
->placeholder('输入文件类型后按回车')
->required()
->default(['pdf', 'docx', 'txt', 'md']),
])
->columns(1),
]),
// 搜索配置
Forms\Components\Tabs\Tab::make('搜索配置')
->icon('heroicon-o-magnifying-glass')
->schema([
Forms\Components\Section::make('搜索参数')
->description('配置搜索功能的参数')
->schema([
Forms\Components\TextInput::make('search.top_k')
->label('最大结果数')
->numeric()
->minValue(1)
->maxValue(100)
->helperText('搜索返回的最大结果数量')
->required()
->default(10),
Forms\Components\TextInput::make('search.similarity_threshold')
->label('相似度阈值')
->numeric()
->minValue(0)
->maxValue(1)
->step(0.01)
->helperText('搜索结果的最小相似度0-1')
->required()
->default(0.7),
Forms\Components\Toggle::make('search.enable_rerank')
->label('启用重排序')
->helperText('是否对搜索结果进行重新排序')
->inline(false)
->default(false),
])
->columns(3),
]),
])
->columnSpanFull(),
])
->statePath('data');
}
protected function getSettingsData(): array
{
$settings = SystemSetting::all();
$data = [];
foreach ($settings as $setting) {
// 从 value JSON 中提取实际值
$value = $setting->value;
// 获取 value 数组中的第一个值(因为种子数据中每个 value 都是单键值对)
if (is_array($value) && count($value) > 0) {
$data[$setting->key] = reset($value);
}
}
return $data;
}
public function save(): void
{
$data = $this->form->getState();
// 按配置键分组保存
foreach ($data as $key => $value) {
// 确定分组
$group = explode('.', $key)[0];
// 获取配置键的最后一部分作为 value 的键
$valueKey = explode('.', $key)[1] ?? $key;
// 更新或创建配置
SystemSetting::updateOrCreate(
['key' => $key],
[
'value' => [$valueKey => $value],
'group' => $group,
]
);
}
Notification::make()
->success()
->title('保存成功')
->body('系统设置已更新')
->send();
}
public function resetForm(): void
{
// 重新加载表单数据
$this->form->fill($this->getSettingsData());
Notification::make()
->info()
->title('已重置')
->body('表单已重置为当前保存的设置')
->send();
}
}