diff --git a/inventory-backend/app/services/inventory_task.py b/inventory-backend/app/services/inventory_task.py index e1011f3..1e08d0e 100644 --- a/inventory-backend/app/services/inventory_task.py +++ b/inventory-backend/app/services/inventory_task.py @@ -129,7 +129,7 @@ class InventoryWarningService: "timestamp": "..." } """ - from app.utils.email_service import send_email + from app.utils.email_service import send_email_async beijing_tz = timezone(timedelta(hours=8)) now = datetime.now(beijing_tz) @@ -248,7 +248,7 @@ class InventoryWarningService: "详情请登录仓库管理系统查看。\n\n" "此邮件由系统自动发送,请勿回复。" ) - send_email(email, subject, content) + send_email_async(email, subject, content) sent_red = True # ★ 按邮箱聚合,批量发送黄色预警邮件 ★ @@ -262,7 +262,7 @@ class InventoryWarningService: "详情请登录仓库管理系统查看。\n\n" "此邮件由系统自动发送,请勿回复。" ) - send_email(email, subject, content) + send_email_async(email, subject, content) sent_yellow = True # ★ 批量更新 last_notified_at ★ diff --git a/inventory-backend/app/utils/email_service.py b/inventory-backend/app/utils/email_service.py index 1b6b58e..a5b8c0d 100644 --- a/inventory-backend/app/utils/email_service.py +++ b/inventory-backend/app/utils/email_service.py @@ -118,6 +118,22 @@ def send_email(to_email: Union[str, List[str]], subject: str, content: str): 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, applicant_name: str = '', remark: str = '', 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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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)