Files
live-hub-py/web/backend/routers/cookies.py
T
yml2213andClaude Fable 5 72bcd1274c 优化登录任务界面 + 修复时间显示 + 增加删除功能
- 筛选栏改为单行横排,概览精简为一行文字
- 任务列表全宽展示,日志移到底部可折叠
- 页面使用百分比布局,一屏展示无外层滚动
- 登录任务增加单条删除和批量删除功能
- 后端: datetime.utcnow 替换为 datetime.now(timezone.utc)
- 后端: schemas 序列化统一输出带时区 ISO 格式
- 前端: 新增 utils/time.ts 统一时间格式化工具
- 前端: CookiePage/LoginTasksPage 时间列使用 formatTime()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-22 17:56:48 +08:00

108 lines
3.4 KiB
Python

"""Cookie 管理路由"""
from datetime import timezone
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
import io
import csv
from ..database import get_db
from ..models import User, LoginTask, Account
from ..deps import get_current_user, require_permission
from ..permissions import has_permission
def _fmt_dt(dt) -> str | None:
"""将 datetime 格式化为带时区的 ISO 字符串。"""
if dt is None:
return None
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return dt.isoformat()
router = APIRouter(prefix="/api/cookies", tags=["Cookie管理"])
@router.get("")
def list_cookies(
db: Session = Depends(get_db),
current: User = Depends(get_current_user),
):
"""查看登录成功的 Cookie 列表。"""
query = db.query(LoginTask).filter(LoginTask.status == "success")
# 客服只能看自己账号的
if not has_permission(current.role, "login:view_all"):
query = query.join(Account, LoginTask.account_id == Account.id).filter(
Account.assigned_to == current.id
)
tasks = query.order_by(LoginTask.finished_at.desc()).all()
result = []
for t in tasks:
acc = db.query(Account).filter(Account.id == t.account_id).first()
item = {
"id": t.id,
"batch_id": t.batch_id,
"account_id": t.account_id,
"account_username": acc.username if acc else "",
"assigned_to": acc.assigned_to,
"assigned_username": acc.assigned_user.username if acc and acc.assigned_user else None,
"created_at": _fmt_dt(t.finished_at),
}
# 只有有 cookie:view 权限才返回 cookie 内容
if has_permission(current.role, "cookie:view"):
cookie = t.cookie or ""
item["cookie"] = cookie
item["cookie_preview"] = cookie[:50] + "..." if len(cookie) > 50 else cookie
else:
item["cookie"] = ""
item["cookie_preview"] = "***"
result.append(item)
return result
@router.get("/export")
def export_cookies(
db: Session = Depends(get_db),
current: User = Depends(require_permission("cookie:export")),
):
"""导出 Cookie 为 CSV。"""
tasks = db.query(LoginTask).filter(
LoginTask.status == "success"
).order_by(LoginTask.finished_at.desc()).all()
output = io.StringIO()
writer = csv.writer(output)
writer.writerow(["账号", "Cookie", "时间"])
for t in tasks:
acc = db.query(Account).filter(Account.id == t.account_id).first()
username = acc.username if acc else ""
writer.writerow([username, t.cookie or "", _fmt_dt(t.finished_at) or ""])
output.seek(0)
return StreamingResponse(
iter([output.getvalue()]),
media_type="text/csv",
headers={"Content-Disposition": "attachment; filename=cookies.csv"},
)
@router.delete("/{task_id}")
def delete_cookie(
task_id: int,
db: Session = Depends(get_db),
current: User = Depends(require_permission("cookie:export")),
):
"""删除一条 Cookie 记录。"""
task = db.query(LoginTask).filter(LoginTask.id == task_id).first()
if not task:
raise HTTPException(status_code=404, detail="记录不存在")
task.cookie = ""
task.status = "failed"
task.message = "Cookie已清除"
db.commit()
return {"message": "已删除", "success": True}