☰
微信小程序奶茶点餐毕设:SSM源码部署与避坑指南
2026/10/26 16:48:21 网站建设 项目流程

简介:面向毕业设计场景的Java微信小程序奶茶点餐系统完整源码包,后台采用SSM框架并使用Vue构建管理页面,小程序端基于微信原生组件,数据库为MySQL,兼容Eclipse、MyEclipse、STS、IDEA等主流开发工具。整包共1065个文件,压缩后约49.71MB,以Vue/JS/Java源码、WXSS/WXML小程序样式与页面、JSON配置、PNG/SVG图片素材为主,另含SQL数据库脚本、Word论文、PPT答辩文稿、开题报告及环境工具包,便于直接导入运行和二次开发。系统覆盖商品管理、商品订单管理、商品评价管理、客服聊天管理、新闻管理等奶茶店自助点餐核心模块,并配套完整的前后端交互与数据库表设计,可整体作为毕业设计交付方案。附带安装教程与相同框架项目说明,能帮助使用者快速完成环境部署、运行调试与排错,降低上手门槛。目前已有130人学习下载,适合需要一套可运行、可讲解、可扩展的Java微信小程序毕业设计项目的本科或高职学生。

1. 微信小程序奶茶点餐毕设资源:一份能直接跑通的 SSM 源码长什么样

假设你正为两个星期后的毕设答辩焦虑,刚从某个网盘里解压出一份奶茶点餐小程序源码。文件夹里躺着一堆main.css.bak、3-build.bat、app.63641066.css,一眼看上去全是编译产物,连个 Readme 都没有——这其实才是大多数 Java 毕设源码包的常态。这份资源本体是一个前后端分离的微信小程序奶茶点餐系统:后端用 SSM 框架,后台管理页面由 Vue 构建,用户端是微信小程序,数据库 MySQL,JDK 1.8,开发工具 Eclipse、MyEclipse、STS、IDEA 都能跑。它覆盖商品管理、客服聊天、商品评价、商品订单、新闻公告五个业务模块,附带的材料包含源码、数据库脚本、论文、答辩 PPT、开题报告、环境工具包和同框架项目的安装教程。适合两类人:一类是毕设选题往小程序方向走的 Java 方向在校生,另一类是想在本地快速搭一个点餐系统原型做验证的开发者。

2. SSM 后端与 MySQL 初始化:数据表、连接串和 Tomcat 启动的三处修改

2.1 为什么这套后端选 SSM 而不是 SpringBoot

先给结论:这套源码是标准 Maven 工程,控制器层用 SpringMVC,业务对象由 Spring 容器管理,数据层走 MyBatis 的 XML Mapper。微信小程序端和 Vue 后台发来的请求,经过 DispatcherServlet 分发给 Controller,Controller 调 Service,Service 调 Mapper,Mapper 里的 SQL 最终打到 MySQL。对毕设答辩而言,这种三层链路非常好讲:一个请求从进到出经过了哪几个类、SQL 写在哪个 XML 里,全程白纸黑字看得见。

SpringBoot 把大量配置收进 starter 里,查询逻辑藏在注解背后,很多同学被问“你自己写的 SQL 在哪”时答不上来。SSM 工程的好处是 mapper.xml 和 Service 实现类都摆在明面上,甚至可以在答辩 PPT 里放一张 Controller→Service→Mapper 的调用链截图。另外,这套工程既然定级在 JDK 1.8,Tomcat 建议用 8.5 或 9,不建议用 Tomcat 10,否则javax.servlet包名不兼容会导致项目起不来,这个坑我放在第 5 章单独说。

2.2 数据库脚本与核心表结构

这套系统从业务上可以拆成五个模块,数据库脚本里对应的核心表我列一下,方便你导入后先有个全局认知。

表名对应模块关键字段说明
goods商品管理id、name、category_id、price、image、statusstatus 控制上架/下架
member用户管理id、openid、nickname、avataropenid 是微信登录的唯一标识
orders订单管理id、order_sn、member_id、total_amount、statusstatus 区分待支付/已支付/已完成
order_detail订单明细id、order_id、goods_id、quantity、price一个订单对应多条明细
comment商品评价id、order_id、member_id、content、rating评价审核逻辑在后端 Service 里
chat_message客服聊天id、from_user_id、to_admin_id、content、create_time用户与后台管理员之间的会话
news新闻公告id、title、content、create_time小程序首页轮播下的公告位

