ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot+uniapp商城全栈实战:从架构设计到多端上架避坑指南

SpringBoot+uniapp商城全栈实战:从架构设计到多端上架避坑指南 简介基于SpringBoot与uniapp构建的商城项目资源包面向有一定Java基础和Vue.js认知、希望系统学习前后端分离开发的开发者。项目参考linjiashop开源商城设计后端以SpringBoot为骨架涵盖业务逻辑处理、RESTful API接口定义、JPA/MyBatis数据库访问前端用uniapp搭建商品列表、购物车、订单管理等跨端页面与交互。资源共67个文件以60个java源文件为主配合3个xml配置、2个yml配置、1个gitignore和1个md说明文档压缩包约64KB目录结构清晰便于按模块阅读与二次开发。已有1938人学习下载可用于毕设选题、课程设计或企业级Web/移动端项目的实战参考。通过阅读源码与配置可掌握SpringBoot自动配置、注解驱动控制器、uniapp生命周期与组件化开发等关键技术还能借鉴数据库设计、权限控制、安全防护与性能优化等落地思路无论用于入门进阶还是项目落地都有实用价值。 如果你正在计划一个 shop 商城项目技术选型锁定 SpringBoot uniapp这事我太熟了。我最近刚把一套完整商城从零搭到上线商品、购物车、订单、支付、多端打包全走了一遍这篇文章就把我实际验证过的方案和踩过的坑整理出来重点是那些文档里不会告诉你的细节。这个项目能做什么一句话说清楚后端用 SpringBoot 提供接口前端用 uniapp 一套代码同时跑微信小程序、H5 和 Android/iOS App覆盖商城最常见的完整闭环。适合谁参考准备做毕业设计、接外包、或者公司要从零起一个中小型电商项目的开发者都可以直接照着搭。1. 项目整体架构设计思路1.1 为什么选 SpringBoot uniapp 这套组合先说选型。商城项目后端可选的东西不少我当时直接定了 SpringBoot原因很朴素生态太成熟了。从数据库连接、缓存、权限、文件上传到支付对接基本都有现成的 starter自动装配机制帮我把大量 bean 的注册和配置都处理好了我只需要关心业务代码。SpringBoot 的社区也大开发中遇到的任何一个报错几乎都能搜到案例这对个人开发者非常友好。以后如果量大了要拆服务Spring Cloud 那一套也能平滑接过来不用推翻重写。前端选 uniapp核心诉求就一个多端复用。商城项目的典型投放渠道是微信小程序、公众号 H5、App要是每个端各写一套光维护成本就能拖垮项目。我用下来的体感是大概 80% 的页面三端完全通用剩下 20% 用条件编译处理差异就够。比如支付调用方式、分享逻辑、更新提示这些本来就该按端区分uniapp 提供了#ifdef MP-WEIXIN这类预处理写法一套代码里做分支不用维护多套工程。这里必须给个实话如果你只做微信生态原生小程序也是一个选项但对后端出身、主要熟悉 Vue 的开发者来说uniapp 的学习路径明显更平缓还有丰富的插件市场可以抄作业。技术选型要结合自己的基础不要盲目追新。1.2 商城模块划分与数据库设计商城项目看着大拆开其实就是两块用户侧与管理侧。用户侧负责首页、分类、商品详情、购物车、订单、支付、个人中心、收货地址管理侧负责商品管理、订单管理、用户管理、轮播图管理、分类管理。个人项目不用一来就把权限系统做得很重能用岗位区分管理员和普通用户就够了先把业务闭环跑通。数据库设计我直接列一份核心表结构给还没动手的人参考表名用途核心字段user用户表id、nickname、avatar、phone、password、openidcategory分类表id、name、sort、iconproduct商品表id、title、main_image、price、stock、statusproduct_sku商品规格表id、product_id、spec_name、price、stockcart购物车表id、user_id、product_id、sku_id、count、checkedorders订单表id、order_no、user_id、total_amount、status、address_idorder_item订单明细表id、order_id、product_id、sku_id、price、countpayment支付流水表id、order_id、transaction_id、amount、statusaddress收货地址表id、user_id、name、phone、province、city、detailbanner轮播图表id、image、link、sort设计时有两个点最容易被新手忽略。第一个只要商品有规格概念比如颜色、尺码价格和库存就必须放在 sku 表而不是商品主表上否则后面下单、秒杀、库存统计全都别扭。第二个金额字段一律用 decimal别用 double浮点运算的精度问题在前端展示和后端对账时会让你抓狂。这两条做到能少踩无数坑。1.3 版本选型SpringBoot 选 2.7 还是 3.x这节单独拎出来说因为很多人第一个坑就栽在版本上。热词里那个“springboot版本太高”基本就是这么来的网上教程用 3.x但你本地是 JDK 8项目根本起不来。SpringBoot 3.x 强制要求 JDK 17如果你没有升级 JDK 的打算老老实实用 2.7.x 配 JDK 8非常稳。我自己用的组合是 SpringBoot 2.7.18 JDK 8 MyBatis-Plus 3.5.x Redis JWT。不是 3.x 不好而是 2.7.x 对第三方 starter 的兼容性经过了大量验证特别是对接老的支付 SDK、短信 SDK 时踩坑成本低得多。uniapp 那边我选了 Vue3 版本语法更现代但市面上很多教程和插件还是 Vue2 写法看资料的时候注意区分别被绕晕。2. 后端核心细节解析2.1 项目初始化与目录分层SpringBoot 项目用 IDEA 初始化很简单选 Spring Initializr 就行。目录结构我建议按经典分层来建简单直接个人项目完全够用com.example.shop ├── controller # 接口层 ├── service # 业务层 ├── mapper # 数据访问层 ├── entity # 数据库实体 ├── dto # 传输对象 ├── vo # 视图对象 ├── config # 配置类 ├── common # 统一返回、异常处理 └── utils # 工具类我不建议一上来就上 DDD 或复杂的分层框架那会把简单问题复杂化。这不是说分层思想不重要而是商城项目初期最重要的是把接口快速跑通等到业务确实膨胀了再调整架构完全来得及。我见过太多人把时间耗在架构设计上结果两个月还没跑通一个完整下单流程。还有一件事真的很重要写任何接口前先定义统一返回结构。我习惯用ResultT包一层包含 code、message、data 三个字段再加一个全局异常处理器。商城项目接口数量非常多前后端联调时统一返回结构能省掉大量无意义沟通。前端只需判断 code 就能决定是否弹提示不用每个接口单独处理错误逻辑。2.2 登录鉴权与 Token 机制商城登录常见有两种方式手机号验证码登录、微信小程序授权登录。我的建议是两个都做后端通过前端传的 loginType 字段来区分。手机号登录走短信验证码小程序登录用 wx.login 拿到的 code 向后端换 openid然后再走同一套 token 签发逻辑。登录成功之后我会签发一个 JWT 返回给前端。要注意一个关键点token 本身有过期时间但用户逛商城可能会很久如果过期时间太短体验极差。我的做法是额外把 token 存一份到 Redis设置更长的过期时间然后用拦截器在每次请求时刷新这个过期时间。用户只要一直在操作就不会掉线真正长时间离开后再回来Redis 里的 key 也过期了重新登录即可。拦截器这边我要特别提醒鉴权逻辑要简单只做“解析 token、校验有效性、放行或拦截”。用户信息解析出来之后放进 ThreadLocal供后续业务代码读取用完在 afterCompletion 里一定要清理。不清理的话Tomcat 线程池复用时会出现用户数据串号的问题这种 bug 极其隐蔽排查起来非常头疼。2.3 商品与订单的库存扣减订单流程是商城最核心的链路。完整流程是用户提交订单 → 校验商品状态和价格 → 扣减库存 → 生成订单和明细 → 支付 → 支付回调更新状态。这里最容易出问题的就是库存超卖。多线程同时下单时如果先查库存再减库存两个请求都查到库存还有 1 件就会同时下单成功库存变成 -1。我之前踩过这个坑后来换成在 SQL 语句里做原子扣减UPDATE product_sku SET stock stock - #{count} WHERE id #{skuId} AND stock #{count}这条 SQL 自带条件检查stock #{count}不满足时受影响行数为 0业务层捕获后直接提示库存不足。不需要分布式锁也不需要 Redis 预减对于商城初期流量完全够用。等哪天并发量真的大了再考虑 Redis 预减库存 消息队列异步扣减的方案不要提前把系统搞复杂。订单状态我用枚举来管理而不是散落一地的魔法字符串。商城订单状态基本是待支付 → 已支付 → 已发货 → 已完成中途可以有取消和退款分支。每个状态对应什么操作、哪些状态可以流转到哪些状态集中写在枚举或状态机里代码可读性和维护性会好很多。2.4 支付对接与回调幂等我接的是微信支付uniapp 的 H5、小程序、App 端拉起支付的方式不同但后端逻辑是一致的统一下单拿到支付参数 → 前端拉起支付 → 用户支付 → 微信服务器异步回调通知后端 → 后端更新订单状态。支付这块最大的坑在回调处理。微信官方文档说得很清楚回调通知可能会重复发送所以后端必须做幂等处理。我的实现是回调进来之后先查订单当前状态如果已经是已支付直接返回成功响应不再重复处理业务逻辑。同时回调处理里的逻辑要尽量精简先把状态更新掉再去做后续的发货提醒、积分赠送之类的附加操作避免回调接口超时被微信重试轰炸。还有一个小细节微信支付要求的回调响应格式是特定 XML 结构错了会被判定为通知失败然后一直重试。我见不少人卡在这其实就是返回体没写对。支付对接完一定要用微信官方提供的沙箱环境多测几遍覆盖正常支付、取消支付、支付金额不对、重复回调几个场景。3. 前端 uniapp 端实现要点3.1 页面结构与路由设计uniapp 的项目结构很清晰pages 目录下放页面文件pages.json 里注册路由和 tabBar。商城标配的四个 tab 是首页、分类、购物车、我的tabBar 图标要用 png 格式建议尺寸 81px 以上的 2 倍图否则真机上会糊。页面生命周期这块我必须强调一下因为几乎每个新手都会踩uniapp 的页面生命周期和 Vue 组件生命周期不是一回事。onLoad只在页面首次加载时执行一次适合拉取初始数据onShow每次进入页面都会触发适合做数据刷新。我之前做“从详情页返回列表列表数据不更新”的功能时就是把刷新逻辑写在了onLoad里改成onShow之后问题立刻解决。3.2 请求封装与登录态管理我习惯在 utils 里封装一个 request.js基于uni.request做一层包装。统一设置 baseURL、请求头、超时时间响应回来统一处理 code错误统一弹 toast。这样做的好处是业务页面里永远只需要写业务代码不用重复关心 loading、错误提示、token 过期这些琐事。token 存储在uni.setStorageSync请求拦截器里从本地读取并塞到 header 的 Authorization 字段。如果接口返回 401清除本地登录信息跳转登录页。这里有个细节token 过期跳转登录页之后用户登录成功应该回到原来想访问的页面而不是固定跳回首页。所以跳转前先把当前页面路径存下来登录成功后用uni.redirectTo回去体验会好很多。3.3 购物车与下单交互购物车数据放服务端还是本地是一个需要想清楚的决策。我的方案是登录后购物车数据全部走服务端接口保证多端同步不登录时允许加购物车但只存本地登录成功后做一次合并。这个逻辑稍微复杂但电商产品基本都这么做因为用户可能会在手机 App 加购、在微信小程序里下单购物车必须跟账号走。下单交互环节比较关键的是前端点击立即购买时不要把商品原价、总价算完传给后端就完事。可靠的方案是前端只传商品 skuId、数量、收货地址 id价格一律由后端实时计算。这样既防止用户篡改价格也保证优惠活动逻辑统一在后端维护。调试这个环节要特别细心前后端的价格对不上是联调时最高频的问题。3.4 多端打包与上架经验uniapp 的多端打包流程我按端说H5 最简单HBuilderX 里发行到 H5 就能产出静态文件微信小程序在 HBuilderX 里运行到小程序模拟器然后在微信开发者工具里上传App 则分云打包和本地打包云打包方便快速但需要自己准备证书。Android 上架应用市场这块热词里好多人问我多说几句。上架到华为、小米、OPPO、VIVO 等应用商店需要准备的东西基本一致软著、隐私政策、应用签名、截图。隐私政策特别容易出问题应用里只要收集了用户任何信息都必须有对应说明很多 App 被驳回就是因为隐私政策写得含糊或没有弹窗告知。建议在项目开发阶段就把隐私弹窗加上别等到审核被拒再改。iOS 打包需要开发者账号个人账号 $99/年打包流程比 Android 麻烦但 uniapp 已经帮我们处理了大部分工作量。如果只是测试可以用 HBuilderX 的真机运行不需要证书也能装到自己的手机上。4. 常见问题与排查技巧实录4.1 SpringBoot 版本太高项目跑不起来遇到这个问题的朋友十有八九是下到了一个 3.x 的项目模板但本机 JDK 还是 8。排查方法很简单先看自己的 JDK 版本java -version再在 pom.xml 里看 spring-boot-starter-parent 的版本号。如果不对齐要么换 JDK 17要么把 SpringBoot 版本改成 2.7.x。我自己的选择是改版本因为第三方 SDK 的兼容性要考虑JDK 8 在中小企业里还是绝对主流。还要注意数据库驱动问题。SpringBoot 2.7.x 配合 MySQL 5.7 或 8.0 都没问题但连接 MySQL 8 时必须使用com.mysql.cj.jdbc.Driver并在 URL 里加上时区参数serverTimezoneAsia/Shanghai否则会报时区相关错误。4.2 uniapp 下拉刷新与页面滚动冲突热词里这个问题问得很多下拉刷新时页面上的滚动内容也跟着动体验很差。其实这是滚动穿透问题。我的处理思路是只在必要的页面开启enablePullDownRefresh比如首页和订单列表其他页面统一用 scroll-view 内部滚动。如果某个页面既需要下拉刷新内部又有可滚动区域那就在 scroll-view 上设置refresher-enabled而不是用页面级下拉刷新这样滚动容器和刷新手势就不会打架。4.3 webview 白屏与 renderjs 视频播放问题webview 打开白屏最常见的两个原因一是加载的 URL 是 http 而 App 强制 https导致被系统拦截二是 webview 页面配置了web-view组件但网络域名没有在后台配置合法域名。排查建议先看 console 输出和客户端日志确认是被拦截还是路径错误。renderjs 录制的 mp4 在手机上无法播放这个问题我也遇到过。renderjs 虽然能和 dom 通信但用它获取录屏数据生成的文件在部分 Android 机型上存在编码兼容性问题。建议优先用原生拍摄或系统录屏能力如果必须用 renderjs视频文件生成后检查编码格式必要时用工具转成 h264 编码的 mp4兼容性会好很多。4.4 页面找不到与其他编译报错error: not found: page这个报错很直白pages.json 里没有注册这个页面路径或者路径写错了。uniapp 的路由是页面化的新增页面必须到 pages.json 里注册这个是新手最容易犯的错。另一个常见问题是有些页面没改 pages.json 直接删掉了启动时也会报找不到页面。组件生命周期和页面生命周期混用是另一个高频问题。onLoad、onShow、onReady是页面级mounted、created是组件级。在组件内部想监听页面显示事件用onShow是拿不到的需要配合uni.$on或自定义事件。理解了这一点类似的诡异问题基本都能自己排查。5. 实际操作后的一些体会项目全部跑通之后我最大的体会是商城项目最大的成本不在写代码而在前后端联调和多端适配。如果你是自己一个人做全栈建议先把后端接口用 Postman 全部测一遍再动前端否则两边同时出问题排查难度会翻倍。另外我强烈建议在开发初期就把日志规范做好。后端统一 logback 配置输出到文件前端在 request.js 里加上请求日志。别小看这件事上线后用户反馈问题你回查日志能少走很多弯路。我后来排查支付回调漏单就是靠日志对比才把问题定位到数据库连接池配置上。如果你想在这个项目上继续延展可以考虑的方向很多增加秒杀功能、接入优惠券系统、做用户积分体系、把管理端改为独立后台管理系统。底子打好了这些模块本质上都是往现有框架上挂新业务表和新接口。商城项目最迷人的地方就在这里看起来庞杂但每块都能拆开做深做完一个收获是全栈的。本文还有配套的精品资源点击获取
返回列表