# mall **Repository Path**: coder-kaho/mall ## Basic Information - **Project Name**: mall - **Description**: 基于 Spring Boot 的前后端分离电商支付项目 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2022-01-19 - **Last Updated**: 2025-04-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前后端分离的 B2C 电商平台+支付系统 > - @author:Kaho WONG > > - @create:2021-09 ## 前言 本仓库包含了 `mall` 和 `pay` 两个工程,分别对应了该项目的商城系统和通用性支付系统。 > 注意:支付系统的使用需要拥有 `微信支付/支付宝` 的商户资质! ## 项目简介 该项目是一个基于 Spring Boot 的 B2C 全模块电商平台和通用性支付系统的双系统项目,电商平台包含用户、订单、商品、购物车、收货地址等模块,使用 MySQL 作存储层,使用 Redis 存储用户购物车内的商品条目;支付系统采用了微信支付和支付宝开发文档的 api 进行开发,使用 RabbitMQ 实现支付的异步通知;使用 Nginx 服务器实现反向代理和负载均衡。 > **什么是 B2C ?** > > [B2C](https://baike.baidu.com/item/B2C) 中的 B 是 Business,即商业供应方(泛指企业),2(two)则是 to 的谐音,C 是 Consumer,即消费者。B2C 电子商务是按电子商务交易主体划分的一种[电子商务模式](https://baike.baidu.com/item/电子商务模式/10834158),即表示企业对消费者的电子商务,具体是指通过信息网络以及电子数据信息的方式实现企业或商家机构与消费者之间的各种商务活动、交易活动、金融活动和综合服务活动,是消费者利用 Internet 直接参与经济活动的形式。 本人主要 负责后端业务逻辑的编写,项目的功能测试,项目架构图、数据库表 E-R 图的绘制以及项目文档的编写。 ## 技术栈和环境参数 - Java 1.8 - **SpringBoot 2.1.7** - MyBatis 2.1.0 - Maven 3.8.1 - MySQL 5.7 - RabbitMQ 3.8.1 - 开发平台:IDEA Ultimate 2021.1 - Nginx - [best-pay-sdk](https://github.com/Pay-Group/best-pay-sdk) - 数据库管理软件:SQLyog(看个人喜好) ## 项目背景 本项目主要是我在学习了 Spring Boot、MyBatis、MySQL 等一系列后端技术后,用于初步了解企业级应用系统设计开发流程,学习如何分析开发文档并理解商城系统和支付系统开发场景的前后端分离项目。 ## 项目架构图 **项目整体架构:**  **支付系统架构概况:**  **支付全流程示意图(通用):**  ## 项目亮点 **1. 使用 Redis 作为购物车缓存,提高购物车中热点数据的读写效率;** **2. 引入 RabbitMQ 消息中间件向商城订单模块推送支付消息,实现了订单模块和支付系统的解耦以及交易结果的异步通知;使用RabbitMQ 死信队列解决未支付订单超时自动取消的问题;** **3. 使用 Nginx 进行动静分离、反向代理和负载均衡;** **4. 使用开源项目 [Best-Pay-SDK](https://github.com/Pay-Group/best-pay-sdk) 接入微信 Native 支付+支付宝网站支付接口,简化支付调用流程;** ## 一、数据库设计 ### 表设计 **要点:** - 表关系(重点) - 表结构 - 唯一索引 - 单索引及组合索引 - not null - 时间戳 **表关系示意图(E-R 图):**  > 下面仅仅粗略展示各表大致结构,完整建表 sql 在下面~ **用户表结构:** ```sql DROP TABLE IF EXISTS `mall_user`; CREATE TABLE `mall_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户表id', `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(50) NOT NULL COMMENT '用户密码,MD5加密', `email` varchar(50) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `question` varchar(100) DEFAULT NULL COMMENT '找回密码问题', `answer` varchar(100) DEFAULT NULL COMMENT '找回密码答案', `role` int(4) NOT NULL COMMENT '角色0-管理员,1-普通用户', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL COMMENT '最后一次更新时间', PRIMARY KEY (`id`), UNIQUE KEY `user_name_unique` (`username`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` **分类表结构:** ```sql CREATE TABLE `mall_category`( `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '类别id', `parent_id` INT(11) DEFAULT NULL COMMENT '父类别id当id=0时说明是根节点', `name` VARCHAR(50) DEFAULT NULL COMMENT '类别名称', `status` TINYINT(1) DEFAULT '1' COMMENT '类别状态1-正常,2-已废弃', `sort_order` INT(4) DEFAULT NULL COMMENT '排序编号,同类展示顺序', `create_time` DATETIME DEFAULT NULL COMMENT '创建时间', `update_time` DATETIME DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ``` **产品表结构:** ```sql CREATE TABLE `mall_product` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id', `category_id` int(11) NOT NULL COMMENT '分类id,对应mall_category表的主键', `name` varchar(100) NOT NULL COMMENT '商品名称', `subtitle` varchar(200) DEFAULT NULL COMMENT '商品副标题', `main_image` varchar(500) DEFAULT NULL COMMENT '产品主图,url相对地址', `sub_images` text COMMENT '图片地址,json格式,扩展用', `detail` text COMMENT '商品详情', `price` decimal(20,2) NOT NULL COMMENT '价格,单位-元保留两位小数', `stock` int(11) NOT NULL COMMENT '库存数量', `status` int(6) DEFAULT '1' COMMENT '商品状态.1-在售 2-下架 3-删除', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` **支付信息表结构:** ```sql CREATE TABLE `mall_pay_info`( `id` INT(11) NOT NULL AUTO_INCREMENT, `user_id` INT(11) DEFAULT NULL COMMENT '用户id', `order_no` BIGINT(20) DEFAULT NULL COMMENT '订单号', `pay_platform` INT(10) DEFAULT NULL COMMENT '支付平台:1-支付宝,2-微信', `platform_number` VARCHAR(200) DEFAULT NULL COMMENT '支付平台订单号', `platform_status` VARCHAR(20) DEFAULT NULL COMMENT '支付状态', `create_time` DATETIME DEFAULT NULL COMMENT '创建时间', `update_time` DATETIME DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ``` **订单表结构:** ```sql CREATE TABLE `mall_order` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单id', `order_no` bigint(20) DEFAULT NULL COMMENT '订单号', `user_id` int(11) DEFAULT NULL COMMENT '用户id', `shipping_id` int(11) DEFAULT NULL, `payment` decimal(20,2) DEFAULT NULL COMMENT '实际付款金额,单位是元,保留两位小数', `payment_type` int(4) DEFAULT NULL COMMENT '支付类型,1-在线支付', `postage` int(10) DEFAULT NULL COMMENT '运费,单位是元', `status` int(10) DEFAULT NULL COMMENT '订单状态:0-已取消-10-未付款,20-已付款,40-已发货,50-交易成功,60-交易关闭', `payment_time` datetime DEFAULT NULL COMMENT '支付时间', `send_time` datetime DEFAULT NULL COMMENT '发货时间', `end_time` datetime DEFAULT NULL COMMENT '交易完成时间', `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `order_no_index` (`order_no`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` user_id 是用户id,即用户表的主键,所以在本订单表中 user_id 是充当外键的作用,这就能保证数据一致性和节省存储空间,可以这么理解:商城系统订单表存储一个用户 ID 作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真实名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。 **订单明细表结构:** ```sql CREATE TABLE `mall_order_item` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单子表id', `user_id` int(11) DEFAULT NULL, `order_no` bigint(20) DEFAULT NULL, `product_id` int(11) DEFAULT NULL COMMENT '商品id', `product_name` varchar(100) DEFAULT NULL COMMENT '商品名称', `product_image` varchar(500) DEFAULT NULL COMMENT '商品图片地址', `current_unit_price` decimal(20,2) DEFAULT NULL COMMENT '生成订单时的商品单价,单位是元,保留两位小数', `quantity` int(10) DEFAULT NULL COMMENT '商品数量', `total_price` decimal(20,2) DEFAULT NULL COMMENT '商品总价,单位是元,保留两位小数', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `order_no_index` (`order_no`) USING BTREE, KEY `order_no_user_id_index` (`user_id`,`order_no`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` **收货地址表结构:** ```sql CREATE TABLE `mall_shipping` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL COMMENT '用户id', `receiver_name` varchar(20) DEFAULT NULL COMMENT '收货姓名', `receiver_phone` varchar(20) DEFAULT NULL COMMENT '收货固定电话', `receiver_mobile` varchar(20) DEFAULT NULL COMMENT '收货移动电话', `receiver_province` varchar(20) DEFAULT NULL COMMENT '省份', `receiver_city` varchar(20) DEFAULT NULL COMMENT '城市', `receiver_district` varchar(20) DEFAULT NULL COMMENT '区/县', `receiver_address` varchar(200) DEFAULT NULL COMMENT '详细地址', `receiver_zip` varchar(6) DEFAULT NULL COMMENT '邮编', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` **支付信息表:** ```sql CREATE TABLE `mall_pay_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL COMMENT '用户id', `order_no` bigint(20) NOT NULL COMMENT '订单号', `pay_platform` int(10) DEFAULT NULL COMMENT '支付平台:1-支付宝,2-微信', `platform_number` varchar(200) DEFAULT NULL COMMENT '支付流水号', `platform_status` varchar(20) DEFAULT NULL COMMENT '支付状态', `pay_amount` decimal(20,2) NOT NULL COMMENT '支付金额', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uqe_order_no` (`order_no`), UNIQUE KEY `uqe_platform_number` (`platform_number`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ``` **TIPS:** **1. 主键索引** 默认会对主键创建聚簇索引,在工程中主要是几张表中的 `XX_id` 字段,同时声明了自增属性,无需我们手动赋值。 **2. 唯一索引** 保证数据唯一性,同时提高在数据库的检索效率。 **3. 单索引及组合索引** 通过 B+ 树提高针对特定字段的查询速度。组合索引符合最左前缀原则,减少创建的索引数量,降低数据库维护成本。 **4. 时间戳** 便于查业务问题 - create_time: 创建时间 - update_time: 更新时间 ### 建立数据库 - 安装Mysql - 执行建表SQL **建表SQL** 本项目建表SQL如下:**mall.sql** ```sql DROP TABLE IF EXISTS `mall_category`; CREATE TABLE `mall_category` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '类别Id', `parent_id` int(11) DEFAULT NULL COMMENT '父类别id当id=0时说明是根节点,一级类别', `name` varchar(50) DEFAULT NULL COMMENT '类别名称', `status` tinyint(1) DEFAULT '1' COMMENT '类别状态1-正常,2-已废弃', `sort_order` int(4) DEFAULT NULL COMMENT '排序编号,同类展示顺序,数值相等则自然排序', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `mall_category` (`id`, `parent_id`, `name`, `status`, `sort_order`, `create_time`, `update_time`) VALUES (100001,0,'家用电器',1,NULL,'2000-03-25 16:46:00','2000-03-25 16:46:00'), (100002,0,'数码3C',1,NULL,'2000-03-25 16:46:21','2000-03-25 16:46:21'), (100003,0,'服装箱包',1,NULL,'2000-03-25 16:49:53','2000-03-25 16:49:53'), (100004,0,'食品生鲜',1,NULL,'2000-03-25 16:50:19','2000-03-25 16:50:19'), (100005,0,'酒水饮料',1,NULL,'2000-03-25 16:50:29','2000-03-25 16:50:29'), (100006,100001,'冰箱',1,NULL,'2000-03-25 16:52:15','2000-03-25 16:52:15'), (100007,100001,'电视',1,NULL,'2000-03-25 16:52:26','2000-03-25 16:52:26'), (100008,100001,'洗衣机',1,NULL,'2000-03-25 16:52:39','2000-03-25 16:52:39'), (100009,100001,'空调',1,NULL,'2000-03-25 16:52:45','2000-03-25 16:52:45'), (100010,100001,'电热水器',1,NULL,'2000-03-25 16:52:54','2000-03-25 16:52:54'), (100011,100002,'电脑',1,NULL,'2000-03-25 16:53:18','2000-03-25 16:53:18'), (100012,100002,'手机',1,NULL,'2000-03-25 16:53:27','2000-03-25 16:53:27'), (100013,100002,'平板电脑',1,NULL,'2000-03-25 16:53:35','2000-03-25 16:53:35'), (100014,100002,'数码相机',1,NULL,'2000-03-25 16:53:56','2000-03-25 16:53:56'), (100015,100002,'3C配件',1,NULL,'2000-03-25 16:54:07','2000-03-25 16:54:07'), (100016,100003,'女装',1,NULL,'2000-03-25 16:54:44','2000-03-25 16:54:44'), (100017,100003,'帽子',1,NULL,'2000-03-25 16:54:51','2000-03-25 16:54:51'), (100018,100003,'旅行箱',1,NULL,'2000-03-25 16:55:02','2000-03-25 16:55:02'), (100019,100003,'手提包',1,NULL,'2000-03-25 16:55:09','2000-03-25 16:55:09'), (100020,100003,'保暖内衣',1,NULL,'2000-03-25 16:55:18','2000-03-25 16:55:18'), (100021,100004,'零食',1,NULL,'2000-03-25 16:55:30','2000-03-25 16:55:30'), (100022,100004,'生鲜',1,NULL,'2000-03-25 16:55:37','2000-03-25 16:55:37'), (100023,100004,'半成品菜',1,NULL,'2000-03-25 16:55:47','2000-03-25 16:55:47'), (100024,100004,'速冻食品',1,NULL,'2000-03-25 16:55:56','2000-03-25 16:55:56'), (100025,100004,'进口食品',1,NULL,'2000-03-25 16:56:06','2000-03-25 16:56:06'), (100026,100005,'白酒',1,NULL,'2000-03-25 16:56:22','2000-03-25 16:56:22'), (100027,100005,'红酒',1,NULL,'2000-03-25 16:56:30','2000-03-25 16:56:30'), (100028,100005,'饮料',1,NULL,'2000-03-25 16:56:37','2000-03-25 16:56:37'), (100029,100005,'调制鸡尾酒',1,NULL,'2000-03-25 16:56:45','2000-03-25 16:56:45'), (100030,100005,'进口洋酒',1,NULL,'2000-03-25 16:57:05','2000-03-25 16:57:05'); DROP TABLE IF EXISTS `mall_order`; CREATE TABLE `mall_order` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单id', `order_no` bigint(20) DEFAULT NULL COMMENT '订单号', `user_id` int(11) DEFAULT NULL COMMENT '用户id', `shipping_id` int(11) DEFAULT NULL, `payment` decimal(20,2) DEFAULT NULL COMMENT '实际付款金额,单位是元,保留两位小数', `payment_type` int(4) DEFAULT NULL COMMENT '支付类型,1-在线支付', `postage` int(10) DEFAULT NULL COMMENT '运费,单位是元', `status` int(10) DEFAULT NULL COMMENT '订单状态:0-已取消-10-未付款,20-已付款,40-已发货,50-交易成功,60-交易关闭', `payment_time` datetime DEFAULT NULL COMMENT '支付时间', `send_time` datetime DEFAULT NULL COMMENT '发货时间', `end_time` datetime DEFAULT NULL COMMENT '交易完成时间', `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `order_no_index` (`order_no`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `mall_order_item` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单子表id', `user_id` int(11) DEFAULT NULL, `order_no` bigint(20) DEFAULT NULL, `product_id` int(11) DEFAULT NULL COMMENT '商品id', `product_name` varchar(100) DEFAULT NULL COMMENT '商品名称', `product_image` varchar(500) DEFAULT NULL COMMENT '商品图片地址', `current_unit_price` decimal(20,2) DEFAULT NULL COMMENT '生成订单时的商品单价,单位是元,保留两位小数', `quantity` int(10) DEFAULT NULL COMMENT '商品数量', `total_price` decimal(20,2) DEFAULT NULL COMMENT '商品总价,单位是元,保留两位小数', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `order_no_index` (`order_no`) USING BTREE, KEY `order_no_user_id_index` (`user_id`,`order_no`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `mall_pay_info`; CREATE TABLE `mall_pay_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL COMMENT '用户id', `order_no` bigint(20) DEFAULT NULL COMMENT '订单号', `pay_platform` int(10) DEFAULT NULL COMMENT '支付平台:1-支付宝,2-微信', `platform_number` varchar(200) DEFAULT NULL COMMENT '支付宝支付流水号', `platform_status` varchar(20) DEFAULT NULL COMMENT '支付宝支付状态', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `mall_product`; CREATE TABLE `mall_product` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id', `category_id` int(11) NOT NULL COMMENT '分类id,对应mall_category表的主键', `name` varchar(100) NOT NULL COMMENT '商品名称', `subtitle` varchar(200) DEFAULT NULL COMMENT '商品副标题', `main_image` varchar(500) DEFAULT NULL COMMENT '产品主图,url相对地址', `sub_images` text COMMENT '图片地址,json格式,扩展用', `detail` text COMMENT '商品详情', `price` decimal(20,2) NOT NULL COMMENT '价格,单位-元保留两位小数', `stock` int(11) NOT NULL COMMENT '库存数量', `status` int(6) DEFAULT '1' COMMENT '商品状态.1-在售 2-下架 3-删除', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `mall_product` (`id`, `category_id`, `name`, `subtitle`, `main_image`, `sub_images`, `detail`, `price`, `stock`, `status`, `create_time`, `update_time`) VALUES (26,100002,'Apple iPhone 7 Plus (A1661) 128G 玫瑰金色 移动联通电信4G手机','iPhone 7,现更以红色呈现。','http://img.springboot.cn/241997c4-9e62-4824-b7f0-7425c3c28917.jpeg','241997c4-9e62-4824-b7f0-7425c3c28917.jpeg,b6c56eb0-1748-49a9-98dc-bcc4b9788a54.jpeg,92f17532-1527-4563-aa1d-ed01baa0f7b2.jpeg,3adbe4f7-e374-4533-aa79-cc4a98c529bf.jpeg','




















