perf: 系统级异步邮件 — 消除SMTP阻塞导致的10-15秒UI冻结
## email_service.py - 新增 send_email_async(): threading.Thread(daemon=True) 包装 send_email() 无需 Flask app_context (send_email仅用os.getenv+smtplib) - 6处 send_email→send_email_async 替换 ## inventory_task.py - 库存预警 send_email→send_email_async (2处)
This commit is contained in:
@ -129,7 +129,7 @@ class InventoryWarningService:
|
|||||||
"timestamp": "..."
|
"timestamp": "..."
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
from app.utils.email_service import send_email
|
from app.utils.email_service import send_email_async
|
||||||
|
|
||||||
beijing_tz = timezone(timedelta(hours=8))
|
beijing_tz = timezone(timedelta(hours=8))
|
||||||
now = datetime.now(beijing_tz)
|
now = datetime.now(beijing_tz)
|
||||||
@ -248,7 +248,7 @@ class InventoryWarningService:
|
|||||||
"详情请登录仓库管理系统查看。\n\n"
|
"详情请登录仓库管理系统查看。\n\n"
|
||||||
"此邮件由系统自动发送,请勿回复。"
|
"此邮件由系统自动发送,请勿回复。"
|
||||||
)
|
)
|
||||||
send_email(email, subject, content)
|
send_email_async(email, subject, content)
|
||||||
sent_red = True
|
sent_red = True
|
||||||
|
|
||||||
# ★ 按邮箱聚合,批量发送黄色预警邮件 ★
|
# ★ 按邮箱聚合,批量发送黄色预警邮件 ★
|
||||||
@ -262,7 +262,7 @@ class InventoryWarningService:
|
|||||||
"详情请登录仓库管理系统查看。\n\n"
|
"详情请登录仓库管理系统查看。\n\n"
|
||||||
"此邮件由系统自动发送,请勿回复。"
|
"此邮件由系统自动发送,请勿回复。"
|
||||||
)
|
)
|
||||||
send_email(email, subject, content)
|
send_email_async(email, subject, content)
|
||||||
sent_yellow = True
|
sent_yellow = True
|
||||||
|
|
||||||
# ★ 批量更新 last_notified_at ★
|
# ★ 批量更新 last_notified_at ★
|
||||||
|
|||||||
@ -118,6 +118,22 @@ def send_email(to_email: Union[str, List[str]], subject: str, content: str):
|
|||||||
logger.error(f"[Email] 发送邮件时发生未知异常: {e}")
|
logger.error(f"[Email] 发送邮件时发生未知异常: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def send_email_async(to_email: Union[str, List[str]], subject: str, content: str):
|
||||||
|
"""
|
||||||
|
异步发送邮件(守护线程,不阻塞主请求线程)。
|
||||||
|
|
||||||
|
用法:直接替代 send_email() 调用,接口完全相同。
|
||||||
|
线程内不依赖 Flask context(仅用 os.getenv + smtplib),无需 app.app_context()。
|
||||||
|
"""
|
||||||
|
import threading
|
||||||
|
t = threading.Thread(
|
||||||
|
target=send_email,
|
||||||
|
args=(to_email, subject, content),
|
||||||
|
daemon=True
|
||||||
|
)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
|
||||||
def send_outbound_new_request_notify(to_emails: List[str], request_no: str,
|
def send_outbound_new_request_notify(to_emails: List[str], request_no: str,
|
||||||
applicant_name: str = '', remark: str = '',
|
applicant_name: str = '', remark: str = '',
|
||||||
items: list = None, is_applicant_notify: bool = False):
|
items: list = None, is_applicant_notify: bool = False):
|
||||||
@ -180,7 +196,7 @@ https://172.16.0.198/outbound/approval
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|
||||||
|
|
||||||
def send_borrow_new_request_notify(to_emails: List[str], request_no: str,
|
def send_borrow_new_request_notify(to_emails: List[str], request_no: str,
|
||||||
@ -245,7 +261,7 @@ https://172.16.0.198/operation/borrow_approval
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|
||||||
|
|
||||||
def send_outbound_approval_result_notify(to_emails: List[str], request_no: str,
|
def send_outbound_approval_result_notify(to_emails: List[str], request_no: str,
|
||||||
@ -276,7 +292,7 @@ def send_outbound_approval_result_notify(to_emails: List[str], request_no: str,
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|
||||||
|
|
||||||
def send_borrow_approval_result_notify(to_emails: List[str], request_no: str,
|
def send_borrow_approval_result_notify(to_emails: List[str], request_no: str,
|
||||||
@ -307,7 +323,7 @@ def send_borrow_approval_result_notify(to_emails: List[str], request_no: str,
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|
||||||
|
|
||||||
def send_outbound_dispatch_notify(to_emails: List[str], request_no: str,
|
def send_outbound_dispatch_notify(to_emails: List[str], request_no: str,
|
||||||
@ -343,7 +359,7 @@ def send_outbound_dispatch_notify(to_emails: List[str], request_no: str,
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|
||||||
|
|
||||||
def send_borrow_dispatch_notify(to_emails: List[str], request_no: str,
|
def send_borrow_dispatch_notify(to_emails: List[str], request_no: str,
|
||||||
@ -379,4 +395,4 @@ def send_borrow_dispatch_notify(to_emails: List[str], request_no: str,
|
|||||||
|
|
||||||
此邮件由系统自动发送,请勿回复。
|
此邮件由系统自动发送,请勿回复。
|
||||||
"""
|
"""
|
||||||
send_email(to_emails, subject, content)
|
send_email_async(to_emails, subject, content)
|
||||||
|
|||||||
Reference in New Issue
Block a user