ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于SpringBoot+Vue的明星周边商品管理系统全栈实战解析

基于SpringBoot+Vue的明星周边商品管理系统全栈实战解析 1. 明星周边商品的信息管理难点以及这套系统的破局思路1.1 周边品类的特殊性决定了它不能照搬普通商城模板我最早接触明星周边销售管理是帮一个做偶像团体应援物的小团队搭后台。当时他们用的是共享表格加微信群接龙库存对不上是常态预售订单和现货订单混在一起到了发货日根本分不清谁付了定金谁补了尾款。后来我换过市面上现成的商城系统问题更多通用商城模板里根本没有场次、版本、限量编号这些字段明星周边这种属性极度分化的商品线硬塞进通用 SPU/SKU 模型会非常别扭。这个星之语项目之所以值得拆解就是因为它从一开始就按周边商品的实际销售场景来建模。周边产品不只是 T 恤、手环、海报、小卡这些品类它还有非常特殊的销售规则同一个明星的多场演唱会周边会分场次同一张专辑会有普通版、签售版、限定版热门单品要限购、要登记身份信息防止倒卖。这些业务规则如果靠运营在后台手工备注迟早会出乱子。系统要解决的核心问题有三个商品上架必须灵活到能描述任何周边属性订单必须能完整记录成交时用户看到的商品信息后台必须能区分普通用户和管理员的权限边界。这个项目把这三个问题都落到了代码里。商品模块支持自定义规格和图文详情订单模块做了快照和状态流转权限模块用 JWT 区分角色。也就是说它不是一个只有增删改查的玩具项目而是一个能真正支撑起一家小型周边店从接单、管库存到发货全流程的管理系统。对想学习全栈开发的人来说这种业务闭环完整的项目比单纯的技术 Demo 有价值得多。1.2 SpringBoot Vue MySQL 这三个组件是什么定位很多人看到这个技术栈的第一反应是烂大街。确实SpringBoot 加 Vue 加 MySQL 是当前国内中小型管理系统最主流的搭配但主流恰恰意味着稳定。选这套组合关键在于它把难度分成了三层每一层都有非常成熟的解决方案SpringBoot 负责后端接口和业务逻辑。内置 Tomcat不用单独部署 Web 容器Starter 机制让整合 MyBatis、Redis、JWT 这类组件基本靠加依赖和写配置完成。Vue 负责前端页面。单页应用配合 Element UI 这类组件库后台管理界面的表格、弹窗、表单全部开箱即用C 端展示页用 Vue Router 做路由跳转做出来的页面交互流畅度和传统多页模板完全不是一个体验。MySQL 负责数据持久化。电商场景下的订单、库存、交易流水都需要事务保证MySQL 的 InnoDB 引擎在这一块非常成熟再加上它部署运维成本低个人开发者和小团队完全能驾驭。从学习角度看这套组合的生态资料最丰富。无论是博客、视频还是开源社区你能找到大量同类项目作为参照。遇到问题搜索SpringBoot 报错Vue 跨域这类关键词基本上都能找到现成解法。这也是为什么很多毕业设计、外包项目、企业内部管理系统都选这套方案。说实话我在完整跑通这个项目之前也担心过会不会太简单、没什么干货。但完整过了一遍代码后发现真正决定项目质量的不是技术有多新而是业务逻辑有没有闭环。星之语这种面向 C 端的交易系统业务链路长涉及用户、商品、购物车、订单、后台管理多个模块跑通一遍下来对前后端分离开发的理解会提升不少。2. SpringBoot 后端核心模块拆解从 JWT 鉴权到订单状态机2.1 工程分层结构这个项目的后端遵循标准的 Controller - Service - Mapper 三层结构。我在看代码时特别注意到它的包名设计得很清晰按功能模块划分而不是按技术类型划分controller 包下是 UserController、ProductController、CartController、OrderControllerservice 包下对应每个业务域mapper 层用 MyBatis 注解或 XML 写 SQL。这种按业务域切分的结构有一个直接好处新人接手项目看包名就能猜到某个功能入口在哪个类里完全不需要全局搜索。Controller 层的职责非常克制。以商品上架接口为例Controller 只负责接收 JSON 请求体、调用 Service、返回统一结果封装。所有非空判断、字段合法性校验都放在 Service 层或使用注解校验完成。这样做的目的是避免 Controller 膨胀保持接口层的干净。项目里用了一个 Result 类统一包裹返回值结构大概是 code、message、data 三段前端拿到结果后先判断 code 是否为 200再决定是否取 data。这种做法虽然简单但配合全局异常处理后非常实用前后端联调时能快速定位问题出在哪个环节。这个项目用 MyBatis-Plus 而不是原生 MyBatis这点值得展开说。MyBatis-Plus 最大的价值是内置了通用 CRUD 方法单表操作根本不用写 SQL直接调用 IService 接口的 save、remove、page 等方法就行。比如商品分类维护这种简单逻辑ServiceImpl 里几十行代码就写完了。只有当涉及多表关联查询比如订单列表要带出用户名和商品名才在 Mapper 里自定义 SQL。这是效率优先的正确取舍也符合实际项目里80% 简单 CRUD、20% 复杂查询的真实比例。2.2 用户与鉴权JWT 令牌的前后端分离落地前后端分离架构下最核心的问题之一是服务器怎么知道当前请求是谁。传统单体应用可以用 Session Cookie但前后端分离后前端可能部署在另一台服务器、甚至跨域名访问接口Cookie 的跨域限制和 Session 的共享问题都会冒出来。这套系统用的是 JWTJSON Web Token方案。JWT 的思路是用户登录成功后服务端生成一个包含用户 ID、角色、过期时间的加密 Token 返回给前端前端把它存在 localStorage 里之后每次请求在请求头里带上Authorization: Bearer token后端用一个拦截器拦截需要登录的接口从 Token 里解析出用户信息并放到当前线程上下文。代码实现上关键在三个地方。第一是生成 Token 的密钥和过期时间要写在配置文件里不要硬编码否则以后换密钥要改代码重新编译。第二是拦截器里必须区分哪些接口放行、哪些接口需要登录、哪些接口需要管理员权限这套系统用自定义注解加拦截器实现比在代码里逐个判断要优雅得多。第三是解析 Token 的异常要处理干净Token 过期、Token 伪造、未携带 Token 要返回不同的错误码这样前端才能做出对应的跳转或提示。// 登录成功后生成 Token 的核心逻辑 String token Jwts.builder() .setSubject(String.valueOf(user.getId())) .claim(role, user.getRole()) .setExpiration(new Date(System.currentTimeMillis() expireTime)) .signWith(SignatureAlgorithm.HS256, secretKey) .compact();提示生产环境下 JWT 密钥一定要放在环境变量或配置中心不要提交到 Git 仓库。另外Token 一旦签发在过期前是无法主动失效的如果遇到用户封禁场景需要结合 Redis 黑名单机制做二次校验。2.3 商品与 SKU周边商品多规格的实现方式明星周边的多规格问题很典型一件应援 T 恤有黑色白色、S 到 XXL 六个尺码每种组合的库存和价格可能都不一样。如果每个组合建一条商品记录后台维护会非常痛苦。这个项目采用经典的商品 SKU 两表设计。商品表存的是所有规格共有的信息标题、主图、详情图文、所属分类、上下架状态。SKU 表存的是每个具体规格的信息规格名比如白色-XL、价格、库存、限购数量、以及可选的限量编号。商品详情页选择规格时前端根据选中的规格组合去查对应的 SKU拿到价格和库存展示给用户。这个方案的扩展性很强以后如果想增加场次这个规格维度只需要在 SKU 表里加字段或者在规格名上拼上2024上海场即可不需要大改表结构。需要说明的是我在不少项目里看到过把规格做成 JSON 字符串塞进商品表一个字段里的做法这样做查询时非常痛苦想按照某个尺码有货来筛选商品基本不可能。星之语这套把规格拆成独立 SKU 表的方案虽然表和代码量都多一点但查询、库存管理、订单关联都非常清晰是更抗折腾的设计。2.4 订单状态机与库存扣减订单模块是整个系统的核心也是最容易出错的地方。这套系统的订单状态设计为待支付、已支付/待发货、已发货、已完成、已取消。每个状态允许的操作不一样例如待支付可以取消、已支付可以发货、已发货可以确认收货但不允许从待支付直接跳到已完成也不允许已取消的订单再支付。实现时代码里对状态流转做了明确的判断如果状态不对直接抛业务异常这样能从代码层面防止脏操作。库存扣减逻辑里有一个关键设计决策是在用户下单时扣库存还是支付成功后扣库存两种方案各有优劣。下单即扣库存可以防止热门商品被大量占单不付导致超卖但可能出现用户下单后不支付库存被白白占用的情况支付后扣库存则更贴合真实成交但并发高时库存校验和扣减之间容易出现超卖。这个项目采取了下单即扣库存、超时未支付自动释放的方式相当于引入了一个简单的占库存机制。为了降低不支付导致的库存浪费后台可以设置一个订单超时时间到点自动把状态改成已取消并回补库存。扣库存操作必须是原子性的SQL 里要用带条件更新的写法不能先查库存再更新后一种方式在高并发下会出问题UPDATE product_sku SET stock stock - 1 WHERE id #{skuId} AND stock 0这条 SQL 执行后受影响行数为 0 说明库存不足Service 层直接抛出库存不足异常即可。整个下单流程还要加上 Transactional 事务保证扣库存、创建订单、清购物车这些操作要么全部成功要么全部回滚。3. Vue 前端的页面骨架与接口联调实战3.1 路由与页面层级前端项目基于 Vue 配合 Vue Router 构建页面分为两大部分面向普通用户的商城端和面向管理员的运营后台。这种一个工程两套布局的做法在中小型系统里很常见好处是前后端只需维护一个项目坏处是路由和权限控制需要做得清晰。商城端页面包括首页、商品列表、商品详情、购物车、结算页、订单列表、登录注册。后台页面包括商品管理、分类管理、订单处理、用户管理、数据概览。路由配置上使用嵌套路由商城端在一个带有头部导航和底部栏的 Layout 组件内嵌套子路由后台端使用一个独立的后台 Layout左侧菜单、右侧内容区。这样公共组件只需要写一次不会出现每个页面都复制一遍导航栏的尴尬。一个值得注意的细节是路由守卫。未登录用户访问购物车、结算页、订单列表时需要跳转到登录页。这类逻辑在 Vue Router 的全局守卫里统一处理判断 localStorage 是否存有 token。但用户登录后要自动跳回原来的页面这需要把进入时的 from 路径存下来登录成功后再跳转回去这个细节很容易被忽略。很多新手只做了未登录跳登录页却没做登录后回跳导致用户体验断裂。3.2 Axios 封装与鉴权拦截前端所有的接口请求都通过一个统一封装的 request.js 发起。这个封装做的事情包括创建 Axios 实例、设置基础路径、请求拦截器里附加 Token、响应拦截器里统一处理错误码、导出 get/post 快捷方法。具体到代码逻辑请求拦截器里从 localStorage 中取出 token附加到 headers.Authorization 上。响应拦截器里拿到后端返回的统一 Result 结构如果 code 为 200返回 data 给业务代码如果 code 为 401说明 Token 失效清空本地登录状态并跳转登录页其他错误码用 Element UI 的 Message 组件弹出错误提示。// 请求拦截器自动附加 Token service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config })这样做之后业务代码里只需要关心成功数据剩下的异常处理都集中在拦截器里完成整个项目的代码重复度会明显下降。我在代码审查时最看重的就是这一点同样的逻辑不要在 20 个页面里各写一遍。关于跨域开发环境下最省心的方案是配置 devServer.proxy把 /api 前缀的请求代理到后端的 8080 端口。这样浏览器看到的请求是同源的完全绕开了跨域限制。生产环境部署时前后端用 Nginx 反向代理到同一个域名下同样可以避免跨域。这两种方案比在后端代码里开 CORS 放行所有域名要干净得多。3.3 商品展示页的联动商品列表页几乎是每个前端开发者必写的页面但做好交互细节并不简单。这个项目的商品列表页支持分类筛选、排序、分页三个维度的联合操作。实现时用一个响应式的查询条件对象维护所有筛选状态任何控件变化后都触发请求请求参数里带上分类 ID、排序字段、页码等参数。这里容易踩的坑是分页组件的当前页码和筛选条件联动切换分类后页码必须重置为第一页否则会出现在第 5 页时切换分类结果列表为空的诡异现象。另一个细节是空数据的展示周边商品经常会遇到某个分类暂时没有上架商品这时候页面不能白屏要有一个友好的空状态提示和返回首页的入口。商品详情页的规格选择交互也值得讲。用户点击不同规格后页面要根据已选规格实时请求对应 SKU 的价格、库存、限购数量。如果没有选中完整规格加购按钮要置灰不可点击。这个逻辑看起来简单但如果规格维度超过两个状态管理就会变得复杂。这套系统用的是基础方案定义规格选项的组合 key点击某个规格时更新 key再通过监听 key 的变化请求 SKU 信息。如果以后规格维度增加到三个以上推荐用更结构化的方式维护已选规格表甚至直接引入状态管理库来管理这个状态。4. MySQL 表结构设计用表说话兼容多变的周边商品线4.1 核心表一览这套系统的数据库表设计得很规整核心表大概有九张表名作用关键字段user用户表id、username、password、role、nickname、avatarcategory商品分类表id、name、parent_id、sort_orderproduct商品表id、category_id、title、subtitle、cover_image、detail_html、statusproduct_sku商品规格表id、product_id、sku_name、price、stock、limit_num、imagecart_item购物车表id、user_id、sku_id、quantity、checkedorders订单表id、order_no、user_id、total_amount、status、receiver_info、create_timeorder_item订单明细表id、order_id、sku_id、product_name、sku_name、price、quantitybanner首页轮播图表id、image_url、link_url、sort_orderaddress收货地址表id、user_id、receiver、phone、province、city、detail用户表的 role 字段直接决定登录后的权限普通用户端和管理员端共用一个用户体系用枚举值区分。密码字段存的是加密后的密文绝对不能明文存储。这个项目的加密采用 BCrypt是 Spring Security 生态常用的加密方式每次加密结果都不一样但校验接口可以验证安全性足够。商品分类表用了 parent_id 字段支持二级分类比如演唱会周边下挂荧光棒应援手幅这个设计虽然简单但比把所有分类压平成一张列表要灵活得多。首页轮播图单独建表也值得点赞运营人员可以直接在后台维护轮播图不用改代码这是很多管理系统容易忽略的细节。4.2 订单快照设计为什么必须冗余商品信息我见过很多新手设计的订单表订单明细里只存 sku_id 和数量觉得商品信息查表关联就行。但实际业务中这是个大坑如果后台修改了商品标题、价格或者直接删除了商品那历史订单里展示的信息就会跟着变甚至查不到商品信息。而订单是交易凭证用户下单时看到的价格和标题在售后场景下都必须原样保留。这个系统在 order_item 表中冗余了 product_name、sku_name、price 这些字段这就是订单快照。下单那一刻把商品当前的信息复制一份存进订单明细后续商品怎么改都不影响历史订单。这个设计看似简单却是电商系统必备的基本功很多二手交易纠纷本质上就是因为订单信息与商品信息脱节导致的。类似的思路还体现在订单表的 receiver_info 字段直接把整个收货地址快照成字符串保存。为什么要这样做因为用户下单后可能修改了默认地址如果不做快照发货时就可能发到用户后来改的地址去造成严重的售后问题。下单那一刻的地址才是这次交易应该使用的地址这一点务必在表结构设计阶段就想清楚。4.3 索引与事务下单链路的关键设置数据库性能的关键在索引。这套系统里最需要索引的表是订单表因为订单量增长后WHERE user_id ? ORDER BY create_time DESC这种查询会非常频繁。复合索引(user_id, create_time)可以同时满足筛选和排序是订单表最重要的索引。另外order_no 订单号应该建唯一索引防止重复下单产生相同订单号。购物车表按用户查询频繁user_id 也要建索引。注意不是每个字段都加索引索引过多会拖慢插入和更新速度要按实际查询场景取舍。下单链路是事务最重要的使用场景。一次完整下单涉及的操作包括校验商品状态、校验并扣减 SKU 库存、写入订单主表、写入订单明细表、清空购物车对应项。这五个操作必须在一个事务里完成任何一步失败整体回滚否则会出现订单创建了但库存没扣或者库存扣了但订单没生成的严重数据不一致问题。项目里在 Service 方法上标注 Transactional 注解同时要考虑事务的传播级别和回滚条件。这里有一个细节库存扣减的原子性在 SQL 层面解决事务只负责整体一致性两者配合才是完整的正确方案。还有一点要注意Transactional 默认只对 RuntimeException 回滚如果业务里抛的是受检异常需要指定 rollbackFor 参数否则会出现事务没回滚的隐蔽问题。5. 从零跑通可直接运行环境准备与启动全流程5.1 基础环境版本搭配标题写着可直接运行但如果你电脑上环境都没有那源码再完整也跑不起来。首先需要准备 JDK 8 或 JDK 11、Node.js 14 以上、MySQL 5.7 或 8.0、以及一个 Java IDE推荐 IDEA 或 Eclipse。版本搭配上有一个容易踩的坑如果本机已经装了更高版本的 JDK比如 JDK 17而项目是基于 JDK 8 语法和依赖编译的启动时可能会报一些奇怪的类加载错误。解决办法是让项目里的 Maven 编译器配置指向本机已有的 JDK或者在 IDE 里给项目单独设置 JDK 版本。MySQL 的版本选择上这个项目基于 8.0 编写的话驱动配置和 5.7 有些差异。MySQL 8.0 的驱动类名是 com.mysql.cj.jdbc.Driver连接 URL 里需要带 serverTimezone 参数5.7 则不一定需要。如果数据库是 8.0 而项目配置是 5.7 的驱动会报 ClassNotFoundException反过来则会出现时区相关的警告。所以推荐的做法是保持项目自带的配置按项目要求安装对应版本的 MySQL不要在这个环节自由发挥。5.2 数据库初始化与后端配置这个项目的根目录下通常会带一个 SQL 文件比如 starsql.sql 或者 init.sql。拿到源码后第一步不是急着启动而是先用 Navicat 或者命令行创建数据库再执行 SQL 脚本。执行成功后检查核心表是否创建成功初始化数据是否导入初始化数据里一般有管理员账号和测试商品登录后台时可以直接用。后端项目的配置文件是 application.yml需要改的地方有四处数据库连接 URL改成自己机器上的 127.0.0.1 端口、数据库用户名、数据库密码、以及 JWT 密钥本地跑可以保持默认但部署到公网环境必须改。改完之后用 Maven 打包或者直接在 IDEA 里运行主类看到 Started Application in xxx seconds 的日志就说明后端启动成功了。启动后可以用浏览器直接访问接口文档页面如果项目集成了 Knife4j 这类 API 文档工具系统会列出所有接口的定义和参数说明。5.3 前端启动npm 镜像、环境变量与跨域代理前端项目启动步骤是标准的进入 frontend 目录执行 npm install 安装依赖然后 npm run serveVue CLI 项目或者 npm run devVite 项目。这里最常见的问题就是依赖安装失败或者下载缓慢解决方案是使用 npm 镜像源把 registry 切换到速度更快的镜像地址。切换方法有全局设置和项目级 .npmrc 两种建议用项目级配置不影响其他项目。前端项目的环境变量文件 .env.development 里一般配置了 VUE_APP_BASE_API 或者类似的变量指向后端的接口地址。开发环境下通常配置成空字符串或者 /api由 devServer 的代理转发到后端端口。确认代理配置正确的方法很简单启动前端后打开浏览器开发者工具看网络请求里 /api/login 的请求有没有成功返回数据。如果 404优先检查代理配置如果 500大概率是后端数据库连接有问题。5.4 跑通一条完整链路做验收环境全部就绪后我建议按这条链路做一次功能验收能快速验证整个系统是否健康用管理员账号登录后台创建一个商品分类再在分类下添加一个带两个 SKU 的商品并上架退出管理员账号注册一个新用户在商城首页找到这个商品加入购物车提交订单并模拟支付然后在我的订单里确认订单状态变化再切回管理员后台完成发货。这一整套走下来前后端交互、数据库读写、状态流转全部验证到位了项目就算是真正跑通了。这条验收链路建议每次都走一遍包括后面改了代码之后也要回归测试不要只测改动的部分。我在实际开发中吃过亏改了一个商品模块的字段结果订单模块的展示崩了就是因为只测了商品模块没做全链路回归。6. 项目运行中的真实踩坑与处理记录6.1 跨域与接口 404前后端分离项目最常见的开局问题是浏览器控制台报跨域错误。报错形式通常是 CORS policy 或者请求被 blocked。我当时排查时先确认了前端的代理配置是否生效如果用的是 Vite 或 webpack 的 proxy那么浏览器 network 面板里请求地址应该是 /api 开头的相对路径而不是完整的 http://localhost:8080 地址。如果用了完整地址说明代理配置没有生效请求是由浏览器直接发起的跨域就必然发生。解决办法是检查代理配置里的 target 是否指向了后端实际端口以及路径重写规则是否写对。很多 Vue CLI 项目的配置长这样// vue.config.js devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: } } } }这里 pathRewrite 的规则特别容易搞错如果后端接口本身没有 /api 前缀就必须把请求路径里的 /api 去掉后再转发。如果后端上下文路径还带了项目名那 target 里就要补上。这个细节我至少帮别人排查过五六次每次都是同一个原因前端请求路径和后端实际接口路径对不上。6.2 MySQL 时区与连接失败MySQL 8.0 的时区问题很经典。如果连接 URL 里没有加 serverTimezoneAsia/Shanghai 或 GMT%2B8启动时通常会报时区错误而且错误信息里的时区名可能是乱码非常影响排查效率。还有一个隐藏点是 MySQL 的 useSSL 参数开发环境建议改成 false否则每次连接都会有 SSL 握手警告慢且烦。如果碰到 Access denied for user 报错先检查密码是否正确再检查用户是否有权限连接。新安装的 MySQL 默认可能只允许 localhost 访问如果你的数据库和项目不在同一台机器上需要给用户授权远程访问权限并且要注意 MySQL 8.0 的认证插件问题有些老客户端连接 8.0 会因为 caching_sha2_password 插件不兼容而报错解决办法是把用户的认证方式改成 mysql_native_password。这个坑在本地连接时通常不会出现但一旦要用 Docker 部署就会冒出来。6.3 端口占用与 IDE 缓存后端启动日志报 Port 8080 was already in use这是端口被其他进程占用了。解决办法有几种找到占用进程杀掉或者改项目的 server.port 配置。我倾向于改端口因为杀进程可能误伤其他服务。IDEA 里右键运行配置在 VM 参数或环境变量里覆盖端口即可。另外如果 Maven 依赖导入后代码依然大量报红先执行一次 clean 清除缓存再重新导入整个 Maven 工程多数情况是 IDE 的索引和缓存问题不是代码真的有问题。前端项目也有类似情况有时候 npm install 装完依赖但 IDEA 里 JS 文件还是报找不到模块这种情况重启一下 IDE 或者 invalidate caches 就好。不要一看到报错就怀疑源码有问题先排查环境问题再下结论。6.4 前端 npm 安装依赖失败的常见原因npm install 失败的原因有很多种网络原因、Node 版本不兼容、依赖包版本冲突。最直接的排查方式是把完整报错信息复制下来看而不是只看最后几行。常见的一种情况是某个包的安装脚本执行出错比如 node-sass 这种老牌包在 Node 高版本下经常编译失败。遇到这种情况可以查看项目用的是 node-sass 还是 dart-sasssass 包如果是前者建议把 Node 版本切换到项目要求的版本或者使用 nvm 这类工具来管理多版本 Node。另外如果项目 lock 文件里锁定的依赖版本太老可能需要删除 node_modules 和 lock 文件后重新 install。这里要提醒一下不要动不动就把整个 lock 文件删了lock 文件的价值在于锁定依赖树保证团队成员安装的版本一致只有确定是版本冲突时才需要重建。这个项目我实际跑下来还有一个小问题前后端启动有先后顺序要求必须先启动后端再启动前端否则第一次请求会因为后端没起来而失败。但如果你配好了前端的代理后端起来后刷新页面就能恢复不需要重启前端。说实话源码管理类的后台项目我跑过不少星之语这套让我比较满意的地方是它业务完整度不错从用户注册、商品上架、购物车、下单支付到后台发货和数据概览整条链路没有断点。对刚开始接触全栈项目的人来说直接在本地把它跑起来再沿着 Controller 到 Mapper 逐层阅读代码比看一堆零散教程要高效得多。如果后续想接着扩展我建议优先考虑两个方向一是接入真实的支付回调把模拟支付的接口替换成微信支付或支付宝的官方 API二是给热门商品加上简单的限时购买或者限量编号登记功能把明星周边最典型的抢购场景做得更逼真。这种扩展既贴近业务也能让技术水平再上一个台阶。
返回列表