import { useState, useEffect } from 'react' import { CheckCircle, Save, Mail, Plus, Trash2, TestTube, Loader2, Settings, Server } from 'lucide-react' import { Card, CardHeader, CardTitle, CardContent, Button, Input } from '../components/common' import { useConfig } from '../hooks/useConfig' import type { MailServiceConfig } from '../types' export default function EmailConfig() { const { config, updateEmailConfig } = useConfig() const [saved, setSaved] = useState(false) const [services, setServices] = useState(config.email?.services || []) const [testingIndex, setTestingIndex] = useState(null) const [testResults, setTestResults] = useState>({}) // 同步配置变化 useEffect(() => { if (config.email?.services) { setServices(config.email.services) } }, [config.email?.services]) const handleSave = async () => { // 保存到前端 context updateEmailConfig({ services }) // 保存到后端 try { const res = await fetch('/api/mail/services', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ services }), }) if (res.ok) { setSaved(true) setTimeout(() => setSaved(false), 2000) } } catch (error) { console.error('保存失败:', error) } } const handleAddService = () => { setServices([ ...services, { name: `邮箱服务 ${services.length + 1}`, apiBase: '', apiToken: '', domain: '', }, ]) } const handleRemoveService = (index: number) => { if (services.length <= 1) { return // 至少保留一个服务 } const newServices = services.filter((_, i) => i !== index) setServices(newServices) } const handleUpdateService = (index: number, updates: Partial) => { const newServices = [...services] newServices[index] = { ...newServices[index], ...updates } setServices(newServices) } const handleTestService = async (index: number) => { const service = services[index] setTestingIndex(index) setTestResults(prev => ({ ...prev, [index]: { success: false, message: '测试中...' } })) try { const res = await fetch('/api/mail/services/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: service.name, api_base: service.apiBase, api_token: service.apiToken, domain: service.domain, email_path: service.emailPath, }), }) const data = await res.json() if (res.ok && data.code === 0) { setTestResults(prev => ({ ...prev, [index]: { success: true, message: '连接成功' } })) } else { setTestResults(prev => ({ ...prev, [index]: { success: false, message: data.message || '连接失败' } })) } } catch (error) { setTestResults(prev => ({ ...prev, [index]: { success: false, message: '网络错误' } })) } finally { setTestingIndex(null) } } return (
{/* Header */}

邮箱服务配置

配置多个邮箱服务用于自动注册和验证码接收

{/* Service Cards */}
{services.map((service, index) => (
{service.name || `服务 ${index + 1}`} (@{service.domain || '未设置域名'})
{testResults[index] && ( {testResults[index].message} )}
handleUpdateService(index, { name: e.target.value })} hint="用于识别不同的邮箱服务" /> handleUpdateService(index, { domain: e.target.value })} hint="生成邮箱地址的域名后缀" />
handleUpdateService(index, { apiBase: e.target.value })} hint="邮箱服务 API 地址" /> handleUpdateService(index, { apiToken: e.target.value })} hint="邮箱服务的 API 认证令牌" /> {/* Advanced Settings (Collapsed by default) */}
高级设置
handleUpdateService(index, { emailPath: e.target.value })} hint="获取邮件列表的 API 路径" /> handleUpdateService(index, { addUserApi: e.target.value })} hint="创建邮箱用户的 API 路径" />
))}
{/* Help Info */}

配置说明:

  • 可以添加多个邮箱服务,系统会轮询使用各个服务
  • 每个服务需要配置独立的 API 地址、Token 和域名
  • 邮箱域名决定生成的邮箱地址后缀(如 xxx@esyteam.edu.kg)
  • 验证码会自动从配置的邮箱服务获取
  • 高级设置通常不需要修改,使用默认值即可
) }