☰
SpringBoot2+Vue3手机商城全栈项目:架构设计到部署全解析
2026/10/20 21:52:30 网站建设 项目流程

从“做一个手机商城”到真正跑起来,中间隔了不止一个SpringBoot配置。我前后带过不少新人把这套欢迪迈手机商城系统从导入代码到完成二次开发,走了很多弯路,也踩了不少坑。今天这篇东西不聊虚的,就围绕SpringBoot2 + Vue3 + MyBatis-Plus + MySQL8.0这套技术栈,把整个手机商城的设计思路、数据库结构、后端接口、前端页面到本地运行部署全链路拆一遍,文档里没写明白的地方,在这篇里尽量补清楚。

这套商城系统,定位是典型的Java Web全栈项目,适合正在做毕业设计的学生、刚入职想练手全栈开发的新人,以及想快速搭一个可直接演示的商城Demo的开发者。它的前端是Vue3 + Vite + Element Plus,后端是SpringBoot2 + MyBatis-Plus,数据库用MySQL8.0,登录认证走JWT,管理端和用户端都齐。我先把系统怎么拆、每个模块怎么实现、实际部署会遇到哪些问题一次说透。

1. 这套项目为什么值得研究:整体架构与技术选型思路

1.1 前后端分离结构:各目录各司其职

这套系统采用前后端完全分离的开发模式,前端工程和后端工程是两个独立项目,通过RESTful API对接。这种结构的最大好处是职责清晰:前端只管页面渲染和用户交互,后端只负责业务逻辑和数据处理,联调的时候只要接口约定好,两边可以并行开发互不阻塞。

后端项目按SpringBoot标准分层:

com.huanweima.shop ├── controller // 控制层,接收前端请求 ├── service // 业务层,处理核心逻辑 ├── mapper // 数据访问层,继承MyBatis-Plus的BaseMapper ├── entity // 实体类,与数据库表字段一一对应 ├── config // 配置类:跨域、分页、拦截器 ├── common // 公共类:统一返回结果、异常处理、JWT工具 └── vo // 视图对象:给前端返回的封装对象

前端工程用Vite构建,按页面功能分了views目录,用户端有首页、商品列表、商品详情、购物车、订单结算、个人中心,管理端有商品管理、订单管理、分类管理、用户管理、数据统计。这种模块划分方式非常标准,对于要拿去做课设或者二次开发的场景,扩展点在哪一眼就能找到。

1.2 为什么要用SpringBoot2而不是SpringBoot3

这是个很实际的问题。现在SpringBoot3已经出了,但很多企业项目和教学项目依然在用SpringBoot2,原因很实在:稳定。SpringBoot2.x经过多年大规模生产环境验证,各种中间件的兼容性资料多,遇到问题搜一下就有答案。而且MyBatis-Plus对SpringBoot2的适配最成熟,起步依赖一拉就通,不用像SpringBoot3那样得处理Jakarta命名空间迁移和JDK17的适配问题。

对于做毕设或者练手项目来说,SpringBoot2踩坑成本远低于SpringBoot3,文档多、同事会的人多、导师也熟悉。等技术积累到一定程度再考虑升级,完全没有问题。

1.3 为什么数据访问层选择MyBatis-Plus

MyBatis-Plus是MyBatis的增强工具,它最吸引人的是单表CRUD不用写SQL。继承BaseMapper之后,insert、deleteById、selectById、selectPage这些基础方法直接就有了,写商城这种体量的系统,90%的单表操作都不用自己拼SQL,开发速度能快一倍。

但MyBatis-Plus绝不是让你完全不写SQL。像订单查询需要关联商品明细、统计报表需要分组聚合这种复杂查询,还是得老老实实写XML或注解SQL。这套系统里就有不少手工SQL,比如首页推荐商品的查询、订单详情的关联查询、后台图表的数据统计,都是通过自定义SQL完成的。这一点非常重要,很多新手以为用了MyBatis-Plus就不用学SQL了,实际上恰恰相反,基础的SQL能力永远都是核心竞争力。

1.4 Vue3 + Element Plus:为什么是管理后台的最佳搭档

