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 = 1048576,10MB = 10485760,100MB = 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(); } }