feat: ✨ 新增系统配置页面
This commit is contained in:
294
src/pages/tabs/BasicConfigTab.tsx
Normal file
294
src/pages/tabs/BasicConfigTab.tsx
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* 基本配置标签页组件
|
||||
* @author MHXY Development Team
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Form, Input, Switch, Select, Card, Button, Space, Row, Col, Tooltip } from 'antd';
|
||||
import {
|
||||
InfoCircleOutlined,
|
||||
SaveOutlined,
|
||||
ReloadOutlined,
|
||||
HistoryOutlined,
|
||||
SettingOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { SystemConfig, SaveConfigRequest } from '../../types/systemConfig';
|
||||
|
||||
const { Option } = Select;
|
||||
const { TextArea } = Input;
|
||||
|
||||
interface BasicConfigTabProps {
|
||||
configs: SystemConfig[];
|
||||
loading: boolean;
|
||||
saving: boolean;
|
||||
onSave: (requests: SaveConfigRequest[]) => void;
|
||||
onReset: (configKey: string) => void;
|
||||
onShowHistory: (configKey: string) => void;
|
||||
onConfigChange: () => void;
|
||||
}
|
||||
|
||||
const BasicConfigTab: React.FC<BasicConfigTabProps> = ({
|
||||
configs,
|
||||
loading,
|
||||
saving,
|
||||
onSave,
|
||||
onReset,
|
||||
onShowHistory,
|
||||
onConfigChange
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const [formData, setFormData] = useState<Record<string, any>>({});
|
||||
|
||||
// 初始化表单数据
|
||||
useEffect(() => {
|
||||
const initialData: Record<string, any> = {};
|
||||
configs.forEach(config => {
|
||||
initialData[config.config_key] = config.config_value;
|
||||
});
|
||||
setFormData(initialData);
|
||||
form.setFieldsValue(initialData);
|
||||
}, [configs, form]);
|
||||
|
||||
// 处理表单值变化
|
||||
const handleValuesChange = (changedValues: any, allValues: any) => {
|
||||
setFormData(allValues);
|
||||
onConfigChange();
|
||||
};
|
||||
|
||||
// 保存配置
|
||||
const handleSave = () => {
|
||||
form.validateFields().then(() => {
|
||||
const saveRequests: SaveConfigRequest[] = configs.map(config => ({
|
||||
config_key: config.config_key,
|
||||
config_value: formData[config.config_key] || '',
|
||||
config_label: config.config_label,
|
||||
config_group: config.config_group
|
||||
}));
|
||||
onSave(saveRequests);
|
||||
}).catch(() => {
|
||||
// 表单验证失败
|
||||
});
|
||||
};
|
||||
|
||||
// 重置为默认值
|
||||
const handleReset = (configKey: string) => {
|
||||
onReset(configKey);
|
||||
};
|
||||
|
||||
// 显示配置历史
|
||||
const handleShowHistory = (configKey: string) => {
|
||||
onShowHistory(configKey);
|
||||
};
|
||||
|
||||
// 语言选项
|
||||
const languageOptions = [
|
||||
{ value: 'zh-CN', label: '简体中文' },
|
||||
{ value: 'zh-TW', label: '繁体中文' },
|
||||
{ value: 'en-US', label: 'English' },
|
||||
{ value: 'ja-JP', label: '日本語' }
|
||||
];
|
||||
|
||||
// 版本选项
|
||||
const versionOptions = [
|
||||
{ value: '1.0.0', label: 'v1.0.0' },
|
||||
{ value: '1.1.0', label: 'v1.1.0' },
|
||||
{ value: '2.0.0', label: 'v2.0.0' }
|
||||
];
|
||||
|
||||
const configItems = [
|
||||
{
|
||||
key: 'site_name',
|
||||
title: '网站名称',
|
||||
description: '系统显示名称,将在页面标题和系统信息中显示',
|
||||
type: 'input',
|
||||
placeholder: '请输入网站名称',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'site_version',
|
||||
title: '系统版本',
|
||||
description: '当前系统版本号,用于显示和版本管理',
|
||||
type: 'select',
|
||||
options: versionOptions,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'site_description',
|
||||
title: '系统描述',
|
||||
description: '系统描述信息,简要介绍系统功能和用途',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入系统描述',
|
||||
rows: 3
|
||||
},
|
||||
{
|
||||
key: 'admin_email',
|
||||
title: '管理员邮箱',
|
||||
description: '系统管理员联系邮箱,用于接收系统通知',
|
||||
type: 'input',
|
||||
placeholder: '请输入管理员邮箱',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'maintenance_mode',
|
||||
title: '维护模式',
|
||||
description: '开启后用户无法正常访问系统,仅管理员可以登录',
|
||||
type: 'switch'
|
||||
},
|
||||
{
|
||||
key: 'default_language',
|
||||
title: '默认语言',
|
||||
description: '系统默认语言设置,影响界面显示语言',
|
||||
type: 'select',
|
||||
options: languageOptions,
|
||||
required: true
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="basic-config-tab" style={{ padding: '0' }}>
|
||||
{/* 配置表单 */}
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onValuesChange={handleValuesChange}
|
||||
style={{ marginBottom: '24px' }}
|
||||
>
|
||||
<Row gutter={[24, 0]}>
|
||||
{configItems.map((item, index) => {
|
||||
const config = configs.find(c => c.config_key === item.key);
|
||||
if (!config) return null;
|
||||
|
||||
return (
|
||||
<Col span={12} key={item.key}>
|
||||
<Card
|
||||
size="small"
|
||||
style={{ marginBottom: '16px' }}
|
||||
title={
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<SettingOutlined />
|
||||
{item.title}
|
||||
{config.config_type === 'boolean' && (
|
||||
<Switch
|
||||
size="small"
|
||||
checked={formData[item.key] === '1' || formData[item.key] === true}
|
||||
onChange={(checked) => {
|
||||
const newValue = checked ? '1' : '0';
|
||||
form.setFieldValue(item.key, newValue);
|
||||
onConfigChange();
|
||||
}}
|
||||
style={{ marginLeft: '8px' }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
extra={
|
||||
<Space>
|
||||
<Tooltip title="查看历史记录">
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HistoryOutlined />}
|
||||
onClick={() => handleShowHistory(item.key)}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="重置为默认值">
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<ReloadOutlined />}
|
||||
onClick={() => handleReset(item.key)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<div style={{ marginBottom: '8px' }}>
|
||||
<div style={{
|
||||
fontSize: '12px',
|
||||
color: '#666',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '4px'
|
||||
}}>
|
||||
<InfoCircleOutlined />
|
||||
{item.description}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 输入控件 */}
|
||||
<Form.Item
|
||||
name={item.key}
|
||||
rules={[
|
||||
{ required: item.required, message: `请输入${item.title}` },
|
||||
...(item.key === 'admin_email' ? [
|
||||
{ type: 'email', message: '请输入有效的邮箱地址' }
|
||||
] : [])
|
||||
]}
|
||||
>
|
||||
{item.type === 'input' && (
|
||||
<Input
|
||||
placeholder={item.placeholder}
|
||||
disabled={config.config_type === 'boolean'}
|
||||
/>
|
||||
)}
|
||||
{item.type === 'textarea' && (
|
||||
<TextArea
|
||||
placeholder={item.placeholder}
|
||||
rows={item.rows || 2}
|
||||
/>
|
||||
)}
|
||||
{item.type === 'select' && (
|
||||
<Select placeholder={item.placeholder}>
|
||||
{item.options?.map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Card>
|
||||
</Col>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</Form>
|
||||
|
||||
{/* 保存按钮 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
padding: '24px 0',
|
||||
borderTop: '1px solid #f0f0f0'
|
||||
}}>
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
icon={<SaveOutlined />}
|
||||
loading={saving}
|
||||
onClick={handleSave}
|
||||
style={{ minWidth: '120px' }}
|
||||
>
|
||||
保存基本配置
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 配置信息 */}
|
||||
<Card size="small" style={{ background: '#fafafa' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '8px' }}>
|
||||
<InfoCircleOutlined style={{ color: '#1890ff' }} />
|
||||
<strong>配置说明</strong>
|
||||
</div>
|
||||
<ul style={{ margin: 0, paddingLeft: '20px', fontSize: '12px', color: '#666' }}>
|
||||
<li>基本配置影响系统的整体显示和行为</li>
|
||||
<li>维护模式开启后,普通用户将无法访问系统</li>
|
||||
<li>系统版本用于标识当前软件版本,建议保持更新</li>
|
||||
<li>管理员邮箱用于接收系统重要通知,请确保可正常接收邮件</li>
|
||||
</ul>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicConfigTab;
|
||||
Reference in New Issue
Block a user