Vue3的组合式API(Setup语法糖)写起来比Vue2的选项式API清爽很多,代码复用也方便。配合Vite开发服务器启动速度极快,保存即热更新,调试体验比老式的Webpack一条龙顺滑得多。

Element Plus是Vue3生态里最成熟的UI组件库,后台管理页面需要的表格、表单、弹窗、分页、消息提示全都有现成组件。欢迪迈商城的管理端商品管理页面就是典型的ElTable + ElDialog + ElForm组合:列表用ElTable渲染商品数据,点击编辑弹出ElDialog加载ElForm表单,提交后刷新列表。这种模式在真实项目中重复度极高,做过后台的人看到这个页面结构会有天然的亲切感。

2. 数据库设计:手机商城的核心表结构与关联关系

2.1 核心表整体设计

手机商城这种系统,表的设计是有固定套路的。欢迪迈商城的数据表不算多,但每一张都对应电商系统的核心模块,搞清楚这些表的字段和关系,电商类项目的基本盘就掌握了。

  • 用户表:保存系统用户和管理员,区分角色
  • 商品分类表:支持两级分类,用于前台导航和商品归类
  • 商品表:包含标题、主图、轮播图、价格、库存、详情描述、销量
  • 购物车表:保存用户加购记录,关联商品和用户
  • 订单表:记录订单编号、总金额、收货信息和订单状态
  • 订单明细表:记录订单中每个商品的快照信息,包括数量、单价
  • 收货地址表:保存用户收货地址,下单时可选择
  • 轮播图表:控制首页轮播广告图的位置和状态

这里说几个在字段设计上容易被忽略的点。第一是商品价格尽量用整数分存储,避免用浮点数。数据库的DECIMAL类型没问题,但Java端用float或double算金额特别容易出精度误差,这套系统更合理的方式是用整数分的思路去设计,展示层再转换成元。第二是订单号不能直接用自增id,因为容易暴露销量,而且并发下自增id会有可预测性问题,一般会用时间戳加随机数的格式生成唯一业务订单号。第三是逻辑删除字段deleted,用户删除购物车记录这种操作,物理删除很容易误删数据,用逻辑删除后期还能追溯数据,这也是MyBatis-Plus默认支持的做法。

2.2 用户、商品与购物车表的关键字段

用户表字段不多但很关键:username、password加密存储、nickname昵称、avatar头像、phone手机号、role角色、createTime注册时间。这套系统用JWT做登录认证,后端登录接口校验完密码后签发token,前端把token存到localStorage里,后续所有需要登录的接口都在请求头里带上token字段。

商品表是商城系统里信息量最大的表。主图地址给列表页用,轮播图地址给详情页的图片轮播用,这两者一般是JSON字符串格式存在一个字段里,比如轮播图存成["url1","url2","url3"],前端拉下来之后parseJSON再渲染。库存字段在多线程并发下单时是锁竞争的焦点,所以库存相关的更新操作建议用带条件更新的SQL来做,比如update product set stock = stock - 1 where id = ? and stock > 0,这样能同时完成扣减库存和防止超卖,比先查再改安全得多。

购物车表里的字段有一个比较容易忽略的细节:商品加入购物车后,原始价格和商品信息可能发生变化,所以购物车表里需要冗余一份商品标题、商品主图、单价字段。但真正的金额计算仍然以下单时的实时数据库数据为准,购物车里的冗余数据只是为了展示方便。下单时用购物车id批量查询,再回源商品表取最新价格计算订单总金额,这一手是防止价格篡改的关键操作。

2.3 订单表与订单明细表的关联设计

订单表和订单明细表的关联,是所有电商系统里最重要的表关系。一张订单对应多件商品,所以订单表存的是订单级别的公共信息:订单号、用户id、总金额、状态、收货人信息,订单明细表存的是每件商品的独立信息:商品id、商品名称、商品图片、购买单价、购买数量。

这里必须注意一件事:订单明细表里的商品名称、商品图片、单价,都是从商品表复制过来的冗余数据,而不是通过商品id去关联查询。这样设计的核心原因在于,商品信息随时可能修改,甚至商品可能下架删除,但历史订单必须原样展示用户当时购买的快照信息。如果订单明细只存商品id,商品改价之后订单金额就对不上了。这套系统的订单列表和详情页能正常回溯历史订单,正是靠了这种快照设计。

