将月份状态、资料输出、调整单编排及工作区查询、 CSV 生成移至现有服务层,路由仅绑定参数并返回响应。 保持接口路径、参数、响应模型和权限依赖一致, 补充九项内存库行为回归并同步测试记录。
81 lines
3.3 KiB
Python
81 lines
3.3 KiB
Python
"""T+ 基础导入和预演的管理员入口;HTTP 不执行长查询或核算。"""
|
||
|
||
from typing import Annotated
|
||
|
||
from fastapi import APIRouter, Path, Query
|
||
from starlette.responses import StreamingResponse
|
||
|
||
from app.api.deps import DbSession, PayrollWriter, WorkbenchReader
|
||
from app.core.response import ApiResponse, PageQuery, PageResult, ok
|
||
from app.schemas.tplus_workbench import FactIn, SourceChoiceQuery, WorkCreateIn, WorkQuery
|
||
from app.services.tplus import workbench
|
||
|
||
router = APIRouter()
|
||
RunNo = Annotated[str, Path(pattern=r"^[A-Za-z0-9_-]+$", max_length=32)]
|
||
|
||
|
||
@router.get("/facts", response_model=ApiResponse[PageResult[dict]])
|
||
def facts(session: DbSession, _: WorkbenchReader, query: Annotated[WorkQuery, Query()]):
|
||
"""有界查询每项补充资料的当前版本。"""
|
||
return ok(workbench.list_facts(session, query))
|
||
|
||
|
||
@router.post("/facts", response_model=ApiResponse[dict])
|
||
def save_fact(session: DbSession, admin: PayrollWriter, payload: FactIn):
|
||
"""追加有依据的人工事实;旧版本不覆盖。"""
|
||
return ok(workbench.save_fact(session, payload, admin.id))
|
||
|
||
|
||
@router.get("/facts/{fact_id}/history", response_model=ApiResponse[PageResult[dict]])
|
||
def fact_history(
|
||
session: DbSession, _: WorkbenchReader, fact_id: int, query: Annotated[PageQuery, Query()]
|
||
):
|
||
"""按事实身份分页查看修改历史,不允许跨账套读取。"""
|
||
return ok(workbench.fact_history(session, fact_id, query))
|
||
|
||
|
||
@router.post("/work-runs", response_model=ApiResponse[dict])
|
||
def create_work(session: DbSession, admin: PayrollWriter, payload: WorkCreateIn):
|
||
"""创建导入预览、执行导入或核算预演任务。"""
|
||
return ok(workbench.queue_work(session, payload, admin.id))
|
||
|
||
|
||
@router.get("/work-runs", response_model=ApiResponse[PageResult[dict]])
|
||
def work_runs(session: DbSession, _: WorkbenchReader, query: Annotated[WorkQuery, Query()]):
|
||
"""分页查询任务,所有金额结果仅为预演。"""
|
||
return ok(workbench.list_work(session, query))
|
||
|
||
|
||
@router.get("/work-runs/{run_no}", response_model=ApiResponse[dict])
|
||
def work_detail(session: DbSession, _: WorkbenchReader, run_no: RunNo):
|
||
"""查询规则版本、输入指纹及结果。"""
|
||
return ok(workbench.work_out(workbench.get_run(session, run_no)))
|
||
|
||
|
||
@router.get("/work-runs/{run_no}/lines", response_model=ApiResponse[PageResult[dict]])
|
||
def work_lines(
|
||
session: DbSession, _: WorkbenchReader, run_no: RunNo, query: Annotated[WorkQuery, Query()]
|
||
):
|
||
"""分页查看新增、待补及分配明细,不公开原始快照 JSON。"""
|
||
return ok(workbench.list_lines(session, run_no, query))
|
||
|
||
|
||
@router.get("/source-records", response_model=ApiResponse[PageResult[dict]])
|
||
def source_choices(
|
||
session: DbSession,
|
||
_: WorkbenchReader,
|
||
query: Annotated[SourceChoiceQuery, Query()],
|
||
):
|
||
"""仅提供挑选资料所需的源编号和名称,不返回电话、地址和原始载荷。"""
|
||
return ok(workbench.source_choices(session, query))
|
||
|
||
|
||
@router.get("/work-runs/{run_no}/report")
|
||
def work_report(session: DbSession, _: WorkbenchReader, run_no: RunNo):
|
||
"""导出全部预演明细,防止源单号被电子表格当作公式执行。"""
|
||
return StreamingResponse(
|
||
workbench.report_csv(session, run_no),
|
||
media_type="text/csv; charset=utf-8",
|
||
headers={"Content-Disposition": f'attachment; filename="{run_no}-preview.csv"'},
|
||
)
|