You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

647 lines
25 KiB

import React, { useState } from 'react';
import { Card, Row, Col, Form, Input, Button, Select, Switch, InputNumber, Alert, Divider, Tabs } from 'antd';
import { DatabaseOutlined, KeyOutlined, SettingOutlined, SaveOutlined, ToolOutlined } from '@ant-design/icons';
import './AdminConfig.css';
const { Option } = Select;
const { Item } = Form;
const { TabPane } = Tabs;
const AdminConfig = () => {
const [form] = Form.useForm();
// 数据库配置
const databaseConfig = {
// MongoDB配置
mongoDB: {
host: 'localhost',
port: 27017,
database: 'alpha-futures',
username: '',
password: '',
authSource: 'admin',
ssl: false,
enabled: true
},
// PostgreSQL配置
postgreSQL: {
host: 'localhost',
port: 5432,
database: 'alpha-futures',
username: 'postgres',
password: 'password',
ssl: false,
enabled: true
},
// Redis配置
redis: {
host: 'localhost',
port: 6379,
password: '',
db: 0,
enabled: true
},
// InfluxDB配置
influxDB: {
host: 'localhost',
port: 8086,
database: 'alpha-futures',
username: '',
password: '',
ssl: false,
enabled: true
}
};
// 服务器配置
const serverConfig = {
port: 3005,
host: '0.0.0.0',
environment: 'development',
debug: true,
timeout: 30000,
maxBodySize: '10mb'
};
// 安全配置
const securityConfig = {
jwtSecret: 'your-secret-key',
jwtExpiresIn: '7d',
rateLimit: {
windowMs: 60000,
max: 120
},
cors: {
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
}
};
const [config, setConfig] = useState({
database: databaseConfig,
server: serverConfig,
security: securityConfig
});
// 处理配置变更
const handleConfigChange = (section, key, value) => {
setConfig(prev => ({
...prev,
[section]: {
...prev[section],
[key]: value
}
}));
};
// 处理数据库配置变更
const handleDatabaseConfigChange = (dbType, key, value) => {
setConfig(prev => ({
...prev,
database: {
...prev.database,
[dbType]: {
...prev.database[dbType],
[key]: value
}
}
}));
};
// 处理表单提交
const handleSubmit = (values) => {
console.log('配置保存:', values);
// 模拟保存操作
Alert.success('配置已保存');
};
// 测试数据库连接
const testDatabaseConnection = (dbType) => {
console.log(`测试${dbType}连接`);
// 模拟测试操作
setTimeout(() => {
Alert.success(`${dbType}连接测试成功`);
}, 1000);
};
return (
<div className="admin-config">
<h2>管理配置</h2>
<Alert
message="警告:此页面包含敏感配置信息,请谨慎操作"
type="warning"
style={{ marginBottom: 24 }}
/>
<Form form={form} layout="vertical" onFinish={handleSubmit}>
<Tabs defaultActiveKey="database">
{/* 数据库配置 */}
<TabPane tab={<span><DatabaseOutlined /> 数据库配置</span>} key="database">
{/* MongoDB配置 */}
<Card title="MongoDB配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Item label="主机" name="database.mongoDB.host">
<Input
defaultValue={config.database.mongoDB.host}
onChange={(e) => handleDatabaseConfigChange('mongoDB', 'host', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="端口" name="database.mongoDB.port">
<InputNumber
defaultValue={config.database.mongoDB.port}
min={1}
max={65535}
onChange={(value) => handleDatabaseConfigChange('mongoDB', 'port', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="数据库" name="database.mongoDB.database">
<Input
defaultValue={config.database.mongoDB.database}
onChange={(e) => handleDatabaseConfigChange('mongoDB', 'database', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="认证源" name="database.mongoDB.authSource">
<Input
defaultValue={config.database.mongoDB.authSource}
onChange={(e) => handleDatabaseConfigChange('mongoDB', 'authSource', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="用户名" name="database.mongoDB.username">
<Input
defaultValue={config.database.mongoDB.username}
onChange={(e) => handleDatabaseConfigChange('mongoDB', 'username', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="密码" name="database.mongoDB.password">
<Input.Password
defaultValue={config.database.mongoDB.password}
onChange={(e) => handleDatabaseConfigChange('mongoDB', 'password', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="SSL" name="database.mongoDB.ssl">
<Switch
defaultChecked={config.database.mongoDB.ssl}
onChange={(checked) => handleDatabaseConfigChange('mongoDB', 'ssl', checked)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="启用" name="database.mongoDB.enabled">
<Switch
defaultChecked={config.database.mongoDB.enabled}
onChange={(checked) => handleDatabaseConfigChange('mongoDB', 'enabled', checked)}
/>
</Item>
</Col>
</Row>
<div style={{ marginTop: 16 }}>
<Button
type="primary"
onClick={() => testDatabaseConnection('MongoDB')}
style={{ marginRight: 8 }}
>
测试连接
</Button>
<Button
type="default"
onClick={() => {
handleDatabaseConfigChange('mongoDB', 'host', 'localhost');
handleDatabaseConfigChange('mongoDB', 'port', 27017);
handleDatabaseConfigChange('mongoDB', 'database', 'alpha-futures');
handleDatabaseConfigChange('mongoDB', 'username', '');
handleDatabaseConfigChange('mongoDB', 'password', '');
handleDatabaseConfigChange('mongoDB', 'authSource', 'admin');
handleDatabaseConfigChange('mongoDB', 'ssl', false);
handleDatabaseConfigChange('mongoDB', 'enabled', true);
}}
>
恢复默认
</Button>
</div>
</Card>
{/* PostgreSQL配置 */}
<Card title="PostgreSQL配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Item label="主机" name="database.postgreSQL.host">
<Input
defaultValue={config.database.postgreSQL.host}
onChange={(e) => handleDatabaseConfigChange('postgreSQL', 'host', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="端口" name="database.postgreSQL.port">
<InputNumber
defaultValue={config.database.postgreSQL.port}
min={1}
max={65535}
onChange={(value) => handleDatabaseConfigChange('postgreSQL', 'port', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="数据库" name="database.postgreSQL.database">
<Input
defaultValue={config.database.postgreSQL.database}
onChange={(e) => handleDatabaseConfigChange('postgreSQL', 'database', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="用户名" name="database.postgreSQL.username">
<Input
defaultValue={config.database.postgreSQL.username}
onChange={(e) => handleDatabaseConfigChange('postgreSQL', 'username', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="密码" name="database.postgreSQL.password">
<Input.Password
defaultValue={config.database.postgreSQL.password}
onChange={(e) => handleDatabaseConfigChange('postgreSQL', 'password', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="SSL" name="database.postgreSQL.ssl">
<Switch
defaultChecked={config.database.postgreSQL.ssl}
onChange={(checked) => handleDatabaseConfigChange('postgreSQL', 'ssl', checked)}
/>
</Item>
</Col>
<Col span={12}>
<Item label="启用" name="database.postgreSQL.enabled">
<Switch
defaultChecked={config.database.postgreSQL.enabled}
onChange={(checked) => handleDatabaseConfigChange('postgreSQL', 'enabled', checked)}
/>
</Item>
</Col>
</Row>
<div style={{ marginTop: 16 }}>
<Button
type="primary"
onClick={() => testDatabaseConnection('PostgreSQL')}
style={{ marginRight: 8 }}
>
测试连接
</Button>
<Button
type="default"
onClick={() => {
handleDatabaseConfigChange('postgreSQL', 'host', 'localhost');
handleDatabaseConfigChange('postgreSQL', 'port', 5432);
handleDatabaseConfigChange('postgreSQL', 'database', 'alpha-futures');
handleDatabaseConfigChange('postgreSQL', 'username', 'postgres');
handleDatabaseConfigChange('postgreSQL', 'password', 'password');
handleDatabaseConfigChange('postgreSQL', 'ssl', false);
handleDatabaseConfigChange('postgreSQL', 'enabled', true);
}}
>
恢复默认
</Button>
</div>
</Card>
{/* Redis配置 */}
<Card title="Redis配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Item label="主机" name="database.redis.host">
<Input
defaultValue={config.database.redis.host}
onChange={(e) => handleDatabaseConfigChange('redis', 'host', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="端口" name="database.redis.port">
<InputNumber
defaultValue={config.database.redis.port}
min={1}
max={65535}
onChange={(value) => handleDatabaseConfigChange('redis', 'port', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="密码" name="database.redis.password">
<Input.Password
defaultValue={config.database.redis.password}
onChange={(e) => handleDatabaseConfigChange('redis', 'password', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="数据库" name="database.redis.db">
<InputNumber
defaultValue={config.database.redis.db}
min={0}
max={15}
onChange={(value) => handleDatabaseConfigChange('redis', 'db', value)}
/>
</Item>
</Col>
<Col span={24}>
<Item label="启用" name="database.redis.enabled">
<Switch
defaultChecked={config.database.redis.enabled}
onChange={(checked) => handleDatabaseConfigChange('redis', 'enabled', checked)}
/>
</Item>
</Col>
</Row>
<div style={{ marginTop: 16 }}>
<Button
type="primary"
onClick={() => testDatabaseConnection('Redis')}
style={{ marginRight: 8 }}
>
测试连接
</Button>
<Button
type="default"
onClick={() => {
handleDatabaseConfigChange('redis', 'host', 'localhost');
handleDatabaseConfigChange('redis', 'port', 6379);
handleDatabaseConfigChange('redis', 'password', '');
handleDatabaseConfigChange('redis', 'db', 0);
handleDatabaseConfigChange('redis', 'enabled', true);
}}
>
恢复默认
</Button>
</div>
</Card>
{/* InfluxDB配置 */}
<Card title="InfluxDB配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Item label="主机" name="database.influxDB.host">
<Input
defaultValue={config.database.influxDB.host}
onChange={(e) => handleDatabaseConfigChange('influxDB', 'host', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="端口" name="database.influxDB.port">
<InputNumber
defaultValue={config.database.influxDB.port}
min={1}
max={65535}
onChange={(value) => handleDatabaseConfigChange('influxDB', 'port', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="数据库" name="database.influxDB.database">
<Input
defaultValue={config.database.influxDB.database}
onChange={(e) => handleDatabaseConfigChange('influxDB', 'database', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="用户名" name="database.influxDB.username">
<Input
defaultValue={config.database.influxDB.username}
onChange={(e) => handleDatabaseConfigChange('influxDB', 'username', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="密码" name="database.influxDB.password">
<Input.Password
defaultValue={config.database.influxDB.password}
onChange={(e) => handleDatabaseConfigChange('influxDB', 'password', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="SSL" name="database.influxDB.ssl">
<Switch
defaultChecked={config.database.influxDB.ssl}
onChange={(checked) => handleDatabaseConfigChange('influxDB', 'ssl', checked)}
/>
</Item>
</Col>
<Col span={12}>
<Item label="启用" name="database.influxDB.enabled">
<Switch
defaultChecked={config.database.influxDB.enabled}
onChange={(checked) => handleDatabaseConfigChange('influxDB', 'enabled', checked)}
/>
</Item>
</Col>
</Row>
<div style={{ marginTop: 16 }}>
<Button
type="primary"
onClick={() => testDatabaseConnection('InfluxDB')}
style={{ marginRight: 8 }}
>
测试连接
</Button>
<Button
type="default"
onClick={() => {
handleDatabaseConfigChange('influxDB', 'host', 'localhost');
handleDatabaseConfigChange('influxDB', 'port', 8086);
handleDatabaseConfigChange('influxDB', 'database', 'alpha-futures');
handleDatabaseConfigChange('influxDB', 'username', '');
handleDatabaseConfigChange('influxDB', 'password', '');
handleDatabaseConfigChange('influxDB', 'ssl', false);
handleDatabaseConfigChange('influxDB', 'enabled', true);
}}
>
恢复默认
</Button>
</div>
</Card>
</TabPane>
{/* 服务器配置 */}
<TabPane tab={<span><ToolOutlined /> 服务器配置</span>} key="server">
<Card title="服务器配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Item label="端口" name="server.port">
<InputNumber
defaultValue={config.server.port}
min={1}
max={65535}
onChange={(value) => handleConfigChange('server', 'port', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="主机" name="server.host">
<Input
defaultValue={config.server.host}
onChange={(e) => handleConfigChange('server', 'host', e.target.value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="环境" name="server.environment">
<Select
defaultValue={config.server.environment}
onChange={(value) => handleConfigChange('server', 'environment', value)}
>
<Option value="development">开发环境</Option>
<Option value="production">生产环境</Option>
<Option value="testing">测试环境</Option>
</Select>
</Item>
</Col>
<Col span={6}>
<Item label="调试模式" name="server.debug">
<Switch
defaultChecked={config.server.debug}
onChange={(checked) => handleConfigChange('server', 'debug', checked)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="超时时间(ms)" name="server.timeout">
<InputNumber
defaultValue={config.server.timeout}
min={1000}
max={60000}
step={1000}
onChange={(value) => handleConfigChange('server', 'timeout', value)}
/>
</Item>
</Col>
<Col span={6}>
<Item label="最大请求体大小" name="server.maxBodySize">
<Input
defaultValue={config.server.maxBodySize}
onChange={(e) => handleConfigChange('server', 'maxBodySize', e.target.value)}
/>
</Item>
</Col>
</Row>
</Card>
</TabPane>
{/* 安全配置 */}
<TabPane tab={<span><KeyOutlined /> 安全配置</span>} key="security">
{/* JWT配置 */}
<Card title="JWT配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={12}>
<Item label="JWT密钥" name="security.jwtSecret">
<Input.Password
defaultValue={config.security.jwtSecret}
onChange={(e) => handleConfigChange('security', 'jwtSecret', e.target.value)}
/>
</Item>
</Col>
<Col span={12}>
<Item label="过期时间" name="security.jwtExpiresIn">
<Input
defaultValue={config.security.jwtExpiresIn}
onChange={(e) => handleConfigChange('security', 'jwtExpiresIn', e.target.value)}
/>
</Item>
</Col>
</Row>
</Card>
{/* 速率限制配置 */}
<Card title="速率限制配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={12}>
<Item label="时间窗口(ms)" name="security.rateLimit.windowMs">
<InputNumber
defaultValue={config.security.rateLimit.windowMs}
min={1000}
max={3600000}
step={1000}
onChange={(value) => handleConfigChange('security', 'rateLimit', { ...config.security.rateLimit, windowMs: value })}
/>
</Item>
</Col>
<Col span={12}>
<Item label="最大请求数" name="security.rateLimit.max">
<InputNumber
defaultValue={config.security.rateLimit.max}
min={1}
max={1000}
step={10}
onChange={(value) => handleConfigChange('security', 'rateLimit', { ...config.security.rateLimit, max: value })}
/>
</Item>
</Col>
</Row>
</Card>
{/* CORS配置 */}
<Card title="CORS配置" className="admin-config-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
<Col span={24}>
<Item label="允许的源" name="security.cors.origin">
<Input
defaultValue={config.security.cors.origin}
onChange={(e) => handleConfigChange('security', 'cors', { ...config.security.cors, origin: e.target.value })}
/>
</Item>
</Col>
<Col span={24}>
<Item label="允许的方法" name="security.cors.methods">
<Input
defaultValue={config.security.cors.methods.join(', ')}
onChange={(e) => handleConfigChange('security', 'cors', { ...config.security.cors, methods: e.target.value.split(', ').map(m => m.trim()) })}
/>
</Item>
</Col>
<Col span={24}>
<Item label="允许的头部" name="security.cors.allowedHeaders">
<Input
defaultValue={config.security.cors.allowedHeaders.join(', ')}
onChange={(e) => handleConfigChange('security', 'cors', { ...config.security.cors, allowedHeaders: e.target.value.split(', ').map(h => h.trim()) })}
/>
</Item>
</Col>
</Row>
</Card>
</TabPane>
</Tabs>
<Divider />
<div className="admin-config-actions">
<Button type="default" style={{ marginRight: 8 }}>
恢复默认配置
</Button>
<Button type="primary" htmlType="submit">
<SaveOutlined /> 保存配置
</Button>
</div>
</Form>
</div>
);
};
export default AdminConfig;