订单状态这个字段也值得说道说道。常见做法是存int值,0待付款、1待发货、2待收货、3已完成、4取消(退款处理),前端用switch表达式或映射表把状态值渲染成对应的标签文案和样式。后端处理状态流转的逻辑集中在订单模块的service里,所有状态变更入口统一管理,不会出现一个接口改状态、另一个接口也改状态导致逻辑混乱的问题。

3. 后端核心功能实现:从登录认证到订单流转全流程

3.1 JWT登录认证:一套完整的Token鉴权流程

登录认证这块,我需要展开讲一下。系统用的JWT是无状态认证的标准做法:用户提交用户名密码到登录接口,后端校验通过后,用secret密钥生成一个包含用户id和用户名的token返回给前端。前端把token存好,后续每次请求都在请求头里带上Authorization字段,后端通过拦截器解析token,解析成功就把用户信息放到当前请求上下文里,解析失败直接返回401。

这套流程看似简单,但有几个点新手很容易踩坑。第一个是拦截器的白名单配置,登录接口、注册接口、商品列表接口、商品详情接口这些不需要登录就能访问的路径必须放行,只拦截需要身份认证的敏感接口,比如购物车操作、订单创建、个人中心。第二个是JWT的过期时间,不要太长。商城系统通常设置24小时左右比较合理,过期后前端统一跳回登录页,用户重新登录获取新token即可。第三个是统一返回结构,不管成功失败都给前端一套固定的JSON格式,前端就能用统一的拦截器处理错误提示,不用每个接口各自写try-catch。

3.2 商品查询与分页:MyBatis-Plus分页插件配置

前台商品列表最核心的接口就是分页查询。MyBatis-Plus用分页插件需要先注册一个MybatisPlusInterceptor的Bean,然后才能调用selectPage方法。前端传current当前页码、size每页条数、keyword搜索关键字、categoryId分类id,后端组装LambdaQueryWrapper实现动态条件查询,按创建时间倒序排序,返回记录列表和总条数。

这里有个细节要说明:分类筛选。商品分类表设计了父级分类和子级分类,首页导航展示一级分类,点击某个一级分类时,应该把该分类下所有子分类的商品都查出来,而不是只查直接挂在父分类下的商品。所以查询商品时如果传入的categoryId是一级分类,要在SQL里加上条件:当前分类id等于一级分类id或商品分类的父id等于一级分类id。这个逻辑处理不好,分类菜单点进去可能什么都查不到。

搜索功能也别搞太复杂。前台搜索框传入keyword,只要对商品标题做模糊查询,或者对商品标题、品牌、描述做多字段模糊查询,就足够支撑展示需求了。整套系统是单体商城,没必要上Elasticsearch这类重型搜索组件。

3.3 购物车实现与价格计算细节

购物车是用户端操作最频繁的模块。加入购物车,往cart表插入一条记录,用户id、商品id、数量、商品冗余信息。前端点击加入购物车时,如果购物车已经有同样商品,应该做数量累加而不是再插一条重复数据,避免购物车列表出现两行相同商品。这个判断可以通过查询cart表那该用户和商品id的记录是否为空来实现。

购物车列表接口相对简单:根据userid查所有购物车记录,关联查询商品最新信息返回给前端。因为购物车页有勾选商品并计算总价的需求,所以前端通常会在本地维护一个勾选状态集合,每次勾选变化就重新计算总价,后端只提供数据不做计算。这样实现压力都分布在前端,后端接口保持简单,够用就好。

但到了下单这一步,后端必须重新计算金额。这是电商系统铁律:前端传过来的总金额永远不可信,必须后端根据购物车里的商品id回到商品表重新取价格计算总金额。不然用户抓包改一下金额参数,少付钱买东西就真出了事故。

3.4 下单流程:库存扣减、订单生成与事务控制

