拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

微信小程序+Java鲜花销售毕设:从环境搭建到答辩亮点的完整链路

微信小程序+Java鲜花销售毕设:从环境搭建到答辩亮点的完整链路

简介:这是一套面向高校计算机相关专业学生的微信小程序+Java后端鲜花销售毕业设计完整资料,适合正在准备毕业设计或课程设计、需要真实项目练手的开发者。项目采用微信开发者工具、SSM框架、MySQL与B/S架构,划分管理员、用户、商家三种角色,覆盖首页、个人中心、用户管理、商家管理、鲜花信息与分类管理、管理员管理及系统管理等功能模块,游客无需登录即可浏览鲜花信息,后台则面向已登录用户提供销售数据维护能力。压缩包共1341个文件,约12.51MB,包含128个Java源文件、140个Vue组件、187个JavaScript脚本、90个WXSS与88个WXML页面文件,以及319张PNG图片、2个SQL数据库脚本和说明文档,前后端代码、静态资源与建库脚本齐全。目前已有235人学习下载,可作为毕业设计选题参考、课程设计模板或SSM与小程序联调的学习范例,帮助读者快速理解三端角色权限设计与鲜花电商业务流程。

1. 鲜花小程序毕设:从选题到跑通,一套能写进简历的完整链路

每年三四月,计算机专业的群里总有人问:有没有那种能跑起来、能答辩、代码量够、还不烂大街的毕业设计?鲜花销售小程序就是被问得最多的方向之一。它踩中了三个刚需:微信小程序前端门槛低、Java 后端生态成熟、业务逻辑(商品、订单、库存、支付)足够撑起一篇论文的技术章节。但真正动手时,多数人卡在同一个地方——网上搜到的源码要么跑不起来,要么缺数据库,要么前后端接口对不上,最后变成“改三天、报错三十个、放弃”。

这篇笔记不讲空泛的选题意义,只讲一件事:拿到一个「微信小程序 + Java 后端」的鲜花销售毕设,怎么从零把它跑通、改出亮点、避开答辩被问倒的坑。适合正在做毕设的本科生、需要快速验证技术栈的自学者,以及想拿一个完整前后端分离项目练手的 Java 新手。核心链路是:环境搭起来 → 数据库导进去 → 后端接口调通 → 小程序页面联调 → 加一个能写进论文的扩展点。

2. 技术选型:为什么是微信小程序 + Spring Boot,而不是别的

2.1 前端为什么选微信小程序而不是 Vue 或 uni-app

毕设场景下,前端选型的核心矛盾是「开发速度」和「答辩演示效果」。微信小程序原生开发(WXML + WXSS + JS)的优势在于:不需要配 webpack、不需要处理跨域代理、真机预览扫码即用。答辩老师看到的是手机上直接跑的应用,而不是浏览器里一个 localhost 页面,观感差距很大。

如果你已经会 Vue,也可以用 uni-app 写一套代码同时出小程序和 H5,但要注意:uni-app 打包微信小程序时,部分原生组件(如 map、canvas)的兼容性需要额外处理,毕设时间紧的话不建议给自己加难度。常见做法是前端用原生小程序,后端用 Spring Boot,两边通过 JSON 接口通信,结构清晰,论文里也好画架构图。

小程序端的页面结构一般包含这几个:首页(轮播图 + 鲜花列表)、分类页、商品详情页、购物车、订单确认、个人中心。其中首页列表加载更多是高频考点,后面会专门讲分页实现。

2.2 后端为什么用 Spring Boot + MyBatis-Plus 而不是 SSM

SSM(Spring + SpringMVC + MyBatis)是很多学校课程里教的老三样,配置量大,光 XML 就能写到你怀疑人生。Spring Boot 把 Tomcat 内嵌、自动配置、起步依赖都封装好了,一个application.yml加几个注解就能跑起来。MyBatis-Plus 在 MyBatis 基础上提供了BaseMapper和LambdaQueryWrapper,单表增删改查基本不用写 SQL。

