Files
gao 05635b76b9 chore: 重构前基线 — 9 个 sync task 全部 ok + akshare 移除 + mairui 资金流接入
状态:
- 9 个 sync task(stock_basic / kline_daily / kline_index / kline_5min /
  moneyflow / industry_sector / sector_features / share_snapshot / market_regime)
- 数据源:baostock + mairui + 雪球(pysnowball) + 新浪(4 个)
- 项目级约束:永远不用 akshare(已落实)
- kline_5min 改用 DB 快照统一全量/增量逻辑
- 零后端 Chrome 扩展 xueqiu_sync(独立项目)
2026-06-15 15:36:09 +08:00

69 lines
1.9 KiB
Python

"""计划任务管理:列出 / 启用 / 禁用 / 改时间。"""
from __future__ import annotations
import json
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from app.core.db import ops as db_ops
from app.core.scheduler import (
get_scheduler_status,
is_trading_day,
next_trading_day,
seed_schedule_configs,
)
router = APIRouter(prefix="/api/schedule", tags=["schedule"])
class ScheduleUpdate(BaseModel):
enabled: bool | None = None
time: str | None = None
intervalSeconds: int | None = None
condition: str | None = None
@router.get("")
def list_schedules():
return {"scheduler": get_scheduler_status(), "isTradingDay": is_trading_day(),
"nextTradingDay": next_trading_day().isoformat()}
@router.post("/reseed")
def reseed():
seed_schedule_configs()
return {"status": "ok"}
@router.patch("/{key}")
def update_schedule(key: str, body: ScheduleUpdate):
target = None
for r in db_ops.fetch_all_config():
if r.get("key") == key and r.get("category") == "schedule":
target = r
break
if target is None:
raise HTTPException(404, f"未知 schedule key: {key}")
try:
obj = json.loads(target.get("value", "") or "{}")
except (json.JSONDecodeError, TypeError):
obj = {}
if body.enabled is not None:
obj["enabled"] = body.enabled
if body.time is not None:
obj["time"] = body.time
if body.intervalSeconds is not None:
obj["intervalSeconds"] = body.intervalSeconds
if body.condition is not None:
if body.condition not in ("always", "trading_day"):
raise HTTPException(400, f"condition 仅支持 always / trading_day")
obj["condition"] = body.condition
db_ops.upsert_config(
key, json.dumps(obj, ensure_ascii=False),
category="schedule", description=target.get("description", ""),
)
return {"status": "ok", "key": key, "value": obj}