下单接口是整套系统业务逻辑最集中的地方,也是新手最容易写崩的地方。完整流程是这样:前端把勾选的购物车id列表发给后端,后端查询这些购物车记录关联的商品,检查商品是否在售、库存是否充足,有一项不满足就返回失败并提示具体原因。校验通过后生成订单号、计算总金额、插入订单记录和订单明细记录,批量扣减商品库存,最后批量删除对应购物车记录,整个流程必须包在同一个事务里。

为什么必须用事务?想象一下:订单插入成功、明细插入成功,但扣库存失败,没回滚的话就会出现一个无法发货的空订单。或者库存扣了、订单没建成功,用户的付款就打了水漂。SpringBoot下只要在service方法上标注@Transactional注解,方法内任意一步抛异常,整个数据库操作都会回滚。这个注解是钱货两清业务逻辑的保障,绝对不能省。

并发扣库存这个点也顺带说一下。商城上线初期并发量不会太高,用乐观锁就能解决。商品表加一个version字段,扣库存时执行update product set stock = stock - #num, version = version + 1 where id = ? and version = #oldVersion,如果影响行数为0说明期间有人改过库存,重新读数据再来一次。这套机制实现成本低,对单体应用够用,高并发大流量场景再考虑Redis缓存库存和异步消息队列也不迟。

3.5 模拟支付接口与订单状态流转

支付功能在这类系统里通常都做模拟实现,不需要也不可能真的对接第三方支付平台。核心逻辑是前端点击支付按钮,调用后端支付接口,后端判断订单状态必须是待付款,把订单状态改为待发货,返回成功结果。前端拿到结果后跳转到支付成功页,刷新订单列表就看到第一笔订单已经变成待发货状态。

订单状态流转就是一个状态机,每个状态能到达什么状态是固定的:待付款能到待发货(支付)或已取消(超时/用户取消),待发货能到待收货(发货)、已取消(退款),待收货能到已完成(确认收货)、已取消(申请退款)。实现上不用搞复杂的设计模式,直接在订单service里做状态判断和变更即可,保持代码直观可读,后续需要理清状态流时一眼就能看懂。

3.6 后台管理的CRUD与统计报表

后台管理模块相对直白,本质就是对几张表的增删改查加一个数据可视化页面。商品管理是管理端最核心的:商品列表分页查询、新增商品、编辑商品、上下架切换、删除商品。新增和编辑表单都要支持上传商品主图和轮播图,这套系统用本地上传方案,图片存在项目的upload目录下,数据库存相对路径,前端通过静态资源映射拼接完整访问地址。实际生产会用对象存储,但本地部署演示阶段够用了。

数据统计模块是体现系统完整性的亮点。后台首页通常展示几个核心指标:今日订单数、今日销售额、商品总数、用户总数。折线图统计近7天或近30天的订单趋势,柱状图展示各分类的商品数量分布。后端提供一个查询接口返回统计数据列表,前端用ECharts渲染图表。ECharts是Vue项目最常用的图表库,封装好数据格式,页面效果出来之后整套系统的完成度立刻上一个档次。

4. 前端核心页面实现:用户端购物链路与管理端CRUD

4.1 前端工程结构和axios封装

前端项目的目录结构是Vue3 + Vite的标准布局。这里重点讲axios封装,因为它是前后端联调是否顺畅的关键。工具文件里创建一个axios实例,设置baseURL统一指向后端地址,请求拦截器里从localStorage取token然后加到请求头,响应拦截器里统一处理业务状态码:code为200就返回data数据,code为401就跳转登录页,其他错误码用Element Plus的ElMessage弹出错误提示。

这套封装完成之后,每个页面组件里写接口调用就很简洁了,只关心业务数据,不关心token、错误处理这些琐碎的细节。整个商城的代码量控制得很好,正文里大量页面复用了这个封装,没有重复代码。

4.2 首页和商品列表页的渲染逻辑

首页结构是轮播图加分类导航加推荐商品。轮播图的实现是调后端轮播图查询接口返回图片url列表,用Element Plus的ElCarousel组件循环渲染。推荐商品则是调商品分页接口,传入推荐状态和分页参数,取第一页几条数据用卡片网格布局展示。整个过程数据流清晰:页面初始化时在onMounted钩子里同时触发两个数据请求,分别赋值给轮播图数组和商品数组。

