SmtpConfigModal.jsx 4.21 KB
import React, { useState, useEffect } from 'react'
import { Modal, Form, Input, Button, message, Space, Alert } from 'antd'
import { MailOutlined, LinkOutlined } from '@ant-design/icons'
import request from '../utils/request'

export default function SmtpConfigModal({ open, onClose }) {
  const [form] = Form.useForm()
  const [loading, setLoading] = useState(false)
  const [testLoading, setTestLoading] = useState(false)
  const [hasConfig, setHasConfig] = useState(false)

  useEffect(() => {
    if (open) loadConfig()
  }, [open])

  const loadConfig = async () => {
    const res = await request.get('/scheduler/smtp')
    if (res.success && res.data) {
      form.setFieldsValue({
        host: res.data.host,
        port: res.data.port || '465',
        user: res.data.user,
        senderName: res.data.senderName,
      })
      setHasConfig(true)
    } else {
      form.resetFields()
      form.setFieldsValue({ port: '465' })
      setHasConfig(false)
    }
  }

  const handleTest = async () => {
    try {
      const values = await form.validateFields()
      setTestLoading(true)
      const res = await request.post('/scheduler/smtp/test', values)
      if (res.success) {
        message.success('SMTP连接测试成功')
      } else {
        message.error(res.message)
      }
    } catch {
      // 表单验证失败
    } finally {
      setTestLoading(false)
    }
  }

  const handleSave = async () => {
    try {
      const values = await form.validateFields()
      setLoading(true)
      const res = await request.post('/scheduler/smtp', values)
      if (res.success) {
        message.success('SMTP配置保存成功')
        onClose()
      } else {
        message.error(res.message)
      }
    } catch {
      // 表单验证失败
    } finally {
      setLoading(false)
    }
  }

  return (
    <Modal
      title="邮件发送配置(SMTP)"
      open={open}
      onCancel={onClose}
      width={520}
      footer={
        <Space>
          <Button onClick={handleTest} loading={testLoading} icon={<LinkOutlined />}>
            测试连接
          </Button>
          <Button onClick={onClose}>取消</Button>
          <Button type="primary" onClick={handleSave} loading={loading}>
            保存配置
          </Button>
        </Space>
      }
    >
      {hasConfig && (
        <Alert
          message="已配置SMTP"
          description="当前已有SMTP配置,保存将覆盖原配置。密码已隐藏,如需修改请重新输入。"
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
        />
      )}

      <Form form={form} layout="vertical">
        <Form.Item name="host" label="SMTP服务器地址" rules={[{ required: true, message: '请输入SMTP地址' }]}>
          <Input placeholder="例如:smtp.qq.com / smtp.163.com / smtp.exmail.qq.com" />
        </Form.Item>
        <div style={{ display: 'flex', gap: 12 }}>
          <Form.Item name="port" label="端口" rules={[{ required: true }]} style={{ flex: 1 }}>
            <Input placeholder="465(SSL) / 587(TLS)" />
          </Form.Item>
          <Form.Item name="senderName" label="发件人名称" style={{ flex: 1 }}>
            <Input placeholder="SQL报表工具" />
          </Form.Item>
        </div>
        <Form.Item name="user" label="邮箱账号" rules={[{ required: true, message: '请输入邮箱账号' }]}>
          <Input placeholder="your@email.com" />
        </Form.Item>
        <Form.Item name="pass" label="邮箱密码/授权码" rules={hasConfig ? [] : [{ required: true, message: '请输入密码' }]}>
          <Input.Password placeholder={hasConfig ? '如需修改请输入新密码' : 'QQ邮箱请使用授权码'} />
        </Form.Item>
      </Form>

      <div style={{ padding: '8px 12px', background: '#f6f6f6', borderRadius: 6, fontSize: 12, color: '#888', lineHeight: 2 }}>
        <div><b>常用SMTP配置参考:</b></div>
        <div>QQ邮箱:smtp.qq.com,端口465,密码用授权码(设置→账户→POP3/SMTP服务获取)</div>
        <div>163邮箱:smtp.163.com,端口465,密码用授权码</div>
        <div>腾讯企业邮箱:smtp.exmail.qq.com,端口465</div>
        <div>阿里企业邮箱:smtp.mxhichina.com,端口465</div>
      </div>
    </Modal>
  )
}