Some checks failed
Test / test (push) Failing after 3m47s
- 替换 Field(max_length=X) 为 StrX/TextX 类型别名(21 个 sqlmodels 文件) - 替换 get + 404 检查为 get_exist_one()(17 个路由文件,约 50 处) - 替换 save + session.refresh 为 save(load=...) - 替换 session.add + commit 为 save()(dav/provider.py) - 更新所有依赖至最新版本 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
157 lines
3.7 KiB
Python
157 lines
3.7 KiB
Python
from typing import Any
|
|
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from loguru import logger as l
|
|
|
|
from middleware.auth import admin_required
|
|
from middleware.dependencies import SessionDep, TableViewRequestDep
|
|
from sqlmodels import (
|
|
ListResponse,
|
|
Task, TaskSummary, TaskStatus, TaskType,
|
|
)
|
|
from sqlmodel_ext import SQLModelBase
|
|
|
|
|
|
class TaskDetailResponse(SQLModelBase):
|
|
"""任务详情响应"""
|
|
|
|
id: int
|
|
"""任务ID"""
|
|
|
|
status: TaskStatus
|
|
"""任务状态"""
|
|
|
|
type: TaskType
|
|
"""任务类型"""
|
|
|
|
progress: int
|
|
"""任务进度"""
|
|
|
|
error: str | None
|
|
"""错误信息"""
|
|
|
|
user_id: str
|
|
"""用户UUID"""
|
|
|
|
username: str | None
|
|
"""用户名"""
|
|
|
|
props: dict[str, Any] | None
|
|
"""任务属性"""
|
|
|
|
created_at: str
|
|
"""创建时间"""
|
|
|
|
updated_at: str
|
|
"""更新时间"""
|
|
|
|
admin_task_router = APIRouter(
|
|
prefix='/task',
|
|
tags=['admin', 'admin_task']
|
|
)
|
|
|
|
@admin_task_router.get(
|
|
path='/list',
|
|
summary='获取任务列表',
|
|
description='Get task list',
|
|
dependencies=[Depends(admin_required)]
|
|
)
|
|
async def router_admin_get_task_list(
|
|
session: SessionDep,
|
|
table_view: TableViewRequestDep,
|
|
user_id: UUID | None = None,
|
|
status: str | None = None,
|
|
) -> ListResponse[TaskSummary]:
|
|
"""
|
|
获取任务列表。
|
|
|
|
:param session: 数据库会话
|
|
:param table_view: 分页排序参数依赖
|
|
:param user_id: 按用户筛选
|
|
:param status: 按状态筛选
|
|
:return: 分页任务列表
|
|
"""
|
|
conditions = []
|
|
if user_id:
|
|
conditions.append(Task.user_id == user_id)
|
|
if status:
|
|
conditions.append(Task.status == status)
|
|
|
|
if conditions:
|
|
condition = conditions[0]
|
|
for c in conditions[1:]:
|
|
condition = condition & c
|
|
else:
|
|
condition = None
|
|
result = await Task.get_with_count(session, condition, table_view=table_view, load=Task.user)
|
|
|
|
items: list[TaskSummary] = []
|
|
for t in result.items:
|
|
user = await t.awaitable_attrs.user
|
|
items.append(TaskSummary.from_task(t, user))
|
|
|
|
return ListResponse(items=items, count=result.count)
|
|
|
|
|
|
@admin_task_router.get(
|
|
path='/{task_id}',
|
|
summary='获取任务详情',
|
|
description='Get task detail by ID',
|
|
dependencies=[Depends(admin_required)]
|
|
)
|
|
async def router_admin_get_task(
|
|
session: SessionDep,
|
|
task_id: int,
|
|
) -> TaskDetailResponse:
|
|
"""
|
|
获取任务详情。
|
|
|
|
:param session: 数据库会话
|
|
:param task_id: 任务ID
|
|
:return: 任务详情
|
|
"""
|
|
task = await Task.get(session, Task.id == task_id, load=Task.props)
|
|
if not task:
|
|
raise HTTPException(status_code=404, detail="任务不存在")
|
|
|
|
user = await task.awaitable_attrs.user
|
|
props = await task.awaitable_attrs.props
|
|
|
|
return TaskDetailResponse(
|
|
id=task.id,
|
|
status=task.status,
|
|
type=task.type,
|
|
progress=task.progress,
|
|
error=task.error,
|
|
user_id=str(task.user_id),
|
|
username=user.email if user else None,
|
|
props=props.model_dump() if props else None,
|
|
created_at=task.created_at.isoformat(),
|
|
updated_at=task.updated_at.isoformat(),
|
|
)
|
|
|
|
|
|
@admin_task_router.delete(
|
|
path='/{task_id}',
|
|
summary='删除任务',
|
|
description='Delete task by ID',
|
|
dependencies=[Depends(admin_required)],
|
|
status_code=204,
|
|
)
|
|
async def router_admin_delete_task(
|
|
session: SessionDep,
|
|
task_id: int,
|
|
) -> None:
|
|
"""
|
|
删除任务。
|
|
|
|
:param session: 数据库会话
|
|
:param task_id: 任务ID
|
|
:return: 删除结果
|
|
"""
|
|
task = await Task.get_exist_one(session, task_id)
|
|
|
|
await Task.delete(session, task)
|
|
|
|
l.info(f"管理员删除了任务: {task_id}") |