电商练习Demo从零搭建:核心链路、库存扣减与踩坑实战
2026/9/8 7:14:07 网站建设 项目流程

简介:电商项目练习demo是一份面向电商开发学习者的完整示例项目,覆盖从用户、商品、订单、支付到物流、推荐等核心业务链路,既能帮助新手建立电商系统整体认知,也可供有经验的开发者对照复盘架构设计与技术选型。压缩包共1024个文件,以949张PNG界面截图与流程图为主,另有53张JPG素材、16个Markdown说明文档、5个GIF动态效果及1个HTML页面,整体仅55.21MB,便于下载后按目录翻阅。包内对前端React/Vue、后端Spring Boot/Django、数据库设计、JWT身份验证、Redis缓存、支付与物流API集成、安全防护、性能优化及自动化部署等十大要点均有涉及,并配有大量截图与动图演示实际页面和交互流程。已有723人学习,适合在课余或实训中作为电商项目练手素材,快速理解模块划分,并延伸出自己的毕业设计或业务原型。 电商项目练习demo这种工程,听起来不像大系统那么唬人,但的的确确是检验后端功底和工程习惯的好地方。我前前后后写过好几个类似的项目,从最开始的纯Servlet版,到Spring Boot + Vue,再到后面加了Docker编排,每个阶段都能从这套demo里学到新东西。有些人觉得练习项目就是“能跑就行”,但我更愿意把它当成一个沙盒:在这里试错成本低,可以把商品的增删改查、购物车、订单流转、库存扣减这些电商核心链路完整走一遍。这篇笔记我就用自己踩过的坑,聊聊怎么把一个电商练习demo做得既完整、又能真正成为面试谈资。

1. 先想清楚:这个电商demo到底要练什么

1.1 功能边界比功能数量更重要

很多初学者做练习项目,容易陷入“功能越多越好”的误区。我见过有人给demo硬塞秒杀、优惠券、直播带货、分销裂变,结果做了一半就烂尾。其实一个合格的电商练习demo,应该先把最经典的闭环做完整:用户登录、商品列表、商品详情、购物车、创建订单、库存扣减、模拟支付、订单状态流转。这几件事跑通了,你对电商系统核心数据流的理解,已经能覆盖大多数初级岗位的面试问题。

那后台管理要加吗?我的建议是“可以做,但不是第一优先级”。练习demo的核心价值在于让你把一条核心链路吃透,而不是把整个电商平台复刻一遍。你可以在纸上先画出用例图:普通用户能做什么、可选的管理员能做什么,再根据用例去定义接口。这一步看似很简单,但真的能帮你避免“首页还没做好就跑去改数据库表结构”这种情况。我个人的经验是,先把用户端走通,再往后端补一个简单的商品管理接口,用于验证“一个商品如何从入库到被下单”,这个顺序最顺。

1.2 技术栈选择的真实理由

技术栈怎么选,完全取决于你的练习目标,没有标准答案。

如果目标是快速验证前后端协作、把简历里的“全栈项目”坐实,Spring Boot + Vue(或React)是最省事的组合,生态成熟、网上资料多,遇到问题基本都能搜到答案。如果目标是学习移动端,Android Kotlin Compose + 本地Mock数据也可以做成一个demo,但你要清楚它和后端联调的成本。如果目标是App加服务端完整跑通,那后端接口一定要先定义好,移动端再用Retrofit或Ktor去调用。

我自己比较推荐“主语言 + 最简数据库 + 一个缓存/队列”的起步组合。什么意思?主语言选你找工作最想用的,数据库用MySQL,缓存可以后加,消息队列可以只在本机用Docker跑一个简单的,别一上来就上微服务、上K8s。把链路跑通,再逐步加复杂度,这样每一步你都清楚它解决了什么问题,而不是为了技术而技术。

2. 从零搭起一套可运行的电商demo

2.1 目录结构与工程初始化

工程初始化这一步看似简单,但目录结构是否清晰,直接决定你后续几天写代码的心情。我建议采用前后端分离,整个仓库目录大致可以这样划分:

shop-demo/ ├── backend/ // Spring Boot服务 ├── web/ // Vue/React前端 ├── app/ // 可选:移动端或桌面端 ├── doc/ // SQL脚本、接口文档、演示截图 └── README.md

后端工程建议从官方初始化器或Maven骨架创建,groupId用com.example就行,artifact命名成shop-demo-backend。前端如果选Vite,直接运行创建命令就能拿到一个干净的基础工程。这里有一个我反复踩过的坑:前后端不要放在同一个Spring Boot静态资源目录下硬揉,会让部署和排查都很难受。前后端独立目录,各跑各的端口,联调的时候通过CORS或代理解决跨域,思路会清晰很多。

