简介:基于SpringBoot+Vue的鲜花商城系统是一套面向毕业设计的完整前后端分离项目,适合计算机专业学生或初级开发者作为课程设计与毕设参考。系统围绕用户、店家、管理员三类角色展开,覆盖注册登录、鲜花浏览与搜索(按花店、花名、用途、花语)、购物车、订单管理、评论收藏、公告与轮播图配置等典型电商功能,业务逻辑完整且层次清晰。压缩包内共90个文件,包含28个Java后端类、7个Vue页面组件、8个JS脚本、12个XML映射与配置、6个HTML页面、4个CSS样式以及图片资源等,整体大小仅4.38MB,结构紧凑便于快速部署。目前已有86人学习下载,对于需要快速搭建商城类毕设项目、理解SpringBoot+Vue整合流程的读者而言,这份源码能直观展示前后端分离项目的分层结构、接口调用方式与页面渲染逻辑,配有可直接运行的工程目录和说明文档,便于二次开发与答辩展示。
1. 收到这个 SpringBoot+Vue 鲜花商城压缩包,先搞清楚你拿到的是什么
花几十块从二手平台买来的、学长离职前从电脑里拷出来的、或者从 GitHub 上某个 star 数不高的仓库整包下载的,这份“基于 SpringBoot+Vue 的鲜花商城”,本质上就是一个 zip 压缩包。它值钱的地方不在代码有多少行,而在于你把它解压、启动、点一遍下单流程之后,能回答清楚答辩老师的三连问:系统里有几个角色、订单状态怎么流转、这一版你改了什么。标题里的“前职离婚”更像是卖家站贴的标签,跟代码本身没有关系,别被它带偏。
这个系统解决的是“前后端分离的电商小系统怎么做”的问题:SpringBoot 负责写接口和维护订单状态,Vue 负责商品展示、购物车和结算页,MySQL 里最核心的四张表是用户、商品、订单、订单明细。适合正在选题的计算机毕业生,也适合想快速上手一个完整前后端分离项目、毕业之后好拿得出手的初学者。整个落地过程会踩的坑,比你想象的更多,下面从解压开始,一步一步把它跑起来。
2. 本地跑通之前:环境选型与解压检查(SpringBoot+Vue 的最小可运行准备)
2.1 先定版本:Java、Node、Maven、MySQL 这四样最容易翻车
很多同学收到 zip 的第一反应是“双击解压、打开 IDEA、Run”,结果反手就被一堆红字劝退。我一般会先把版本定死:不是越新越好,而是跟你这个压缩包配套。原因也很好理解——SpringBoot 2.x 和 3.x 的底层包名都不一样,Vue 2 和 Vue 3 的创建方式也不一样,版本差一级,报错方式完全不一样。
先看后端根目录下的 pom.xml,这是最快的“验货”方式。如果依赖里出现 javax.servlet,那大概率是 SpringBoot 2.x;如果出现 jakarta.servlet,那是 SpringBoot 3.x。SpringBoot 2.x 建议用 JDK 8 或 11,SpringBoot 3.x 必须 JDK 17 起步,用 8 跑 3.x 会直接编译报错,换 JDK 版本本身又是半个小时的折腾。
前端也一样。Vue 2 项目里一般有 vue.config.js,Vue 3 项目里一般有 vite.config.js。Vue 2 + vue-cli 建议 Node 14 或 16,Node 18 以上跑 vue2 的老项目经常报 OpenSSL 错误;Vue 3 + Vite 用 Node 16/18/20 都行。拿到压缩包先别急着装依赖,用下面几条命令把底细摸清楚:
java -version mvn -v node -v npm -v mysql --version逻辑说明:这几条命令分别检查 JDK、Maven、Node、npm、MySQL 是否已安装,以及当前默认版本是多少。其中mvn -v会同时输出 Maven 版本和它依赖的 JDK 版本,如果这里显示的 JDK 和你的java -version不一致,说明 IDEA 或系统环境变量里还套了一层,后面跑后端很容易出现“命令行能编、IDEA 里爆红”的错位问题。
参数说明:mysql --version只显示客户端版本,不一定代表 MySQL 服务端版本。更准的做法是连接后执行select version();。如果你机器上的 JDK 版本和项目需要的对不上,不用卸载重装,用 IDEA 的 Project Structure 单独指定 SDK 就能避免把整个系统搞乱。
2.2 解压 ZIP 后第一眼要检查的文件清单
解压这一步也存在“翻车”可能,最常见的是中文文件名乱码。Windows 自带解压会按系统默认编码解压,部分压缩包是用 UTF-8 打包的,解出来全是乱码,这个乱码会一路传染到 IDEA 的项目名和代码注释里。常见做法是先用 Bandizip 或 7-Zip 这类支持选择编码的工具解压,看到乱码再换编码重新解压一次,比手动改文件名靠谱得多。
解压完成后,不要急着双击任何文件,先看目录长什么样。常规的整包形态有两种:一种是前后端混在一个文件夹里,后端叫 server 或 backend,前端叫 web 或 front;另一种是前后端分两个独立压缩包。不管哪种,进到根目录后我都会执行一遍:
cd flower-shop ls -la find . -maxdepth 2 -type d | sort逻辑说明:ls -la看根目录下有没有 README、sql 文件夹、pom.xml、package.json,find列出两层目录能让你快速判断这是 Maven 工程还是 Gradle 工程、前端用的是 webpack 还是 vite、有没有把不必要的上传文件混进来。
参数说明:-maxdepth 2表示只看两层目录,避免把 target 或 node_modules 里成千上万个文件也打出来。如果看到 node_modules 目录已经在压缩包里,建议果断删掉,拿到本机重新 npm install 一次——别人机器上装好的依赖拿到你机器上,版本和系统架构都可能对不上,留着只会让后续报错变本加厉。
这 4 样东西必须存在:后端 pom.xml、前端 package.json、数据库 SQL 脚本、README(或者至少有一处写了启动步骤)。缺任何一样,这个压缩包的完整度都要打问号。
2.3 初始化数据库与改连接配置:90% 的启动失败都卡在这
代码本身写得再烂,IDEA 也会帮你在语法上把关,但数据库连不上只能靠你自己排查。我之前拿到过一份“十块钱包”的毕业设计,解压后没有 sql 文件夹,翻遍代码才知道建表语句在 resource/db 目录下,文件名还叫 init.sql.template——这种模板文件不改名不导入,系统是不可能跑起来的。
找到 sql 文件后,先建库,再导表。SQL 脚本里可能已经包含建库语句,也可能没包含,稳妥做法是手动建一个空库:
CREATE DATABASE flower_shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后进入项目目录执行导入(如果脚本是 flower_shop.sql):
mysql -u root -p flower_shop < sql/flower_shop.sql逻辑说明:<是 MySQL 客户端从文件读取 SQL 执行,-p会提示你输入密码。字符集一律建议 utf8mb4,不要省那几行,否则商品名里带个 emoji 或者特殊符号就会出现乱码,答辩演示时商品名称显示成“???”特别尴尬。
参数说明:如果 mysql 命令不在系统 PATH 里,要换成 MySQL 安装目录下 bin 文件夹里的 mysql.exe 全路径。Windows 下也可以用可视化工具 DataGrip、Navicat 直接运行 sql 文件,效果一样,但命令行方式最适合写进毕业设计说明书里凑“部署步骤”那一节。
数据库就绪之后,改后端配置文件。SpringBoot 项目的配置一般在 src/main/resources/application.yml 或 application.properties 里,也可能被拆成 application-dev.yml / application-prod.yml。先看主配置里 spring.profiles.active 指向哪个环境,再去改那个文件:
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/flower_shop?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver逻辑说明:url 里 3306 是 MySQL 默认端口,flower_shop 是库名,serverTimezone=Asia/Shanghai 解决 MySQL 8 的时区报错,characterEncoding=utf8 保证中文写入不乱码。驱动类 com.mysql.cj.jdbc.Driver 是 MySQL 8 的写法,MySQL 5.7 则是 com.mysql.jdbc.Driver,如果版本对不上,启动时直接报 ClassNotFound。
参数说明:show-sql 建议先打开,跑通后再关掉,不然答辩演示时控制台刷屏影响观感。还有一处必须注意——ddl-auto 一定要保持 none。如果某个配置文件里写的是 update,项目启动时会自动按实体类来改表,字段名对不齐就可能把表结构改坏,遇到数据丢失就真没后悔药吃了。
提示:改完配置文件后重启后端,看到“Tomcat started on port(s): 8080”才算真正启动成功。如果报数据库错误,回头检查密码和库名,这是最常见的两个原因。
3. 前后端怎么对上:从下单到支付的一条完整链路
3.1 后端分包与四张核心表的关系
接下来要进入“看得懂代码”环节。先看后端的包结构,几乎所有的 com.xxx.flower 或 com.xxx.shop 目录下都是同一套路:entity(实体类)、mapper(数据库操作)、service(业务逻辑)、controller(接口入口)、config(配置类)。最快的熟悉方式不是逐行读代码,而是把实体类和数据库表对照着看一遍。
核心表的关系我用一张表说清楚:flower_user 存用户和角色,flower_goods 存商品、价格、库存、销量,flower_order 存订单号、下单用户、总金额、状态和收货地址,flower_order_item 存订单里每个商品的快照。购物车如果做了就额外有一张 flower_cart;如果后端没做,前端也会有 localStorage 版的购物车。关系也非常直白:用户 1 对多订单,订单 1 对多订单明细,商品与订单明细是多对多但通过快照字段弱化掉了。
订单状态是你答辩时一定会被问到的点,强烈建议先把状态流转画出来。我这里不画图,用文字说明:用户下单生成待付款订单,点击付款后变成待发货,管理员发货后变成待收货,用户确认收货后变成已完成,中间任何一步都可以取消。这几句话你如果能用代码指出来对应哪个字段、哪个 controller 方法,基本就是全场最扎实的那个。
3.2 前端 Vue 的路由、页面与购物车状态
前端这块,很多毕业设计用的是 Vue 2 + Vue Router,页面一般在 views 目录下。Login.vue、Home.vue、Cart.vue、Order.vue、Profile.vue 这五个页面构成了一个商城的最小闭环。看代码时先看路由文件,它决定了页面之间的“通行证”逻辑:
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const router = new Router({ mode: 'hash', routes: [ { path: '/login', component: () => import('@/views/Login.vue') }, { path: '/', component: () => import('@/views/Home.vue') }, { path: '/cart', component: () => import('@/views/Cart.vue'), meta: { requiresAuth: true } }, { path: '/order', component: () => import('@/views/Order.vue'), meta: { requiresAuth: true } } ] }) router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !localStorage.getItem('token')) { next('/login') } else { next() } }) export default router逻辑说明:mode 用 hash 表示地址栏里会带 #,好处是前端页面刷新不会 404,适合打包后扔进后端 static 目录的场景。component 用箭头函数返回 import 是路由懒加载,页面被访问时才加载对应组件,首屏更快。beforeEach 是全局前置守卫,没有 token 就踢回登录页,这就是你答辩时能讲的“登录鉴权”。
参数说明:如果你用的是 Vue 3,写法稍有不同,需要把 new Router 换成 createRouter、mode 换成 createWebHashHistory,但守卫逻辑完全一样。“动态路由”是加分项:从后端 /api/user/menus 拿到菜单列表后用 router.addRoute 动态注册,面试官问起 Vue Router 时能答到这一层,比只会写静态路由强不少。
购物车页面是另一个会被追问的地方,常见做法是商品数量用组件内 data 维护,商品列表用 v-for 渲染,删除或改数量通过后端接口同步;如果后端没有购物车模块,前端会直接把购物车数组存进 localStorage。商品卡片组件里,父组件通过 props 传入商品对象,子组件用 $emit 告诉父组件“加入购物车”,如果商品列表部分需要自定义推荐位,还会用到 slot 具名插槽——这一块看懂之后,Vue 的组件通信你就基本通关了。两种方案都能自圆其说,答辩时别自己先说漏。
3.3 联调三件套:跨域、Axios 封装与 Token 拦截
前后端分开跑,前端在 8081 或者 5173,后端在 8080,跨域问题躲不掉。市面上很多低质量项目用后端 @CrossOrigin 直接放行所有域名,写起来是省事,但答辩时被问到“怎么防止别人乱调你接口”就卡住了。我更推荐的做法是前端用代理,后端只兜底一次 CORS 配置。
前端 vue.config.js 里加代理:
devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } }逻辑说明:前端发的请求只要以 /api 开头,开发服务器就会转发到后端的 8080 端口,浏览器看到的始终是同源地址,既不触发跨域,也不需要后端大量加注解。这也是 Vue 2 项目最标准的联调配置。
参数说明:changeOrigin 很关键,它会把请求头里的 Host 改成目标地址,不然部分后端框架会校验 Host 导致请求失败。如果你的前端发请求的路径本身没有 /api 前缀,比如直接写 /user/login,这里就要配成 '/user',保持前缀规则统一。
后端这边再补一个全局 CORS 兜底,放进 config 包:
@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.addAllowedOriginPattern("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); config.setAllowCredentials(true); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }逻辑说明:addAllowedOriginPattern("*") 是 SpringBoot 2.x 以后的写法,允许任意来源跨域;setAllowCredentials(true) 允许携带 Cookie,但需要注意它和通配符 Origin 在旧版本里是互斥的,这里用 addAllowedOriginPattern 写法就是为了绕开这个问题。
参数说明:如果你在项目中看到 @CrossOrigin 注解,不用急着删,但要知道它只能作用在单个 controller 或方法上。全局配置的好处是新增的接口天然带 CORS 支持,不用每次手写。Token 的传递则靠前端 Axios 拦截器:请求前从 localStorage 取 token 放进 Header,响应返回 401 时统一踢回登录页。这套逻辑几乎所有商城项目都有,找到 axios 封装文件看 interceptors 那段就行。
4. 把默认项目改成“你的”项目:改名字、改流程、改支付
4.1 全局替换项目名与启动 banner:反查重的第一步
二手压缩包最大的问题不是代码跑不起来,而是答辩老师也能在 GitHub 上搜到同款。因此“把它变成你自己的项目”是拿到之后最值得投入的一件事。第一步是改名字。后端 pom.xml 里的 artifactId、group 里带的前缀、前端 package.json 里的 name、title 标签、数据库库名,这五处至少有三处通常还留着原作者的痕迹,搜索替换一遍就能大改头换面。
更明显的是启动时的打印信息,SpringBoot 启动时控制台会打印一段 ASCII Art,正规项目里那行字要么是 SHOP 要么是 FLOWER,但很多直接抄的压缩包会保留原作者的名字。替换方法很简单,在后端 src/main/resources 下新建一个 banner.txt,里面放自己的 ASCII 字样:
F L O W E R SpringBoot + Vue graduation project 2026逻辑说明:SpringBoot 启动时会优先读取 classpath 下的 banner.txt 作为启动横幅,没有 banner.txt 才打印默认的 Spring 图案。这一步虽小,但截图放进论文里很能说明“我动过这个项目”。
参数说明:还可以在 banner 里加上 {spring-boot.version} 这类占位符让它显示框架版本;用纯文本也完全够用。很多在线 banner 生成器能把你中文名变成字符画,答辩时会显得很个性化,值得一行一行微调字体宽度,密一点比散一点好看。
4.2 订单状态机怎么调整:把五张页面的逻辑理顺
订单状态是商城项目的命根子,同时也是你答辩被追问的主战场。绝大部分压缩包的订单状态字段是 Int 类型,值从 0 到 4,含义各不相同。我建议你把它整理成一张表,贴进论文的“系统设计”一节,也方便自己对着改代码:
| 状态值 | 含义 | 用户可以做的操作 | 管理员可以做的操作 |
|---|---|---|---|
| 0 | 待付款 | 取消订单、去支付 | 无 |
| 1 | 待发货 | 无 | 发货 |
| 2 | 已发货 | 确认收货 | 无 |
| 3 | 已完成 | 评价 | 无 |
| 4 | 已取消 | 无 | 无 |
状态流转写的越清晰,后端代码就越简单。常见做法是订单 controller 里五个方法一一对应:createOrder、payOrder、shipOrder、confirmOrder、cancelOrder。每个方法开头第一件事就是检查当前状态是否允许跳转,比如待发货订单不允许直接确认收货。
如果你觉得这个压缩包里的状态写得太乱,硬改代码又容易牵连前端页面,那就用最稳妥的一招:只在 createOrder 生成订单时把初始状态写死成 0,其余方法保持原有逻辑。这样改动最小,但答辩时你能讲清楚整条链路,就没人会追究状态定义是不是多个常量冗余。
4.3 支付模块“模拟支付”:不接微信支付的体面做法
毕业设计最容易被老师问住的场景是:你说这是商城系统,那支付怎么实现的?接真实的微信支付或支付宝需要商户号、证书、回调域名,个人拿不到,所以绝大多数毕设项目都在后端写一个 mock 支付接口。重要的是把“模拟”这件事做得体面一点,别真在页面上写死“支付成功”。
后端可以做一个独立的支付控制器,只负责翻转订单状态:
@RestController @RequestMapping("/api/pay") public class PayController { @Autowired private OrderService orderService; @PostMapping("/mock") public Result mockPay(@RequestBody PayDTO dto) { // 模拟支付:假设第三方支付平台回调成功 Order order = orderService.getByOrderNo(dto.getOrderNo()); if (order == null) { return Result.fail("订单不存在"); } if (order.getStatus() != 0) { return Result.fail("订单状态不允许支付"); } order.setStatus(1); order.setPayTime(LocalDateTime.now()); orderService.updateById(order); return Result.ok("支付成功"); } }逻辑说明:mockPay 接收前端传来的订单号,先查出订单,再判断状态是否为 0(待付款),是则把状态改成 1(待发货)并记录支付时间。这段代码的意义在于让支付动作像一次真实的业务操作,而不是前端弹个框就完事。
参数说明:@RequestBody PayDTO 里的 DTO 类只要包含 orderNo 一个字段就够,前后端约定好 JSON 字段名即可。这个接口文件名建议叫 PayController 而不是 MockController,答辩时你完全可以说“为了演示方便,支付接口目前走的是沙箱模式”,这是行业内标准说法,比“我随便写了个假的”好听十倍。
前端页面里把“去支付”按钮指向这个 /api/pay/mock 就行,响应成功后再跳转到订单列表页。整条链路真正跑通了,你才敢在答辩时拍胸脯说系统是完整的。
5. 跑得通和跑得稳:常见问题排查与避坑记录
5.1 “端口 8080 被占用”:前后端抢同一个端口
现象:后端启动约 3 秒后控制台抛Web server failed to start. Port 8080 was already in use.。前端不会报这个错,因为前端开发服务器默认是 8081 或 5173,但如果你把前端也配成 8080,两个一起启动就会互踩。
原因:IDEA 里残留上一个 SpringBoot 实例没关干净,或者你机器上本来就有别的程序占了 8080。还有一种隐蔽情况:你后端明明跑起来了,前端代理又把请求转发到 8080,结果页面报一堆 502,排查方向也是这个。
解决:先定位再处理,不要盲目改端口。Windows 下用netstat -ano | findstr :8080查到占用进程 PID,然后taskkill /F /PID 那个PID。如果端口被系统服务占用,那么改后端 application.yml 里的 server.port 换一个端口,同时把前端代理的 target 也同步改掉。注意前后端代理目标端口必须一致,这属于“差一个数字找半小时”的经典翻车现场。
注意:改端口时还要看拦截器里有没有把端口写进白名单,有些项目登录校验为了演示方便会判断 request.getServerPort(),端口不一致直接给你返回未登录。
5.2 “Access denied for user”:密码改了却连不上库
现象:后端启动报java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)。这个报错不是项目代码问题,是数据库账号密码的事。
原因:压缩包里的 application.yml 写的密码是作者本机的 root 密码,比如 root 或 123456,而你本机的 MySQL 密码并不是这个。有时候你明明改成了自己的密码,依然报错,那就是改错文件了——主配置里激活的 profile 是 dev,你却改了 prod 文件。
解决:先确认 spring.profiles.active 指向哪个环境,再改对应文件。改完别急着跑,用命令行验证一遍:mysql -u root -p 进入 MySQL 里执行 use flower_shop; 如果能进去,说明库和用户都没问题,那问题就只出在配置没生效。另外密码里如果带 @、# 这类字符,在 yml 里必须加引号,不然 YAML 解析会把密码截断,这也是一个迟到半小时才发现的玄学问题。
5.3 “程序包 javax.servlet 不存在”:SpringBoot 3 和 2 搞混了
现象:IDEA 里后端代码大面积标红,编译报“程序包 javax.servlet 不存在”,或者 org.springframework.boot.autoconfigure.EnableAutoConfiguration 找不到。
原因:代码是从 SpringBoot 2.x 项目抄来的,用了 javax.* 包,但你新建的工程或 Maven 拉下来的依赖是 SpringBoot 3.x,3.x 全部迁移到 jakarta.。也有反过来:代码是 3.x 的 jakarta.,Maven 仓库里缓存的却是旧版本依赖。这个问题是“毕业设计从 GitHub 抄来”的特产。
解决:进到 pom.xml 看 parent 版本号。如果 version 是 2.7.x 系列,整体替换包名太麻烦,把 parent 版本保持原样就行;如果 version 是 3.x,就把代码里的 javax 包名整体替换成 jakarta。还有一个牵一发动全身的地方:SpringBoot 3 里 mybatis-plus 等三方依赖也要用对应版本,版本不匹配大概率还会继续爆红。我的建议是尽量跟着原压缩包走,不要自己“好心”升级大版本。
5.4 npm install 报 ERESOLVE:Node 版本太高把 Vue2 坑了
现象:前端目录执行 npm install,进度条走到一半直接抛ERESOLVE unable to resolve dependency tree,或者报cb() never called!。如果你装的是 Node 18 以上,而项目是 Vue 2 + webpack 的老组合,这句话几乎必出现。
原因:Node 17 以后自带的 npm 升级了依赖解析算法,对嵌套依赖的冲突处理变得极严格;Vue 2 时代的老依赖声明方式在新算法下看就是“不合法”,于是直接罢工。这不是你操作问题,是时代错位。
解决:最快的方式是装一个 Node 16 或 14(推荐用 nvm 切换,nvm list 看版本、nvm use 16 切过去),再重新删掉 node_modules 和 package-lock.json 跑 npm install。不想降级 Node 的话,也可以在 npm install 后加 --legacy-peer-deps 跳过严格校验,两个办法我都用过,前者干净、后者赶时间。
5.5 登录成功却拿不到数据:Token 与拦截器没对齐
现象:登录页填账号密码,接口返回成功,也拿到了 token,但跳转首页之后所有商品列表接口全部返回 401 未登录。
原因:这类商城项目的权限拦截器通常会拦截 /api/** 全部路径,再放行一部分白名单。如果你登录接口路径叫 /user/login 而不带 /api 前缀,那它可能压根没被拦截,问题不在这;更大的可能是前端 Axios 请求头里没有把你的 token 带上,或者 localStorage 里存的键名跟拦截器里读取的键名不一致。
解决:先按 F12 看接口请求详情,确认请求头 Authorization 或 token 有没有值。如果没值,去 axios 封装文件找请求拦截器,把 localStorage.getItem(你的键名) 放进 header;如果键名对不上,就统一改成同一个。后端拦截器里也要看一遍白名单列表,登录和注册接口必须放行,其余路径统一走校验。这一套检查完,一般五分钟能定位,前提是别同时在两个地方找问题。
6. 答辩前最值得做的一个技巧:用接口自测把启动链路钉死
离答辩还有几天的时候,我建议你把“启动一条龙”压缩成一条可以重复走的链路,然后每天用命令行自测代替肉眼观察。老师让你现场演示时,你越熟练就越稳。最值得练熟的验证技巧是 curl 打接口:后端启动后,先用浏览器登录一次拿到 token,再命令行测试受保护接口:
curl -X POST http://localhost:8080/api/user/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456"}'逻辑说明:-X POST 指定请求方法,-H 设置请求头,-d 传 JSON 请求体。返回结果里带 token 后,把它复制到下一步的 Authorization 请求头里,再去请求订单接口。这两条 curl 能够验证“后端起来、数据库通、登录可用、订单接口没被拦截器误伤”四件事。
如果你还想让演示更省心,就做一次“前端打包进后端”的简化部署:将 Vue 构建产物放进后端 static 目录,一个 jar 同时提供页面和接口,现场不再需要开两个终端:
cd front npm run build cp -r dist/* ../backend/src/main/resources/static/ cd ../backend mvn clean package -DskipTests java -jar target/flower-shop-0.0.1-SNAPSHOT.jar逻辑说明:npm run build 把 Vue 项目输出成静态文件,cp 复制到后端静态目录,之后浏览器访问 8080 就能直接看到商城页面,整个过程与“vue 打包放进 springboot 中”的做法完全一致,是答辩演示最可靠的方式。
验证完整后,把访问地址、管理员账号密码、下单步骤写在项目 README 的最前面。我见过太多翻车现场不是功能缺失,而是演示者临时找不到管理员密码。最后说一个我自己的教训:拿到任何压缩包,第一天别着急改代码,先花半小时把“清数据库、启动后端、启动前端、走通一笔订单”完整做三遍,第一遍找坑、第二遍熟路、第三遍计时。能三遍通关再去改功能,改不动也有缓冲时间换方案。希望帮到你。
本文还有配套的精品资源,点击获取