from celery import shared_task from django.core.mail import EmailMultiAlternatives from django.template.loader import render_to_string FROM_EMAIL = '可乐平台 ' EMAIL_CONFIG = { 'register': { 'subject': '【可乐平台】账号注册验证码', 'title': '欢迎注册可乐平台', 'greeting': '欢迎使用可乐平台!', 'description': '感谢您的注册,您正在完成账号注册操作,请在注册页面输入以下验证码完成验证。', }, 'login': { 'subject': '【可乐平台】登录验证验证码', 'title': '登录安全验证', 'greeting': '感谢您的信任!', 'description': '您正在进行邮箱登录操作,请在登录页面输入以下验证码完成验证。', }, 'reset_password': { 'subject': '【可乐平台】重置密码验证码', 'title': '重置您的密码', 'greeting': '您好!', 'description': '您正在进行重置密码操作,请在重置密码页面输入以下验证码完成验证,以重新设置您的账号密码。', }, 'change_email_old': { 'subject': '【可乐平台】验证当前邮箱', 'title': '邮箱修改验证', 'greeting': '您好!', 'description': '您正在进行邮箱修改操作,请先验证当前绑定的邮箱。请输入以下验证码完成验证。', }, 'change_email_new': { 'subject': '【可乐平台】验证新邮箱', 'title': '绑定新邮箱', 'greeting': '您好!', 'description': '您正在将可乐平台账号绑定到此新邮箱,请输入以下验证码完成新邮箱的绑定操作。', }, } def _send_html_email(to_email, code, config_key): config = EMAIL_CONFIG[config_key] context = { 'code': code, 'title': config['title'], 'greeting': config['greeting'], 'description': config['description'], } html_content = render_to_string('email/verification_code.html', context) text_content = ( f'{config["subject"]}\n' f'{config["description"]}\n' f'您的验证码:{code}\n' f'验证码10分钟内有效,请勿泄露给他人。\n' f'如非本人操作,请忽略此邮件。\n' f'— 可乐平台 ChunYu.dev' ) email = EmailMultiAlternatives( subject=config['subject'], body=text_content, from_email=FROM_EMAIL, to=[to_email], ) email.attach_alternative(html_content, 'text/html') try: email.send() except Exception as e: import logging logger = logging.getLogger(__name__) logger.error( f'[Email] SMTP send failed: to={to_email}, type={config_key}, error={str(e)}', exc_info=True ) raise @shared_task def send_verification_email_task(to_email, code, email_type='register'): _send_html_email(to_email, code, email_type) return {'email': to_email, 'type': email_type, 'status': 'sent'} @shared_task def send_reset_password_email_task(to_email, code): _send_html_email(to_email, code, 'reset_password') return {'email': to_email, 'type': 'reset_password', 'status': 'sent'} @shared_task def send_change_email_task(to_email, code, target='old'): config_key = 'change_email_old' if target == 'old' else 'change_email_new' _send_html_email(to_email, code, config_key) return {'email': to_email, 'target': target, 'status': 'sent'}