确认下单:购物车页面点击 去结算 按钮发起两个请求trade(显示购物车的商品信息和计算商品的总金额)findUserAddressList

文章目录

  • 1、确认下单:购物车页面点击去结算
    • 1.1、在OrderController类中创建 trade 方法
    • 1.2、在CartController类中创建 checkedCartInfos
    • 1.3、CartServiceImpl 实现 checkedCartInfos的业务功能
    • 1.4、在service-cart-client模块下定义远程openFeign接口
    • 1.5、在SpzxOrderApplication类上加上@EnableFeignClients
    • 1.6、OrderServiceImpl 实现 trade的业务逻辑
    • 1.7、此时启动 SpzxOrderApplication
  • 2、 openFeign拦截器使用
    • 2.1、使用feign拦截器拦截请求,获取token,重新传递token
      • 2.1.1、CartClientInterceptor
      • 2.1.2、@EnableCartClientConfig
      • 2.1.3、SpzxOrderApplication

1、确认下单:购物车页面点击去结算

  • 点击去结算这个按钮,会发起一个请求,这个请求是trade,然后展示我们要购买的商品商品的总金额
    在这里插入图片描述

1.1、在OrderController类中创建 trade 方法

@RestController
@Tag(name = "订单管理模块", description = "订单管理模块")
@RequestMapping("/api/order/orderInfo")
public class OrderController {@Resourceprivate OrderService orderService;//查询购物车中选中的购物项列表 转为 orderItem 列表交给前端展示@Operation(summary = "确认下单:购物车页面点击去结算")@GetMapping("/auth/trade")public Result trade() {TradeVo tradeVo = orderService.trade();return Result.ok(tradeVo);}
}

1.2、在CartController类中创建 checkedCartInfos

@RestController
@RequestMapping("/api/order/cart")
@Tag(name = "购物车模块")
public class CartController {//只要请求头中携带token,不需要再传用户id@Operation(summary = "查询用户购物车已选中购物项列表")@GetMapping("/auth/checkedCartInfos")public Result checkedCartInfos(){List<CartInfo> cartInfos = cartService.checkedCartInfos();return Result.ok(cartInfos);}
}

1.3、CartServiceImpl 实现 checkedCartInfos的业务功能