初始化的第一件事不是写代码,而是确认前后端基础工程都能“空跑”起来。前端启动后能看到Vite欢迎页,后端启动后/actuator/health能返回UP,这一步做好了,后面所有联调问题都更容易定位。

2.2 数据模型设计:电商的核心是“关系”

电商业务的数据模型非常典型,练习项目不需要设计几十张表,但核心的表结构必须符合业务直觉。我推荐一份最小可用的表设计:

表名核心字段作用
userid、username、password、nickname用户认证信息
productid、title、cover_url、price、stock、status商品主数据
cart_itemid、user_id、product_id、quantity购物车明细
ordersid、order_no、user_id、total_amount、status、created_at订单主表
order_itemid、order_id、product_id、product_title、product_price、quantity订单快照明细

注意order_item里要把商品标题和价格冗余进去,因为商品信息可能随时被改动,但订单一旦生成,这笔交易的商品名称和成交价就应该固定下来。这是电商设计里一个很容易被忽略的点,也是面试经常喜欢问的“为什么订单明细要存快照”的原因。

数据库初始化我建议准备两份SQL:schema.sql负责建表,data.sql负责插入一些测试商品。Spring Boot整合MySQL时,记得配置spring.sql.init.mode=always,这样每次启动都会执行初始化脚本,省去手动导入的麻烦。当然生产环境不能这么干,但练习阶段简直是提效利器。

2.3 后端接口设计思路

接口设计不要照搬大公司的文档风格,练习项目最重要的是“面向使用场景”。前端页面需要什么数据,后端就提供什么接口,先让闭环能跑,再考虑RESTful标准。

我常用的接口清单:

  • POST /api/user/login:登录,返回用户信息基础数据
  • GET /api/product/list?page=1&size=10:分页获取商品列表
  • GET /api/product/{id}:商品详情
  • POST /api/cart/add:加入购物车
  • GET /api/cart:查看购物车
  • POST /api/cart/clear:清空购物车
  • POST /api/order/create:创建订单
  • POST /api/order/pay/{orderNo}:模拟支付
  • GET /api/order/{orderNo}:查询订单状态

这里有一个细节:接口路径里的动词用loginpay这类业务动作是可接受的,因为它们是业务语义;但增删改查尽量用HTTP方法表达,比如POST /api/cart/addPOST /api/order/create,很多规范党会觉得冗余,但练习阶段这样写直白、不容易搞混,后续再慢慢做REST化也不迟。

2.4 前端页面与交互闭环

Web端页面控制在5个以内:商品列表页、商品详情页、购物车页、结算页、订单结果页。过多的花哨页面会消耗你的精力,却对核心链路没帮助。

前端技术细节上,如果用了Vue,推荐用Pinia管理购物车状态;如果用了React,就用Redux Toolkit或Zustand。购物车交互要做到“本地状态即时更新、后端持久化兜底”:加购时先更新前端store,同时调后端接口,接口成功则返回最新购物车列表并整体替换,失败则回滚本地状态并且弹出提示。这样能避免用户在多个浏览器标签页操作时出现数据不一致。

还有一个前后端联调的小心得:字段命名两端一定要统一。前端用cartNum,后端用count,这种看着不起眼的问题,调试起来会比业务逻辑bug更浪费时间。我第一次做demo时就在这上面卡了两个小时。

3. 核心链路实操:从商品列表到订单支付

3.1 商品列表与详情

商品列表接口不要上来就select *,至少要有分页参数,并且支持按关键词模糊搜索和按上下架状态过滤。对应的SQL大致是:

