From 264fc9e3f386cafa446edbf4aa9832637e440296 Mon Sep 17 00:00:00 2001 From: yuyx <237899745@qq.com> Date: Thu, 11 Dec 2025 23:27:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=B9=E6=AC=A1?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E5=9C=A8=E6=88=AA=E5=9B=BE=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=90=8E=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前邮件在run_task线程结束时发送,但截图是异步的,导致截图还没完成就发送了。 现在改为在截图回调中检测,当所有截图完成时才发送打包邮件。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app.py | 59 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/app.py b/app.py index a503cb6..727d77b 100755 --- a/app.py +++ b/app.py @@ -2564,7 +2564,9 @@ def take_screenshot_for_account(user_id, account_id, browse_type="应读", sourc account_name = account.remark if account.remark else account.username if batch_id: - # 批次任务:收集截图信息,等待统一发送 + # 批次任务:收集截图信息,当所有截图完成时发送打包邮件 + should_send_email = False + batch_info = None with batch_task_lock: if batch_id in batch_task_screenshots: batch_task_screenshots[batch_id]['screenshots'].append({ @@ -2574,6 +2576,29 @@ def take_screenshot_for_account(user_id, account_id, browse_type="应读", sourc 'attachments': browse_result.get('total_attachments', 0) }) batch_task_screenshots[batch_id]['completed'] += 1 + # 检查是否所有截图都完成了 + if batch_task_screenshots[batch_id]['completed'] >= batch_task_screenshots[batch_id]['total_accounts']: + should_send_email = True + batch_info = batch_task_screenshots.pop(batch_id) + print(f"[批次邮件] 批次 {batch_id} 所有 {batch_info['total_accounts']} 个截图已完成,准备发送邮件") + + # 在锁外发送邮件 + if should_send_email and batch_info and batch_info['screenshots']: + try: + batch_user_id = batch_info['user_id'] + user_info = database.get_user_by_id(batch_user_id) + if user_info and user_info.get('email') and database.get_user_email_notify(batch_user_id): + email_service.send_batch_task_complete_email_async( + user_id=batch_user_id, + email=user_info['email'], + username=user_info['username'], + schedule_name=batch_info['schedule_name'], + browse_type=batch_info['browse_type'], + screenshots=batch_info['screenshots'] + ) + print(f"[批次邮件] 已发送打包邮件,包含 {len(batch_info['screenshots'])} 个截图") + except Exception as batch_email_err: + print(f"[批次邮件] 发送失败: {batch_email_err}") else: # 非批次任务:直接发送邮件(保持原有逻辑) user_info = database.get_user_by_id(user_id) @@ -3769,10 +3794,11 @@ def scheduled_task_worker(): print(f"[用户定时任务] 已启动 {started_count} 个账号,跳过 {skipped_count} 个账号,批次ID: {batch_id}") - # 启动监控线程,等待所有任务完成后更新日志并发送打包邮件 - def wait_and_update_log(threads, start_time, lid, total, success, sid, bid): + # 启动监控线程,等待所有任务完成后更新日志 + # 注意:邮件发送已移至截图回调中,当所有截图完成时自动发送 + def wait_and_update_log(threads, start_time, lid, total, success, sid): for t in threads: - t.join() # 等待每个任务完成 + t.join() # 等待每个任务完成(注意:这只是run_task线程,截图是异步的) execution_duration = int(time_mod.time() - start_time) database.update_schedule_execution_log( lid, @@ -3782,33 +3808,12 @@ def scheduled_task_worker(): duration_seconds=execution_duration, status='completed' ) - print(f"[用户定时任务] 任务#{sid}执行完成,耗时{execution_duration}秒") - - # 发送打包邮件 - try: - with batch_task_lock: - batch_info = batch_task_screenshots.pop(bid, None) - - if batch_info and batch_info['screenshots']: - batch_user_id = batch_info['user_id'] - user_info = database.get_user_by_id(batch_user_id) - if user_info and user_info.get('email') and database.get_user_email_notify(batch_user_id): - email_service.send_batch_task_complete_email_async( - user_id=batch_user_id, - email=user_info['email'], - username=user_info['username'], - schedule_name=batch_info['schedule_name'], - browse_type=batch_info['browse_type'], - screenshots=batch_info['screenshots'] - ) - print(f"[用户定时任务] 批次邮件已发送,包含 {len(batch_info['screenshots'])} 个账号截图") - except Exception as email_err: - print(f"[用户定时任务] 发送批次邮件失败: {email_err}") + print(f"[用户定时任务] 任务#{sid}浏览阶段完成,耗时{execution_duration}秒,等待截图完成后发送邮件") if task_threads: monitor_thread = threading.Thread( target=wait_and_update_log, - args=(task_threads, execution_start_time, log_id, len(account_ids), started_count, schedule_id, batch_id), + args=(task_threads, execution_start_time, log_id, len(account_ids), started_count, schedule_id), daemon=True ) monitor_thread.start()