拿到数据库脚本后,第一步是用 Navicat 或命令行执行整个 SQL 文件。执行前看一眼文件开头的CREATE DATABASE语句,确认库名。很多同学直接双击导入,结果表建进了默认库,后端连接串又指向另一个库,查出来全是空数据。顺手在 SQL 文件里搜索INSERT INTO,你能看到脚本自带的初始数据,比如几杯奶茶、几个用户、几条评价,这些数据后面演示时会非常有用。

这里要提醒一句:这套工程用的是原生 MyBatis,不是 MyBatis-Plus。如果你平时习惯了用 MyBatis-Plus 根据实体类反向生成建表 SQL 的思路,在这个工程里别套用。工程的 mapper.xml 全是手写的 resultMap 与字段对应关系,实体类一旦加了字段而 SQL 没同步,运行时不报错,但查询结果里那个字段永远是 null,排查起来很费劲。

2.3 导入工程与连接数据库的三处修改

环境工具包里应该有 JDK 1.8 和 MySQL 的安装介质。先保证本机java -version输出的是 1.8,然后用 IDEA 的File → New → Project from Existing Sources选择 Maven 工程导入,或者在 Eclipse 里Import → Maven → Existing Maven Projects。导入后等 Maven 把依赖拉完,目录里通常有 root 和 web 两个子模块,真正要部署的是带src/main/java和src/main/webapp的那个 web 模块。

连接数据库的配置文件名一般是jdbc.properties或db.properties,以你解压出来的实际情况为准。我在本地环境通常是把配置改成下面这样:

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/milktea?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8 jdbc.username=root jdbc.password=123456

这段配置里三个参数值得说明:库名milktea必须跟 SQL 脚本里CREATE DATABASE的名字一致,不一致直接报Unknown database;serverTimezone=Asia/Shanghai是 MySQL 8.x 的必备参数,不写会报时区错误,具体报错现场见第 5 章;useSSL=false是本地开发关掉 SSL 握手,不然每次连接都会慢几十毫秒,调试阶段没必要开。characterEncoding=utf8保证中文不乱码,尤其是商品名、评价内容这类带 Emoji 的文本。

改完配置就可以启动 Tomcat。IDEA 里Edit Configurations → Tomcat Server → Local,Deployment 里加war exploded,Application context 填/。启动后控制台出现Artifact is deployed successfully就说明后端起来了。这时候访问http://localhost:8080理论上能看到后台页面,如果页面 404,多半是 Deployment 里没把 webapp 目录或构建产物加进去,这个问题在第 3 章讲 Vue 后台时一起解决。

3. Vue 后台管理端:npm 工程怎么起、接口转发与 token 鉴权

3.1 先分清编译产物与源码目录

解压目录里那些app.63641066.css、chunk-vendors.6d894868.css、main.css.bak确实容易劝退人,但它们其实都是 Vue 工程npm run build之后的产物,源码藏在src目录里。1-install.bat对应npm install,2-run.bat对应npm run serve,3-build.bat对应npm run build,三个脚本名字起得直白,说明作者打包时已经考虑过“让小白也能跑起来”。

把压缩包里 Vue 后台那份工程单独解压出来,目录结构大致是这个样子:

├── src │ ├── api # 接口请求封装,按模块拆文件 │ ├── router # 路由表,登录拦截在这里 │ ├── views # 页面组件:商品、订单、评价、客服、新闻 │ ├── components # 公共组件:侧边栏、头部、上传组件 │ ├── utils # request.js,axios 实例 │ ├── App.vue │ └── main.js ├── package.json ├── vue.config.js └── dist # 打包产物,就是源码包根目录那一堆 css/js

main.css.bak这种文件是上一轮编辑器的备份文件,可以直接删掉,不影响工程。真正要改的是vue.config.js、src/utils/request.js和src/api下的接口地址前缀。

3.2 启动后台命令与 devServer 转发配置

启动 Vue 后台前先确认本机有 Node.js,版本建议 12 以上。然后在工程根目录执行:

npm install npm run serve

