ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Spring Boot + Vue3 + 微信小程序汽车用品商城系统实战指南

Spring Boot + Vue3 + 微信小程序汽车用品商城系统实战指南 这次我们来看一个基于 Spring Boot Vue 3 微信小程序实现的汽车用品交易商城系统。这类项目的名字很多有叫“汽车用品交易小程序”的有叫“汽车用品电商平台”的也有叫“在线汽车用品销售系统”的。本质上都是同一个东西——用一套前后端分离的工程把汽车用品的浏览、搜索、购物车、下单、支付、售后、后台管理全部串起来同时覆盖小程序 C 端和管理后台 B 端。这类项目最值得关注的不是概念而是三层能力小程序端能不能真正跑通微信登录、商品下单、模拟支付流程后台管理端能不能完成商品上下架、订单处理、用户管理、数据统计Spring Boot 接口和 Vue 3 管理页面能不能在同一套工程里协同开发、独立部署。这篇文章会先拆解系统功能和模块边界再给出本地部署的通用步骤然后分别演示小程序端、管理后台端、订单流程的关键配置最后补充批量任务处理、性能观察、常见问题和上线合规建议。不需要你有完整的电商开发经验只要熟悉 Spring Boot 基础注解、Vue 基础语法和微信开发者工具的基本操作就能照着这篇文章把一个汽车用品电商商城从代码跑起来。适合的读者有两类一是做毕业设计或课程设计的学生二是准备接私活或做外包演示的 Java 全栈开发者。前者需要完整的“项目介绍 功能清单 部署流程”后者需要“模块怎么拆、接口怎么调、批量任务怎么加”。这两种需求在下面都会覆盖。1. 核心能力速览先给一张整体表方便你在往下读之前快速判断这个汽车用品小程序商城项目适不适合自己。能力项说明项目类型前后端分离电商系统小程序端 管理后台端 后端接口服务后端技术栈Spring Boot MyBatis/MyBatis-Plus MySQL Redis按实际工程为准前端技术栈Vue 3 Vite Pinia Vue Router Element Plus管理后台微信小程序原生或 uni-app小程序端主要功能商品分类、商品详情、购物车、订单提交、支付回调、后台商品管理、订单管理、用户管理、轮播图管理小程序能力微信登录、商品浏览、下单、地址管理、模拟支付、我的订单后台管理基于 Vue 3 的单页应用按权限模块管理商城数据推荐部署环境JDK 17 或 JDK 8、Node.js 18、微信开发者工具、本地 MySQL、Redis显存/GPU要求无需 GPU属于常规 Web 项目2 核 4G 服务器即可运行演示环境启动方式后端启动接口服务前端启动后台管理小程序用微信开发者工具导入是否支持 API支持前后端通过 RESTful 接口通信是否支持批量任务可按 Spring Task 或 xxl-job 扩展例如订单超时关闭、自动确认收货适合场景课程设计、毕设演示、外包项目脚手架、商城私活二次开发需要注意不同源码作者给出的版本组合可能不同。有些版本后端用的是 Spring Boot 2.7 JDK 8 MyBatis-Plus有些已经升级到 Spring Boot 3.x JDK 17。你在部署前要先去pom.xml里确认版本不要盲目按“网上教程写 JDK 17”就装环境。2. 适用场景与使用边界汽车用品商城和普通商品商城在业务上没有本质区别核心差异在于商品数据和类目结构。这类汽车用品电商平台适合解决的问题包括搭建一个支持商品浏览、搜索筛选、购物车、下单的小程序商城搭建一个后台管理页面让运营人员自主维护商品分类、品牌、轮播图、推荐位给没有电商开发经验的团队提供一个可二次开发的骨架快速对接真实支付和物流做毕业设计时需要一套能够现场演示“用户下单 - 后台接单 - 订单状态流转”的完整 Demo。但是也有不适用的情况如果要支撑高并发秒杀、分布式事务、多机房容灾这种单体 Spring Boot 项目不是最优选择如果要接入真实微信支付和真实物流接口你需要自己申请商户号并替换模拟支付模块如果数据量达到百万级且商品详情、订单表、SKU 表需要深度分库分表那需要引入更重的中间件不建议在单体项目上继续堆功能。从合法合规角度看商城项目涉及三类风险要特别注意用户手机号、收货地址、订单信息属于敏感数据不能明文存入日志不能打印到前端控制台接口响应中不要返回多余字段商品图片、品牌 Logo、车辆型号图片可能涉及版权和商标权演示阶段要用自有素材或开源图片商用前必须确认授权如果要换脸、人脸识别、图像检测等功能必须获得明确授权本项目涉及的主要是商品交易不涉及人脸和声音但如果后续扩展“到店安装服务”或“车辆识别”模块就要提前做好合规评估。从支付合规角度看小程序商城如果要上线运营微信小程序类目必须选择“电商平台”或“商家自营”否则无法开通微信支付。本地开发测试时使用模拟支付只需要做状态变更不涉及真实资金。3. 系统功能模块拆解在写代码之前先理解功能边界。一个完整的汽车用品电商系统通常拆成三个端小程序用户端、后台管理端、后端接口服务。3.1 小程序用户端小程序端面向普通车主用户核心功能是“找商品、下订单”。推荐保留这些页面首页轮播图、金刚区入口、推荐汽车用品、限时活动位分类页按汽车用品类目展示例如脚垫、座垫、行车记录仪、车载充电器、洗车工具、车灯、机油养护等商品列表页支持关键词搜索、按销量/价格/上架时间排序支持列表和宫格切换商品详情页展示商品轮播图、价格、库存、规格参数、图文详情、用户评价购物车页管理勾选商品、修改数量、计算合计金额结算页选择收货地址、填写买家留言、选择配送方式、生成订单订单列表页按状态展示待付款、待发货、待收货、待评价、售后/退款我的页面用户头像昵称、我的订单、收货地址、优惠券、联系客服。小程序端有一个容易忽略的需求刷新商品列表时会出现图片闪现或白屏。汽车用品图片通常是正方形大图一张图在 100KB 到 300KB 左右如果直接加载原图会拖慢页面。最好在后端返回商品数据时同时返回缩略图 URL或者由对象存储服务自动生成?imageView2/2/w/400这类压缩参数。图片压缩、懒加载、分包加载这些优化在商品 SKU 多、详情图多的时候尤其重要。3.2 后台管理端后台管理端使用 Vue 3 开发目标用户是运营管理员。模块上一般要覆盖仪表盘统计今日订单数、今日销售额、总用户数、总商品数展示近七日订单趋势图商品管理商品列表、新增商品、编辑商品、上下架、删除、批量上下架分类管理添加一级分类、二级分类、排序、设置分类图片订单管理订单列表、按订单号搜索、按订单状态筛选、订单详情、发货操作用户管理用户列表、用户状态禁用/启用、查看用户订单轮播图管理上传轮播图、设置跳转链接、开启/关闭状态系统设置公告配置、运费模板、售后设置或其他营销配置。管理后台最核心的交互是“商品发布”。汽车用品商品通常有多个销售规格例如颜色、尺寸、适配车型所以后端要设计好 SKU 结构。在 Vue 3 页面里需要用到动态表单运营人员点击“添加规格项”页面里就多一行属性和价格库存输入框。保存时前端把 SKU 列表通过 JSON 提交给后端后端再拆表存储或整体 JSON 存储。使用 Element Plus 的el-table配合el-dialog就能实现这套操作。3.3 后端接口服务Spring Boot 后端提供 RESTful API按业务模块划分 Controller。比较常见的包结构是com.example.autoparts ├── common // 通用返回结果、异常处理、工具类 ├── config // 跨域、拦截器、MyBatis 配置 ├── controller // 前端接口入口 ├── service // 业务逻辑层 ├── mapper // 数据库访问层 ├── entity // 数据库实体 ├── dto // 请求参数对象 ├── vo // 响应结果对象 └── utils // JWT、日期等工具接口设计上建议使用统一返回结构。例如{ code: 200, message: success, data: { orderId: 1001 } }后端只关心业务逻辑不直接输出后端异常堆栈给前端。新增一个GlobalExceptionHandler用RestControllerAdvice处理参数校验异常、业务异常和兜底异常是接入前最容易提高开发效率的一步。4. 技术栈与架构设计这是一套典型的前后端分离应用架构上分为三层。4.1 服务端架构后端服务是整个商城的中枢负责用户鉴权、商品数据、订单流程、支付回调等逻辑。技术组合通常包括Spring Boot提供 IOC 容器、Web MVC、定时任务、事务管理Spring Security 或 Sa-Token负责登录鉴权和接口权限控制MyBatis-Plus简化单表 CRUD配合分页插件使用MySQL保存用户、商品、分类、订单等业务数据Redis缓存首页轮播图、商品分类、商品详情以及处理分布式登录状态Maven统一依赖管理。如果项目标题中写的“SpringBoot4”是指版本迭代名不需要太纠结。部署前打开pom.xml看实际版本即可。当前常见的 Spring Boot 正式版在 2.7.x 和 3.x 之间。2.7 使用javax.servlet命名空间3.x 换成了jakarta.servlet如果从 2.x 升到 3.x需要同步调整依赖坐标和拦截器代码。建议后端启动时做两件事第一检查 MySQL 和 Redis 是否先启动第二检查配置文件里的数据库名和密码是否正确。很多项目启动失败发生在第一步而不是代码本身。4.2 前端架构Vue 3 管理后台一般使用 Vite 构建核心依赖是Vue 3 组合式 APIVue Router 4实现页面路由和菜单权限控制Pinia管理用户登录态、菜单权限、全局配置Element Plus页面组件库Axios封装 HTTP 请求ECharts实现仪表盘图表。小程序端可以选微信小程序原生也可以用 uni-app 实现一套代码多端发布。如果项目目标是“微信小程序商城”这类关键词用原生小程序也够用如果后续想发布到支付宝小程序、抖音小程序建议用 uni-app。不过需要注意接入微信支付时不同端底层 API 不一样。原生小程序使用wx.requestPaymentuni-app 使用uni.requestPaymentH5 端则使用jsapi或wx.chooseWXPay。支付模块的封装层要预留扩展点不要把所有端写死在同一个页面组件里。4.3 数据库设计汽车用品商城核心表至少要有用户表、商品分类表、商品表、SKU 表、购物车表、订单表、订单明细表、收货地址表、轮播图表、系统配置表。下面给商品表一个参考字段设计CREATE TABLE product ( id bigint NOT NULL AUTO_INCREMENT COMMENT 商品ID, category_id bigint NOT NULL COMMENT 分类ID, product_name varchar(255) NOT NULL COMMENT 商品名称, sub_title varchar(255) DEFAULT NULL COMMENT 商品卖点副标题, main_image varchar(500) DEFAULT NULL COMMENT 主图, detail text COMMENT 图文详情, price decimal(10,2) NOT NULL COMMENT 价格, stock int NOT NULL DEFAULT 0 COMMENT 总库存, sales int NOT NULL DEFAULT 0 COMMENT 销量, status tinyint NOT NULL DEFAULT 1 COMMENT 状态 1上架 0下架, sort_order int DEFAULT 0 COMMENT 排序, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_category (category_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT汽车用品商品表;订单表要注意订单号、用户ID、订单状态和支付时间这几个索引字段。日常查询中用户查看“我的订单”和后台筛选“待发货订单”都靠状态字段检索如果没有索引随着订单数据增长会越来越慢。5. 本地部署环境准备在开始跑项目之前先把依赖环境准备好。这套系统不需要 GPU普通办公电脑就能跑。5.1 环境清单推荐版本如下具体以项目 README 为准环境推荐配置JDKJDK 8 或 JDK 17取决于 Spring Boot 版本Maven3.6 以上Node.js16.20 或 18 以上MySQL5.7 或 8.0Redis5.x 以上微信开发者工具最新稳定版开发系统Windows 10/11 或 macOS低配置电脑跑这套项目没有压力。后端 Spring Boot 启动后内存占用大约在 300MB 到 800MB 之间具体取决于是否加载了 Redis 缓存、定时任务和监控组件。Vue 3 的 Node 开发服务占内存 500MB 左右。开发阶段建议电脑至少有 8GB 内存16GB 会更舒服。5.2 本地服务安装检查启动项目前先用命令行确认基础环境可用java -version mvn -v node -v npm -v mysql --version redis-cli ping看到redis-cli ping返回PONG说明 Redis 已经启动。MySQL 可以在命令行使用mysql -u root -p确保能进入 MySQL 再继续。5.3 导入数据库通常项目源码里会带一个sql目录里面是初始化脚本。使用命令行导入即可mysql -u root -p auto_parts_mall.sql导入完成后进入数据库查看表数量SHOW DATABASES; USE auto_parts_mall; SHOW TABLES;如果表数量为零检查导入时是否有报错最常见的问题是 SQL 文件编码和 MySQL 字符集不一致需要在导入前设置mysql -u root -p --default-character-setutf8mb46. Spring Boot 后端启动配置6.1 修改配置文件打开后端模块下的application.yml或application.properties重点修改数据源和 Redis 地址。server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/auto_parts_mall?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 redis: host: localhost port: 6379 password: database: 0 servlet: multipart: max-file-size: 10MB max-request-size: 50MB mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0需要注意项目里如果配置了password: 123456并且本机 MySQL 密码不是这个启动时就会报Access denied for user。这是最常见的启动失败原因先改配置再谈其它。6.2 启动后端在 IDEA 中打开项目等待 Maven 下载依赖。如果是命令行启动执行mvn spring-boot:run或者先打包再运行mvn clean package -DskipTests java -jar target/auto-parts-mall.jar看到类似日志Tomcat started on port(s): 8080 (http) Started Application in 5.32 seconds表示后端启动成功。如果端口被占用在配置文件中改成 8081然后重新启动。6.3 验证后端接口浏览器打开一个最简单的接口例如轮播图列表接口http://localhost:8080/api/banner/list如果返回统一 JSON 结构说明后端接口服务正常。7. Vue 3 后台管理系统启动配置7.1 安装依赖进入admin-web目录执行npm install这一步在网络不稳定或 Node 版本不对时经常卡住。如果遇到node-sass或sass编译报错优先检查 Node 版本或者使用 npm 镜像源npm config set registry https://registry.npmmirror.com rm -rf node_modules package-lock.json npm install7.2 启动后台开发服务npm run devVite 默认会启动一个本地开发服务器控制台会输出访问地址例如VITE v5.0.0 ready in 1200 ms ➜ Local: http://localhost:5173/打开浏览器就能看到登录页。首次登录使用项目默认管理员账号账号密码在后端sys_user表里或者查看 SQL 初始化脚本。7.3 Vue Router 配置后台管理系统页面较多路由配置需要在router/index.js中管理。为了方便后期加页面可以把路由拆成静态路由和动态路由。一个动态路由简单示例import { createRouter, createWebHistory } from vue-router const routes [ { path: /login, component: () import(/views/Login.vue) }, { path: /, component: () import(/layout/Index.vue), redirect: /dashboard, children: [ { path: dashboard, name: Dashboard, component: () import(/views/Dashboard.vue), meta: { title: 仪表盘 } }, { path: product/list, name: ProductList, component: () import(/views/product/ProductList.vue) } ] } ] const router createRouter({ history: createWebHistory(), routes }) export default router这里有一个需要特别说明的点很多 Vue 3 商城项目页面跳转不稳定不是后端接口问题而是刷新页面后路由丢失或用户状态丢失。建议在 Pinia 中保存用户信息和动态路由表同时把路由meta.title同步到浏览器标题维护成本会低很多。7.4 封装 Axios 请求在 Vue 3 项目里建议把 Axios 封装成一个独立模块统一处理 token、超时时间和错误消息。import axios from axios import { ElMessage } from element-plus import { useUserStore } from /store/user import router from /router const service axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || http://localhost:8080, timeout: 10000 }) service.interceptors.request.use((config) { const userStore useUserStore() if (userStore.token) { config.headers[Authorization] Bearer ${userStore.token} } return config }) service.interceptors.response.use( (response) { const res response.data if (res.code ! 200) { ElMessage.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res.data }, (error) { ElMessage.error(error.message || 网络异常) return Promise.reject(error) } ) export default service后台管理系统的 API 请求统一走这个实例开发接口时不需要在页面组件里重复处理 token。8. 小程序端接入与运行8.1 导入微信开发者工具用微信开发者工具导入mp-weixin目录注意 AppID 处理方式。如果你只是本地测试没有注册小程序账号可以在开发者工具的详情设置里选择“测试号”也可以使用游客模式。但如果需要用到微信登录和支付能力必须在微信公众平台注册小程序拿到正式的 AppID并把服务器域名配置到合法域名列表中。一个小程序商城项目最核心的注意事项包括微信小程序要求所有请求域名必须是 HTTPS且需要在小程序后台配置 request 合法域名本地开发阶段可以在微信开发者工具里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”但是真机预览和上线前必须关闭这项配置本地开发时request的地址要改成电脑的局域网 IP 或本机 localhost例如http://127.0.0.1:8080真机调试时不能使用 localhost需要填电脑在局域网中的 IP。8.2 小程序登录与签名微信小程序登录的经典流程是wx.login()获取临时code把code传给后端后端调用微信接口code2Session换取openid和session_key后端用openid查询本地用户不存在则自动注册后端签发自定义登录态 token返回给小程序小程序把 token 存入 storage后续请求带上 token。这里要注意一个细节很多课程设计项目在小程序端调用后端接口时不会做签名校验只传 token。但在真实项目中请求签名也是需要考虑的事尤其在用户登录态容易被伪造的场景。如果项目涉及支付、退款、订单状态变更等敏感接口应该在请求头或请求参数中加入签名机制核心思路是对固定参数排序后拼接 secret再用 MD5 或 HMAC-SHA256 生成签名后端再校验一次。简单代码示例// 小程序端生成请求签名示意 function generateSign(params, secret) { const keys Object.keys(params).sort() let str keys.forEach((key) { str ${key}${params[key]} }) str key${secret} // 实际使用 MD5 或 HMAC return md5(str).toUpperCase() }后端拿到请求参数后用同样的方式重新计算签名并比对。这个过程能防止接口参数被恶意篡改尤其在涉及金额、商品 ID、数量时非常有用。如果你只是做毕设演示可以不做但如果你想准备一个用于面试或接私活的项目建议补上。8.3 小程序商品列表与数据处理小程序首页商品列表分页加载是商城开发的高频问题。页面加载更多时要注意防抖防止请求重复发送。一个简单做法是Page({ data: { list: [], page: 1, pageSize: 10, loading: false, finished: false }, onLoad() { this.loadList(true) }, onReachBottom() { if (this.data.finished || this.data.loading) return this.loadList(false) }, loadList(reset) { if (this.data.loading) return const page reset ? 1 : this.data.page 1 this.setData({ loading: true }) wx.request({ url: http://127.0.0.1:8080/api/product/list, method: GET, data: { page, pageSize: this.data.pageSize }, success: (res) { const list reset ? res.data.records : this.data.list.concat(res.data.records) this.setData({ list, page, finished: page * this.data.pageSize res.data.total }) }, complete: () { this.setData({ loading: false }) } }) } })finished标记是否没有更多数据避免用户不断翻页时反复触发请求。分页接口后端只需要返回records、total、current、size这和 MyBatis-Plus 的分页结构是对应的。8.4 模拟支付与真实支付在小程序商城中订单支付是核心环节。如果是本地演示可以直接在后端模拟支付成功回调PostMapping(/order/pay/mock) public Result mockPay(RequestBody MockPayRequest request) { // 1. 校验订单归属用户 // 2. 把订单状态改为待发货 // 3. 记录支付时间 // 4. 扣减库存 return Result.success(); }这个逻辑和真实支付回调非常接近先保留支付前检查再更新订单状态最后处理库存。把这段写清楚之后接微信支付只需要在回调入口替换成微信支付验签操作即可。另外需要提醒在订单状态流转中一定要考虑订单超时未支付、支付后未发货、用户取消订单、后台拒绝退款等情况。不要把支付处理写成只有一条 if 分支。控制订单状态的建议是用一个整数状态字段管理代码里定义常量类去引用不要散落在各个 Service 类里写魔法数字。9. 后台商品管理与订单流转测试9.1 新增商品登录 Vue 3 后台进入“商品管理 - 新增商品”。测试时建议填写完整的测试数据商品名称车载手机支架分类车载配件价格39.90库存100主图上传一张本地图片详情填入几段 html 文本提交后去数据库确认SELECT id, product_name, price, stock, status FROM product ORDER BY id DESC LIMIT 5;这条 SQL 能看到新商品是否成功写入。9.2 小程序端下单在开发者工具中找到对应商品点击加入购物车再点击结算。正常流程下购物车页面会展示商品数量、总价结算页需要选择收货地址提交订单后订单状态应变为“待付款”。测试时可以重点记录三个问题创建订单时商品库存是否扣减未支付订单在多少分钟后被自动取消取消后库存是否回补。这里如果项目没有做库存回补那么批量取消订单后库存会越来越少。对于电商项目来说这是严重问题扩展批量任务时要把这个场景覆盖进去。9.3 后台订单发货进入后台“订单管理”找到刚才的订单点击发货按钮正常会弹出填写物流公司和物流单号的对话框。提交后小程序端订单状态更新为“待收货”。在实际商城项目中发货动作通常要对接物流接口。课程设计一般只需要保存物流单号。这里应该在代码里写一个线下物流接口抽象public interface LogisticsService { ShippingResult ship(Order order, ShippingRequest request); }这样后期对接快递100、顺丰、菜鸟的时候只需要新增实现类不需要改订单服务里的业务逻辑。10. 批量任务与自动化扩展汽车用品电商系统的价值取决于“事务一致性”和“批量扩展能力”。这里的批量不是指“一次性改1000个商品状态”那么简单而是指系统要能自动处理超时未支付订单、自动确认收货、自动回补库存等场景。10.1 使用 Spring Task 处理订单超时最简单的方式是在 Spring Boot 启动类上开启定时任务SpringBootApplication EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }然后新建一个定时任务类Component Slf4j public class OrderTask { Resource private OrderService orderService; // 每分钟执行一次关闭超时未支付订单 Scheduled(cron 0 */1 * * * ?) public void closeExpiredOrders() { ListOrder orderList orderService.listExpiredUnpaidOrders(30); for (Order order : orderList) { try { orderService.closeOrder(order); } catch (Exception e) { log.error(关闭超时订单失败 orderId{}, order.getId(), e); } } } }这里需要注意单机定时任务适合课程设计和中小商城。如果以后拆成多实例部署定时任务会在多个节点同时执行需要引入分布式锁或使用 xxl-job。项目里没有引入中间件时可以先使用一个task_lock表每次执行前用SELECT ... FOR UPDATE获取锁避免重复处理。批量任务设计时有几个工程建议每次批量处理要限制数量不要一次扫全表。例如按LIMIT 100分批处理单个失败不能中断整个批次要单独 try-catch每次任务执行完要记录最后处理的时间和批次大小方便排查涉及金额和库存变更的任务必须开启事务避免中途失败产生脏数据。10.2 批量任务中的库存回补订单超时关闭或用户取消订单时订单中的商品 SKU 库存要回补。这个逻辑最好写在同一个事务里例如Transactional(rollbackFor Exception.class) public void closeOrder(Order order) { // 1. 校验订单状态必须是待付款 if (order.getStatus() ! OrderStatus.WAIT_PAY) { throw new BizException(订单状态已变更); } // 2. 更新订单状态为已取消 order.setStatus(OrderStatus.CANCELED); order.setCloseTime(new Date()); orderMapper.updateById(order); // 3. 回补商品库存 ListOrderItem itemList orderItemMapper.selectByOrderId(order.getId()); for (OrderItem item : itemList) { productSkuMapper.increaseStock(item.getSkuId(), item.getQuantity()); } }这里要注意扣减库存和回补库存不能只操作商品总库存还要关心 SKU 级库存。汽车用品种类多、规格属性差别大没有 SKU 库存管理订单和商品表容易出现超卖或负数库存。10.3 批量发货与批量上架后台管理界面里运营经常会用到跨页勾选批量上架或批量发货。Vue 3 批量操作并不难核心是拿到选中行的 ID 数组然后请求后端接口。const handleBatchShip async () { if (selectedRows.value.length 0) { ElMessage.warning(请先选择订单) return } const ids selectedRows.value.map((item) item.id) await shipOrderApi(ids, { logisticsCompany: form.logisticsCompany, logisticsNo: form.logisticsNo }) ElMessage.success(发货成功) loadData() }后端接收数组时用RequestBody接收 List 即可。批量操作接口要注意数据量限制一次传几百个订单号是可行的但一次传几万个就不合理。建议在前端限制最大选择数量为 200或者分成多次批量请求。11. 权限控制与过滤链11.1 小程序接口鉴权在课程设计项目里很多 Controller 接口默认未拦截用户只要知道接口路径就能越权访问别人的订单。上线前需要对敏感接口做权限校验。推荐用拦截器实现登录校验。注册拦截器Configuration public class WebMvcConfig implements WebMvcConfigurer { Resource private AuthInterceptor authInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns(/api/**) .excludePathPatterns( /api/banner/list, /api/product/list, /api/product/detail ); } }拦截器里从请求头获取 token解析后把当前用户 ID 写入 ThreadLocal 或请求属性这样后续 Service 层不需要反复查 token。注意事项登录、注册、轮播图列表、首页推荐等接口可以放行加入购物车、创建订单、取消订单、查看订单详情这些接口必须拦截后台管理接口建议单独加管理员权限校验不能只依赖一个小程序 token 通用逻辑。11.2 Vue 3 管理端权限后台管理菜单根据用户角色动态生成这种需求在管理后台里常用。如果项目只有管理员一种角色不做动态权限也能演示但如果要按角色区分运营人员和超级管理员需要在登录接口中返回权限标识数组。比较直接的做法是{ username: admin, roles: [admin], permissions: [product:add, product:edit, order:ship] }前端拿到 permissions 后在 Pinia 中保存页面按钮通过自定义指令控制显隐。这里不建议把所有权限逻辑都写在路由守卫里因为按钮级权限最好放在组件内部。12. 资源占用与性能观察在没有 GPU 的普通 Java Web 项目里性能观察主要看三块接口响应时间、数据库慢查询、前端资源加载。12.1 后端启动资源占用后端 Spring Boot 项目首次启动会经历类扫描、Bean 初始化、数据库连接池初始化等过程启动时间通常在 3 到 10 秒之间。可以通过 JVM 参数控制开发环境内存java -Xms256m -Xmx512m -jar auto-parts-mall.jar生产环境如果并发量不大2 核 4G 服务器上可以给 JVM 分配 1G 到 2G 内存其余留给 MySQL 和 Redis。需要注意的是内存占用不是越高越好关键是看 Full GC 频率堆大小不足时接口会频繁卡顿。12.2 接口性能商城项目接口要尤其关注商品列表、订单列表这类查询接口。数据量小的时候一次全表查询也可以但当商品超过几百条、订单超过几千条后必须用分页并为常用查询条件加索引。一个简单的排查方法是打开 MySQL 慢查询日志SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1;然后观察mysqld-slow.log。如果发现某条 SQL 扫描行数很大就检查 where 条件字段是否在索引中。12.3 Vue 3 构建优化管理后台代码发布到服务器时要使用生产构建npm run build构建产物会输出到dist目录由 Nginx 托管。打开dist/index.html时如果发现首页加载慢可以检查是否引入了过大的 ECharts 包建议按需引入是否未开启 gzip 压缩静态资源是否没有加哈希缓存。在 Nginx 中开启 gzip 能明显减少首屏体积gzip on; gzip_types text/plain text/css application/json application/javascript; gzip_min_length 1024;小程序端首屏优化上建议把汽车用品图片目录放在对象存储服务上避免小程序包体积过大。首页轮播图不建议本地写死而是从接口读取这样运营可以后台随时调整。13. 常见问题与排查方法部署这类商城项目时绝大多数问题集中在环境、依赖、数据库、请求地址这四类。下面按问题现象整理一套排查表格。问题现象可能原因排查方式解决方案后端启动报Access denied for userMySQL 用户名或密码错误检查配置文件和 MySQL 实际账号修改application.yml中的账号密码后端启动报Table doesnt exist数据库导入失败或连错库执行SHOW TABLES检查重新导入 SQL 或修改jdbc:mysql://后的数据库名Spring Boot 3.x 启动后报 ClassNotFound依赖没刷新或 JDK 版本过旧查看 Maven 依赖树和 JDK 版本升级 JDK 17mvn clean install重新下载依赖Vue 后台npm run dev后白屏Node 版本过高导致依赖编译失败查看终端报错删除node_modules和package-lock.json后重装或切换 Node 到适配版本小程序请求接口报url not in domain list域名未配置或没关闭校验查看开发者工具控制台本地测试勾选不校验合法域名上线前配置 HTTPS 域名小程序请求接口报 404后端接口路径前缀不一致对比请求 URL 和 Controller 注解统一接口前缀/api加入购物车失败token 过期或用户态未初始化查看 Network 请求是否返回 401重新登录或者调整拦截器放行规则商品列表分页滚到底重复请求没有在请求完成后限制加载状态检查 onReachBottom 和 loading 控制增加finished/loading双判断Vue 后台管理页面登录后刷新 404路由模式与 Nginx 配置不匹配修改 Nginx history 回退在 location 中配置try_files $uri $uri/ /index.html;订单状态不更新前端修改了状态但后端事务回滚检查后端日志中的异常在 Service 层开启事务并回滚异常定时任务没有执行缺少EnableScheduling或配置 cron 错误检查启动类和任务日志补上注解并设置正确的 cron 表达式Redis 连接失败导致商品列表报错Redis 服务未启动或密码错误执行redis-cli ping启动 Redis 或去掉密码配置再补充一个很多人会踩的坑Vue 3 项目在本地开发时接口是http://localhost:8080打包部署到服务器后仍然请求 localhost导致页面能打开但数据不加载。这里要把接口地址写到环境变量文件中例如.env.development和.env.production// .env.production VITE_API_BASE_URLhttp://你的服务器IP:8080打包时使用的是npm run build读取的.env.production不要在代码里把 baseURL 写死。14. 部署上线与合规建议如果只是本地演示前 13 节已经足够。但如果你准备把汽车用品商城项目展示在简历里或者准备交给客户做私活验收上线部署还需要处理几件事。14.1 前后端分离部署后端直接使用java -jar启动或者使用 Docker 打包。生产环境建议用 Docker Compose 统一管理 MySQL、Redis 和应用容器。这里给一个通用配置模板实际使用时把镜像名和端口替换成自己的即可。version: 3 services: mysql: image: mysql:8.0 container_name: mall-mysql environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: auto_parts_mall ports: - 3306:3306 volumes: - ./mysql-data:/var/lib/mysql redis: image: redis:7-alpine container_name: mall-redis ports: - 6379:6379 backend: build: ./backend container_name: mall-backend depends_on: - mysql - redis ports: - 8080:8080前端 Vue 3 打包后的dist目录放入 Nginx推荐在nginx.conf中配置反向代理把/api转发到后端服务server { listen 80; server_name www.example.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这里要注意proxy_pass http://127.0.0.1:8080;结尾不带/时会把原始 URI 全部转发如果带/会剥离location前缀。不同后端接口前缀需要按实际调试。14.2 数据备份与恢复汽车用品电商平台一旦产生订单数据就不能只靠 SQL 初始化文件铺底。上线后需要定期备份 MySQL。一个最基础的备份策略是使用 mysqldumpmysqldump -u root -p auto_parts_mall backup_$(date %Y%m%d_%H%M%S).sql也建议不要把备份文件存放到服务器同一块磁盘否则磁盘损坏时备份会一起丢。14.3 微信小程序上线类目与隐私协议小程序商城具备用户个人信息收集功能时微信平台会要求配置《用户隐私保护指引》。需要在微信公众平台中声明收集的信息类型包括手机号、地址、订单信息等。如果涉及支付还需要完成微信支付商户号申请和商户平台配置。从项目验收角度至少需要准备四份材料项目设计文档说明前后端架构、数据库设计、核心业务流程部署文档写明环境要求和启动步骤测试用例表列出功能点、操作路径、预期结果和实际结果演示脚本从注册登录、商品浏览、下单支付到后台发货、库存扣减保证把主流程走通。14.4 不在代码中泄露敏感信息很多 Spring Boot 商城项目会把数据库密码、Redis 密码、小程序 AppSecret、微信支付商户密钥写在application.yml中。课程设计项目这样写问题不大但如果项目要推送 Git 仓库必须把敏感信息放到环境变量或者配置中心并在.gitignore中排除配置文件防止密钥泄露。一个小程序项目最容易泄露的三个位置前端代码中的app.js或配置文件后端application.yml中的支付密钥Git 提交历史中的旧密码。建议在上传代码前全局搜索password、secret、appid等敏感字段把真实值替换为环境变量占位符。微信小程序 AppSecret 一旦泄露任何人都有机会拿到用户登录态必须重视。15. 从这个项目里能学到什么先想清楚你要从这个项目中拿什么再决定怎么读代码。如果你是在准备毕业设计重点读订单状态流转和数据库设计。把“用户下单 - 库存扣减 - 模拟支付 - 后台发货 - 用户确认收货 - 订单完成”这条主链路完整画出来答辩时能一眼看出你对业务是否理解。如果你是在准备实习或校招重点读两层Spring Boot 拦截器的接口鉴权方式以及 Axios 拦截器 Vue Router 的前端权限控制方式。很多面试官会问“前后端权限是怎么做的”你再从这个小程序商城里讲 token 如何存储、接口如何校验、按钮级权限如何控制。如果你想把这个汽车用品商城项目扩展成可用的私活项目建议优先增加三个模块优惠券模块、商品评价模块、物流轨迹模块。这三者会让商城一下从“演示项目”变成“可运营项目”。但需要注意二次开发前要确认源码本身的代码质量。如果项目里所有业务逻辑都写在了 Controller也没有全局异常处理不要试图在这样的地基上直接加新功能先做一轮基础重构把通用逻辑抽到 Service 层再把文件上传、分页查询、异常返回等封装好。也就是说你在微信开发者工具里打开小程序先注册一个用户随手加一件商品到购物车提交订单然后去 Vue 3 后台把这个订单发货最后回到小程序确认收货。这个循环走通了系统的骨架才算真正被你掌控。之后再谈加支付、加物流、加优惠券都是在同一根主线上做增量不会再让人一头雾水。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进