From d8745774587f00cb26cdcdc5bbcc023ff8824e24 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Tue, 14 Apr 2026 17:27:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=82=AE=E4=BB=B6=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=20v1.9.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 289 bytes xian_favor/__pycache__/api.cpython-310.pyc | Bin 0 -> 70447 bytes xian_favor/__pycache__/cli.cpython-310.pyc | Bin 0 -> 10807 bytes xian_favor/__pycache__/config.cpython-310.pyc | Bin 0 -> 748 bytes xian_favor/__pycache__/db.cpython-310.pyc | Bin 0 -> 14731 bytes xian_favor/api.py | 22 +++++++++++ xian_favor/db.py | 37 ++++++++++++++++++ 8 files changed, 63 insertions(+) create mode 100644 xian_favor/__pycache__/__init__.cpython-310.pyc create mode 100644 xian_favor/__pycache__/api.cpython-310.pyc create mode 100644 xian_favor/__pycache__/cli.cpython-310.pyc create mode 100644 xian_favor/__pycache__/config.cpython-310.pyc create mode 100644 xian_favor/__pycache__/db.cpython-310.pyc diff --git a/README.md b/README.md index b10a37b..18c2c4a 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,10 @@ xian-favor/ ## 版本历史 +- v1.9.2 (2026-04-14): 邮件发送历史记录 + - 详情页面显示邮件发送记录(发送邮箱、时间) + - 支持多次发送,显示多条记录 + - 发送成功/失败状态标记 - v1.9.0 (2026-04-14): 发送邮件功能 + 邮箱管理 - 每个收藏卡片添加"发送邮件"按钮 - 选择已有邮箱或输入新邮箱发送 diff --git a/xian_favor/__pycache__/__init__.cpython-310.pyc b/xian_favor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ac628cf2c96f4dc4573a4fbb6a8926814516d13 GIT binary patch literal 289 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 WUKd^zzCFA++!|iazYtD>zWP64N!FwQ literal 0 HcmV?d00001 diff --git a/xian_favor/__pycache__/config.cpython-310.pyc b/xian_favor/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e0c59049bb06020a9e71aba587acd34dfa4e473 GIT binary patch literal 748 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 literal 0 HcmV?d00001 diff --git a/xian_favor/api.py b/xian_favor/api.py index f4e7266..d839b60 100644 --- a/xian_favor/api.py +++ b/xian_favor/api.py @@ -65,6 +65,9 @@ def get_item(item_id): item = db.get_item(item_id) if not item: return jsonify({'success': False, 'error': '条目不存在'}), 404 + # 获取邮件发送历史 + email_logs = db.get_email_logs(item_id) + item['email_logs'] = email_logs return jsonify({'success': True, 'data': item}) @@ -403,9 +406,14 @@ def send_email(): server.sendmail(smtp_user, email_addr, msg.as_string()) server.quit() + # 记录发送日志 + db.log_email_send(item_id, email_addr, success=True) + return jsonify({'success': True, 'message': f'已发送到 {email_addr}'}) except Exception as e: + # 记录失败日志 + db.log_email_send(item_id, email_addr, success=False) return jsonify({'success': False, 'error': f'发送失败: {str(e)}'}), 500 @@ -1143,6 +1151,20 @@ async function showDetail(id) { html += `

创建时间: ${formatDate(item.created_at)}
更新时间: ${formatDate(item.updated_at)}
`; + // 邮件发送历史 + if (item.email_logs && item.email_logs.length > 0) { + html += `
📧 邮件发送记录:
`; + html += `
`; + item.email_logs.forEach(log => { + const statusIcon = log.success ? '✅' : '❌'; + html += `
+ ${statusIcon} 发送到: ${log.email} + ${formatDate(log.sent_at)} +
`; + }); + html += `
`; + } + document.getElementById('detailContent').innerHTML = html; new bootstrap.Modal(document.getElementById('detailModal')).show(); diff --git a/xian_favor/db.py b/xian_favor/db.py index b66f95f..4a32d9f 100644 --- a/xian_favor/db.py +++ b/xian_favor/db.py @@ -90,6 +90,18 @@ class Database: ) """) + # 邮件发送记录表 + cursor.execute(""" + CREATE TABLE IF NOT EXISTS email_logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + item_id INTEGER NOT NULL, + email TEXT NOT NULL, + sent_at TEXT NOT NULL, + success INTEGER DEFAULT 1, + FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE + ) + """) + # 创建索引 cursor.execute("CREATE INDEX IF NOT EXISTS idx_items_type ON items(type)") cursor.execute("CREATE INDEX IF NOT EXISTS idx_items_status ON items(status)") @@ -371,6 +383,31 @@ class Database: conn.commit() return cursor.rowcount > 0 + # ============ 邮件日志 操作 ============ + + def log_email_send(self, item_id: int, email: str, success: bool = True) -> int: + """记录邮件发送""" + now = datetime.now().isoformat() + with self.get_conn() as conn: + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO email_logs (item_id, email, sent_at, success) + VALUES (?, ?, ?, ?) + """, (item_id, email, now, 1 if success else 0)) + conn.commit() + return cursor.lastrowid + + def get_email_logs(self, item_id: int) -> List[Dict[str, Any]]: + """获取收藏的邮件发送记录""" + with self.get_conn() as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM email_logs + WHERE item_id = ? + ORDER BY sent_at DESC + """, (item_id,)) + return [dict(row) for row in cursor.fetchall()] + def stats(self) -> Dict[str, Any]: """获取统计信息""" self._ensure_init()