feat: Multi-user system with PostgreSQL - WIP temporary save

This commit is contained in:
TIANHE
2026-01-14 05:29:55 +08:00
parent 996e3b38fe
commit 61a5e5e6aa
68 changed files with 91057 additions and 1920 deletions
+28 -12
View File
@@ -15,10 +15,11 @@ import json
import time
from typing import Any, Dict, List, Tuple
from flask import Blueprint, jsonify, request
from flask import Blueprint, jsonify, request, g
from app.utils.db import get_db_connection
from app.utils.logger import get_logger
from app.utils.auth import login_required
logger = get_logger(__name__)
@@ -255,19 +256,24 @@ def _compute_strategy_stats(trades: List[Dict[str, Any]], strategies: List[Dict[
@dashboard_bp.route("/summary", methods=["GET"])
@login_required
def summary():
"""
Return dashboard summary used by `quantdinger_vue/src/views/dashboard/index.vue`.
"""
try:
# Strategy counts
user_id = g.user_id
# Strategy counts (filtered by user_id)
with get_db_connection() as db:
cur = db.cursor()
cur.execute(
"""
SELECT id, strategy_name, strategy_type, status, initial_capital, trading_config
FROM qd_strategies_trading
"""
WHERE user_id = ?
""",
(user_id,)
)
strategies = cur.fetchall() or []
cur.close()
@@ -292,7 +298,7 @@ def summary():
if isinstance(tc, dict) and _truthy(tc.get("enable_ai_filter")):
ai_enabled_strategy_count += 1
# Positions (best-effort)
# Positions (best-effort, filtered by user_id)
with get_db_connection() as db:
cur = db.cursor()
cur.execute(
@@ -300,8 +306,10 @@ def summary():
SELECT p.*, s.strategy_name, s.initial_capital, s.leverage, s.market_type
FROM qd_strategy_positions p
LEFT JOIN qd_strategies_trading s ON s.id = p.strategy_id
WHERE p.user_id = ?
ORDER BY p.updated_at DESC
"""
""",
(user_id,)
)
rows = cur.fetchall() or []
cur.close()
@@ -332,7 +340,7 @@ def summary():
}
)
# Recent trades (best-effort)
# Recent trades (best-effort, filtered by user_id)
with get_db_connection() as db:
cur = db.cursor()
cur.execute(
@@ -340,9 +348,11 @@ def summary():
SELECT t.*, s.strategy_name
FROM qd_strategy_trades t
LEFT JOIN qd_strategies_trading s ON s.id = t.strategy_id
WHERE t.user_id = ?
ORDER BY t.created_at DESC
LIMIT 500
"""
""",
(user_id,)
)
recent_trades = cur.fetchall() or []
cur.close()
@@ -497,18 +507,20 @@ def summary():
@dashboard_bp.route("/pendingOrders", methods=["GET"])
@login_required
def pending_orders():
"""
Return pending orders list for dashboard page.
"""
try:
user_id = g.user_id
page = max(1, _safe_int(request.args.get("page"), 1))
page_size = max(1, min(200, _safe_int(request.args.get("pageSize"), 20)))
offset = (page - 1) * page_size
with get_db_connection() as db:
cur = db.cursor()
cur.execute("SELECT COUNT(1) AS cnt FROM pending_orders")
cur.execute("SELECT COUNT(1) AS cnt FROM pending_orders WHERE user_id = ?", (user_id,))
total = int((cur.fetchone() or {}).get("cnt") or 0)
cur.close()
@@ -525,10 +537,11 @@ def pending_orders():
s.execution_mode AS strategy_execution_mode
FROM pending_orders o
LEFT JOIN qd_strategies_trading s ON s.id = o.strategy_id
WHERE o.user_id = ?
ORDER BY o.id DESC
LIMIT %s OFFSET %s
LIMIT ? OFFSET ?
""",
(int(page_size), int(offset)),
(user_id, int(page_size), int(offset)),
)
rows = cur.fetchall() or []
cur.close()
@@ -607,18 +620,21 @@ def pending_orders():
@dashboard_bp.route("/pendingOrders/<int:order_id>", methods=["DELETE"])
@login_required
def delete_pending_order(order_id: int):
"""
Delete a pending order record (dashboard operation).
"""
try:
user_id = g.user_id
oid = int(order_id or 0)
if oid <= 0:
return jsonify({"code": 0, "msg": "invalid_id", "data": None}), 400
with get_db_connection() as db:
cur = db.cursor()
cur.execute("SELECT id, status FROM pending_orders WHERE id = %s", (oid,))
# Verify the order belongs to current user
cur.execute("SELECT id, status FROM pending_orders WHERE id = ? AND user_id = ?", (oid, user_id))
row = cur.fetchone() or {}
if not row:
cur.close()
@@ -627,7 +643,7 @@ def delete_pending_order(order_id: int):
if st == "processing":
cur.close()
return jsonify({"code": 0, "msg": "cannot_delete_processing", "data": None}), 400
cur.execute("DELETE FROM pending_orders WHERE id = %s", (oid,))
cur.execute("DELETE FROM pending_orders WHERE id = ? AND user_id = ?", (oid, user_id))
db.commit()
cur.close()