3 Commits

4 changed files with 25 additions and 4 deletions

View File

@ -29,6 +29,14 @@ services:
command: gunicorn -c gunicorn.conf.py run:app command: gunicorn -c gunicorn.conf.py run:app
environment: environment:
DATABASE_URL: postgresql://prod_user:StrongPassword123!@db:5432/inventory_system DATABASE_URL: postgresql://prod_user:StrongPassword123!@db:5432/inventory_system
MAIL_ENABLED: "true"
MAIL_SERVER: smtp.mxhichina.com
MAIL_PORT: "465"
MAIL_USERNAME: wms@iris-rs.cn
MAIL_PASSWORD: Q7nYyyESWlaThKjx
MAIL_DEFAULT_SENDER: wms@iris-rs.cn
MAIL_USE_SSL: "true"
MAIL_USE_TLS: "false"
depends_on: depends_on:
- db - db

View File

@ -26,6 +26,14 @@ services:
command: gunicorn -c gunicorn.conf.py run:app --reload command: gunicorn -c gunicorn.conf.py run:app --reload
environment: environment:
DATABASE_URL: postgresql://test:1234@db:5432/inventory_system DATABASE_URL: postgresql://test:1234@db:5432/inventory_system
MAIL_ENABLED: "true"
MAIL_SERVER: smtp.mxhichina.com
MAIL_PORT: "465"
MAIL_USERNAME: wms@iris-rs.cn
MAIL_PASSWORD: Q7nYyyESWlaThKjx
MAIL_DEFAULT_SENDER: wms@iris-rs.cn
MAIL_USE_SSL: "true"
MAIL_USE_TLS: "false"
depends_on: depends_on:
- db - db

View File

@ -45,7 +45,7 @@ def _get_config():
} }
def send_email(to_email: Union[str, List[str]], subject: str, content: str): def send_email(to_email: Union[str, List[str]], subject: str, content: str, cfg: dict = None):
""" """
通用邮件发送函数 通用邮件发送函数
@ -53,9 +53,11 @@ def send_email(to_email: Union[str, List[str]], subject: str, content: str):
to_email: 收件人,单个邮箱字符串或列表 to_email: 收件人,单个邮箱字符串或列表
subject: 邮件主题 subject: 邮件主题
content: 邮件正文(纯文本) content: 邮件正文(纯文本)
cfg: 可选,预先获取的配置字典(用于异步线程传参,避免丢失 Flask context)
发送失败时打印日志,不抛出异常 发送失败时打印日志,不抛出异常
""" """
if cfg is None:
cfg = _get_config() cfg = _get_config()
print(f"[DEBUG send_email] cfg = {cfg}") print(f"[DEBUG send_email] cfg = {cfg}")
@ -123,12 +125,15 @@ def send_email_async(to_email: Union[str, List[str]], subject: str, content: str
异步发送邮件(守护线程,不阻塞主请求线程)。 异步发送邮件(守护线程,不阻塞主请求线程)。
用法:直接替代 send_email() 调用,接口完全相同。 用法:直接替代 send_email() 调用,接口完全相同。
线程内不依赖 Flask context(仅用 os.getenv + smtplib),无需 app.app_context()。 在主线程中预取配置,传入守护线程,避免线程内丢失 Flask context 导致
_get_config() 回退到 os.getenv() 而 docker-compose 未设置 MAIL_* 环境变量。
""" """
import threading import threading
cfg = _get_config()
t = threading.Thread( t = threading.Thread(
target=send_email, target=send_email,
args=(to_email, subject, content), args=(to_email, subject, content),
kwargs={'cfg': cfg},
daemon=True daemon=True
) )
t.start() t.start()

View File

@ -239,7 +239,7 @@ const handleLogout = () => {
<footer v-if="!isLoginPage" class="app-footer"> <footer v-if="!isLoginPage" class="app-footer">
<span class="version-tag"> <span class="version-tag">
<el-icon style="vertical-align: middle; margin-right: 4px"><InfoFilled /></el-icon> <el-icon style="vertical-align: middle; margin-right: 4px"><InfoFilled /></el-icon>
当前版本:V3.59 当前版本:V3.60
</span> </span>
</footer> </footer>