@Service
public class CartServiceImpl implements CartService {@Resourceprivate RedisTemplate redisTemplate;private BoundHashOperations getUserCart() {UserInfo userInfo = SpzxServiceAuthInterceptor.THREAD_LOCAL.get();BoundHashOperations ops = redisTemplate.boundHashOps("spzx:cart:" + userInfo.getId());return ops;}@Overridepublic List<CartInfo> checkedCartInfos() {//泛型1:redis键类型,泛型2:hash的key类型, 泛型3:hash的value的类型BoundHashOperations<String,String,CartInfo> userCart = getUserCart();return userCart.values().stream().filter(cartInfo -> cartInfo.getIsChecked()==1).toList();}
}

1.4、在service-cart-client模块下定义远程openFeign接口

@FeignClient(value = "service-cart")
public interface CartClient {@GetMapping("/api/order/cart/auth/checkedCartInfos")public Result<List<CartInfo>> checkedCartInfos();@DeleteMapping("/api/order/cart/auth/delCheckedCartInfos")public Result<Void> delCheckedCartInfos();
}

1.5、在SpzxOrderApplication类上加上@EnableFeignClients

@SpringBootApplication
@EnableSpzxServiceAuth
@EnableFeignClients(basePackages = "com.atguigu.spzx")
@EnableCartClientConfig
@MapperScan(basePackages = "com.atguigu.spzx.order.mapper")
@EnableTransactionManagement
public class SpzxOrderApplication {public static void main(String[] args){SpringApplication.run(SpzxOrderApplication.class,args);}
}

1.6、OrderServiceImpl 实现 trade的业务逻辑

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implements OrderService {@Resourceprivate CartClient cartClient;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic TradeVo trade() {//1、查询 当前用户 的购物车中已选中的购物项列表(cart服务管理购物车数据)Result<List<CartInfo>> cartInfos = cartClient.checkedCartInfos();if (cartInfos.getCode() != 200) {throw new SpzxException(ResultCodeEnum.FAIL,null);}List<CartInfo> cartInfoList = cartInfos.getData();if (CollectionUtils.isEmpty(cartInfoList)) {//没有已选中的购物项throw new SpzxException(ResultCodeEnum.FAIL,null);}Long token = IdUtil.getSnowflake(1,1).nextId();//将token存到redis:redis的大key问题stringRedisTemplate.opsForValue().set("spzx:order:"+token.toString(), "1",  30, TimeUnit.MINUTES);//2、将购物项列表转为 OrderItem列表List<OrderItem> orderItemList = cartInfoList.stream().map(cartInfo -> {OrderItem orderItem = new OrderItem();orderItem.setOrderId(token);orderItem.setSkuId(cartInfo.getSkuId());orderItem.setSkuName(cartInfo.getSkuName());orderItem.setSkuNum(cartInfo.getSkuNum());orderItem.setSkuPrice(cartInfo.getCartPrice());orderItem.setThumbImg(cartInfo.getImgUrl());return orderItem;}).toList();TradeVo tradeVo = new TradeVo();tradeVo.setOrderItemList(orderItemList);//遍历每一个订单项,计算它的小计金额返回//最后对所有小计金额累加 得到总金额tradeVo.setTotalAmount(orderItemList.stream().map(orderItem -> {return orderItem.getSkuPrice().multiply(new java.math.BigDecimal(orderItem.getSkuNum()));}).reduce(BigDecimal::add).get());return tradeVo;}
}

1.7、此时启动 SpzxOrderApplication

-点击 购物车页面的 去结算按钮 发现报错NullPointerException

java.lang.NullPointerException: Cannot invoke "com.atguigu.spzx.model.entity.user.UserInfo.getId()" 
because the return value of "com.atguigu.spzx.common.util.AuthContextUtil.getUserInfo()" is nullat com.atguigu.spzx.cart.service.impl.CartServiceImpl.getAllCkecked(CartServiceImpl.java:147)

2、 openFeign拦截器使用

在这里插入图片描述

2.1、使用feign拦截器拦截请求,获取token,重新传递token

针对service-cart微服务是获取不到当前登录用户的信息。原因:service-order微服务调用service-cart微服务的时候,是通过openFeign进行调用,openFeign在调用的时候会丢失请求头

2.1.1、CartClientInterceptor

@Component
public class CartClientInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {//1、获取引入cartClient模块的 项目 在使用cartClient时  请求报文中的tokenServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = requestAttributes.getRequest();String token = request.getHeader("token");//2、将token设置到feign客户端的请求报文中requestTemplate.header("token", token);}
}

现在订单服务无法使用feign拦截器,因为这个组件类放到了com.atguigu.spzx.cart.interceptor下面,订单服务扫描不到,如果我们想启用它,可以创建注解,然后把注解加到订单服务的启动类上面

2.1.2、@EnableCartClientConfig

@Target({ElementType.TYPE})
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
@Import(value = {CartClientInterceptor.class})
public @interface EnableCartClientConfig {
}

2.1.3、SpzxOrderApplication

@SpringBootApplication
@EnableSpzxServiceAuth
@EnableFeignClients(basePackages = "com.atguigu.spzx")
@EnableCartClientConfig
@MapperScan(basePackages = "com.atguigu.spzx.order.mapper")
@EnableTransactionManagement
public class SpzxOrderApplication {public static void main(String[] args){SpringApplication.run(SpzxOrderApplication.class,args);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/371217.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构--二叉树和堆

目录 1.基本概念 2.树的遍历方法 3.满二叉树&&完全二叉树 4.逻辑结构&&物理结构 5.推理公式 6.二叉树应用--堆 7.简单实现堆 1.基本概念 &#xff08;1&#xff09;这个里面的概念还是比较多的&#xff0c;但是大部分我们只需要了解即可&#xff0c;因为…

【Linux进阶】文件系统5——ext2文件系统(inode)

1.再谈inode (1) 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个…

数智化配补调:零售品牌增长新引擎

随着科技的不断进步和消费者需求的日益个性化、多元化&#xff0c;传统服装行业正面临着前所未有的挑战与机遇。在这个快速变化的时代&#xff0c;如何精准把握市场脉搏&#xff0c;实现库存的高效管理&#xff0c;成为了服装品牌生存与发展的关键。数智化配补调策略应运而生&a…

广州佛山中山数据中心机房搬迁公司

随着数据中心的发展和迭代&#xff0c;必然面临数据中心搬迁。数据中心搬迁听来简单&#xff0c;其实涉及诸多方面&#xff0c;如信息迁移的安全性、业务的连续性、搬迁的规范性、方案的可行性、组织的统一性等。友力科技&#xff08;广州&#xff09;有限公司&#xff0c;自原…

快速解决找不到krpt.dll,无法继续执行代码问题

对于那些遇到计算机开机出现由于无法找到krpt.dll&#xff0c;进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件&#xff0c;如果它出现问题&#xff0c;可能会对一些特定的软件或游戏的运行产生影响。实际上&#xff0c;我们有多种解决该…

音视频开发35 FFmpeg 编码- 将YUV 和 pcm合成一个mp4文件

一 程序的目的 /*** *该程序的目的是: * 将 一个pcm文件 和 一个 yuv文件&#xff0c;合成为一个 0804_out.mp4文件 * pcm文件和yuv文件是从哪里来的呢&#xff1f;是从 sound_in_sync_test.mp4 文件中&#xff0c;使用ffmpeg命令 抽取出来的。 * 这样做的目的是为了对比前…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第55课-芝麻开门(语音 识别 控制3D纪念馆开门 和 关门)

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第55课-芝麻开门&#xff08;语音识别控制3D纪念馆开门和关门&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtn…

搜狐新闻HarmonyOS版本 push 推送开发

背景 搜狐新闻作为HarmonyOS的合作伙伴&#xff0c;于2023年12月成功上架鸿蒙单框架应用市场&#xff0c;成为首批鸿蒙应用矩阵的一员。 新闻类推送作为应用的重要组成部分&#xff0c;在二期规划中&#xff0c;我们将推送功能列为核心功能模块。本文将推送集成过程中的步骤和…

C++左值右值

在C中&#xff0c;左值&#xff08;lvalue&#xff09;和右值&#xff08;rvalue&#xff09;是表达式分类的关键概念&#xff0c;它们主要影响表达式的赋值、函数调用以及操作符的使用方式。这些概念在C11及以后的版本中变得更加重要&#xff0c;因为引入了移动语义和右值引用…

秋招提前批面试经验分享(上)

⭐️感谢点开文章&#x1f44b;&#xff0c;欢迎来到我的微信公众号&#xff01;我是恒心&#x1f60a; 一位热爱技术分享的博主。如果觉得本文能帮到您&#xff0c;劳烦点个赞、在看支持一下哈&#x1f44d;&#xff01; ⭐️我叫恒心&#xff0c;一名喜欢书写博客的研究生在读…

华为仓颉可以取代 Java 吗?

大家好&#xff0c;我是君哥。 在最近的华为开发者大会上&#xff0c;华为亮相了仓颉编程语言&#xff0c;这是华为历经 5 年&#xff0c;投入大量研发成本沉淀的一门编程语言。 1 仓颉简介 按照官方报告&#xff0c;仓颉编程语言是一款面向全场景智能的新一代编程语言&#…

嵌入式开发SPI基本介绍与应用

目录 #SPI通信协议 #SPI基础概念 #SPI通信模式 #SPI通信时序类型 前言&#xff1a;本篇笔记参考嘉立创的开发文档&#xff0c;连接放在最后。 #SPI通信协议 #SPI基础概念 Serial Peripheral Interface 缩写SPI 翻译&#xff1a;串行外设接口 同步串行通信协议&…

保研复习 | 数据结构

目录 CH1 绪论☆ 数据项、数据元素、数据结构☆ 逻辑结构和存储结构的区别☆ 顺序存储结构和链式存储结构的比较☆ 算法的重要特性☆ 算法的复杂度 CH2 线性表☆ 单链表 CH3 栈、队列和数组☆ 栈和堆是什么&#xff1f;☆ 栈在括号匹配中的应用☆ 栈在表达式求值中的应用☆ …

【因果推断】优惠券政策对不同店铺的影响

这次依然是用之前rossmann店铺竞赛的数据集。 之前的数据集探索处理在这里已经做过了&#xff0c;此处就不再赘述了CSDN链接 数据集地址&#xff1a;竞赛链接 这里探讨数据集中Promo2对于每家店铺销售额的影响。其中&#xff0c;Promo2是一个基于优惠券的邮寄活动&#xff0c;发…

基于Python API的机械臂UDP上报设置及读取

睿尔曼机械臂提供了1个可持续读取机械臂状态的接口&#xff0c;UDP通信状态反馈接口。 该接口提供了json协议、API的读取&#xff0c;设置通信开启之后无需再进行设置即可以固定频率读取。 Python程序源码可从以下网盘地址获取&#xff08;地址永久有效&#xff09;&#xff1…

基础权限存储

一丶要求 建立用户组shengcan&#xff0c;其id为 2000建立用户组 caiwu&#xff0c;其id 为2001建立用户组 jishu&#xff0c;其id 为 2002建立目录/sc,此目录是 shengchan 部门的存储目录&#xff0c;只能被 shengchan 组的成员操作4.其他用户没有任何权限建立目录/cw,此目录…

51单片机-第一节-LED和独立按键

一、点亮LED&#xff1a; 首先包含头文件 <REGX52.H> 随后令P2为0xFE。(此时二进制对应1111 1110&#xff0c;为0 的LED亮&#xff0c;故八个灯中的最后一个亮起)。 注&#xff1a;P2为控制LED的8位寄存器。 void main() {P2 0xFE;//1111 1110while(1){} } 二、L…

微信小程序简历Demo

微信小程序简历Demo 使用介绍最后获取源码 bilibili视频介绍 使用介绍 使用微信小程序实现的一个简历实现Demo 拖动马里奥&#xff0c;到指定Name下方 向上顶就可以显示对应的简历样式 点击头像可拨打电话 点击信息处可显示当前位置 最后 这是一个简单并且有趣的微信小程…

acwing 291.蒙德里安的梦想

解法&#xff1a; 核心&#xff1a;先放横着的&#xff0c;再放竖着的。 总方案数&#xff0c;等于只放横着的小方块的合法方案数。 如何判断当前方案是否合法&#xff1f;所有剩余位置&#xff0c;能否填充满竖着的小方块。 即按列来看&#xff0c;每一列内部所有连续的空着的…

Cyber Weekly #14:WAIC 2024

赛博新闻 1、WAIC2024开幕&#xff1a;一半机器人&#xff0c;一半大模型 7月4日&#xff0c;AI界春晚——2024世界人工智能大会&#xff08;WAIC 2024&#xff09;在上海开幕&#xff0c;大会展示了500家企业的1500项展品&#xff0c;突出了机器人和大模型技术。国产机器人和…