import React, { useState, useEffect } from 'react'; import { Card, Row, Col, Button, Tabs, Form, Input, Switch, Select, Avatar, Upload, message, Divider, Typography, Space, Tag, Table, Modal, Descriptions, List, Badge, Popconfirm, TimePicker, Checkbox, Radio, Slider, Tooltip, Alert, } from 'antd'; import { UserOutlined, TeamOutlined, SettingOutlined, LockOutlined, BellOutlined, GlobalOutlined, SafetyOutlined, UploadOutlined, EditOutlined, DeleteOutlined, PlusOutlined, KeyOutlined, MailOutlined, MobileOutlined, DesktopOutlined, ApiOutlined, DatabaseOutlined, CloudOutlined, FileTextOutlined, QuestionCircleOutlined, SaveOutlined, ReloadOutlined, } from '@ant-design/icons'; import type { ColumnsType } from 'antd/es/table'; import moment from 'moment'; const { Title, Text, Paragraph } = Typography; const { TabPane } = Tabs; const { Option } = Select; const { TextArea } = Input; // 用户设置接口 interface UserProfile { id: string; username: string; email: string; phone: string; avatar: string; role: string; department: string; timezone: string; language: string; createdAt: string; lastLoginAt: string; } // 通知设置接口 interface NotificationSettings { emailEnabled: boolean; smsEnabled: boolean; pushEnabled: boolean; orderAlerts: boolean; inventoryAlerts: boolean; complianceAlerts: boolean; systemAlerts: boolean; marketingEmails: boolean; digestFrequency: 'realtime' | 'hourly' | 'daily' | 'weekly'; quietHoursStart: string; quietHoursEnd: string; } // 安全设置接口 interface SecuritySettings { twoFactorEnabled: boolean; loginNotification: boolean; passwordExpiryDays: number; sessionTimeout: number; ipWhitelist: string[]; apiKey: string; lastPasswordChange: string; } // 系统设置接口 interface SystemSettings { autoSync: boolean; syncInterval: number; dataRetentionDays: number; backupEnabled: boolean; backupFrequency: 'daily' | 'weekly' | 'monthly'; logLevel: 'debug' | 'info' | 'warn' | 'error'; theme: 'light' | 'dark' | 'auto'; dateFormat: string; currency: string; } // API密钥接口 interface ApiKey { id: string; name: string; key: string; permissions: string[]; createdAt: string; lastUsedAt: string; status: 'active' | 'inactive'; } // 操作日志接口 interface OperationLog { id: string; userId: string; username: string; action: string; module: string; details: string; ip: string; userAgent: string; createdAt: string; } const MOCK_USER_PROFILE: UserProfile = { id: '1', username: 'admin', email: 'admin@crawlful.com', phone: '+86 13800138000', avatar: '', role: 'ADMIN', department: '技术部', timezone: 'Asia/Shanghai', language: 'zh-CN', createdAt: '2025-01-15', lastLoginAt: '2026-03-18 10:30:00', }; const MOCK_NOTIFICATION_SETTINGS: NotificationSettings = { emailEnabled: true, smsEnabled: false, pushEnabled: true, orderAlerts: true, inventoryAlerts: true, complianceAlerts: true, systemAlerts: true, marketingEmails: false, digestFrequency: 'daily', quietHoursStart: '22:00', quietHoursEnd: '08:00', }; const MOCK_SECURITY_SETTINGS: SecuritySettings = { twoFactorEnabled: false, loginNotification: true, passwordExpiryDays: 90, sessionTimeout: 30, ipWhitelist: [], apiKey: 'sk_live_xxxxxxxxxxxxxxxx', lastPasswordChange: '2026-01-01', }; const MOCK_SYSTEM_SETTINGS: SystemSettings = { autoSync: true, syncInterval: 15, dataRetentionDays: 365, backupEnabled: true, backupFrequency: 'daily', logLevel: 'info', theme: 'light', dateFormat: 'YYYY-MM-DD', currency: 'CNY', }; const MOCK_API_KEYS: ApiKey[] = [ { id: '1', name: 'Production API Key', key: 'sk_live_prod_xxxxxxxx', permissions: ['read', 'write'], createdAt: '2026-01-01', lastUsedAt: '2026-03-18 09:00:00', status: 'active', }, { id: '2', name: 'Test API Key', key: 'sk_test_xxxxxxxx', permissions: ['read'], createdAt: '2026-02-01', lastUsedAt: '2026-03-17 15:30:00', status: 'active', }, ]; const MOCK_OPERATION_LOGS: OperationLog[] = [ { id: '1', userId: '1', username: 'admin', action: 'LOGIN', module: 'AUTH', details: '用户登录成功', ip: '192.168.1.100', userAgent: 'Mozilla/5.0', createdAt: '2026-03-18 10:30:00', }, { id: '2', userId: '1', username: 'admin', action: 'UPDATE_PRODUCT', module: 'PRODUCT', details: '更新产品信息: P001', ip: '192.168.1.100', userAgent: 'Mozilla/5.0', createdAt: '2026-03-18 10:35:00', }, { id: '3', userId: '1', username: 'admin', action: 'CREATE_ORDER', module: 'ORDER', details: '创建订单: ORD-2026-001', ip: '192.168.1.100', userAgent: 'Mozilla/5.0', createdAt: '2026-03-18 11:00:00', }, ]; const Settings: React.FC = () => { const [activeTab, setActiveTab] = useState('profile'); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); // 表单实例 const [profileForm] = Form.useForm(); const [notificationForm] = Form.useForm(); const [securityForm] = Form.useForm(); const [systemForm] = Form.useForm(); const [passwordForm] = Form.useForm(); const [apiKeyForm] = Form.useForm(); // 数据状态 const [userProfile, setUserProfile] = useState(MOCK_USER_PROFILE); const [notificationSettings, setNotificationSettings] = useState(MOCK_NOTIFICATION_SETTINGS); const [securitySettings, setSecuritySettings] = useState(MOCK_SECURITY_SETTINGS); const [systemSettings, setSystemSettings] = useState(MOCK_SYSTEM_SETTINGS); const [apiKeys, setApiKeys] = useState(MOCK_API_KEYS); const [operationLogs, setOperationLogs] = useState(MOCK_OPERATION_LOGS); // 模态框状态 const [passwordModalVisible, setPasswordModalVisible] = useState(false); const [apiKeyModalVisible, setApiKeyModalVisible] = useState(false); const [twoFactorModalVisible, setTwoFactorModalVisible] = useState(false); useEffect(() => { // 初始化表单值 profileForm.setFieldsValue(userProfile); notificationForm.setFieldsValue(notificationSettings); securityForm.setFieldsValue(securitySettings); systemForm.setFieldsValue(systemSettings); }, []); // ==================== 个人资料 ==================== const handleProfileSave = async () => { try { setSaving(true); const values = await profileForm.validateFields(); await new Promise(resolve => setTimeout(resolve, 500)); setUserProfile({ ...userProfile, ...values }); message.success('个人资料已保存'); } catch (error) { console.error('Save failed:', error); } finally { setSaving(false); } }; const handleAvatarUpload = (info: any) => { if (info.file.status === 'done') { message.success('头像上传成功'); } }; // ==================== 通知设置 ==================== const handleNotificationSave = async () => { try { setSaving(true); const values = await notificationForm.validateFields(); await new Promise(resolve => setTimeout(resolve, 500)); setNotificationSettings(values); message.success('通知设置已保存'); } catch (error) { console.error('Save failed:', error); } finally { setSaving(false); } }; // ==================== 安全设置 ==================== const handlePasswordChange = async () => { try { const values = await passwordForm.validateFields(); if (values.newPassword !== values.confirmPassword) { message.error('两次输入的密码不一致'); return; } await new Promise(resolve => setTimeout(resolve, 500)); message.success('密码修改成功'); setPasswordModalVisible(false); passwordForm.resetFields(); } catch (error) { console.error('Password change failed:', error); } }; const handleTwoFactorToggle = async (enabled: boolean) => { if (enabled) { setTwoFactorModalVisible(true); } else { setSecuritySettings({ ...securitySettings, twoFactorEnabled: false }); message.success('双因素认证已关闭'); } }; const handleSecuritySave = async () => { try { setSaving(true); const values = await securityForm.validateFields(); await new Promise(resolve => setTimeout(resolve, 500)); setSecuritySettings({ ...securitySettings, ...values }); message.success('安全设置已保存'); } catch (error) { console.error('Save failed:', error); } finally { setSaving(false); } }; // ==================== API密钥管理 ==================== const handleCreateApiKey = async () => { try { const values = await apiKeyForm.validateFields(); const newKey: ApiKey = { id: `${Date.now()}`, name: values.name, key: `sk_${values.environment}_${Math.random().toString(36).substring(2, 15)}`, permissions: values.permissions, createdAt: moment().format('YYYY-MM-DD'), lastUsedAt: '-', status: 'active', }; setApiKeys([newKey, ...apiKeys]); setApiKeyModalVisible(false); apiKeyForm.resetFields(); message.success('API密钥创建成功'); } catch (error) { console.error('Create API key failed:', error); } }; const handleDeleteApiKey = (id: string) => { setApiKeys(apiKeys.filter(key => key.id !== id)); message.success('API密钥已删除'); }; const handleCopyApiKey = (key: string) => { navigator.clipboard.writeText(key); message.success('API密钥已复制到剪贴板'); }; // ==================== 系统设置 ==================== const handleSystemSave = async () => { try { setSaving(true); const values = await systemForm.validateFields(); await new Promise(resolve => setTimeout(resolve, 500)); setSystemSettings(values); message.success('系统设置已保存'); } catch (error) { console.error('Save failed:', error); } finally { setSaving(false); } }; // ==================== 表格列定义 ==================== const apiKeyColumns: ColumnsType = [ { title: '名称', dataIndex: 'name', key: 'name', }, { title: '密钥', dataIndex: 'key', key: 'key', render: (key) => ( {key.substring(0, 20)}... ), }, { title: '权限', dataIndex: 'permissions', key: 'permissions', render: (permissions) => ( {permissions.map((perm: string) => ( {perm === 'read' ? '读取' : '写入'} ))} ), }, { title: '状态', dataIndex: 'status', key: 'status', render: (status) => ( ), }, { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', }, { title: '最后使用', dataIndex: 'lastUsedAt', key: 'lastUsedAt', }, { title: '操作', key: 'action', render: (_, record) => ( handleDeleteApiKey(record.id)} okText="删除" cancelText="取消" > ), }, ]; const logColumns: ColumnsType = [ { title: '时间', dataIndex: 'createdAt', key: 'createdAt', width: 160, }, { title: '用户', dataIndex: 'username', key: 'username', }, { title: '操作', dataIndex: 'action', key: 'action', render: (action) => { const actionMap: Record = { LOGIN: { color: 'green', text: '登录' }, LOGOUT: { color: 'default', text: '登出' }, CREATE: { color: 'blue', text: '创建' }, UPDATE: { color: 'orange', text: '更新' }, DELETE: { color: 'red', text: '删除' }, }; const config = actionMap[action] || { color: 'default', text: action }; return {config.text}; }, }, { title: '模块', dataIndex: 'module', key: 'module', }, { title: '详情', dataIndex: 'details', key: 'details', }, { title: 'IP地址', dataIndex: 'ip', key: 'ip', }, ]; return (
系统设置 管理您的账户设置、通知偏好和系统配置
{/* 个人资料 */} 个人资料 } key="profile" > } src={userProfile.avatar} />
{userProfile.id} {userProfile.role} {userProfile.department} {userProfile.createdAt} {userProfile.lastLoginAt}
} placeholder="用户名" /> } placeholder="邮箱" /> } placeholder="手机号" />
{/* 通知设置 */} 通知设置 } key="notifications" >
通知渠道
邮件通知
接收重要事件的邮件通知
短信通知
接收紧急事件的短信通知
推送通知
接收浏览器推送通知
通知类型 订单提醒 - 新订单、订单状态变更 库存提醒 - 库存不足、库存预警 合规提醒 - 证书过期、合规检查失败 系统提醒 - 系统维护、功能更新 营销邮件 - 产品更新、优惠活动 高级设置
{/* 安全设置 */} 安全设置 } key="security" > setPasswordModalVisible(true)}> 修改密码 , ]} > } title="登录密码" description={`上次修改: ${securitySettings.lastPasswordChange}`} /> , ]} > } title="双因素认证 (2FA)" description="启用后,登录时需要输入手机验证码" /> setSecuritySettings({ ...securitySettings, loginNotification: checked })} />, ]} > } title="登录通知" description="新设备登录时发送通知" />
{/* API密钥 */} API密钥 } key="apikeys" > } onClick={() => setApiKeyModalVisible(true)}> 创建API密钥 } > {/* 系统设置 */} 系统设置 } key="system" >
数据同步
数据管理 显示设置 日志设置 调试 信息 警告 错误 {/* 操作日志 */} 操作日志 } key="logs" >
{/* 配置管理 */} 配置管理 } key="configs" > window.location.href = '/Settings/PlatformAccountConfig'} >
平台账号配置 管理各平台的API账号和授权信息
window.location.href = '/Settings/ExchangeRateConfig'} >
汇率配置 管理多币种汇率和自动同步设置
window.location.href = '/Settings/CostTemplateConfig'} >
成本模板配置 管理各平台和品类的成本计算模板
window.location.href = '/Settings/WinNodeConfig'} >
WinNode配置 管理Windows执行节点和浏览器实例
{/* 修改密码模态框 */} { setPasswordModalVisible(false); passwordForm.resetFields(); }} >
{/* 创建API密钥模态框 */} { setApiKeyModalVisible(false); apiKeyForm.resetFields(); }} >
读取 写入
{/* 双因素认证模态框 */} { setSecuritySettings({ ...securitySettings, twoFactorEnabled: true }); setTwoFactorModalVisible(false); message.success('双因素认证已启用'); }} onCancel={() => setTwoFactorModalVisible(false)} >

启用双因素认证后,每次登录时除了密码外,还需要输入手机验证码。

这将大大提高您账户的安全性。

); }; export default Settings;