2. 在 pom.xml 中引入lombok依赖:

3. 再在IEDA插件市场下载lombok插件,但是我发现 IDEA 2021.1 的插件市场找不到 lombok 插件,但是能使用 lombok 的功能,只要在使用其注解的时候导入lombok的包就能使用,如图:
## 四、MyBatis xml方式使用梳理
先来一个小贴士(非必要):如果觉得每次运行程序时控制台输出的东西太多太乱,可以在application.yml文件中添加下面的配置,可以**简化日志的输出**:
```yml
logging:
pattern:
console: "[%thread] %-5level %logger{36} - %msg%n"
```
### 1. 新建 mapper.xml
首先,在resources包下创建一个mappers包,新建一个mapper文件:

> 要注意,如果该mapper文件创建在与dao同个包下,则不需要特别告知程序这个文件的位置,而因为我将这个文件放在了resourses下,所以需要特别在配置文件application.yml下进行配置:(否则会报错)

这样程序才能找到mapper.xml文件。
### 2. 在 dao 包下的 mapper 接口中声明方法
编写mapper方法:

### 3. 编写 mapper.xml 文件
编写mapper文件:
```xml

一般我们对一个模块进行测试,都会单独建一个测试类,而非全部测试写在同一个test中,所以这里也这样做:
首先在要进行测试的类的空白处右击并选择生成Test(Ctrl + Shift + T):
进行相关配置:
便自动在test包下生成了对应的test类:
现在将原先 MallApplicationTests 类中的测试方法迁移进刚刚生成的test类,并**让新的test类继承于MallApplicationTests 【这是为了让新生成的测试类也继承到@RunWith(SpringRunner.class)、@SpringBootTest两个注解,能够被springboot识别】**
原测试类清空:
单一模块测试类:
运行正常:

## 五、MyBatis 三剑客
- MyBatis-generator
- MyBatis-plugin
- MyBatis-PageHelper
### 1. MyBatis-generator
在使用Mybatis的时候,dao接口、pojo实体类、还有每个实体类对应的xml如果都得自己写,这个工作量也是蛮大的,而插件Mybatis-generator就是用来自动生成这些代码的
在 pom.xml 中添加插件:

在终端中输入命令:

因为终端提示 `在mall\src\main\resources目录下generatorConfig.xml文件不存在`,所以要先把这个文件创建了:
在resources目录下创建 **generatorConfig.xml**,文件中的内容可以在mybatis官方文档找,也可以上网找,配置详解如下:
```xml

