首页 / 资讯中心 / 文章详情

SpringBoot+Vue无人智慧超市管理系统:从架构到部署全解析

SpringBoot+Vue无人智慧超市管理系统:从架构到部署全解析 ★ FEATURED ARTICLE
最近这段时间找我聊毕业设计的人不少问来问去绕不开一个选题SpringBoot Vue 的无人智慧超市管理系统。这确实是代码量适中、完整性高、答辩好讲、又能往简历上写一笔的经典方向。其实换个名字像自助便利店管理系统校园智慧商店平台内核是一模一样的一套进销存 订单 会员后台加一层无人自助购物的业务包装。适合做毕设、课设也适合想快速掌握前后端分离全流程的同学当练手项目。我帮学生拆过很多套这类源码也自己梳理过完整的开发路线。这篇就把它的功能拆解、技术选型逻辑、从零启动步骤、核心代码实现和最常见踩坑点全部摊开讲给正在对着源码发愁的你一份看得懂、能复现、会答辩的实操笔记。1. 这个项目到底在做什么无人超市管理系统的功能拆解1.1 所谓无人智慧超市本质上是一套什么系统先把概念捋清楚。无人超市不等于纯靠人工智能撑着大部分毕业设计里的无人体现在用户自主进店、自助选品、自助结算、自助支付这几段流程上。后台真正承担绝大部分业务的还是经典的管理系统三件套商品、订单、用户。换句话说你拿到手的这套源码核心是解决两类角色的诉求。顾客端扫码/刷脸进入超市浏览商品加购物车在线或扫码支付支付完成离店。管理端维护商品信息、上下架、管理库存、处理订单、查看销售统计、管理会员和权限。毕设评分老师看重的不是你有没有真的接一台闸机而是业务闭环是否完整从商品录入到用户购物到支付结算到订单入库到库存扣减再到统计报表整条链路走通系统就能立住。很多做得好的项目还会加上人脸识别、扫码开门等模拟接口作为亮点展示。1.2 核心功能模块一览这套系统我常拆成六个模块来跟学生讲模块说明涉及角色用户与权限管理注册、登录、JWT鉴权、管理员/顾客身份区分顾客 管理员商品管理商品增删改查、分类、上下架、图片上传、价格库存管理员购物车模块加入购物车、修改数量、总价计算顾客订单与结算模块创建订单、模拟支付、订单状态流转、订单详情顾客 管理员库存管理商品库存扣减与回补库存预警管理员统计与报表销售趋势、商品排行、营业额统计管理员有的人可能还不理解为什么要单独分一个库存管理。我做课设时吃过亏只在商品表里改一个 stock 字段看起来没问题但订单一旦发生退款、取消库存没法精确回补最后对账全是漏洞。所以打包源码里如果带stock_log、order_detail这类明细表说明作者是真考虑过数据一致性的答辩时拿出来讲是稳稳的加分点。1.3 这个题目为什么适合毕设/课设第一业务规模适中。六个模块不多不少覆盖了 Java 后端、Vue 前端的常见知识点又不会复杂到一个人做不完。第二技术栈主流。SpringBoot MySQL 是企业里最常见的后端组合Vue 是目前需求量很大的前端框架这套组合写在简历上面试官基本都有共鸣。第三扩展性强。你可以往里面加支付模拟、人脸识别、大屏数据可视化、WebSocket 实时监控每加一个功能复杂度都可控。2. 技术选型为什么是 SpringBoot Vue MySQL2.1 前后端分离不是流行是分工和迭代需要有些同学会问为什么不用 JSP Servlet 一把梭我的回答是可以用但前后端分离的价值在无人超市这种项目里太明显了。管理端界面和顾客端的自助收银界面风格完全不同、更新频率也不同拆成两个独立端互不影响。前端通过 HTTP 接口调用后端数据后端只负责提供 JSON两边可以并行开发也是目前公司里最主流的分工模式。SpringBoot 提供 RESTful APIVue 负责页面渲染前端通过 axios 请求后端接口。你只要把接口约定好前端页面之间怎么跳转、后端接口怎么返回数据都各管各的。源码里基本上都是这个路子。2.2 后端选 SpringBoot 的底层逻辑SpringBoot 是 Spring 体系的开箱即用版本它解决了传统 Spring 项目配置地狱的问题。以我这个项目的经验最常用的几个 starter 你一定会碰到dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency写数据访问的时候我建议直接用 MyBatis-Plus而不是纯 MyBatis。理由特别现实毕设开发周期短MyBatis-Plus 的BaseMapper自带selectPage、selectById、insert等通用方法80% 的基础 CRUD 不用自己写 SQL。剩下复杂的多表统计查询再写 XML 或注解 SQL工作量直接砍半。网上很多热词也提到mybatisplus根据java实体类生成创建表的sql语句这个功能虽然实际项目不太用但研究一下可以加深对 ORM 映射的理解。2.3 前端为什么选 Vue 而不是其他框架Vue 在国内的生态积累很深Element UI / Element Plus 组件库把表格、表单、弹窗、分页、消息提示全都封装好了你不需要从零手写管理后台 UI三天就能把页面骨架搭完。Vue 的核心概念也不多数据绑定、指令、组件、路由、插槽、状态管理。无人超市管理端里最常用到的是这三种能力组件化商品表格、订单卡片、图表组件全部拆成独立.vue文件方便复用。路由/goods、/order、/user、/dashboard各自对应一个页面。插槽拿表格自定义操作列举例Element 组件提供的slot-scope能让你在表格里塞入编辑/删除/上下架按钮属于每个做管理系统的人都会用到的功能。前端代码里大量的v-if、v-for、:data、click都是 Vue 的基础语法。如果你在学 Vue 时卡住了建议先分清楚数据驱动视图这个核心理念别急着刷复杂组件。2.4 MySQL 与数据持久化别忽略字符集和时区MySQL 在这个项目里承担所有业务数据的落地。设计表的时候建议每张表都带create_time、update_time字符集统一采用utf8mb4排序规则用utf8mb4_general_ci或utf8mb4_unicode_ci否则商品名称里出现表情符号时直接报错。JDBC 连接串里也必须带时区参数我见过太多同学栽在这里后面章节会专门展开。2.5 权限设计JWT 拦截器 RBAC无人超市系统至少有两种身份管理员和普通顾客。不要把所有接口都做成登录即可访问的裸奔状态那样答辩时老师一问权限控制你就会露馅。推荐的做法是基于 RBAC角色-权限模型用户表存角色角色对应菜单权限后端用拦截器统一校验 JWT。JWT 的工作流程一句话能讲清用户登录成功后后端生成一个带签名、带过期时间的 token 返回给前端前端把 token 存在本地每次请求塞进请求头后端拦截器校验 token 合法性和角色权限。这样既不用在服务端维护 Session也符合前后端分离的架构。3. 环境搭建与项目首次运行实录3.1 版本选择能用比最新更重要先跟你说句大实话源码打不开、项目跑不起来八成不是代码的问题是环境版本对不上。很多同学一上来就装最新版 JDK、最新版 SpringBoot结果第三方依赖还没适配直接抛编译异常。我给的建议版本是这个组合稳定网上资料也多组件建议版本备注JDK1.8 或 11如果你的源码是 SpringBoot 2.x别用 JDK 17Maven3.6.3 以上管理后端依赖MySQL5.7 或 8.0注意 8.0 需要调整驱动和连接参数Node.js14.x 或 16.xVue2 项目别轻易用 Node 18Vue CLI4.x / 5.x看源码前端是 Vue2 还是 Vue3开发工具IDEA 2021 / VS Code前后端建议都放 IDEA 里很多真题源码是拿 SpringBoot 2.7 JDK8 写的。这种组合不新但非常稳Maven 仓库里的依赖几乎不会缺。有同学问springboot版本太高会不会有问题答案是会。SpringBoot 3.x 强制要求 JDK17部分老版 mybatis-plus、velocity 模板插件还没完全兼容你调试的时间比写项目的时间都长。一切以源码为准先看pom.xml里的 parent 版本。3.2 初始化数据库先建库再导数据拿到源码后通常在sql目录下会有supermarket.sql之类的脚本。打开 MySQL 命令行或 Navicat执行CREATE DATABASE IF NOT EXISTS supermarket DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE supermarket; SOURCE /你的路径/supermarket.sql;注意如果脚本文件里本身有建库语句就不用重复创建如果没有一定要先指定数据库再执行脚本否则会报未选择数据库的错误。导入成功后重点检查三张表的数据量商品表有没有测试数据、用户表有没有默认管理员账号、订单表是不是空的。没有测试数据的系统跑起来奇奇怪怪的后面演示都费劲。3.3 启动后端改配置是第一步后端工程导入 IDEA 后先把application.yml或application.properties里的数据库连接改成本机的server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/supermarket?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 你的数据库密码配置文件里的密码和库名是源码作者的本地环境不改的话一启动就报Access denied for user或Unknown database。改完之后点启动SupermarketApplication看到控制台出现 Spring Boot 的 Logo 和 Tomcat started on port(s) 8080后端就通了。3.4 启动前端npm install 是最大的一道坎前端目录一般是frontend或vue-web用 IDEA 里的 Terminal 或 VS Code 打开执行npm install听到这个命令你先有个心理准备这一步能卡住一半人。常见情况是下载太慢、报错node-sass、或者模块明明装了但运行时找不到。解决办法很简单先把 npm 源换成国内镜像npm config set registry https://registry.npmmirror.com再用npm install如果遇到node-sass相关的安装失败直接删掉package.json里的node-sass换成sass或用dart-sass兼容。装完后执行npm run serve看到App running at Localhost:8081具体端口以你自己为准浏览器打开地址输入管理员账号页面能正常显示数据和图表整个系统就算跑通进入正常的改业务加功能阶段了。4. 核心业务实现与关键代码走读4.1 表结构设计先看表再看代码拿到源码第一件事别急着翻代码先看表结构。我以这套系统的常见设计为例给你列几张核心表的字段思路userid、username、password、role、avatar、status、create_time。密码必须加密存储用 BCrypt 或 MD5盐都行。goodsid、name、category_id、price、stock、image、status、sales。categoryid、name、sort。cartid、user_id、goods_id、quantity关联商品表取实时价格。orderid、order_no、user_id、total_amount、status、pay_type、create_time。order_detailid、order_id、goods_id、goods_name、price、quantity。stock_logid、goods_id、change_type、quantity、create_time用于库存流水对账。一个核心原则订单表里要冗余商品名称和商品快照价格不能只存 goods_id否则商品以后改价或改名历史订单全部乱套。这就是快照思维能在答辩时体现你的数据设计能力。4.2 登录鉴权JWT 的生成与拦截器校验登录接口的代码逻辑并不复杂。前端把用户名密码发给后端后端查库比对密码然后生成 token 返回String token JWT.create() .withClaim(userId, user.getId()) .withClaim(role, user.getRole()) .withExpiresAt(new Date(System.currentTimeMillis() 2 * 60 * 60 * 1000)) .sign(Algorithm.HMAC256(your-secret-key));后端写一个拦截器AuthInterceptor实现HandlerInterceptor在preHandle里取request.getHeader(token)校验签名和过期时间。校验通过就把用户信息放到ThreadLocal或request上下文里后续 Controller 就能直接取当前登录用户。注意两个细节白名单放行/login、/register这类接口管理员接口要再判断一次角色防止普通用户把商品价格改了。4.3 商品管理MyBatis-Plus 的分页查询商品模块看似是 CRUD其实是整个系统的骨架。商品列表页需要分页、条件筛选和状态控制用 MyBatis-Plus 写这个分页查询非常省事public PageGoods pageGoods(int page, int size, String keyword, Long categoryId) { LambdaQueryWrapperGoods wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(keyword), Goods::getName, keyword) .eq(categoryId ! null, Goods::getCategoryId, categoryId) .orderByDesc(Goods::getCreateTime); return goodsMapper.selectPage(new Page(page, size), wrapper); }注意查询条件要动态拼接用like方法时第一个参数放布尔值关键词为空就不拼这个条件。很多同学一开始用狂堆if的写法代码又臭又长答辩投影到大屏上很难看。4.4 自助结算流程分布式事务思维的简化版无人智慧超市最能体现业务价值的是结算。你卖点是无人所以结算流程一定要清晰。我对这套系统的建议实现是顾客提交购物车中选中的商品前端请求/order/create。后端创建主订单状态设为待支付同时创建订单明细。调用支付模块支付接口可以模拟比如直接返回成功或对接支付宝沙箱。支付成功后订单状态改成已支付同时扣减商品库存写一条库存流水。如果支付超时或失败订单置为已取消库存不动。扣库存和生成订单之间必须加事务控制。写一个 Service 方法用Transactional注解任何一个数据库操作抛异常整个流程回滚Transactional(rollbackFor Exception.class) public Order createAndPayOrder(Long userId, ListCartItem items) { // 1. 生成订单 // 2. 扣库存 // 3. 生成库存流水 // 4. 模拟支付成功更新状态 }毕业设计阶段这个事务就能解决一致性问题。如果你还想更专业一点可以在简历或论文里写后续可引入 RabbitMQ 延迟队列处理超时未支付订单这句话本身就是项目亮点。4.5 前端关键模块axios 封装、路由守卫、表格插槽后端接口写好了前端得把页面串起来。这套系统的前端核心逻辑我拆成三块。axios 封装。直接在组件里写this.$http.get(...)很乱建议统一放在utils/request.js在请求拦截器里把 token 塞进去service.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers[token] token; } return config; });路由守卫。管理端页面必须登录才能访问用 Vue Router 的beforeEachrouter.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.path ! /login !token) { next(/login); } else { next(); } });表格插槽。Element UI 的表格加操作按钮这是每个管理系统都会用到的模式el-table-column label操作 width200 template slot-scopescope el-button typeprimary sizemini clickhandleEdit(scope.row)编辑/el-button el-button typedanger sizemini clickhandleDelete(scope.row)删除/el-button el-button sizemini clickhandleToggleStatus(scope.row) {{ scope.row.status 1 ? 下架 : 上架 }} /el-button /template /el-table-column组件里拿到的是scope.row也就是当前行数据你不需要自己再存一个当前选中行的变量。这个细节虽然很小但能把代码量压下来一截。5. 高频坑位排查与毕设答辩加分技巧5.1 常见报错速查表我帮学生看过的这套源码报错翻来覆去就那么几个。整理成表格给你遇到问题直接对着排查现象大概率原因解决方案Access denied for user rootlocalhost数据库密码不对改application.yml里的 Spring datasource 密码Unknown database supermarket没建库或库名不一致核对application.yml中的库名并创建数据库Server returns invalid timezoneMySQL 时区问题JDBC 连接串加serverTimezoneAsia/Shanghai端口被占用Port 8080 was already in use其他进程占用端口换server.port或杀掉占用进程跨域报错No Access-Control-Allow-Origin后端没配置跨域写一个 WebMvcConfigurer 配置addCorsMappings前端node-sass编译失败Node 版本和 node-sass 不匹配换成sass依赖或降 Node 版本npm 下载卡死或超时npm 源在国外换 npmmirror 镜像源中文乱码建库字符集不是 utf8mb4删库重建统一 utf8mb4连接串加characterEncodingutf85.2 必踩的一个坑SpringBoot 版本和 JDK 不匹配这是热词里出现率极高的点几乎每届都能碰到几个。如果你是 SpringBoot 2.x但用 JDK17 跑项目编译报cannot find symbol或某些类加载失败在排除依赖问题前先检查 JDK 版本。强烈建议把pom.xml里的 parent 版本一眼看明白parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version /parent如果项目用的是 2.7.x就老实配 JDK8/11不要上 JDK17。反过来如果项目是 SpringBoot 3.x则必须配 JDK17 及以上。这个匹配关系卡住了很多人一点都不夸张。5.3 跨域问题怎么看、怎么改前后端分离项目前端跑在 8081后端跑在 8080两个端口不一样浏览器就会发预检请求。后端不做跨域配置前端请求直接被拦截。最简单的配置是写一个 CORS 配置类我一般直接这么干Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET,POST,PUT,DELETE,OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }注意如果配了 JWT 拦截器要确保OPTIONS请求不需要经过拦截器否则前端预检请求都过不了。方法是在拦截器里直接放行HttpMethod.OPTIONS。5.4 毕设/课设答辩的项目包装技巧代码能跑是底线答辩才是拿高分的关键。我整理几个常用技巧你可以在自己的项目上直接套用。第一讲业务闭环不要只讲 我写了增删改查。讲到订单模块时把下单 - 扣库存 - 支付 - 对账 - 异常回滚这个完整流程串起来讲评委一下就知道你理解了业务。第二主动说异常处理。全局异常处理器RestControllerAdvice加上普通异常返回友好提示数据库异常记日志。光这一条就能说明你有生产意识。第三给系统留一两个可扩展的想象空间。比如在 README 里写未来可接入大屏数据可视化、引入 Redis 缓存热点商品、用 RabbitMQ 延迟队列处理超时订单这种写在文档里的扩展规划不用实现但能让老师看到你的思考。另外数据库设计时一定要加索引。商品表category_id和status是高频查询字段订单表order_no是唯一索引。这一条对你的 SQL 优化答辩帮助很大。5.5 我的实操体会源码不是终点跑通才是开始这套 SpringBootVue 的无人智慧超市管理系统源码最大的价值不是让你直接交差而是给你一个完整的、能跑通的参考骨架。最开始我也不建议你逐行去背代码那没有意义。正确做法是先跑通整个项目然后用断点去走一遍下单流程每走一步对照数据库里的表变化你很快就会明白前端一次点击、后端一次事务、数据库一条记录之间是什么关系。等这个流程熟悉了试着改几个功能比如加一个会员折扣你会发现改代码并不难难的是想清楚什么时候该改价格、什么时候该算折扣、日志记录在哪一步。这种从拿到项目到能魔改项目的过程比 HTML 背标签、Java 刷语法有意义得多。这套系统的题目虽然叫无人但它真正锻炼的还是数据管理和业务建模能力换个包装就是新的毕设换个需求就是新的项目经验。最后一句话送给你源码和教程都只是地图真正宝贵的是你从踩坑到爬出来的那段路。把每个报错、每个接口都吃透这套项目就是你的了。
阅读完成 · 觉得有帮助?
咨询建站