feat(server): add date field to POST /tasks with legality validation
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import queue
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
@@ -190,11 +190,12 @@ class TaskRequest(BaseModel):
|
|||||||
force: bool = (
|
force: bool = (
|
||||||
False # 强制重下:忽略已落库去重,重新提交所有班次/交接单的导出任务(默认关)
|
False # 强制重下:忽略已落库去重,重新提交所有班次/交接单的导出任务(默认关)
|
||||||
)
|
)
|
||||||
|
date: Optional[str] = None # YYYY-MM-DD;指定则下载该日数据,否则走站点 offset
|
||||||
|
|
||||||
|
|
||||||
@app.post("/tasks")
|
@app.post("/tasks")
|
||||||
def create_task(req: TaskRequest):
|
def create_task(req: TaskRequest):
|
||||||
"""提交任务 {site, kind} → 入队,返回 task_id。"""
|
"""提交任务 {site, kind, force, date?} → 入队,返回 task_id。"""
|
||||||
# 【P0】后端未就绪时直接拒绝,避免任务在 worker 启动前入队卡死
|
# 【P0】后端未就绪时直接拒绝,避免任务在 worker 启动前入队卡死
|
||||||
if not worker_state["ready"]:
|
if not worker_state["ready"]:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -202,8 +203,32 @@ def create_task(req: TaskRequest):
|
|||||||
)
|
)
|
||||||
if (req.site, req.kind) not in TASK_HANDLERS:
|
if (req.site, req.kind) not in TASK_HANDLERS:
|
||||||
raise HTTPException(status_code=400, detail=f"无效任务: {req.site}/{req.kind}")
|
raise HTTPException(status_code=400, detail=f"无效任务: {req.site}/{req.kind}")
|
||||||
|
# 指定日期合法性校验(仅在传了 date 时)
|
||||||
|
if req.date:
|
||||||
|
try:
|
||||||
|
target_date = datetime.strptime(req.date, "%Y-%m-%d").date()
|
||||||
|
except ValueError:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail=f"date 格式非法,需 YYYY-MM-DD: {req.date}"
|
||||||
|
)
|
||||||
|
today = datetime.now().date()
|
||||||
|
if target_date > today:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail=f"date 不可为未来日期: {req.date}"
|
||||||
|
)
|
||||||
|
if target_date < today - timedelta(days=90):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail=f"date 超出 90 天回溯上限: {req.date}"
|
||||||
|
)
|
||||||
|
if req.site == "百世":
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="百世固定下载当天,不支持指定日期"
|
||||||
|
)
|
||||||
task_id = state_store.create_task(req.site, req.kind)
|
task_id = state_store.create_task(req.site, req.kind)
|
||||||
task_queue.put((task_id, {"site": req.site, "kind": req.kind, "force": req.force}))
|
spec = {"site": req.site, "kind": req.kind, "force": req.force}
|
||||||
|
if req.date:
|
||||||
|
spec["date"] = req.date
|
||||||
|
task_queue.put((task_id, spec))
|
||||||
return {"task_id": task_id}
|
return {"task_id": task_id}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user