毕业设计实战:基于SpringBoot+Vue的鲜牛奶订购系统,从零到上线全流程拆解,附送避坑指南!
谁懂啊!当初做鲜牛奶订购系统毕设时,光“订单并发”和“库存扣减”问题就折腾了我一周——一开始没加数据库事务锁,结果同一瓶牛奶卖给了两个人,导师直接让我“重写库存管理逻辑”😫 今天把从需求分析到功能实现的全流程经验分享出来,跟着做就能轻松搞定毕设!
一、先搞懂“鲜牛奶订购系统要做什么”!需求分析是关键
刚开始我跳过需求分析就写代码,花两周做了个“智能推荐算法”,结果导师一句“核心是商家管理、库存控制、订单处理,不是推荐算法”直接打回重改!
1. 核心用户&功能拆解(实战总结版)
鲜牛奶订购系统有三类核心用户:管理员、商家、消费者,功能要区分清楚:
管理员端(系统管理):
- 商家管理:审核商家入驻、管理商家信息(营业执照、星级评定)、禁用违规商家
- 用户管理:管理消费者账号、重置密码、查看消费记录
- 公告管理:发布系统通知、管理公告内容
- 数据统计:销售额统计、热销商品分析、用户活跃度
商家端(商品管理):
- 商品管理:上架商品(名称、图片、价格、库存)、设置上下架、修改商品信息
- 库存管理:实时查看库存、设置库存预警、补货管理
- 订单管理:处理消费者订单(接单、发货、取消)、查看订单详情
- 评价管理:回复消费者评价、查看商品评分
- 数据统计:店铺销售分析、热销时段统计
消费者端(购物消费):
- 商品浏览:查看商家列表、浏览商品、按分类筛选
- 购物车:添加商品到购物车、修改数量、批量结算
- 下单支付:选择收货地址、确认订单、在线支付
- 订单管理:查看订单状态(待支付/待发货/已发货/已完成)、申请退款
- 个人中心:管理收货地址、查看余额、修改个人信息
2. 需求分析避坑指南(血泪教训!)
- 别一个人闷头想!找同学测试提意见:有同学说“想看到牛奶的保质期”,我才加了“生产日期/保质期”字段,比加“智能推荐”实用多了
- 一定要画用例图!用DrawIO画“消费者-下单支付”“商家-库存管理”等核心用例
- 写需求规格文档!约束条件要写清楚:“库存不能为负数”“订单15分钟未支付自动取消”“退款需在收货前申请”
3. 可行性分析要专业
导师最爱问“可行吗”,从3个角度回答:
- 技术可行:SpringBoot+Vue+MySQL都是成熟技术,资料丰富
- 经济可行:开发工具全免费,服务器可用学生优惠
- 操作可行:界面参考美团/饿了么,用户上手快
二、技术选型别追新!稳定最重要
刚开始我用微服务+Redis+MongoDB,结果配置复杂,本地都跑不起来😫 后来换成SpringBoot 2.7+Vue2+MySQL 8.0,真香!
1. 技术栈对比(附避坑提醒)
| 技术工具 | 为什么选它 | 避坑提醒! |
|---|---|---|
| SpringBoot 2.7 | 配置简单,内置Tomcat,生态完善 | 别用3.0!部分依赖不稳定 |
| Vue 2 | 生态成熟,Element UI组件丰富 | 别用Vue 3组合式API!增加复杂度 |
| Element UI | 组件齐全,开发效率高 | 按需引入,避免打包过大 |
| MySQL 8.0 | 支持事务,保证数据一致性 | utf8mb4编码必须设! |
| Redis(可选) | 缓存热点商品,提升性能 | 别强求!不加也能完成毕设 |
2. 开发环境搭建
# 后端spring init --dependencies=web,mybatis,mysql,jdbc,lombok milk-order# 前端vue create milk-order-frontendcdmilk-order-frontend vueaddelementnpminstallaxios vue-router vuex3. 架构图要画!答辩加分
用DrawIO画前后端分离架构图:
- 前端:Vue + Element UI + Axios + Vue Router
- 后端:SpringBoot + MyBatis + MySQL
- 存储:MySQL(业务数据)+ Redis(缓存)
- 部署:Nginx(反向代理)+ Docker(容器化)
三、数据库设计:库存管理是核心
这部分是系统的核心,我当初库存表设计不合理,并发下单就出问题。
1. 核心实体&ER图
核心表设计:
- 用户表(user):id、用户名、手机号、密码、头像、余额
- 商家表(merchant):id、商家名、联系方式、营业执照、星级、状态
- 商品表(product):id、商品名、图片、价格、库存、商家ID、保质期
- 购物车表(cart):id、用户ID、商品ID、数量、添加时间
- 订单表(order):id、订单号、用户ID、总金额、状态、创建时间
- 订单详情表(order_detail):id、订单ID、商品ID、数量、单价
- 收货地址表(address):id、用户ID、收货人、电话、地址、是否默认
- 评价表(comment):id、订单ID、用户ID、商品ID、评分、内容、时间
2. 建表SQL示例(关键表)
-- 商品表(核心业务表)CREATETABLE`product`(`id`intNOTNULLAUTO_INCREMENT,`merchant_id`intNOTNULLCOMMENT'商家ID',`name`varchar(100)NOTNULLCOMMENT'商品名称',`image`varchar(200)DEFAULTNULLCOMMENT'商品图片',`price`decimal(10,2)NOTNULLCOMMENT'单价',`stock`intNOTNULLDEFAULT0COMMENT'库存',`shelf_life`intDEFAULTNULLCOMMENT'保质期(天)',`production_date`dateDEFAULTNULLCOMMENT'生产日期',`status`intDEFAULT1COMMENT'状态(1-上架,0-下架)',`sold_count`intDEFAULT0COMMENT'已售数量',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,`update_time`datetimeDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`),KEY`idx_merchant`(`merchant_id`),KEY`idx_status`(`status`),CONSTRAINT`fk_product_merchant`FOREIGNKEY(`merchant_id`)REFERENCES`merchant`(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 订单表(业务核心)CREATETABLE`order`(`id`intNOTNULLAUTO_INCREMENT,`order_no`varchar(50)NOTNULLCOMMENT'订单号',`user_id`intNOTNULLCOMMENT'用户ID',`merchant_id`intNOTNULLCOMMENT'商家ID',`address_id`intNOTNULLCOMMENT'收货地址ID',`total_amount`decimal(10,2)NOTNULLCOMMENT'订单总金额',`actual_amount`decimal(10,2)NOTNULLCOMMENT'实付金额',`status`intDEFAULT0COMMENT'状态(0-待支付,1-已支付,2-已发货,3-已完成,4-已取消,5-已退款)',`payment_type`intDEFAULTNULLCOMMENT'支付类型(1-微信,2-支付宝,3-余额)',`payment_time`datetimeDEFAULTNULLCOMMENT'支付时间',`delivery_time`datetimeDEFAULTNULLCOMMENT'发货时间',`complete_time`datetimeDEFAULTNULLCOMMENT'完成时间',`cancel_time`datetimeDEFAULTNULLCOMMENT'取消时间',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),UNIQUEKEY`uk_order_no`(`order_no`),KEY`idx_user`(`user_id`),KEY`idx_merchant`(`merchant_id`),KEY`idx_status`(`status`),KEY`idx_create_time`(`create_time`),CONSTRAINT`fk_order_user`FOREIGNKEY(`user_id`)REFERENCES`user`(`id`),CONSTRAINT`fk_order_merchant`FOREIGNKEY(`merchant_id`)REFERENCES`merchant`(`id`),CONSTRAINT`fk_order_address`FOREIGNKEY(`address_id`)REFERENCES`address`(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 订单详情表CREATETABLE`order_detail`(`id`intNOTNULLAUTO_INCREMENT,`order_id`intNOTNULLCOMMENT'订单ID',`product_id`intNOTNULLCOMMENT'商品ID',`product_name`varchar(100)NOTNULLCOMMENT'商品名称(快照)',`product_image`varchar(200)DEFAULTNULLCOMMENT'商品图片(快照)',`price`decimal(10,2)NOTNULLCOMMENT'单价(快照)',`quantity`intNOTNULLCOMMENT'购买数量',`subtotal`decimal(10,2)NOTNULLCOMMENT'小计金额',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),KEY`idx_order`(`order_id`),KEY`idx_product`(`product_id`),CONSTRAINT`fk_detail_order`FOREIGNKEY(`order_id`)REFERENCES`order`(`id`),CONSTRAINT`fk_detail_product`FOREIGNKEY(`product_id`)REFERENCES`product`(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;3. 库存扣减方案(难点!)
方案一(简单版):UPDATE时检查库存
UPDATEproductSETstock=stock-#{quantity},sold_count=sold_count+#{quantity}WHEREid=#{productId}ANDstock>=#{quantity}方案二(推荐版):乐观锁+版本号
-- 商品表增加version字段ALTERTABLEproductADDCOLUMN`version`intDEFAULT0;-- 更新时检查版本UPDATEproductSETstock=stock-#{quantity},version=version+1WHEREid=#{productId}ANDstock>=#{quantity}ANDversion=#{oldVersion}方案三(高并发版):Redis预减库存 + 消息队列异步扣减
四、功能实现:核心模块详解
1. 下单支付模块(必做!难点)
核心流程:
- 用户提交订单 → 检查库存 → 锁定库存(可选)
- 生成待支付订单 → 跳转支付页面
- 支付成功 → 扣减库存 → 更新订单状态
- 支付失败/超时 → 释放库存 → 取消订单
关键代码逻辑:
// 下单逻辑(带事务)@TransactionalpublicResultcreateOrder(OrderCreateDTOdto){// 1. 检查收货地址Addressaddress=addressService.getById(dto.getAddressId());if(address==null||!address.getUserId().equals(getCurrentUserId())){returnResult.error("收货地址无效");}// 2. 检查商品库存(加锁防止超卖)List<OrderItemDTO>items=dto.getItems();for(OrderItemDTOitem:items){Productproduct=productService.getById(item.getProductId());if(product.getStock()<item.getQuantity()){returnResult.error("商品["+product.getName()+"]库存不足");}}// 3. 扣减库存(使用乐观锁)for(OrderItemDTOitem:items){introws=productMapper.reduceStock(item.getProductId(),item.getQuantity());if(rows==0){thrownewRuntimeException("库存扣减失败,请重试");}}// 4. 生成订单Orderorder=newOrder();order.setOrderNo(generateOrderNo());order.setUserId(getCurrentUserId());order.setAddressId(dto.getAddressId());order.setTotalAmount(calculateTotalAmount(items));order.setActualAmount(order.getTotalAmount());// 实际业务可能有优惠order.setStatus(0);// 待支付orderMapper.insert(order);// 5. 生成订单详情for(OrderItemDTOitem:items){Productproduct=productService.getById(item.getProductId());OrderDetaildetail=newOrderDetail();detail.setOrderId(order.getId());detail.setProductId(item.getProductId());detail.setProductName(product.getName());detail.setProductImage(product.getImage());detail.setPrice(product.getPrice());detail.setQuantity(item.getQuantity());detail.setSubtotal(product.getPrice().multiply(newBigDecimal(item.getQuantity())));orderDetailMapper.insert(detail);}returnResult.success("订单创建成功,请在15分钟内完成支付",order.getOrderNo());}2. 支付回调处理模块
支付流程:
- 前端调用支付接口 → 生成支付参数
- 跳转到支付平台(微信/支付宝)或模拟支付页面
- 支付完成 → 支付平台回调通知系统
- 系统验证签名 → 更新订单状态
模拟支付实现(毕设可用):
// 模拟支付接口@PostMapping("/pay")publicResultpay(@RequestBodyPayDTOdto){// 1. 查询订单Orderorder=orderService.getByOrderNo(dto.getOrderNo());if(order==null){returnResult.error("订单不存在");}// 2. 检查订单状态if(order.getStatus()!=0){returnResult.error("订单状态异常");}// 3. 检查支付金额if(order.getActualAmount().compareTo(dto.getAmount())!=0){returnResult.error("支付金额不正确");}// 4. 模拟支付成功order.setStatus(1);// 已支付order.setPaymentType(dto.getPaymentType());order.setPaymentTime(newDate());orderService.updateById(order);// 5. 发送支付成功通知(可选)notificationService.sendPaymentSuccess(order.getUserId(),order);returnResult.success("支付成功");}3. 库存预警模块(商家端)
功能要点:
- 实时显示库存情况
- 设置库存预警阈值(如:库存<10时预警)
- 自动提醒补货
- 库存变化日志
实现方案:
-- 库存预警查询SELECTp.name,p.stock,p.sold_count,m.nameasmerchant_nameFROMproduct pJOINmerchant mONp.merchant_id=m.idWHEREp.merchant_id=#{merchantId}ANDp.status=1ANDp.stock<=#{threshold}ORDERBYp.stockASC;4. 订单状态流转模块
状态设计:
- 待支付(0)→ 已支付(1)→ 已发货(2)→ 已完成(3)
- 待支付(0)→ 已取消(4)【用户取消】
- 已支付(1)→ 已退款(5)【用户申请退款】
状态机实现:
publicenumOrderStatus{UNPAID(0,"待支付"),PAID(1,"已支付"),SHIPPED(2,"已发货"),COMPLETED(3,"已完成"),CANCELLED(4,"已取消"),REFUNDED(5,"已退款");// 状态流转规则publicstaticbooleancanChangeTo(intfrom,intto){switch(from){case0:returnto==1||to==4;// 待支付只能→已支付或已取消case1:returnto==2||to==5;// 已支付只能→已发货或已退款case2:returnto==3;// 已发货只能→已完成default:returnfalse;}}}五、前端页面设计要点
1. 消费者端页面
- 首页:轮播图 + 商家推荐 + 热销商品
- 商家列表页:按星级/距离排序,显示商家评分
- 商品详情页:商品图片轮播、价格、库存、保质期、评价列表
- 购物车页:商品列表、数量修改、批量结算
- 订单确认页:选择收货地址、确认商品信息、选择支付方式
- 我的订单页:按状态筛选订单、查看订单详情、申请退款/取消
2. 商家端页面
- 商品管理页:商品列表、上架/下架操作、库存修改
- 订单管理页:订单列表、接单/发货操作、订单筛选
- 数据统计页:销售趋势图、热销商品排行、库存预警
3. 管理员端页面
- 商家审核页:待审核商家列表、查看营业执照、审核操作
- 数据看板:系统数据概览、用户增长趋势、销售统计
六、测试:这些场景必须测!
1. 功能测试用例
表1:下单流程测试
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 正常下单 | 选择商品→加入购物车→提交订单→支付 | 订单创建成功,库存扣减,状态流转正常 |
| 库存不足下单 | 商品库存1,下单数量2 | 提示"库存不足",下单失败 |
| 并发下单 | 两人同时下单同一商品(库存1) | 一人成功,一人失败,库存不出现负数 |
表2:支付流程测试
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 正常支付 | 待支付订单点击支付→完成支付 | 订单状态变已支付,商家可看到订单 |
| 支付超时 | 下单后15分钟不支付 | 订单自动取消,库存恢复 |
| 重复支付 | 对已支付订单再次支付 | 提示"订单已支付,请勿重复支付" |
2. 并发测试(重点!)
使用JMeter模拟场景:
- 100个用户同时抢购限量商品
- 50个商家同时处理订单
- 测试结果:系统不崩,数据一致,无超卖
3. 边界条件测试
- 价格边界:商品价格为0或负数
- 数量边界:购买数量为0或负数
- 时间边界:保质期已过的商品不能购买
七、部署与答辩准备
1. 项目打包部署
# 后端打包mvn clean package -DskipTests# 前端打包npmrun build# 部署(简化版)# 1. 上传jar包和dist到服务器# 2. 导入数据库脚本# 3. 启动后端:nohup java -jar milk-order.jar &# 4. 配置Nginx指向dist目录2. 答辩准备(3个加分技巧)
演示流程要顺畅:
- 消费者:注册→浏览商品→下单支付→查看订单
- 商家:登录→上架商品→处理订单→查看统计
- 管理员:审核商家→查看系统数据
重点讲技术难点:
- 如何解决"库存超卖"问题(乐观锁+事务)
- 如何设计"订单状态机"(状态流转规则)
- 如何优化"查询性能"(数据库索引+缓存)
准备常见问题:
- Q:为什么用SpringBoot不用SSM?
A:SpringBoot配置简单,开发效率高,适合快速迭代 - Q:实际应用中怎么改进?
A:①加Redis缓存 ②用消息队列异步处理 ③做读写分离 - Q:系统安全性如何保证?
A:①SQL注入防护 ②支付接口签名验证 ③敏感数据加密
- Q:为什么用SpringBoot不用SSM?
八、毕设文档结构
鲜牛奶订购系统/ ├── 毕业论文.docx # 完整论文(含所有章节) ├── 开题报告.docx # 研究背景、意义、计划 ├── 中期检查表.docx # 进度汇报 ├── 源码/ │ ├── backend/ # SpringBoot后端源码 │ ├── frontend/ # Vue前端源码 │ ├── sql/ # 数据库脚本(含测试数据) │ └── api/ # API接口文档 ├── 演示视频.mp4 # 10分钟功能演示 ├── 答辩PPT.pptx # 15分钟答辩展示 └── 部署文档.md # 系统部署说明最后:真心话时间
鲜牛奶订购系统是贴近生活的毕设选题,业务场景清晰,技术难点明确。关键是做好库存管理和订单流程这两个核心,处理好并发问题和数据一致性。
需要完整源码(带详细注释)、数据库脚本(含测试数据)、答辩PPT模板的同学,评论区扣"鲜牛奶订购",我发你。遇到具体技术问题(比如库存扣减、支付回调),也可以留言讨论!
这篇干货整理了我所有经验教训,点赞收藏,毕设路上不迷路!祝大家顺利毕业!🥛✨