fix: 修复批次邮件在截图完成后发送

之前邮件在run_task线程结束时发送,但截图是异步的,导致截图还没完成就发送了。
现在改为在截图回调中检测,当所有截图完成时才发送打包邮件。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-11 23:27:56 +08:00
parent d6fa5b91ea
commit 264fc9e3f3

59
app.py
View File

@@ -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 account_name = account.remark if account.remark else account.username
if batch_id: if batch_id:
# 批次任务:收集截图信息,等待统一发送 # 批次任务:收集截图信息,当所有截图完成时发送打包邮件
should_send_email = False
batch_info = None
with batch_task_lock: with batch_task_lock:
if batch_id in batch_task_screenshots: if batch_id in batch_task_screenshots:
batch_task_screenshots[batch_id]['screenshots'].append({ 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) 'attachments': browse_result.get('total_attachments', 0)
}) })
batch_task_screenshots[batch_id]['completed'] += 1 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: else:
# 非批次任务:直接发送邮件(保持原有逻辑) # 非批次任务:直接发送邮件(保持原有逻辑)
user_info = database.get_user_by_id(user_id) 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}") 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: for t in threads:
t.join() # 等待每个任务完成 t.join() # 等待每个任务完成注意这只是run_task线程截图是异步的
execution_duration = int(time_mod.time() - start_time) execution_duration = int(time_mod.time() - start_time)
database.update_schedule_execution_log( database.update_schedule_execution_log(
lid, lid,
@@ -3782,33 +3808,12 @@ def scheduled_task_worker():
duration_seconds=execution_duration, duration_seconds=execution_duration,
status='completed' status='completed'
) )
print(f"[用户定时任务] 任务#{sid}执行完成,耗时{execution_duration}") 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}")
if task_threads: if task_threads:
monitor_thread = threading.Thread( monitor_thread = threading.Thread(
target=wait_and_update_log, 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 daemon=True
) )
monitor_thread.start() monitor_thread.start()