对于鲜花销售这种业务,核心表就几张:用户表、鲜花商品表、分类表、购物车表、订单表、订单明细表。用 MyBatis-Plus 的代码生成器,五分钟能把实体类和 Mapper 全生成出来。数据库选 MySQL 8.0,字符集用utf8mb4,因为鲜花名称和描述里可能有特殊符号。

提示:JDK 版本建议用 8 或 11,Spring Boot 2.7.x 对这两个版本支持最稳。不要盲目上 JDK 17 + Spring Boot 3,部分旧版依赖会报javax包找不到的错误,毕设没必要折腾这个。

2.3 前后端分离的接口约定怎么定

前后端分离最容易翻车的地方不是技术,是约定。后端返回什么格式、前端怎么解析、错误码怎么定义,必须在写第一行代码前定好。我一般用这套统一响应结构:

{ "code": 200, "msg": "操作成功", "data": {} }

code为 200 表示成功,401 表示未登录,500 表示服务端异常。前端封装一个request.js,统一处理code不等于 200 的情况,弹出msg提示。这样后端改接口时,前端只需要关注data里的字段变化,不用每个页面都写一遍错误处理。

接口路径按资源划分:/api/goods/list、/api/cart/add、/api/order/create。登录用 JWT,token 放在请求头Authorization里,后端写一个拦截器校验。这套约定写进论文的“系统设计”章节,条理分明的。

3. 环境搭建与数据库导入:把项目跑起来的第一步

3.1 开发环境清单与版本锁定

毕设项目跑不起来,八成是环境版本不对。下面这套组合是我在多个项目中验证过的,直接照抄:

组件版本说明
JDK1.8 或 11编译后端
Maven3.6+依赖管理
MySQL8.0数据库
Redis5.0+缓存(可选,用于验证码和 token)
微信开发者工具稳定版小程序调试
IDEA2021+后端开发

Maven 的settings.xml记得配阿里云镜像,否则拉依赖能等到天黑。MySQL 安装时选自定义路径,不要带中文和空格,不然后面导入 SQL 文件可能报错。

3.2 数据库建库与 SQL 导入的完整命令

拿到源码后,先看sql文件夹里的.sql文件。常见做法是建一个名为flower_shop的数据库,字符集utf8mb4,排序规则utf8mb4_general_ci。命令行操作如下:

# 登录 MySQL mysql -u root -p # 创建数据库 CREATE DATABASE flower_shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 切换到该数据库 USE flower_shop; # 导入 SQL 文件(在 MySQL 命令行中执行) source /path/to/flower_shop.sql;

如果 SQL 文件里有CREATE DATABASE语句,直接source也行,但要注意文件里的库名和你application.yml里配的是否一致。导入完成后用SHOW TABLES;确认表都建好了。常见的有user、goods、category、cart、orders、order_detail这几张。

注意:如果导入时报Unknown collation: 'utf8mb4_0900_ai_ci',说明 SQL 文件是在 MySQL 8.0 高版本导出的,而你本地是 5.7。解决办法是把 SQL 文件里的utf8mb4_0900_ai_ci全部替换成utf8mb4_general_ci,再重新导入。

3.3 后端配置文件修改与启动验证

数据库导入后,打开后端项目,找到src/main/resources/application.yml,修改这几处:

spring: datasource: url: jdbc:mysql://localhost:3306/flower_shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver

serverTimezone必须配,否则连接 MySQL 8 会报时区错误。改完后在 IDEA 里找到主启动类(通常叫Application.java或FlowerShopApplication.java),右键 Run。控制台出现Started Application in x.x seconds就说明后端起来了。然后用浏览器访问http://localhost:8080/api/goods/list,能看到 JSON 数据返回,后端就算通了。

如果启动报Port 8080 was already in use,要么改端口,要么用lsof -i:8080找到占用进程杀掉。Windows 下用netstat -ano | findstr 8080查 PID,再在任务管理器里结束。

4. 小程序端联调:从首页列表到购物车下单

4.1 首页鲜花列表分页加载的实现

