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
+20 -19
View File
@@ -17,12 +17,13 @@ import time
import traceback
from typing import Any, Dict, List
from flask import Blueprint, Response, jsonify, request
from flask import Blueprint, Response, jsonify, request, g
import pandas as pd
import numpy as np
from app.utils.db import get_db_connection
from app.utils.logger import get_logger
from app.utils.auth import login_required
import requests
logger = get_logger(__name__)
@@ -115,24 +116,21 @@ def _generate_mock_df(length=200):
return df
@indicator_bp.route("/getIndicators", methods=["POST"])
@indicator_bp.route("/getIndicators", methods=["GET"])
@login_required
def get_indicators():
"""
Get indicator list for a user.
Request:
{ userid: number }
Get indicator list for the current user.
Response:
{ code: 1, data: [ ... ] }
"""
try:
data = request.get_json() or {}
user_id = int(data.get("userid") or 1)
user_id = g.user_id
with get_db_connection() as db:
cur = db.cursor()
# Local mode: "我的指标" should include both purchased and custom indicators.
# Get user's own indicators (both purchased and custom).
cur.execute(
"""
SELECT
@@ -156,13 +154,13 @@ def get_indicators():
@indicator_bp.route("/saveIndicator", methods=["POST"])
@login_required
def save_indicator():
"""
Create or update an indicator.
Create or update an indicator for the current user.
Request (frontend sends many extra fields; we store only the essentials):
{
userid: number,
id: number (0 for create),
name: string,
code: string,
@@ -172,7 +170,7 @@ def save_indicator():
"""
try:
data = request.get_json() or {}
user_id = int(data.get("userid") or 1)
user_id = g.user_id
indicator_id = int(data.get("id") or 0)
code = data.get("code") or ""
name = (data.get("name") or "").strip()
@@ -199,7 +197,7 @@ def save_indicator():
if not name:
name = "Custom Indicator"
now = _now_ts()
now = _now_ts() # For BIGINT fields (createtime, updatetime)
with get_db_connection() as db:
cur = db.cursor()
@@ -209,10 +207,10 @@ def save_indicator():
UPDATE qd_indicator_codes
SET name = ?, code = ?, description = ?,
publish_to_community = ?, pricing_type = ?, price = ?, preview_image = ?,
updatetime = ?, updated_at = ?
updatetime = ?, updated_at = NOW()
WHERE id = ? AND user_id = ? AND (is_buy IS NULL OR is_buy = 0)
""",
(name, code, description, publish_to_community, pricing_type, price, preview_image, now, now, indicator_id, user_id),
(name, code, description, publish_to_community, pricing_type, price, preview_image, now, indicator_id, user_id),
)
else:
cur.execute(
@@ -221,9 +219,9 @@ def save_indicator():
(user_id, is_buy, end_time, name, code, description,
publish_to_community, pricing_type, price, preview_image,
createtime, updatetime, created_at, updated_at)
VALUES (?, 0, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, 0, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
""",
(user_id, name, code, description, publish_to_community, pricing_type, price, preview_image, now, now, now, now),
(user_id, name, code, description, publish_to_community, pricing_type, price, preview_image, now, now),
)
indicator_id = int(cur.lastrowid or 0)
db.commit()
@@ -236,11 +234,12 @@ def save_indicator():
@indicator_bp.route("/deleteIndicator", methods=["POST"])
@login_required
def delete_indicator():
"""Delete an indicator by id."""
"""Delete an indicator by id for the current user."""
try:
data = request.get_json() or {}
user_id = int(data.get("userid") or 1)
user_id = g.user_id
indicator_id = int(data.get("id") or 0)
if not indicator_id:
return jsonify({"code": 0, "msg": "id is required", "data": None}), 400
@@ -261,6 +260,7 @@ def delete_indicator():
@indicator_bp.route("/verifyCode", methods=["POST"])
@login_required
def verify_code():
"""
Verify/Dry-run indicator code with mock data.
@@ -372,6 +372,7 @@ def verify_code():
@indicator_bp.route("/aiGenerate", methods=["POST"])
@login_required
def ai_generate():
"""
SSE endpoint to generate indicator code.