#!/usr/bin/env python3 """ 彩票数据分析系统启动脚本 """ import os import sys import subprocess import time import requests from pathlib import Path def check_python_version(): """检查Python版本""" if sys.version_info < (3, 8): print("❌ 错误: 需要Python 3.8或更高版本") print(f"当前版本: {sys.version}") return False print(f"✅ Python版本检查通过: {sys.version}") return True def check_dependencies(): """检查依赖是否安装""" try: import fastapi import uvicorn import sqlalchemy import pandas import requests print("✅ 后端依赖检查通过") return True except ImportError as e: print(f"❌ 后端依赖缺失: {e}") print("请运行: cd backend && pip install -r requirements.txt") return False def start_backend(): """启动后端服务""" print("\n🚀 启动后端服务...") backend_dir = Path("backend") if not backend_dir.exists(): print("❌ 错误: 找不到backend目录") return False try: # 切换到backend目录 os.chdir(backend_dir) # 启动后端服务 print("📝 启动命令: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload") process = subprocess.Popen([ sys.executable, "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # 等待服务启动 print("⏳ 等待后端服务启动...") time.sleep(8) # 增加等待时间 # 检查服务是否启动成功 try: response = requests.get("http://localhost:8000/", timeout=10) if response.status_code == 200: print("✅ 后端服务启动成功") print("📊 API文档地址: http://localhost:8000/docs") return process else: print(f"❌ 后端服务启动失败,状态码: {response.status_code}") # 检查进程输出 stdout, stderr = process.communicate(timeout=1) if stderr: print(f"错误输出: {stderr}") return False except requests.exceptions.RequestException as e: print(f"❌ 后端服务启动失败,无法连接到服务: {e}") # 检查进程是否还在运行 if process.poll() is None: print("⚠️ 进程仍在运行,可能是数据库连接问题") # 检查进程输出 try: stdout, stderr = process.communicate(timeout=2) if stderr: print(f"错误输出: {stderr}") if stdout: print(f"标准输出: {stdout}") except subprocess.TimeoutExpired: process.kill() print("⚠️ 进程被强制终止") else: print(f"⚠️ 进程已退出,退出码: {process.returncode}") return False except Exception as e: print(f"❌ 启动后端服务时出错: {e}") return False def start_frontend(original_dir): """启动前端服务""" print("\n🚀 启动前端服务...") # 确保回到根目录 os.chdir(original_dir) frontend_dir = Path("frontend") if not frontend_dir.exists(): print("❌ 错误: 找不到frontend目录") return False try: # 切换到frontend目录 os.chdir(frontend_dir) # 检查node_modules是否存在 if not Path("node_modules").exists(): print("📦 安装前端依赖...") subprocess.run(["npm", "install"], check=True) # 启动前端服务 print("📝 启动命令: npm run dev") process = subprocess.Popen([ "npm", "run", "dev" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # 等待服务启动 print("⏳ 等待前端服务启动...") time.sleep(10) # 增加等待时间 # 检查服务是否启动成功 try: response = requests.get("http://localhost:5173/", timeout=10) if response.status_code == 200: print("✅ 前端服务启动成功") print("🌐 前端地址: http://localhost:5173") return process else: print(f"❌ 前端服务启动失败,状态码: {response.status_code}") # 检查进程输出 stdout, stderr = process.communicate(timeout=1) if stderr: print(f"错误输出: {stderr}") return False except requests.exceptions.RequestException as e: print(f"❌ 前端服务启动失败,无法连接到服务: {e}") # 检查进程是否还在运行 if process.poll() is None: print("⚠️ 进程仍在运行,可能是端口被占用") # 检查进程输出 try: stdout, stderr = process.communicate(timeout=2) if stderr: print(f"错误输出: {stderr}") if stdout: print(f"标准输出: {stdout}") except subprocess.TimeoutExpired: process.kill() print("⚠️ 进程被强制终止") else: print(f"⚠️ 进程已退出,退出码: {process.returncode}") return False except Exception as e: print(f"❌ 启动前端服务时出错: {e}") return False def check_database_connection(): """检查数据库连接""" print("\n🔍 检查数据库连接...") try: import pymysql from backend.app.core.database import SQLALCHEMY_DATABASE_URL # 解析数据库URL if SQLALCHEMY_DATABASE_URL.startswith("mysql+pymysql://"): # 提取连接信息 url_parts = SQLALCHEMY_DATABASE_URL.replace( "mysql+pymysql://", "").split("@") if len(url_parts) == 2: credentials = url_parts[0] host_port_db = url_parts[1] username, password = credentials.split(":") host_port, database = host_port_db.split("/") host, port = host_port.split(":") print(f"📊 数据库信息:") print(f" 主机: {host}") print(f" 端口: {port}") print(f" 数据库: {database}") print(f" 用户: {username}") # 尝试连接数据库 try: connection = pymysql.connect( host=host, port=int(port), user=username, password=password, database=database, connect_timeout=10 ) connection.close() print("✅ 数据库连接成功") return True except Exception as e: print(f"❌ 数据库连接失败: {e}") print("💡 请检查:") print(" 1. 数据库服务器是否运行") print(" 2. 网络连接是否正常") print(" 3. 数据库凭据是否正确") return False else: print("❌ 数据库URL格式错误") return False else: print("❌ 不支持的数据库类型") return False except ImportError: print("❌ 缺少pymysql依赖") return False except Exception as e: print(f"❌ 检查数据库连接时出错: {e}") return False def main(): """主函数""" print("🎯 彩票数据分析系统启动器") print("=" * 50) # 检查Python版本 if not check_python_version(): return # 检查依赖 if not check_dependencies(): return # 检查数据库连接 if not check_database_connection(): print("\n💡 建议:") print("1. 检查数据库服务器是否正常运行") print("2. 确认网络连接是否正常") print("3. 验证数据库凭据是否正确") print("4. 如果使用本地数据库,请修改 backend/app/core/database.py 中的配置") response = input("\n是否继续启动系统?(y/N): ") if response.lower() != 'y': print("❌ 用户取消启动") return # 保存当前目录 original_dir = os.getcwd() try: # 启动后端 backend_process = start_backend() if not backend_process: print("\n💡 后端启动失败,可能的原因:") print("1. 数据库连接问题") print("2. 端口8000被占用") print("3. 依赖包缺失") print("4. 代码错误") print("\n请检查后端日志获取详细错误信息") return # 启动前端 frontend_process = start_frontend(original_dir) if not frontend_process: backend_process.terminate() print("\n💡 前端启动失败,可能的原因:") print("1. Node.js未安装或版本过低") print("2. 端口5173被占用") print("3. 依赖包缺失") print("\n请检查前端日志获取详细错误信息") return print("\n🎉 系统启动成功!") print("=" * 50) print("📊 后端API: http://localhost:8000") print("📊 API文档: http://localhost:8000/docs") print("🌐 前端界面: http://localhost:5173") print("=" * 50) print("💡 使用说明:") print("1. 打开浏览器访问 http://localhost:5173") print("2. 在首页点击'更新数据'按钮获取最新开奖信息") print("3. 使用各种分析功能进行数据分析") print("=" * 50) print("按 Ctrl+C 停止服务") # 等待用户中断 try: while True: time.sleep(1) except KeyboardInterrupt: print("\n🛑 正在停止服务...") backend_process.terminate() frontend_process.terminate() print("✅ 服务已停止") except Exception as e: print(f"❌ 启动过程中出错: {e}") finally: # 恢复原始目录 os.chdir(original_dir) if __name__ == "__main__": main()