125 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import smtplib
 | 
						||
from email.mime.text import MIMEText
 | 
						||
from email.mime.multipart import MIMEMultipart
 | 
						||
from email.utils import formataddr
 | 
						||
from flask import current_app
 | 
						||
import logging
 | 
						||
 | 
						||
def _send_email(recipient, subject, html_body):
 | 
						||
    """
 | 
						||
    统一的邮件发送内部函数.
 | 
						||
    :param recipient: 收件人邮箱
 | 
						||
    :param subject: 邮件主题
 | 
						||
    :param html_body: HTML格式的邮件内容
 | 
						||
    :return: True if success, False otherwise.
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        # 创建邮件对象
 | 
						||
        msg = MIMEMultipart()
 | 
						||
        
 | 
						||
        # 使用 formataddr 来正确编码包含非ASCII字符(如中文)的发件人名称
 | 
						||
        msg['From'] = formataddr((
 | 
						||
            current_app.config['EMAIL_FROM_NAME'],
 | 
						||
            current_app.config['EMAIL_FROM']
 | 
						||
        ))
 | 
						||
        
 | 
						||
        msg['To'] = recipient
 | 
						||
        msg['Subject'] = subject
 | 
						||
        
 | 
						||
        msg.attach(MIMEText(html_body, 'html', 'utf-8'))
 | 
						||
        
 | 
						||
        # 发送邮件
 | 
						||
        server = smtplib.SMTP(current_app.config['EMAIL_HOST'], current_app.config['EMAIL_PORT'])
 | 
						||
        if current_app.config['EMAIL_ENCRYPTION'] == 'starttls':
 | 
						||
            server.starttls()
 | 
						||
        server.login(current_app.config['EMAIL_USERNAME'], current_app.config['EMAIL_PASSWORD'])
 | 
						||
        server.send_message(msg)
 | 
						||
        server.quit()
 | 
						||
        
 | 
						||
        current_app.logger.info(f"成功发送邮件到: {recipient}, 主题: {subject}")
 | 
						||
        return True
 | 
						||
        
 | 
						||
    except Exception as e:
 | 
						||
        # 统一记录错误日志
 | 
						||
        current_app.logger.error(f"发送邮件到 {recipient} 失败 (主题: {subject}): {str(e)}")
 | 
						||
        return False
 | 
						||
 | 
						||
def send_verification_email(email, verification_code):
 | 
						||
    """发送注册验证码邮件"""
 | 
						||
    subject = '【儿童语言学习系统】邮箱验证码'
 | 
						||
    body = f"""
 | 
						||
    <html>
 | 
						||
    <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
 | 
						||
        <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
 | 
						||
            <div style="text-align: center; margin-bottom: 30px;">
 | 
						||
                <h2 style="color: #4a90e2;">儿童语言学习系统</h2>
 | 
						||
                <div style="height: 3px; background: linear-gradient(to right, #4a90e2, #7b68ee); margin: 10px auto; width: 100px;"></div>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="background: #f8f9fa; padding: 25px; border-radius: 10px; margin: 20px 0;">
 | 
						||
                <h3 style="color: #2c3e50; margin-bottom: 15px;">您的验证码</h3>
 | 
						||
                <div style="background: white; padding: 20px; border-radius: 8px; text-align: center; margin: 15px 0;">
 | 
						||
                    <span style="font-size: 32px; font-weight: bold; color: #4a90e2; letter-spacing: 8px;">{verification_code}</span>
 | 
						||
                </div>
 | 
						||
                <p style="color: #666; margin-top: 15px;">
 | 
						||
                    <strong>注意:</strong>验证码5分钟内有效,请及时使用。如果不是您本人操作,请忽略此邮件。
 | 
						||
                </p>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107;">
 | 
						||
                <h4 style="color: #856404; margin-bottom: 10px;">安全提示</h4>
 | 
						||
                <p style="color: #856404; margin: 0;">
 | 
						||
                    为了您的账号安全,请不要将验证码泄露给他人。我们不会主动向您索要验证码。
 | 
						||
                </p>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="margin-top: 30px; text-align: center; color: #6c757d; font-size: 14px;">
 | 
						||
                <p>此邮件由系统自动发送,请勿直接回复</p>
 | 
						||
                <p style="margin-top: 5px;">© 儿童语言学习系统 - 让孩子快乐学语言</p>
 | 
						||
            </div>
 | 
						||
        </div>
 | 
						||
    </body>
 | 
						||
    </html>
 | 
						||
    """
 | 
						||
    return _send_email(email, subject, body)
 | 
						||
 | 
						||
def send_password_reset_email(email, verification_code):
 | 
						||
    """发送密码重置邮件"""
 | 
						||
    subject = '【儿童语言学习系统】密码重置验证码'
 | 
						||
    body = f"""
 | 
						||
    <html>
 | 
						||
    <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
 | 
						||
        <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
 | 
						||
            <div style="text-align: center; margin-bottom: 30px;">
 | 
						||
                <h2 style="color: #dc3545;">密码重置</h2>
 | 
						||
                <div style="height: 3px; background: linear-gradient(to right, #dc3545, #fd7e14); margin: 10px auto; width: 100px;"></div>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="background: #f8f9fa; padding: 25px; border-radius: 10px; margin: 20px 0;">
 | 
						||
                <h3 style="color: #2c3e50; margin-bottom: 15px;">密码重置验证码</h3>
 | 
						||
                <div style="background: white; padding: 20px; border-radius: 8px; text-align: center; margin: 15px 0;">
 | 
						||
                    <span style="font-size: 32px; font-weight: bold; color: #dc3545; letter-spacing: 8px;">{verification_code}</span>
 | 
						||
                </div>
 | 
						||
                <p style="color: #666; margin-top: 15px;">
 | 
						||
                    <strong>注意:</strong>验证码5分钟内有效,请及时使用。如果不是您本人操作,请立即修改密码并联系我们。
 | 
						||
                </p>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="background: #f8d7da; padding: 15px; border-radius: 8px; border-left: 4px solid #dc3545;">
 | 
						||
                <h4 style="color: #721c24; margin-bottom: 10px;">重要提醒</h4>
 | 
						||
                <p style="color: #721c24; margin: 0;">
 | 
						||
                    如果您没有申请密码重置,请忽略此邮件。为了账号安全,建议您定期更换密码。
 | 
						||
                </p>
 | 
						||
            </div>
 | 
						||
            
 | 
						||
            <div style="margin-top: 30px; text-align: center; color: #6c757d; font-size: 14px;">
 | 
						||
                <p>此邮件由系统自动发送,请勿直接回复</p>
 | 
						||
                <p style="margin-top: 5px;">© 儿童语言学习系统 - 让孩子快乐学语言</p>
 | 
						||
            </div>
 | 
						||
        </div>
 | 
						||
    </body>
 | 
						||
    </html>
 | 
						||
    """
 | 
						||
    # 调用统一的发送函数
 | 
						||
    return _send_email(email, subject, body)
 |