init: 初始化 dpb 桃育种系统代码库
前后端 + 后端 FastAPI 全量源码、部署脚本与文档。
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"""邮件发送工具(基于标准库 smtplib,465 端口 SSL)。
|
||||
|
||||
配置来自 app.config.setting.settings(SMTP_HOST/PORT/USER/PASSWORD/FROM/FROM_NAME/TLS)。
|
||||
"""
|
||||
from email.header import Header
|
||||
from email.mime.text import MIMEText
|
||||
from smtplib import SMTP_SSL, SMTPException
|
||||
|
||||
from app.config.setting import settings
|
||||
from app.core.logger import logger
|
||||
|
||||
|
||||
def send_email(to_addr: str, subject: str, html_body: str) -> None:
|
||||
"""发送一封 HTML 邮件(同步,内部阻塞;服务层用线程池调用)。
|
||||
|
||||
参数:
|
||||
- to_addr (str): 收件人邮箱
|
||||
- subject (str): 邮件主题
|
||||
- html_body (str): HTML 正文
|
||||
|
||||
异常:
|
||||
- SMTPException: 发送失败时抛出,由调用方捕获并处理
|
||||
"""
|
||||
if not settings.SMTP_HOST or not settings.SMTP_USER:
|
||||
raise RuntimeError("SMTP 未配置:请在 .env 中设置 SMTP_HOST/SMTP_USER/SMTP_PASSWORD")
|
||||
|
||||
from_addr = settings.SMTP_FROM or settings.SMTP_USER
|
||||
display = settings.SMTP_FROM_NAME or from_addr
|
||||
# 显示名单独编码,邮箱地址保持 ASCII
|
||||
from_header = f"{Header(display, 'utf-8').encode()} <{from_addr}>"
|
||||
|
||||
msg = MIMEText(html_body, "html", "utf-8")
|
||||
msg["From"] = from_header
|
||||
msg["To"] = to_addr
|
||||
msg["Subject"] = Header(subject, "utf-8").encode()
|
||||
|
||||
with SMTP_SSL(settings.SMTP_HOST, settings.SMTP_PORT, timeout=10) as server:
|
||||
server.login(settings.SMTP_USER, settings.SMTP_PASSWORD)
|
||||
server.sendmail(from_addr, [to_addr], msg.as_string())
|
||||
|
||||
|
||||
def send_reset_code_email(to_addr: str, code: str, expire_seconds: int) -> None:
|
||||
"""发送找回密码验证码邮件。"""
|
||||
try:
|
||||
send_email(
|
||||
to_addr=to_addr,
|
||||
subject="【dpb】找回密码验证码",
|
||||
html_body=(
|
||||
f"<p>您好,</p>"
|
||||
f"<p>您正在申请找回密码,验证码为:</p>"
|
||||
f'<p style="font-size:24px;font-weight:bold;color:#1677ff;letter-spacing:4px;">{code}</p>'
|
||||
f"<p>验证码 {expire_seconds // 60} 分钟内有效,请勿泄露给他人。</p>"
|
||||
f"<p>若非本人操作,请忽略本邮件。</p>"
|
||||
),
|
||||
)
|
||||
except SMTPException as e:
|
||||
logger.error(f"发送验证码邮件失败 -> {to_addr}: {e!s}")
|
||||
raise
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.error(f"发送验证码邮件异常 -> {to_addr}: {e!s}")
|
||||
raise
|
||||
Reference in New Issue
Block a user