waynblog

1.2k Star 的 waynboot-mall:这次我把开源商城从里到外重构了一遍

Image

waynboot-mall 是我长期维护的一套开源 H5 商城项目,后端主仓库目前在 GitHub 上大约 1.2k Star。

项目包含后端接口、运营后台和 H5 商城前台,覆盖商品、购物车、下单、支付、订单、会员、优惠券、后台运营等基础链路。

这次重构,我主要做了三件事。

第一,后端按业务领域重新拆分模块,交易、库存、商品、购物车、营销、支付渠道不再混在 common 里。

第二,运营后台 waynboot-admin 从 Vue 2 / Vue CLI / Element UI 迁移到 Vue 3 / Vite 6 / Element Plus。

第三,H5 商城 waynboot-mobile 迁移到 Vue 3 + Vite 6 + Vant 4,并继续围绕真实购物链路优化页面和构建体验。

我的目标很明确:让项目不只适合演示,也更适合学习、二开和长期维护。

ONBOARDING 新人上手

这次我在 waynboot-mall 也补了一份 ONBOARDING.md,它不是单纯的安装说明,而是给第一次接触 waynboot-mall 的开发者准备的代码导读。

这份文档的定位很明确:帮助新手在 30 分钟内建立整体认知,并能顺着代码追踪一条完整业务链路。

里面我没有从“项目有多少功能”开始讲,而是直接给出阅读路径:

  • 先看订单状态枚举,理解 1xx / 2xx / 3xx / 4xx 状态分组
  • 再看下单责任链,理解一次下单被拆成哪 6 个步骤
  • 接着看订单状态机,理解支付、取消、发货、退款、收货的合法流转
  • 然后看库存支撑类,理解冻结、确认、释放、回补四个库存动作
  • 最后再看支付回调、本地消息表、库存对账和后台首页统计

我希望新开发者不是从一堆 Controller 里乱翻,而是按业务链路读代码。

后端现在的结构也更适合这种阅读方式:admin-api 和 mobile-api 只做 HTTP 入口,业务逻辑放在各个 waynboot-domain-* 模块里;Support 类负责具体能力切片,比如订单校验、库存处理、状态流转、取消补偿;跨领域契约统一收敛到 waynboot-domain-api。

这对二开也有帮助。

你要改下单,就从 SubmitOrderController 追到 OrderSubmitChain。你要看支付回调,就从 PayController 追到 PaymentCallbackSupport。你要理解库存,就直接看 OrderStockSupport 和 Redis 预扣逻辑。路径清楚以后,改代码的风险会低很多。

运营后台已升级到 Vue 3 + Vite 6

很多商城项目维护到后期,前端栈会先开始拖慢开发。

后端还能继续升级,业务还能继续加,但前端栈停在 Vue 2、Vue CLI、旧组件库,后面每改一次都会变得很难受。

waynboot-admin 这次已经升级到:

  • Vue 3.5
  • Vue Router 4
  • Vuex 4
  • Vite 6
  • Element Plus 2
  • TinyMCE 8
  • Vitest + Vue Test Utils

后台管理端功能也比较完整。动态路由菜单、权限控制、商品管理、订单管理、会员管理、运营配置、系统管理、富文本编辑、消息通知这些后台常见能力都在。

对我来说,这次后台前端升级最大的意义,不在于“Vue 3 比 Vue 2 新”。

它更实际的价值是:项目后面继续维护时,不用继续背 Vue CLI 和 Element UI 的历史包袱。

开发服务走 Vite,生产构建走 Vite,单元测试切到 Vitest。该删的旧配置也删掉了,比如旧的 Babel、Jest、Travis、Element UI 入口配置。

这比单纯改 package.json 里的版本号更重要。

因为真实项目升级,最怕的是表面升级了,项目里面还到处残留旧时代的入口和写法。

H5 商城前台也完成了 Vue 3 迁移

H5 前台这次也同步升级。

waynboot-mobile 现在是 Vue 3 + Vite 6 + Vant 4,核心页面覆盖首页、分类、搜索、商品详情、购物车、下单、支付、订单、地址、优惠券和用户中心。

我不希望这个项目只停留在页面展示层。

商城前台更重要的是购物链路完整。

用户要能看商品、选规格、加购物车、下单、支付、看订单。开发者要能顺着这些页面摸到接口、状态管理、路由、鉴权、请求封装和移动端适配。

这次迁移也改善了构建体验。

它现在更偏真实移动端商城体验:浅色、清楚、少装饰,重点放在商品信息和下单流程上。Vite 6 带来的开发体验提升很直接,启动和构建都更轻,后续继续改页面也更顺。

如果你想找一个 Vue 3 + Vite 6 的商城前台练手,这个项目比单页模板更适合。

因为它有真实业务链路。

后端重构重点是重新划清领域边界

前端升级容易被看见,后端重构更难一眼看出来。

这次工作量最大的部分在后端。

以前这类项目很容易出现一个问题:common 模块越写越大。一开始它只是放通用能力,后来商品、订单、库存、支付、消息、营销都往里面塞。

短期能跑。

长期很麻烦。

因为所有东西都能互相引用,最后谁都不敢拆。你想改订单,可能碰到库存。你想改支付,可能绕到优惠券。你想做微服务拆分,也会发现编译期边界不清楚。