### 3. MyBatis-PageHelper
很著名的分页插件了,这个在具体使用时再说吧~
## 六、支付系统模块要点剖析
详情见微信和支付宝的支付开发文档:
微信支付:https://pay.weixin.qq.com/wiki/doc/api/index.html
支付宝支付:https://opendocs.alipay.com/home
**名词解释**:
appid:不是移动app的id,是应用id,一个应用有多个支付产品(建议小程序支付和App支付独立)
openid(微信):公众号和小程序支付需要,appid不同,则获取到的opinid就不同
**注意**:
**支付系统是一个独立的系统,与 mall 商城工程独立开来,有它自己专用的数据库/表**。
创建一个 **pay 工程**作为支付系统。
这个支付系统比较小,只有一张表,所以还是用之前的数据库就行。
使用Github上开源的 微信/支付宝支付SDK: **Pay-Group/best-pay-sdk**
***
本项目支付模块接入了**微信支付的 Native 支付模式**和**支付宝的网站支付模式**。
Native支付是指商户系统按微信支付协议生成一个关于本订单预支付信息的交易链接 codeUrl,支付模块调用接口将 codeUrl 渲染成一个支付二维码,然后支付系统会将这个二维码返回到前端显示,用户再用微信“扫一扫”完成支付的模式。由于微信支付必须要求企业资质,个人无法实现,下图为 native 支付流程图,以供了解:

由于没有企业资质,所以本人将回显前端的二维码写死了,如下:

支付宝网站支付模式与微信 Native 支付模式并没有太大不同之处,一样是在商城后台系统订单模块生成订单后,用户点击支付,后台就会调用支付系统的统一下单 API `create()`,这个 API 内部会调用微信/支付宝开放的接口,生成一个针对这个订单的预支付交易的链接 codeUrl,后续支付系统会根据这个 codeUrl 生成一个二维码并回显到前端。用户提交支付授权,扫码支付后,支付系统就会验证这个用户授权并完成这笔交易,最后将交易成功的消息放入消息队列进行异步通知,商城系统的订单模块从 MQ 中取出消息消费后就会更改订单状态并保存到数据库中。
## 七、后端商城模块要点剖析
### 用户模块
需要注意:在进行用户模块单测,Controller接收参数时,前端如果发来的是url格式请求,controller方法的接收参数应该使用**@RequestParam**注解:

前端如果发来的是json格式的请求,controller方法的接收参数应该使用**@RequestBody**:

**注意:**
在使用 Postman 进行接口请求测试时,需要注意 **cookie 跨域**
127.0.0.1 和 localhost 是不同的两个域,两个域访问时携带的 cookie 不同
localhost 是域名,127.0.0.1 是ip地址
### 商品模块
PageHelper 分页插件:
```xml