JobData/app/api/v1/token/token.py

187 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
import time
from typing import Any, Dict, Tuple
from fastapi import APIRouter, Query, Body, Path, BackgroundTasks
from fastapi.background import P
from tortoise.expressions import Q
from app.controllers.token import token_controller
from app.schemas.base import Fail, Success, SuccessExtra
from app.schemas.token import BossTokenUpdate,BossTokenCreate
logger = logging.getLogger(__name__)
token_router = APIRouter()
# 简单内存缓存key 为查询参数组合value 为 (缓存时间戳, 响应数据)
_TOKENS_CACHE: Dict[Tuple[Any, Any, int, int], Tuple[float, Dict[str, Any]]] = {}
_CACHE_TTL_SECONDS: int =60
@token_router.get("/tokens", summary="获取Boss Token列表")
async def list_boss_tokens(
page: int = Query(1, description="页码"),
page_size: int = Query(10, description="每页数量"),
status: int = Query(None, description="状态筛选"),
):
"""获取Boss Token列表"""
from tortoise.expressions import Q
q = Q()
if status is not None:
q &= Q(status=status)
total, token_objs = await token_controller.get_tokens(page=page, page_size=page_size, search=q)
data = [await obj.to_dict() for obj in token_objs]
return SuccessExtra(data=data, total=total, page=page, page_size=page_size)
@token_router.get("/tokens/{token_id}", summary="获取Boss Token详情")
async def get_boss_token(
token_id: int = Path(..., description="Token ID"),
):
"""获取Boss Token详情"""
token_obj = await token_controller.get_token(token_id)
token_dict = await token_obj.to_dict()
return Success(data=token_dict)
@token_router.post("/tokens", summary="创建Boss Token")
async def create_boss_token(
token_data: BossTokenCreate = Body(..., description="Token数据"),
):
"""创建Boss Token"""
await token_controller.create_token(token_data)
# 清空缓存,确保新数据立即生效
_TOKENS_CACHE.clear()
return Success(msg="创建成功")
@token_router.put("/tokens/{token_id}", summary="更新Boss Token")
async def update_boss_token(
token_id: int = Path(..., description="Token ID"),
token_data: BossTokenUpdate = Body(..., description="Token数据"),
):
"""更新Boss Token"""
await token_controller.update_token(token_id, token_data)
# 清空缓存,确保更新立即生效
_TOKENS_CACHE.clear()
return Success(msg="更新成功")
@token_router.delete("/tokens/{token_id}", summary="删除Boss Token")
async def delete_boss_token(
token_id: int = Path(..., description="Token ID"),
):
"""删除Boss Token"""
await token_controller.delete_token(token_id)
# 清空缓存,确保删除立即生效
_TOKENS_CACHE.clear()
return Success(msg="删除成功")
@token_router.post("/tokens/cache/clear", summary="强制清除Token缓存")
async def clear_token_cache():
"""强制清除Token列表缓存"""
global _TOKENS_CACHE
cache_size = len(_TOKENS_CACHE)
_TOKENS_CACHE.clear()
logger.info(f"手动清除Token缓存清除了 {cache_size} 条缓存数据")
return Success(msg=f"成功清除 {cache_size} 条Token缓存")
from typing import Optional, Dict, Any
from fastapi import APIRouter, Query, HTTPException
from tortoise.transactions import in_transaction
from app.models.token import BossToken
from app.schemas.base import Success
token_router = APIRouter()
@token_router.get("/tokens")
async def list_tokens(
wt2: Optional[str] = Query(None),
mpt: Optional[str] = Query(None),
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1, le=200),
):
"""获取 BossToken 列表,带两小时内存缓存。
Args:
wt2 (Optional[str]): 按 `wt2` 模糊匹配。
mpt (Optional[str]): 按 `mpt` 模糊匹配。
page (int): 页码。
page_size (int): 每页数量。
Returns:
Dict[str, Any]: 响应字典,包含 `code`、`data`、`total`。
"""
cache_key: Tuple[Any, Any, int, int] = (wt2, mpt, page, page_size)
now = time.monotonic()
cached = _TOKENS_CACHE.get(cache_key)
if cached and (now - cached[0] < _CACHE_TTL_SECONDS):
return cached[1]
qs = BossToken.all()
if wt2:
qs = qs.filter(wt2__icontains=wt2)
if mpt:
qs = qs.filter(mpt__icontains=mpt)
total = await qs.count()
items = await qs.order_by("-id").offset((page - 1) * page_size).limit(page_size)
data = [
{
"id": item.id,
"wt2": item.wt2,
"mpt": item.mpt,
"is_active": item.is_active,
"failed_count": item.failed_count,
"last_used_time": item.last_used_time,
"created_at": item.created_at,
}
for item in items
]
resp: Dict[str, Any] = {"code": 200, "data": data, "total": total}
_TOKENS_CACHE[cache_key] = (now, resp)
return resp
@token_router.post("/tokens")
async def create_token(payload: Dict[str, Any]):
try:
async with in_transaction():
item = await BossToken.create(
wt2=payload.get("wt2"),
mpt=payload.get("mpt"),
is_active=bool(payload.get("is_active", True)),
failed_count=int(payload.get("failed_count", 0)),
last_used_time=payload.get("last_used_time"),
)
_TOKENS_CACHE.clear()
return Success(data={"id": item.id})
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@token_router.put("/tokens/{id}")
async def update_token(id: int, payload: Dict[str, Any]):
token_id = id
item = await BossToken.get_or_none(id=token_id)
if not item:
raise HTTPException(status_code=404, detail="Token not found")
for field in ["wt2", "mpt", "is_active", "failed_count", "last_used_time"]:
if field in payload:
setattr(item, field, payload[field])
await item.save()
_TOKENS_CACHE.clear()
return Success(data={"id": item.id})
@token_router.delete("/tokens/{token_id}")
async def delete_token(token_id: int):
item = await BossToken.get_or_none(id=token_id)
if not item:
raise HTTPException(status_code=404, detail="Token not found")
await item.delete()
_TOKENS_CACHE.clear()
return Success(data={"id": token_id})