This commit is contained in:
2026-06-16 03:00:06 +08:00
parent 964c17c200
commit 5b4d7bf280
5 changed files with 612 additions and 50 deletions

View File

@@ -58,10 +58,11 @@ import position_cost as pc
import trade_calendar as cal
import data_manager as dm
import paper_trading as paper
import task_manager
from db import init_db, get_session
from models import (DailyQuote, IndexDaily, SectorDaily, FundFlowDaily,
SentimentDaily, DragonTiger, Security, JobRun, StockMetric, Trade,
AlertRule, AlertEvent, SelectorStrategy, SelectorAlert)
AlertRule, AlertEvent, SelectorStrategy, SelectorAlert, ScheduledTask)
@asynccontextmanager
@@ -71,8 +72,9 @@ async def lifespan(app: FastAPI):
init_auth.init_default_admin()
wl.init_default_groups()
paper.ensure_default_account()
task_manager.init_tasks()
scheduler.start_scheduler()
print("[startup] db + scheduler + auth ready")
print("[startup] db + scheduler + task_manager + auth ready")
except Exception as e:
print("[startup] WARN:", repr(e)[:160])
yield
@@ -1636,6 +1638,50 @@ def paper_place_order(account_id: int, req: PaperOrderIn):
return paper.place_order(account_id, req.code, req.side, req.qty, req.price, req.reason)
# ============ 定时任务管理 ============
@app.get("/api/tasks")
def list_tasks(current_user = Depends(require_admin)):
"""获取所有定时任务"""
return {"ok": True, "tasks": task_manager.get_all_tasks()}
class UpdateTaskRequest(BaseModel):
enabled: Optional[bool] = None
schedule_type: Optional[str] = None
cron_expression: Optional[str] = None
interval_seconds: Optional[int] = None
@app.put("/api/tasks/{task_id}")
def update_task(task_id: str, req: UpdateTaskRequest, current_user = Depends(require_admin)):
"""更新任务配置"""
return task_manager.update_task(
task_id,
enabled=req.enabled,
schedule_type=req.schedule_type,
cron_expression=req.cron_expression,
interval_seconds=req.interval_seconds
)
@app.post("/api/tasks/{task_id}/toggle")
def toggle_task(task_id: str, current_user = Depends(require_admin)):
"""切换任务开关"""
return task_manager.toggle_task(task_id)
@app.get("/api/tasks/{task_id}/logs")
def task_logs(task_id: str, limit: int = Query(50, le=200), current_user = Depends(require_admin)):
"""获取任务执行日志"""
return {"ok": True, "logs": task_manager.get_task_logs(task_id, limit)}
@app.post("/api/tasks/reload")
def reload_tasks(current_user = Depends(require_admin)):
"""重新加载调度器"""
return scheduler.reload_scheduler()
@app.get("/api/paper/accounts/{account_id}/portfolio")
def paper_get_portfolio(account_id: int):
return paper.get_portfolio(account_id)