feat: Implement result deduplication by email and enhance summary reporting to detail only failed accounts.

This commit is contained in:
2026-01-18 06:59:35 +08:00
parent 49cb2430c8
commit 95fa705768
3 changed files with 135 additions and 15 deletions

View File

@@ -5,6 +5,7 @@ import asyncio
import sys
from concurrent.futures import ThreadPoolExecutor
from functools import wraps
from pathlib import Path
from typing import Optional
from telegram import Update, Bot, BotCommand
@@ -22,6 +23,8 @@ from config import (
TEAMS,
AUTH_PROVIDER,
TEAM_JSON_FILE,
TEAM_TRACKER_FILE,
CSV_FILE,
TELEGRAM_CHECK_INTERVAL,
TELEGRAM_LOW_STOCK_THRESHOLD,
CONFIG_FILE,
@@ -114,6 +117,7 @@ class ProvisionerBot:
("include_owners", self.cmd_include_owners),
("reload", self.cmd_reload),
("s2a_config", self.cmd_s2a_config),
("clean", self.cmd_clean),
]
for cmd, handler in handlers:
self.app.add_handler(CommandHandler(cmd, handler))
@@ -219,6 +223,7 @@ class ProvisionerBot:
/fingerprint - 开启/关闭随机指纹
/include_owners - 开启/关闭 Owner 入库
/reload - 重载配置文件 (无需重启)
/clean - 清理 team.json 和 tracker 数据
<b>📊 S2A 专属:</b>
/dashboard - 查看 S2A 仪表盘
@@ -555,6 +560,113 @@ class ProvisionerBot:
except Exception as e:
await update.message.reply_text(f"❌ 重载配置失败: {e}")
@admin_only
async def cmd_clean(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""清理 team.json 和 team_tracker.json 数据"""
# 检查是否有任务正在运行
if self.current_task and not self.current_task.done():
await update.message.reply_text(
f"⚠️ 有任务正在运行: {self.current_team}\n"
"请等待任务完成或使用 /stop 停止后再清理"
)
return
# 解析参数
args = [a.lower() for a in context.args] if context.args else []
include_csv = "all" in args
confirmed = "confirm" in args
# 需要确认参数
if not confirmed:
# 统计当前数据
team_count = len(TEAMS)
tracker = load_team_tracker()
tracker_accounts = sum(len(accs) for accs in tracker.get("teams", {}).values())
# 统计 CSV 行数
csv_count = 0
csv_path = Path(CSV_FILE)
if csv_path.exists():
try:
with open(csv_path, "r", encoding="utf-8") as f:
csv_count = max(0, sum(1 for _ in f) - 1) # 减去表头
except:
pass
msg = (
f"<b>⚠️ 确认清理数据?</b>\n\n"
f"将清空以下文件:\n"
f"• team.json ({team_count} 个 Team)\n"
f"• team_tracker.json ({tracker_accounts} 个账号记录)\n"
)
if include_csv:
msg += f"• accounts.csv ({csv_count} 条记录)\n"
msg += (
f"\n<b>此操作不可恢复!</b>\n\n"
f"确认清理请发送:\n"
f"<code>/clean confirm</code>\n\n"
f"如需同时清理 CSV:\n"
f"<code>/clean all confirm</code>"
)
await update.message.reply_text(msg, parse_mode="HTML")
return
# 执行清理
cleaned = []
errors = []
# 清理 team.json
try:
if TEAM_JSON_FILE.exists():
with open(TEAM_JSON_FILE, "w", encoding="utf-8") as f:
f.write("[]")
cleaned.append("team.json")
except Exception as e:
errors.append(f"team.json: {e}")
# 清理 team_tracker.json
try:
tracker_file = Path(TEAM_TRACKER_FILE)
if tracker_file.exists():
with open(tracker_file, "w", encoding="utf-8") as f:
f.write('{"teams": {}}')
cleaned.append("team_tracker.json")
except Exception as e:
errors.append(f"team_tracker.json: {e}")
# 清理 accounts.csv (可选)
if include_csv:
try:
csv_path = Path(CSV_FILE)
if csv_path.exists():
with open(csv_path, "w", encoding="utf-8") as f:
f.write("email,password,team,status,crs_id,timestamp\n")
cleaned.append("accounts.csv")
except Exception as e:
errors.append(f"accounts.csv: {e}")
# 重载配置以清空内存中的 TEAMS
reload_config()
# 返回结果
if errors:
await update.message.reply_text(
f"<b>⚠️ 部分清理失败</b>\n\n"
f"已清理: {', '.join(cleaned) or ''}\n"
f"失败: {'; '.join(errors)}",
parse_mode="HTML"
)
else:
await update.message.reply_text(
f"<b>✅ 清理完成</b>\n\n"
f"已清空: {', '.join(cleaned)}\n\n"
f"现在可以导入新的 team.json 了",
parse_mode="HTML"
)
@admin_only
async def cmd_s2a_config(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""配置 S2A 服务参数"""