Paginate review list (10/page); show open/close/hold duration in BJT.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-17 22:21:12 +08:00
parent 3164a21348
commit dbfddeedcb
4 changed files with 133 additions and 27 deletions
+56 -8
View File
@@ -4,9 +4,11 @@ from __future__ import annotations
import json
import secrets
import time
from datetime import datetime
from datetime import datetime, timedelta, timezone
from functools import wraps
BJT = timezone(timedelta(hours=8))
from flask import (
Flask,
Response,
@@ -186,10 +188,39 @@ def register_routes(app: Flask) -> None:
if value is None or value == "":
return "—"
try:
return datetime.fromtimestamp(float(value)).strftime("%Y-%m-%d %H:%M:%S")
return datetime.fromtimestamp(float(value), BJT).strftime("%Y-%m-%d %H:%M:%S")
except (TypeError, ValueError, OSError):
return str(value)
def _fmt_hold(open_ts, close_ts) -> str:
"""持仓时长:平仓−开仓;未平仓则按当前时间估算。"""
if open_ts is None or open_ts == "":
return "—"
try:
start = float(open_ts)
end = float(close_ts) if close_ts not in (None, "") else time.time()
except (TypeError, ValueError):
return "—"
secs = max(0, int(end - start))
days, rem = divmod(secs, 86400)
hours, rem = divmod(rem, 3600)
mins, sec = divmod(rem, 60)
if days > 0:
return f"{days}天{hours}小时{mins}分"
if hours > 0:
return f"{hours}小时{mins}分"
if mins > 0:
return f"{mins}分{sec}秒"
return f"{sec}秒"
def _annotate_trade_times(t: dict) -> None:
t["open_time_fmt"] = _fmt_ts(t.get("open_time"))
t["close_time_fmt"] = _fmt_ts(t.get("close_time"))
closed = t.get("close_time") not in (None, "")
t["hold_duration"] = _fmt_hold(t.get("open_time"), t.get("close_time"))
if not closed and t.get("open_time"):
t["hold_duration"] = t["hold_duration"] + "(持仓中)"
def _dashboard_payload(u: dict) -> dict:
with database.get_db() as conn:
if u["role"] == "admin":
@@ -596,22 +627,38 @@ def register_routes(app: Flask) -> None:
u = current_user()
machine_raw = (request.args.get("machine_id") or "").strip()
machine_id = int(machine_raw) if machine_raw.isdigit() else None
page_raw = (request.args.get("page") or "1").strip()
page = int(page_raw) if page_raw.isdigit() and int(page_raw) >= 1 else 1
per_page = 10
account_id = None if u["role"] == "admin" else u.get("account_id")
with database.get_db() as conn:
machines = database.list_machines_for_user(conn, u)
allowed_ids = {int(m["id"]) for m in machines}
if machine_id is not None and machine_id not in allowed_ids:
machine_id = None
if u["role"] == "admin":
trades = database.list_trades(conn, 300, machine_id=machine_id)
else:
trades = database.list_trades(
conn, 300, account_id=u.get("account_id"), machine_id=machine_id
)
total = database.count_trades(conn, account_id=account_id, machine_id=machine_id)
total_pages = max(1, (total + per_page - 1) // per_page)
if page > total_pages:
page = total_pages
offset = (page - 1) * per_page
trades = database.list_trades(
conn,
limit=per_page,
account_id=account_id,
machine_id=machine_id,
offset=offset,
)
for t in trades:
_annotate_trade_times(t)
return render_template(
"records.html",
trades=trades,
machines=machines,
selected_machine_id=machine_id,
page=page,
per_page=per_page,
total=total,
total_pages=total_pages,
)
@app.get("/records/<int:tid>")
@@ -623,6 +670,7 @@ def register_routes(app: Flask) -> None:
if not trade or not database.user_can_access_account(u, trade.get("account_id")):
flash("记录不存在或无权查看", "error")
return redirect(url_for("records_page"))
_annotate_trade_times(trade)
center = trade.get("open_time") or trade.get("created_at") or database.now()
window = 3600 * 6
charts = {}