#!/usr/bin/env python3 """ AI Chat App - 后台管理服务 端口: 19020 (与前端同一端口) """ from flask import Flask, jsonify, request, send_from_directory from flask_cors import CORS import os import json import sqlite3 from datetime import datetime import hashlib app = Flask(__name__, static_folder='../www') CORS(app) # 数据库路径 DB_PATH = os.path.join(os.path.dirname(__file__), 'data.db') # 管理员账户(默认) ADMIN_USERNAME = 'admin' ADMIN_PASSWORD_HASH = hashlib.sha256('admin123'.encode()).hexdigest() def get_db(): """获取数据库连接""" conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row return conn def init_db(): """初始化数据库""" conn = get_db() cursor = conn.cursor() # 大模型接口配置表 cursor.execute(''' CREATE TABLE IF NOT EXISTS llm_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, provider TEXT NOT NULL, api_url TEXT NOT NULL, api_key TEXT NOT NULL, model TEXT NOT NULL, max_tokens INTEGER DEFAULT 2048, temperature REAL DEFAULT 0.7, is_default INTEGER DEFAULT 0, is_active INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 智能体配置表 cursor.execute(''' CREATE TABLE IF NOT EXISTS agents ( id INTEGER PRIMARY KEY AUTOINCREMENT, agent_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, avatar TEXT DEFAULT '🤖', category TEXT NOT NULL, description TEXT, system_prompt TEXT NOT NULL, llm_config_id INTEGER, temperature REAL DEFAULT 0.7, max_tokens INTEGER DEFAULT 2048, enable_tools TEXT, tags TEXT, heat INTEGER DEFAULT 0, is_online INTEGER DEFAULT 1, is_active INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (llm_config_id) REFERENCES llm_configs(id) ) ''') # 搜索配置表(改为工具配置) cursor.execute(''' CREATE TABLE IF NOT EXISTS tool_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, tool_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, type TEXT NOT NULL, provider TEXT NOT NULL, api_url TEXT NOT NULL, api_key TEXT, config_json TEXT, max_results INTEGER DEFAULT 10, is_default INTEGER DEFAULT 0, is_active INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 对话配置表 cursor.execute(''' CREATE TABLE IF NOT EXISTS chat_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, config_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, llm_config_id INTEGER, enable_search INTEGER DEFAULT 1, enable_tools TEXT, max_history INTEGER DEFAULT 20, temperature REAL DEFAULT 0.7, system_prompt TEXT, is_default INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (llm_config_id) REFERENCES llm_configs(id) ) ''') # 系统配置表 cursor.execute(''' CREATE TABLE IF NOT EXISTS system_configs ( key TEXT PRIMARY KEY, value TEXT, description TEXT, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 统计日志表 cursor.execute(''' CREATE TABLE IF NOT EXISTS stats_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, log_type TEXT NOT NULL, log_key TEXT NOT NULL, log_value INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 用户表(后台管理) cursor.execute(''' CREATE TABLE IF NOT EXISTS admin_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, role TEXT DEFAULT 'admin', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 初始化默认大模型配置 cursor.execute('SELECT COUNT(*) FROM llm_configs') if cursor.fetchone()[0] == 0: cursor.execute(''' INSERT INTO llm_configs (name, provider, api_url, api_key, model, is_default) VALUES ('智谱GLM', 'zhipu', 'https://open.bigmodel.cn/api/paas/v4/chat/completions', '2259e33a1357460abe17919aaf81e73d.K44a8LPQTmFM5PKm', 'glm-4.5-air', 1) ''') # 初始化默认工具配置(搜索工具) cursor.execute('SELECT COUNT(*) FROM tool_configs') if cursor.fetchone()[0] == 0: cursor.execute(''' INSERT INTO tool_configs (tool_id, name, type, provider, api_url, api_key, max_results, is_default) VALUES ('search', '联网搜索', 'search', 'tavily', 'https://api.tavily.com/search', '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', 10, 1) ''') # 初始化默认对话配置 cursor.execute('SELECT COUNT(*) FROM chat_configs') if cursor.fetchone()[0] == 0: cursor.execute(''' INSERT INTO chat_configs (config_id, name, llm_config_id, enable_tools, is_default) VALUES ('default', '默认对话配置', 1, 'search', 1) ''') # 初始化默认智能体 cursor.execute('SELECT COUNT(*) FROM agents') if cursor.fetchone()[0] == 0: default_agents = [ # 基础类别 ('assistant', '通用助手', '🤖', 'basic', '能回答各类问题,帮助写作、分析、解答疑惑', '你是一个智能助手,能够回答各类问题,帮助用户解决问题。', 'hot', 9500), ('writer', '写作助手', '✍️', 'basic', '专注于文章写作、文案创作、内容润色', '你是一个专业的写作助手,擅长各类文章写作、文案创作和内容润色。', 'hot', 8800), ('coder', '编程助手', '👨‍💻', 'basic', '精通编程语言,解答技术问题,生成代码', '你是一个专业的编程助手,精通各类编程语言,能够解答技术问题并生成高质量代码。', 'hot', 8500), ('translator', '翻译助手', '🌐', 'basic', '多语言翻译,精准表达,文化适配', '你是一个专业的翻译助手,精通多语言翻译,能够精准表达并适配文化差异。', 'hot', 7200), # 工作类别 ('work', '工作助手', '💼', 'work', '职场问题解答,工作效率提升', '你是一个工作助手,帮助解决职场问题,提升工作效率。', 'popular', 5000), ('ppt', 'PPT助手', '📊', 'work', 'PPT内容生成,结构优化,设计建议', '你是一个PPT助手,擅长PPT内容生成、结构优化和设计建议。', 'popular', 4500), ('excel', 'Excel助手', '📈', 'work', 'Excel公式、数据分析、表格优化', '你是一个Excel助手,精通Excel公式、数据分析和表格优化。', '', 4000), # 学习类别 ('teacher', '学习助手', '📚', 'study', '知识讲解,学习方法,考试辅导', '你是一个学习助手,擅长知识讲解、学习方法指导和考试辅导。', 'popular', 5500), ('english', '英语助手', '🔤', 'study', '英语学习,语法纠正,口语练习', '你是一个英语助手,帮助英语学习、语法纠正和口语练习。', '', 5000), ('math', '数学助手', '🔢', 'study', '数学解题,公式推导,概念讲解', '你是一个数学助手,擅长数学解题、公式推导和概念讲解。', '', 4500), # 生活类别 ('health', '健康助手', '🏥', 'life', '健康咨询,养生建议,运动指导', '你是一个健康助手,提供健康咨询、养生建议和运动指导。', '', 3500), ('travel', '旅行助手', '✈️', 'life', '旅行规划,景点推荐,美食指南', '你是一个旅行助手,擅长旅行规划、景点推荐和美食指南。', 'popular', 3200), ('food', '美食助手', '🍳', 'life', '菜谱推荐,烹饪技巧,营养搭配', '你是一个美食助手,提供菜谱推荐、烹饪技巧和营养搭配建议。', '', 3000), ] for agent in default_agents: cursor.execute(''' INSERT INTO agents (agent_id, name, avatar, category, description, system_prompt, tags, heat, is_online) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1) ''', agent) # 初始化系统配置 cursor.execute('SELECT COUNT(*) FROM system_configs') if cursor.fetchone()[0] == 0: default_configs = [ ('app_name', 'AI助手', '应用名称'), ('app_version', '3.5.1', '应用版本'), ('llm_provider', 'zhipu', '默认大模型提供商'), ('enable_search', 'true', '是否启用联网搜索'), ('guest_chat_sessions', '1', '游客每日对话会话限制'), ('guest_chat_messages', '20', '游客每日对话消息限制'), ('guest_agent_messages', '20', '游客每日智能体消息限制'), ('admin_password', 'admin123', '管理员密码'), ] for key, value, desc in default_configs: cursor.execute('INSERT INTO system_configs (key, value, description) VALUES (?, ?, ?)', (key, value, desc)) # 初始化管理员账户 cursor.execute('SELECT COUNT(*) FROM admin_users') if cursor.fetchone()[0] == 0: cursor.execute('INSERT INTO admin_users (username, password_hash) VALUES (?, ?)', (ADMIN_USERNAME, ADMIN_PASSWORD_HASH)) conn.commit() conn.close() # ==================== 前端静态文件服务 ==================== @app.route('/') def index(): """前端首页""" return send_from_directory(app.static_folder, 'index.html') @app.route('/admin') def admin(): """后台管理页面""" return send_from_directory(app.static_folder, 'admin.html') @app.route('/admin/') def admin_static(path): """后台管理静态文件""" return send_from_directory(app.static_folder, path) @app.route('/') def static_files(path): """前端静态文件""" return send_from_directory(app.static_folder, path) # ==================== 后台管理 API ==================== # 管理员登录验证 def check_admin_auth(): """检查管理员权限""" auth = request.authorization if not auth: return False password_hash = hashlib.sha256(auth.password.encode()).hexdigest() conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM admin_users WHERE username = ? AND password_hash = ?', (auth.username, password_hash)) user = cursor.fetchone() conn.close() return user is not None @app.route('/api/admin/login', methods=['POST']) def admin_login(): """管理员登录""" data = request.json username = data.get('username') password = data.get('password') if not username or not password: return jsonify({'error': '请输入用户名和密码'}), 400 password_hash = hashlib.sha256(password.encode()).hexdigest() conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM admin_users WHERE username = ? AND password_hash = ?', (username, password_hash)) user = cursor.fetchone() conn.close() if user: return jsonify({'success': True, 'message': '登录成功'}) else: return jsonify({'error': '用户名或密码错误'}), 401 # ==================== 大模型接口管理 ==================== @app.route('/api/admin/llm', methods=['GET']) def get_llm_configs(): """获取所有大模型配置""" conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM llm_configs ORDER BY is_default DESC, created_at DESC') configs = [dict(row) for row in cursor.fetchall()] conn.close() return jsonify(configs) @app.route('/api/admin/llm', methods=['POST']) def add_llm_config(): """添加大模型配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' INSERT INTO llm_configs (name, provider, api_url, api_key, model, max_tokens, temperature) VALUES (?, ?, ?, ?, ?, ?, ?) ''', (data['name'], data['provider'], data['api_url'], data['api_key'], data['model'], data.get('max_tokens', 2048), data.get('temperature', 0.7))) conn.commit() config_id = cursor.lastrowid conn.close() return jsonify({'success': True, 'id': config_id}) @app.route('/api/admin/llm/', methods=['PUT']) def update_llm_config(id): """更新大模型配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' UPDATE llm_configs SET name=?, provider=?, api_url=?, api_key=?, model=?, max_tokens=?, temperature=?, updated_at=CURRENT_TIMESTAMP WHERE id=? ''', (data['name'], data['provider'], data['api_url'], data['api_key'], data['model'], data.get('max_tokens', 2048), data.get('temperature', 0.7), id)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/llm/', methods=['DELETE']) def delete_llm_config(id): """删除大模型配置""" conn = get_db() cursor = conn.cursor() cursor.execute('DELETE FROM llm_configs WHERE id=?', (id,)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/llm//default', methods=['POST']) def set_default_llm(id): """设置默认大模型""" conn = get_db() cursor = conn.cursor() cursor.execute('UPDATE llm_configs SET is_default=0') cursor.execute('UPDATE llm_configs SET is_default=1 WHERE id=?', (id,)) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 智能体管理 ==================== @app.route('/api/admin/agents', methods=['GET']) def get_agents(): """获取所有智能体""" conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM agents ORDER BY category, heat DESC') agents = [dict(row) for row in cursor.fetchall()] conn.close() return jsonify(agents) @app.route('/api/admin/agents', methods=['POST']) def add_agent(): """添加智能体""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' INSERT INTO agents (agent_id, name, avatar, category, description, system_prompt, llm_config_id, temperature, max_tokens, enable_tools, tags, heat, is_online) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''', (data['agent_id'], data['name'], data.get('avatar', '🤖'), data['category'], data.get('description', ''), data['system_prompt'], data.get('llm_config_id'), data.get('temperature', 0.7), data.get('max_tokens', 2048), data.get('enable_tools', ''), data.get('tags', ''), data.get('heat', 0), data.get('is_online', 1))) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/agents/', methods=['PUT']) def update_agent(agent_id): """更新智能体""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' UPDATE agents SET name=?, avatar=?, category=?, description=?, system_prompt=?, llm_config_id=?, temperature=?, max_tokens=?, enable_tools=?, tags=?, heat=?, is_online=?, updated_at=CURRENT_TIMESTAMP WHERE agent_id=? ''', (data['name'], data.get('avatar', '🤖'), data['category'], data.get('description', ''), data['system_prompt'], data.get('llm_config_id'), data.get('temperature', 0.7), data.get('max_tokens', 2048), data.get('enable_tools', ''), data.get('tags', ''), data.get('heat', 0), data.get('is_online', 1), agent_id)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/agents/', methods=['DELETE']) def delete_agent(agent_id): """删除智能体""" conn = get_db() cursor = conn.cursor() cursor.execute('DELETE FROM agents WHERE agent_id=?', (agent_id,)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/agents//online', methods=['POST']) def toggle_agent_online(agent_id): """切换智能体上线状态""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute('UPDATE agents SET is_online=?, updated_at=CURRENT_TIMESTAMP WHERE agent_id=?', (data.get('is_online', 1), agent_id)) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 对话配置管理 ==================== @app.route('/api/admin/chat', methods=['GET']) def get_chat_config(): """获取对话配置(只有一个默认配置)""" conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM chat_configs WHERE is_default=1 LIMIT 1') config = cursor.fetchone() if not config: # 如果没有配置,创建默认配置 cursor.execute(''' INSERT INTO chat_configs (config_id, name, llm_config_id, enable_search, enable_tools, max_history, temperature, is_default) VALUES ('default', '默认配置', 1, 1, 'search', 20, 0.7, 1) ''') conn.commit() cursor.execute('SELECT * FROM chat_configs WHERE is_default=1 LIMIT 1') config = cursor.fetchone() conn.close() return jsonify(dict(config) if config else {}) @app.route('/api/admin/chat', methods=['PUT']) def update_chat_config(): """更新对话配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' UPDATE chat_configs SET llm_config_id=?, enable_search=?, enable_tools=?, max_history=?, temperature=?, system_prompt=?, updated_at=CURRENT_TIMESTAMP WHERE is_default=1 ''', (data.get('llm_config_id', 1), data.get('enable_search', 1), data.get('enable_tools', 'search'), data.get('max_history', 20), data.get('temperature', 0.7), data.get('system_prompt', ''))) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 工具配置管理 ==================== @app.route('/api/admin/tools', methods=['GET']) def get_tool_configs(): """获取工具配置""" conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM tool_configs ORDER BY is_default DESC, type') tools = [dict(row) for row in cursor.fetchall()] conn.close() return jsonify(tools) @app.route('/api/admin/tools', methods=['POST']) def add_tool_config(): """添加工具配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' INSERT INTO tool_configs (tool_id, name, type, provider, api_url, api_key, config_json, max_results) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', (data['tool_id'], data['name'], data['type'], data['provider'], data['api_url'], data.get('api_key', ''), data.get('config_json', ''), data.get('max_results', 10))) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/tools/', methods=['PUT']) def update_tool_config(tool_id): """更新工具配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' UPDATE tool_configs SET name=?, type=?, provider=?, api_url=?, api_key=?, config_json=?, max_results=?, updated_at=CURRENT_TIMESTAMP WHERE tool_id=? ''', (data['name'], data['type'], data['provider'], data['api_url'], data.get('api_key', ''), data.get('config_json', ''), data.get('max_results', 10), tool_id)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/tools/', methods=['DELETE']) def delete_tool_config(tool_id): """删除工具配置""" conn = get_db() cursor = conn.cursor() cursor.execute('DELETE FROM tool_configs WHERE tool_id=?', (tool_id,)) conn.commit() conn.close() return jsonify({'success': True}) @app.route('/api/admin/tools//default', methods=['POST']) def set_default_tool(tool_id): """设置默认工具""" conn = get_db() cursor = conn.cursor() cursor.execute('UPDATE tool_configs SET is_default=0 WHERE type=(SELECT type FROM tool_configs WHERE tool_id=?)', (tool_id,)) cursor.execute('UPDATE tool_configs SET is_default=1 WHERE tool_id=?', (tool_id,)) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 系统配置管理 ==================== @app.route('/api/admin/system', methods=['GET']) def get_system_configs(): """获取系统配置""" conn = get_db() cursor = conn.cursor() cursor.execute('SELECT * FROM system_configs') configs = {row['key']: {'value': row['value'], 'description': row['description']} for row in cursor.fetchall()} conn.close() return jsonify(configs) @app.route('/api/admin/system', methods=['POST']) def update_system_config(): """更新系统配置""" data = request.json conn = get_db() cursor = conn.cursor() for key, value in data.items(): cursor.execute(''' UPDATE system_configs SET value=?, updated_at=CURRENT_TIMESTAMP WHERE key=? ''', (value, key)) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 统计信息 ==================== @app.route('/api/admin/stats', methods=['GET']) def get_stats(): """获取统计信息""" conn = get_db() cursor = conn.cursor() # 今日统计 today = datetime.now().strftime('%Y-%m-%d') # 各类型统计 stats = {} # LLM调用统计 cursor.execute('SELECT SUM(log_value) FROM stats_logs WHERE log_type="llm_call"') stats['llm_total_calls'] = cursor.fetchone()[0] or 0 cursor.execute('SELECT SUM(log_value) FROM stats_logs WHERE log_type="llm_call" AND created_at >= ?', (today,)) stats['llm_today_calls'] = cursor.fetchone()[0] or 0 # 搜索统计 cursor.execute('SELECT SUM(log_value) FROM stats_logs WHERE log_type="search_call"') stats['search_total_calls'] = cursor.fetchone()[0] or 0 cursor.execute('SELECT SUM(log_value) FROM stats_logs WHERE log_type="search_call" AND created_at >= ?', (today,)) stats['search_today_calls'] = cursor.fetchone()[0] or 0 # 智能体使用统计 cursor.execute(''' SELECT log_key, SUM(log_value) as count FROM stats_logs WHERE log_type="agent_use" GROUP BY log_key ORDER BY count DESC LIMIT 10 ''') stats['agent_usage'] = [dict(row) for row in cursor.fetchall()] # 用户统计 cursor.execute('SELECT COUNT(*) FROM stats_logs WHERE log_type="user_register"') stats['total_users'] = cursor.fetchone()[0] or 0 # 智能体数量 cursor.execute('SELECT COUNT(*) FROM agents WHERE is_active=1') stats['agent_count'] = cursor.fetchone()[0] # LLM配置数量 cursor.execute('SELECT COUNT(*) FROM llm_configs WHERE is_active=1') stats['llm_count'] = cursor.fetchone()[0] conn.close() return jsonify(stats) @app.route('/api/admin/stats/log', methods=['POST']) def log_stats(): """记录统计日志""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute('INSERT INTO stats_logs (log_type, log_key, log_value) VALUES (?, ?, ?)', (data['type'], data.get('key', ''), data.get('value', 1))) conn.commit() conn.close() return jsonify({'success': True}) # ==================== 前端配置获取 ==================== @app.route('/api/config', methods=['GET']) def get_frontend_config(): """获取前端使用的配置""" conn = get_db() cursor = conn.cursor() # 获取默认LLM配置 cursor.execute('SELECT * FROM llm_configs WHERE is_default=1 AND is_active=1 LIMIT 1') llm = cursor.fetchone() # 获取默认工具配置(搜索等) cursor.execute('SELECT * FROM tool_configs WHERE is_default=1 AND is_active=1') tools = [dict(row) for row in cursor.fetchall()] # 获取所有智能体(上线且活跃) cursor.execute('SELECT agent_id, name, avatar, category, description, system_prompt, heat, tags, enable_tools FROM agents WHERE is_online=1 AND is_active=1') agents = [dict(row) for row in cursor.fetchall()] # 获取默认对话配置 cursor.execute('SELECT * FROM chat_configs WHERE is_default=1 LIMIT 1') chat_config = cursor.fetchone() # 获取系统配置 cursor.execute('SELECT key, value FROM system_configs') system = {row['key']: row['value'] for row in cursor.fetchall()} conn.close() config = { 'llm': dict(llm) if llm else None, 'tools': tools, 'agents': agents, 'chat_config': dict(chat_config) if chat_config else None, 'system': { 'appName': system.get('app_name', 'AI助手'), 'version': system.get('app_version', '3.6.0'), 'enableSearch': system.get('enable_search', 'true') == 'true', 'guestLimits': { 'chatSessions': int(system.get('guest_chat_sessions', '1')), 'chatMessages': int(system.get('guest_chat_messages', '20')), 'agentMessages': int(system.get('guest_agent_messages', '20')), } } } return jsonify(config) # ==================== 启动 ==================== if __name__ == '__main__': # 初始化数据库 init_db() # 启动服务 print('🚀 AI Chat App Backend started on http://localhost:19021') print('📊 Admin Panel: http://localhost:19021/admin') print('👤 Default admin: admin / admin123') app.run(host='0.0.0.0', port=19021, debug=True)