mirror of
https://git.oceanpay.cc/danial/kami_apple_exchage.git
synced 2025-12-18 21:23:49 +00:00
- 新增 CODEBUDDY.md、GEMINI.md、GEMINI_CN.md 等项目文档 - 更新 Dockerfile 和其他配置文件 - 优化部分代码结构,如 orders.py、tasks.py 等 - 新增 .dockerignore 文件
188 lines
5.7 KiB
Python
188 lines
5.7 KiB
Python
"""
|
|
任务管理API
|
|
提供任务暂停/恢复控制功能
|
|
"""
|
|
|
|
import traceback
|
|
from typing import Any
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.celery_app import get_celery_app
|
|
from app.core.database import get_async_db
|
|
from app.core.redis_manager import redis_manager
|
|
from app.core.log import get_logger
|
|
from app.core.state_manager import task_state_manager
|
|
from app.services.task_service import TaskService
|
|
from app.schemas.task import (
|
|
GiftCardSubmissionRequest,
|
|
GiftCardSubmissionResponse,
|
|
QueueStatsResponse,
|
|
TaskListResponse,
|
|
TaskControlRequest,
|
|
TaskControlResponse,
|
|
TaskStateResponse,
|
|
)
|
|
|
|
logger = get_logger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/toggle", response_model=TaskControlResponse)
|
|
async def toggle_task_state(request: TaskControlRequest) -> TaskControlResponse:
|
|
"""
|
|
切换任务状态(暂停/恢复)
|
|
|
|
Args:
|
|
request: 任务状态切换请求
|
|
|
|
Returns:
|
|
TaskControlResponse: 操作结果
|
|
"""
|
|
try:
|
|
success = await redis_manager.set_task_pause_state(
|
|
is_paused=request.is_paused, reason=request.reason
|
|
)
|
|
|
|
if success:
|
|
action = "暂停" if request.is_paused else "恢复"
|
|
logger.info(f"任务{action}操作成功: {request.reason}")
|
|
return TaskControlResponse(
|
|
success=True,
|
|
is_paused=request.is_paused,
|
|
reason=request.reason,
|
|
message=f"任务已成功{action}",
|
|
)
|
|
else:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail="设置任务状态失败",
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"设置任务状态异常: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"设置任务状态失败: {str(e)}",
|
|
)
|
|
|
|
|
|
@router.get("/status", response_model=TaskStateResponse)
|
|
async def get_task_status() -> TaskStateResponse:
|
|
"""
|
|
获取任务状态
|
|
|
|
Returns:
|
|
TaskStatusResponse: 当前任务状态
|
|
"""
|
|
try:
|
|
paused, reason = await redis_manager.get_task_pause_state()
|
|
|
|
status_text = "已暂停" if paused else "运行中"
|
|
return TaskStateResponse(
|
|
success=True,
|
|
is_paused=paused,
|
|
reason=reason,
|
|
message=f"任务当前状态: {status_text}",
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"获取任务状态异常: {traceback.format_exc()}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"获取任务状态失败: {str(e)}",
|
|
)
|
|
|
|
|
|
@router.get("/list", response_model=TaskListResponse)
|
|
async def get_task_list(db: AsyncSession = Depends(get_async_db)) -> TaskListResponse:
|
|
"""
|
|
获取任务列表
|
|
|
|
Returns:
|
|
TaskListResponse: 任务列表响应
|
|
"""
|
|
try:
|
|
# 获取数据库会话
|
|
task_service = TaskService(db)
|
|
return await task_service.get_task_list()
|
|
|
|
except Exception as e:
|
|
logger.error(f"获取任务列表失败: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"获取任务列表失败: {str(e)}",
|
|
)
|
|
|
|
|
|
@router.get("/queue/stats", summary="获取队列统计", response_model=QueueStatsResponse)
|
|
async def get_queue_stats() -> QueueStatsResponse:
|
|
"""获取Celery队列统计信息"""
|
|
try:
|
|
from datetime import datetime
|
|
|
|
celery_app = get_celery_app()
|
|
inspect = celery_app.control.inspect()
|
|
|
|
# 获取队列统计
|
|
active_tasks = inspect.active()
|
|
scheduled_tasks = inspect.scheduled()
|
|
reserved_tasks = inspect.reserved()
|
|
|
|
stats = {
|
|
"active_tasks": active_tasks or {},
|
|
"scheduled_tasks": scheduled_tasks or {},
|
|
"reserved_tasks": reserved_tasks or {},
|
|
"total_active": sum(len(tasks) for tasks in (active_tasks or {}).values()),
|
|
"total_scheduled": sum(
|
|
len(tasks) for tasks in (scheduled_tasks or {}).values()
|
|
),
|
|
"total_reserved": sum(
|
|
len(tasks) for tasks in (reserved_tasks or {}).values()
|
|
),
|
|
}
|
|
|
|
logger.info("获取队列统计成功")
|
|
return QueueStatsResponse(
|
|
success=True, stats=stats, timestamp=datetime.now().isoformat()
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"获取队列统计失败: {e}", exc_info=True)
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"获取队列统计失败: {str(e)}",
|
|
)
|
|
|
|
|
|
@router.post("/submit", response_model=GiftCardSubmissionResponse)
|
|
async def submit_gift_card(
|
|
request: GiftCardSubmissionRequest, db: AsyncSession = Depends(get_async_db)
|
|
):
|
|
"""
|
|
提交礼品卡信息并更新任务状态
|
|
|
|
Args:
|
|
request: 礼品卡提交请求
|
|
|
|
Returns:
|
|
GiftCardSubmissionResponse: 操作结果
|
|
"""
|
|
try:
|
|
# 获取数据库会话
|
|
task_service = TaskService(db)
|
|
return await task_service.submit_gift_card(request)
|
|
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
|
|
except RuntimeError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"提交礼品卡失败: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"提交礼品卡失败: {str(e)}",
|
|
)
|