feat: 档案统计独立卡片、共用交易日历与四所统计页日历

内照明心统计表移至顶部卡片,右侧为日历/图表/交易记录;日历样式适配浅深主题,四所统计分析页同步展示按月盈亏日历。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-30 08:17:53 +08:00
parent 6b872b1f43
commit 14dbf25798
16 changed files with 681 additions and 245 deletions
+49
View File
@@ -66,6 +66,8 @@ def install_instance_theme_static(app) -> None:
"instance_embed.js": "application/javascript; charset=utf-8",
"focus_chart_page.js": "application/javascript; charset=utf-8",
"focus_chart_page.css": "text/css; charset=utf-8",
"trade_stats_calendar.js": "application/javascript; charset=utf-8",
"trade_stats_calendar.css": "text/css; charset=utf-8",
}
for name, mime in assets.items():
@@ -83,6 +85,53 @@ def install_instance_theme_static(app) -> None:
)
def register_trade_stats_calendar_route(
app,
*,
login_required_fn,
load_pnls_fn,
row_matches_segment_fn,
reset_hour: int,
):
"""四所统计分析页:按月返回各交易日盈亏/笔数。"""
from flask import jsonify, request
from trade_stats_calendar_lib import build_trade_stats_calendar
@app.route("/api/stats/calendar")
@login_required_fn
def api_stats_calendar():
year = request.args.get("year", type=int)
month = request.args.get("month", type=int)
segment = (request.args.get("segment") or "all").strip() or "all"
if not year or not month:
from datetime import datetime
now = datetime.now()
year = year or now.year
month = month or now.month
get_db = (app.config.get("HUB_CTX") or {}).get("get_db")
if not get_db:
return jsonify({"ok": False, "msg": "未配置数据库"}), 500
conn = get_db()
try:
pnls = load_pnls_fn(conn)
finally:
conn.close()
try:
payload = build_trade_stats_calendar(
pnls,
year,
month,
segment,
row_matches_segment_fn,
reset_hour=int(reset_hour),
)
except ValueError as exc:
return jsonify({"ok": False, "msg": str(exc)}), 400
return jsonify({"ok": True, **payload})
def _hub_auth_required(f):
@wraps(f)
def wrapped(*args, **kwargs):