要求: 所有数据传输均使用json格式 后端使用workflow框架 端口8081 前端使用nginx 端口8080 启动方式 sudo nginx -c /home/me/EzTest01/config/nginxConfig/nginx.conf
CREATE TABLE userInfo (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE stock_basic_info (
id INT AUTO_INCREMENT PRIMARY KEY,
stock_code VARCHAR(10) UNIQUE NOT NULL,
stock_name VARCHAR(100) NOT NULL,
market VARCHAR(20),
industry VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE user_stocks_<user_id> (
id INT AUTO_INCREMENT PRIMARY KEY,
stock_code VARCHAR(10) NOT NULL,
stock_name VARCHAR(100) NOT NULL,
subscribe_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_user_stock (stock_code)
);- 框架: Workflow C++
- 路由处理: cHttpServer
- 支持方法: GET, POST, OPTIONS
- CORS: 已配置跨域支持
- 框架: Boost.Beast
- 线程池: 4个工作线程
- 连接管理: 自动连接池管理
- 主机: localhost
- 数据库: Eztest
- 用户: EzTest01
- 密码: 123456
- 连接池: 最小5个连接
- 根目录: /home/me/EzTest01/static
- 支持文件: HTML, CSS, JS, 图片等
- 缓存策略: 静态文件缓存
location /api/ {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
- API_BASE_URL: http://localhost:8080
- 请求方法: Fetch API
- 数据格式: JSON
- 错误处理: 统一错误提示
cd build
export HTTP_PORT=8081
./stockApiTest &sudo nginx -c /home/me/EzTest01/config/nginxConfig/nginx.conf# 停止后端
killall stockApiTest
# 停止Nginx
sudo nginx -s stop# 检查端口占用
ss -tlnp | grep -E ":(8080|8081|8082)"
# 检查进程
ps aux | grep stockApiTest# 测试健康检查
curl http://localhost:8080/api/health
# 测试注册
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"123456"}'# 访问主页
curl http://localhost:8080/
问题描述: 前端登录时出现405 Method Not Allowed错误
问题原因: 后端服务(stockApiTest)未启动,nginx将请求代理到8081端口,但该端口没有服务监听
解决方案:
- 启动后端服务:
cd build && export HTTP_PORT=8081 && ./stockApiTest & - 验证服务状态:
ss -tlnp | grep -E ":(8080|8081|8082)" - 测试API连通性: 使用Python脚本测试登录接口
修复结果:
- 后端服务成功启动在8081端口
- WebSocket服务启动在8082端口
- 登录API返回200状态码和正确的JSON响应
- 前端登录功能恢复正常
测试命令:
# 测试登录API
python3 test_api.py
# 手动测试
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"123456"}'注意事项:
- 确保在启动前端之前先启动后端服务
- 后端服务需要在build目录下启动
- 可以通过日志文件监控服务状态:
tail -f ./Python/Log/backend.log
- 主程序:
test/stockApiTest.cc- 启动HTTP(8081)和WebSocket(8082)服务器 - HTTP服务器:
src/cHttpServer.cc- 处理REST API请求 - WebSocket服务器:
src/cWsServer.cc- 实时数据推送 - 数据库操作:
src/cMysql.cc- MySQL数据库CRUD操作 - 股票业务:
src/cStockController.cc- 股票订阅、搜索等业务逻辑 - 用户管理:
src/cUserLogin.cc,src/cUserRegister.cc- 用户认证 - 密码加密:
src/PasswordHasher.cc- SHA-256+盐值密码加密 - 前端页面:
static/index.html- 用户界面 - 前端逻辑:
static/js/app.js- JavaScript交互 - 数据爬虫:
Python/scripts/main_ubuntu.py- Tushare股票数据爬取
- 构建配置:
CMakeLists.txt- C++项目构建 - Nginx配置:
config/nginxConfig/nginx.conf- 前端服务器配置 - 数据库配置:
config/mysqlini.json- MySQL连接配置 - 启动脚本:
start_full_system.sh- 一键启动所有服务
- 8080: Nginx前端服务器
- 8081: Workflow HTTP API服务器
- 8082: Boost.Beast WebSocket服务器
- 3306: MySQL数据库
- ✅ 用户注册 (POST /register)
- ✅ 用户登录 (POST /login)
- ✅ 密码SHA-256+盐值加密存储
- ✅ 用户验证和会话管理
- ✅ 股票搜索 (GET /api/stock/search)
- ✅ 股票订阅 (POST /api/stock/subscribe)
- ✅ 取消订阅 (POST /api/stock/unsubscribe)
- ✅ 订阅列表 (GET /api/stock/subscriptions)
- ✅ 价格提醒 (POST /api/stock/alert)
- ✅ 股票数据 (GET /api/stock/data)
- ✅ 实时价格 (GET /api/stock/prices)
- ✅ WebSocket服务器 (端口8082)
- ✅ 多用户并发连接
- ✅ 线程池处理 (4个工作线程)
- ✅ 实时股票价格推送
- ✅ Tushare API集成
- ✅ 股票基础信息爬取
- ✅ 实时行情数据获取
- ✅ 新闻资讯爬取
- ✅ 数据库连接池管理
- ✅ SQL注入防护 (PreparedStatement)
- ✅ CORS跨域支持
- ✅ 统一日志系统 (spdlog)
- ✅ 错误处理和异常管理
- ✅ 配置文件管理
- ✅ 模块化代码设计
新增实时成交数据采集、存储和查询功能,支持获取股票的实时成交明细数据。
CREATE TABLE IF NOT EXISTS realtime_trades (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
ts_code VARCHAR(20) NOT NULL COMMENT '股票代码',
trade_time VARCHAR(20) NOT NULL COMMENT '交易时间',
price DECIMAL(10,3) NOT NULL COMMENT '成交价格',
change_amount DECIMAL(10,3) DEFAULT 0 COMMENT '价格变动',
volume BIGINT NOT NULL COMMENT '成交量(手)',
amount BIGINT NOT NULL COMMENT '成交金额(元)',
trade_type VARCHAR(10) NOT NULL COMMENT '交易类型:买入/卖出/中性',
trade_date DATE NOT NULL COMMENT '交易日期',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX idx_ts_code (ts_code),
INDEX idx_trade_date (trade_date),
INDEX idx_trade_time (trade_time),
INDEX idx_ts_code_date (ts_code, trade_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='实时成交数据表';GET /api/realtime/trades?ts_code=600000.SH&start_time=2024-01-01&end_time=2024-01-31&limit=100参数说明:
ts_code(可选): 股票代码,如 600000.SHstart_time(可选): 开始时间,格式 YYYY-MM-DDend_time(可选): 结束时间,格式 YYYY-MM-DDlimit(可选): 返回条数,默认100
响应示例:
{
"success": true,
"data": [
{
"ts_code": "600000.SH",
"trade_time": "09:30:01",
"price": 6.57,
"change": -0.01,
"volume": 429,
"amount": 281853,
"trade_type": "卖出",
"created_at": "2024-01-15 09:30:01"
}
]
}GET /api/realtime/latest?ts_code=600000.SH&limit=50参数说明:
ts_code(必选): 股票代码limit(可选): 返回条数,默认50
from Python.classes.C_RealtimeTrade import C_RealtimeTrade
# 创建采集器
trader = C_RealtimeTrade()
# 创建表
trader.create_table()
# 采集单只股票数据
trades = trader.get_realtime_tick('600000.SH')
trader.save_realtime_trades(trades)
# 批量采集
stock_codes = ['600000.SH', '000001.SZ']
results = trader.collect_trades_for_stocks(stock_codes)- sina: 新浪财经(默认)
- dc: 东方财富
python3 test_realtime_trade.py# 测试获取实时成交数据
curl "http://localhost:8081/api/realtime/trades?ts_code=600000.SH&limit=10"
# 测试获取最新成交数据
curl "http://localhost:8081/api/realtime/latest?ts_code=600000.SH&limit=5"- ✅ 实时成交数据采集(基于Tushare)
- ✅ 批量数据存储和查询
- ✅ RESTful API接口
- ✅ 多数据源支持(sina/dc)
- ✅ 灵活的查询条件(股票代码、时间范围、数量限制)
- ✅ 事务支持的批量插入
- ✅ 完整的日志记录
- ✅ 异常处理和错误恢复
- API限制: 使用Tushare API需要注册并获取token
- 请求频率: 避免过频请求,建议间隔1秒以上
- 数据量: 实时成交数据量较大,建议定期清理历史数据
- 交易时间: 只有在交易时间内才能获取到实时数据
- 🔄 WebSocket实时推送成交数据
- 📊 成交数据统计分析
- ⏰ 定时任务自动采集
- 📈 成交量价关系分析
在 realtime_trades 表中新增 stock_name 字段,提供完整的股票信息:
ALTER TABLE realtime_trades ADD COLUMN stock_name VARCHAR(100) COMMENT '股票全名' AFTER ts_code;数据结构示例:
{
"ts_code": "000001.SZ",
"stock_name": "平安银行",
"trade_time": "09:30:01",
"price": 6.57,
"change": -0.01,
"volume": 429,
"amount": 281853,
"trade_type": "卖出"
}实现了完整的用户会话管理系统,包括Session创建、验证、销毁和清理功能。
CREATE TABLE IF NOT EXISTS user_sessions (
session_id VARCHAR(64) PRIMARY KEY,
username VARCHAR(50) NOT NULL,
user_id VARCHAR(50) NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
created_at DATETIME NOT NULL,
last_access DATETIME NOT NULL,
expires_at DATETIME NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
INDEX idx_username (username),
INDEX idx_user_id (user_id),
INDEX idx_expires_at (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户会话表';- Session创建: 生成安全的Session ID,设置过期时间
- Session验证: 检查Session有效性和过期状态
- Session销毁: 安全删除Session记录
- 自动清理: 定期清理过期Session
实现了安全的Cookie管理策略:
// Cookie配置
HttpOnly: true // 防XSS攻击
Max-Age: 1800 // 30分钟过期
SameSite: Lax // CSRF防护
Secure: false // HTTP环境(生产环境建议true)修复问题: 注册和登录使用了不同的密码哈希方法导致验证失败
解决方案:
- 注册时统一使用
PasswordHasher::hashPasswordWithSalt() - 登录验证使用
PasswordHasher::verifyPasswordWithSaltedHash() - 密码存储格式:
salt:hash
修复前:
// 注册 (cUserRegister.cc)
password_hash = cPasswordUtils::hashPasswordWithSalt(password, "EzTest01_Salt_2025");
// 登录 (cUserLogin.cc) - 不一致!
bool is_valid = PasswordHasher::verifyPasswordWithSaltedHash(password, stored_hash);修复后:
// 注册和登录都使用相同的PasswordHasher类
// 确保密码哈希和验证的一致性
std::string hashedPassword = PasswordHasher::hashPasswordWithSalt(password);
bool is_valid = PasswordHasher::verifyPasswordWithSaltedHash(password, stored_hash);POST /api/user/login
Content-Type: application/json
{
"username": "testuser",
"password": "password123"
}响应:
{
"success": true,
"message": "登录成功",
"session_id": "a1b2c3d4e5f6...",
"user": {
"username": "testuser",
"user_id": "123"
}
}POST /api/user/logout
Cookie: session_id=a1b2c3d4e5f6...GET /api/user/session/validate
Cookie: session_id=a1b2c3d4e5f6...GET /api/user/info
Cookie: session_id=a1b2c3d4e5f6...GET /api/realtime/trades?limit=10响应示例:
{
"success": true,
"data": [
{
"ts_code": "000001.SZ",
"stock_name": "平安银行",
"trade_time": "09:30:01",
"price": 6.57,
"change": -0.01,
"volume": 429,
"amount": 281853,
"trade_type": "卖出",
"created_at": "2024-01-15 09:30:01"
}
]
}重新设计了前端登录界面,实现了标准的登录优先工作流:
<!-- 登录/注册区域 -->
<div id="auth-section">
<h2>用户认证</h2>
<!-- 注册表单 -->
<!-- 登录表单 -->
</div>
<!-- 主功能区域 (需登录后才显示) -->
<div id="main-section" style="display:none;">
<h2>实时成交数据</h2>
<!-- 股票数据表格 -->
<!-- 退出登录按钮 -->
</div>改进要点:
- 🔐 先登录,后访问功能 - 标准安全流程
- 🎨 分离登录界面和主要功能界面
- 🔄 Session状态自动检查和维护
- 📱 响应式设计,适配不同设备
include/cSessionManager.h- Session管理器接口定义src/cSessionManager.cc- Session管理器实现- 数据库迁移脚本 - 添加stock_name字段
include/cMysql.h- 添加getUserPasswordHash方法和RealtimeTrade结构体stock_name字段src/cMysql.cc- 实现getUserPasswordHash,修改insertRealtimeTrade和getRealtimeTradessrc/cHttpServer.cc- 集成SessionManager,新增用户Session相关API路由src/cUserLogin.cc- 修复密码验证逻辑,集成Session管理include/cUserLogin.h- 添加Session相关方法声明frontend/index.html- 重新设计登录优先的界面流程
- 🔐 安全的Session ID生成 (随机64位字符串)
- ⏰ Session自动过期机制 (30分钟)
- 🧹 定期清理过期Session
- 🔍 Session状态实时验证
- 🧂 SHA-256 + 随机盐值加密
- 🔄 统一的密码哈希和验证流程
- 🚫 防止密码哈希不一致导致的登录失败
- 🍪 HttpOnly Cookie防XSS
- 🛡️ SameSite Cookie防CSRF
- 📋 详细的错误日志记录
- 🔍 输入参数验证和SQL注入防护
# 1. 编译项目
cd build && make clean && make
# 2. 启动后端服务
export HTTP_PORT=8081 && ./stockApiTest &
# 3. 启动前端服务
cd ../frontend && python3 -m http.server 8080 &
# 4. 访问应用
# 前端: http://localhost:8080/index.html
# API: http://localhost:8081/api/# 测试用户注册
curl -X POST http://localhost:8081/api/user/register \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"test123"}'
# 测试用户登录
curl -X POST http://localhost:8081/api/user/login \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"test123"}'
# 测试实时数据 (包含股票名称)
curl "http://localhost:8081/api/realtime/trades?limit=5"问题: 用户注册成功但登录始终失败,提示"用户名或密码错误" 原因: 注册时使用cPasswordUtils::hashPasswordWithSalt,登录验证使用PasswordHasher::verifyPasswordWithSaltedHash,两个类的实现不一致 解决: 统一使用PasswordHasher类进行密码哈希和验证
问题: API返回的实时成交数据只有股票代码,缺少股票中文名称 解决: 在realtime_trades表添加stock_name字段,修改相关查询和插入逻辑
问题: 登录和主要功能界面混合在一起,用户体验差 解决: 重新设计为登录优先的标准工作流,分离认证和功能界面
- 📊 数据库查询优化: 为realtime_trades表的关键字段添加索引
- 🔄 Session缓存: 内存中缓存活跃Session,减少数据库查询
- 🧹 自动清理: 定期清理过期Session和历史数据
- 📦 批量操作: 实时成交数据支持批量插入,提高写入效率
- ✅ 用户注册和登录 (密码哈希修复)
- ✅ Session创建、验证、销毁管理
- ✅ Cookie安全设置 (HttpOnly, SameSite)
- ✅ 实时成交数据查询 (包含股票名称)
- ✅ 前端登录优先界面设计
- ✅ 统一的错误处理和日志记录
- ✅ RESTful API接口规范
- ✅ 数据库连接池和事务支持
- ✅ 自动数据清理和维护
- 🔄 实现WebSocket实时推送Session状态变更
- 📊 添加用户操作日志和统计分析
- 🎨 优化前端UI/UX设计
- 🔐 实现多设备登录管理和踢出功能
- ⚡ 引入Redis缓存提升Session性能
- 📱 开发移动端适配界面