
简介这是一套完整的微信小程序毕业设计项目源码面向计算机专业本科生及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小程序端、/serverNode.js 后端、/crawlerPython 爬虫无隐藏文件、无平台绑定配置如未硬编码腾讯云 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或你自己的小程序 AppIDapp.js中onLaunch内是否有wx.login()后调用https://your-domain.com/api/login的逻辑这是与 server 端联调的关键跳点。启动后若首页显示“沪深3003,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/wscrawler/main.py每次抓取后调用requests.post(http://localhost:3000/api/push-stock, jsonstock_data)server 将数据广播给所有已连接的客户端见server/wsServer.jsHTTP 备份通道小程序端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_idSnowflake 算法写入mock_orders表并触发ORDER_PLACED事件5 秒后自动撮合模拟 T0更新status为filled或rejected。数据一致性所有订单操作均在 MySQL 事务中完成避免并发下单导致资金超扣。mock_orders表含created_at、updated_at、status ENUM(pending,filled,rejected)小程序端通过GET /api/orders?statuspending轮询状态。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与小程序后台一致用 微信官方解密工具 手动验证encryptedDataivsession_key是否能解出手机号关键session_key必须由code换取且code有效期 5 分钟小程序端勿缓存code。4.2 现象爬虫运行时报TimeoutException浏览器打不开东方财富网原因东方财富反爬升级Selenium 默认 User-Agent 被拦截且未启用 Headless 模式下的 GPU 加速。解决修改crawler/main.py中 ChromeOptionsoptions 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-agentMozilla/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) continue4.3 现象WebSocket 连接成功但小程序收不到行情推送原因微信小程序 WebSocket 不支持wss://自签名证书且server/wsServer.js中未设置origin白名单。解决确保域名已备案且wss://使用 Lets Encrypt 正规证书非自签在server/wsServer.js中显式设置verifyClientconst 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.jsmodule.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 fsnapshots/{timestamp}.json os.makedirs(snapshots, exist_okTrue) 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(fFetch 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% 的排坑时间。希望帮到你。本文还有配套的精品资源点击获取