首页列表是小程序里最核心的页面,也是热搜词里“微信小程序页面列表加载更多”的直接对应点。实现思路是:页面data里维护page、pageSize、hasMore、list四个变量,onLoad时调第一页,onReachBottom时加载下一页。

// pages/index/index.js Page({ data: { list: [], page: 1, pageSize: 10, hasMore: true }, onLoad() { this.loadGoods(); }, // 触底加载更多 onReachBottom() { if (!this.data.hasMore) return; this.setData({ page: this.data.page + 1 }); this.loadGoods(); }, loadGoods() { const { page, pageSize, list } = this.data; wx.request({ url: 'http://localhost:8080/api/goods/list', data: { page, pageSize }, success: (res) => { if (res.data.code === 200) { const newList = res.data.data.records; this.setData({ list: list.concat(newList), hasMore: newList.length === pageSize }); } } }); } });

onReachBottom是小程序页面生命周期函数,用户滚动到底部时自动触发。hasMore的判断逻辑是:如果本次返回的数据条数等于pageSize,说明可能还有下一页;小于pageSize则没有更多了。后端分页用 MyBatis-Plus 的Page对象,返回的records就是当前页数据。

提示:开发阶段小程序请求localhost需要在微信开发者工具里勾选“不校验合法域名”。上线时才需要配置 HTTPS 域名,毕设答辩用开发者工具演示即可。

4.2 购物车与订单接口的联调要点

购物车的逻辑比列表复杂,涉及“添加商品”“修改数量”“删除”“选中状态”四个操作。后端接口设计成:

  • POST /api/cart/add:参数goodsId、count
  • PUT /api/cart/update:参数cartId、count
  • DELETE /api/cart/delete/{cartId}
  • GET /api/cart/list:返回当前用户的购物车列表

用户身份从 JWT token 里解析,不要前端传userId,否则答辩时老师问一句“这样安全吗”你就答不上来了。订单创建接口POST /api/order/create需要处理库存扣减,这里必须用事务,否则并发下会出现超卖。代码结构如下:

@Service public class OrderServiceImpl implements OrderService { @Transactional(rollbackFor = Exception.class) public Order createOrder(Long userId, List<CartItem> items) { // 1. 校验库存 for (CartItem item : items) { Goods goods = goodsMapper.selectById(item.getGoodsId()); if (goods.getStock() < item.getCount()) { throw new BusinessException("库存不足:" + goods.getName()); } } // 2. 扣减库存 for (CartItem item : items) { goodsMapper.decreaseStock(item.getGoodsId(), item.getCount()); } // 3. 生成订单和订单明细 // ... 省略具体代码 return order; } }

@Transactional注解保证三步操作要么全成功,要么全回滚。rollbackFor = Exception.class确保任何异常都触发回滚,默认只回滚RuntimeException,不写这个可能踩坑。

4.3 前后端接口对不上的排查方法

联调时最常见的报错是400 Bad Request和500 Internal Server Error。排查顺序:

  1. 打开微信开发者工具的 Network 面板,看请求的 URL、参数、请求头是否正确。
  2. 看后端控制台有没有异常堆栈,NullPointerException通常是某个字段没传或数据库查不到。
  3. 用 Postman 单独调后端接口,排除是小程序端的问题还是后端的问题。
  4. 检查Content-Type是否为application/json,POST 请求 body 格式对不对。

如果后端返回401,检查请求头里有没有带 token,以及 token 是否过期。JWT 一般设 7 天过期,开发阶段可以设长一点,免得频繁登录。

5. 避坑与常见问题:那些答辩前夜还在改的 bug

5.1 图片上传后小程序不显示

现象:后台上传鲜花图片成功,数据库里也有路径,但小程序端image组件显示空白。

原因:后端把图片存到了本地磁盘(如D:/upload/),返回的 URL 是http://localhost:8080/upload/xxx.jpg,但小程序端请求图片时没有走同一个域名,或者后端没有配置静态资源映射。

解决:在后端加一个配置类,把上传目录映射为静态资源路径:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:D:/upload/"); } }

这样http://localhost:8080/upload/xxx.jpg就能访问到本地文件。小程序端image的src直接拼这个完整 URL。

5.2 订单列表查出来是空的

现象:用户下单成功,数据库orders表里有数据,但小程序订单列表页显示“暂无订单”。

原因:查询订单时用了userId作为条件,但前端请求时没有传userId,或者后端从 token 里解析出的userId和下单时的userId不一致。常见于测试时换了账号登录,但 token 没更新。

解决:在订单查询接口里打印当前登录用户的 ID,和数据库里的user_id对比。如果是 token 解析问题,检查 JWT 工具类的getUserId方法是否正确读取了claims。测试时清掉小程序缓存重新登录。

5.3 MySQL 8 连接报时区错误

现象:后端启动时报The server time zone value '?D1ú±ê×?ê±??' is unrecognized。

原因:MySQL 8 的默认时区是 UTC,而 JDBC 连接串里没有指定serverTimezone,或者指定了但值不对。

解决:在application.yml的url后面加上serverTimezone=Asia/Shanghai。如果还是报错,去 MySQL 命令行执行SET GLOBAL time_zone = '+8:00';然后重启 MySQL 服务。

5.4 小程序真机预览请求失败

现象:开发者工具里一切正常,手机扫码预览时接口全部报错。

原因:手机和电脑不在同一个局域网,或者电脑防火墙拦截了 8080 端口。另外,小程序真机调试时localhost指向的是手机本身,不是你的电脑。

解决:把小程序请求的baseUrl改成电脑的局域网 IP,如http://192.168.1.100:8080。确保手机和电脑连同一个 WiFi,Windows 防火墙里放行 8080 端口。答辩演示时如果教室网络不稳定,可以提前用手机热点组网。

5.5 论文查重时代码和数据库被标红

现象:论文里贴了大段实体类代码和建表 SQL,查重率飙升。

原因:代码和 SQL 语句在知网等系统里会被识别为重复内容,尤其是从网上直接复制的。

解决:论文正文里不要贴完整代码,用流程图和接口说明代替。必须贴的代码只保留核心逻辑(如订单创建的事务部分),变量名适当改写。数据库表设计用表格描述字段,不要贴CREATE TABLE语句。这样既降重,又显得你对系统理解更深。

6. 让毕设从“能跑”到“有亮点”:加一个数据统计看板

答辩时老师最常问的一句话是:“你这个系统有什么创新点?”如果只答“实现了增删改查”,分数不会高。一个成本低、效果好的加分项是:给后台加一个鲜花销售数据统计看板,用 ECharts 展示近 7 天订单量和销售额趋势。

后端加一个接口GET /api/stats/sales?days=7,返回日期和对应金额:

@GetMapping("/sales") public Result<List<SalesVO>> salesTrend(@RequestParam(defaultValue = "7") Integer days) { // 查询近 days 天的订单,按日期分组求和 List<SalesVO> list = orderMapper.selectSalesTrend(days); return Result.success(list); }

对应的 SQL 用DATE(create_time)分组:

SELECT DATE(create_time) AS date, SUM(total_amount) AS amount FROM orders WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL #{days} DAY) GROUP BY DATE(create_time) ORDER BY date;

小程序端用 ECharts 的微信小程序版本(ec-canvas),在后台管理页面渲染折线图。这个功能代码量不大,但论文里可以写“基于 ECharts 的数据可视化模块”,答辩时演示效果直观,老师一看就知道你确实动了手。

验证方法:手动在数据库里插入几条不同日期的订单,刷新看板,确认折线图有数据。如果图表不显示,检查ec-canvas的ec对象是否正确初始化,以及接口返回的日期格式是否和 ECharts 的xAxis.data匹配。

我自己的习惯是:每做完一个模块,先在 Postman 里把接口全部跑一遍,确认返回格式和字段名,再写小程序页面。这样联调时至少少一半的返工。毕设时间紧,别把精力浪费在“猜接口”上。希望帮到你。

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

返回列表