商品列表页相比首页要复杂一些,需要处理分类筛选、关键字搜索、排序和分页。顶部搜索框输入关键字回车后,把搜索的参数拼进查询条件,重新拉取第一页数据。分页组件用ElPagination,点击页码时更新路由参数并重新请求接口。为了让搜索结果刷新后还能保持,可以把页码和关键字同步到URL的query参数上,刷新页面后还能回到相同的列表状态。

商品详情页需要展示标题、主图、价格、库存、销量、详情描述和商品轮播图,还要提供数量选择和加入购物车按钮。加购之后右上角购物车图标显示的数字就要增加,这类跨页面状态共享就是Pinia的用武之地。Store里维护购物车总数量,后端返回加入成功后更新Store的值,所有页面读取的购物车角标就同时更新了。

4.3 购物车页面与结算下单页

购物车页面的核心是勾选商品后计算总价。表格的每一行有复选框,表格上方有全选复选框,页面底部固定展示当前勾选商品的总数量、总金额和去结算按钮。勾选状态变化时用computed计算属性实时汇总,这个功能是Vue响应式数据的典型案例:数据结构没有复杂到需要绕弯,所有价格汇总都是基于勾选集合的派生数据。

点击去结算跳转到确认订单页,这页需要从购物车勾选列表、选择或新增收货地址、选择订单备注,确认无误后点击提交订单。这个页面拿到购物车id列表和地址id,下单成功返回的订单号用于跳转到支付页。实现上需要注意的是,从购物车页跳过来要带上勾选的购物车id列表,如果直接传数组对象会很长且容易丢失,可以只在本地暂存var列表到SessionStorage,跳转过去读取即可。

4.4 支付页与订单列表

支付页最简单但也直观,展示订单信息(订单号、商品图片、商品标题、订单总金额),中间放一个二维码图片提升演示效果,二维码可以是任意静态占位,下方一个大按钮立即支付。点击后调用支付接口,等待后端返回成功,跳转到支付成功页,同时更新当前订单状态。

订单列表页是所有订单的汇总展示区,按状态Tab分批筛选:全部、待付款、待发货、待收货、已完成/已取消。每张订单卡片显示主图、标题、单价、数量、总金额、订单状态和时间,底部根据状态显示不同的操作按钮:待付款显示去支付和取消订单,待发货显示提醒发货(演示用),待收货显示确认收货。按钮事件根据订单状态调用对应接口,然后刷新列表数据,整个流程和状态机设计完全对上。

4.5 后台管理页面的通用CRUD模式

后台管理页面的模式极其统一,掌握一个页面就等于掌握了全部。以商品管理为例:页面顶层是搜索栏和新增按钮,中间是ElTable渲染列表,表格操作列是编辑和删除,底部是分页。新增和编辑共用一个ElDialog弹窗表单,弹窗打开时根据是否有当前编辑行决定回填数据还是清空表单,点击确定后调用新增或更新接口,接口成功就关弹窗刷新表格。

其他管理页面只是换字段而已,模式完全一致。这个通用CRUD套路在生产里高频出现,用熟了工作效率能提升一大截。用户管理、分类管理、订单管理几乎都复刻这套框架,比每个页面从零实现表单和弹窗要省太多事。

5. 本地运行部署实操:从零跑通这套手机商城

5.1 环境准备

在跑通项目之前,先确认本机环境是否齐备。JDK要求8或11版本,太新的JDK版本对SpringBoot2的兼容性可能有小问题,建议直接装JDK11最稳妥。Node.js建议14以上版本,Vite对Node版本有一定要求,太老的可能启动失败。MySQL必须8.0及以上,因为项目用了MySQL8的驱动和语法特性,5.7会有兼容问题。数据库管理工具我用Navicat,个人用也行,命令行也可,没有限制。

这三个环境装好后,可以用命令验证:java -version、node -v、mysql --version,都能正常打印版本号就说明环境没问题。

5.2 数据库初始化

