feat(cookies): Cookie 失效后可账号重新登录替换, 并修复 Cookie 列空白过多

This commit is contained in:
yml2213
2026-08-08 01:39:02 +08:00
parent 64b017fd6a
commit 39ea0d2184
5 changed files with 269 additions and 60 deletions
+68 -3
View File
@@ -1,5 +1,6 @@
"""Cookie 管理路由"""
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime, timezone
import requests
@@ -10,10 +11,12 @@ from sqlalchemy.orm import Session, defer, joinedload
import io
import csv
from ..database import get_db
from ..models import User, LoginTask, Account
from ..database import get_db, SessionLocal
from ..models import User, LoginTask, Account, ProxyConfig as ProxyConfigModel
from ..deps import get_current_user, require_permission
from ..permissions import user_has_permission
from ..permissions import user_has_permission, get_user_permissions
from ..schemas import CookieReloginRequest
from ..services.login_service import LoginBatchRunner
def _fmt_dt(dt) -> str | None:
@@ -327,6 +330,68 @@ def check_cookies(
return {"results": results, "success": True}
@router.post("/relogin")
def relogin_cookies(
req: CookieReloginRequest,
db: Session = Depends(get_db),
current: User = Depends(require_permission("login:batch")),
):
"""重新登录失效的 Cookie:用账号信息重新登录,成功后替换旧 Cookie。
复用原 LoginTask 记录,行不消失;重新登录失败保留旧 Cookie 并记录原因。
"""
if not req.ids:
raise HTTPException(status_code=400, detail="请选择要重新登录的 Cookie")
tasks = _visible_cookie_tasks_query(db, current).filter(LoginTask.id.in_(req.ids)).all()
if not tasks:
raise HTTPException(status_code=404, detail="记录不存在")
# 过滤缺少登录凭据的账号(密码/邮箱),避免启动后全部失败
task_ids: list[int] = []
skipped: list[str] = []
accounts_map = {t.account_id: t for t in tasks}
for acc_id, task in accounts_map.items():
acc = db.query(Account).filter(Account.id == acc_id).first()
if not acc:
continue
if not acc.password or not acc.email:
skipped.append(task.id)
continue
task_ids.append(task.id)
if not task_ids:
raise HTTPException(
status_code=400,
detail="所选 Cookie 对应账号缺少密码或邮箱信息,无法重新登录,请先在账号管理中补充",
)
proxy = db.query(ProxyConfigModel).first()
thread_db = SessionLocal()
runner = LoginBatchRunner(
db=thread_db,
account_ids=[],
created_by=current.id,
creator_permissions=get_user_permissions(current),
proxy_config=proxy,
log_queue=None,
loop=None,
concurrency=3,
mode="relogin",
relogin_task_ids=task_ids,
)
batch_id = runner.batch_id
thread = threading.Thread(target=runner.run, daemon=True)
thread.start()
return {
"batch_id": batch_id,
"count": len(task_ids),
"skipped": len(skipped),
"success": True,
}
@router.get("/{task_id}")
def get_cookie(
task_id: int,