feat: 添加邮件功能第四阶段 - 任务完成通知

1. 添加任务完成邮件模板 (templates/email/task_complete.html)
2. 在email_service.py中添加:
   - task_notify_enabled 字段支持
   - send_task_complete_email() 函数,支持附件大小限制和分批发送
   - send_task_complete_email_async() 异步发送函数
   - MAX_ATTACHMENT_SIZE 常量 (10MB)
3. 更新app.py:
   - 邮件设置API支持task_notify_enabled字段
   - 截图回调中集成任务完成邮件发送
4. 更新admin.html:
   - 添加"启用任务完成通知"开关
   - 更新loadEmailSettings/updateEmailSettings函数

附件超过10MB时会自动分两封邮件发送(通知+截图),作为容错机制

🤖 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 22:09:59 +08:00
parent 0c0a5a7770
commit f020a9c6d9
4 changed files with 373 additions and 6 deletions

View File

@@ -1233,6 +1233,15 @@
开启后,新用户注册需通过邮箱验证才能激活账号(优先级高于自动审核)
</div>
</div>
<div class="form-group" style="margin-bottom: 10px;">
<label style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="taskNotifyEnabled" onchange="updateEmailSettings()" style="width: auto; max-width: none;">
启用任务完成通知
</label>
<div style="font-size: 12px; color: #666; margin-top: 5px;">
开启后,定时任务完成时将发送邮件通知给用户(用户需已设置邮箱)
</div>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label style="display: block; margin-bottom: 5px;">网站基础URL</label>
<input type="text" id="baseUrl" placeholder="例如: https://example.com" style="width: 100%;" onblur="updateEmailSettings()">
@@ -2797,6 +2806,7 @@
document.getElementById('emailEnabled').checked = data.enabled;
document.getElementById('failoverEnabled').checked = data.failover_enabled;
document.getElementById('registerVerifyEnabled').checked = data.register_verify_enabled || false;
document.getElementById('taskNotifyEnabled').checked = data.task_notify_enabled || false;
document.getElementById('baseUrl').value = data.base_url || '';
}
} catch (error) {
@@ -2814,6 +2824,7 @@
enabled: document.getElementById('emailEnabled').checked,
failover_enabled: document.getElementById('failoverEnabled').checked,
register_verify_enabled: document.getElementById('registerVerifyEnabled').checked,
task_notify_enabled: document.getElementById('taskNotifyEnabled').checked,
base_url: document.getElementById('baseUrl').value.trim()
})
});

View File

@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 0; font-family: 'Microsoft YaHei', Arial, sans-serif; background-color: #f5f5f5;">
<table width="100%" cellpadding="0" cellspacing="0" style="background-color: #f5f5f5; padding: 30px 0;">
<tr>
<td align="center">
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
<!-- 头部 -->
<tr>
<td style="background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%); padding: 30px; border-radius: 10px 10px 0 0; text-align: center;">
<h1 style="color: #ffffff; margin: 0; font-size: 24px;">知识管理平台</h1>
<p style="color: rgba(255,255,255,0.9); margin: 10px 0 0 0; font-size: 14px;">任务完成通知</p>
</td>
</tr>
<!-- 内容 -->
<tr>
<td style="padding: 40px 30px;">
<p style="color: #333; font-size: 16px; margin: 0 0 20px 0;">
您好,<strong>{{ username }}</strong>
</p>
<p style="color: #666; font-size: 14px; line-height: 1.8; margin: 0 0 25px 0;">
您的浏览任务已完成,以下是任务详情:
</p>
<!-- 任务详情 -->
<table width="100%" cellpadding="0" cellspacing="0" style="background: #f8f9fa; border-radius: 8px; margin-bottom: 25px;">
<tr>
<td style="padding: 20px;">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td style="padding: 8px 0; color: #666; font-size: 14px;">账号:</td>
<td style="padding: 8px 0; color: #333; font-size: 14px; font-weight: bold;">{{ account_name }}</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #666; font-size: 14px;">浏览类型:</td>
<td style="padding: 8px 0; color: #333; font-size: 14px;">{{ browse_type }}</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #666; font-size: 14px;">浏览条目:</td>
<td style="padding: 8px 0; color: #27ae60; font-size: 14px; font-weight: bold;">{{ total_items }} 条</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #666; font-size: 14px;">附件数量:</td>
<td style="padding: 8px 0; color: #333; font-size: 14px;">{{ total_attachments }} 个</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #666; font-size: 14px;">完成时间:</td>
<td style="padding: 8px 0; color: #333; font-size: 14px;">{{ complete_time }}</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- 截图信息 -->
<div style="background: #e8f5e9; border-left: 4px solid #27ae60; padding: 15px; margin: 25px 0; border-radius: 0 5px 5px 0;">
<p style="color: #2e7d32; font-size: 13px; margin: 0;">
<strong>截图已附在邮件中</strong>{{ batch_info }}
</p>
</div>
<p style="color: #999; font-size: 13px; margin: 20px 0 0 0;">
如有任何问题,请登录平台查看详情。
</p>
</td>
</tr>
<!-- 底部 -->
<tr>
<td style="background: #f8f9fa; padding: 20px 30px; border-radius: 0 0 10px 10px; text-align: center;">
<p style="color: #999; font-size: 12px; margin: 0;">
此邮件由系统自动发送,请勿直接回复。
</p>
<p style="color: #ccc; font-size: 11px; margin: 10px 0 0 0;">
&copy; 知识管理平台
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>