"""管理员管理 T+ 只读任务;长任务交给独立 worker 执行。""" from typing import Annotated from fastapi import APIRouter, Path, Query from app.api.deps import DbSession, PayrollWriter, RequestMetaDep, WorkbenchReader from app.api.v1.system.tplus_workbench import router as workbench_router from app.core.response import ApiResponse, PageResult, ok from app.schemas.tplus import ( TPlusAutomationOverview, TPlusAutomationUpdate, TPlusBatchDetailOut, TPlusBatchOut, TPlusBatchQuery, TPlusCreateIn, TPlusErrorOut, TPlusErrorQuery, TPlusOverviewOut, TPlusRetryIn, TPlusRuntimeOut, TPlusRuntimeUpdate, ) from app.services.tplus import automation_config, query_service, runtime_control, task_service router = APIRouter(prefix="/tplus", tags=["系统管理 · T+ 数据同步"]) router.include_router(workbench_router) BatchNumber = Annotated[str, Path(min_length=1, max_length=32, pattern=r"^[A-Za-z0-9_-]+$")] @router.get("/overview", response_model=ApiResponse[TPlusOverviewOut]) def overview(session: DbSession, _: WorkbenchReader): """查询配置状态、任务统计和最近核验。""" return ok(query_service.overview(session)) @router.put("/automation", response_model=ApiResponse[TPlusAutomationOverview]) def update_automation(session: DbSession, admin: PayrollWriter, meta: RequestMetaDep, payload: TPlusAutomationUpdate): """保存自动排队开关;既有活动任务继续执行。""" return ok(automation_config.save(session, payload, task_service.TaskActor(admin, meta))) @router.get("/runtime", response_model=ApiResponse[TPlusRuntimeOut]) def runtime_status(session: DbSession, _: WorkbenchReader): return ok(runtime_control.overview(session)) @router.put("/runtime", response_model=ApiResponse[TPlusRuntimeOut]) def update_runtime(session: DbSession, admin: PayrollWriter, meta: RequestMetaDep, payload: TPlusRuntimeUpdate): return ok(runtime_control.save(session, payload, task_service.TaskActor(admin, meta))) @router.get("/batches", response_model=ApiResponse[PageResult[TPlusBatchOut]]) def batches(session: DbSession, _: WorkbenchReader, query: Annotated[TPlusBatchQuery, Query()]): """分页查询批次元数据。""" return ok(query_service.list_batches(session, query)) @router.get("/batches/{batch_no}", response_model=ApiResponse[TPlusBatchDetailOut]) def detail(session: DbSession, _: WorkbenchReader, batch_no: BatchNumber): """查询批次详情与受控的核验报告。""" return ok(query_service.get_batch(session, batch_no)) @router.get("/batches/{batch_no}/errors", response_model=ApiResponse[PageResult[TPlusErrorOut]]) def errors( session: DbSession, _: WorkbenchReader, batch_no: BatchNumber, query: Annotated[TPlusErrorQuery, Query()], ): """分页查询异常定位和固定错误说明。""" return ok(query_service.list_errors(session, batch_no, query)) @router.post("/batches", response_model=ApiResponse[TPlusBatchDetailOut]) def create(session: DbSession, admin: PayrollWriter, meta: RequestMetaDep, payload: TPlusCreateIn): """将读取或核验任务持久化排队。""" batch = task_service.create_task(session, payload, task_service.TaskActor(admin, meta)) return ok(query_service.get_batch(session, batch.batch_no)) @router.post("/batches/{batch_no}/retry", response_model=ApiResponse[TPlusBatchDetailOut]) def retry( session: DbSession, admin: PayrollWriter, meta: RequestMetaDep, batch_no: BatchNumber, payload: TPlusRetryIn, ): """新建重试批次,保留原批次与异常历史。""" batch = task_service.retry_task(session, batch_no, payload, task_service.TaskActor(admin, meta)) return ok(query_service.get_batch(session, batch.batch_no))