import React, {useEffect, useRef, useState} from 'react'; import { Button, Card, Checkbox, Col, Divider, Form, Input, InputNumber, Menu, message, Popconfirm, Radio, Row, Space, Spin, Switch, Typography, } from 'antd'; import { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, SaveOutlined, SettingOutlined, } from '@ant-design/icons'; import XinForm from '@/components/XinForm'; import type { XinFormRef } from '@/components/XinForm/typings'; import type { FormColumn } from '@/components/XinFormField/FieldRender/typings'; import {useTranslation} from 'react-i18next'; import type {IConfigGroup} from '@/domain/iConfigGroup.ts'; import type {IConfigItem} from '@/domain/iConfigItem.ts'; import { createConfigGroup, createConfigItem, deleteConfigGroup, deleteConfigItem, getConfigGroupList, getConfigItemList, refreshCache, saveConfigItems, updateConfigGroup, updateConfigItem, } from '@/api/system/sys_config.ts'; const { TextArea } = Input; const { Text, Title } = Typography; const ConfigManagement: React.FC = () => { const { t } = useTranslation(); /** 表单组件类型选项 */ const FORM_COMPONENT_OPTIONS = [ { label: t('system.config.component.Input'), value: 'Input' }, { label: t('system.config.component.TextArea'), value: 'TextArea' }, { label: t('system.config.component.InputNumber'), value: 'InputNumber' }, { label: t('system.config.component.Switch'), value: 'Switch' }, { label: t('system.config.component.Radio'), value: 'Radio' }, { label: t('system.config.component.Checkbox'), value: 'Checkbox' }, ]; const [configGroups, setConfigGroups] = useState([]); const [selectedGroupId, setSelectedGroupId] = useState(); const [selectedGroupKey, setSelectedGroupKey] = useState(); const [configItems, setConfigItems] = useState([]); const [loading, setLoading] = useState(false); const [itemsLoading, setItemsLoading] = useState(false); const [saving, setSaving] = useState(false); // 设置组表单 const [editingGroup, setEditingGroup] = useState(null); const groupFormRef = useRef(null); // 设置项表单 const [editingItem, setEditingItem] = useState(null); const itemFormRef = useRef(null); // 设置项值表单 const [valuesForm] = Form.useForm(); /** 加载设置组列表 */ const loadConfigGroups = async () => { try { setLoading(true); const { data } = await getConfigGroupList(); const groups = data.data || []; setConfigGroups(groups); // 如果当前没有选中的组,选中第一个 if (!selectedGroupId && groups.length > 0) { setSelectedGroupId(groups[0].id); setSelectedGroupKey(groups[0].key); } } finally { setLoading(false); } }; /** 加载设置项列表 */ const loadConfigItems = async (groupId?: number) => { if (!groupId) return; try { setItemsLoading(true); const { data } = await getConfigItemList(groupId); const items = data.data || []; setConfigItems(items); // 初始化表单值 const initialValues: { [key: string]: any } = {}; items.forEach(item => { if(!item.type || ['Input', 'TextArea', 'Radio'].includes(item.type)) { initialValues[`item_${item.id}`] = String(item.values); } if(item.type && item.type === 'InputNumber') { initialValues[`item_${item.id}`] = Number(item.values); } if(item.type && item.type === 'Switch') { if(item.values === '0' || item.values === 'false') { initialValues[`item_${item.id}`] = false; }else { initialValues[`item_${item.id}`] = Boolean(item.values); } } if(item.type && item.type === 'Checkbox') { try { initialValues[`item_${item.id}`] = JSON.parse(item.values || '[]'); } catch { initialValues[`item_${item.id}`] = []; } } }); console.log(initialValues) valuesForm.setFieldsValue(initialValues); } finally { setItemsLoading(false); } }; useEffect(() => { loadConfigGroups(); }, []); useEffect(() => { if (selectedGroupId) { loadConfigItems(selectedGroupId); } }, [selectedGroupId]); /** 打开新增设置组对话框 */ const handleAddGroup = () => { setEditingGroup(null); groupFormRef.current?.resetFields(); groupFormRef.current?.open(); }; /** 打开编辑设置组对话框 */ const handleEditGroup = (group: IConfigGroup) => { setEditingGroup(group); groupFormRef.current?.setFieldsValue(group); groupFormRef.current?.open(); }; /** 保存设置组 */ const handleSaveGroup = async (values: IConfigGroup) => { try { if (editingGroup) { await updateConfigGroup(editingGroup.id!, values); message.success(t('system.config.group.updateSuccess')); } else { await createConfigGroup(values); message.success(t('system.config.group.createSuccess')); } groupFormRef.current?.close(); await loadConfigGroups(); return true; } catch { return false; } }; /** 删除设置组 */ const handleDeleteGroup = async (id: number) => { try { await deleteConfigGroup(id); message.success(t('system.config.group.deleteSuccess')); if (selectedGroupId === id) { setSelectedGroupId(undefined); setSelectedGroupKey(undefined); } await loadConfigGroups(); } catch (error) { console.error('删除设置组失败:', error); } }; /** 打开新增设置项对话框 */ const handleAddItem = () => { setEditingItem(null); itemFormRef.current?.resetFields(); itemFormRef.current?.setFieldsValue({ group_id: selectedGroupId }); itemFormRef.current?.open(); }; /** 打开编辑设置项对话框 */ const handleEditItem = (item: IConfigItem) => { setEditingItem(item); itemFormRef.current?.setFieldsValue(item); itemFormRef.current?.open(); }; /** 保存设置项 */ const handleSaveItem = async (values: IConfigItem) => { try { if (editingItem) { await updateConfigItem(editingItem.id!, { ...values, group_id: selectedGroupId }); message.success(t('system.config.item.updateSuccess')); } else { await createConfigItem({ ...values, group_id: selectedGroupId }); message.success(t('system.config.item.createSuccess')); } itemFormRef.current?.close(); await loadConfigItems(selectedGroupId); return true; } catch { return false; } }; /** 删除设置项 */ const handleDeleteItem = async (id: number) => { try { await deleteConfigItem(id); message.success(t('system.config.item.deleteSuccess')); await loadConfigItems(selectedGroupId); } catch (error) { console.error('删除设置项失败:', error); } }; /** 批量保存所有设置项值 */ const handleSaveAll = async () => { try { setSaving(true); const values = valuesForm.getFieldsValue(); const configs = configItems.map(item => { const value = values[`item_${item.id}`]; if(!item.type || ['Input', 'TextArea', 'Radio'].includes(item.type)) { return { id: item.id!, value: String(value) }; } if(item.type && item.type === 'InputNumber') { return { id: item.id!, value: String(value) }; } if(item.type && item.type === 'Switch') { if(value === '0' || value === 'false' || !!value) { return { id: item.id!, value: 'false' }; }else { return { id: item.id!, value: 'true' }; } } if(item.type && item.type === 'Checkbox') { return { id: item.id!, value: JSON.stringify(value) }; } return { id: item.id!, value: value }; }); await saveConfigItems(configs); message.success(t('system.config.item.updateSuccess')); } finally { setSaving(false); } }; const handleRefresh = async () => { try { setSaving(true); await refreshCache(); message.success(t('system.config.item.refreshCacheSuccess')) } finally { setSaving(false); } } /** 渲染设置项的表单组件 */ const renderConfigItemComponent = (item: IConfigItem) => { const fieldName = `item_${item.id}`; const componentType = item.type || 'Input'; const usage = `site_config('${selectedGroupKey}.${item.key}')`; // 解析options let options: any[] = []; if (item.options_json) { try { options = JSON.parse(item.options_json); } catch { console.error('options解析失败:', item.options_json); } } // 解析props let componentProps: any = {}; if (item.props_json) { try { componentProps = JSON.parse(item.props_json); } catch { console.error('props解析失败:', item.props_json); } } // 自定义Label组件 const CustomLabel = () => (
{item.title}
); let component; switch (componentType) { case 'Input': component = ( ); break; case 'TextArea': component = (