Technical Documentation: gz-yami/mall4cloud
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
Mall4cloud 开源版微服务商城系统
Mall4cloud 是 Mall4j 体系下的微服务商城产品线。本仓库是 Mall4cloud 开源版主仓库,开源版面向 B2B2C 商城架构,基于 Spring Boot 4、Spring Cloud、Nacos、Seata、MySQL、Redis、RocketMQ、Canal、Elasticsearch、MinIO 等组件构建,包含平台端、商家端、用户端和完整订单流程,适合学习微服务电商架构、评估多商户商城源码,以及进行企业商城系统二次开发。
项目说明
- 项目名称:Mall4cloud 微服务商城开源版、Mall4cloud B2B2C 开源商城、Mall4j 微服务商城开源仓库。
- 项目简介:Mall4cloud 是 Mall4j 体系下的微服务商城产品线;本仓库是 Mall4cloud 开源版主仓库,开源版面向 B2B2C 商城架构,适合学习微服务电商架构、评估多商户商城源码和企业商城二次开发。
- 技术说明:Mall4cloud 主线已升级到 Spring Boot 4、Spring Cloud 和 Vue3,具体依赖版本以后端
pom.xml和前端package.json为准。 - 开源授权:本仓库开源版遵守 AGPLv3 协议,适合学习、评估和符合协议的使用场景。
- 商业授权:闭源商用、企业私有化交付、微服务集群交付、企业级售后和更多业务版本应参考 Mall4j 官网商业授权说明。
- 企业版本:商业版坚持 100% 源码交付、源码无加密、永久授权;付费企业版本覆盖 B2C、B2B2C、S2B2C、B2B2B、SaaS、多租户、跨境等场景,具体功能和服务范围以官网与合同确认为准。
- 版本说明:Mall4cloud 是 Mall4j 体系下的微服务商城产品线,区别于 Mall4j 单体开源版;企业版本的功能和服务以官网说明为准。
- 相关链接:官网、价格/功能对比、客户案例、当前仓库。
项目特点
- Spring Boot 4 + Spring Cloud 微服务架构
- Nacos 服务注册与配置,Seata 分布式事务
- Redis 缓存、RocketMQ 消息队列、Elasticsearch 搜索、MinIO 文件存储
- 平台端、商家端、用户端、多服务模块协同
- AGPLv3 开源,商业授权和企业版本说明见“授权与版本”
技术版本说明
Mall4cloud 主线已升级到 Spring Boot 4、Spring Cloud 和 Vue3,适合微服务商城新项目评估和长期维护。对于仍停留在旧技术栈上的商城系统,后续框架升级、依赖兼容和安全维护成本通常更高;本项目的具体依赖版本以后端 pom.xml 和前端 package.json 为准。
前言
本仓库致力于提供一个功能完整、易于维护的 Mall4cloud 开源版微服务电商系统参考实现。当前开源版面向 B2B2C 商城架构,后台管理系统包含平台管理、店铺管理、商品管理、订单管理、规格管理、权限管理、资源管理等模块。Mall4j 体系下更多版本和功能范围以官网说明为准。
文档与快速启动
项目文档位于仓库 doc 目录,也可以通过以下链接查看:
- Gitee 文档:https://gitee.com/gz-yami/mall4cloud/tree/master/doc
- 开发环境搭建视频:https://www.bilibili.com/video/BV1TK411C7aV
- Agent Skill:权威副本
.agents/skills/mall4cloud/(Cursor / Codex);Claude Code 使用.claude/skills/mall4cloud/(同一份内容)。按现有功能点辅助启动、使用和二次开发
建议先阅读文档,再结合视频搭建本地开发环境。先起启动中间件 MySQL、Redis、Nacos、MinIO;后端最小链路是网关 mall4cloud-gateway(8000)+ auth + rbac + biz + 平台端 platform 或商家端 multishop。前端 VITE_APP_BASE_API 只配网关,不要直连业务端口。
项目按阿里巴巴代码规约进行检查,以下是代码规约扫描结果:
具体目录结构和二次开发阅读路径,可以查看 技术文档。
授权与版本
本仓库开源版使用 AGPLv3 协议。你可以按协议学习、研究、二次开发和自行部署。
闭源商用、企业私有化部署交付、微服务集群部署支持、100% 源码交付、源码无加密、永久授权、供应链/SaaS/跨境版本、演示环境和企业级售后支持属于商业授权或企业版本范围,可以通过 Mall4j 官网了解。
- 开源版:微服务 B2B2C 商城系统,适合学习、评估和符合 AGPLv3 的使用场景。
- 企业版本:覆盖 B2C、B2B2C、S2B2C、B2B2B、SaaS、多租户、跨境商城等业务场景,具体功能以官网版本页为准。
- Mall4j 商城官网:https://www.mall4j.com
- 版本价格与功能对比:https://www.mall4j.com/price/
- 客户案例:https://www.mall4j.com/case/
商业授权支持
开源版与企业版本
| 对比项 | 开源版 | 企业版本 |
|---|---|---|
| 学习微服务电商架构 | 支持 | 支持 |
| 授权方式 | AGPLv3 开源协议 | 商业授权 |
| 闭源商用 | 需另行取得商业授权 | 按商业授权使用 |
| 部署方式 | 可自行部署(遵循 AGPLv3) | 可提供企业私有化部署交付服务 |
| 仓库/版本定位 | Mall4cloud 开源版主仓库,面向微服务 B2B2C 商城架构 | Mall4j/Mall4cloud 企业版本体系,不等同于本开源仓库的增强版 |
| 版本范围 | 微服务 B2B2C 开源架构与基础业务能力 | 可覆盖 B2C、B2B2C、S2B2C、B2B2B、SaaS、多租户、跨境等版本 |
| 100% 源码交付、源码无加密、永久授权 | 可获取当前开源代码,不等同商业交付承诺 | 商业版支持,具体以官网和合同为准 |
| 企业级售后支持 | 社区交流为主 | 可提供商业支持 |
常见问题
Mall4cloud 是什么?
Mall4cloud 是 Mall4j 体系下的微服务商城产品线。本仓库是 Mall4cloud 开源版主仓库,开源版面向 B2B2C 商城架构,基于 Spring Boot 4、Spring Cloud、Nacos、Seata、Redis、RocketMQ、Elasticsearch、MinIO 等组件构建。
Mall4cloud 和 Mall4j 有什么区别?
Mall4j 开源版主仓库更适合了解 Java 单体商城和 B2C 单商户基础能力;Mall4cloud 开源版主仓库面向微服务 B2B2C 商城架构,包含平台端、商家端、用户端和多个后端服务模块。
Mall4cloud 是否适合企业私有化部署?
开源版可以按 AGPLv3 协议自行部署和评估。
闭源商用、企业私有化交付、集群部署支持、长期售后和更多业务版本,可以通过 Mall4j 官网了解企业版本。
前端应该连哪个端口?
管理后台和 uni-app 都只连网关 8000。auth、rbac、product 等业务服务有各自端口,用于本机启动和注册 Nacos,不要配进 VITE_APP_BASE_API。
仓库示例 IP 是 192.168.1.46,拿到源码后请批量替换成自己的地址。
Mall4cloud 是否已经升级到 Spring Boot 4?
Mall4cloud 主线已升级到 Spring Boot 4,具体依赖版本以后端 pom.xml 和前端 package.json 为准。
相关资料
- 技术论坛:https://www.mall4j.com/forum/
- Gitee 主仓库:https://gitee.com/gz-yami/mall4cloud
- GitHub 主仓库:https://github.com/gz-yami/mall4cloud
相关开源仓库
| 仓库 | 说明 |
|---|---|
| mall4cloud | Mall4cloud 开源版 Java 微服务后端主仓库,面向 B2B2C 架构 |
| mall4cloud-platform | 平台端管理后台,默认账号 admin,密码 123456 |
| mall4cloud-multishop | 商家端管理后台,默认账号 admin,密码 123456 |
| mall4cloud-uniapp | uni-app 用户端 |
| mall4j | Mall4j 开源版主仓库,面向 B2C 单商户商城 |
演示地址
演示地址:
pc端:https://cloud-pc.mall4j.com
H5端:https://h5.mall4j.com/cloud
小程序演示
目录结构规范
我们也有自己的目录结构
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
- DTO(Data Transfer Object):数据传输对象,前端像后台进行传输的对象,类似于param。
- BO(Business Object):业务对象,内部业务对象,只在内部传递,不对外进行传递。
- Model:模型层,此对象与数据库表结构一一对应,通过 Mapper 层向上传输数据源对象。
- Controller:主要是对外部访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。为了简单起见,一些与事务无关的代码也在这里编写。
- FeignClient:由于微服务之间存在互相调用,这里是内部请求的接口。
- Controller:主要是对内部访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。为了简单起见,一些与事务无关的代码也在这里编写。
- Service 层:相对具体的业务逻辑服务层。
- Manager 层:通用业务处理层,它有如下特征:
- 1) 对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口。
- 2) 对 Service 层通用能力的下沉,如缓存方案、中间件通用处理。
- 3) 与 DAO 层交互,对多个 DAO 的组合复用。
- Mapper持久层:数据访问层,与底层 MySQL进行数据交互。
- Listener:监听
RocketMQ进行处理,有时候会监听easyexcel相关数据。
关于FeignClient,由于微服务之间存在互相调用,Feign 是http协议,理论上是为了解耦,而实际上提供方接口进行修改,调用方却没有进行修改的时候,会造成异常,所以我们抽取出来。还有就是对内暴露的接口,是很多地方都公用的,所以我们还将接口抽取了出了一个模块,方便引用。可以看到mall4cloud-api这个模块下是所有对内feign接口的信息。
目录结构
mall4cloud
├─mall4cloud-api -- 内网接口
│ ├─mall4cloud-api-auth -- 授权对内接口
│ ├─mall4cloud-api-biz -- biz对内接口
│ ├─mall4cloud-api-leaf -- 美团分布式id生成接口
│ ├─mall4cloud-api-multishop -- 店铺对内接口
│ ├─mall4cloud-api-order -- 订单对内接口
│ ├─mall4cloud-api-platform -- 平台对内接口
│ ├─mall4cloud-api-product -- 商品对内接口
│ ├─mall4cloud-api-rbac -- 用户角色权限对内接口
│ ├─mall4cloud-api-search -- 搜索对内接口
│ └─mall4cloud-api-user -- 用户对内接口
├─mall4cloud-auth -- 授权校验模块
├─mall4cloud-biz -- mall4cloud 业务代码。如图片上传/短信等
├─mall4cloud-common -- 一些公共的方法
│ ├─mall4cloud-common-cache -- 缓存相关公共代码
│ ├─mall4cloud-common-core -- 公共模块核心(公共中的公共代码)
│ ├─mall4cloud-common-database -- 数据库连接相关公共代码
│ ├─mall4cloud-common-order -- 订单相关公共代码
│ ├─mall4cloud-common-product -- 商品相关公共代码
│ ├─mall4cloud-common-rocketmq -- rocketmq相关公共代码
│ └─mall4cloud-common-security -- 安全相关公共代码
├─mall4cloud-gateway -- 网关
├─mall4cloud-leaf -- 基于美团leaf的生成id服务
├─mall4cloud-multishop -- 商家端
├─mall4cloud-order -- 订单服务
├─mall4cloud-payment -- 支付服务
├─mall4cloud-platform -- 平台端
├─mall4cloud-product -- 商品服务
├─mall4cloud-rbac -- 用户角色权限模块
├─mall4cloud-search -- 搜索模块
└─mall4cloud-user -- 用户服务商城部署后 API 地址
| 服务 | 地址 |
|---|---|
| mall4cloud-gatway 网关服务 | http://127.0.0.1:8000 |
| mall4cloud-auth 授权校验服务 | http://127.0.0.1:9101 |
| mall4cloud-biz 业务代码服务(如图片上传/短信等) | http://127.0.0.1:9000 |
| mall4cloud-leaf 基于美团leaf的生成id服务 | http://127.0.0.1:9100 |
| mall4cloud-multishop 商家服务 | http://127.0.0.1:9103 |
| mall4cloud-order 订单服务 | http://127.0.0.1:9106 |
| mall4cloud-payment 支付服务 | http://127.0.0.1:9113 |
| mall4cloud-product 商品服务 | http://127.0.0.1:9104 |
| mall4cloud-rbac 用户角色服务 | http://127.0.0.1:9102 |
| mall4cloud-search 搜索服务 | http://127.0.0.1:9108 |
| mall4cloud-user 用户服务 | http://127.0.0.1:9105 |
部署教程
部署教程请参考 环境搭建 和 中间件 Docker Compose。
代码运行相关截图
1.后台截图
平台端
商家端
2.小程序截图
3.uni-app截图
提交反馈
- mall4cloud开源技术QQ群:561496886
- Mall4j 商城官网:https://www.mall4j.com
支持项目
如果这个项目对你有帮助,欢迎 Star、Fork 和提交 Issue。
Overview (`doc/README.md`)
Mall4cloud 技术文档
用 Cursor、Codex 或 Claude Code 打开本仓库时,可使用内置 Skill:.agents/skills/mall4cloud/(Claude Code 为 .claude/skills/mall4cloud/,内容相同)。它按开源版现有功能点辅助启动、使用和二次开发,详细说明仍以本 doc/ 目录为准。不要套用 Mall4j 单体仓库的模块和端口。
这里是 Mall4cloud 开源版的技术文档入口。按下面顺序阅读:先跑起来,再理解结构,最后做一个后台管理二开练习。
阅读路径
| 目标 | 阅读顺序 | 验收结果 |
|---|---|---|
| 30 分钟跑起基础链路 | 环境搭建 -> 中间件 Docker Compose -> 故障排查 | 网关、后端服务、平台端或商家端能登录 |
| 2 小时读懂系统结构 | 项目概览 -> 技术框架 -> 技术实现 -> 数据模型 | 能说清服务、前端、权限、数据库的请求链路 |
| 1 天完成简单二开 | 数据模型 -> 权限体系 -> 二次开发 | 能按现有模式写一个后台管理功能 |
一级目录
学习方式
检查题采用“题目 + 答案 + 原因”。阅读时先看结论,再打开对应代码、配置或 SQL 核对一次。
Overview (`doc/1-项目概览/README.md`)
项目概览
先用这部分建立全局地图:Mall4cloud 是什么、先看什么、每个模块负责什么。
阅读顺序
读完后,你应该能判断自己接下来要进入环境搭建、技术框架、数据模型还是二次开发。
Overview (`doc/2-环境搭建/README.md`)
环境搭建
这部分只服务一个目标:尽快跑起后端网关、必要服务和一个管理后台。
阅读顺序
中间件用 Docker Compose 时,直接看 部署运维/中间件 Docker Compose。
Overview (`doc/3-技术框架/README.md`)
技术框架
这部分解释项目骨架。先知道代码放哪里、请求怎么走、前后端如何对应。
阅读顺序
权限和分页等具体机制在 技术实现。
Overview (`doc/4-技术实现/README.md`)
技术实现
这部分讲二开最常碰到的机制:权限、上传、分页、验证、异常、消息和搜索。
阅读顺序
Overview (`doc/5-二次开发/README.md`)
二次开发
这部分用一个后台管理功能示例,演示项目现有开发模式。
阅读顺序
示例只写教程,不在仓库里新增业务代码。开始前先读 权限链路 和 核心表速查。
Overview (`doc/6-核心业务/README.md`)
核心业务
本目录只写业务阅读路线,不展开订单、支付、库存等高风险链路的改造教程。
阅读顺序
业务表的结构解释在 数据模型。
Overview (`doc/7-数据模型/README.md`)
数据模型
跑起来之后,先读数据库。权限、商品 SKU、订单结算相关表决定了登录、菜单、商品展示、下单和二开的基础理解。
阅读顺序
Overview (`doc/8-部署运维/README.md`)
部署运维
这部分区分本地启动、中间件一键部署、生产配置和上线检查。没有确认过的配置会列为待核对项。
阅读顺序
Overview (`doc/9-故障排查/README.md`)
故障排查
这部分优先覆盖新读者第一次启动最常遇到的问题。
阅读顺序
Overview (`front-end/mall4cloud-multishop/README.md`)
README
前言
本商城是基于Spring Cloud、Nacos、Seata、Mysql、Redis、RocketMQ、canal、ElasticSearch、minio的微服务B2B2C电商商城系统,采用主流的互联网技术架构、全新的UI设计、支持集群部署、服务注册和发现以及拥有完整的订单流程等,代码完全开源,没有任何二次封装,是一个非常适合二次开发的电商平台系统。
本商城致力于为中大型企业打造一个功能完整、易于维护的微服务B2B2C电商商城系统,采用主流微服务技术实现。后台管理系统包含平台管理,店铺管理、商品管理、订单管理、规格管理、权限管理、资源管理等模块
授权
除开源版本外,本商城还提供商业版本的商城,欲知详情,请访问官网。
商城使用 AGPLv3 开源,请遵守 AGPLv3 的相关条款,或者联系作者获取商业授权(https://www.mall4j.com)
项目链接
JAVA后台:https://gitee.com/gz-yami/mall4cloud
平台端:https://gitee.com/gz-yami/mall4cloud-platform
商家端:https://gitee.com/gz-yami/mall4cloud-multishop
uni-app:https://gitee.com/gz-yami/mall4cloud-uniapp
部署教程
1.安装nodejs
NodeJS 项目要求最低 18.12.0,推荐 20.9.0
如果不了解怎么安装nodejs的,可以参考 菜鸟教程的nodejs相关
2.启动
- 项目要求使用 pnpm 包管理工具
- 使用编辑器打开项目,在根目录执行以下命令安装依赖
pnpm install- 运行
pnpm run dev- 部署
pnpm run build- 如果不想使用 pnpm,请删除
package.json文件中preinstall脚本后再进行安装
{
"scripts" : {
"preinstall": "npx only-allow pnpm" // 使用其他包管理工具(npm、yarn、cnpm等)请删除此命令
}
}目录结构
├── build # 构建相关
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── api # 所有请求(根据不同后台不同的服务分包)
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── directive # 全局指令
│ ├── filters # 全局 filter
│ ├── icons # 项目所有 svg icons
│ ├── lang # 国际化 language
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
├── tests # 测试
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .babelrc # babel-loader 配置
├── .travis.yml # 自动化CI配置
├── vue.config.js # vue-cli 配置
├── postcss.config.js # postcss 配置
└── package.json # package.json运行相关截图
后台截图
提交反馈
Mall4j官网 https://www.mall4j.com
如需购买商业版源码,请联系商务微信
mall4cloud开源技术QQ群:561496886
springboot版本商城请点击
https://gitee.com/gz-yami/mall4j
更多内容请查看 主项目 https://gitee.com/gz-yami/mall4cloud
Overview (`front-end/mall4cloud-platform/README.md`)
README
前言
本商城是基于Spring Cloud、Nacos、Seata、Mysql、Redis、RocketMQ、canal、ElasticSearch、minio的微服务B2B2C电商商城系统,采用主流的互联网技术架构、全新的UI设计、支持集群部署、服务注册和发现以及拥有完整的订单流程等,代码完全开源,没有任何二次封装,是一个非常适合二次开发的电商平台系统。
本商城致力于为中大型企业打造一个功能完整、易于维护的微服务B2B2C电商商城系统,采用主流微服务技术实现。后台管理系统包含平台管理,店铺管理、商品管理、订单管理、规格管理、权限管理、资源管理等模块
授权
除开源版本外,本商城还提供商业版本的商城,欲知详情,请访问官网。
商城使用 AGPLv3 开源,请遵守 AGPLv3 的相关条款,或者联系作者获取商业授权(https://www.mall4j.com)
项目链接
JAVA后台:https://gitee.com/gz-yami/mall4cloud
平台端:https://gitee.com/gz-yami/mall4cloud-platform
商家端:https://gitee.com/gz-yami/mall4cloud-multishop
uni-app:https://gitee.com/gz-yami/mall4cloud-uniapp
部署教程
1.安装nodejs
NodeJS 项目要求最低 18.12.0,推荐 20.9.0
如果不了解怎么安装nodejs的,可以参考 菜鸟教程的nodejs相关
2.启动
- 项目要求使用 pnpm 包管理工具
- 使用编辑器打开项目,在根目录执行以下命令安装依赖
pnpm install- 运行
pnpm run dev- 部署
pnpm run build- 如果不想使用 pnpm,请删除
package.json文件中preinstall脚本后再进行安装
{
"scripts" : {
"preinstall": "npx only-allow pnpm" // 使用其他包管理工具(npm、yarn、cnpm等)请删除此命令
}
}目录结构
├── build # 构建相关
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── api # 所有请求(根据不同后台不同的服务分包)
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── directive # 全局指令
│ ├── filters # 全局 filter
│ ├── icons # 项目所有 svg icons
│ ├── lang # 国际化 language
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
├── tests # 测试
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .babelrc # babel-loader 配置
├── .travis.yml # 自动化CI配置
├── vue.config.js # vue-cli 配置
├── postcss.config.js # postcss 配置
└── package.json # package.json运行相关截图
后台截图
提交反馈
Mall4j官网 https://www.mall4j.com
如需购买商业版源码,请联系商务微信
mall4cloud开源技术QQ群:561496886
springboot版本商城请点击
https://gitee.com/gz-yami/mall4j
更多内容请查看 主项目 https://gitee.com/gz-yami/mall4cloud
Overview (`front-end/mall4cloud-uniapp/README.md`)
README
前言
本商城是基于Spring Cloud、Nacos、Seata、Mysql、Redis、RocketMQ、canal、ElasticSearch、minio的微服务B2B2C电商商城系统,采用主流的互联网技术架构、全新的UI设计、支持集群部署、服务注册和发现以及拥有完整的订单流程等,代码完全开源,没有任何二次封装,是一个非常适合二次开发的电商平台系统。
本商城致力于为中大型企业打造一个功能完整、易于维护的微服务B2B2C电商商城系统,采用主流微服务技术实现。后台管理系统包含平台管理,店铺管理、商品管理、订单管理、规格管理、权限管理、资源管理等模块
授权
除开源版本外,本商城还提供商业版本的商城,欲知详情,请访问官网。
商城使用 AGPLv3 开源,请遵守 AGPLv3 的相关条款,或者联系作者获取商业授权(https://www.mall4j.com)
项目链接
JAVA后台:https://gitee.com/gz-yami/mall4cloud
平台端:https://gitee.com/gz-yami/mall4cloud-platform
商家端:https://gitee.com/gz-yami/mall4cloud-multishop
uni-app:https://gitee.com/gz-yami/mall4cloud-uniapp
部署教程
1.安装nodejs
NodeJS 项目要求最低 18.12.0,推荐 20.9.0
如果不了解怎么安装nodejs的,可以参考 菜鸟教程的nodejs相关
2.启动
- 项目要求使用 pnpm 包管理工具
- 使用编辑器打开项目,在根目录执行以下命令安装依赖
textpnpm install- 运行
textpnpm run dev:h5- 部署
textpnpm run build:h5- 如果不想使用 pnpm,请删除
package.json文件中preinstall脚本后再进行安装
json{ "scripts" : { "preinstall": "npx only-allow pnpm" // 使用其他包管理工具(npm、yarn、cnpm等)请删除此命令 } }技术介绍
本项目是一个uniapp的项目,使用cli进行构建,目录结构如下
text├── dist # 构建相关 ├── src # 源代码 │ ├── components # 全局公用组件 │ ├── hybrid # webview本地页面 │ ├── js_sdk # 外部js │ ├── lang # 国际化 language │ ├── package-activities # 活动分包 │ ├── package-refund # 退款分包 │ ├── package-shop # 店铺分包 │ ├── package-user # 用户分包 │ ├── pages # 主包 │ ├── router # 路由配置 │ ├── static # 静态资源 │ ├── uni_modules # uni第三方组件 │ ├── utils # 全局公用方法 │ ├── wxs # wxs │ ├── app.css # 全局样式 │ ├── App.vue # 入口页面 │ ├── main.js # 入口文件 加载组件 初始化等 │ ├── manifest.json # uniapp 项目配置 │ ├── pages.json # 页面配置文件 │ ├── manifest.json # uniapp 项目配置 │ ├── popup.scss # 全局弹窗样式 │ └── uni.scss # uni样式变量 ├── .editorconfig # 编辑器配置 ├── .env.xxx # 环境变量配置 ├── .eslintxxx.xx # eslint 相关配置 ├── .gitignore # git 忽略清单 ├── .npmrc # npm 配置 ├── Dockerfile # docker部署配置 ├── index.html # html 模板 ├── nginx.conf # nginx 配置 ├── package.json # package.json ├── tsconfig.json # ts 编译配置 └── vite.config.js # vite 配置文件运行相关截图
1.小程序截图
2.uni-app截图
提交反馈
Mall4j官网 https://www.mall4j.com
如需购买商业版源码,请联系商务微信
mall4cloud开源技术QQ群:561496886
springboot版本商城请点击
https://gitee.com/gz-yami/mall4j
更多信息请查看官网
Overview (`mall4cloud-common/mall4cloud-common-cache/README.md`)
一些通用的缓存配置
缓存key命名规范:
服务名:业务名:方法名:key, 大小写以下划线分割 如
mall4cloud_oauth:token:access:
mall4cloud_oauth:token:refresh_to_access:
mall4cloud_oauth:token:uid_to_access:
Overview (`doc/8-部署运维/2-中间件-docker-compose/README.md`)
中间件 Docker Compose
这个目录保留 Mall4cloud 本地或单机服务器启动中间件所需的 compose 文件和配置材料。它不是通用 Docker 教程;Docker/Compose 安装问题请先查官方文档。
先改服务器地址
compose 和初始化 SQL 中仍保留示例地址。启动前请把本目录下的示例 IP 统一替换为你的服务器或本机局域网 IP:
192.168.1.46 -> <你的服务器IP>需要重点核对的地方:
docker-compose.yaml、docker-compose-native.yaml中的 Nacos、MinIO、Seata、RocketMQ 地址。mysql/initdb/mall4cloud_nacos.sql中 Nacos 配置中心写入的 Redis、Seata、OSS、RocketMQ、各服务 MySQL 地址。seata/application.yml中的 Seata 数据库地址。canal/conf/example/instance.properties中的 MySQL 地址和账号。
启动前权限
Linux 服务器上进入本目录后执行:
chmod -R 777 ./rocketmq
chmod -R 666 ./minio/data
chmod -R 777 ./elasticsearch/data启动命令
优先使用带国内镜像地址的 compose:
docker compose -f docker-compose.yaml up -d --build如果服务器访问 Docker Hub 稳定,也可以使用原生镜像版本:
docker compose -f docker-compose-native.yaml up -d --builddocker-compose.yaml 使用处理过的镜像地址,适合国内网络优先尝试。docker-compose-native.yaml 使用原生镜像名,只有在服务器 Docker Hub 或镜像源稳定时再使用;不需要重命名文件,直接用 -f 指定即可。
首次拉取镜像体积较大,等待时间较长是正常现象。若 RocketMQ 报 No route info of this topic,先检查 rocketmq/broker/conf/broker.conf 是否成功挂载、rocketmq/ 目录权限是否足够,再重建 broker/dashboard/namesrv。
端口与默认账号
| 中间件 | 端口/地址 | 默认账号 |
|---|---|---|
| MySQL | <你的服务器IP>:3306 |
root / 80jpnH4.r5g |
| Redis | <你的服务器IP>:6379 |
密码 80jpnH4.r5g |
| Nacos 控制台 | http://<你的服务器IP>:8080/index.html |
本目录初始化 SQL 写入的是 nacos / 80jpnH4.r5g,服务配置也必须保持一致 |
| MinIO API | http://<你的服务器IP>:9000 |
用于后端和前端资源访问 |
| MinIO 控制台 | http://<你的服务器IP>:9001 |
admin / 80jpnH4.r5g |
| Elasticsearch | http://<你的服务器IP>:9200 |
elastic / 80jpnH4.r5g |
| RocketMQ namesrv | <你的服务器IP>:9876 |
无控制台账号 |
| RocketMQ dashboard | http://<你的服务器IP>:8180 |
当前未配置登录保护,生产环境不要裸露 |
| Canal | <你的服务器IP>:11111 |
由 canal/conf 配置 |
| Seata | <你的服务器IP>:8091 |
Seata 2.6 只使用 8091 |
MinIO 桶
进入 MinIO 控制台后创建桶:
mall4cloud端口用途:
9000:对象访问和上传地址,Nacos 的biz.oss.endpoint、前端VITE_APP_RESOURCES_URL都应指向这里。9001:控制台地址,只给运维人员使用。
如果前端图片无法展示,先检查桶是否存在、桶策略是否允许读取、Nacos 中 biz.oss.resources-url 是否是 http://<你的服务器IP>:9000/mall4cloud。
参考截图:
Elasticsearch 索引
搜索服务依赖 product 和 order 两类索引。mapping 以仓库根目录为准:
创建索引时用 Elasticsearch 账号 elastic / 80jpnH4.r5g。下面截图只作为操作界面参考:
Nacos、Canal、Seata
初始化配置在 mysql/initdb 下:
mall4cloud_nacos.sql:写入 Nacos 配置中心,包含网关路由、数据源、Redis、OSS、RocketMQ、Seata 地址。mall4cloud_seata.sql:Seata 事务表。- Canal 相关配置保留在
canal/conf。
Nacos v3 控制台走 8080,服务客户端配置仍使用 8848,Nacos 2/3 客户端还会用到 9848、9849。防火墙或安全组只放开控制台端口时,Java 服务仍可能连不上。
Seata 2.6 本目录的 compose 只暴露 8091。如果需要控制台能力,请按 Seata 官方方式单独部署,不要在 seata/application.yml 中添加未验证的 console 配置。
验收
docker ps能看到 MySQL、Redis、Nacos、Seata、ES、Canal、RocketMQ、MinIO 容器运行。- Nacos 控制台能登录,并能看到
application.yml、mall4cloud-gateway.yml等配置。 - MySQL 中存在
mall4cloud_auth、mall4cloud_rbac、mall4cloud_product、mall4cloud_order等库。 - MinIO 存在
mall4cloud桶。 - RocketMQ dashboard 能看到 namesrv。
如果这些都通过,再回到 环境搭建/后端启动。
Overview (`front-end/mall4cloud-multishop/public/static/js/tinymce/js/tinymce/langs/README.md`)
This is where language files should be placed.
Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/
Doc 1 项目概览 1 项目定位与阅读路径 (`doc/1-项目概览/1-项目定位与阅读路径.md`)
项目定位与阅读路径
Mall4cloud 开源版是一个微服务 B2B2C 商城系统。当前仓库包含后端微服务、数据库脚本、中间件配置和三个前端工程:平台端、商家端、uni-app 用户端。
适合谁读
| 读者 | 先解决的问题 |
|---|---|
| 新维护者 | 先把项目跑起来,再知道服务、数据库和前端怎么连起来。 |
| 二次开发者 | 先理解权限、数据表和后台管理功能模式,再新增后台功能。 |
| 开源评估者 | 先判断技术栈、运行成本、授权边界和是否符合自己的商城场景。 |
30 分钟目标:跑起基础链路
先不用跑全量业务,重点确认网关、登录、权限和一个后台端可用:
- MySQL、Redis、Nacos、MinIO 先可用。
- 网关
mall4cloud-gateway在8000端口可访问。 - 认证、权限、平台端或商家端相关服务启动。
- 管理后台能打开登录页,并能请求网关。
如果使用 Docker Compose 中间件,先看 中间件 Docker Compose。
2 小时目标:读懂结构
按这个顺序建立地图:
读完后应该能回答:请求从前端发出后,经过网关到哪个服务;菜单从哪里来;按钮权限为什么能隐藏;商品和订单核心表怎么关联。
1 天目标:完成一次后台二开
优先做后台管理功能,不先碰订单、支付、库存、结算。可以从热搜、轮播图、附件分组这类后台 CRUD 学起,再迁移到自己的功能。
学习路线:
- 读 核心表速查。
- 读 权限链路。
- 照 后台管理功能二开示例 写自己的文档或代码。
- 用 命名约定与验收清单 自检。
阅读原则
- 每个目录对应一个学习阶段。
- 检查题都给答案和原因。
- 结论以当前源码、配置和 SQL 为准。
Doc 1 项目概览 2 模块职责地图 (`doc/1-项目概览/2-模块职责地图.md`)
模块职责地图
本页帮助你先知道“改哪里”,再去看细节。
后端服务
| 模块 | 职责 | 常见二开入口 |
|---|---|---|
mall4cloud-gateway |
网关,端口 8000,按 Nacos 路由把 /mall4cloud_xxx/** 转给服务 |
调整跨域、路由、统一入口 |
mall4cloud-auth |
登录、Token 发放和校验 | 登录方式、账号体系 |
mall4cloud-rbac |
菜单、角色、按钮权限、接口权限 | 新增菜单和按钮权限 |
mall4cloud-platform |
平台端后台业务 | 平台用户、系统配置、平台运营功能 |
mall4cloud-multishop |
商家端后台业务 | 店铺用户、店铺装修、商家运营功能 |
mall4cloud-product |
商品、分类、品牌、SKU、库存 | 商品管理和库存相关功能 |
mall4cloud-order |
订单、订单项、收货地址、发货 | 订单查询和发货,先阅读再改造 |
mall4cloud-payment |
支付信息和支付通知 | 支付接入,先阅读再改造 |
mall4cloud-biz |
文件上传、附件等通用业务 | MinIO 上传、附件管理 |
mall4cloud-search |
Elasticsearch 搜索、Canal 消息消费 | 商品/订单索引同步 |
mall4cloud-user |
用户、地址、区域 | 用户资料和收货地址 |
mall4cloud-leaf |
分布式 ID | 新表主键生成策略 |
mall4cloud-api |
服务间 Feign 接口 | 跨服务调用契约 |
mall4cloud-common |
公共响应、异常、分页、安全、缓存、数据库、消息 | 新功能复用基础能力 |
前端工程
| 工程 | 角色 | 怎么读 |
|---|---|---|
front-end/mall4cloud-platform |
平台端管理后台 | 重点读登录、动态菜单、后台列表页模式 |
front-end/mall4cloud-multishop |
商家端管理后台 | 重点读商家端菜单和同类 CRUD 页面 |
front-end/mall4cloud-uniapp |
用户端 | 先核对接口地址,后台跑通后再看页面 |
平台端和商家端都是 Vue 3 + Vite + Pinia + Element Plus,环境变量使用 VITE_APP_*。
数据库脚本
| 目录/文件 | 用途 |
|---|---|
db/*.sql |
当前库表结构和初始数据,是数据模型文档的主要依据 |
doc/8-部署运维/2-中间件-docker-compose/mysql/initdb/*.sql |
Docker Compose 启动中间件时导入 Nacos、Seata 等配置 |
es/product.md、es/order.md |
Elasticsearch 索引 mapping |
请求链路
管理后台请求 VITE_APP_BASE_API,默认指向网关 8000。网关读取 Nacos 中的路由配置,例如 /mall4cloud_rbac/** 转到 mall4cloud-rbac。业务服务再通过 MySQL、Redis、RocketMQ、Seata、MinIO、Elasticsearch 等中间件完成各自职责。
练习:我应该改哪个模块
问题:要新增一个“公告管理”后台功能,第一步应该去订单服务吗?
答案:不应该。公告管理更像平台端运营能力。优先在 mall4cloud-platform 增加后端接口,在 front-end/mall4cloud-platform 增加页面,在 mall4cloud-rbac 的菜单和按钮权限中补权限。
为什么:订单服务涉及交易状态和库存协作,不适合作为学习项目分层的第一个改动点。
Doc 1 项目概览 3 学习与自检 (`doc/1-项目概览/3-学习与自检.md`)
学习与自检
这部分说明怎么读文档、怎么确认自己读懂了。检查题不是考试,答案和原因都会直接给出。
阅读时先看三件事
| 问题 | 读到什么程度算够 |
|---|---|
| 我现在要做什么? | 知道本页目标和下一步入口。 |
| 项目怎么实现? | 能指出对应源码、配置或 SQL。 |
| 我怎么知道自己做对了? | 能对照验收信号或检查题说明原因。 |
检查题怎么用
每道题都有三个部分:
- 题目:先自己判断一次。
- 答案:直接给出正确结论。
- 为什么:说明依据来自哪个代码、配置或 SQL 事实。
示例:
问题:平台端前端应该配置 VUE_APP_BASE_API 还是 VITE_APP_BASE_API?
答案:配置 VITE_APP_BASE_API。
为什么:当前平台端和商家端是 Vite 工程,.env.development 中使用 VITE_APP_BASE_API,代码通过 import.meta.env 读取。
读者自检
| 阶段 | 自检答案应该是什么 |
|---|---|
| 启动后 | 网关 8000 可访问,后台登录页能请求到网关。 |
| 读完框架后 | 能说出 Controller -> Service -> Mapper -> DB 的基本链路和 Feign 的用途。 |
| 读完权限后 | 能说出菜单控制页面可见性,按钮权限控制按钮显示,后端接口权限控制请求是否放行。 |
| 读完数据模型后 | 能说出 menu、menu_permission、role_menu、user_role 的关系。 |
避免误判
- 不用截图代替源码、配置或 SQL 结论。
- 不把通用安装教程当成项目配置。
- 不把未经核对的命令写成当前可用。
Doc 2 环境搭建 1 环境要求 (`doc/2-环境搭建/1-环境要求.md`)
环境要求
以下版本来自当前仓库配置。后台前端是 Vue 3 + Vite,后端要求 JDK 17。
后端
| 组件 | 当前要求 | 依据 |
|---|---|---|
| JDK | 17 | 根 pom.xml 的 java.version |
| Maven | 3.9+ | 当前多模块 Maven 工程 |
| Spring Boot | 4.0.3 | 根 pom.xml |
| Spring Cloud | 2025.1.1 | 根 pom.xml |
| Spring Cloud Alibaba | 2025.1.0.0 | 根 pom.xml |
| Nacos Client | 3.1.1 | 根 pom.xml |
| Seata | 2.6.0 | 根 pom.xml |
前端
| 组件 | 当前要求 | 依据 |
|---|---|---|
| Node.js | `^20.19.0 | |
| pnpm | >=8 <11 |
平台端/商家端 package.json |
| Vite | 8.x | 平台端/商家端 package.json |
| Vue | 3.5.x | 平台端/商家端 package.json |
前端包管理器必须使用 pnpm。package.json 里有 preinstall: npx only-allow pnpm,用 npm/yarn 安装会被拦截。
中间件
| 组件 | 版本 | 当前配置来源 |
|---|---|---|
| MySQL | 8.0.x | Docker Compose 使用 MySQL 8 |
| Redis | 7.0 | Docker Compose |
| Nacos | 3.1.1 | Docker Compose |
| Seata | 2.6.0 | Docker Compose |
| RocketMQ | 5.2.0 | Docker Compose |
| Elasticsearch | 7.17.21 | Docker Compose |
| MinIO | RELEASE.2024-04-18T19-09-19Z |
Docker Compose |
| Canal | 1.1.7 | Docker Compose |
检查题
问题:当前后台前端启动前,应该先安装 pnpm 还是直接用 npm install?
答案:先安装并使用 pnpm。
为什么:平台端和商家端 package.json 声明了 pnpm 版本范围,并用 only-allow pnpm 限制安装工具。
问题:当前后端是否还是 JDK 8 项目?
答案:不是,当前要求是 JDK 17。
为什么:根 pom.xml 的 java.version 是 17。
Doc 2 环境搭建 2 数据库初始化 (`doc/2-环境搭建/2-数据库初始化.md`)
数据库初始化
数据库初始化分两类:业务库脚本和中间件初始化脚本。
业务库脚本
仓库根目录 db/ 下是当前业务表结构和初始数据:
| 文件 | 数据库 |
|---|---|
mall4cloud_auth.sql |
账号与登录 |
mall4cloud_rbac.sql |
菜单、角色、按钮权限 |
mall4cloud_platform.sql |
平台端用户与配置 |
mall4cloud_multishop.sql |
店铺、商家用户、热搜、轮播 |
mall4cloud_product.sql |
商品、SKU、库存 |
mall4cloud_order.sql |
订单、订单项、收货地址 |
mall4cloud_biz.sql |
附件和附件分组 |
mall4cloud_user.sql、mall4cloud_user_area_data.sql |
用户与地区数据 |
mall4cloud_leaf.sql |
分布式 ID |
mall4cloud_payment.sql |
支付信息 |
如果不用 Docker Compose 自动初始化,请手动创建库并执行这些 SQL。
中间件初始化脚本
使用 中间件 Docker Compose 时,mysql/initdb 会导入 Nacos、Seata、Canal 等配置。这里包含网关路由、各服务数据源、Redis、RocketMQ、OSS、Seata 地址。
启动前请先把示例 IP 替换为你的环境 IP,否则服务可能注册到了错误地址。
默认账号
当前初始化数据里可见:
| 端 | 用户名 | 密码 | 说明 |
|---|---|---|---|
| 平台端 | admin |
123456 |
根 README 对应平台端仓库说明;账号记录在 mall4cloud_auth.sql、mall4cloud_platform.sql |
| 商家端 | admin |
123456 |
根 README 对应商家端仓库说明;账号记录在 mall4cloud_auth.sql、mall4cloud_multishop.sql |
如果登录失败,先确认导入的 auth、platform、multishop、rbac 库来自同一套脚本,不要混用其他版本数据。
验收
- MySQL 中存在
mall4cloud_auth、mall4cloud_rbac、mall4cloud_product、mall4cloud_order等库。 mall4cloud_auth.auth_account中有平台端和商家端账号。mall4cloud_rbac.menu和mall4cloud_rbac.menu_permission中有菜单和按钮权限数据。- Nacos 中有
application.yml和mall4cloud-gateway.yml。
检查题
问题:为什么只导入 db/mall4cloud_product.sql 不能完成后台登录?
答案:登录至少还依赖 mall4cloud_auth、mall4cloud_rbac,平台端或商家端还依赖对应的 mall4cloud_platform 或 mall4cloud_multishop。
为什么:账号在 auth 库,菜单和权限在 rbac 库,登录后用户信息来自平台端或商家端业务库。
Doc 2 环境搭建 3 后端启动 (`doc/2-环境搭建/3-后端启动.md`)
后端启动
先跑“登录 + 权限 + 一个后台端”链路,不要一开始全量启动所有业务。
先启动中间件
至少需要:
- MySQL
- Redis
- Nacos
- MinIO
如果要验证商品搜索、订单搜索或商品发布后的索引同步,再启动 Elasticsearch、RocketMQ、Canal。
服务端口
| 服务 | 端口 |
|---|---|
mall4cloud-gateway |
8000 |
mall4cloud-leaf |
9100 |
mall4cloud-auth |
9101 |
mall4cloud-rbac |
9102 |
mall4cloud-multishop |
9103 |
mall4cloud-product |
9104 |
mall4cloud-user |
9105 |
mall4cloud-order |
9106 |
mall4cloud-search |
9108 |
mall4cloud-platform |
9112 |
mall4cloud-payment |
9113 |
mall4cloud-biz |
9000 |
这些端口来自各服务 bootstrap.yml 和网关 application.yml。
最小平台端链路
启动:
mall4cloud-gatewaymall4cloud-authmall4cloud-rbacmall4cloud-platformmall4cloud-biz
如果页面需要商品、店铺或订单数据,再启动对应服务。
最小商家端链路
启动:
mall4cloud-gatewaymall4cloud-authmall4cloud-rbacmall4cloud-multishopmall4cloud-biz
商品管理页面还会需要 mall4cloud-product。
Nacos 地址
各服务默认从环境变量读取 Nacos:
NACOS_HOST,默认 192.168.1.46
NACOS_PORT,默认 8848本地开发时,如果 Nacos 不在 192.168.1.46,请设置环境变量或修改启动配置。还要注意:当前服务 bootstrap 中 Nacos 用户名/密码默认写的是 nacos/nacos;如果使用本仓库 Compose 初始化 SQL,Nacos 用户表写入的是 nacos / 80jpnH4.r5g,两边必须统一。
开发机资源
一次在 IDEA 中启动多个微服务会比较吃内存。当前项目使用 JDK 17,如果本机内存紧张,优先只启动最小链路服务,并给单个服务配置类似 -Xms512m -Xmx512m -Xss256k 的启动参数。
不要无脑全仓替换 192.168.1.46。更稳妥的做法是重点核对 bootstrap、Nacos 配置、Compose、Canal、Seata、RocketMQ 和前端 .env.* 中的示例地址。
验收
- 网关日志显示服务启动在
8000。 - 服务能注册到 Nacos。
- 访问
http://<网关IP>:8000/mall4cloud_rbac/menu/route时,如果未登录返回未授权,说明路由到了后端。 - 登录成功后,前端能获取菜单。
检查题
问题:前端请求应该直连 mall4cloud-rbac:9102 吗?
答案:不应该,管理后台应请求网关 8000。
为什么:Nacos 中 mall4cloud-gateway.yml 配置了 /mall4cloud_rbac/** 等路由,前端只需要配置网关地址。
Doc 2 环境搭建 4 管理后台启动 (`doc/2-环境搭建/4-管理后台启动.md`)
管理后台启动
平台端和商家端都是 Vite 工程,命令和环境变量以当前 package.json、.env.* 为准。
安装依赖
平台端:
cd front-end/mall4cloud-platform
pnpm install
pnpm dev商家端:
cd front-end/mall4cloud-multishop
pnpm install
pnpm dev当前 Vite dev server 端口是 9527。如果两个后台同时启动,第二个需要手动换端口或按 Vite 提示处理。
关键环境变量
.env.development 和 .env.production 使用:
VITE_APP_BASE_API
VITE_APP_RESOURCES_URL
VITE_APP_RESOURCES_TYPE本地常见配置:
VITE_APP_BASE_API = 'http://<网关IP>:8000'
VITE_APP_RESOURCES_URL = 'http://<MinIO-IP>:9000/mall4cloud'
VITE_APP_RESOURCES_TYPE = '1'不要使用 VUE_APP_*,当前后台只读取 VITE_APP_*。
登录
默认账号参考 数据库初始化:
- 平台端:
admin / 123456 - 商家端:
admin / 123456
登录失败先看浏览器 Network:
- 请求是否发到
VITE_APP_BASE_API。 - 是否返回
A00004未授权。 - 是否跨域失败。
- auth、rbac、platform/multishop 服务是否已启动。
检查题
问题:图片能上传但前端显示 404,先改哪个配置?
答案:先核对 VITE_APP_RESOURCES_URL 和 Nacos 中 biz.oss.resources-url 是否都指向 http://<MinIO-IP>:9000/mall4cloud。
为什么:上传和展示使用的资源域名必须和 MinIO 桶地址一致,后台返回的是对象路径,前端需要拼接正确资源地址。
Doc 2 环境搭建 5 移动端接口地址 (`doc/2-环境搭建/5-移动端接口地址.md`)
移动端接口地址
本页只说明 uni-app 用户端如何接后端,不展开移动端源码结构。
当前范围
front-end/mall4cloud-uniapp 是用户端工程。新维护者先确保后端网关和管理后台可用,再处理移动端。
要核对什么
- 网关地址:应指向
http://<网关IP>:8000。 - 图片资源地址:应指向
http://<MinIO-IP>:9000/mall4cloud。 - H5、小程序、App 构建模式下的接口地址是否分别配置。
为什么不先看移动端源码
先跑通网关、登录、权限和管理后台,再处理移动端。移动端涉及发布平台、运行时权限、端侧兼容和页面业务,不适合作为第一批启动任务。
检查题
问题:后台管理端没跑通时,是否应该先调 uni-app 页面?
答案:不要。
为什么:后台登录、权限、网关、数据库、中间件是基础链路。基础链路没通时,移动端错误会混入更多端侧变量,排查成本更高。
Doc 3 技术框架 1 后端分层与模块 (`doc/3-技术框架/1-后端分层与模块.md`)
后端分层与模块
Mall4cloud 后端是多模块 Maven 工程。二开时优先沿用现有分层,不要为了一个功能引入新架构。
常见分层
| 层 | 常见目录 | 职责 |
|---|---|---|
| Controller | controller |
接收 HTTP 请求、做参数校验、调用 Service、返回 ServerResponseEntity |
| DTO | dto |
前端传入参数 |
| VO | vo |
返回给前端的数据 |
| Service | service、service/impl |
业务编排、事务边界、跨服务调用 |
| Mapper | mapper |
MyBatis 数据访问接口 |
| XML | resources/mapper |
SQL |
| Model | model |
与数据库表结构对应 |
| FeignClient | mall4cloud-api-* |
服务间调用契约 |
| Common | mall4cloud-common-* |
公共响应、异常、分页、缓存、安全、消息等能力 |
一个后台列表请求怎么走
以常见列表页为例:
- 前端页面调用
src/api/**中的方法。 - 请求进入网关
mall4cloud-gateway:8000。 - 网关按 Nacos 路由转发到对应服务。
- Controller 接收
PageDTO和搜索条件。 - Service 调 Mapper 查询。
PageUtil.doPage生成PageVO。- Controller 返回
ServerResponseEntity.success(pageVO)。
Feign 的位置
跨服务调用不要直接拼 URL。项目把内部接口放在 mall4cloud-api 下,例如商品库存锁定、用户信息、权限校验等。服务实现方实现对应 Feign 接口,调用方只依赖 API 模块。
新功能落点
- 后台 CRUD 功能优先找同业务域已有的
HotSearch、IndexImg、Attr、Category模式。 - 需要跨服务时,先判断是否已有
mall4cloud-api-*接口;没有再补接口契约。 - 需要事务跨服务时,参考已有
@GlobalTransactional用法,不要只加本地事务。
检查题
问题:新增后台表单时,前端传来的对象应该直接用 Model 接收吗?
答案:不要,优先使用 DTO。
为什么:当前项目用 DTO 承接前端输入,用 Model 对应数据库表,用 VO 返回前端。直接暴露 Model 容易把数据库字段和接口契约绑死。
Doc 3 技术框架 2 前端工程与动态路由 (`doc/3-技术框架/2-前端工程与动态路由.md`)
前端工程与动态路由
平台端和商家端是 Vue 3 + Vite + Pinia + Element Plus,环境变量使用 VITE_APP_*。
关键目录
| 目录 | 用途 |
|---|---|
src/api |
后端接口封装 |
src/views/modules |
后台业务页面 |
src/router |
基础静态路由 |
src/stores/modules/user.js |
登录用户、权限列表、菜单 ID |
src/stores/modules/permission.js |
动态路由生成 |
src/directive/permission |
v-permission 按钮权限 |
src/directive/rich |
富文本展示前的 DOMPurify 清洗 |
.env.* |
VITE_APP_* 环境变量 |
动态菜单怎么来
登录后,src/permission.js 执行:
getUserInfo()获取用户信息和是否管理员。listPermissions()获取按钮权限编码。- 非管理员调用
listMenuIds()获取可见菜单 ID。 permissionStore.generateRoutes(menuIds)调/mall4cloud_rbac/menu/route获取菜单路由。component为Layout时加载布局,否则从src/views/modules下按路径加载页面。
后台菜单的 component 字段必须和页面路径对应。例如 product/category 会加载 src/views/modules/product/category/index.vue。
按钮权限怎么来
页面按钮使用:
v-permission="['product:category:save']"用户登录后,前端把 /mall4cloud_rbac/menu_permission/list 返回的权限编码放到 roles。v-permission 指令判断当前用户是否有对应编码,没有就移除按钮。管理员直接放行。
检查题
问题:新增菜单后,页面文件存在但点击菜单空白,最可能先查什么?
答案:先查 menu.component 是否能映射到 src/views/modules/<component>/index.vue 或 src/views/modules/<component>.vue。
为什么:动态路由通过 import.meta.glob('../../views/modules/**/**.vue') 加载页面,路径对不上就没有组件。
Doc 4 技术实现 1 登录认证与权限链路 (`doc/4-技术实现/1-登录认证与权限链路.md`)
登录认证与权限链路
权限链路分三层:登录 Token、菜单可见性、按钮/接口权限。二开后台功能时三层都要考虑。
登录 Token
- 前端登录调用 auth 服务。
mall4cloud-auth校验账号密码后,通过TokenStore.storeAndGetVo生成 access token 和 refresh token,并把用户信息写入 Redis。- 前端后续请求在
Authorization请求头带 token。 - 业务服务里的
AuthFilter调TokenFeignClient.checkToken(accessToken)校验 token。 - 校验成功后,用户信息放入
AuthUserContext。
Token 相关的当前入口:
| 入口 | 作用 |
|---|---|
LoginController /ua/login |
登录后清理权限缓存,并返回 token |
TokenStore |
保存、刷新、删除、解析 token |
TokenFeignController |
提供内部 checkToken 校验 |
AuthFilter |
每个业务请求进入服务后的 token 和权限校验 |
不需要登录的路径由 AuthConfigAdapter.excludePathPatterns 控制。默认放行:
/v3/api-docs- 内部 Feign 路径
/**/ua/**
菜单权限
菜单数据在 mall4cloud_rbac.menu。关键字段:
| 字段 | 用途 |
|---|---|
menu_id |
菜单 ID |
parent_id |
父菜单 |
biz_type |
1 商家端,2 平台端 |
path |
前端路由路径 |
component |
前端页面组件路径 |
title、icon |
侧边栏展示 |
非管理员登录后,前端用 /mall4cloud_rbac/menu/list_menu_ids 获取可见菜单 ID,再过滤 /mall4cloud_rbac/menu/route 返回的菜单。
按钮权限
按钮权限数据在 mall4cloud_rbac.menu_permission。关键字段:
| 字段 | 用途 |
|---|---|
menu_id |
归属菜单 |
permission |
前端按钮权限编码 |
uri |
后端接口 URI |
method |
请求方法:1 GET、2 POST、3 PUT、4 DELETE |
biz_type |
商家端或平台端 |
角色授权通过 role_menu 关联菜单和按钮权限,用户通过 user_role 关联角色。
后端接口权限
AuthFilter 对平台端和商家端用户会调用 PermissionFeignClient.checkPermission。当前 AuthConfigAdapter 没有全局 needRbac() 开关;是否进入 RBAC 校验由用户 sysType 决定,平台端和商家端会校验,普通用户端直接放行 RBAC。
mall4cloud-rbac 中的实现会:
- 查询用户拥有的权限编码。
- 查询当前端所有
uri + method -> permission映射。 - 用
AntPathMatcher匹配请求 URI 和方法。 - 如果接口匹配到权限要求,用户必须拥有该权限;如果没有匹配到权限要求,则放行。
这意味着:只加前端按钮权限不够,后端接口权限也要能对应上。
新增页面/按钮时要做什么
| 要新增 | 必做 |
|---|---|
| 页面菜单 | 新增 menu,component 对应前端页面路径 |
| 新增按钮 | 新增 menu_permission,编码与前端 v-permission 一致 |
| 接口保护 | menu_permission.uri 和 method 对上 Controller 路径和 HTTP 方法 |
| 给角色授权 | 在角色管理中勾选菜单和按钮权限 |
排错清单
| 现象 | 答案 |
|---|---|
| 菜单不显示 | 用户不是管理员时,先查角色是否勾选该菜单,list_menu_ids 是否返回该 menu_id。 |
| 按钮不显示 | 查 v-permission 编码是否在 /menu_permission/list 返回值里。 |
| 按钮显示但接口 401 | 查 menu_permission.uri、method 是否与真实请求匹配,角色是否拥有该按钮权限。 |
| 管理员可见,普通角色不可见 | 这是正常差异;管理员前端和后端都会走放行逻辑。 |
检查题
问题:新增删除按钮,只在 Vue 页面加 v-permission 是否足够?
答案:不够。
为什么:v-permission 只控制按钮显示,接口访问还要靠 menu_permission.uri + method 和角色授权通过后端 AuthFilter 校验。
Doc 4 技术实现 2 文件上传与富文本安全 (`doc/4-技术实现/2-文件上传与富文本安全.md`)
文件上传与富文本安全
当前文件上传主要由 mall4cloud-biz 的 OSS/MinIO 能力承接,富文本展示在前端通过 DOMPurify 做清洗。
MinIO 上传链路
核心类:
OssControllerOssConfigMinioTemplate
常见流程:
- 前端请求
/mall4cloud_biz/oss/info?fileNum=...获取上传地址。 - 后端根据
biz.oss.*配置创建 MinIO 预签名上传 URL。 - 前端上传到 MinIO。
- 前端展示图片时使用
VITE_APP_RESOURCES_URL拼接资源路径。
也存在 /oss/upload_minio 由后端接收文件再上传 MinIO 的接口。
两种方式的区别:/oss/info 是前端拿预签名地址后直传 MinIO,服务端不转发文件内容;/oss/upload_minio 是文件先进业务服务再写入 MinIO,会多占一次服务端流量,适合少量或需要后端介入处理的文件。
必须对齐的配置
| 配置 | 示例 |
|---|---|
Nacos biz.oss.endpoint |
http://<MinIO-IP>:9000 |
Nacos biz.oss.resources-url |
http://<MinIO-IP>:9000/mall4cloud |
Nacos biz.oss.bucket |
mall4cloud |
Nacos biz.oss.type |
1 表示 MinIO |
前端 VITE_APP_RESOURCES_URL |
http://<MinIO-IP>:9000/mall4cloud |
前端 VITE_APP_RESOURCES_TYPE |
1 |
Compose 初始化 SQL 中的 biz.oss.access-key-secret 是 80jpnH4.r5g,与 MINIO_ROOT_PASSWORD 一致。如果 Docker Compose 中 MinIO root 密码改了,Nacos 里的 biz.oss.access-key-secret 也要同步。
富文本安全
当前平台端和商家端有 src/directive/rich 指令,使用 DOMPurify.sanitize 后再写入 HTML。商品详情等富文本展示应使用 v-rich,不要直接 v-html 展示未清洗内容。
后端没有在本轮核对到统一 XSS 过滤器,因此不要把“后端已统一清洗所有输入”写进文档或作为安全假设。
检查题
问题:图片上传成功但页面不显示,是否一定是后端上传失败?
答案:不一定。
为什么:上传成功只说明对象写入了 MinIO。展示还依赖桶策略、resources-url、前端 VITE_APP_RESOURCES_URL 和对象路径拼接。
问题:富文本展示能直接用 v-html 吗?
答案:不要直接用,优先使用项目已有 v-rich。
为什么:v-rich 会先经过 DOMPurify 清洗,直接 v-html 会绕开当前前端安全处理。
Doc 4 技术实现 3 分页验证异常与事务 (`doc/4-技术实现/3-分页验证异常与事务.md`)
分页、验证、异常与事务
这几个机制是后台 CRUD 二开最常用的公共能力。
分页
核心类:
PageDTOPageVOPageUtil
Controller 通常接收 @Valid PageDTO pageDTO。PageDTO 要求 pageNum、pageSize 非空,并把最大 pageSize 限制为 500。排序字段会校验字段名,只允许字母、数字、下划线,再把驼峰转下划线。
Service 里常见写法是:
PageUtil.doPage(pageDTO, () -> mapper.list(...))返回给前端的是 PageVO:pages、total、list。
常用对象命名按当前代码理解:
| 名称 | 当前用法 |
|---|---|
Model/PO |
与数据库表结构对应,放在 model 目录 |
DTO |
前端传入参数,例如 PageDTO、SpuDTO |
VO |
返回给前端的数据,例如 PageVO |
BO |
服务内部或跨服务传递的业务对象 |
当前前端是 Vue 3,不使用 Vue 2 的 .sync 写法;页面交互以现有 Vue 3 页面和组件为准。
验证
DTO 字段使用 Jakarta Validation 注解,例如 @NotNull、@NotBlank。Controller 参数上加 @Valid 后,验证失败会进入统一异常处理。
统一异常
DefaultExceptionHandlerConfig 处理:
| 异常 | 返回 |
|---|---|
MethodArgumentNotValidException、BindException |
METHOD_ARGUMENT_NOT_VALID,并返回字段错误列表 |
HttpMessageNotReadableException |
HTTP_MESSAGE_NOT_READABLE |
Mall4cloudException |
使用异常自带枚举或直接显示消息 |
其他 Exception |
EXCEPTION,并在存在 Seata XID 时尝试回滚全局事务 |
项目约定:请求到达服务并被业务处理后,大多数失败也返回 HTTP 200,前端按业务 code 判断。
分布式事务
跨服务写操作参考已有 @GlobalTransactional。典型位置包括订单、商品、平台用户、商家用户等服务。不要只在本地方法上加事务就认为跨服务一致性已经解决。
Redis 锁
公共缓存模块提供 RedisLockRegistry,锁前缀为 spring-cloud。需要并发控制时优先看是否已有业务模式可复用。
检查题
问题:列表接口返回值应该是裸 List<T> 还是 PageVO<T>?
答案:后台分页列表应该返回 PageVO<T>。
为什么:当前分页公共模型包含 pages、total、list,前端分页组件依赖这些字段。
问题:pageSize=10000 会照单全查吗?
答案:不会按 10000 查,PageDTO 会把超过 500 的分页大小限制为 500。
为什么:PageDTO.setPageSize 中有 MAX_PAGE_SIZE = 500 的保护。
Doc 4 技术实现 4 消息搜索与库存链路 (`doc/4-技术实现/4-消息搜索与库存链路.md`)
消息、搜索与库存链路
这部分用于理解消息、搜索和库存协作,先阅读再改造。
RocketMQ
当前代码中可见的消息用途包括:
- 订单取消后解锁库存。
- 支付通知后触发订单和库存后续处理。
- Canal 变更消息驱动搜索索引更新。
注意:提交订单时的初次库存锁定不是 RocketMQ 触发,而是订单服务通过 SkuStockLockFeignClient.lock 调商品服务完成。RocketMQ 主要负责延迟取消、延迟解锁和支付成功后的后续通知。
相关入口:
mall4cloud-order的 RocketMQ 配置和订单监听器。mall4cloud-product的库存锁定和解锁监听器。mall4cloud-search的 Canal 监听器。
Elasticsearch
搜索服务依赖 Elasticsearch。索引 mapping 在仓库根目录:
商品发布后列表或搜索没有数据时,不要只看商品库,还要检查 Canal、RocketMQ、Elasticsearch 三段是否正常。
Canal 当前监听配置在中间件目录的 canal/conf 下:instance.properties 指向 MySQL binlog,canal.properties 指向 RocketMQ namesrv,topic 是 canal-topic。搜索服务通过 CanalListener 消费 RocketMqConstant.CANAL_TOPIC,再分发到商品、店铺、分类、品牌、订单等监听器。
不要用 update mall4cloud_product set update_time = now() 触发同步;当前表结构没有这个表名。需要按 canal.instance.filter.regex 里的表名触发,例如 spu、sku、sku_stock、order 等。
库存锁定
核心表:
sku_stocksku_stock_lock
下单链路会涉及订单服务和商品服务协作。sku_stock_lock 通过 spu_id + sku_id + order_id 保证同一订单同一 SKU 的锁定记录唯一。
检查题
问题:商品库里有商品,但搜索列表没有数据,最可能只查 MySQL 吗?
答案:不够。
为什么:搜索列表依赖 Elasticsearch 索引,索引更新又可能依赖 Canal 和 RocketMQ。MySQL 有数据只能证明源数据存在。
问题:为什么不要第一个二开功能就选择库存扣减?
答案:因为它横跨订单、商品、消息、事务和库存锁定,风险高。
为什么:学习分层时应先选后台 CRUD,避免一开始就碰交易一致性。
Doc 5 二次开发 1 后台管理功能二开示例 (`doc/5-二次开发/1-后台管理功能二开示例.md`)
后台管理功能二开示例
本示例选择“平台公告管理”作为学习题材。它是后台 CRUD,不直接触碰订单、支付、库存、结算。本页只写教程和检查清单,不在仓库中新增业务代码。
目标
做一个平台端公告管理:
- 列表查询公告。
- 新增公告。
- 编辑公告。
- 删除或禁用公告。
- 平台端菜单可见。
- 普通角色只有授权后才能看到按钮和访问接口。
后端步骤
| 步骤 | 应该做什么 | 验收 |
|---|---|---|
| 建表 | 在平台业务库新增公告表,包含主键、标题、内容、状态、排序、创建/更新时间 | 表能初始化,字段含义明确 |
| Model | 新增与表对应的 Model | 字段类型和数据库一致 |
| DTO | 新增保存/更新入参 DTO | 必填字段有验证注解 |
| VO | 新增列表和详情返回 VO | 不把不需要的内部字段暴露给前端 |
| Mapper/XML | 写分页列表、详情、新增、更新、删除或改状态 SQL | SQL 字段名和表字段一致 |
| Service | 封装业务逻辑 | Controller 不直接写 SQL |
| Controller | 提供 page、get、save、update、delete 接口 | 返回 ServerResponseEntity |
| 分页 | 列表使用 PageDTO 和 PageVO |
前端能拿到 total 和 list |
接口路径放在平台端语义下,例如 /platform/notice,或采用现有平台模块风格。落地前先参考 HotSearchController、IndexImgController、SysUserController 等后台接口。
前端步骤
| 步骤 | 应该做什么 | 验收 |
|---|---|---|
| API | 在 src/api 下新增公告接口文件 |
请求都走网关前缀 |
| 列表页 | 在 src/views/modules/platform/notice 下新增页面 |
能查询、分页、重置 |
| 表单弹窗 | 新增或复用 add-or-update 组件 | 新增和编辑共用校验 |
| 按钮权限 | 新增、编辑、删除按钮加 v-permission |
无权限用户按钮不可见 |
| 环境变量 | 不新增 VUE_APP_* |
仍使用 VITE_APP_BASE_API |
菜单和按钮权限
需要在 rbac 中配置:
| 类型 | 示例 |
|---|---|
| 菜单 | menu.path = notice,menu.component = platform/notice |
| 新增按钮 | platform:notice:save,POST /platform/notice |
| 编辑按钮 | platform:notice:update,PUT /platform/notice |
| 删除按钮 | platform:notice:delete,DELETE /platform/notice |
编码只是示例,落地命名要和现有平台端权限风格保持一致。
验收清单
- 平台管理员能看到公告菜单。
- 普通角色未授权时看不到菜单。
- 普通角色授权菜单后能看到菜单。
- 未授权按钮权限时,新增/编辑/删除按钮不显示。
- 直接请求未授权接口会被后端拒绝。
- 列表分页返回
PageVO。 - 表单必填项缺失时返回统一验证错误。
检查题
问题:这个示例为什么选公告管理,而不是订单退款?
答案:公告管理是后台 CRUD,能覆盖分层、分页、表单、菜单和按钮权限;订单退款涉及交易一致性,不适合作为第一课。
为什么:学习的目标是先掌握项目模式,再进入高风险业务。
Doc 5 二次开发 2 命名约定与验收清单 (`doc/5-二次开发/2-命名约定与验收清单.md`)
命名约定与验收清单
新功能要像项目原生功能,而不是单独长出来的一套风格。
命名约定
| 对象 | 约定 |
|---|---|
| 数据库表 | 下划线命名,如 notice、notice_item |
| 主键 | xxx_id 或同业务已有风格 |
| Java 类 | NoticeController、NoticeService、NoticeMapper、NoticeDTO、NoticeVO |
| 前端目录 | 放到 src/views/modules/<业务域>/<功能> |
| API 文件 | 放到 src/api/<业务域> |
| 权限编码 | <业务域>:<功能>:<动作> |
| 接口路径 | 跟当前 Controller 风格一致,不混用多个前缀 |
后端验收
- Controller 返回
ServerResponseEntity。 - 新增/更新入参使用 DTO,并对必填字段加验证。
- 列表使用
PageDTO、PageVO。 - Service 负责业务编排,Mapper 只做数据访问。
- 涉及跨服务写操作时评估是否需要
@GlobalTransactional。 - 接口路径和 HTTP 方法能与
menu_permission对上。
前端验收
- 请求走
VITE_APP_BASE_API指向网关。 - 页面路径能被
menu.component动态加载。 - 按钮使用
v-permission。 - 列表、表单、删除确认、加载态、错误提示与现有页面风格一致。
- 不新增
VUE_APP_*或 Vue 2/Vue CLI 配置。
权限验收
- 管理员可见全部菜单和按钮。
- 普通角色只在授权后可见菜单。
- 普通角色只在授权后可见按钮。
- 直接调用未授权接口也不能成功。
检查题
问题:权限编码写成 notice:add 可以吗?
答案:不要,除非当前业务域已有这种风格。
为什么:项目现有编码多是 <业务域>:<功能>:<动作>,例如 product:category:save。统一风格方便维护和排查。
Doc 6 核心业务 1 商品订单库存阅读路线 (`doc/6-核心业务/1-商品订单库存阅读路线.md`)
商品、订单、库存阅读路线
核心业务先读请求链路,不急着改交易逻辑。
商品
从 mall4cloud-product 开始:
- 分类和品牌决定商品基础归属。
spu保存商品主信息。sku保存具体规格和价格。sku_stock保存库存。- 商品搜索还会进入
mall4cloud-search和 Elasticsearch。
订单
从 mall4cloud-order 开始:
/a/order/confirm根据立即购买或购物车结算组装购物项,按店铺拆分并计算金额,同时把确认结果和防重复提交标记写入 Redis。/a/order/submit从缓存取确认结果,校验未过期且未重复提交后保存订单、订单项和收货地址快照。- 提交订单后通过
SkuStockLockFeignClient.lock锁定库存,并发送ORDER_CANCEL_TOPIC延迟消息;CANCEL_ORDER_DELAY_LEVEL = 16,对应 RocketMQ 30 分钟延迟级别。 sku_stock_lock保存锁定记录,商品服务还会发送比取消订单晚一级的库存解锁延迟消息。- 支付入口是
/mall4cloud_payment/pay/order。当前代码会创建pay_info,再直接调用PayNoticeController.submit模拟支付成功,然后通过ORDER_NOTIFY_TOPIC通知订单服务、通过ORDER_NOTIFY_STOCK_TOPIC通知商品服务扣减实际库存。
这里有一个代码风险:PayController 里仍硬编码了 http://192.168.1.17:8126/mall4cloud_payment 作为回调前缀,Nacos 里也存在 application.domainUrl 配置项。接入第三方支付前,要先把回调域名配置收口,不能直接当成生产可用配置。
库存
库存不是简单减字段。当前项目有 sku_stock_lock 锁定记录,订单、商品服务、RocketMQ、Seata 都可能参与。
检查题
问题:学习二开时,为什么不先改订单状态流?
答案:订单状态流牵涉支付、库存、消息和事务,风险比普通后台配置功能高很多。
为什么:一个状态字段变化可能要求多个服务和多张表保持一致,适合作为后续专题,不适合作为第一天练习。
Doc 7 数据模型 1 数据库阅读路线 (`doc/7-数据模型/1-数据库阅读路线.md`)
数据库阅读路线
读数据库不要从所有表平铺开始。先读能解释“登录、菜单、商品、订单”的表。
第一步:登录和权限
先读:
mall4cloud_auth.auth_accountmall4cloud_rbac.menumall4cloud_rbac.menu_permissionmall4cloud_rbac.rolemall4cloud_rbac.role_menumall4cloud_rbac.user_rolemall4cloud_platform.sys_usermall4cloud_multishop.shop_user
这组表能解释:谁登录、属于平台还是商家、看见哪些菜单、拥有哪些按钮权限。
第二步:商品和 SKU
再读:
mall4cloud_product.spumall4cloud_product.skumall4cloud_product.sku_stockmall4cloud_product.sku_stock_lockmall4cloud_product.spu_attr_valuemall4cloud_product.spu_sku_attr_valuemall4cloud_product.categorymall4cloud_product.brand
这组表能解释:商品主信息、具体 SKU、库存、销售属性、分类和品牌。
第三步:订单
再读:
mall4cloud_order.ordermall4cloud_order.order_itemmall4cloud_order.order_addr
这组表能解释:订单头、订单明细和收货地址快照。
第四步:二开建表习惯
新表优先沿用这些习惯:
- 主键使用
bigint,字段名用下划线。 - 常见字段包含
create_time、update_time。 - 多端或多店铺数据要考虑
shop_id、tenant_id、user_id。 - 状态字段要明确枚举值,例如
1:enable, 0:disable, -1:deleted。 - 软删除不是全表统一字段,需先看同业务域已有表如何处理。
- Seata 参与的库有
undo_log。
检查题
问题:为什么权限表应该先读,而不是最后读?
答案:后台二开离不开菜单、按钮和接口权限,权限表决定新页面能不能被看见、按钮能不能显示、接口能不能访问。
为什么:前端动态路由、v-permission、后端 AuthFilter 都依赖 rbac 表。
Doc 7 数据模型 2 权限商品订单核心表 (`doc/7-数据模型/2-权限商品订单核心表.md`)
权限、商品、订单核心表速查
本页只讲启动和二开最常用的表。
权限表
| 表 | 作用 | 关键字段 |
|---|---|---|
auth_account |
统一账号 | username、password、sys_type、user_id、tenant_id、is_admin |
menu |
后台菜单和动态路由 | menu_id、parent_id、biz_type、path、component |
menu_permission |
按钮和接口权限 | permission、uri、method、menu_id、biz_type |
role |
角色 | role_id、biz_type、tenant_id |
role_menu |
角色拥有的菜单和按钮 | role_id、menu_id、menu_permission_id |
user_role |
用户拥有的角色 | user_id、role_id |
sys_type 和 biz_type 的常见含义:1 商家端,2 平台端。
商品表
| 表 | 作用 | 关键字段 |
|---|---|---|
spu |
商品主信息 | spu_id、brand_id、category_id、shop_id、name、status |
sku |
具体销售 SKU | sku_id、spu_id、sku_name、attrs、price_fee、status |
sku_stock |
SKU 库存 | sku_id、actual_stock、lock_stock、stock |
sku_stock_lock |
下单库存锁定 | spu_id、sku_id、order_id、status、count |
spu_detail |
商品详情 | spu_id、detail |
spu_sku_attr_value |
SKU 销售属性 | spu_id、sku_id、attr_name、attr_value_name |
价格字段如 price_fee 用整数保存,二开时不要随意改成浮点金额。
订单表
| 表 | 作用 | 关键字段 |
|---|---|---|
order |
订单主表 | order_id、shop_id、user_id、total、status、is_payed |
order_item |
订单商品明细 | order_id、spu_id、sku_id、count、price、spu_total_amount |
order_addr |
收货地址快照 | order_addr_id、user_id、consignee、mobile、addr |
pay_info |
支付记录 | pay_id、user_id、pay_amount、pay_status、order_ids、version |
订单状态当前 SQL 注释中说明:1 待付款,2 待发货,3 待收货,5 成功,6 失败。
订单主表中以下字段在读订单状态时需要一起看:
| 字段 | 含义 |
|---|---|
close_type |
订单关闭原因,SQL 注释含 1 超时未支付、4 买家取消、15 货到付款交易 |
delete_status |
用户侧删除状态:0 未删除、1 回收站、2 永久删除 |
version |
订单版本号,SQL 注释为每处理一次订单版本号加一 |
order_addr_id |
指向 order_addr,保存下单时的收货地址快照 |
关系速记
- 一个账号
auth_account通过sys_type + user_id指向平台用户或商家用户。 - 一个用户通过
user_role拥有多个角色。 - 一个角色通过
role_menu拥有菜单和按钮权限。 - 一个商品
spu有多个sku,每个sku对应库存。 - 一个订单
order有多个order_item,每个明细记录当时的spu_id、sku_id、价格和数量。 - 一个订单保存一个
order_addr_id,避免用户后续修改地址影响已下单记录展示。
检查题
问题:前端按钮权限编码应该去哪个表找?
答案:mall4cloud_rbac.menu_permission.permission。
为什么:前端 v-permission 使用的就是这个编码,后端接口权限也用它匹配用户权限。
Doc 7 数据模型 3 带答案的表结构检查题 (`doc/7-数据模型/3-带答案的表结构检查题.md`)
带答案的表结构检查题
这些题不是考试,是帮助读者确认自己已经读懂关键关系。
权限
问题:一个普通平台用户登录后,为什么可能看不到某个菜单?
答案:因为用户不是管理员时,前端会根据 /menu/list_menu_ids 返回的菜单 ID 过滤动态路由;如果角色没有关联该菜单,菜单就不会显示。
为什么:用户通过 user_role 找到角色,角色通过 role_menu.menu_id 拥有菜单,前端再用这些菜单 ID 过滤 menu 路由。
问题:按钮显示和接口放行是不是同一件事?
答案:不是。
为什么:按钮显示由前端 v-permission 判断 menu_permission.permission;接口放行由后端根据 menu_permission.uri + method 和用户权限判断。
商品
问题:SPU 和 SKU 的区别是什么?
答案:SPU 是商品主信息,SKU 是具体可销售规格。
为什么:spu 保存商品名称、店铺、分类、上下架状态;sku 保存 spu_id、规格属性、价格和 SKU 状态。
问题:库存为什么不只放在 sku 表?
答案:库存独立放在 sku_stock,锁定记录放在 sku_stock_lock。
为什么:库存会被下单、取消、支付等链路频繁改变,独立表和锁定表便于处理可售库存、实际库存、锁定库存和订单锁定记录。
订单
问题:订单明细为什么要保存商品名称、SKU 名称和价格?
答案:因为订单需要保留下单时的商品快照。
为什么:商品后续可能改名、改价或下架,order_item 仍要展示和结算下单时的信息。
问题:订单表里的 total 和订单项里的 spu_total_amount 可以直接改成小数吗?
答案:不要。
为什么:当前金额字段以整数保存,随意改成小数会影响支付、结算、前后端展示和已有数据。
二开
问题:新增“公告管理”表是否一定要有 shop_id?
答案:不一定,要看公告是平台全局还是店铺独立。
为什么:平台全局公告可以归平台端管理;店铺独立公告才需要 shop_id 或租户维度。建表前先明确数据归属。
问题:新表一定要有 undo_log 吗?
答案:新业务表本身不需要 undo_log 字段;参与 Seata 分布式事务的数据库需要有独立的 undo_log 表。
为什么:undo_log 是 Seata AT 模式使用的事务回滚表,不是每张业务表的字段。
Doc 8 部署运维 1 部署路径与上线检查 (`doc/8-部署运维/1-部署路径与上线检查.md`)
部署路径与上线检查
部署前先区分三种路径。
路径一:本地开发
适合二开:
- 本地或服务器启动中间件。
- IDEA 启动后端服务。
pnpm dev启动平台端或商家端。- 前端
VITE_APP_BASE_API指向网关8000。
路径二:单机服务器中间件 + 本地代码
适合团队共享中间件:
- 服务器用 中间件 Docker Compose 启动 MySQL、Redis、Nacos 等。
- 本地服务通过
NACOS_HOST指向服务器。 - 前端资源地址指向服务器 MinIO。
路径三:生产部署
生产部署需要额外确认:
- Nacos、Redis、MySQL、MinIO、RocketMQ、Elasticsearch 不应直接暴露公网。
- RocketMQ dashboard 当前未配置登录保护,不能裸露。
- 前端构建后由 Nginx 提供静态资源。
- 前端 API 地址要指向生产网关域名。
- MinIO 桶策略和资源域名要按生产安全要求配置。
Nginx 注意点
平台端和商家端当前仓库内的 nginx.conf 只配置了静态资源根目录,没有代理后端 API。生产环境更常见做法是:
- 静态资源由 Nginx 服务。
- API 通过
VITE_APP_BASE_API指向网关域名。 - 或在外层 Nginx 单独配置 API 反向代理。
不要假设前端工程里的 Nginx 配置已经覆盖生产代理。
上线检查
| 检查项 | 正确结果 |
|---|---|
| 网关 | 8000 或生产域名可访问 |
| Nacos | 服务已注册,配置可读取 |
| MySQL | 业务库、Nacos 库、Seata 库存在 |
| Redis | 密码和 Nacos 配置一致 |
| MinIO | 桶存在,资源地址可访问 |
| 前端 | VITE_APP_BASE_API 指向网关 |
| 登录 | 平台端或商家端能登录 |
| 权限 | 普通角色权限符合预期 |
| 日志 | 后端错误能在对应服务日志中定位 |
检查题
问题:生产环境只改前端 .env.production 就够了吗?
答案:不够。
为什么:还要核对 Nacos 中数据源、Redis、OSS、RocketMQ、Seata、网关路由,以及中间件自身的网络和安全暴露。
Doc 8 部署运维 3 已知风险与待核对项 (`doc/8-部署运维/3-已知风险与待核对项.md`)
已知风险与待核对项
这页记录不能直接按生产配置使用的内容。
已知风险
| 风险 | 当前处理 |
|---|---|
| Docker 安装教程过于通用 | 本文不展开,按 Docker 官方文档安装 |
| 部分截图可能和当前 UI 不完全一致 | 只作为操作界面参考,不作为验证依据 |
| 前端环境变量 | 当前必须使用 VITE_APP_* |
| RocketMQ dashboard 未配置登录保护 | 生产环境不要公网暴露 |
| Seata 控制台 | 当前 Seata 2.6 compose 只使用 8091 |
| Nacos 默认账号 | 本目录初始化 SQL 写入 nacos / 80jpnH4.r5g,而部分服务 bootstrap 默认值仍写着 nacos/nacos;如果启用 Nacos 鉴权,必须把两边统一 |
| 搜索同步 SQL | update mall4cloud_product set update_time = now()、update mall4cloud_order set update_time = now() 不匹配当前表名,不能照搬 |
| 支付回调地址 | PayController 当前仍硬编码网关地址,支付专题前不能把它写成生产可用配置 |
当前未展开的内容
- 移动端/小程序源码结构。
- 订单退款、支付、结算、库存扣减的二开教程。
- 生产级高可用部署。
- 商业授权和企业版本差异的技术交付细节。
这些内容需要单独设计和验证,不放在启动文档里。
检查题
问题:未经验证的命令,可以直接照搬吗?
答案:不可以。
为什么:当前项目使用 Spring Boot 4、Vue 3、Vite、pnpm,命令必须和当前仓库配置一致。
Doc 9 故障排查 1 启动登录接口常见问题 (`doc/9-故障排查/1-启动登录接口常见问题.md`)
启动、登录、接口常见问题
先按现象排查,不要一上来改代码。
服务连不上 Nacos
答案:先核对 NACOS_HOST、NACOS_PORT,再看 Nacos 容器、控制台和客户端端口。
为什么:各服务默认 Nacos 地址是 ${NACOS_HOST:192.168.1.46}:${NACOS_PORT:8848},如果你的环境不是这个 IP,就要改环境变量或启动配置。当前 Compose 的 Nacos v3 控制台是 8080,服务客户端主要看 8848,同时要放开 9848、9849。
排查顺序:
- 在服务器执行
docker ps -a,确认mall4cloud-nacos没有反复重启。 - 用
docker logs -f mall4cloud-nacos看是否 MySQL 连接、账号或初始化库错误。 - 打开
http://:8080/index.html,确认能登录控制台。 - 在配置列表里确认
application.yml、mall4cloud-gateway.yml等配置存在。 - 如果 Nacos 配置已改但服务仍读到缓存地址,重启 Nacos 容器后再重启 Java 服务。
前端登录请求 404
答案:先核对 VITE_APP_BASE_API 是否指向网关 8000,不是某个业务服务端口。
为什么:前端接口带 /mall4cloud_auth、/mall4cloud_rbac 等前缀,网关负责按前缀转发。
前端请求 503
答案:先查网关路由目标服务是否启动并注册到 Nacos。
为什么:503 常见于网关能收到请求,但后面的 auth、rbac、platform、multishop、biz 等服务没有可用实例。
前端登录返回未授权
答案:检查账号密码、auth 服务、Redis、数据库初始化是否一致。
为什么:登录依赖 mall4cloud_auth.auth_account,Token 校验依赖 auth 服务和 Redis。
滑动验证码加载或校验失败
答案:先用浏览器 F12 的 Network 看验证码接口请求,再查 Redis。
为什么:验证码校验依赖 Redis。Redis 未启动、密码不一致,或 Nacos application.yml 中 Redis 地址仍指向错误 IP,都会导致验证码正常显示但校验失败。
登录后菜单不显示
答案:先判断用户是否管理员;非管理员再查角色是否拥有菜单。
为什么:非管理员会通过 list_menu_ids 获取菜单 ID,前端只显示这些 ID 对应的路由。
按钮不显示
答案:查按钮上的 v-permission 编码是否存在于用户权限列表。
为什么:前端 src/directive/permission 会从用户 store 的 roles 里查编码,没有就移除按钮。
接口 401 或权限失败
答案:查 Authorization 请求头、Token 是否过期、menu_permission.uri 和 method 是否匹配。
为什么:后端 AuthFilter 先校验 Token,再校验平台端/商家端 RBAC 权限。
图片不显示
答案:核对 MinIO 桶、桶策略、Nacos biz.oss.resources-url、前端 VITE_APP_RESOURCES_URL。
为什么:上传、返回路径、前端拼接地址、桶读取权限任何一处错都会导致图片不可见。
商品发布后搜索不到
答案:除 MySQL 外,还要查 Canal、RocketMQ、Elasticsearch。
为什么:搜索列表依赖 ES 索引,索引更新链路不等于商品表写入成功。
排查顺序:
- MySQL 执行
SHOW MASTER STATUS,确认 binlog 可读。 - 检查
canal/conf/example/instance.properties中 MySQL 地址、mysql-binlog.*文件名、canal账号密码。 - 检查
canal/conf/canal.properties中rocketmq.namesrv.addr。 - 看
canal/logs/example/example.log是否还在报错。 - 看 RocketMQ dashboard 是否收到
canal-topic。 - 看
mall4cloud-search是否消费canal-topic,ES 中是否已创建product、ordermapping。
RocketMQ 无法发送 topic
答案:遇到 No route info of this topic: stock-unlock-topic,先查 RocketMQ broker 配置挂载和目录权限。
为什么:一种常见情况是 broker 没读到挂载的配置,导致 topic 路由不符合项目预期。当前中间件目录要求启动前给 rocketmq/ 目录足够权限。
Seata 连接失败
答案:先核对 seata/application.yml 的 MySQL 地址和 application.yml 中 seata.service.grouplist.default。
为什么:当前 Seata 2.6 compose 只暴露 8091,本仓库没有使用 7091 控制台配置。
检查题
问题:跨域报错时,第一反应是改业务 Controller 吗?
答案:不是,先查网关和前端 API 地址。
为什么:跨域主要发生在浏览器访问网关时,Nacos 中网关配置包含 CORS 规则,前端也必须请求正确网关地址。
Doc 8 部署运维 2 中间件 Docker Compose Docker Compose Native.Yaml (`doc/8-部署运维/2-中间件-docker-compose/docker-compose-native.yaml`)
version: "3.5"
services:
mall4cloud-mysql:
image: mysql:8.0
container_name: mall4cloud-mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=80jpnH4.r5g
network_mode: "host"
expose:
- 3306
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/initdb:/docker-entrypoint-initdb.d
mall4cloud-minio:
image: minio/minio:RELEASE.2024-04-18T19-09-19Z
container_name: mall4cloud-minio
restart: always
command: server /data --console-address ":9001"
network_mode: "host"
expose:
- 9000
- 9001
volumes:
- ./minio/data:/data
environment:
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=80jpnH4.r5g
- MINIO_BROWSER_REDIRECT_URL=http://192.168.1.46:9001
mall4cloud-redis:
image: redis:7.0
container_name: mall4cloud-redis
restart: always
network_mode: "host"
command: redis-server --requirepass 80jpnH4.r5g
expose:
- 6379
mall4cloud-nacos:
image: nacos/nacos-server:v3.1.1
container_name: mall4cloud-nacos
restart: always
depends_on:
- mall4cloud-mysql
network_mode: "host"
expose:
- 8848
- 9848
- 9849
- 8080
environment:
- JVM_XMS=256m
- JVM_XMX=256m
- MODE=standalone
- PREFER_HOST_MODE=hostname
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=192.168.1.46
- MYSQL_SERVICE_DB_NAME=mall4cloud_nacos
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=80jpnH4.r5g
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=TWFsbDRqTWFsbDRjbG91ZE1hbGw0ak1hbGw0Y2xvdWRNYWxsNGpNYWxsNGNsb3Vk
- NACOS_AUTH_IDENTITY_KEY=mall4jmall4jmall4jmall4jmall4jmall4jmall4jmall4j
- NACOS_AUTH_IDENTITY_VALUE=mall4cloudmall4cloudmall4cloudmall4cloudmall4cloudmall4cloudmall4cloud
volumes:
- ./nacos/logs:/home/nacos/logs
mall4cloud-seata:
image: apache/seata-server:2.6.0
container_name: mall4cloud-seata
restart: always
network_mode: "host"
expose:
- 8091
environment:
- TZ
- STORE_MODE=db
- SEATA_IP=192.168.1.46
- SEATA_PORT=8091
volumes:
- ./seata/application.yml:/seata-server/resources/application.yml
mall4cloud-elasticsearch:
image: elasticsearch:7.17.21
container_name: mall4cloud-elasticsearch
restart: always
network_mode: "host"
expose:
- 9200
- 9300
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
- ELASTICSEARCH_USERNAME=elastic
- ELASTIC_PASSWORD=80jpnH4.r5g
- xpack.security.enabled=true
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/data:/usr/share/elasticsearch/data
- ./elasticsearch/plugins:/usr/share/elasticsearch/plugins
mall4cloud-canal:
image: canal/canal-server:v1.1.7
container_name: mall4cloud-canal
restart: always
network_mode: "host"
expose:
- 11111
volumes:
- ./canal/conf/example:/home/admin/canal-server/conf/example
- ./canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties
- ./canal/logs:/home/admin/canal-server/logs
mall4cloud-rocketmq-namesrv:
image: apache/rocketmq:5.2.0
container_name: mall4cloud-rocketmq-namesrv
restart: always
network_mode: "host"
expose:
- 9876
volumes:
- ./rocketmq/namesrv/logs:/home/rocketmq/logs
- ./rocketmq/namesrv/store:/home/rocketmq/store
environment:
JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms512M -Xmx512M -Xmn128M"
command: ["sh","mqnamesrv"]
mall4cloud-rocketmq-broker:
image: apache/rocketmq:5.2.0
container_name: mall4cloud-rocketmq-broker
restart: always
network_mode: "host"
expose:
- 10909
- 10911
volumes:
- ./rocketmq/broker/logs:/home/rocketmq/logs
- ./rocketmq/broker/store:/home/rocketmq/store
- ./rocketmq/broker/conf/broker.conf:/etc/rocketmq/broker.conf
environment:
JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms512M -Xmx512M -Xmn128M -XX:-AssumeMP"
command: ["sh","mqbroker","-c","/etc/rocketmq/broker.conf","-n","192.168.1.46:9876","autoCreateTopicEnable=true"]
depends_on:
- mall4cloud-rocketmq-namesrv
mall4cloud-rocketmq-dashboard:
image: fsckzy01/rocketmq-dashboard:1.0.1
container_name: mall4cloud-rocketmq-dashboard
restart: always
ports:
- 8180:8082
environment:
JAVA_OPTS: "-Drocketmq.namesrv.addr=192.168.1.46:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
depends_on:
- mall4cloud-rocketmq-namesrv
Doc 8 部署运维 2 中间件 Docker Compose Docker Compose.Yaml (`doc/8-部署运维/2-中间件-docker-compose/docker-compose.yaml`)
version: "3.5"
services:
mall4cloud-mysql:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/mysql:8.0.35
container_name: mall4cloud-mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=80jpnH4.r5g
network_mode: "host"
expose:
- 3306
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/initdb:/docker-entrypoint-initdb.d
mall4cloud-minio:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/minio:RELEASE.2024-04-18T19-09-19Z
container_name: mall4cloud-minio
restart: always
command: server /data --console-address ":9001"
network_mode: "host"
expose:
- 9000
- 9001
volumes:
- ./minio/data:/data
environment:
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=80jpnH4.r5g
- MINIO_BROWSER_REDIRECT_URL=http://192.168.1.46:9001
mall4cloud-redis:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/redis:7.0
container_name: mall4cloud-redis
restart: always
network_mode: "host"
command: redis-server --requirepass 80jpnH4.r5g
expose:
- 6379
mall4cloud-nacos:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/nacos-server:v3.1.1
container_name: mall4cloud-nacos
restart: always
depends_on:
- mall4cloud-mysql
network_mode: "host"
expose:
- 8848
- 9848
- 9849
- 8080
environment:
- JVM_XMS=256m
- JVM_XMX=256m
- MODE=standalone
- PREFER_HOST_MODE=hostname
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=192.168.1.46
- MYSQL_SERVICE_DB_NAME=mall4cloud_nacos
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=80jpnH4.r5g
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=TWFsbDRqTWFsbDRjbG91ZE1hbGw0ak1hbGw0Y2xvdWRNYWxsNGpNYWxsNGNsb3Vk
- NACOS_AUTH_IDENTITY_KEY=mall4jmall4jmall4jmall4jmall4jmall4jmall4jmall4j
- NACOS_AUTH_IDENTITY_VALUE=mall4cloudmall4cloudmall4cloudmall4cloudmall4cloudmall4cloudmall4cloud
volumes:
- ./nacos/logs:/home/nacos/logs
mall4cloud-seata:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/seata-server:2.6.0
container_name: mall4cloud-seata
restart: always
network_mode: "host"
expose:
- 8091
environment:
- TZ
- STORE_MODE=db
- SEATA_IP=192.168.1.46
- SEATA_PORT=8091
volumes:
- ./seata/application.yml:/seata-server/resources/application.yml
mall4cloud-elasticsearch:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/elasticsearch:7.17.21
container_name: mall4cloud-elasticsearch
restart: always
network_mode: "host"
expose:
- 9200
- 9300
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
- ELASTICSEARCH_USERNAME=elastic
- ELASTIC_PASSWORD=80jpnH4.r5g
- xpack.security.enabled=true
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/data:/usr/share/elasticsearch/data
- ./elasticsearch/plugins:/usr/share/elasticsearch/plugins
mall4cloud-canal:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/canal-server:v1.1.7
container_name: mall4cloud-canal
restart: always
network_mode: "host"
expose:
- 11111
volumes:
- ./canal/conf/example:/home/admin/canal-server/conf/example
- ./canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties
- ./canal/logs:/home/admin/canal-server/logs
mall4cloud-rocketmq-namesrv:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/rocketmq:5.2.0
container_name: mall4cloud-rocketmq-namesrv
restart: always
network_mode: "host"
expose:
- 9876
volumes:
- ./rocketmq/namesrv/logs:/home/rocketmq/logs
- ./rocketmq/namesrv/store:/home/rocketmq/store
environment:
JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms512M -Xmx512M -Xmn128M"
command: ["sh","mqnamesrv"]
mall4cloud-rocketmq-broker:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/rocketmq:5.2.0
container_name: mall4cloud-rocketmq-broker
restart: always
network_mode: "host"
expose:
- 10909
- 10911
volumes:
- ./rocketmq/broker/logs:/home/rocketmq/logs
- ./rocketmq/broker/store:/home/rocketmq/store
- ./rocketmq/broker/conf/broker.conf:/etc/rocketmq/broker.conf
environment:
JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms512M -Xmx512M -Xmn128M -XX:-AssumeMP"
command: ["sh","mqbroker","-c","/etc/rocketmq/broker.conf","-n","192.168.1.46:9876","autoCreateTopicEnable=true"]
depends_on:
- mall4cloud-rocketmq-namesrv
mall4cloud-rocketmq-dashboard:
image: registry.cn-hongkong.aliyuncs.com/mall4j-images/rocketmq-dashboard:1.0.1
container_name: mall4cloud-rocketmq-dashboard
restart: always
ports:
- 8180:8082
environment:
JAVA_OPTS: "-Drocketmq.namesrv.addr=192.168.1.46:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
depends_on:
- mall4cloud-rocketmq-namesrv
Doc 8 部署运维 2 中间件 Docker Compose Seata Application.Yml (`doc/8-部署运维/2-中间件-docker-compose/seata/application.yml`)
spring:
application:
name: seata-server
main:
web-application-type: none
logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: file
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: file
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
dbType: mysql
# 需要根据mysql的版本调整driverClassName
# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
# mysql8以下版本的driver:com.mysql.jdbc.Driver
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.1.46:3306/mall4cloud_seata?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&rewriteBatchedStatements=true
user: root
password: 80jpnH4.r5g
server:
service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,//*.css,//.js,/**/.html,//*.map,//.svg,/**/.png,//*.ico,/console-fe/public/,/api/v1/auth/login
--- METRICS ---
- Files Extracted: 43
- Estimated Token Budget: ~17065 tokens
- Canonical Reference: https://codewiki.google/github.com/gz-yami/mall4cloud