@@ -816,9 +816,6 @@ def get_strategy_notifications():
|
|||||||
user_strategy_ids = [r.get('id') for r in rows if r.get('id')]
|
user_strategy_ids = [r.get('id') for r in rows if r.get('id')]
|
||||||
cur.close()
|
cur.close()
|
||||||
|
|
||||||
if not user_strategy_ids:
|
|
||||||
return jsonify({'code': 1, 'msg': 'success', 'data': {'items': []}})
|
|
||||||
|
|
||||||
where = []
|
where = []
|
||||||
args = []
|
args = []
|
||||||
|
|
||||||
@@ -830,9 +827,15 @@ def get_strategy_notifications():
|
|||||||
else:
|
else:
|
||||||
return jsonify({'code': 1, 'msg': 'success', 'data': {'items': []}})
|
return jsonify({'code': 1, 'msg': 'success', 'data': {'items': []}})
|
||||||
else:
|
else:
|
||||||
placeholders = ",".join(["?"] * len(user_strategy_ids))
|
if user_strategy_ids:
|
||||||
where.append(f"strategy_id IN ({placeholders})")
|
placeholders = ",".join(["?"] * len(user_strategy_ids))
|
||||||
args.extend(user_strategy_ids)
|
where.append(f"(strategy_id IN ({placeholders}) OR (strategy_id IS NULL AND user_id = ?))")
|
||||||
|
args.extend(user_strategy_ids)
|
||||||
|
args.append(user_id)
|
||||||
|
else:
|
||||||
|
# Only portfolio monitor notifications (strategy_id is NULL)
|
||||||
|
where.append("strategy_id IS NULL AND user_id = ?")
|
||||||
|
args.append(user_id)
|
||||||
|
|
||||||
if since_id:
|
if since_id:
|
||||||
where.append("id > ?")
|
where.append("id > ?")
|
||||||
@@ -889,15 +892,18 @@ def mark_notification_read():
|
|||||||
if not notification_id:
|
if not notification_id:
|
||||||
return jsonify({'code': 0, 'msg': 'Missing id'}), 400
|
return jsonify({'code': 0, 'msg': 'Missing id'}), 400
|
||||||
|
|
||||||
# Only update notifications for user's strategies
|
# Update notifications for user's strategies OR portfolio monitor notifications
|
||||||
with get_db_connection() as db:
|
with get_db_connection() as db:
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"""
|
"""
|
||||||
UPDATE qd_strategy_notifications SET is_read = 1
|
UPDATE qd_strategy_notifications SET is_read = 1
|
||||||
WHERE id = ? AND strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
WHERE id = ? AND (
|
||||||
|
strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
||||||
|
OR (strategy_id IS NULL AND user_id = ?)
|
||||||
|
)
|
||||||
""",
|
""",
|
||||||
(int(notification_id), user_id)
|
(int(notification_id), user_id, user_id)
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
@@ -920,8 +926,9 @@ def mark_all_notifications_read():
|
|||||||
"""
|
"""
|
||||||
UPDATE qd_strategy_notifications SET is_read = 1
|
UPDATE qd_strategy_notifications SET is_read = 1
|
||||||
WHERE strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
WHERE strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
||||||
|
OR (strategy_id IS NULL AND user_id = ?)
|
||||||
""",
|
""",
|
||||||
(user_id,)
|
(user_id, user_id)
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
@@ -944,8 +951,9 @@ def clear_notifications():
|
|||||||
"""
|
"""
|
||||||
DELETE FROM qd_strategy_notifications
|
DELETE FROM qd_strategy_notifications
|
||||||
WHERE strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
WHERE strategy_id IN (SELECT id FROM qd_strategies_trading WHERE user_id = ?)
|
||||||
|
OR (strategy_id IS NULL AND user_id = ?)
|
||||||
""",
|
""",
|
||||||
(user_id,)
|
(user_id, user_id)
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
|
|||||||
@@ -768,8 +768,9 @@ def _send_monitor_notification(
|
|||||||
cur.close()
|
cur.close()
|
||||||
elif ch == 'telegram':
|
elif ch == 'telegram':
|
||||||
chat_id = targets.get('telegram', '')
|
chat_id = targets.get('telegram', '')
|
||||||
|
token_override = targets.get('telegram_bot_token', '')
|
||||||
if chat_id:
|
if chat_id:
|
||||||
notifier._notify_telegram(chat_id=chat_id, text=f"<b>{error_title}</b>\n\n{error_msg}", parse_mode="HTML")
|
notifier._notify_telegram(chat_id=chat_id, text=f"<b>{error_title}</b>\n\n{error_msg}", token_override=token_override, parse_mode="HTML")
|
||||||
elif ch == 'email':
|
elif ch == 'email':
|
||||||
to_email = targets.get('email', '')
|
to_email = targets.get('email', '')
|
||||||
if to_email:
|
if to_email:
|
||||||
@@ -815,11 +816,13 @@ def _send_monitor_notification(
|
|||||||
|
|
||||||
elif ch == 'telegram':
|
elif ch == 'telegram':
|
||||||
chat_id = targets.get('telegram', '')
|
chat_id = targets.get('telegram', '')
|
||||||
|
token_override = targets.get('telegram_bot_token', '')
|
||||||
if chat_id:
|
if chat_id:
|
||||||
# Use Telegram-optimized format
|
# Use Telegram-optimized format
|
||||||
notifier._notify_telegram(
|
notifier._notify_telegram(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
text=telegram_report,
|
text=telegram_report,
|
||||||
|
token_override=token_override,
|
||||||
parse_mode="HTML"
|
parse_mode="HTML"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1099,8 +1102,9 @@ def _check_position_alerts():
|
|||||||
cur.close()
|
cur.close()
|
||||||
elif ch == 'telegram':
|
elif ch == 'telegram':
|
||||||
chat_id = targets.get('telegram', '')
|
chat_id = targets.get('telegram', '')
|
||||||
|
token_override = targets.get('telegram_bot_token', '')
|
||||||
if chat_id:
|
if chat_id:
|
||||||
notifier._notify_telegram(chat_id=chat_id, text=alert_message, parse_mode="HTML")
|
notifier._notify_telegram(chat_id=chat_id, text=alert_message, token_override=token_override, parse_mode="HTML")
|
||||||
elif ch == 'email':
|
elif ch == 'email':
|
||||||
to_email = targets.get('email', '')
|
to_email = targets.get('email', '')
|
||||||
if to_email:
|
if to_email:
|
||||||
|
|||||||
@@ -52,29 +52,48 @@ class TradingExecutor:
|
|||||||
self._ensure_db_columns()
|
self._ensure_db_columns()
|
||||||
|
|
||||||
def _ensure_db_columns(self):
|
def _ensure_db_columns(self):
|
||||||
"""确保必要的数据库字段存在"""
|
"""确保必要的数据库字段存在(支持 SQLite 和 PostgreSQL)"""
|
||||||
try:
|
try:
|
||||||
|
db_type = os.getenv('DB_TYPE', 'sqlite').lower()
|
||||||
with get_db_connection() as db:
|
with get_db_connection() as db:
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
col_names = set()
|
||||||
|
|
||||||
# SQLite 兼容:使用 PRAGMA table_info 检查列是否存在
|
if db_type == 'postgresql':
|
||||||
try:
|
# PostgreSQL: 使用 information_schema 查询列
|
||||||
cursor.execute("PRAGMA table_info(qd_strategy_positions)")
|
try:
|
||||||
cols = cursor.fetchall() or []
|
cursor.execute("""
|
||||||
col_names = {c.get('name') for c in cols if isinstance(c, dict)}
|
SELECT column_name FROM information_schema.columns
|
||||||
except Exception:
|
WHERE table_name = 'qd_strategy_positions'
|
||||||
col_names = set()
|
""")
|
||||||
|
cols = cursor.fetchall() or []
|
||||||
|
col_names = {c.get('column_name') or c.get('COLUMN_NAME') for c in cols if isinstance(c, dict)}
|
||||||
|
except Exception:
|
||||||
|
col_names = set()
|
||||||
|
else:
|
||||||
|
# SQLite: 使用 PRAGMA table_info
|
||||||
|
try:
|
||||||
|
cursor.execute("PRAGMA table_info(qd_strategy_positions)")
|
||||||
|
cols = cursor.fetchall() or []
|
||||||
|
col_names = {c.get('name') for c in cols if isinstance(c, dict)}
|
||||||
|
except Exception:
|
||||||
|
col_names = set()
|
||||||
|
|
||||||
if 'highest_price' not in col_names:
|
if 'highest_price' not in col_names:
|
||||||
logger.info("Adding highest_price column to qd_strategy_positions (SQLite)...")
|
logger.info(f"Adding highest_price column to qd_strategy_positions ({db_type})...")
|
||||||
# SQLite 不支持 AFTER 子句,类型用 REAL 即可
|
if db_type == 'postgresql':
|
||||||
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN highest_price REAL DEFAULT 0")
|
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN IF NOT EXISTS highest_price DOUBLE PRECISION DEFAULT 0")
|
||||||
|
else:
|
||||||
|
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN highest_price REAL DEFAULT 0")
|
||||||
db.commit()
|
db.commit()
|
||||||
logger.info("highest_price column added")
|
logger.info("highest_price column added")
|
||||||
|
|
||||||
if 'lowest_price' not in col_names:
|
if 'lowest_price' not in col_names:
|
||||||
logger.info("Adding lowest_price column to qd_strategy_positions (SQLite)...")
|
logger.info(f"Adding lowest_price column to qd_strategy_positions ({db_type})...")
|
||||||
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN lowest_price REAL DEFAULT 0")
|
if db_type == 'postgresql':
|
||||||
|
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN IF NOT EXISTS lowest_price DOUBLE PRECISION DEFAULT 0")
|
||||||
|
else:
|
||||||
|
cursor.execute("ALTER TABLE qd_strategy_positions ADD COLUMN lowest_price REAL DEFAULT 0")
|
||||||
db.commit()
|
db.commit()
|
||||||
logger.info("lowest_price column added")
|
logger.info("lowest_price column added")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user