这一步最流程化。在MySQL中新建一个数据库,编码utf8mb4,字符集排序规则用utf8mb4_general_ci。然后在Navicat中右键运行SQL文件,把项目自带的sql脚本导入完成建表和数据初始化。数据初始化这步很贴心,没让我从零造数据,系统将自动生成演示所需的分类、商品、用户和管理员账号,省了很多手工构造数据的时间。

导入后验证一下:打开用户表看是否有测试账号数据,打开商品表看是否有演示商品,这就说明数据落库成功了。需要注意的点是SQL脚本执行过程中如果报错,多半是数据库版本低或者执行方式不对,8.0环境换个执行工具重跑即可。

5.3 后端启动与配置修改

后端项目导入IDE之后,主要关心配置文件application.yml。关键配置项有:

  • 数据源配置:数据库地址、账号、密码必须改成自己本机的
  • MyBatis-Plus配置:日志开启、逻辑删除配置、mapper-locations
  • 文件上传路径:图片上传后保存的本地目录
  • JWT密钥:可以保持默认,生产环境必须修改

改完配置文件,启动SpringBoot主类。看到日志输出启动成功字样,控制台不报连接错误,就说明后端已启动完成。

新手最容易栽的跟头基本都在数据源配置:密码写错、数据库名字写错、端口写错,启动就报连接失败。遇到这类问题不要慌,先把配置里的连接串放进Navicat里试连,Navicat能连上再回过来检查代码,一定能解决。

5.4 前端启动与代理配置

前端项目导入IDE后,在项目根目录打开终端执行npm install,等待依赖安装完成。这一步因为要拉取大量npm包,网络不好时容易卡住或报错,可以换成国内npm镜像再执行,速度会快很多。安装完成后执行npm run dev,Vite启动开发服务器并输出本地访问地址,浏览器打开就能看到商城首页。

前端联调的关键是代理配置。前端开发服务器默认在5173端口,后端接口在8080端口,直接跨域请求会被拦截。项目里通过Vite配置了代理dev server把/api前缀的请求转发到localhost:8080,这样浏览器里所有请求都是同源的前端请求,由开发服务器转发到后端,完美规避跨域问题。如果你把代理配错了,前端页面能打开但所有接口请求都404或跨域报错,一定要先检查prod配置。

5.5 演示账号与访问入口

全部启动成功后,系统有两条访问链路。用户端是前端项目的默认地址,直接打开就是商城首页,可用数据库预置的普通用户账号登录。管理端地址是在前端路由里配的/admin路径,如http://localhost:5173/#/admin或6153端口带管理路由的入口,用管理员账号登录就能进入后台。具体账号密码在项目文档里写得很清楚,没有就自己在数据库用户表里查一条role为管理员的记录改密码用。

这里分享一个小经验:跑通系统之后,第一时间把数据库里的演示商品价格和名称改成自己想要的商品数据,后台管理页上传自己的商品图,整套演示效果马上就有个人项目的感觉了,面试演示或答辩时也不会显得千篇一律。

6. 常见问题与避坑实录:我实测踩过的那些坑

6.1 数据库相关的坑

MySQL8.0默认认证插件是caching_sha2_password,如果本机装了旧版本管理工具或者旧驱动,连接时可能会报Public Key Retrieval is not allowed。解决方案有两个,一个是连接串加参数allowPublicKeyRetrieval=true,另一个是把MySQL用户插件改为mysql_native_password。我自己直接按SQL脚本建新用户并授权,能顺利避免这个问题。

另一个高频问题是SQL脚本导入报错sql_mode=only_full_group_by。MySQL5.7之后默认开启严格模式,如果SQL脚本里有非严格模式的聚合查询就会报错。要么修改数据库的sql_mode配置去除only_full_group_by,要么检查相关查询是否每个非聚合字段都写了group by,我改配置一劳永逸,因为商城系统的统计报表涉及分组查询,改动最方便。

6.2 后端启动失败的排查思路

后端启动失败导致一时间摸不着头脑,有套快速的排查顺序:第一步看数据库连接是否能连上,用Navicat测试一下配置里的账号密码,确认没问题再继续。第二步看端口是否被占用,8080如果被其他程序占用,启动必然失败,换一个空闲端口即可。第三步看控制台日志的具体异常信息,如果是mapper找不到XML文件,大概率是配置里的mapper-locations路径写错了;如果是JWT相关类初始化报错,检查依赖是否完整,刷新一下Maven重新导入即可。

