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(独立项目)
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"""计划任务管理:列出 / 启用 / 禁用 / 改时间。"""
|
||||
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}
|
||||
Reference in New Issue
Block a user