第一条命令是安装依赖,根据网络情况可能要几分钟,装完后目录里会多出node_modules文件夹。第二条命令启动开发服务器,默认端口一般 8081,如果报端口占用,说明上一个前端进程没杀干净,具体处理看第 5 章。启动成功后终端会打印Local: http://localhost:8081/,浏览器打开这个地址就是后台登录页。

这里有一个非常关键的文件。后台工程和后端是分离的,浏览器访问 8081 端口,后端在 8080 端口,直接请求必然跨域。作者在vue.config.js里做了转发配置,常见写法如下:

const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ devServer: { port: 8081, proxy: { '/dev-api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/dev-api': '' } } } } })

这段配置解释起来不复杂:前端请求路径里只要带/dev-api前缀,devServer 就会把请求转发给8080端口,也就是本机的 SSM 后端。changeOrigin: true的含义是让后端感觉这个请求来自同源,避免某些校验 Origin 的拦截器把请求干掉。pathRewrite把/dev-api这个前缀在转发时去掉,因为后端接口路径里并没有这个前缀。

很多人在这一步翻车的原因是改了端口号但忘了同步改request.js里的baseURL。如果baseURL写的是绝对地址http://localhost:8080,那 proxy 根本不会生效。我一般会统一规定:开发环境baseURL用相对路径/dev-api,所有接口请求都走 devServer 转发;生产环境才改成后端完整地址。

3.3 axios 封装与登录 token 链路

后台登录之后,所有操作接口都得带 token,否则后端拦截器直接 401。token 的存取逻辑集中在src/utils/request.js里,常见封装长这样:

import axios from 'axios' const service = axios.create({ baseURL: '/dev-api', // 开发环境走 devServer 转发 timeout: 10000 }) // 请求拦截器:从 localStorage 取 token,放到请求头 service.interceptors.request.use(config => { const token = localStorage.getItem('bk_token') if (token) { config.headers['Authorization'] = token } return config }) // 响应拦截器:401 直接踢回登录页 service.interceptors.response.use( res => res.data, err => { if (err.response && err.response.status === 401) { localStorage.removeItem('bk_token') window.location.href = '/login' } return Promise.reject(err) } ) export default service

这段代码有两处值得说明。Authorization这个请求头字段必须跟后端拦截器里取的字段名一致,有些后端写的是token,有些写的是Authorization,对不上就会一直 401。bk_token是 localStorage 的 key,可以改,但改了之后登录页存 token 的地方也要同步改,漏一处就会陷入“登录成功,刷新又回到登录页”的死循环。

后台管理端的功能按五个模块展开:商品管理是增删改查和图片上传,订单管理是列表和状态流转,评价管理一般是审核和回复,客服聊天是管理员回复用户消息,新闻公告是维护首页展示的公告内容。这些页面在src/views下都能找到对应目录,数据结构是服务端接口返回的 JSON,字段名跟第 2 章里的表结构一一对应。

4. 微信小程序端:导入工程、接上后端与点餐主流程闭环

4.1 导入小程序工程要改的两处

微信小程序端是单独的工程目录,解压后用微信开发者工具直接Import Project选中该目录。AppID 有两个选择:有正式小程序账号就填自己的 AppID,没有就点“测试号”。测试号不影响本地调试,但会影响后面提到的登录换 openid,所以最佳实践是先去微信公众平台注册一个个人小程序,拿到 AppID 填进去。

导入后先别急着跑,先干两件事。第一件,打开app.json,看第一页是不是首页路径,如果指定的是某个不存在或路径写错的页面,工具会直接白屏报错。第二件,打开app.js或utils/config.js,找到BASE_URL全局变量,这个变量就是小程序请求后端接口的基础地址。

4.2 baseURL 改造与登录体系

本地调试时,小程序跑在开发者工具里,后端跑在电脑的 8080 端口,接口地址一定是http://局域网IP:8080而不是http://localhost:8080。原因很简单:真机预览时手机和电脑不在同一个进程里,localhost指向的是手机自己。我一般是这么改配置的:

// app.js 中的全局配置 const BASE_URL = 'http://192.168.1.108:8080' // 改成你电脑的局域网 IP,手机和电脑必须在同一 WiFi

改完再用开发者工具右上角详情 → 本地设置,勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。这个开关是本地调试专属,不勾的话请求会被微信拦截,报request:fail。

登录链路是毕设答辩时很容易被追问的点。微信小程序登录获取手机号,现在不便用纯前端模拟,标准做法是前端调wx.login拿code,把code发给后端,后端拿 AppID、AppSecret 和 code 去微信接口code2Session换openid,然后以openid作为用户唯一标识入库。手机号需要用户在界面上点授权按钮触发bindgetphonenumber事件,拿到encryptedData和iv后再由后端解密。这套流程里最容易出问题的是后端配置的 AppID 和前端不一致,报错场景在第 5 章有现场记录。

4.3 点餐主流程与自定义顶栏

小程序端的核心闭环是这样的:首页轮播图和分类导航展示商品 → 进入商品详情页点击加购 → 购物车页提交订单 → 支付(毕设阶段一般模拟支付成功)→ 订单状态回查,同时可以发起评价和客服聊天。这个闭环覆盖了商品、订单、评价、客服四个模块,新闻公告模块通常放在首页底部或者单独一个 Tab。

加购和下单的请求代码,正常来说会封装在src/api/order.js或pages/cart/cart.js里。以加购接口为例,大概长这样:

// 加入购物车 addToCart(goodsId, quantity) { return new Promise((resolve, reject) => { wx.request({ url: `${BASE_URL}/cart/add`, method: 'POST', data: { goodsId, quantity }, header: { 'Content-Type': 'application/json' }, success: res => { if (res.data.code === 200) { resolve(res.data) } else { reject(res.data) } }, fail: err => reject(err) }) }) }

这段代码里有几个细节:BASE_URL必须提前定义,我的写法是在app.js的globalData里挂一个BASE_URL,页面试图通过getApp().globalData.BASE_URL取;data里的字段名要和后端CartController的入参类对上,goodsId大小写不一致会直接报参数绑定错误;code === 200的判断要和后端统一,有些后端返回的是code: 0或code: 20000,不一致时前端会一直走 reject 分支。

再提一个搜索引擎上经常被搜到的问题:微信小程序顶部导航栏高度。这套工程的首页大概率设置了navigationStyle: custom自定义导航,以便把奶茶店 logo 和搜索框做到状态栏里。自定义导航最麻烦的是适配刘海屏,胶囊按钮的位置每台手机都不一样。正确做法是用wx.getMenuButtonBoundingClientRect()拿到胶囊按钮的坐标和高度,再用wx.getSystemInfoSync()拿到状态栏高度,两者相加算出自定义导航栏的 padding。抖音上一堆教程教你硬写 64px 或 88px,换成 iPhone 15 Pro Max 直接顶到灵动岛里,调试时一定用真机预览,别只信模拟器。

5. 避坑排查:换皮前不看就会翻车的五个现场

5.1 后端启动报数据库时区错误

现象:Tomcat 启动过程中抛异常,日志里出现The server time zone value '???É?±??×??' is unrecognized或java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized。

原因:MySQL 8.x 驱动要求连接串显式指定时区,而工程里默认的jdbc.url没带serverTimezone参数。

解决:在jdbc.properties的 url 末尾追加?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8,重启 Tomcat。如果本机 MySQL 是 5.7,不会报这个错,但加上也无副作用。

5.2 小程序端白屏或接口全部request:fail

现象:小程序编译成功,页面空白;或者有页面但请求全部失败,报request:fail。

原因:没在开发者工具里勾选“不校验合法域名”;或者BASE_URL写成了localhost,真机预览时手机无法访问电脑的localhost。

解决:开发者工具右上角详情 → 本地设置 → 勾选不校验合法域名;把BASE_URL改成电脑的局域网 IP,同时确认手机和电脑连的是同一个 WiFi。如果改了 IP 还连不上,检查电脑防火墙是否放行了 8080 端口,Windows 下用ping 电脑IP先确认网络通不通。

5.3npm run serve报端口占用

现象:执行启动命令后报EADDRINUSE: Address already in use :::8081。

原因:上一次的 devServer 进程没杀干净,或者本机已经有其他程序占了 8081 端口。

解决:改端口,可以在vue.config.js里把port改成 8082;如果想保留 8081,在 Windows 命令行执行netstat -ano | findstr 8081查出占用进程的 PID,再taskkill /F /PID 该PID。改完端口记得同步检查request.js的baseURL,如果写死了http://localhost:8081,以后每次换端口都要改。

5.4 图片上传成功但页面 404

现象:后台商品管理里上传商品图片,提示成功,但前端页面图片打不开,控制台显示GET /upload/xxx.jpg 404。

原因:上传代码把图片写到本地磁盘某个目录,比如D:/upload,但 Tomcat 并没有把这个目录映射成 URL 可访问的静态资源路径。

解决:有两种常见做法。一种是把上传目录直接改成工程内的webapp/static/upload,随项目一起走,适合毕设这种小体量场景。另一种是在 Tomcat 的server.xml的Host节点下加一段Context配置,把D:/upload映射到 URL 路径/upload,改完重启 Tomcat。第一种方案更省事,我倾向于推荐它,毕竟答辩时没人关心你的图片存在哪里,能显示就行。

5.5 微信登录code2Session报错

现象:小程序点击登录按钮,后端日志提示appid or secret is not valid,或者code 无效。

原因:三个值不一致。后端配置文件里写死的 AppID、AppSecret 和小程序开发者工具里填的 AppID 对不上。还有一种情况是 AppSecret 填错了,这种错误前端的表现是“请求成功但登录失败”,非常隐蔽。

解决:登录微信公众平台,在开发 → 开发设置里复制 AppID 和 AppSecret,替换工程里的对应配置。注意 AppSecret 只能完整查看一次,如果之前重置过,要用新值。另外,如果后端是多租户设计,要确认code2Session请求里传的是当前小程序对应的 AppID,而不是后台管理端自己的。

6. 换皮与答辩技巧:演示前按这个顺序过三遍

6.1 换皮清单

拿到源码第一件事永远是让系统先跑通,跑通之后再换皮。换皮是拿高分的关键,但换得不好反而扣分。我一般按这个顺序操作:先改数据库里的店铺名称和新闻公告,让小程序首页看不出“这是从别处下架的”;再替换商品图片和价格,奶茶图片建议宽度 750px 左右,比例 1:1,太大加载慢,太小模糊;然后改后台登录页的标题和 logo,把 Vue 工程里public/index.html和src/layout组件里的默认文字全部搜一遍;最后预置几条初始评价数据,让商品详情页看起来有真实感。

换皮时最容易漏的是小程序端project.config.json里的appid和后端配置里的 AppID,以及各种写死在代码里的localhost。我习惯在改完所有配置后,用全文搜索功能搜一遍/api和http://,把漏网的绝对地址全部揪出来,这个习惯救了我很多次。

6.2 演示顺序

答辩现场演示最忌讳边点边找功能,我建议按“用户下单 → 后台处理 → 数据验证 → 评价闭环”的顺序走。先把 MySQL、SSM 后端、Vue 后台、小程序四端全部拉起,小程序端用真机预览,不要用模拟器,模拟器在某些老师眼里等于“没做真机适配”。演示时先在小程序端选一杯奶茶加购下单,切换到后台管理端刷新订单列表,看到新订单后把状态改为“已发货”或“已完成”,再回到小程序端完成评价并发送一条客服消息,最后打开 Navicat 看一眼orders表的新增记录,形成完整闭环。

这个顺序的价值在于:每一步都能被老师看见,且每一步都有后端日志和数据库记录兜底,就算接口请求超时,你也可以从日志里找到证据说明代码逻辑没问题。答辩 PPT 里不用放太多代码,放一张三端架构图和一张时序图,把“小程序 → SSM → MySQL 的数据流向”讲清楚,比贴十页代码有用。

6.3 我踩过的最后一个坑

这套资源我前后帮着拆过三次,最后一次翻车是在答辩前一天:后端能启动,小程序能进首页,但登录一直失败,查了两个小时才发现后端配置里写的是别人的 AppSecret,而我拿自己的 AppID 去对,当然对不上。从那以后,我每次拿到一套新的毕设源码,第一件事不是跑起来,而是先检查数据库脚本里的库名、jdbc.properties里的连接串、后端配置里的 AppID,最后才谈得上启动和演示。这套排查顺序帮我避开了绝大多数“看起来能跑但一演示就崩”的尴尬,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询