一个特别隐蔽的坑是application.yml配置文件被IDE识别成普通文件而不是配置文件,导致配置没有加载生效,启动后数据库地址是默认的localhost且账号密码不对。用IDE打开文件看有没有Spring的绿叶标志,没有就右键标记为配置文件,这才生效。

6.3 前端构建与联调的坑

npm install报错是最常见的,绝大多数是网络问题或node版本问题。切换npm镜像源之后,大概率都能解决。如果还报某个依赖版本不支持当前Node版本,建议直接用Node官方LTS版本(比如16或18),不要用太新的奇数版本。

前端页面能打开但接口全挂,基本是代理配置或后端没起。先在后端console里看有没有收到请求,收到的说明后端没问题就是代理问题;没收到就是代理配置没生效或后端没起。前端请求报401,说明token没传或过期,重新登录就能解决。请求报403跨域,就要检查CorsConfig的跨域配置,后端实现里CorsFilter配好就能互通。

6.4 图片上传与显示问题的处理方式

本地上传的图片有个常见套路:后端把图片存到项目的upload目录,同时把访问路径映射成http://localhost:8080/upload/**。如果是单文件上传,直接在controller里用MultipartFile接收,转存到目标目录并在数据库存相对路径。如果是多图上传,前端用一个图片列表组件循环调用单文件上传接口,返回的url数组存到商品表轮播图字段里。

图片上传后前端加载不出,90%的原因是静态资源映射没有生效或路径拼接错误。看后端日志确认上传文件保存位置,再直接浏览器访问拼接地址测试。如果404,检查是否有WebMvcConfigurer配置addResourceHandlers映射upload目录。如果403,检查目录权限和路径大小写。

6.5 二次开发时的扩展方向建议

跑通整套系统后,如果不想止步于运行Demo,可以试着从以下几个方向做二次开发,每个方向都有实际场景支撑,改起来也不会伤筋动骨。第一个是接入第三方支付接口,把模拟支付替换为微信或支付宝沙箱支付,这一步对理解真实支付流程帮助很大。第二个是把首页推荐改成按销量和创建时间的加权算法排序,替换现在的简单推荐逻辑。第三个是给商品增加规格属性(型号、内存、颜色),购物车和订单都要相应支持,这是商城系统从玩具级到实用级的跨越。

另外一个很值得花时间的方向是代码优化:把购物车、订单这类涉及多表操作的业务逻辑梳理清楚,把重复的CRUD封出通用接口,对代码能力锻炼比任何练习题都有效。这套源码本身结构不复杂,正是做重构练习的好素材。

7. 关于这套系统,我最后想说的几句话

说实话,像欢迪迈手机商城这种SpringBoot2 + Vue3 + MyBatis-Plus + MySQL8.0的组合,就是当前Java全栈学习的主流路线。它的价值不在于技术多前沿,而在于把电商系统最核心的业务闭环完整呈现了一遍:商品展示、购物车、下单、支付、后台管理、统计报表,该有的模块都齐了,数据表设计规范,接口和前端页面之间的交互逻辑清晰,非常适合作为学习范本和二次开发底座。

我在实际跑这个项目过程中,最大的体会是:项目能不能跑通是第一步,弄明白每行代码为什么这么写才是真正有收获的地方。建议拿到源码后,先用我上面说的方法把环境跑通,然后沿着订单流程从商品、购物车、下单、支付、发货、收货把接口和前端代码对应着读一遍。这个过程走完之后,再回头去看任何一套电商项目,心里都会有底。

如果后面你在这个项目基础上继续扩展,还有一个非常建议优先做的事情:把日志体系完善起来。这套系统虽然功能完整,但对日志记录不太在意,自己线上维护时如果没有日志,排查线上问题会非常痛苦。给service层关键方法加上日志打卡,给全局异常处理里记录异常堆栈,这种基础能力的积累,比任何炫技功能都值钱。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询