mottery/start_system.py

388 lines
13 KiB
Python

#!/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
import schedule
print("✅ 后端依赖检查通过")
return True
except ImportError as e:
print(f"❌ 后端依赖缺失: {e}")
print("请运行: cd backend && pip install -r requirements.txt")
return False
def start_scheduler():
"""启动定时任务调度器"""
print("\n⏰ 启动定时任务调度器...")
backend_dir = Path("backend")
if not backend_dir.exists():
print("❌ 错误: 找不到backend目录")
return False
try:
# 切换到backend目录
os.chdir(backend_dir)
# 启动定时任务调度器
print("📝 启动命令: python scheduler.py")
process = subprocess.Popen([
sys.executable, "scheduler.py"
], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# 等待调度器启动
print("⏳ 等待定时任务调度器启动...")
time.sleep(3)
# 检查进程是否还在运行
if process.poll() is None:
print("✅ 定时任务调度器启动成功")
print("📅 定时任务设置:")
print(" - 每天早上6点: 更新开奖数据")
print(" - 每天下午5点: 生成拼盘推荐")
return process
else:
print("❌ 定时任务调度器启动失败")
# 检查进程输出
stdout, stderr = process.communicate(timeout=1)
if stderr:
print(f"错误输出: {stderr}")
if stdout:
print(f"标准输出: {stdout}")
return False
except Exception as e:
print(f"❌ 启动定时任务调度器时出错: {e}")
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
# 询问是否启动定时任务
print("\n⏰ 定时任务选项:")
print("1. 启动定时任务(推荐)")
print("2. 不启动定时任务")
scheduler_choice = input("请选择 (1/2): ").strip()
start_scheduler_task = scheduler_choice == "1"
# 保存当前目录
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
# 启动定时任务(如果选择)
scheduler_process = None
if start_scheduler_task:
scheduler_process = start_scheduler()
if not scheduler_process:
print("⚠️ 定时任务启动失败,但系统将继续运行")
print("💡 您可以稍后手动启动定时任务: cd backend && python scheduler.py")
# 启动前端
frontend_process = start_frontend(original_dir)
if not frontend_process:
backend_process.terminate()
if scheduler_process:
scheduler_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")
if scheduler_process:
print("⏰ 定时任务: 已启动")
print(" - 每天早上6点: 更新开奖数据")
print(" - 每天下午5点: 生成拼盘推荐")
else:
print("⏰ 定时任务: 未启动")
print("=" * 50)
print("💡 使用说明:")
print("1. 打开浏览器访问 http://localhost:5173")
print("2. 在首页点击'补全场早点'按钮获取最新开奖信息")
print("3. 在一键下单页面查看今日拼盘推荐")
print("4. 使用各种分析功能进行数据分析")
print("=" * 50)
print("按 Ctrl+C 停止服务")
# 等待用户中断
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n🛑 正在停止服务...")
backend_process.terminate()
frontend_process.terminate()
if scheduler_process:
scheduler_process.terminate()
print("✅ 服务已停止")
except Exception as e:
print(f"❌ 启动过程中出错: {e}")
finally:
# 恢复原始目录
os.chdir(original_dir)
if __name__ == "__main__":
main()