diff --git a/README.md b/README.md index fc3e10f..41c494d 100644 --- a/README.md +++ b/README.md @@ -620,11 +620,13 @@ timeout 300 当需要更新代码时,可以使用以下命令: -退出虚拟环境 -deactivate ```bash +# 退出虚拟环境 +deactivate + +# 切换到项目目录 cd /var/www/diary-family # 1. 拉取远程最新代码(只获取,不合并) diff --git a/diary_family/__pycache__/settings.cpython-313.pyc b/diary_family/__pycache__/settings.cpython-313.pyc index f9a5ce4..c0902c7 100644 Binary files a/diary_family/__pycache__/settings.cpython-313.pyc and b/diary_family/__pycache__/settings.cpython-313.pyc differ diff --git a/logs/app.log b/logs/app.log index 27f9d3a..fc34e2e 100644 --- a/logs/app.log +++ b/logs/app.log @@ -1,2 +1,50 @@ -2026-01-13 21:34:19.816 | INFO | __main__:main:167 - 开始PDF生成功能测试 -2026-01-13 21:36:11.549 | INFO | __main__:main:216 - 开始Windows环境PDF生成测试 +2026-01-18 16:23:51.077 | INFO | __main__:test_email_config:39 - 邮件配置信息: +2026-01-18 16:23:51.092 | WARNING | __main__:test_email_config:42 - smtp_server: 未配置 +2026-01-18 16:23:51.093 | INFO | __main__:test_email_config:44 - smtp_port: 587 +2026-01-18 16:23:51.093 | WARNING | __main__:test_email_config:42 - smtp_username: 未配置 +2026-01-18 16:23:51.093 | WARNING | __main__:test_email_config:42 - smtp_password: 未配置 +2026-01-18 16:23:51.093 | WARNING | __main__:test_email_config:42 - recipient_email: 未配置 +2026-01-18 16:23:51.094 | INFO | __main__:test_email_config:44 - send_time: 08:00 +2026-01-18 16:23:51.094 | ERROR | __main__:test_email_config:54 - 缺少必要的邮件配置: smtp_server, smtp_username, smtp_password +2026-01-18 16:23:51.094 | INFO | __main__:test_email_config:55 - 请在系统配置页面配置以下参数: +2026-01-18 16:23:51.094 | INFO | __main__:test_email_config:56 - - SMTP服务器: SMTP服务器地址 +2026-01-18 16:23:51.095 | INFO | __main__:test_email_config:57 - - SMTP端口: SMTP端口(通常是587或465) +2026-01-18 16:23:51.095 | INFO | __main__:test_email_config:58 - - SMTP用户名: 发件邮箱 +2026-01-18 16:23:51.095 | INFO | __main__:test_email_config:59 - - SMTP密码: 发件邮箱密码 +2026-01-18 16:23:51.095 | INFO | __main__:main:510 - +[测试2] SMTP连接测试 +2026-01-18 16:23:51.095 | INFO | __main__:test_smtp_connection:72 - 开始测试SMTP连接... +2026-01-18 16:23:51.118 | INFO | __main__:test_smtp_connection:92 - 连接SMTP服务器: localhost:587 +2026-01-18 16:23:51.119 | INFO | __main__:test_smtp_connection:93 - 使用TLS: True, 使用SSL: False +2026-01-18 16:23:51.119 | INFO | __main__:test_smtp_connection:108 - 正在建立SMTP连接... +2026-01-18 16:23:56.491 | ERROR | __main__:test_smtp_connection:131 - SMTP连接测试失败: [WinError 10061] 由于目标计算机积极拒绝,无法连接。 +2026-01-18 16:23:56.492 | ERROR | __main__:test_smtp_connection:171 - 请检查: +2026-01-18 16:23:56.493 | ERROR | __main__:test_smtp_connection:172 - 1. SMTP服务器配置是否正确 +2026-01-18 16:23:56.494 | ERROR | __main__:test_smtp_connection:173 - 2. 邮箱账号和密码是否正确 +2026-01-18 16:23:56.494 | ERROR | __main__:test_smtp_connection:174 - 3. 网络连接是否正常 +2026-01-18 16:23:56.495 | ERROR | __main__:test_smtp_connection:175 - 4. 防火墙是否允许出站连接 +2026-01-18 16:23:56.496 | INFO | __main__:main:515 - +[测试3] 发送简单文本邮件 +2026-01-18 16:23:56.496 | INFO | __main__:test_send_simple_email:182 - 开始测试发送简单邮件... +2026-01-18 16:23:56.502 | ERROR | __main__:test_send_simple_email:198 - 未配置发件邮箱 (smtp_username) +2026-01-18 16:23:56.503 | INFO | __main__:main:520 - +[测试4] 发送HTML邮件(带附件) +2026-01-18 16:23:56.503 | INFO | __main__:test_send_html_email_with_attachment:288 - 开始测试发送HTML邮件(带附件)... +2026-01-18 16:23:56.506 | ERROR | __main__:test_send_html_email_with_attachment:304 - 未配置发件邮箱 +2026-01-18 16:23:56.507 | INFO | __main__:main:525 - +[测试5] 邮件发送性能测试 +2026-01-18 16:23:56.508 | INFO | __main__:test_email_performance:398 - 开始测试邮件发送性能... +2026-01-18 16:23:56.510 | ERROR | __main__:test_email_performance:415 - 未配置发件邮箱 +2026-01-18 16:23:56.511 | INFO | __main__:main:530 - +============================================================ +2026-01-18 16:23:56.511 | INFO | __main__:main:531 - 测试总结: +2026-01-18 16:23:56.511 | INFO | __main__:main:532 - 通过测试: 0/5 +2026-01-18 16:23:56.512 | INFO | __main__:main:533 - ============================================================ +2026-01-18 16:23:56.512 | ERROR | __main__:main:556 - 多数测试失败,邮件系统无法正常工作。 +2026-01-18 16:23:56.512 | INFO | __main__:main:557 - +紧急处理: +2026-01-18 16:23:56.512 | INFO | __main__:main:558 - 1. ❌ 检查SMTP服务器配置 +2026-01-18 16:23:56.512 | INFO | __main__:main:559 - 2. ❌ 验证邮箱账号和密码 +2026-01-18 16:23:56.513 | INFO | __main__:main:560 - 3. ❌ 检查网络连接 +2026-01-18 16:23:56.513 | INFO | __main__:main:561 - 4. 参考README中的邮件配置章节 +2026-01-18 16:23:56.513 | INFO | __main__:main:562 - 5. 查看详细错误日志 diff --git a/test_celery_email.py b/test_celery_email.py index 6dacc22..7c60268 100644 --- a/test_celery_email.py +++ b/test_celery_email.py @@ -24,6 +24,7 @@ def test_celery_email_config(): from django.conf import settings from diary_family.celery import app + from core.models import SystemConfig # 检查Celery配置 celery_config = { @@ -45,12 +46,13 @@ def test_celery_email_config(): else: logger.info(f" {key}: {value}") - # 检查邮件配置 + # 从数据库获取邮件配置 + config = SystemConfig.get_config() email_config = { - 'EMAIL_BACKEND': getattr(settings, 'EMAIL_BACKEND', None), - 'EMAIL_HOST': getattr(settings, 'EMAIL_HOST', None), - 'EMAIL_PORT': getattr(settings, 'EMAIL_PORT', None), - 'EMAIL_HOST_USER': getattr(settings, 'EMAIL_HOST_USER', None), + 'smtp_server': config.smtp_server, + 'smtp_port': config.smtp_port, + 'smtp_username': config.smtp_username, + 'recipient_email': config.recipient_email, } logger.info("邮件配置信息:") @@ -58,19 +60,18 @@ def test_celery_email_config(): if value is None: logger.warning(f" {key}: 未配置") else: - if 'password' in key.lower(): - logger.info(f" {key}: ***") - else: - logger.info(f" {key}: {value}") + logger.info(f" {key}: {value}") # 验证必要配置 missing_configs = [] if not getattr(settings, 'CELERY_BROKER_URL', None): missing_configs.append('CELERY_BROKER_URL') - if not getattr(settings, 'EMAIL_HOST', None): - missing_configs.append('EMAIL_HOST') - if not getattr(settings, 'EMAIL_HOST_USER', None): - missing_configs.append('EMAIL_HOST_USER') + if not config.smtp_server: + missing_configs.append('smtp_server') + if not config.smtp_username: + missing_configs.append('smtp_username') + if not config.smtp_password: + missing_configs.append('smtp_password') if missing_configs: logger.error(f"缺少必要的配置: {', '.join(missing_configs)}") @@ -179,16 +180,33 @@ def celery_send_test_email(self, test_mode=True): logger.info(f"[任务 {task_id}] 开始执行异步邮件发送任务") try: - # 获取邮件配置 - from_email = getattr(settings, 'EMAIL_HOST_USER', None) + # 从数据库获取邮件配置 + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend + config = SystemConfig.get_config() + from_email = config.smtp_username if not from_email: - raise ValueError("未配置发件邮箱 (EMAIL_HOST_USER)") + raise ValueError("未配置发件邮箱 (smtp_username)") - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) - if isinstance(to_email, list): - recipient_list = to_email - else: - recipient_list = [to_email] + to_email = config.recipient_email or from_email + recipient_list = [to_email] + + # 获取SMTP配置 + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS + + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) # 创建邮件内容 subject = f"[Celery测试] 异步邮件发送成功 - {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}" @@ -206,8 +224,8 @@ def celery_send_test_email(self, test_mode=True): - 执行重试次数: {self.request.retries} 邮件配置: -- 发件服务器: {getattr(settings, 'EMAIL_HOST', '未知')}:{getattr(settings, 'EMAIL_PORT', '未知')} -- 使用TLS: {getattr(settings, 'EMAIL_USE_TLS', '未知')} +- 发件服务器: {host}:{port} +- 使用TLS: {use_tls} --- 家庭日报系统 @@ -222,7 +240,7 @@ def celery_send_test_email(self, test_mode=True): 任务ID: {task_id} 这是一封测试邮件,用于验证Celery异步邮件发送功能。 - " + "" # 创建邮件 email = EmailMessage( @@ -230,6 +248,7 @@ def celery_send_test_email(self, test_mode=True): body=body, from_email=from_email, to=recipient_list, + connection=backend ) email.content_subtype = 'plain' email.encoding = 'utf-8' @@ -294,17 +313,27 @@ def celery_send_html_report_email(self, include_attachment=False): logger.info(f"[任务 {task_id}] 开始执行HTML报告邮件发送任务") try: - # 获取邮件配置 - from_email = getattr(settings, 'EMAIL_HOST_USER', None) + # 从数据库获取邮件配置 + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend + config = SystemConfig.get_config() + from_email = config.smtp_username if not from_email: raise ValueError("未配置发件邮箱") - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) + to_email = config.recipient_email or from_email if isinstance(to_email, list): recipient_list = to_email else: recipient_list = [to_email] + # 获取SMTP配置 + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS + # 准备报告数据 today = timezone.now().date() yesterday = today - timedelta(days=1) @@ -374,6 +403,16 @@ def celery_send_html_report_email(self, include_attachment=False): """ + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) + # 创建邮件 subject = f"[Celery] 家庭日报 {report_data['today']} - 测试报告" @@ -382,6 +421,7 @@ def celery_send_html_report_email(self, include_attachment=False): body=html_content, from_email=from_email, to=recipient_list, + connection=backend ) email.attach_alternative(html_content, "text/html") email.encoding = 'utf-8' @@ -525,9 +565,34 @@ def main(): from django.conf import settings from django.core.mail import EmailMessage from django.utils import timezone + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend - from_email = getattr(settings, 'EMAIL_HOST_USER', None) - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) + # 从数据库获取邮件配置 + config = SystemConfig.get_config() + from_email = config.smtp_username + if not from_email: + raise ValueError("未配置发件邮箱") + + to_email = config.recipient_email or from_email + recipient_list = [to_email] if isinstance(to_email, str) else to_email + + # 获取SMTP配置 + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS + + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) subject = f"[直接测试] Celery邮件测试 - {timezone.now().strftime('%H:%M:%S')}" body = f""" @@ -547,7 +612,8 @@ def main(): subject=subject, body=body, from_email=from_email, - to=[to_email] if isinstance(to_email, str) else to_email, + to=recipient_list, + connection=backend ) sent = email.send(fail_silently=False) diff --git a/test_email.py b/test_email.py index 584c1f8..4ec094a 100644 --- a/test_email.py +++ b/test_email.py @@ -21,19 +21,19 @@ def test_email_config(): django.setup() from django.conf import settings - from django.core.mail import get_connection - from email.mime.text import MIMEText - from email.mime.multipart import MIMEMultipart + from core.models import SystemConfig + + # 从数据库获取系统配置 + config = SystemConfig.get_config() # 检查邮件配置 email_config = { - 'EMAIL_BACKEND': getattr(settings, 'EMAIL_BACKEND', None), - 'EMAIL_HOST': getattr(settings, 'EMAIL_HOST', None), - 'EMAIL_PORT': getattr(settings, 'EMAIL_PORT', None), - 'EMAIL_USE_TLS': getattr(settings, 'EMAIL_USE_TLS', None), - 'EMAIL_USE_SSL': getattr(settings, 'EMAIL_USE_SSL', None), - 'EMAIL_HOST_USER': getattr(settings, 'EMAIL_HOST_USER', None), - 'EMAIL_HOST_PASSWORD': '***' if getattr(settings, 'EMAIL_HOST_PASSWORD', None) else None, + 'smtp_server': config.smtp_server, + 'smtp_port': config.smtp_port, + 'smtp_username': config.smtp_username, + 'smtp_password': '***' if config.smtp_password else None, + 'recipient_email': config.recipient_email, + 'send_time': config.send_time, } logger.info("邮件配置信息:") @@ -44,16 +44,19 @@ def test_email_config(): logger.info(f" {key}: {value}") # 验证必要配置 - required_configs = ['EMAIL_HOST', 'EMAIL_PORT', 'EMAIL_HOST_USER'] - missing_configs = [cfg for cfg in required_configs if not getattr(settings, cfg, None)] + required_configs = ['smtp_server', 'smtp_port', 'smtp_username', 'smtp_password'] + missing_configs = [] + for cfg in required_configs: + if not getattr(config, cfg, None): + missing_configs.append(cfg) if missing_configs: logger.error(f"缺少必要的邮件配置: {', '.join(missing_configs)}") - logger.info("请在系统配置页面或settings.py中配置以下参数:") - logger.info(" - EMAIL_HOST: SMTP服务器地址") - logger.info(" - EMAIL_PORT: SMTP端口(通常是587或465)") - logger.info(" - EMAIL_HOST_USER: 发件邮箱") - logger.info(" - EMAIL_HOST_PASSWORD: 发件邮箱密码") + logger.info("请在系统配置页面配置以下参数:") + logger.info(" - SMTP服务器: SMTP服务器地址") + logger.info(" - SMTP端口: SMTP端口(通常是587或465)") + logger.info(" - SMTP用户名: 发件邮箱") + logger.info(" - SMTP密码: 发件邮箱密码") return False logger.success("邮件配置测试通过!") @@ -73,17 +76,17 @@ def test_smtp_connection(): import django django.setup() - from django.conf import settings - from django.core.mail import get_connection from django.core.mail.backends.smtp import EmailBackend + from core.models import SystemConfig - # 获取SMTP配置 - host = getattr(settings, 'EMAIL_HOST', 'localhost') - port = getattr(settings, 'EMAIL_PORT', 587) - username = getattr(settings, 'EMAIL_HOST_USER', '') - password = getattr(settings, 'EMAIL_HOST_PASSWORD', '') - use_tls = getattr(settings, 'EMAIL_USE_TLS', True) - use_ssl = getattr(settings, 'EMAIL_USE_SSL', False) + # 从数据库获取SMTP配置 + config = SystemConfig.get_config() + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS + use_ssl = False # 默认不使用SSL timeout = 10 # 连接超时时间 logger.info(f"连接SMTP服务器: {host}:{port}") @@ -183,29 +186,28 @@ def test_send_simple_email(): import django django.setup() - from django.conf import settings from django.core.mail import EmailMessage from django.utils import timezone + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend - # 获取配置 - from_email = getattr(settings, 'EMAIL_HOST_USER', None) + # 从数据库获取配置 + config = SystemConfig.get_config() + from_email = config.smtp_username or None if not from_email: - logger.error("未配置发件邮箱 (EMAIL_HOST_USER)") + logger.error("未配置发件邮箱 (smtp_username)") return False # 获取收件人(如果没有配置,使用发件人自己) - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) - if isinstance(to_email, list): - recipient_list = to_email - else: - recipient_list = [to_email] + to_email = config.recipient_email or from_email + recipient_list = [to_email] # 获取SMTP配置 - host = getattr(settings, 'EMAIL_HOST', 'localhost') - port = getattr(settings, 'EMAIL_PORT', 587) - username = getattr(settings, 'EMAIL_HOST_USER', '') - password = getattr(settings, 'EMAIL_HOST_PASSWORD', '') - use_tls = getattr(settings, 'EMAIL_USE_TLS', True) + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS # 创建测试邮件 subject = f"家庭日报系统测试邮件 - {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}" @@ -228,12 +230,23 @@ def test_send_simple_email(): logger.info(f" 收件人: {recipient_list}") logger.info(f" 主题: {subject}") + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) + # 创建邮件 email = EmailMessage( subject=subject, body=body, from_email=from_email, to=recipient_list, + connection=backend ) email.content_subtype = 'plain' email.encoding = 'utf-8' @@ -279,18 +292,27 @@ def test_send_html_email_with_attachment(): import django django.setup() - from django.conf import settings from django.core.mail import EmailMessage - from django.template.loader import render_to_string from django.utils import timezone + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend - # 获取配置 - from_email = getattr(settings, 'EMAIL_HOST_USER', None) - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) - if isinstance(to_email, list): - recipient_list = to_email - else: - recipient_list = [to_email] + # 从数据库获取配置 + config = SystemConfig.get_config() + from_email = config.smtp_username or None + if not from_email: + logger.error("未配置发件邮箱") + return False + + to_email = config.recipient_email or from_email + recipient_list = [to_email] + + # 获取SMTP配置 + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS # 创建HTML内容 html_content = f""" @@ -328,12 +350,23 @@ def test_send_html_email_with_attachment(): subject = f"家庭日报系统 HTML测试邮件 - {timezone.now().strftime('%Y-%m-%d')}" + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) + # 创建邮件 email = EmailMessage( subject=subject, body=html_content, from_email=from_email, to=recipient_list, + connection=backend ) email.content_subtype = 'html' email.encoding = 'utf-8' @@ -369,18 +402,38 @@ def test_email_performance(): import django django.setup() - from django.conf import settings from django.core.mail import EmailMessage from django.utils import timezone + from core.models import SystemConfig + from django.core.mail.backends.smtp import EmailBackend import time - # 获取配置 - from_email = getattr(settings, 'EMAIL_HOST_USER', None) - to_email = getattr(settings, 'EMAIL_HOST_USER', from_email) - if isinstance(to_email, list): - recipient_list = to_email - else: - recipient_list = [to_email] + # 从数据库获取配置 + config = SystemConfig.get_config() + from_email = config.smtp_username or None + if not from_email: + logger.error("未配置发件邮箱") + return False + + to_email = config.recipient_email or from_email + recipient_list = [to_email] + + # 获取SMTP配置 + host = config.smtp_server or 'localhost' + port = config.smtp_port or 587 + username = config.smtp_username or '' + password = config.smtp_password or '' + use_tls = True # 默认使用TLS + + # 创建邮件后端 + backend = EmailBackend( + host=host, + port=port, + username=username, + password=password, + use_tls=use_tls, + fail_silently=False + ) # 性能测试 test_count = 3 @@ -395,6 +448,7 @@ def test_email_performance(): body=body, from_email=from_email, to=recipient_list, + connection=backend ) start_time = time.time()