?php namespace App\Filament\Pages; use App\Models\SystemSetting; use Filament\Forms; use Filament\Pages\Page; use Filament\Forms\Components\Section; use Filament\Forms\Components\TextInput; use Filament\Notifications\Notification; use Illuminate\Support\Facades\Artisan; class Settings extends Page { protected static ?string $navigationIcon = 'heroicon-o-cog'; protected static ?string $navigationLabel = '系统设置'; protected static ?string $title = '系统设置'; protected static string $view = 'filament.pages.settings'; protected static ?int $navigationSort = 99; protected static ?string $navigationGroup = '系统管理'; // 设置明确的 slug,避免占用根路径 protected static ?string $slug = 'system-settings'; public ?array $data = []; public function mount(): void { $company = SystemSetting::getCompanyInfo(); $this->form->fill([ // 改装企业信息(从数据库读取) 'company_name' => $company['company_name'], 'company_code' => $company['company_code'], 'company_address' => $company['company_address'], 'modified_brand' => $company['modified_brand'], 'modified_model' => $company['modified_model'], 'modified_manufacturer' => $company['modified_manufacturer'], // 大华API配置 'dahua_api_url' => env('DAHUA_API_URL', 'https://open.lechange.com'), 'dahua_app_key' => env('DAHUA_APP_KEY', ''), 'dahua_app_secret' => env('DAHUA_APP_SECRET', ''), // 百度OCR配置 'ocr_provider' => env('OCR_PROVIDER', 'php'), 'baidu_ocr_api_key' => env('BAIDU_OCR_API_KEY', ''), 'baidu_ocr_secret_key' => env('BAIDU_OCR_SECRET_KEY', ''), // 存储配置 'storage_driver' => env('FILESYSTEM_DISK', 'local'), 'oss_access_key' => env('OSS_ACCESS_KEY_ID', ''), 'oss_access_secret' => env('OSS_ACCESS_KEY_SECRET', ''), 'oss_bucket' => env('OSS_BUCKET', ''), 'oss_endpoint' => env('OSS_ENDPOINT', ''), // 图片压缩配置 'image_compression_quality' => env('IMAGE_COMPRESSION_QUALITY', 85), 'image_max_width' => env('IMAGE_MAX_WIDTH', 1920), 'image_max_height' => env('IMAGE_MAX_HEIGHT', 1080), ]); } protected function getFormSchema(): array { return [ Section::make('改装企业信息') ->description('配置改装企业基本信息,将用于文档生成和出厂采集页面的改装后信息默认值') ->schema([ TextInput::make('company_name') ->label('改装企业名称') ->required() ->maxLength(200) ->helperText('用于生成的文档中的企业名称,如"上海埃尔帝汽车有限公司"'), TextInput::make('company_code') ->label('企业代码') ->maxLength(50) ->helperText('用于合格证编号前缀,如"SCC",生成编号格式:SCC-202601-001'), TextInput::make('company_address') ->label('企业地址') ->maxLength(500) ->helperText('改装企业详细地址,用于合格证等文档'), TextInput::make('modified_brand') ->label('改装后品牌(默认值)') ->required() ->maxLength(100) ->helperText('出厂采集时的改装后品牌默认值,如"埃尔帝"。操作员可在采集时修改。'), TextInput::make('modified_model') ->label('改装后型号(默认值)') ->maxLength(100) ->helperText('出厂采集时的改装后型号默认值,如"ELD-A"。操作员可在采集时修改。'), TextInput::make('modified_manufacturer') ->label('改装后生产厂商(默认值)') ->maxLength(200) ->helperText('出厂采集时的改装后生产厂商默认值。操作员可在采集时修改。'), ]) ->columns(2) ->collapsible(), Section::make('大华云API配置') ->description('配置大华云开放平台API,用于自动拍摄功能') ->schema([ TextInput::make('dahua_api_url') ->label('API地址') ->default('https://open.lechange.com') ->required() ->url() ->helperText('大华云开放平台API地址'), TextInput::make('dahua_app_key') ->label('APP KEY') ->required() ->helperText('从大华云开放平台获取'), TextInput::make('dahua_app_secret') ->label('APP SECRET') ->required() ->password() ->helperText('从大华云开放平台获取'), ]) ->columns(1) ->collapsible(), Section::make('OCR识别配置') ->description('配置OCR服务,用于铭牌识别功能') ->schema([ Forms\Components\Select::make('ocr_provider') ->label('OCR提供商') ->options([ 'php' => 'PHP OCR (本地)', 'baidu' => '百度OCR (云服务)', ]) ->default('php') ->required() ->reactive() ->helperText('选择OCR识别服务提供商'), TextInput::make('baidu_ocr_api_key') ->label('百度OCR API Key') ->visible(fn ($get) => $get('ocr_provider') === 'baidu') ->helperText('从百度AI开放平台获取'), TextInput::make('baidu_ocr_secret_key') ->label('百度OCR Secret Key') ->password() ->visible(fn ($get) => $get('ocr_provider') === 'baidu') ->helperText('从百度AI开放平台获取'), ]) ->columns(1) ->collapsible(), Section::make('存储配置') ->description('配置图片存储方式') ->schema([ Forms\Components\Select::make('storage_driver') ->label('存储驱动') ->options([ 'local' => '本地存储', 'oss' => '阿里云OSS', 's3' => 'AWS S3', ]) ->default('local') ->required() ->reactive() ->helperText('选择图片存储方式'), TextInput::make('oss_access_key') ->label('Access Key ID') ->visible(fn ($get) => in_array($get('storage_driver'), ['oss', 's3'])) ->helperText('OSS/S3访问密钥ID'), TextInput::make('oss_access_secret') ->label('Access Key Secret') ->password() ->visible(fn ($get) => in_array($get('storage_driver'), ['oss', 's3'])) ->helperText('OSS/S3访问密钥'), TextInput::make('oss_bucket') ->label('Bucket名称') ->visible(fn ($get) => in_array($get('storage_driver'), ['oss', 's3'])) ->helperText('存储桶名称'), TextInput::make('oss_endpoint') ->label('Endpoint') ->visible(fn ($get) => $get('storage_driver') === 'oss') ->helperText('OSS访问域名,如:oss-cn-hangzhou.aliyuncs.com'), ]) ->columns(1) ->collapsible(), Section::make('图片压缩配置') ->description('配置图片压缩质量和尺寸限制') ->schema([ TextInput::make('image_compression_quality') ->label('压缩质量 (1-100)') ->numeric() ->default(85) ->minValue(1) ->maxValue(100) ->required() ->helperText('推荐值:85'), TextInput::make('image_max_width') ->label('最大宽度 (像素)') ->numeric() ->default(1920) ->minValue(800) ->maxValue(4096) ->required() ->helperText('推荐值:1920'), TextInput::make('image_max_height') ->label('最大高度 (像素)') ->numeric() ->default(1080) ->minValue(600) ->maxValue(4096) ->required() ->helperText('推荐值:1080'), ]) ->columns(3) ->collapsible(), ]; } public function submit(): void { $data = $this->form->getState(); // 企业信息保存到数据库 SystemSetting::setMany([ 'company_name' => $data['company_name'] ?? '', 'company_code' => $data['company_code'] ?? '', 'company_address' => $data['company_address'] ?? '', 'modified_brand' => $data['modified_brand'] ?? '', 'modified_model' => $data['modified_model'] ?? '', 'modified_manufacturer' => $data['modified_manufacturer'] ?? '', ]); // 其余配置写 .env $this->updateEnvFile([ 'DAHUA_API_URL' => $data['dahua_api_url'], 'DAHUA_APP_KEY' => $data['dahua_app_key'], 'DAHUA_APP_SECRET' => $data['dahua_app_secret'], 'OCR_PROVIDER' => $data['ocr_provider'], 'BAIDU_OCR_API_KEY' => $data['baidu_ocr_api_key'] ?? '', 'BAIDU_OCR_SECRET_KEY' => $data['baidu_ocr_secret_key'] ?? '', 'FILESYSTEM_DISK' => $data['storage_driver'], 'OSS_ACCESS_KEY_ID' => $data['oss_access_key'] ?? '', 'OSS_ACCESS_KEY_SECRET' => $data['oss_access_secret'] ?? '', 'OSS_BUCKET' => $data['oss_bucket'] ?? '', 'OSS_ENDPOINT' => $data['oss_endpoint'] ?? '', 'IMAGE_COMPRESSION_QUALITY' => $data['image_compression_quality'] ?? 85, 'IMAGE_MAX_WIDTH' => $data['image_max_width'] ?? 1920, 'IMAGE_MAX_HEIGHT' => $data['image_max_height'] ?? 1080, ]); Artisan::call('config:clear'); Notification::make() ->title('设置已保存') ->success() ->body('系统配置已更新。') ->send(); } protected function updateEnvFile(array $data): void { $envFile = base_path('.env'); $envContent = file_get_contents($envFile); foreach ($data as $key => $value) { $value = str_replace('"', '\"', $value); if (preg_match('/\s/', $value) || $value === '') { $value = '"' . $value . '"'; } if (preg_match("/^{$key}=/m", $envContent)) { $envContent = preg_replace("/^{$key}=.*/m", "{$key}={$value}", $envContent); } else { $envContent .= "\n{$key}={$value}"; } } file_put_contents($envFile, $envContent); } protected function getFormStatePath(): string { return 'data'; } } {"success":false,"error":{"type":"NOT_FOUND","message":"\u8bf7\u6c42\u7684\u8d44\u6e90\u4e0d\u5b58\u5728"}}