这次 waynboot-mall 把后端拆成了更明确的结构:

  • waynboot-domain-api:跨领域契约,放 entity、Mapper、Service 接口、VO、枚举
  • waynboot-domain-trade:订单、支付编排、状态机、本地消息、对账
  • waynboot-domain-inventory:库存冻结、库存流水、Redis 库存快照、库存对账
  • waynboot-domain-goods:商品、SKU、类目、搜索和 ES 同步
  • waynboot-domain-cart:购物车读写与选中商品聚合
  • waynboot-domain-promotion:优惠券、营销位和 Diamond 策略实现
  • waynboot-payment-channel:微信、支付宝、易支付的支付 / 退款渠道适配

common 退回到它本来该做的事:通用配置、切面、策略接口、通用模型和基础设施。

这一步改完,项目边界清楚了很多。

所有业务不再挤在一个模块里。商品归商品,订单归订单,库存归库存,支付渠道归支付渠道。

后面继续加功能时,这个边界能减少很多沟通和排查成本。

交易链路补上了库存、支付、消息和对账治理

我一直觉得,商城项目最值得看的地方,不是首页做得多漂亮。

而是下单、库存、支付、退款、消息补偿这些链路怎么处理。

因为这些地方一旦写虚了,项目看起来功能完整,实际一压测、一并发、一重复回调,就会露馅。

这次后端重构重点围绕交易链路展开:

  • 下单链路按责任链拆分
  • Redis Lua 做库存预占和入口削峰
  • MySQL 条件更新做最终一致性兜底
  • 订单状态统一走状态机校验
  • 支付回调用幂等键处理重复通知
  • 支付成功后的库存确认、虚拟销量等后置动作走本地消息
  • 本地消息失败后支持重试、死信、人工重投
  • 库存和支付都补了对账治理能力

这些内容没有“重写前端页面”那么直观,但它们决定了商城项目能不能继续往下做。

举个例子,库存这里不是简单扣一下库存字段。

现在的思路是:Redis Lua 先挡住热点 SKU 的并发压力,MySQL 条件更新负责最终库存正确,库存流水用唯一 flowKey 保证重试时不会重复产生副作用。

支付回调也不是收到通知就直接改订单。

它要先验签,再用订单状态条件更新处理并发,再用支付流水唯一键处理重复回调,后续动作交给本地消息去做。

这会更接近真实商城系统的处理方式。

我保留了可以继续深入的技术入口

我不想把这次改动包装成“已经完美”。

开源项目最怕这种话。

这次重构完成了主体拆分,但项目里仍然保留了一些后续可以继续收口的点,比如支付 SDK 还可以进一步从 common 和交易模块里剥离,部分接口异常也可以继续封装得更干净。

我觉得这反而是项目值得看的地方。

它还不是一个被包装好的静态样板,更像一个还在持续演进的工程。

如果你想看后端,建议从这些入口开始:

  • OrderStateTransitionSupport:订单状态流转
  • PaymentCallbackSupport:支付回调统一处理
  • OrderStockSupport:库存冻结、确认、释放、退款回补
  • RedisStockPreDeductSupport:Redis Lua 库存预占
  • LocalMessageService:本地消息状态流转
  • TradeOpsController:后台交易治理接口
  • DashboardController:后台首页统计接口

如果你想看前端,建议直接看这两个仓库:

  • waynboot-admin:Vue 3 + Vite 6 + Element Plus 后台管理端
  • waynboot-mobile:Vue 3 + Vite 6 + Vant 4 H5 商城前台

这样看,比只看 README 更容易理解这次重构到底改了什么。

这个项目现在适合三类开发者

第一类,想学 Spring Boot 3 + Java 17 商城项目的人。

你能看到 Controller、Service、Mapper 这种基础分层,也能看到订单、库存、支付、本地消息、MQ、对账这些真实业务链路怎么组织。

第二类,想看 Vue 2 项目怎么迁到 Vue 3 + Vite 6 的人。

waynboot-admin 和 waynboot-mobile 都不是空项目。一个是后台管理端,一个是 H5 商城端,迁移中会遇到组件库、路由、状态管理、构建、环境变量、测试工具这些实际问题。

第三类,想拿开源商城做二开的开发者。

现在三个仓库都拆得比较清楚:

  • 后端接口:waynboot-mall
  • 运营后台:waynboot-admin
  • H5 商城:waynboot-mobile

后端负责 API 和交易治理,后台负责运营管理,H5 负责用户购物链路。

这个边界清楚以后,二开会更容易控制范围。

项目地址

后端接口项目:https://github.com/wayn111/waynboot-mall

运营后台前端:https://github.com/wayn111/waynboot-admin

H5 商城前端:https://github.com/wayn111/waynboot-mobile

如果你觉得这个项目对你有帮助,可以给主仓库点个 Star。

我更希望它被跑起来、改起来、用起来,而不是只停留在收藏夹里。


总结

这次 waynboot-mall 重构,我不想只强调“项目升级到了 Vue 3 和 Vite 6”。

这当然重要。

我更看重的是,项目开始从一个能演示完整商城流程的开源项目,往一个更像真实工程的方向走。

前端栈更新了,后端边界拆开了,交易链路也开始补上库存、支付、消息、对账这些硬逻辑。

如果你正在找一个能系统学习商城项目的开源工程,现在的 waynboot-mall,比以前更值得看。