+
-
+
{{ num.padStart(2, '0') }}
+
+
{{ scope.row.blue.toString().padStart(2, '0') }}
+
+ {{ b.toString().padStart(2, '0') }}
+
@@ -312,6 +329,7 @@ export default {
method: '机器学习',
numbers: response.data.predicted_numbers.join(' '),
blue: response.data.predicted_blue,
+ blues: response.data.predicted_blues,
confidence: '高'
})
ElMessage.success('机器学习预测完成')
@@ -344,6 +362,7 @@ export default {
method: '模式预测',
numbers: response.data.predicted_numbers.join(' '),
blue: response.data.predicted_blue,
+ blues: response.data.predicted_blues,
confidence: '中'
})
ElMessage.success('模式预测完成')
@@ -391,6 +410,7 @@ export default {
method: `集成预测-${rec.method}`,
numbers: rec.numbers.join(' '),
blue: rec.blue,
+ blues: rec.blues,
confidence: rec.confidence
})
})
@@ -507,7 +527,7 @@ export default {
.red-balls {
display: flex;
gap: 10px;
- flex-wrap: wrap;
+ align-items: center;
}
.ball {
@@ -561,8 +581,17 @@ export default {
color: #303133;
}
-.recommendation-numbers {
- margin: 10px 0;
+.recommendation-numbers.flex-balls {
+ display: flex;
+ align-items: center;
+}
+.red-balls, .blue-balls {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+}
+.blue-balls {
+ margin-left: 20px;
}
.pattern-analysis {
@@ -601,4 +630,9 @@ h3 {
border-bottom: 2px solid #409eff;
padding-bottom: 10px;
}
+
+.prediction-numbers.flex-balls {
+ display: flex;
+ align-items: center;
+}
\ No newline at end of file
diff --git a/start_system.py b/start_system.py
new file mode 100644
index 0000000..a6b928d
--- /dev/null
+++ b/start_system.py
@@ -0,0 +1,315 @@
+#!/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()
diff --git a/test_backend.py b/test_backend.py
new file mode 100644
index 0000000..3106d83
--- /dev/null
+++ b/test_backend.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+"""
+测试后端启动的脚本
+"""
+
+import os
+import sys
+import subprocess
+import time
+import requests
+
+
+def test_backend_startup():
+ """测试后端启动"""
+ print("🧪 测试后端启动...")
+
+ # 切换到backend目录
+ backend_dir = "backend"
+ if not os.path.exists(backend_dir):
+ print("❌ 找不到backend目录")
+ return False
+
+ os.chdir(backend_dir)
+
+ try:
+ # 启动后端服务
+ 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(10)
+
+ # 检查进程状态
+ if process.poll() is not None:
+ # 进程已退出
+ stdout, stderr = process.communicate()
+ print(f"❌ 进程已退出,退出码: {process.returncode}")
+ if stderr:
+ print(f"错误输出:\n{stderr}")
+ if stdout:
+ print(f"标准输出:\n{stdout}")
+ return False
+
+ # 尝试连接服务
+ try:
+ response = requests.get("http://localhost:8000/", timeout=5)
+ print(f"✅ 服务响应成功,状态码: {response.status_code}")
+ print(f"响应内容: {response.text}")
+
+ # 测试API文档
+ try:
+ docs_response = requests.get(
+ "http://localhost:8000/docs", timeout=5)
+ print(f"✅ API文档可访问,状态码: {docs_response.status_code}")
+ except Exception as e:
+ print(f"⚠️ API文档访问失败: {e}")
+
+ return True
+
+ except requests.exceptions.RequestException as e:
+ print(f"❌ 无法连接到服务: {e}")
+
+ # 检查进程输出
+ try:
+ stdout, stderr = process.communicate(timeout=2)
+ if stderr:
+ print(f"错误输出:\n{stderr}")
+ if stdout:
+ print(f"标准输出:\n{stdout}")
+ except subprocess.TimeoutExpired:
+ process.kill()
+ print("⚠️ 进程被强制终止")
+
+ return False
+
+ except Exception as e:
+ print(f"❌ 启动过程中出错: {e}")
+ return False
+ finally:
+ # 清理进程
+ if 'process' in locals() and process.poll() is None:
+ process.terminate()
+ try:
+ process.wait(timeout=5)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+
+def test_database_connection():
+ """测试数据库连接"""
+ print("\n🔍 测试数据库连接...")
+
+ try:
+ # 导入数据库配置
+ sys.path.append('backend')
+ from app.core.database import SQLALCHEMY_DATABASE_URL
+
+ print(f"数据库URL: {SQLALCHEMY_DATABASE_URL}")
+
+ # 尝试创建引擎
+ from sqlalchemy import create_engine, text
+ engine = create_engine(SQLALCHEMY_DATABASE_URL)
+
+ # 测试连接
+ with engine.connect() as connection:
+ result = connection.execute(text("SELECT 1"))
+ print("✅ 数据库连接成功")
+ return True
+
+ except Exception as e:
+ print(f"❌ 数据库连接失败: {e}")
+ return False
+
+
+def main():
+ """主函数"""
+ print("🧪 后端启动测试")
+ print("=" * 50)
+
+ # 测试数据库连接
+ db_ok = test_database_connection()
+
+ if not db_ok:
+ print("\n💡 数据库连接失败,可能的原因:")
+ print("1. 数据库服务器未运行")
+ print("2. 网络连接问题")
+ print("3. 数据库凭据错误")
+ print("4. 防火墙阻止连接")
+
+ response = input("\n是否继续测试后端启动?(y/N): ")
+ if response.lower() != 'y':
+ return
+
+ # 测试后端启动
+ backend_ok = test_backend_startup()
+
+ if backend_ok:
+ print("\n🎉 后端启动测试成功!")
+ else:
+ print("\n❌ 后端启动测试失败!")
+ print("\n💡 建议:")
+ print("1. 检查数据库连接")
+ print("2. 检查依赖包是否安装完整")
+ print("3. 检查端口8000是否被占用")
+ print("4. 查看详细的错误输出")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/使用指南.md b/使用指南.md
new file mode 100644
index 0000000..b5e45af
--- /dev/null
+++ b/使用指南.md
@@ -0,0 +1,172 @@
+# 彩票数据分析系统使用指南
+
+## 🚀 快速开始
+
+### 1. 启动系统
+```bash
+# 一键启动(推荐)
+python start_system.py
+
+# 或者手动启动
+# 后端:cd backend && uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
+# 前端:cd frontend && npm run dev
+```
+
+### 2. 访问系统
+- 前端界面:http://localhost:5173
+- 后端API文档:http://localhost:8000/docs
+
+## 📊 主要功能
+
+### 1. 数据更新功能 ⭐ 新功能
+
+#### 位置
+- 在首页顶部可以看到"数据更新"卡片
+- 包含三个按钮:更新双色球、更新大乐透、更新全部
+
+#### 使用方法
+1. **更新双色球数据**
+ - 点击"更新双色球"按钮
+ - 系统会自动从API获取最新开奖数据
+ - 只添加数据库中不存在的新记录
+ - 更新完成后会显示新增记录数量
+
+2. **更新大乐透数据**
+ - 点击"更新大乐透"按钮
+ - 功能与双色球更新类似
+
+3. **更新全部数据**
+ - 点击"更新全部"按钮
+ - 同时更新双色球和大乐透数据
+ - 适合批量更新场景
+
+#### 更新逻辑
+- 自动去重:只添加数据库中未存在的开奖日期
+- 数据验证:验证开奖号码的格式和范围
+- 实时反馈:显示更新进度和结果
+- 自动刷新:更新完成后自动刷新首页最新开奖信息
+
+### 2. 数据查看功能
+
+#### 最新开奖信息
+- 首页显示双色球和大乐透的最新开奖记录
+- 包含期号、开奖时间、开奖号码
+- 支持手动刷新功能
+
+#### 历史数据查询
+- 进入"双色球数据"或"大乐透数据"页面
+- 支持按期号、日期范围查询
+- 分页显示,每页20条记录
+
+### 3. 统计分析功能
+
+#### 基础统计
+- 号码出现频率统计
+- 热门号码和冷门号码分析
+- 数据可视化展示
+
+#### 高级分析 ⭐ 新功能
+- **遗漏值分析**:分析各号码的遗漏期数
+- **和值分析**:统计红球和值的分布规律
+- **AC值分析**:邻号差值分析
+- **质合比分析**:质数与合数的比例分析
+- **012路分析**:除3余数分析
+- **跨度分析**:最大最小号码差值分析
+- **综合分析**:多维度数据整合分析
+
+### 4. 智能预测功能 ⭐ 新功能
+
+#### 预测方法
+- **机器学习预测**:基于AI算法的预测
+- **模式预测**:基于统计模式的预测
+- **集成预测**:多方法综合预测
+
+#### 使用步骤
+1. 进入"智能预测"页面
+2. 选择彩票类型(双色球/大乐透)
+3. 设置训练期数(建议100-500期)
+4. 点击"训练模型"按钮
+5. 选择预测方法并查看结果
+
+### 5. 智能选号功能
+
+#### 选号策略
+- 随机选号
+- 频率选号
+- 热门号码选号
+- 冷门号码选号
+- 自定义选号策略
+
+## 🔧 技术特性
+
+### 数据管理
+- **自动去重**:避免重复数据导入
+- **数据验证**:确保数据格式正确
+- **批量处理**:支持大量数据的高效处理
+- **事务安全**:数据库操作支持回滚
+
+### 性能优化
+- **API缓存**:减少重复请求
+- **分页查询**:提高大数据量查询性能
+- **异步处理**:支持并发请求处理
+- **错误重试**:网络请求自动重试机制
+
+### 用户体验
+- **响应式设计**:支持各种屏幕尺寸
+- **实时反馈**:操作状态实时显示
+- **错误提示**:友好的错误信息展示
+- **加载状态**:长时间操作的进度提示
+
+## 🛠️ 故障排除
+
+### 常见问题
+
+#### 1. 系统启动失败
+**问题**:运行 `python start_system.py` 后系统无法启动
+**解决**:
+- 检查Python版本是否为3.8+
+- 检查Node.js版本是否为16+
+- 确保已安装所有依赖包
+
+#### 2. 数据更新失败
+**问题**:点击更新按钮后显示错误
+**解决**:
+- 检查网络连接
+- 确认API密钥是否有效
+- 查看后端日志获取详细错误信息
+
+#### 3. 前端页面无法访问
+**问题**:浏览器无法打开 http://localhost:5173
+**解决**:
+- 确认前端服务是否正常启动
+- 检查端口5173是否被占用
+- 查看前端控制台错误信息
+
+#### 4. 数据库连接失败
+**问题**:后端启动时显示数据库连接错误
+**解决**:
+- 检查数据库服务是否启动
+- 确认数据库连接配置是否正确
+- 验证数据库用户权限
+
+### 日志查看
+- 后端日志:查看终端输出或日志文件
+- 前端日志:打开浏览器开发者工具查看控制台
+- 数据库日志:查看数据库服务器日志
+
+## 📞 技术支持
+
+如果遇到问题,请:
+1. 查看本文档的故障排除部分
+2. 检查系统日志获取详细错误信息
+3. 确认系统环境配置是否正确
+4. 联系技术支持团队
+
+## 🔄 更新日志
+
+### v1.0.0 (最新版本)
+- ✅ 新增数据更新功能
+- ✅ 新增高级分析功能
+- ✅ 新增智能预测功能
+- ✅ 优化用户界面和用户体验
+- ✅ 提升系统性能和稳定性
\ No newline at end of file