拓冰建站拓冰建站
首页 / 资讯中心 / 正文

SpringBoot+Vue3+微信小程序:全栈商城系统开发实践

这次我们来看一个典型的全栈商城项目基于SpringBoot Vue3 微信小程序的健身器材交易平台。项目分为三端用户看到的微信小程序端负责商品浏览、购物车、下单支付运营人员使用的 Vue3 管理后台负责商品管理、订单处理和批量上架后端统一由 SpringBoot 提供 RESTful API数据库走 MySQL。标题里出现的“SpringBoot4”多数情况下是项目模板命名习惯实际技术栈仍然以 Spring Boot 为准编写代码时先确认pom.xml里的官方版本基线。这个项目最值得关注的不是健身器材这个垂直领域本身而是它的电商闭环足够完整从微信登录、商品分页、购物车、生成订单、支付回调到后台发货和状态流转几乎覆盖了“小程序电商系统”的所有核心节点。如果你正在做课程设计、毕业设计或者需要一套前端后台都能用的商城脚手架这个项目可以作为直接改造的起点。本文会按照“核心能力梳理 - 使用边界与合规提醒 - 系统架构与数据库设计 - 本地环境部署 - 后端接口实现 - Vue3 管理后台开发 - 小程序端对接 - 接口联调与排错 - 运维最佳实践”的顺序展开。这篇文章适合已经掌握 Java、Vue 基础想完整跑通一个多端电商项目的人也适合只差一个能演示的实训项目、需要快速评估技术方案的人。1. 核心能力速览能力项说明项目类型健身器材电商交易系统包含用户小程序、管理后台、后端接口三层后端框架SpringBoot主流版本为 2.7.x 或 3.x具体看课程项目基线前端框架Vue3 Vite Element Plus 管理后台用户端微信小程序原生开发也可迁移到 uni-app数据库MySQL 8.x订单模块可扩展 Redis 缓存核心功能用户登录、商品分类、商品详情、购物车、订单结算、支付回调、后台发货后台功能商品 CRUD、批量上下架、订单管理、库存管理、用户管理接口形式RESTful JSONToken 或 JWT 鉴权权限模型普通用户、管理员/商家两种核心角色课程项目可精简为一种管理员典型场景课程设计、毕业设计、小型器材商户私域商城二次开发从材料看该项目更偏向“完整电商功能演示 多端代码组织”而不是只做静态页面。验证项目是否合格重点看三件事订单状态机是否完整、商品管理能否支撑批量操作、移动端接口是否能在微信开发者工具里直接跑通。2. 适用场景与使用边界2.1 适合谁用如果你是需要完成 SpringBoot 全栈项目的在校学生这类项目最大的价值就是结构清晰前端调用 API、后端处理业务、数据库落表每一层都能在答辩时讲明白。如果你是一个小型健身器材商户想在微信生态里做私域售卖也可以基于这套代码进行二次开发替换品牌、价格、分类即可。2.2 能解决什么问题健身器材交易与普通服装电商不同商品重量大、物流费用高、售后服务周期长因此系统里一般会重点关注商品规格、库存扣减、订单状态和物流发货。一个可用的系统至少包含商品列表搜索、商品详情展示、加入购物车、选择数量与规格、提交订单、支付回调、后台订单处理。2.3 使用边界和合规提醒这里必须提醒几件事。第一微信小程序上线和微信支付都要求企业主体个人开发者无法直接使用微信支付原生能力课程项目通常用模拟支付或沙箱环境演示接入真实支付需要商户号和产品资质。第二小程序图片、品牌 Logo、代言人肖像等素材需要获得授权不能直接抓取商业网站的素材用于演示发布。第三商品数据可能涉及商标上架前要进行版权核对。第四系统应遵循最小化采集用户手机号、地址属于敏感信息不要写入日志接口返回时也要做脱敏处理。3. 系统架构与功能模块拆解3.1 整体分层后端采用经典三层架构层级模块/作用Controller 层接收请求参数校验统一返回 ResultService 层业务逻辑订单状态机、库存扣减、支付回调处理Mapper/Repository 层数据库 CRUD前端小程序首页、分类、购物车、结算、订单、我的Vue3 管理后台登录、商品管理、订单管理、数据概览实际开发时建议把跨端公共逻辑放到后端例如商品状态判断、价格计算、库存校验都只做一次避免小程序端和管理后台逻辑不一致。3.2 核心数据表设计电商系统最少需要以下核心表。字段取名可以根据 MyBatis-Plus 或 JPA 的习惯调整但逻辑上要完整user 用户表 product_category 商品分类表 product 健身器材商品表 product_sku 商品规格表比如颜色、重量 cart_item 购物车表 order_info 订单主表 order_item 订单明细表 payment_record 支付流水表商品表建议字段id, category_id, title, cover_image, image_list, price, original_price, stock, sales, status, detail, create_time, update_time。订单表建议字段id, order_no, user_id, total_amount, pay_amount, status, receiver_name, receiver_phone, receiver_address, pay_time, delivery_time, finish_time。3.3 订单状态设计课程项目最容易出问题的是订单状态不清晰。建议统一用枚举或固定字符串维护状态不要把“待付款”“已付款”这类展示文字直接存库CREATED已创建待支付 PAID已支付待发货 DELIVERED已发货待收货 FINISHED已完成 CLOSED已取消/超时关闭 REFUNDING退款中后端做状态流转时核心代码应该使用状态校验。比如订单状态从“待付款”变为“已付款”时不允许从“已发货”状态直接改为“已完成”这部分可以用简单的 switch 判断也可以引入状态机框架但课程项目没有必要过度设计。4. 本地部署环境准备与工程启动4.1 环境清单部署前先确认环境。下面的版本是通用参考具体以项目pom.xml和package.json里的锁定版本为准工具建议版本JDK8 / 11 / 17取决于 SpringBoot 大版本Maven3.6MySQL5.7 / 8.0Node.js16 或 18IDEIntelliJ IDEA VS Code微信开发者工具最新稳定版如果项目使用 Spring Boot 3.xJDK 必须是 17 以上并且代码中的javax.*要换成jakarta.*。如果项目还在用 Spring Boot 2.7JDK 8/11 即可。不要盲目升级 JDK避免依赖不兼容。4.2 初始化数据库先创建数据库并导入 SQL 初始化脚本CREATE DATABASE IF NOT EXISTS fitness_mall DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;执行完建表 SQL 后再确认数据库账号、密码和项目配置一致。4.3 后端配置示例使用 SpringBoot 时核心配置集中在application.ymlserver: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/fitness_mall?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your-password jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai 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 jwt: secret: your-project-jwt-secret-key expire-minutes: 1440注意真实项目中 MySQL 地址、账号密码、JWT Secret 不能直接提交到公开仓库。课程作业提交时可以保留默认配置但商用项目建议放到环境变量或配置中心。4.4 打包并启动后端启动命令mvn clean package -DskipTests java -jar target/fitness-mall.jar如果项目没有安装 Maven 也可以使用 Maven Wrappermvnw spring-boot:run管理后台启动命令npm install npm run dev微信小程序端用微信开发者工具导入miniapp目录修改utils/config.js里的接口域名后直接编译预览。5. SpringBoot 后端核心链路实现5.1 统一返回结构与异常处理接口返回建议使用统一格式否则小程序、管理后台都要各自处理数据格式错误public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.code 200; result.message success; result.data data; return result; } public static T ResultT failed(String message) { ResultT result new Result(); result.code 500; result.message message; return result; } }建议在 Controller 里不要直接返回实体类而是返回ResultT。这样接口返回报文稳定前端可以统一拦截错误状态。5.2 微信登录与 Token 签发小程序获取用户身份的标准流程是小程序端调用wx.login拿到临时code再将code发送给后端后端调用微信接口换取openid。课程项目如果不想每次请求都访问微信接口可以只在登录时换取然后签发自己的 JWT Token。后端接口大致如下PostMapping(/api/auth/login) public ResultString login(RequestBody LoginRequest request) { // 1. 用 code 调用微信 jscode2session 接口得到 openid // 2. 根据 openid 查找用户不存在则创建 // 3. 生成 JWT Token返回给小程序端 String token userService.login(request.getCode()); return Result.success(token); }小程序端拿到 Token 后需要把 Token 放到请求头的Authorization字段里。后端使用拦截器或 Spring Security 解析 Token并将 userId 设置到请求上下文。5.3 商品列表分页查询商品接口需要支持关键字搜索、分类筛选、排序。代码如下GetMapping(/api/products) public ResultPageResultProductVO pageProduct(RequestParam(defaultValue 1) int page, RequestParam(defaultValue 10) int size, RequestParam(required false) Long categoryId, RequestParam(required false) String keyword, RequestParam(required false) String sort) { PageProduct productPage productService.pageProduct(page, size, categoryId, keyword, sort); return Result.success(PageResult.of(productPage)); }数据库查询时重点关注根据status1只查上架商品库存为 0 的商品不下发到小程序图片字段返回相对路径由前端拼接域名减少数据流量。5.4 购物车与库存预扣加入购物车本身不扣库存只是记录用户选择的商品和数量。真正的库存扣减放在下单时而且要使用数据库乐观锁或唯一约束避免超卖。核心逻辑先查商品当前库存再使用UPDATE ... SET stock stock - #{count} WHERE id #{productId} AND stock #{count}用更新行数判断是否扣减成功。5.5 订单创建与支付回调创建订单的关键操作是生成订单号、计算订单金额、扣减库存、清空对应购物车项。支付模块在商业项目里应走微信支付 V3但课程演示可以先做一个“模拟支付”接口PostMapping(/api/pay/mock) public ResultString mockPay(RequestBody MockPayRequest request) { // 1. 根据订单号查询订单 // 2. 校验订单未支付 // 3. 调用微信支付统一下单或演示时直接进入回调逻辑 // 4. 更新订单状态为 PAID // 5. 记录支付流水 return Result.success(支付成功); }在真实微信支付流程里后端只负责生成 prepay 参数小程序通过wx.requestPayment拉起收银台微信服务器回调后端通知接口后端再把订单状态改为已支付。这个回调接口必须校验签名不能只凭订单号就改订单状态。5.6 库存与订单状态一致性课程项目常见的隐藏问题是用户下单后不支付库存却被扣掉。更合理的方案是订单创建时不立即扣库存而是“预占库存”超时未支付后释放在简化版本里可以直接在用户提交订单支付成功后扣减库存。无论采用哪种方式都要保证订单表和库存表的数据一致。建议为订单增加expire_time字段任务调度定时扫描超时未支付订单并关闭。6. Vue3 管理后台与批量运营操作6.1 管理后台初始化Vue3 环境建议使用 Vite 创建项目npm create vitelatest admin-web -- --template vue cd admin-web npm install npm install element-plus vue-router pinia axios npm run dev管理后台目录建议src ├── api │ ├── product.js │ └── order.js ├── router │ └── index.js ├── store │ └── user.js ├── views │ ├── Login.vue │ ├── Dashboard.vue │ ├── product/ProductList.vue │ └── order/OrderList.vue6.2 登录与路由权限管理后台不是小程序端不能使用微信登录通常采用账号密码 Token 方式。登录成功后在 Pinia 中保存用户信息和 Token。路由守卫判断没有 Token 时跳转登录页router.beforeEach((to, from, next) { const token localStorage.getItem(admin-token); if (!token to.path ! /login) { next(/login); } else { next(); } });如果角色不止一种可以在路由 meta 上标记roles再结合用户角色过滤路由。6.3 商品列表页与上传商品列表页是后台最高频操作。表格里最好展示商品图、标题、价格、库存、销量、上下架状态。常规页面结构是搜索表单 批量操作按钮 表格 分页 新建/编辑弹窗。批量操作接口可以设计为export function batchUpdateProductStatus(data) { return request({ url: /api/admin/products/batch-status, method: put, data }); }请求体示例{ ids: [1001, 1002, 1003], status: 1 }这个接口能够一次上架或下架多个商品后台调用时先校验权限再逐条更新并返回最终成功条数。对于几千条商品的批量改价、批量设库存也建议使用类似结构不要用循环前端请求单个接口。6.4 图片上传与回显健身器材图片不适合很小的压缩图详情页通常会使用多图展示。管理后台保存商品图片时可以上传到本地服务器目录也可以接入对象存储。上传接口返回图片 URL前端再将该 URL 和其他商品字段一起提交。后端建议限制图片类型和大小避免把可执行文件上传到服务器。6.5 订单管理订单管理页需要完成订单查询、详情查看、发货。发货时填写物流公司和物流单号后将订单状态改为DELIVERED。为了展示完整还需要一个小型操作日志表记录“谁在什么时间改了什么状态”这比把管理员操作过程硬编码在前端要可靠得多。7. 微信小程序端接口对接与购物流程7.1 请求封装小程序端建议封装统一的request方法每次请求自动携带 Token遇到 401 时跳转登录页const BASE_URL http://127.0.0.1:8080; function request({ url, method GET, data {} }) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, method, data, header: { Content-Type: application/json, Authorization: wx.getStorageSync(token) || }, success(res) { if (res.data.code 200) { resolve(res.data.data); } else { wx.showToast({ title: res.data.message, icon: none }); reject(res.data); } }, fail(err) { reject(err); } }); }); } module.exports { request };这种封装能显著减少每个页面的重复代码。在小程序真机预览时BASE_URL 不能写localhost或127.0.0.1要改为局域网 IP 或线上域名并且需要在微信公众平台配置域名白名单。7.2 小程序登录流程小程序首页加载前可以先检测本地 Token 是否存在如果不存在就执行静默登录async function login() { const code await new Promise((resolve, reject) { wx.login({ success: (res) resolve(res.code), fail: reject }); }); const token await request({ url: /api/auth/login, method: POST, data: { code } }); wx.setStorageSync(token, token); }7.3 首页与商品列表首页由轮播图、分类导航、推荐商品列表组成。轮播图和分类数据来自后端接口商品列表可以带“加载更多”或“上拉触底加载下一页”的逻辑。小程序使用scroll-view或页面自带的onReachBottom实现分页时注意设置page和size参数并把hasMore保存到 data 中。7.4 购物车页面购物车页面在本地操作体验更流畅但提交订单时必须以服务端数据为准。本地购物车数据结构至少要保存skuId、商品 ID、数量、选中状态。用户点击结算时把选中的商品列表传给后端后端重新计算价格并返回订单确认信息。7.5 下单与支付下单按钮触发POST /api/orders返回订单号。支付时进入模拟支付或微信支付支付成功后跳转订单详情。整个流程涉及多个异步状态建议用一个状态变量控制按钮防止用户重复点击导致重复下单if (this.submitting) return; this.submitting true; try { const order await createOrder(this.selectedItems); await mockPay(order.orderNo); wx.redirectTo({ url: /pages/order/detail?orderNo order.orderNo }); } finally { this.submitting false; }7.6 个人中心与订单列表个人中心展示用户头像、昵称、待付款、待发货、待收货等入口。订单列表页面按照状态分类用户可以取消待付款订单、确认收货。确认收货后再次提示用户避免误操作。商家管理操作应该在管理后台完成不在小程序端暴露。8. 接口 API、联调与常见问题排查8.1 核心接口规划功能请求方法路径权限小程序登录POST/api/auth/login公开商品分页GET/api/products公开商品详情GET/api/products/{id}公开加入购物车POST/api/cart/items用户查看购物车GET/api/cart/items用户创建订单POST/api/orders用户模拟支付POST/api/pay/mock用户我的订单GET/api/orders/mine用户确认收货PUT/api/orders/{orderNo}/confirm用户后台商品列表GET/api/admin/products管理员后台批量上下架PUT/api/admin/products/batch-status管理员后台发货PUT/api/admin/orders/{orderNo}/delivery管理员调用方式统一为 JSON时间字段统一为字符串格式。小程序端和 Vue3 管理后台都读取同一个后端接口可以避免同一业务逻辑重复实现。8.2 curl 调试示例后端启动后先用 curl 验证接口是否正常curl -X GET http://127.0.0.1:8080/api/products?page1size10 \ -H Content-Type: application/json如果返回{ code: 200, message: success, data: { records: [], total: 0 } }说明商品列表接口链路正常接下来再排查数据填充问题。8.3 常见问题与排查方法问题现象可能原因排查方式解决方案后端无法启动端口被占用或数据库连接失败查看控制台日志检查 8080 端口换端口或修改 application.yml小程序接口 404BASE_URL 配错或者路径不一致打开开发者工具 Network 面板对照后端 RequestMapping 修正路径小程序连不上本地后端真机无法访问 localhost改用电脑局域网 IP 或用云服务器调试在 config.js 修改接口域名接口返回“请先登录”未传 Token 或 Token 过期查看请求头是否带 Authorization重新登录刷新 Token新增商品后小程序看不到商品状态不是上架状态查询数据库 status 字段后台改为上架状态订单支付后状态未改变支付回调未触发或签名校验失败查看后端支付日志和回调请求检查回调路径和签名算法Vue3 请求跨域后端没有放开 CORS观察浏览器控制台 CORS 报错后端配置跨域过滤器页面白屏JS 报错或依赖缺失打开浏览器控制台根据报错重新安装依赖商品图片不显示图片路径错误或静态资源被拦截直接访问图片 URL配置静态资源映射路径批量操作只成功一部分中间某条数据异常查看批量接口返回明细增加事务失败时整体回滚8.4 前后端联调流程推荐顺序先调登录接口再调商品接口再调购物车最后调订单和支付。每一步都要以数据库实际变化为准不要只看前端页面是否“看起来成功”。例如创建订单后应该去数据库order_info和order_item表核对金额、用户、商品明细支付接口调用后要核对订单状态是否从CREATED变成PAID。因为本项目没有内置音视频、大模型等复杂推理场景对 CPU 和显存没有特殊要求。部署时关注的是 JVM 内存、MySQL 连接数和前端静态资源的带宽而不是显卡资源消耗。本地开发电脑 8GB 内存即可正常跑后端和数据库16GB 会更宽松。9. 性能观察、最佳实践与后续扩展9.1 本地资源占用观察后端启动后可以通过以下命令检查 Java 服务的资源占用jps -l jstat -gc pid 1000如果出现内存溢出通常是查询返回数据量过大或 JVM 堆设置过小。可以在启动命令中显式指定内存java -Xms512m -Xmx1024m -jar target/fitness-mall.jar9.2 代码与工程最佳实践项目二次开发时建议先做一次全面检查数据库密码、JWT Secret 不要使用默认值。application.yml中的配置可以拆成application-dev.yml和application-prod.yml两套。商品价格使用整数分存储避免浮点数造成金额误差。删除商品使用逻辑删除不要直接物理删除否则历史订单明细会找不到商品快照。小程序端和管理后台不要共用一套登录接口后台必须限制访问来源并增加验证码。接口层做参数校验至少校验商品数量不能为负数、收货电话格式是否正确。支付类操作要记录流水号方便对账。9.3 像“练手项目”一样验证一遍任何类似商城项目拿到手都建议按下面的检查清单验证一遍注册或登录是否能在数据库生成对应用户数据。商品上下架状态是否能影响小程序端展示。库存为 0 的商品是否还能被加入购物车。下单时库存是否会被正确扣减。订单支付后后台“待发货”列表是否出现新订单。管理后台发货后小程序端订单状态是否变为“待收货”。用户确认收货后订单是否能正常结束。取消订单后库存是否回补。一个账号能否看到自己的订单而看不到别人的订单。未登录用户能否直接调用需要登录的接口。如果这十条都能跑通这套商城可以继续在此基础上扩展秒杀、优惠券、会员积分、物流查询等功能。9.4 可扩展方向当前项目核心是“健身器材电商”。如果希望它更像一个能实际运营的平台可以从三个方向扩。第一增加会员体系比如按消费金额划分普通用户与 VIP 用户VIP 用户享受不同折扣。第二增加多商户入驻健身器材厂商直接在自己的店铺后台上传商品平台只做审核和订单分账这会涉及更复杂的权限与结算设计。第三增加运动内容板块器材销售不是一次性交易可以结合训练计划、使用教程视频等提升复购率相当于把商城做成“器材销售 内容服务”结合体。这次的健身器材交易小程序本身并不复杂真正值得吸收的是“SpringBoot 后端怎么把商品、订单、支付状态管理好Vue3 管理后台怎么做运营操作小程序怎么跟后端完成一次电商闭环”这条完整链路。建议先跑通后端连接 MySQL再打开 Vue3 管理后台造一批测试商品最后在微信开发者工具里完成一次从浏览到支付的演示。最容易踩的坑集中在三处数据库账号密码不匹配、小程序接口地址不是局域网 IP、订单状态没有实现闭环。搭建完这套项目后直接把它当成自己后续写电商、写后台管理系统时的脚手架会节省大量重复搭框架的时间。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门