import React, { useCallback, useEffect, useState } from 'react'; import { Button, Col, Form, Input, InputNumber, Modal, Popconfirm, Row, Select, Space, Switch, Table, Tag, Typography, message, } from 'antd'; import { ApiOutlined, DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, SaveOutlined, } from '@ant-design/icons'; import { deleteDatabaseConfig, getDatabaseConfig, getDatabaseConfigs, getSystemDatabaseConfig, testDatabaseConfig, testSystemDatabaseConfig, updateDatabaseConfig, updateSystemDatabaseConfig, } from '../../api/admin'; import { SycmCard } from '../../components/Common'; const { Text } = Typography; const DRIVER_OPTIONS = [ { value: 'mysql', label: 'MySQL / MariaDB' }, { value: 'mssql', label: 'SQL Server (MSSQL)' }, { value: 'postgres', label: 'PostgreSQL' }, ]; const DEFAULT_PORTS = { mysql: 3306, mssql: 1433, postgres: 5432, }; const CORE_CONFIG_NAMES = new Set([ 'cloud_database', 'cloud_database_public', 'planning_database', ]); const CONFIG_LABELS = { cloud_database: '默认业务数据库', cloud_database_public: '公网业务数据库', planning_database: '企划数据库', jiansun_database: '简尚业务数据库', product_information_database: '产品资料系统数据库', }; const DatabaseSettings = () => { const [systemForm] = Form.useForm(); const [databaseForm] = Form.useForm(); const [systemLoading, setSystemLoading] = useState(false); const [systemTesting, setSystemTesting] = useState(false); const [listLoading, setListLoading] = useState(false); const [saving, setSaving] = useState(false); const [testing, setTesting] = useState(false); const [configs, setConfigs] = useState([]); const [editorOpen, setEditorOpen] = useState(false); const [editingConfig, setEditingConfig] = useState(null); const [envConfig, setEnvConfig] = useState(null); const useEnvConfig = Form.useWatch('useEnvConfig', databaseForm); const loadSystemConfig = useCallback(async () => { try { const config = await getSystemDatabaseConfig(); systemForm.setFieldsValue({ driver: 'mysql', host: config.host || '', port: config.port || 3306, database: config.database || '', username: config.username || '', password: '', }); } catch (error) { message.error(error.response?.data?.error || '获取系统数据库配置失败'); } }, [systemForm]); const loadConfigs = useCallback(async () => { try { setListLoading(true); const result = await getDatabaseConfigs(); setConfigs(Array.isArray(result) ? result : []); } catch (error) { message.error(error.response?.data?.error || '获取数据库配置列表失败'); } finally { setListLoading(false); } }, []); useEffect(() => { loadSystemConfig(); loadConfigs(); }, [loadConfigs, loadSystemConfig]); const saveSystemConfig = async () => { try { const values = await systemForm.validateFields(); setSystemLoading(true); const result = await updateSystemDatabaseConfig(values); message.success(result.message || '系统数据库配置已保存'); await loadSystemConfig(); } catch (error) { if (!error?.errorFields) { message.error(error.response?.data?.error || '保存系统数据库配置失败'); } } finally { setSystemLoading(false); } }; const testSystemConfig = async () => { try { const values = await systemForm.validateFields(); if (!values.password) { message.warning('测试系统数据库前请填写密码'); return; } setSystemTesting(true); const result = await testSystemDatabaseConfig(values); message.success(result.message || '系统数据库连接成功'); } catch (error) { if (!error?.errorFields) { message.error(error.response?.data?.message || error.response?.data?.error || '系统数据库连接失败'); } } finally { setSystemTesting(false); } }; const openCreate = () => { setEditingConfig(null); setEnvConfig(null); databaseForm.resetFields(); databaseForm.setFieldsValue({ driver: 'mysql', port: 3306, ssl: false, useEnvConfig: false }); setEditorOpen(true); }; const openEdit = async (record) => { try { setEditingConfig(record); const config = await getDatabaseConfig(record.name); setEnvConfig(config.envConfig || null); databaseForm.setFieldsValue({ ...config, password: '', ssl: Boolean(config.ssl), useEnvConfig: Boolean(config.useEnvConfig), }); setEditorOpen(true); } catch (error) { message.error(error.response?.data?.error || '获取数据库配置失败'); } }; const testEditorConfig = async () => { try { const values = await databaseForm.validateFields(); setTesting(true); const result = await testDatabaseConfig(values); message.success(`${result.message || '连接成功'}${result.responseTime ? `,${result.responseTime}ms` : ''}`); } catch (error) { if (!error?.errorFields) { message.error(error.response?.data?.error || error.message || '数据库连接失败'); } } finally { setTesting(false); } }; const saveDatabaseConfig = async () => { try { const values = await databaseForm.validateFields(); setSaving(true); const result = await updateDatabaseConfig({ ...values, status: editingConfig?.status || 'active' }, values.name); message.success(result.message || '数据库配置已保存'); setEditorOpen(false); await loadConfigs(); } catch (error) { if (!error?.errorFields) { message.error(error.response?.data?.error || error.message || '保存数据库配置失败'); } } finally { setSaving(false); } }; const toggleStatus = async (record, enabled) => { try { const current = await getDatabaseConfig(record.name); await updateDatabaseConfig({ ...current, password: '', status: enabled ? 'active' : 'inactive' }, record.name); message.success(enabled ? '数据库配置已启用' : '数据库配置已停用'); await loadConfigs(); } catch (error) { message.error(error.response?.data?.error || '更新数据库状态失败'); } }; const removeConfig = async (record) => { try { const result = await deleteDatabaseConfig(record.id); message.success(result.message || '数据库配置已删除'); await loadConfigs(); } catch (error) { message.error(error.response?.data?.error || '删除数据库配置失败'); } }; const columns = [ { title: '配置', dataIndex: 'name', width: 220, render: (value) => (
{CONFIG_LABELS[value] || value} {CONFIG_LABELS[value] ? {value} : null}
), }, { title: '类型', dataIndex: 'driver', width: 150, render: (value) => DRIVER_OPTIONS.find((item) => item.value === value)?.label || value, }, { title: '连接地址', key: 'endpoint', ellipsis: true, render: (_, record) => `${record.host || '-'}:${record.port || '-'}/${record.database || '-'}`, }, { title: '用户名', dataIndex: 'username', width: 150, ellipsis: true }, { title: '来源', key: 'source', width: 100, render: (_, record) => {record.useEnvConfig ? '.env' : '系统配置'}, }, { title: '状态', dataIndex: 'status', width: 90, render: (value, record) => ( toggleStatus(record, checked)} /> ), }, { title: '操作', key: 'actions', width: 120, fixed: 'right', render: (_, record) => (
业务与扩展数据库 统一管理业务库和管理员自定义的数据源连接。
setEditorOpen(false)} footer={[ , , , ]} destroyOnHidden >
( !editingConfig && configs.some((item) => item.name === value) ? Promise.reject(new Error('该配置标识已经存在')) : Promise.resolve() ), }, ]} > ); }; export default DatabaseSettings;