实现虎牙积分查询执行器

This commit is contained in:
yml2213
2026-07-04 17:07:29 +08:00
parent e1d47a85be
commit 56ffaf531c
6 changed files with 525 additions and 13 deletions
+62 -11
View File
@@ -1,11 +1,13 @@
"""虎牙基础管理路由"""
import asyncio
import threading
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Query, WebSocket
from fastapi import APIRouter, Depends, HTTPException, Query, WebSocket, WebSocketDisconnect
from sqlalchemy.orm import Session, joinedload
from ..database import get_db
from ..database import SessionLocal, get_db
from ..deps import authenticate_websocket, require_permission
from ..models import HuyaAccount, HuyaConfig, HuyaGoodsSnapshot, HuyaTask, User
from ..schemas import (
@@ -23,6 +25,7 @@ from ..services.huya_service import (
ensure_huya_config,
import_huya_cookies,
)
from ..services.huya_runner import HuyaBatchRunner, huya_batch_registry
router = APIRouter(prefix="/api/huya", tags=["虎牙"])
@@ -197,12 +200,12 @@ def list_goods(
@router.post("/tasks/batch")
def create_task_batch(
async def create_task_batch(
req: HuyaTaskBatchRequest,
db: Session = Depends(get_db),
current: User = Depends(require_permission("huya:task")),
):
"""创建虎牙任务记录,真实执行器后续接入"""
"""创建虎牙任务记录并启动后台执行器"""
if not req.account_ids:
raise HTTPException(status_code=400, detail="请选择虎牙账号")
try:
@@ -217,6 +220,24 @@ def create_task_batch(
raise HTTPException(status_code=400, detail=str(exc)) from exc
if count == 0:
raise HTTPException(status_code=400, detail="没有有效的虎牙账号")
log_queue = asyncio.Queue()
loop = asyncio.get_running_loop()
thread_db = SessionLocal()
runner = HuyaBatchRunner(
db=thread_db,
batch_id=batch_id,
task_type=req.task_type,
payload=req.payload,
log_queue=log_queue,
loop=loop,
concurrency=req.concurrency,
)
huya_batch_registry.register(batch_id, log_queue, loop, runner)
thread = threading.Thread(target=runner.run, daemon=True)
thread.start()
return {"batch_id": batch_id, "count": count, "success": True}
@@ -234,17 +255,47 @@ def list_tasks(
return [_task_out(task) for task in tasks]
@router.post("/stop/{batch_id}")
def stop_batch(
batch_id: str,
current: User = Depends(require_permission("huya:task")),
):
"""停止正在运行的虎牙批次。"""
batch = huya_batch_registry.get(batch_id)
if batch:
batch["runner"].stop()
return {"message": "已发送停止信号", "success": True}
raise HTTPException(status_code=404, detail="批次不存在或已结束")
@router.websocket("/ws/{batch_id}")
async def ws_huya_logs(websocket: WebSocket, batch_id: str):
"""虎牙实时日志占位通道。"""
"""虎牙实时日志推送通道。"""
user = authenticate_websocket(websocket)
if not user:
await websocket.close(code=1008, reason="未授权")
return
await websocket.accept()
await websocket.send_json({
"level": "warning",
"message": f"虎牙批次 {batch_id} 已创建,真实执行器尚未接入",
})
await websocket.send_json({"level": "result", "message": ""})
await websocket.close()
batch = huya_batch_registry.get(batch_id)
if not batch:
await websocket.send_json({"level": "error", "message": "批次不存在或已结束"})
await websocket.close()
return
log_queue: asyncio.Queue = batch["log_queue"]
try:
while True:
try:
msg = await asyncio.wait_for(log_queue.get(), timeout=30)
await websocket.send_json(msg)
if msg.get("level") == "result":
await asyncio.sleep(0.1)
break
except asyncio.TimeoutError:
await websocket.send_json({"level": "heartbeat", "message": ""})
except WebSocketDisconnect:
pass
finally:
huya_batch_registry.pop(batch_id)