""" 邮件发送服务模块 ============================================================= 封装 Flask-Mail 提供邮件发送能力,供业务模块和定时任务调用。 使用方式: from application.services import mail_svc # 简单发送 mail_svc.send_mail(to='user@example.com', subject='标题', body='内容') # HTML 邮件 mail_svc.send_mail(to='user@example.com', subject='标题', html='

Hello

') # 多收件人 / 抄送 mail_svc.send_mail( to=['a@example.com', 'b@example.com'], subject='标题', body='内容', cc=['cc@example.com'], ) """ import logging from typing import List, Optional, Union from extensions.mail import mail from flask import current_app from flask_mail import Message logger = logging.getLogger(__name__) def send_mail( to: Union[str, List[str]], subject: str, body: Optional[str] = None, html: Optional[str] = None, cc: Optional[Union[str, List[str]]] = None, bcc: Optional[Union[str, List[str]]] = None, reply_to: Optional[str] = None, ) -> bool: """ 发送邮件 Args: to: 收件人地址,字符串或列表 subject: 邮件主题 body: 纯文本正文(与 html 二选一,都提供时邮件客户端自行选择显示) html: HTML 正文 cc: 抄送地址 bcc: 密送地址 reply_to: 回复地址 Returns: bool: 发送成功返回 True,失败返回 False """ if not to: logger.warning("发送邮件失败:收件人不能为空") return False if not subject: logger.warning("发送邮件失败:主题不能为空") return False if not body and not html: logger.warning("发送邮件失败:正文不能为空") return False # 统一转为列表 if isinstance(to, str): to = [to] if cc and isinstance(cc, str): cc = [cc] if bcc and isinstance(bcc, str): bcc = [bcc] try: msg = Message( subject=subject, recipients=to, cc=cc, bcc=bcc, reply_to=reply_to, body=body, html=html, ) mail.send(msg) logger.info(f"邮件发送成功: to={to}, subject={subject}") return True except Exception as e: logger.error(f"邮件发送失败: to={to}, subject={subject}, error={str(e)}") return False