diff --git a/api.py b/api.py index 1281cc3..95fb433 100644 --- a/api.py +++ b/api.py @@ -1,9 +1,9 @@ -from fastapi import FastAPI, HTTPException, status, UploadFile +from fastapi import FastAPI, HTTPException, status, UploadFile, Request from pydantic import BaseModel -from typing import Optional +from typing import Optional, List from sqlalchemy import select, func, delete, desc from pathlib import Path -from database import get_session, AccountModel, init_db +from database import get_session, AccountModel, AccountUsageRecordModel, init_db from fastapi.middleware.cors import CORSMiddleware from datetime import datetime import uvicorn @@ -1103,7 +1103,7 @@ async def import_accounts(file: UploadFile): # 添加"使用Token"功能 @app.post("/account/use-token/{id}", tags=["Accounts"]) -async def use_account_token(id: int): +async def use_account_token(id: int, request: Request): """使用指定账号的Token更新Cursor认证""" try: async with get_session() as session: @@ -1130,6 +1130,25 @@ async def use_account_token(id: int): resetter = CursorShadowPatcher() patch_success = resetter.reset_machine_ids() + + # 记录使用记录 + if success: + # 获取请求客户端IP + client_ip = request.client.host + # 获取用户代理 + user_agent = request.headers.get("User-Agent", "") + + # 创建使用记录 + usage_record = AccountUsageRecordModel( + id=int(time.time() * 1000), # 使用毫秒级时间戳作为ID + account_id=id, + email=account.email, + ip=client_ip, + user_agent=user_agent, + created_at=datetime.now().isoformat() + ) + session.add(usage_record) + await session.commit() if success and patch_success: return { @@ -1149,6 +1168,52 @@ async def use_account_token(id: int): error(traceback.format_exc()) return {"success": False, "message": f"使用Token失败: {str(e)}"} +# 添加获取账号使用记录接口 +@app.get("/account/{id}/usage-records", tags=["Accounts"]) +async def get_account_usage_records(id: int): + """获取指定账号的使用记录""" + try: + async with get_session() as session: + # 通过ID查询账号 + result = await session.execute( + select(AccountModel).where(AccountModel.id == id) + ) + account = result.scalar_one_or_none() + + if not account: + return {"success": False, "message": f"ID为 {id} 的账号不存在"} + + # 查询使用记录 + result = await session.execute( + select(AccountUsageRecordModel) + .where(AccountUsageRecordModel.account_id == id) + .order_by(desc(AccountUsageRecordModel.created_at)) + ) + + records = result.scalars().all() + + # 转换记录为字典列表 + records_list = [] + for record in records: + records_list.append({ + "id": record.id, + "account_id": record.account_id, + "email": record.email, + "ip": record.ip, + "user_agent": record.user_agent, + "created_at": record.created_at + }) + + return { + "success": True, + "records": records_list + } + + except Exception as e: + error(f"获取账号使用记录失败: {str(e)}") + error(traceback.format_exc()) + return {"success": False, "message": f"获取账号使用记录失败: {str(e)}"} + # 添加"重置设备id"功能 @app.get("/reset-machine", tags=["System"]) async def reset_machine(): diff --git a/database.py b/database.py index a0603f8..8a441e6 100644 --- a/database.py +++ b/database.py @@ -1,6 +1,6 @@ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.orm import DeclarativeBase -from sqlalchemy import Column, String, Text, text, BigInteger +from sqlalchemy import Column, String, Text, text, BigInteger, ForeignKey from contextlib import asynccontextmanager from logger import info, error from config import DATABASE_URL @@ -24,6 +24,17 @@ class AccountModel(Base): id = Column(BigInteger, nullable=False, index=True) # 添加毫秒时间戳列并创建索引 +# 账号使用记录模型 +class AccountUsageRecordModel(Base): + __tablename__ = "account_usage_records" + id = Column(BigInteger, primary_key=True, autoincrement=True) + account_id = Column(BigInteger, nullable=False, index=True) # 账号ID + email = Column(String, nullable=False, index=True) # 账号邮箱 + ip = Column(String, nullable=True) # 使用者IP + user_agent = Column(Text, nullable=True) # 使用者UA + created_at = Column(Text, nullable=False) # 创建时间 + + def create_engine(): """创建数据库引擎""" # 直接使用配置文件中的数据库URL diff --git a/index.html b/index.html index b0def13..8d37bd9 100644 --- a/index.html +++ b/index.html @@ -589,6 +589,44 @@ + +
+