From 3aae24920f24df81972c5b55a70a5c575452bb08 Mon Sep 17 00:00:00 2001 From: zhinianboke <115088296+zhinianboke@users.noreply.github.com> Date: Sun, 27 Jul 2025 10:47:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docker快速启动指南.md | 21 ++++ XianyuAutoAsync.py | 20 ++-- db_manager.py | 222 ++++++++++++++++++++++++++++-------------- docker-compose.yml | 3 + reply_server.py | 22 +++-- 5 files changed, 199 insertions(+), 89 deletions(-) diff --git a/Docker快速启动指南.md b/Docker快速启动指南.md index cc02de8..f020d1f 100644 --- a/Docker快速启动指南.md +++ b/Docker快速启动指南.md @@ -107,6 +107,27 @@ docker-compose exec xianyu-app bash docker-compose exec xianyu-app ls -la /app/data/ ``` +### SQL日志调试 +```bash +# SQL日志默认已启用(INFO级别) +# 查看SQL执行日志 +docker-compose logs -f xianyu-app | grep "SQL" + +# 如需禁用SQL日志 +export SQL_LOG_ENABLED=false +docker-compose up -d + +# 如需调整日志级别 +export SQL_LOG_LEVEL=DEBUG # 更详细的日志 +# 或 +export SQL_LOG_LEVEL=WARNING # 更少的日志 +docker-compose up -d + +# 在.env文件中配置 +echo "SQL_LOG_ENABLED=false" >> .env +echo "SQL_LOG_LEVEL=DEBUG" >> .env +``` + ### 故障排除 ```bash # 重新构建镜像 diff --git a/XianyuAutoAsync.py b/XianyuAutoAsync.py index 7a8c19b..e4e7e4e 100644 --- a/XianyuAutoAsync.py +++ b/XianyuAutoAsync.py @@ -989,18 +989,26 @@ class XianyuLive: logger.error(f"处理Token刷新通知失败: {self._safe_str(e)}") def _is_normal_token_expiry(self, error_message: str) -> bool: - """检查是否是正常的令牌过期(这种情况不需要发送通知)""" - # 正常的令牌过期关键词 - normal_expiry_keywords = [ + """检查是否是正常的令牌过期或其他不需要通知的情况""" + # 不需要发送通知的关键词 + no_notification_keywords = [ + # 正常的令牌过期 'FAIL_SYS_TOKEN_EXOIRED::令牌过期', 'FAIL_SYS_TOKEN_EXPIRED::令牌过期', 'FAIL_SYS_TOKEN_EXOIRED', 'FAIL_SYS_TOKEN_EXPIRED', - '令牌过期' + '令牌过期', + # Session过期(正常情况) + 'FAIL_SYS_SESSION_EXPIRED::Session过期', + 'FAIL_SYS_SESSION_EXPIRED', + 'Session过期', + # Token定时刷新失败(会自动重试) + 'Token定时刷新失败,将自动重试', + 'Token定时刷新失败' ] - # 检查错误消息是否包含正常的令牌过期关键词 - for keyword in normal_expiry_keywords: + # 检查错误消息是否包含不需要通知的关键词 + for keyword in no_notification_keywords: if keyword in error_message: return True diff --git a/db_manager.py b/db_manager.py index d6db0d2..cb80516 100644 --- a/db_manager.py +++ b/db_manager.py @@ -49,6 +49,19 @@ class DBManager: logger.info(f"数据库路径: {self.db_path}") self.conn = None self.lock = threading.RLock() # 使用可重入锁保护数据库操作 + + # SQL日志配置 - 默认启用 + self.sql_log_enabled = True # 默认启用SQL日志 + self.sql_log_level = 'INFO' # 默认使用INFO级别 + + # 允许通过环境变量覆盖默认设置 + if os.getenv('SQL_LOG_ENABLED'): + self.sql_log_enabled = os.getenv('SQL_LOG_ENABLED', 'true').lower() == 'true' + if os.getenv('SQL_LOG_LEVEL'): + self.sql_log_level = os.getenv('SQL_LOG_LEVEL', 'INFO').upper() + + logger.info(f"SQL日志已启用,日志级别: {self.sql_log_level}") + self.init_db() def init_db(self): @@ -191,12 +204,12 @@ class DBManager: # 检查并添加 user_id 列(用于数据库迁移) try: - cursor.execute("SELECT user_id FROM cards LIMIT 1") + self._execute_sql(cursor, "SELECT user_id FROM cards LIMIT 1") except sqlite3.OperationalError: # user_id 列不存在,需要添加 logger.info("正在为 cards 表添加 user_id 列...") - cursor.execute("ALTER TABLE cards ADD COLUMN user_id INTEGER NOT NULL DEFAULT 1") - cursor.execute("CREATE INDEX IF NOT EXISTS idx_cards_user_id ON cards(user_id)") + self._execute_sql(cursor, "ALTER TABLE cards ADD COLUMN user_id INTEGER NOT NULL DEFAULT 1") + self._execute_sql(cursor, "CREATE INDEX IF NOT EXISTS idx_cards_user_id ON cards(user_id)") logger.info("cards 表 user_id 列添加完成") # 创建商品信息表 @@ -318,54 +331,54 @@ class DBManager: logger.info("创建默认admin用户,密码: admin123") # 获取admin用户ID,用于历史数据绑定 - cursor.execute("SELECT id FROM users WHERE username = 'admin'") + self._execute_sql(cursor, "SELECT id FROM users WHERE username = 'admin'") admin_user = cursor.fetchone() if admin_user: admin_user_id = admin_user[0] # 将历史cookies数据绑定到admin用户(如果user_id列不存在) try: - cursor.execute("SELECT user_id FROM cookies LIMIT 1") + self._execute_sql(cursor, "SELECT user_id FROM cookies LIMIT 1") except sqlite3.OperationalError: # user_id列不存在,需要添加并更新历史数据 - cursor.execute("ALTER TABLE cookies ADD COLUMN user_id INTEGER") - cursor.execute("UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "ALTER TABLE cookies ADD COLUMN user_id INTEGER") + self._execute_sql(cursor, "UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) else: # user_id列存在,更新NULL值 - cursor.execute("UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) # 为delivery_rules表添加user_id字段(如果不存在) try: - cursor.execute("SELECT user_id FROM delivery_rules LIMIT 1") + self._execute_sql(cursor, "SELECT user_id FROM delivery_rules LIMIT 1") except sqlite3.OperationalError: # user_id列不存在,需要添加并更新历史数据 - cursor.execute("ALTER TABLE delivery_rules ADD COLUMN user_id INTEGER") - cursor.execute("UPDATE delivery_rules SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "ALTER TABLE delivery_rules ADD COLUMN user_id INTEGER") + self._execute_sql(cursor, "UPDATE delivery_rules SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) else: # user_id列存在,更新NULL值 - cursor.execute("UPDATE delivery_rules SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "UPDATE delivery_rules SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) # 为notification_channels表添加user_id字段(如果不存在) try: - cursor.execute("SELECT user_id FROM notification_channels LIMIT 1") + self._execute_sql(cursor, "SELECT user_id FROM notification_channels LIMIT 1") except sqlite3.OperationalError: # user_id列不存在,需要添加并更新历史数据 - cursor.execute("ALTER TABLE notification_channels ADD COLUMN user_id INTEGER") - cursor.execute("UPDATE notification_channels SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "ALTER TABLE notification_channels ADD COLUMN user_id INTEGER") + self._execute_sql(cursor, "UPDATE notification_channels SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) else: # user_id列存在,更新NULL值 - cursor.execute("UPDATE notification_channels SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self._execute_sql(cursor, "UPDATE notification_channels SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) # 为email_verifications表添加type字段(如果不存在) try: - cursor.execute("SELECT type FROM email_verifications LIMIT 1") + self._execute_sql(cursor, "SELECT type FROM email_verifications LIMIT 1") except sqlite3.OperationalError: # type列不存在,需要添加并更新历史数据 - cursor.execute("ALTER TABLE email_verifications ADD COLUMN type TEXT DEFAULT 'register'") - cursor.execute("UPDATE email_verifications SET type = 'register' WHERE type IS NULL") + self._execute_sql(cursor, "ALTER TABLE email_verifications ADD COLUMN type TEXT DEFAULT 'register'") + self._execute_sql(cursor, "UPDATE email_verifications SET type = 'register' WHERE type IS NULL") else: # type列存在,更新NULL值 - cursor.execute("UPDATE email_verifications SET type = 'register' WHERE type IS NULL") + self._execute_sql(cursor, "UPDATE email_verifications SET type = 'register' WHERE type IS NULL") self.conn.commit() logger.info(f"数据库初始化成功: {self.db_path}") @@ -386,6 +399,53 @@ class DBManager: if self.conn is None: self.conn = sqlite3.connect(self.db_path, check_same_thread=False) return self.conn + + def _log_sql(self, sql: str, params: tuple = None, operation: str = "EXECUTE"): + """记录SQL执行日志""" + if not self.sql_log_enabled: + return + + # 格式化参数 + params_str = "" + if params: + if isinstance(params, (list, tuple)): + if len(params) > 0: + # 限制参数长度,避免日志过长 + formatted_params = [] + for param in params: + if isinstance(param, str) and len(param) > 100: + formatted_params.append(f"{param[:100]}...") + else: + formatted_params.append(repr(param)) + params_str = f" | 参数: [{', '.join(formatted_params)}]" + + # 格式化SQL(移除多余空白) + formatted_sql = ' '.join(sql.split()) + + # 根据配置的日志级别输出 + log_message = f"🗄️ SQL {operation}: {formatted_sql}{params_str}" + + if self.sql_log_level == 'DEBUG': + logger.debug(log_message) + elif self.sql_log_level == 'INFO': + logger.info(log_message) + elif self.sql_log_level == 'WARNING': + logger.warning(log_message) + else: + logger.debug(log_message) + + def _execute_sql(self, cursor, sql: str, params: tuple = None): + """执行SQL并记录日志""" + self._log_sql(sql, params, "EXECUTE") + if params: + return cursor.execute(sql, params) + else: + return cursor.execute(sql) + + def _executemany_sql(self, cursor, sql: str, params_list): + """批量执行SQL并记录日志""" + self._log_sql(sql, f"批量执行 {len(params_list)} 条记录", "EXECUTEMANY") + return cursor.executemany(sql, params_list) # -------------------- Cookie操作 -------------------- def save_cookie(self, cookie_id: str, cookie_value: str, user_id: int = None) -> bool: @@ -396,17 +456,17 @@ class DBManager: # 如果没有提供user_id,尝试从现有记录获取,否则使用admin用户ID if user_id is None: - cursor.execute("SELECT user_id FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "SELECT user_id FROM cookies WHERE id = ?", (cookie_id,)) existing = cursor.fetchone() if existing: user_id = existing[0] else: # 获取admin用户ID作为默认值 - cursor.execute("SELECT id FROM users WHERE username = 'admin'") + self._execute_sql(cursor, "SELECT id FROM users WHERE username = 'admin'") admin_user = cursor.fetchone() user_id = admin_user[0] if admin_user else 1 - cursor.execute( + self._execute_sql(cursor, "INSERT OR REPLACE INTO cookies (id, value, user_id) VALUES (?, ?, ?)", (cookie_id, cookie_value, user_id) ) @@ -414,7 +474,7 @@ class DBManager: logger.info(f"Cookie保存成功: {cookie_id} (用户ID: {user_id})") # 验证保存结果 - cursor.execute("SELECT user_id FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "SELECT user_id FROM cookies WHERE id = ?", (cookie_id,)) saved_user_id = cursor.fetchone() if saved_user_id: logger.info(f"Cookie保存验证: {cookie_id} 实际绑定到用户ID: {saved_user_id[0]}") @@ -432,9 +492,9 @@ class DBManager: try: cursor = self.conn.cursor() # 删除关联的关键字 - cursor.execute("DELETE FROM keywords WHERE cookie_id = ?", (cookie_id,)) + self._execute_sql(cursor, "DELETE FROM keywords WHERE cookie_id = ?", (cookie_id,)) # 删除Cookie - cursor.execute("DELETE FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "DELETE FROM cookies WHERE id = ?", (cookie_id,)) self.conn.commit() logger.debug(f"Cookie删除成功: {cookie_id}") return True @@ -448,7 +508,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("SELECT value FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "SELECT value FROM cookies WHERE id = ?", (cookie_id,)) result = cursor.fetchone() return result[0] if result else None except Exception as e: @@ -461,9 +521,9 @@ class DBManager: try: cursor = self.conn.cursor() if user_id is not None: - cursor.execute("SELECT id, value FROM cookies WHERE user_id = ?", (user_id,)) + self._execute_sql(cursor, "SELECT id, value FROM cookies WHERE user_id = ?", (user_id,)) else: - cursor.execute("SELECT id, value FROM cookies") + self._execute_sql(cursor, "SELECT id, value FROM cookies") return {row[0]: row[1] for row in cursor.fetchall()} except Exception as e: logger.error(f"获取所有Cookie失败: {e}") @@ -481,7 +541,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("SELECT id, value, created_at FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "SELECT id, value, created_at FROM cookies WHERE id = ?", (cookie_id,)) result = cursor.fetchone() if result: return { @@ -500,7 +560,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("SELECT id, value, user_id, created_at FROM cookies WHERE id = ?", (cookie_id,)) + self._execute_sql(cursor, "SELECT id, value, user_id, created_at FROM cookies WHERE id = ?", (cookie_id,)) result = cursor.fetchone() if result: return { @@ -522,14 +582,11 @@ class DBManager: cursor = self.conn.cursor() # 先删除该cookie_id的所有关键字 - cursor.execute("DELETE FROM keywords WHERE cookie_id = ?", (cookie_id,)) + self._execute_sql(cursor, "DELETE FROM keywords WHERE cookie_id = ?", (cookie_id,)) # 插入新关键字 for keyword, reply in keywords: - cursor.execute( - "INSERT INTO keywords (cookie_id, keyword, reply) VALUES (?, ?, ?)", - (cookie_id, keyword, reply) - ) + self._execute_sql(cursor, "INSERT INTO keywords (cookie_id, keyword, reply) VALUES (?, ?, ?)", (cookie_id, keyword, reply)) self.conn.commit() logger.info(f"关键字保存成功: {cookie_id}, {len(keywords)}条") @@ -544,10 +601,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute( - "SELECT keyword, reply FROM keywords WHERE cookie_id = ?", - (cookie_id,) - ) + self._execute_sql(cursor, "SELECT keyword, reply FROM keywords WHERE cookie_id = ?", (cookie_id,)) return [(row[0], row[1]) for row in cursor.fetchall()] except Exception as e: logger.error(f"获取关键字失败: {e}") @@ -566,7 +620,7 @@ class DBManager: WHERE c.user_id = ? """, (user_id,)) else: - cursor.execute("SELECT cookie_id, keyword, reply FROM keywords") + self._execute_sql(cursor, "SELECT cookie_id, keyword, reply FROM keywords") result = {} for row in cursor.fetchall(): @@ -796,7 +850,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM default_replies WHERE cookie_id = ?", (cookie_id,)) + self._execute_sql(cursor, "DELETE FROM default_replies WHERE cookie_id = ?", (cookie_id,)) self.conn.commit() logger.debug(f"删除默认回复设置: {cookie_id}") return True @@ -909,7 +963,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM notification_channels WHERE id = ?", (channel_id,)) + self._execute_sql(cursor, "DELETE FROM notification_channels WHERE id = ?", (channel_id,)) self.conn.commit() logger.debug(f"删除通知渠道: {channel_id}") return cursor.rowcount > 0 @@ -1003,7 +1057,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM message_notifications WHERE id = ?", (notification_id,)) + self._execute_sql(cursor, "DELETE FROM message_notifications WHERE id = ?", (notification_id,)) self.conn.commit() logger.debug(f"删除消息通知配置: {notification_id}") return cursor.rowcount > 0 @@ -1017,7 +1071,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM message_notifications WHERE cookie_id = ?", (cookie_id,)) + self._execute_sql(cursor, "DELETE FROM message_notifications WHERE cookie_id = ?", (cookie_id,)) self.conn.commit() logger.debug(f"删除账号通知配置: {cookie_id}") return cursor.rowcount > 0 @@ -1042,7 +1096,7 @@ class DBManager: if user_id is not None: # 用户级备份:只备份该用户的数据 # 备份用户的cookies - cursor.execute("SELECT * FROM cookies WHERE user_id = ?", (user_id,)) + self._execute_sql(cursor, "SELECT * FROM cookies WHERE user_id = ?", (user_id,)) columns = [description[0] for description in cursor.description] rows = cursor.fetchall() backup_data['data']['cookies'] = { @@ -1113,12 +1167,12 @@ class DBManager: # 开始事务 cursor = self.conn.cursor() - cursor.execute("BEGIN TRANSACTION") + self._execute_sql(cursor, "BEGIN TRANSACTION") if user_id is not None: # 用户级导入:只清空该用户的数据 # 获取用户的cookie_id列表 - cursor.execute("SELECT id FROM cookies WHERE user_id = ?", (user_id,)) + self._execute_sql(cursor, "SELECT id FROM cookies WHERE user_id = ?", (user_id,)) user_cookie_ids = [row[0] for row in cursor.fetchall()] if user_cookie_ids: @@ -1132,7 +1186,7 @@ class DBManager: cursor.execute(f"DELETE FROM {table} WHERE cookie_id IN ({placeholders})", user_cookie_ids) # 删除用户的cookies - cursor.execute("DELETE FROM cookies WHERE user_id = ?", (user_id,)) + self._execute_sql(cursor, "DELETE FROM cookies WHERE user_id = ?", (user_id,)) else: # 系统级导入:清空所有数据(除了用户和管理员密码) tables = [ @@ -1145,7 +1199,7 @@ class DBManager: cursor.execute(f"DELETE FROM {table}") # 清空系统设置(保留管理员密码) - cursor.execute("DELETE FROM system_settings WHERE key != 'admin_password_hash'") + self._execute_sql(cursor, "DELETE FROM system_settings WHERE key != 'admin_password_hash'") # 导入数据 data = backup_data['data'] @@ -1199,7 +1253,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("SELECT value FROM system_settings WHERE key = ?", (key,)) + self._execute_sql(cursor, "SELECT value FROM system_settings WHERE key = ?", (key,)) result = cursor.fetchone() return result[0] if result else None except Exception as e: @@ -1228,7 +1282,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("SELECT key, value FROM system_settings") + self._execute_sql(cursor, "SELECT key, value FROM system_settings") settings = {} for row in cursor.fetchall(): @@ -1759,7 +1813,7 @@ class DBManager: params.append(card_id) sql = f"UPDATE cards SET {', '.join(update_fields)} WHERE id = ?" - cursor.execute(sql, params) + self._execute_sql(cursor, sql, params) if cursor.rowcount > 0: self.conn.commit() @@ -1896,19 +1950,29 @@ class DBManager: logger.error(f"根据关键字获取发货规则失败: {e}") return [] - def get_delivery_rule_by_id(self, rule_id: int): - """根据ID获取发货规则""" + def get_delivery_rule_by_id(self, rule_id: int, user_id: int = None): + """根据ID获取发货规则(支持用户隔离)""" with self.lock: try: cursor = self.conn.cursor() - cursor.execute(''' - SELECT dr.id, dr.keyword, dr.card_id, dr.delivery_count, dr.enabled, - dr.description, dr.delivery_times, dr.created_at, dr.updated_at, - c.name as card_name, c.type as card_type - FROM delivery_rules dr - LEFT JOIN cards c ON dr.card_id = c.id - WHERE dr.id = ? - ''', (rule_id,)) + if user_id is not None: + self._execute_sql(cursor, ''' + SELECT dr.id, dr.keyword, dr.card_id, dr.delivery_count, dr.enabled, + dr.description, dr.delivery_times, dr.created_at, dr.updated_at, + c.name as card_name, c.type as card_type + FROM delivery_rules dr + LEFT JOIN cards c ON dr.card_id = c.id + WHERE dr.id = ? AND dr.user_id = ? + ''', (rule_id, user_id)) + else: + self._execute_sql(cursor, ''' + SELECT dr.id, dr.keyword, dr.card_id, dr.delivery_count, dr.enabled, + dr.description, dr.delivery_times, dr.created_at, dr.updated_at, + c.name as card_name, c.type as card_type + FROM delivery_rules dr + LEFT JOIN cards c ON dr.card_id = c.id + WHERE dr.id = ? + ''', (rule_id,)) row = cursor.fetchone() if row: @@ -1932,8 +1996,8 @@ class DBManager: def update_delivery_rule(self, rule_id: int, keyword: str = None, card_id: int = None, delivery_count: int = None, enabled: bool = None, - description: str = None): - """更新发货规则""" + description: str = None, user_id: int = None): + """更新发货规则(支持用户隔离)""" with self.lock: try: cursor = self.conn.cursor() @@ -1964,8 +2028,13 @@ class DBManager: update_fields.append("updated_at = CURRENT_TIMESTAMP") params.append(rule_id) - sql = f"UPDATE delivery_rules SET {', '.join(update_fields)} WHERE id = ?" - cursor.execute(sql, params) + if user_id is not None: + params.append(user_id) + sql = f"UPDATE delivery_rules SET {', '.join(update_fields)} WHERE id = ? AND user_id = ?" + else: + sql = f"UPDATE delivery_rules SET {', '.join(update_fields)} WHERE id = ?" + + self._execute_sql(cursor, sql, params) if cursor.rowcount > 0: self.conn.commit() @@ -1999,7 +2068,7 @@ class DBManager: with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM cards WHERE id = ?", (card_id,)) + self._execute_sql(cursor, "DELETE FROM cards WHERE id = ?", (card_id,)) if cursor.rowcount > 0: self.conn.commit() @@ -2013,16 +2082,19 @@ class DBManager: self.conn.rollback() raise - def delete_delivery_rule(self, rule_id: int): - """删除发货规则""" + def delete_delivery_rule(self, rule_id: int, user_id: int = None): + """删除发货规则(支持用户隔离)""" with self.lock: try: cursor = self.conn.cursor() - cursor.execute("DELETE FROM delivery_rules WHERE id = ?", (rule_id,)) + if user_id is not None: + self._execute_sql(cursor, "DELETE FROM delivery_rules WHERE id = ? AND user_id = ?", (rule_id, user_id)) + else: + self._execute_sql(cursor, "DELETE FROM delivery_rules WHERE id = ?", (rule_id,)) if cursor.rowcount > 0: self.conn.commit() - logger.info(f"删除发货规则成功: ID {rule_id}") + logger.info(f"删除发货规则成功: ID {rule_id} (用户ID: {user_id})") return True else: return False # 没有找到对应的记录 @@ -2039,7 +2111,7 @@ class DBManager: cursor = self.conn.cursor() # 获取卡券的批量数据 - cursor.execute("SELECT data_content FROM cards WHERE id = ? AND type = 'data'", (card_id,)) + self._execute_sql(cursor, "SELECT data_content FROM cards WHERE id = ? AND type = 'data'", (card_id,)) result = cursor.fetchone() if not result or not result[0]: @@ -2145,7 +2217,7 @@ class DBManager: params.extend([cookie_id, item_id]) sql = f"UPDATE item_info SET {', '.join(update_parts)} WHERE cookie_id = ? AND item_id = ?" - cursor.execute(sql, params) + self._execute_sql(cursor, sql, params) if cursor.rowcount > 0: logger.info(f"更新商品基本信息: {item_id} - {item_title}") @@ -2483,7 +2555,7 @@ class DBManager: updated_at = CURRENT_TIMESTAMP WHERE cookie_id = ? AND item_id = ? ''' - cursor.execute(update_sql, ( + self._execute_sql(cursor, update_sql, ( item_title, item_title, item_description, item_description, item_category, item_category, diff --git a/docker-compose.yml b/docker-compose.yml index bf2b93e..64d4b60 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,9 @@ services: - LOG_LEVEL=${LOG_LEVEL:-INFO} - DEBUG=${DEBUG:-false} - RELOAD=${RELOAD:-false} + # SQL日志配置(默认启用,可通过环境变量覆盖) + - SQL_LOG_ENABLED=${SQL_LOG_ENABLED:-true} + - SQL_LOG_LEVEL=${SQL_LOG_LEVEL:-INFO} - ADMIN_USERNAME=${ADMIN_USERNAME:-admin} - ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin123} - JWT_SECRET_KEY=${JWT_SECRET_KEY:-default-secret-key} diff --git a/reply_server.py b/reply_server.py index bc28d8d..53ebc85 100644 --- a/reply_server.py +++ b/reply_server.py @@ -2271,11 +2271,13 @@ def download_database_backup(admin_user: Dict[str, Any] = Depends(require_admin) try: log_with_user('info', "请求下载数据库备份", admin_user) - db_file_path = 'xianyu_data.db' + # 使用db_manager的实际数据库路径 + from db_manager import db_manager + db_file_path = db_manager.db_path # 检查数据库文件是否存在 if not os.path.exists(db_file_path): - log_with_user('error', "数据库文件不存在", admin_user) + log_with_user('error', f"数据库文件不存在: {db_file_path}", admin_user) raise HTTPException(status_code=404, detail="数据库文件不存在") # 生成带时间戳的文件名 @@ -2352,25 +2354,29 @@ async def upload_database_backup(admin_user: Dict[str, Any] = Depends(require_ad raise HTTPException(status_code=400, detail="无效的数据库文件") # 备份当前数据库 - current_db_path = 'xianyu_data.db' - backup_current_path = f"xianyu_data_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.db" + from db_manager import db_manager + current_db_path = db_manager.db_path + + # 生成备份文件路径(与原数据库在同一目录) + db_dir = os.path.dirname(current_db_path) + backup_filename = f"xianyu_data_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.db" + backup_current_path = os.path.join(db_dir, backup_filename) if os.path.exists(current_db_path): shutil.copy2(current_db_path, backup_current_path) log_with_user('info', f"当前数据库已备份为: {backup_current_path}", admin_user) # 关闭当前数据库连接 - from db_manager import db_manager if hasattr(db_manager, 'conn') and db_manager.conn: db_manager.conn.close() log_with_user('info', "已关闭当前数据库连接", admin_user) # 替换数据库文件 shutil.move(temp_file_path, current_db_path) - log_with_user('info', "数据库文件已替换", admin_user) + log_with_user('info', f"数据库文件已替换: {current_db_path}", admin_user) - # 重新初始化数据库连接 - db_manager.__init__() + # 重新初始化数据库连接(使用原有的db_path) + db_manager.__init__(db_manager.db_path) log_with_user('info', "数据库连接已重新初始化", admin_user) # 验证新数据库