文章目录

  • 一、订单
    • 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,这设计挺巧妙的

微服务商城系统(十三)订单、支付流程分析相关推荐

  1. springcloud 整合 gateway_GitHub上最火的SpringCloud微服务商城系统项目,附全套教程

    项目介绍 mall-swarm是一套微服务商城系统,采用了 Spring Cloud Greenwich.Spring Boot 2.MyBatis.Docker.Elasticsearch等核心技术 ...

  2. mall-swarm是一套微服务商城系统

    介绍: mall-swarm是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba.Spring Boot 2.3.Oauth2.MyBatis.Elasti ...

  3. mall-swarm微服务商城系统

    mall-swarm是一套微服务商城系统,采用了 Spring Cloud 2021 & Alibaba.Spring Boot 2.7.Oauth2.MyBatis.Docker.Elast ...

  4. 微服务商城系统(十四)微信支付

    文章目录 一.支付微服务 1.微信支付 API 2.HttpClient 工具类 3.支付微服务搭建 二.微信支付二维码生成 三.检测支付状态 四.内网穿透 五.支付结果通知 1.支付结果回调通知 2 ...

  5. 微服务商城系统(十六)秒杀核心

    代码链接: https://github.com/betterGa/ChangGou 文章目录 一.防止秒杀重复排队 二. 并发超卖问题解决 三. 订单支付 1.实现根据不同类型订单识别不同操作队列 ...

  6. 微服务商城系统(十) Spring Security Oauth2 + JWT 用户认证

    文章目录 一.用户认证分析 1.认证 与 授权 2.单点登录 3.第三方账号登录 4.第三方认证 5.认证技术方案 6.Security Oauth 2.0 入门 7. 资源服务授权 (1)资源服务授 ...

  7. 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch

    文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...

  8. 微服务商城系统(一)框架搭建、商品微服务搭建

    文章目录 一.预备 1.微服务 2.缓存 3.通用Mapper 和 PageHelper 4.持久化 5.电商模式 二.系统设计 三.框架搭建 1.环境准备 2.项目结构介绍 3.公共工程搭建 (1) ...

  9. 微服务商城系统 实战记录 用户、商家、后台管理员注册与登录功能实现

    代码见 https://github.com/betterGa/ChangGou 文章目录 一.用户注册 1.使用 ajax (POST 方法) 2.使用 thymeleaf 3.解决跨域问题 二.用 ...

最新文章

  1. STS中applicationContext.xml配置文件
  2. java 502错误,Spring Boot连接超时导致502错误的实战案例
  3. 在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
  4. 事件相关去同步 (ERD) 和事件相关同步化 (ERS)在脑电信号研究中的应用
  5. 也来看看Android的ART运行时
  6. xp删除管理员账户_在Windows XP中从登录屏幕删除用户帐户
  7. 二分查找求上界和下界
  8. 编程语言对比 命名空间
  9. 用spss做哑变量--给不敲代码同学福音
  10. java设计模式--基础思想总结--抽象类与架构设计思想
  11. 应用安全-软件安全-漏洞修复整理
  12. github上springcloud 项目框架的前后端的启动(2021-08-05)
  13. 排队系统拥塞控制的位置
  14. 小程序谷歌统计 Google Analytics
  15. 桌面虚拟化:软件为先
  16. 红帽子企业版RHEL5.0 的软件包管理
  17. QT5.1标准对话框按钮显示英文问题解决办法
  18. 2021_WSDM_Pre-Training Graph Neural Networks for Cold-Start Users and Items Representation
  19. 用python制作相册影集_影集制作APP哪个好?就用这些APP把照片做成相册!
  20. Win10恢复照片查看器

热门文章

  1. 拉格朗日插值法与牛顿插值多项式
  2. 怎么使用ArcScene进行洪水淹没分析
  3. 算法入门-合并二叉树
  4. SAP 获取本机信息(IP及电脑名称)
  5. Java时间片轮转(简单模拟实现,适合初学者)
  6. comsol动网格(als)帮助文档翻译
  7. 获得KKR领投的2亿美元融资的公司,究竟随手记怎么样靠谱吗?
  8. SSE AVX 文档
  9. python程序编译错误_Python编译错误集锦
  10. arcgis风向_arcgis趋势分析