import React, { useEffect, useState } from 'react'; import { Button, Card, Form, Input, message, Space, Switch, Typography, Upload, } from 'antd'; import { SettingOutlined, SaveOutlined, UploadOutlined, FilePdfOutlined, EyeOutlined, } from '@ant-design/icons'; import { getSystemConfigs, updateSystemConfig, uploadPdf } from '../api'; import type { SystemConfig } from '../types'; const AdminSettings: React.FC = () => { const [configs, setConfigs] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [uploading, setUploading] = useState(''); const [form] = Form.useForm(); useEffect(() => { load(); }, []); const load = async () => { setLoading(true); const data = await getSystemConfigs(); setConfigs(data); const formValues: Record = {}; data.forEach(c => { formValues[c.key] = c.value; }); form.setFieldsValue(formValues); setLoading(false); }; const handleSave = async () => { try { const values = await form.validateFields(); setSaving(true); for (const config of configs) { const newVal = values[config.key]; if (newVal !== undefined && newVal !== config.value) { await updateSystemConfig(config.id, newVal ?? ''); } } message.success('系统配置已保存'); const data = await getSystemConfigs(); setConfigs(data); setSaving(false); } catch (e: any) { setSaving(false); message.error(e?.message || '保存失败'); } }; const handleUpload = async (file: File, configKey: string) => { setUploading(configKey); try { const res = await uploadPdf(file, configKey); // Update local state setConfigs(prev => prev.map(c => c.key === configKey ? { ...c, value: res.url } : c)); form.setFieldsValue({ [configKey]: res.url }); message.success('PDF上传成功'); } catch { message.error('上传失败'); } finally { setUploading(''); } return false; // prevent default upload }; const groupedConfigs: Record = { '站点信息': configs.filter(c => c.key.startsWith('site_')), '协议配置': configs.filter(c => c.key === 'user_agreement_url' || c.key === 'privacy_policy_url'), 'SEO 设置': configs.filter(c => c.key.startsWith('seo_')), '用户积分配置': configs.filter(c => c.key.startsWith('user_') && c.key.includes('credits')), }; const getFieldDescription = (config: SystemConfig): string => { const descMap: Record = { site_name: '平台显示名称,将展示在页面标题和导航栏', site_logo: '平台Logo图片URL,建议尺寸 200x40px', user_agreement_url: '用户注册/登录时需同意的用户协议PDF文件', privacy_policy_url: '用户注册/登录时需同意的隐私政策PDF文件', seo_title: '搜索引擎结果中显示的标题', seo_description: '搜索引擎结果中显示的描述文字,建议150字以内', seo_keywords: '用逗号分隔的关键词列表', user_register_credits: '用户注册时赠送的初始积分,默认100', user_login_credits: '用户每日登录赠送的积分数量', user_login_credits_enabled: '是否启用每日登录赠送积分功能', }; return descMap[config.key] || config.description || ''; }; const getFieldComponent = (config: SystemConfig) => { if (config.key === 'seo_description') { return ; } if (config.key === 'seo_keywords') { return ; } if (config.key === 'user_login_credits_enabled') { return (
{config.value === 'true' ? '已启用' : '已禁用'}
); } if (config.key === 'user_register_credits' || config.key === 'user_login_credits') { return ; } return ; }; const PdfUploadField: React.FC<{ config: SystemConfig }> = ({ config }) => { const label = config.key === 'user_agreement_url' ? '用户协议' : '隐私政策'; const hasFile = config.value && config.value.startsWith('/uploads/'); return (
{label} {hasFile && ( )} handleUpload(file, config.key)} >
{hasFile ? `已上传: ${config.value}` : '尚未上传,前台将不显示对应链接'}
); }; if (loading) { return ; } return (
系统设置 管理站点基础信息、协议文件和SEO配置
{Object.entries(groupedConfigs).map(([group, items]) => (
{group} {group === '协议配置' ? ( items.map(config => ( )) ) : ( items.map(config => ( {config.description}} extra={getFieldDescription(config)} > {getFieldComponent(config)} )) )}
))}
); }; export default AdminSettings;