feat: redesign workspaces and stabilize screeners

This commit is contained in:
leefer
2026-07-26 13:31:45 +08:00
parent 149c468240
commit 6adeb54458
21 changed files with 18786 additions and 917 deletions
+28
View File
@@ -21,6 +21,34 @@ class StrategyTrackingService:
user_id, run_id, selection_date, strategy_name, candidates
)
def add_candidate(self, user_id: int, run_id: int, code: str) -> dict[str, Any]:
run = self.database.get_screener_run(user_id, run_id)
if not run:
raise ValueError("选股结果不存在或不属于当前账号。")
normalized_code = str(code or "").strip().split(".")[0]
candidate = next(
(
item for item in run.get("candidates", [])
if str(item.get("code") or item.get("ts_code") or "").split(".")[0]
== normalized_code
),
None,
)
if not candidate:
raise ValueError("该股票不在本次选股结果中。")
added = self.record_run(
user_id,
run_id,
str(run.get("meta", {}).get("trade_date") or ""),
str(run.get("strategy_name") or "未命名策略"),
[candidate],
)
return {"added": added, "tracking": self.list_tracking(user_id)}
def remove_candidate(self, user_id: int, track_id: int) -> dict[str, Any]:
deleted = self.database.delete_strategy_track(user_id, track_id)
return {"deleted": deleted, "tracking": self.list_tracking(user_id)}
def list_tracking(self, user_id: int, limit_batches: int = 12) -> dict[str, Any]:
tracks = self.database.list_strategy_tracks(user_id, limit_batches)
if not tracks: