From e15b1d749191525f9ffeeef7dcbe0f65aef56a93 Mon Sep 17 00:00:00 2001 From: dekun Date: Fri, 23 Oct 2026 13:28:27 +0800 Subject: [PATCH] Auto-refresh review list and stats when trades or annotations change. Clarify that category/style breakdowns need manual entry tagging. Co-authored-by: Cursor --- app/db.py | 39 ++++++++++++++++++++++- app/routes.py | 14 +++++++++ app/templates/records.html | 7 +++-- app/templates/records_stats.html | 53 ++++++++++++++++++++++++++++++-- 4 files changed, 108 insertions(+), 5 deletions(-) diff --git a/app/db.py b/app/db.py index d2e76fe..804f722 100644 --- a/app/db.py +++ b/app/db.py @@ -398,6 +398,43 @@ def count_trades( return int(row["c"] if row else 0) +def trades_fingerprint( + conn: sqlite3.Connection, + account_id: Optional[int] = None, + machine_id: Optional[int] = None, +) -> str: + """列表/统计页轮询用:成交条数、最新 id/平仓时间、标注变化任一变即刷新。""" + clause, params = _trades_where(account_id, machine_id, hide_synthetic=True) + row = conn.execute( + f""" + SELECT COUNT(*) AS c, + COALESCE(MAX(t.id), 0) AS max_id, + COALESCE(MAX(t.close_time), 0) AS max_close, + COALESCE(MAX(t.open_time), 0) AS max_open, + SUM(CASE WHEN IFNULL(t.entry_style,'') != '' THEN 1 ELSE 0 END) AS annotated, + SUM(CASE WHEN IFNULL(t.review_issues,'') != '' THEN 1 ELSE 0 END) AS issues, + SUM(CASE WHEN t.close_time IS NULL OR t.close_time='' THEN 1 ELSE 0 END) AS open_n + FROM trades t + {clause} + """, + tuple(params), + ).fetchone() + if not row: + return "0" + return "|".join( + str(x) + for x in ( + int(row["c"] or 0), + int(row["max_id"] or 0), + round(float(row["max_close"] or 0), 3), + round(float(row["max_open"] or 0), 3), + int(row["annotated"] or 0), + int(row["issues"] or 0), + int(row["open_n"] or 0), + ) + ) + + def list_trades( conn: sqlite3.Connection, limit: int = 200, @@ -792,7 +829,7 @@ def trade_stats( "by_style": [ _finalize_group(by_style[k]) for k in style_order - if k in by_style and (by_style[k]["count"] or k in ENTRY_STYLES) + if k in by_style and by_style[k]["count"] ], } diff --git a/app/routes.py b/app/routes.py index de1d0f3..381d067 100644 --- a/app/routes.py +++ b/app/routes.py @@ -941,6 +941,20 @@ def register_routes(app: Flask) -> None: total_pages=total_pages, ) + @app.get("/api/records/fingerprint") + @login_required + def records_fingerprint(): + """复盘列表/统计页轮询:成交或标注变化时前端自动刷新。""" + u = current_user() + machine_raw = (request.args.get("machine_id") or "").strip() + account_id = None if u["role"] == "admin" else u.get("account_id") + _machines, machine_id = _resolve_machine_filter(u, machine_raw) + with database.get_db() as conn: + fp = database.trades_fingerprint( + conn, account_id=account_id, machine_id=machine_id + ) + return jsonify({"ok": True, "fp": fp, "ts": database.now()}) + @app.get("/records/stats") @login_required def records_stats_page(): diff --git a/app/templates/records.html b/app/templates/records.html index b03d97c..ff86b49 100644 --- a/app/templates/records.html +++ b/app/templates/records.html @@ -1,8 +1,11 @@ {% extends "base.html" %} {% block title %}交易复盘 · {{ app_name }}{% endblock %} {% block content %} -

交易记录与复盘

-

按机器筛选 · 每页 {{ per_page }} 条 · 时间均为北京时间 · 已隐藏对账/去重影子记录

+

+ 交易记录与复盘 + 自动刷新中… +

+

按机器筛选 · 每页 {{ per_page }} 条 · 北京时间 · 成交变化会自动刷新 · 已隐藏对账/去重影子记录

交易列表 diff --git a/app/templates/records_stats.html b/app/templates/records_stats.html index a5b5bd7..d3484da 100644 --- a/app/templates/records_stats.html +++ b/app/templates/records_stats.html @@ -1,9 +1,13 @@ {% extends "base.html" %} {% block title %}统计看板 · {{ app_name }}{% endblock %} {% block content %} -

统计看板

+

+ 统计看板 + 自动刷新中… +

默认按北京时间今日真实平仓统计;对账/去重产生的假平仓已排除。 + 成交/标注变化会自动刷新本页。 {% if selected_period == 'today' and stats.day %}当前:{{ stats.day }}{% endif %} {% if stats.skipped_synthetic %} · 已排除假平仓 {{ stats.skipped_synthetic }} 笔{% endif %} {% if stats.skipped_dup_ticket %} · 已排除重复单号 {{ stats.skipped_dup_ticket }} 笔{% endif %} @@ -82,6 +86,7 @@

按大类(顺势 / 反转 / 其他)

+

需在复盘页选「入场形式」后才会分入顺势/反转;未选的汇总在「未标注」。

@@ -107,6 +112,7 @@

按入场形式(细项)

+

只显示已标注过的形式;全部为「—」时请先打开复盘标注。

@@ -125,7 +131,7 @@ {% else %} - + {% endfor %}
{{ g.avg_hold }}
暂无数据
暂无入场形式标注
@@ -239,3 +245,46 @@
{% endblock %} + +{% block scripts %} + +{% endblock %}