微服务商城系统(十三)订单、支付流程分析
文章目录
- 一、订单
- 1、登录页面配置
- 2、用户收件地址查询
- 3、 下单
- (1)表结构介绍
- (2)下单实现
- (3)库存变更
- (4)增加积分
- 二、 支付流程分析
- 1、 二维码创建
- 2、微信扫码支付简介
- (1)微信扫码支付申请
- (2) 开发文档
- (3)微信支付模式介绍
- 三、总结
一、订单
1、登录页面配置
前面使用的都是采用 Postman 实现登录,现在实现 oauth 自定义登录。
先 将登录相关的静态资源导入到 changgou-user-oauth 中:
导入 thymeleaf 模板引擎依赖:
<!--thymeleaf-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
提供控制器 com.changgou.oauth.controller.LoginRedirect,实现登录页跳转:
@Controller
@RequestMapping(value = "/oauth")
public class LoginRedirect {/**** 跳转到登录页面* @return*/@GetMapping(value = "/login")public String login(){return "login";}
}
针对静态资源和登录页面,我们需要实现忽略安全配置,并且要指定登录页面。修改com.changgou.oauth.config.WebSecurityConfig 的 2 个 configure 方法:
第 2 个 configure 配置:
测试:
点击登录按钮,访问之前的登录方法实现登录,需要对登录页做一下调整。
首先,修改 login.html,引入 thymeleaf 命名空间:
点击登录按钮,使用 vue+axios 实现登录,需要定义脚本,访问后台登录方法。
先添加 vue 入口标签,修改 login.html,添加id=“app” :
引入 js:
登录脚本实现:
修改表单:
测试:输入用户名和密码都是 changgou,点击”登录“按钮,页面显示 ”正在登录“后跳转至:
用户未登录的时候,并清除 Cookie ,直接访问购物车:
可以看到,返回的只是个错误状态码,不方便测试,可以设置为重定向到登录页面,让用户登录。需要修改网关的头文件,让用户每次没登录的时候,都跳转到登录页面。
修改 changgou-gateway-web 的 com.changgou.filter.AuthorizeFilter,代码如下:
此时再测试,未登录时访问购物车页面,就可以跳转到登录页面了。当然,在实际应用中,这里不能直接跳转到登录页,应该提示状态给页面,让页面根据判断跳转,这里只是为了方便测试。
现在还有个问题,如果未登录访问购物车,会跳转到登录页面,但是登录成功后,却并没有再返回到要访问的购物车页面。可以将用户要访问的页面作为参数传递给登录控制器,登录控制器记录下来,每次登录成功后,再跳转记录访问路劲参数指定的页面。
先修改网关,携带当前 URI。修改 changgou-gateway-web 的 com.changgou.filter.AuthorizeFilter,在之前的 URL 后面添加 FROM 参数以及 FROM 参数的值为 request.getURI(),代码如下:
再修改 changgou-user-oauth 的 com.changgou.oauth.controller.LoginRedirect 记录访问来源页,使 认证服务器获取 FROM 参数:
@GetMapping(value = "/login")public String login(@RequestParam(value = "FROM",required = false,defaultValue = "")String from, Model model){model.addAttribute("from",from);return "login";}
修改页面,获取来源页信息,并存到 from 变量中,登录成功后跳转到该地址。
这里的计时跳转逻辑是有问题的,到时间并没能跳转,改成:
此时再测试,就可以识别未登录用户,跳转到登录页,然后根据登录状态,如果登录成功,则跳转到来源页。
2、用户收件地址查询
订单的前端页面是这样的:
这里,“收件人信息”,是从 user 工程中获取到的,在数据库中对应 tb_address 表:
对应表结构:
CREATE TABLE `tb_address` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) DEFAULT NULL COMMENT '用户名',`provinceid` varchar(20) DEFAULT NULL COMMENT '省',`cityid` varchar(20) DEFAULT NULL COMMENT '市',`areaid` varchar(20) DEFAULT NULL COMMENT '县/区',`phone` varchar(20) DEFAULT NULL COMMENT '电话',`address` varchar(200) DEFAULT NULL COMMENT '详细地址',`contact` varchar(50) DEFAULT NULL COMMENT '联系人',`is_default` varchar(1) DEFAULT NULL COMMENT '是否是默认 1默认 0否',`alias` varchar(50) DEFAULT NULL COMMENT '别名',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;
需要在 user 工程中提供根据用户名查询收件地址的方法。
在 AddressService 中提供方法:
List<Address> list(String username);
实现:
@Overridepublic List<Address> list(String username) {Address address = new Address();address.setUsername(username);return addressMapper.select(address);}
控制层:
@GetMapping("/user/list")
public Result<List<Address>> list(){// 获取用户登录名String username = tokenDecode.getUserInfo().get("username");List<Address> address=addressService.list(username);return new Result<>(true,StatusCode.OK,"查询成功",address);
}
运行结果:
送货清单其实就是购物车列表,直接查询之前的购物车列表即可。
3、 下单
点击结算页的时候,会立即创建订单数据,创建订单数据会将数据存入到 2 张表中,分别是 订单表 和 订单明细表,此处还需要修改商品对应的库存数量。
而且提交订单后,需要把商品详情从用户的购物车中删除;需要进行价格校验,检查价格是否变化,以当前数据库中的价格为准,以防出现 “异价” 的问题;需要检查库存,特别是并非库存,以防出现 “超卖” 的问题。
(1)表结构介绍
订单表:
CREATE TABLE `tb_order` (`id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '订单id',`total_num` int(11) DEFAULT NULL COMMENT '数量合计',`total_money` int(11) DEFAULT NULL COMMENT '金额合计',`pre_money` int(11) DEFAULT NULL COMMENT '优惠金额',`post_fee` int(11) DEFAULT NULL COMMENT '邮费',`pay_money` int(11) DEFAULT NULL COMMENT '实付金额',`pay_type` varchar(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付类型,1、在线支付、0 货到付款',`create_time` datetime DEFAULT NULL COMMENT '订单创建时间',`update_time` datetime DEFAULT NULL COMMENT '订单更新时间',`pay_time` datetime DEFAULT NULL COMMENT '付款时间',`consign_time` datetime DEFAULT NULL COMMENT '发货时间',`end_time` datetime DEFAULT NULL COMMENT '交易完成时间',`close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',`shipping_name` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流名称',`shipping_code` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流单号',`username` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名称',`buyer_message` varchar(1000) COLLATE utf8_bin DEFAULT NULL COMMENT '买家留言',`buyer_rate` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否评价',`receiver_contact` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人',`receiver_mobile` varchar(12) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人手机',`receiver_address` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人地址',`source_type` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '订单来源:1:web,2:app,3:微信公众号,4:微信小程序 5 H5手机页面',`transaction_id` varchar(30) COLLATE utf8_bin DEFAULT NULL COMMENT '交易流水号',`order_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '订单状态,0:未完成,1:已完成,2:已退货',`pay_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付状态,0:未支付,1:已支付,2:支付失败',`consign_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '发货状态,0:未发货,1:已发货,2:已收货',`is_delete` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否删除',PRIMARY KEY (`id`),KEY `create_time` (`create_time`),KEY `status` (`order_status`),KEY `payment_type` (`pay_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
订单明细表:
CREATE TABLE `tb_order_item` (`id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT 'ID',`category_id1` int(11) DEFAULT NULL COMMENT '1级分类',`category_id2` int(11) DEFAULT NULL COMMENT '2级分类',`category_id3` int(11) DEFAULT NULL COMMENT '3级分类',`spu_id` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'SPU_ID',`sku_id` bigint(20) NOT NULL COMMENT 'SKU_ID',`order_id` bigint(20) NOT NULL COMMENT '订单ID',`name` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '商品名称',`price` int(20) DEFAULT NULL COMMENT '单价',`num` int(10) DEFAULT NULL COMMENT '数量',`money` int(20) DEFAULT NULL COMMENT '总金额',`pay_money` int(11) DEFAULT NULL COMMENT '实付金额',`image` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '图片地址',`weight` int(11) DEFAULT NULL COMMENT '重量',`post_fee` int(11) DEFAULT NULL COMMENT '运费',`is_return` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否退货,0:未退货,1:已退货',PRIMARY KEY (`id`),KEY `item_id` (`sku_id`),KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
两个表通过外键 orde_id 进行连结。
(2)下单实现
下单的时候,先添加订单,向 tb_order 表中增加数据,再添加订单明细,向 tb_order_item 表中增加数据。
需要修改 changgou-service-order 微服务,实现下单操作,这里会生成订单号,我们首先需要在 启动类 中创建一个 IdWorker 对象( 为什么不使用自增 ID 呢?因为可能存在重复 和 数值超出范围 问题):
@Bean
public IdWorker idWorker(){return new IdWorker(1,1);
}
- 业务层
修改 changgou-service-order 微服务,修改com.changgou.order.service.impl.OrderServiceImpl:
void addOrder(Order order);
实现:
@Overridepublic void addOrder(Order order) {// 订单主键order.setId(String.valueOf(idWorker.nextId()));// 总数量int totolNum = 0;// 总金额int totalMoney = 0;// 获取订单(购物车)明细List<OrderItem> orderItem = redisTemplate.boundHashOps("Cart_" + order.getUsername()).values();for (OrderItem item : orderItem) {// 价格校验int price = orderItemMapper.selectByPrimaryKey(item.getId()).getPrice();if (price == item.getMoney()) {// 总金额totalMoney += item.getMoney();} else totalMoney += price;// 总数量totolNum += item.getNum();}// 订单商品总数目 = 每个商品数量之和order.setTotalNum(totolNum);// 订单总金额 = 每个商品金额之和order.setTotalMoney(totalMoney);// 订单实付金额 = 每个商品实付金额之和order.setPayMoney(totalMoney);// 订单优惠金额 = 总金额 - 实付金额,暂时为 0order.setPreMoney(0);// 订单创建时间order.setCreateTime(new Date());// 订单修改时间order.setUpdateTime(order.getCreateTime());// 订单评价状态,0 表示未评价,1 表示已评价order.setBuyerRate("0");// 订单来源,1 表示 Weborder.setSourceType("1");// 订单状态,0 表示未完成,1 表示已完成,2 表示已退货order.setOrderStatus("0");// 订单支付状态,0 表示未支付,1 表示已支付,2 表示支付失败order.setPayStatus("0");// 订单删除状态,0 表示未删除order.setIsDelete("0");// 订单发货状态,0 表示未发货,1 表示已发货,2 表示已收货order.setConsignStatus("0");// 先添加订单信息orderMapper.insertSelective(order);// 再添加订单明细信息for (OrderItem item : orderItem) {item.setId(String.valueOf(idWorker.nextId()));// 是否退货,0 表示未退货,1 表示已退货item.setIsReturn("0");item.setOrderId(order.getId());// 退货状态,0 表示未退货item.setIsReturn("0");orderItemMapper.insertSelective(item);}// 下单后需要把商品从购物车中移除redisTemplate.delete("Cart_" + order.getUsername());}
可以看到,逻辑是传来 order 对象, 从 Redis 中查到 “Cart_xxx” 为命名空间的记录对应的 value,也就是 xxx 用户购物车/订单的所有记录,遍历,求出总金额和数量;再为 order 对象设置属性,将 order 对象持久化到 order 表中,再遍历一次 Redis 中的记录,把这些记录都持久化到 order_item 表中,下单后还需要把 xxx 用户购物车中的所有记录移除。
这里,通用 Mapper 使用的是 insertSelective 方法。 如果使用的是 insert ,那么所有的字段都会添加一遍,即使有的字段没有值;如果使用 inserSelective 就会只给有值的字段赋值(会对传进来的值做非空判断)。还有要注意的是,在启动类用 @MapperScan 注解,导入的包应该是 tk 的,而不是 spring mybatis 的。
( RedisTemplate 中的命名空间、key、value 的关系示意图:
可以看到,用用户名作命名空间,商品的 sku ID 作 key,商品详情的 orderItem 作 value,这设计挺巧妙的
微服务商城系统(十三)订单、支付流程分析相关推荐
- springcloud 整合 gateway_GitHub上最火的SpringCloud微服务商城系统项目,附全套教程
项目介绍 mall-swarm是一套微服务商城系统,采用了 Spring Cloud Greenwich.Spring Boot 2.MyBatis.Docker.Elasticsearch等核心技术 ...
- mall-swarm是一套微服务商城系统
介绍: mall-swarm是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba.Spring Boot 2.3.Oauth2.MyBatis.Elasti ...
- mall-swarm微服务商城系统
mall-swarm是一套微服务商城系统,采用了 Spring Cloud 2021 & Alibaba.Spring Boot 2.7.Oauth2.MyBatis.Docker.Elast ...
- 微服务商城系统(十四)微信支付
文章目录 一.支付微服务 1.微信支付 API 2.HttpClient 工具类 3.支付微服务搭建 二.微信支付二维码生成 三.检测支付状态 四.内网穿透 五.支付结果通知 1.支付结果回调通知 2 ...
- 微服务商城系统(十六)秒杀核心
代码链接: https://github.com/betterGa/ChangGou 文章目录 一.防止秒杀重复排队 二. 并发超卖问题解决 三. 订单支付 1.实现根据不同类型订单识别不同操作队列 ...
- 微服务商城系统(十) Spring Security Oauth2 + JWT 用户认证
文章目录 一.用户认证分析 1.认证 与 授权 2.单点登录 3.第三方账号登录 4.第三方认证 5.认证技术方案 6.Security Oauth 2.0 入门 7. 资源服务授权 (1)资源服务授 ...
- 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch
文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...
- 微服务商城系统(一)框架搭建、商品微服务搭建
文章目录 一.预备 1.微服务 2.缓存 3.通用Mapper 和 PageHelper 4.持久化 5.电商模式 二.系统设计 三.框架搭建 1.环境准备 2.项目结构介绍 3.公共工程搭建 (1) ...
- 微服务商城系统 实战记录 用户、商家、后台管理员注册与登录功能实现
代码见 https://github.com/betterGa/ChangGou 文章目录 一.用户注册 1.使用 ajax (POST 方法) 2.使用 thymeleaf 3.解决跨域问题 二.用 ...
最新文章
- STS中applicationContext.xml配置文件
- java 502错误,Spring Boot连接超时导致502错误的实战案例
- 在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
- 事件相关去同步 (ERD) 和事件相关同步化 (ERS)在脑电信号研究中的应用
- 也来看看Android的ART运行时
- xp删除管理员账户_在Windows XP中从登录屏幕删除用户帐户
- 二分查找求上界和下界
- 编程语言对比 命名空间
- 用spss做哑变量--给不敲代码同学福音
- java设计模式--基础思想总结--抽象类与架构设计思想
- 应用安全-软件安全-漏洞修复整理
- github上springcloud 项目框架的前后端的启动(2021-08-05)
- 排队系统拥塞控制的位置
- 小程序谷歌统计 Google Analytics
- 桌面虚拟化:软件为先
- 红帽子企业版RHEL5.0 的软件包管理
- QT5.1标准对话框按钮显示英文问题解决办法
- 2021_WSDM_Pre-Training Graph Neural Networks for Cold-Start Users and Items Representation
- 用python制作相册影集_影集制作APP哪个好?就用这些APP把照片做成相册!
- Win10恢复照片查看器