SELECT * FROM product WHERE status = 1 AND title LIKE CONCAT('%', #{keyword}, '%') ORDER BY created_at DESC LIMIT #{offset}, #{size}

前端拿到列表后,点击某个商品进入详情页,详情页再调/api/product/{id}获取完整信息。图片字段建议存URL字符串,不要存base64,否则数据库会脏、接口也会变得很慢。这个细节对练习demo而言更重要:它能帮助你理解“文件服务”和“业务服务”为什么要分开,至于实际部署时用OSS还是本地静态目录,都是后续扩展的事。

3.2 购物车状态管理

购物车是前端状态交互的重头戏。一个商品可能已经被加入购物车,此时加购按钮应该显示“去结算”而不是“加入购物车”。这个状态需要由前端根据购物车数据自行判断,后端不需要额外提供“是否已加购”的接口。

如果做跨端复用,购物车接口一定要设计成“按用户维度存取”,而不是把购物车数据只存在前端localStorage里。否则你在手机端加购的东西,网页端根本看不到,就失去了电商的核心体验。练习项目可以前后端都做:本地store覆盖即时交互,后端接口覆盖数据持久化,刷新页面后从后端拉取恢复。

3.3 下单与库存扣减

创建订单是整个demo里技术含量最高的地方,也是面试最容易追着问的点。核心逻辑是:在同一个事务里完成“检查库存、扣减库存、创建订单、创建订单明细”。

最稳妥的做法是用数据库行锁或乐观锁。我先说推荐写法,一句带条件的update语句完成原子扣减:

UPDATE product SET stock = stock - #{quantity} WHERE id = #{id} AND stock >= #{quantity}

如果这条语句返回的影响行数为1,说明库存扣减成功;返回0,说明库存不足或商品已下架,需要抛出异常并回滚整个事务。为什么推荐这个写法?因为它把“判断库存是否充足”和“扣减库存”合并成了一步,避免了“先查再用”导致的并发超卖问题。练习阶段用这个方案完全够用,也足够解释清楚原理。

如果要更进一步,可以在product表增加一个version字段,用乐观锁控制并发,但逻辑会稍微复杂。我第一次跑并发测试时,用JMeter模拟100个并发请求下单同一件库存为20的商品,使用上面的update方案后,最终只成功了20单,库存正好归零,这个结果让我对“原子操作”有了非常直观的理解。

3.4 模拟支付与订单状态机

真实项目对接支付网关很复杂,但练习demo只需要一个“模拟支付成功”的接口就能闭环。我的做法是在订单详情页放一个“确认支付”按钮,点击后后端直接更新订单状态,并在pay_log表里插入一条支付流水。

订单状态可以用一个int字段表示,也可以用字符串枚举,我推荐用字符串,因为阅读起来更友好,比如INITPAIDCANCELLEDSHIPPED。状态流转逻辑一定要清晰:

  • 用户创建订单后,状态为INIT,也就是待支付
  • 用户模拟支付成功,状态变为PAID
  • 如果超过一段时间未支付,状态可以由一个定时任务改为CANCELLED
  • 发货后状态变为SHIPPED

练习项目里至少要把前两个状态流转做扎实,后面两个可以留作扩展。状态机这个概念听起来很高深,但落到电商订单上就是“不同状态下允许执行哪些操作”,把规则定义清楚,后面加购物优惠、退款流程都会轻松很多。

4. 常见问题与排查技巧实录

4.1 跨域、端口占用、接口404

电商demo前后端分离后,每天都要面对这几个问题。

跨域是最常见的:前端跑在5173,后端跑在8080,不配置CORS的话浏览器会直接拦截。解决办法很简单,后端的配置类里加一个全局CORS配置,允许所有来源、所有方法;或者在前端开发服务器里配置proxy,把/api代理到http://localhost:8080。我推荐用后者,因为生产环境部署时通常也会有类似的网关转发逻辑。

端口占用也很好排查:启动后端显示Port 8080 was already in use,多半是之前启动的进程没杀干净。在Linux/Mac上用lsof -i :8080,Windows上用netstat -ano | findstr 8080,把对应进程关掉就好。

接口404基本都是路径写错了,特别是@RequestMapping("/api")这种类级别的注解配合@GetMapping("/product/list"),双重路径很容易拼错。遇到404别急着改代码,先开浏览器的Network面板,看实际请求的URL和后端Controller路径是否完全一致。

4.2 数据库连接与初始化数据加载失败

“数据库连不上”是新手遇到最多的拦路虎。现象通常是应用启动时报Access denied for user 'root'@'localhost'。排查时先确认MySQL服务启动了没,再确认配置文件里的用户名密码对不对,最后检查时区配置,建议在JDBC URL里加上serverTimezone=Asia/Shanghai

还有一次我在练习项目的fetch步骤遇到了无法下载依赖的问题,报错信息各种各样,后来发现是Maven本地仓库缓存坏了。先删掉本地仓库中对应组件目录,重新构建一般都能解决。另外数据导入失败通常是因为SQL脚本里混了MySQL 8新增语法,而本地却是5.7,务必保证数据库版本和依赖版本对应得上。

4.3 并发下单导致的库存超卖“假象”

如果你用JMeter压测时发现库存变成了负数,先不要觉得是数据库不够强,多半是代码逻辑问题。典型错误是先查询库存,判断大于0,再执行更新:

SELECT stock FROM product WHERE id = #{id}; -- 在代码里判断 stock > 0 UPDATE product SET stock = stock - 1 WHERE id = #{id};

这两条SQL一旦被并发执行,查询时都看到还有库存,更新时也都会成功,超卖就发生了。上一节我写的UPDATE ... WHERE stock >= #{quantity}就能解决这个问题。还有一个小技巧:压测时如果MySQL事务隔离级别比较高,可能会遇到锁等待超时,不用太紧张,降低一下并发线程数,先把业务跑通。

4.4 专项踩坑:构建打包时遇到的“non-resolvable parent pom”问题

热词里有一条project build error: non-resolvable parent pom for com.example:demo:0.0.1-sn,我看到这个描述特别有共鸣,因为我在练习demo时就踩过一次。这个报错的意思是:当前模块声明的父POM,在Maven仓库里找不到。

排查主要看三个地方:

  1. 父工程的groupIdartifactIdversion是否和实际一致,尤其在多模块工程里,子模块的<parent>坐标写错一个字母都找不到。
  2. 本地仓库中是否真的缓存了对应版本,可以在~/.m2/repository/com/example/...目录下看有没有对应的.pom文件。
  3. 如果父POM也是自己写的,子模块需要能通过relativePath找到父模块目录,默认是../pom.xml,目录结构变了就会出问题。

我当时的解决方案是删掉本地仓库里那一整个com/example目录,然后重新执行Maven构建,让它重新拉取。经验教训是:练习项目尽可能不要自己手写复杂多模块POM,直接用Spring Boot官方父依赖就能覆盖大部分需求,少折腾、少踩坑。

5. 扩展方向:让练习demo变成面试谈资

5.1 微服务拆分与容器化

单体demo跑通后,可以尝试把用户、商品、订单三个模块拆成独立服务。拆分前先想清楚一个关键问题:购物车和商品详情的联调怎么办?我是用最简单的Spring Cloud OpenFeign做服务间调用,不用太复杂,只要让order-service能调用product-service的接口完成库存扣减即可。

容器化是另一个高性价比扩展方向。写一个Dockerfile把后端打成镜像,再用docker-compose.yml把MySQL和Redis一起编排起来。这一套做完,你对“环境一致”“一键部署”的理解会非常深刻。值得注意的是,不要在练习阶段就上K8s,成本高、排错难,很容易打击信心。

5.2 从Web端到鸿蒙端/安卓端的demo迁移

同一个后端API,其实可以很轻松复用到多个端。我后来就把这套电商demo的后端接口,在一款Android Kotlin Compose的练习工程里调用了一遍,发现只要后端接口参数稳定,移动端代码写起来比想象中顺手。

如果要做鸿蒙的练习demo,要注意它的工程产物可以打包成HAP、HSP、HAR三种格式,分别对应应用包、共享包和静态共享包。你在练习阶段不用太纠结这些产物格式的具体差异,只需要理解“后端接口是数据来源,不同端负责不同展示和交互”即可。多端复用的价值在于:它让你明白分层设计为什么重要,数据层、业务层、展示层的边界一旦清晰,换端损耗就会很低。

5.3 从电商demo到MCP服务demo的延展

最近很多人在聊MCP,也就是Model Context Protocol,简单地把它理解为“让外部工具能力标准化地接入到AI应用”的一种协议。如果你已经有一个电商demo的商品接口,完全可以照着MCP的规范把它封装成一个服务demo,让AI助手可以直接调用你的商品查询、订单创建等能力。这是一个很有意思的延伸玩法,能让你同时拥有传统Web开发和AI应用开发的交叉视角。

但我的建议是:这个扩展适合在主流程已经很熟练之后再加。先学会走,再去跑。把电商核心闭环做扎实,后面的扩展都是锦上添花。

我做了很多次demo之后最大的体会是,练习项目的价值不在于页面有多漂亮、接口数量有多惊人,而在于你有没有把一个闭环跑通,并且知道每个环节为什么这么做。如果你现在正准备做电商练习demo,不用贪多,把商品、购物车、订单和支付这四个模块做扎实,然后把打包、部署、写接口文档这些事也顺手做一遍,收获会比想象中大得多。最后一个小建议:demo一定要提交到Git仓库,每次扩展功能前都留一个可运行的tag,这样你改坏了也不怕回不去。

本文还有配套的精品资源,点击获取

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

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

立即咨询