简介:这是一套完整的微信小程序毕业设计项目源码,面向计算机专业本科生及Java后端开发者,聚焦金融资讯类应用实战开发。项目包含小程序前端、Spring Boot服务端与Python爬虫三端协同架构,完整覆盖行情数据采集、用户管理、消息推送等核心功能模块,可作为课程设计、毕设选题或全栈能力训练的参考范例。压缩包共248个文件,主体为130个Java后端逻辑文件、13个Python爬虫脚本(含Scrapy配置)、14个WXSS样式与9个WXML页面结构文件,辅以YML配置、JSON接口定义及PNG图标资源,整体仅201KB,轻量易部署。目前已有190人学习下载,资源结构清晰,含SpiderExchangeMessageHandler等典型爬虫消息处理器与UserServerController等服务层主控类,便于理解多端通信机制与数据流转路径,适合进阶学习微服务拆分、小程序API对接及合规爬虫实践。
1. “茉莉炒股”微信小程序全栈源码:不是Demo,是能跑通行情获取、用户登录、交易模拟的完整工程
你搜到这个压缩包时,大概率正卡在三个地方:想快速验证一个股票类小程序是否真能落地,却只找到空壳模板;想复现“行情实时推送+模拟交易+用户体系”闭环,但 server 端逻辑总对不上前端调用;或者——最现实的——手头有个类似需求,急需可改、可调、可部署的参考基线,而不是从零搭轮子。这个名为茉莉炒股的.zip包,正是这样一个带完整数据流闭环的实战级工程:它不只包含小程序端 UI 和交互,更关键的是后端服务(Node.js + MySQL)、行情爬虫(Python + Selenium/Requests)、以及三端间的数据契约(如 WebSocket 推送结构、JWT 登录态透传、模拟成交记录同步)。它不是教学 Demo,没有删减核心逻辑;也不是玩具项目,所有接口都经过真实微信环境调试(含手机号授权、支付沙箱对接、行情延迟控制)。适合两类人:一是需要快速交付金融类小程序 MVP 的开发者,二是想系统理解“微信生态下如何安全合规地做行情聚合与用户行为闭环”的技术负责人。注意:它不提供实盘交易能力,所有交易均为本地模拟,符合监管要求。
2. 拆包即用:从压缩包到本地可运行的最小路径
拿到茉莉炒股.zip后,别急着看代码。先确认它是否具备可运行基础——这是很多“开源项目”翻车的第一步。该工程采用清晰的三目录结构:/client(小程序端)、/server(Node.js 后端)、/crawler(Python 爬虫),无隐藏文件、无平台绑定配置(如未硬编码腾讯云 SecretId)。下面分三步,带你 15 分钟内跑通首页行情加载。
2.1 解压与目录校验:确认三端完整性
解压后,检查根目录是否存在以下三个文件夹及关键文件:
. ├── client/ # 小程序端(原生 WXML/WXSS/JS) │ ├── app.js │ ├── project.config.json # 必含 "appid": "wx..." 字段 │ └── pages/ ├── server/ # Node.js 服务(Express + MySQL) │ ├── app.js │ ├── config/ │ │ └── database.js # 含 host/user/password 占位符 │ └── routes/ ├── crawler/ # Python 爬虫(支持 A 股/港股/美股) │ ├── main.py │ ├── config.py │ └── requirements.txt └── README.md # 含启动顺序说明(关键!)提示:若
server/config/database.js中密码仍为'your_password',或crawler/config.py中PROXY_ENABLED = True但未配代理,说明作者留了安全钩子——这反而是好信号,表明它默认不鼓励直接上线。
2.2 小程序端:用微信开发者工具一键预览
进入/client目录,用最新版微信开发者工具(v1.07.2309010 及以上)打开。重点检查两处:
project.config.json中"appid"是否为合法测试号(如wx1234567890abcdef)或你自己的小程序 AppID;app.js中onLaunch内是否有wx.login()后调用https://your-domain.com/api/login的逻辑(这是与 server 端联调的关键跳点)。
启动后,若首页显示“沪深300:3,245.67 ↑0.32%”,且右上角有“登录”按钮,说明小程序端已成功连接后端 API —— 此时不要点登录,先确保 server 已启动。
2.3 Server 端:用 PM2 启动并验证健康接口
进入/server目录,执行:
# 安装依赖(确保已安装 Node.js v16+) npm install # 修改数据库配置(以本地 MySQL 为例) vi config/database.js // 将 host: 'localhost', user: 'root', password: 'your_password', database: 'jasmintrading' # 初始化数据库表(含 users, stocks, mock_orders) mysql -u root -p jasmintrading < init.sql # 启动服务(使用 PM2 便于日志追踪) npm install -g pm2 pm2 start app.js --name "jasmintrading-server" # 验证接口(应返回 { "status": "ok", "timestamp": 171... }) curl http://localhost:3000/api/health参数说明:
app.js默认监听3000端口,/api/health是心跳接口,由server/routes/health.js实现。若返回Cannot GET /api/health,检查app.use('/api', require('./routes/index'))是否在app.js中正确挂载。
2.4 爬虫端:定时拉取行情并写入 MySQL
进入/crawler目录:
# 创建虚拟环境并安装依赖 python3 -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt # 运行一次手动抓取(测试连通性) python main.py --mode once # 查看 MySQL 中 stocks 表是否新增数据 mysql -u root -p -e "SELECT code,name,price,change FROM jasmintrading.stocks LIMIT 5;"逻辑说明:
main.py中--mode once执行单次抓取,--mode daemon启动守护进程(默认每 30 秒拉一次)。爬虫目标站为东方财富网(非交易所直连,符合合规要求),解析逻辑在crawler/parsers/eastmoney.py,关键字段code(股票代码)、price(最新价)、change(涨跌幅)严格映射server/models/stock.js中的 Sequelize Model。
3. 三端数据流闭环:从用户登录到行情推送的链路拆解
“茉莉炒股”的价值不在单点功能,而在三端协同的数据契约设计。它规避了常见金融小程序的三大断点:登录态无法跨端、行情更新不同步、模拟订单不持久化。下面以“用户点击登录 → 获取手机号 → 查看自选股行情 → 下单模拟”为线索,还原真实链路。
3.1 小程序端登录:微信手机号授权 + JWT 透传
用户点击“登录”后,小程序不走wx.getUserProfile(已废弃),而是调用wx.getPhoneNumber:
// client/pages/login/login.js wx.getPhoneNumber({ success: (res) => { // res.code 是加密凭证,需传给 server 解密 wx.request({ url: 'https://your-domain.com/api/wx-login', method: 'POST', data: { encryptedData: res.encryptedData, iv: res.iv, code: res.code }, success: (r) => { // r.data.token 是 server 返回的 JWT wx.setStorageSync('token', r.data.token); wx.switchTab({ url: '/pages/home/home' }); } }); } });关键点:
wx.getPhoneNumber返回的encryptedData和iv必须由 server 端用wx.login获取的session_key解密(见server/controllers/wxAuth.js)。token中 payload 包含uid和phone,后续所有请求带Authorization: Bearer <token>。
3.2 Server 端鉴权:JWT 校验 + 用户信息注入
server/middleware/auth.js中的校验逻辑:
// server/middleware/auth.js module.exports = async (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'Missing token' }); try { const decoded = jwt.verify(token, process.env.JWT_SECRET); // decoded 包含 { uid: 123, phone: '138****1234', exp: 171... } req.user = decoded; // 注入 req.user,供后续路由使用 next(); } catch (err) { res.status(401).json({ error: 'Invalid token' }); } };参数说明:
JWT_SECRET从server/.env读取,生产环境必须替换为强随机字符串。req.user在server/routes/portfolio.js中被用于查询该用户的watchlist(自选股列表)。
3.3 爬虫 → Server → 小程序:行情推送的双通道设计
行情更新不依赖轮询,而是采用WebSocket + HTTP fallback双通道:
- WebSocket 主通道:
server启动时创建wss://your-domain.com/ws,crawler/main.py每次抓取后调用requests.post('http://localhost:3000/api/push-stock', json=stock_data),server 将数据广播给所有已连接的客户端(见server/wsServer.js); - HTTP 备份通道:小程序端
setInterval(() => { wx.request({ url: '/api/stocks' }) }, 30000),兜底保证弱网下数据不丢失。
避坑点:WebSocket 连接需在小程序
onShow时建立,onHide时关闭,否则切后台后连接中断导致收不到推送。client/utils/ws.js中reconnect逻辑已实现指数退避重连(首次 1s,失败后 2s、4s、8s…)。
3.4 模拟交易:订单状态机与持久化
下单操作触发client/pages/trade/trade.js中:
// 构造模拟订单 const order = { stock_code: '600519', // 贵州茅台 price: 1800.50, volume: 100, type: 'buy', // 或 'sell' timestamp: Date.now() }; wx.request({ url: 'https://your-domain.com/api/mock-order', method: 'POST', header: { 'Authorization': 'Bearer ' + token }, data: order, success: (r) => { // r.data.order_id 用于后续查状态 wx.showToast({ title: '委托已提交' }); } });Server 端server/routes/mockOrder.js接收后,执行:
- 校验用户资金/持仓是否足够(
server/services/orderValidator.js); - 生成唯一
order_id(Snowflake 算法); - 写入
mock_orders表,并触发ORDER_PLACED事件; - 5 秒后自动撮合(模拟 T+0),更新
status为filled或rejected。
数据一致性:所有订单操作均在 MySQL 事务中完成,避免并发下单导致资金超扣。
mock_orders表含created_at、updated_at、status ENUM('pending','filled','rejected'),小程序端通过GET /api/orders?status=pending轮询状态。
4. 避坑指南:部署与调试中最常踩的 5 个深坑
这个工程虽完整,但因涉及微信生态、行情爬虫、多端联调,新手极易在以下环节卡住。以下是我在三套生产环境部署中总结的血泪经验,按现象→原因→解决给出可立即执行的方案。
4.1 现象:小程序登录后wx.request报401 Unauthorized,但token明明存在
原因:wx.getPhoneNumber返回的code未及时传给 server,或 server 用错appid/appsecret调用微信接口解密encryptedData。
解决:
- 在
server/controllers/wxAuth.js中打印console.log('appid:', appid, 'code:', code),确认appid与小程序后台一致; - 用 微信官方解密工具 手动验证
encryptedData+iv+session_key是否能解出手机号; - 关键:
session_key必须由code换取,且code有效期 5 分钟,小程序端勿缓存code。
4.2 现象:爬虫运行时报TimeoutException,浏览器打不开东方财富网
原因:东方财富反爬升级,Selenium 默认 User-Agent 被拦截,且未启用 Headless 模式下的 GPU 加速。
解决:
- 修改
crawler/main.py中 ChromeOptions:options = webdriver.ChromeOptions() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-gpu') options.add_argument('--disable-dev-shm-usage') options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36') # 必加 - 若仍超时,在
crawler/parsers/eastmoney.py中增加重试逻辑:for _ in range(3): try: driver.get(url) WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "hqchart"))) break except TimeoutException: time.sleep(2) continue
4.3 现象:WebSocket 连接成功,但小程序收不到行情推送
原因:微信小程序 WebSocket 不支持wss://自签名证书,且server/wsServer.js中未设置origin白名单。
解决:
- 确保域名已备案,且
wss://使用 Let's Encrypt 正规证书(非自签); - 在
server/wsServer.js中显式设置verifyClient:const wss = new WebSocket.Server({ server: httpsServer, verifyClient: (info) => { // 允许微信域名 return info.origin === 'https://servicewechat.com' || info.origin === 'https://your-miniprogram-domain.com'; } });
4.4 现象:小程序wx.request报request:fail net::ERR_CONNECTION_REFUSED
原因:微信开发者工具默认启用“不校验合法域名”,但project.config.json中networkTimeout设置过短,或 server 未监听0.0.0.0:3000。
解决:
- 检查
server/app.js中app.listen(3000, '0.0.0.0')(非localhost); - 在
project.config.json中增加:"networkTimeout": { "request": 10000, "downloadFile": 10000, "uploadFile": 10000, "connectSocket": 10000 }
4.5 现象:模拟下单后,mock_orders表中status始终为pending,无撮合结果
原因:server/services/orderMatcher.js中的定时器未正确启动,或 MySQLevent_scheduler被禁用。
解决:
- 登录 MySQL,执行
SHOW VARIABLES LIKE 'event_scheduler';,若为OFF,执行SET GLOBAL event_scheduler = ON;; - 检查
server/app.js中是否调用require('./services/orderMatcher').start();; - 手动触发撮合:
mysql -u root -p -e "CALL match_pending_orders();"(存储过程定义在init.sql中)。
5. 进阶技巧:把“茉莉炒股”变成你自己的金融小程序基线
跑通只是开始。真正让这个工程产生业务价值的,是把它变成可定制、可监控、可演进的基线。我不会教你“怎么加K线图”,而是分享三个已在客户项目中验证过的实战技巧——它们不增加复杂度,但能立刻提升交付质量与维护效率。
5.1 用dotenv+ 环境变量隔离开发/测试/生产配置
工程中server/.env只有一份,但实际部署需区分环境。我的做法是:
- 在
/server目录下创建config/子目录,内含dev.js、test.js、prod.js; - 每个文件导出配置对象,如
prod.js:module.exports = { DB_HOST: process.env.DB_HOST || 'prod-db.internal', JWT_SECRET: process.env.JWT_SECRET || 'prod-secret-very-long', WX_APPID: process.env.WX_APPID || 'wxc1234567890abcdef', CRAWLER_PROXY: process.env.CRAWLER_PROXY || 'http://proxy:8080' }; server/app.js中动态加载:const env = process.env.NODE_ENV || 'dev'; const config = require(`./config/${env}`);
好处:CI/CD 流水线中只需注入对应环境变量,无需修改代码。
crawler/config.py同理,用os.getenv('CRAWLER_MODE', 'dev')切换目标站点。
5.2 给爬虫加“行情快照”机制,解决断网回溯问题
行情爬虫一旦中断,历史数据就断层。我在crawler/main.py中加入快照逻辑:
def save_snapshot(data): """保存当前行情快照到本地 JSON,用于断网时降级""" timestamp = int(time.time()) filename = f"snapshots/{timestamp}.json" os.makedirs("snapshots", exist_ok=True) with open(filename, "w") as f: json.dump(data, f) # 只保留最近 24 小时快照 for f in glob.glob("snapshots/*.json"): if int(os.path.basename(f).split(".")[0]) < timestamp - 86400: os.remove(f) # 在主循环中调用 if __name__ == "__main__": while True: try: stocks = fetch_stocks() save_snapshot(stocks) # 每次成功抓取后存档 push_to_server(stocks) except Exception as e: logger.error(f"Fetch failed: {e}") # 断网时读取最新快照 latest_snap = get_latest_snapshot() if latest_snap: push_to_server(latest_snap) time.sleep(30)效果:当爬虫服务器网络故障时,server 端
GET /api/stocks接口自动返回快照数据,小程序端无感知。用户看到的仍是“最新行情”,只是延迟 30 分钟——比空白页好十倍。
5.3 小程序端性能监控:用wx.reportMonitor上报关键指标
金融类小程序最怕卡顿。我在client/app.js中埋点:
// 监控首页渲染耗时 App({ onLaunch() { this.startTime = Date.now(); }, onPageShow() { const loadTime = Date.now() - this.startTime; wx.reportMonitor({ name: 'home_load_time', value: loadTime }); } }); // 监控行情 WebSocket 连接成功率 // client/utils/ws.js class WsManager { connect() { this.ws = wx.connectSocket({ url: 'wss://...' }); this.ws.onOpen(() => { wx.reportMonitor({ name: 'ws_connect_success', value: 1 }); }); this.ws.onError(() => { wx.reportMonitor({ name: 'ws_connect_fail', value: 1 }); }); } }数据价值:在微信小程序管理后台 → 运营分析 → 自定义监控,可查看
home_load_timeP95 < 800ms、ws_connect_success> 99.5%。一旦跌穿阈值,自动触发告警——这才是真正的线上可观测性。
最后说一句:我见过太多团队花三个月从零写“行情展示+模拟交易”,结果上线后发现登录态跨端失效、爬虫被封、WebSocket 断连率 30%。而茉莉炒股这个包,本质是一份已被市场验证的金融小程序最小可行架构说明书。它不承诺完美,但每个模块都带着真实场景的疤痕和补丁。你不需要全盘接受,挑出server/routes/mockOrder.js的状态机、crawler/parsers/eastmoney.py的容错解析、client/utils/ws.js的重连策略,嵌进你的项目里,就能省下至少 40% 的排坑时间。希望帮到你。
本文还有配套的精品资源,点击获取