feat(hub): trend plan breakeven and stop from monitor fullscreen

Proxy /api/hub/trend/stop and breakeven to instances; enable offset input and actions in hub UI. Add horizontal padding on strategy records page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-04 14:46:24 +08:00
parent 52d97482f2
commit f9301b92b9
8 changed files with 253 additions and 14 deletions
+48
View File
@@ -158,6 +158,29 @@ def _invoke_view(view_name: str, path: str, form=None) -> dict:
return {"ok": ok, "messages": msgs}
def _invoke_view_get(view_name: str, path: str) -> dict:
views = _ctx().get("views") or {}
view = views.get(view_name)
if not view:
return {"ok": False, "messages": [f"未配置视图 {view_name}"]}
with current_app.test_request_context(path, method="GET"):
session["logged_in"] = True
try:
view()
except Exception as e:
return {"ok": False, "messages": [str(e)]}
try:
msgs = [str(x) for x in get_flashed_messages()]
except Exception as e:
return {"ok": False, "messages": [f"读取提示信息失败: {e}"]}
ok = True
for m in msgs:
if any(k in m for k in _FAIL_HINTS):
ok = False
break
return {"ok": ok, "messages": msgs}
def _hub_json(view_name: str, path: str, form=None):
try:
return jsonify(_invoke_view(view_name, path, form=form))
@@ -445,6 +468,31 @@ def register_hub_routes(app):
return jsonify({"ok": False, "msg": "预览不存在或已过期"}), 404
return jsonify({"ok": True, "preview": preview})
@app.route("/api/hub/trend/stop/<int:pid>", methods=["POST"])
@_hub_auth_required
def api_hub_trend_stop(pid):
if not _ctx().get("has_trend"):
return jsonify({"ok": False, "msg": "该实例无趋势回调"}), 400
return jsonify(_invoke_view_get("stop_trend_pullback", f"/stop_trend_pullback/{pid}"))
@app.route("/api/hub/trend/breakeven/<int:pid>", methods=["POST"])
@_hub_auth_required
def api_hub_trend_breakeven(pid):
if not _ctx().get("has_trend"):
return jsonify({"ok": False, "msg": "该实例无趋势回调"}), 400
body = request.get_json(silent=True) or {}
raw = (request.form.get("breakeven_offset_pct") or body.get("breakeven_offset_pct") or "").strip()
form = {}
if raw != "":
form["breakeven_offset_pct"] = raw
return jsonify(
_invoke_view(
"trend_pullback_breakeven",
f"/trend_pullback_breakeven/{pid}",
form=form,
)
)
@app.route("/hub-sso")
def hub_sso_login():
"""中控签发的临时链接:写入 session 后跳转,直链访问仍走 /login。"""