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

news2024/10/7 11:28:28

文章目录

  • 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 {
	@Resource
    private 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 {
    @Resource
    private RedisTemplate redisTemplate;
   
    private BoundHashOperations getUserCart() {
        UserInfo userInfo = SpzxServiceAuthInterceptor.THREAD_LOCAL.get();
        BoundHashOperations ops = redisTemplate.boundHashOps("spzx:cart:" + userInfo.getId());
        return ops;
    }
    @Override
    public 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 {
    @Resource
    private CartClient cartClient;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
	@Override
    public 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 null
	at 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 {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //1、获取引入cartClient模块的 项目 在使用cartClient时  请求报文中的token
        ServletRequestAttributes 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.coloradmin.cn/o/1893327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue-org-tree搜索到对应项高亮展开

效果图&#xff1a; 代码&#xff1a; <template><div class"AllTree"><el-form :inline"true" :model"formInline" class"demo-form-inline"><el-form-item><el-input v-model"formInline.user&quo…

2024年【天津市安全员B证】最新解析及天津市安全员B证实操考试视频

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【天津市安全员B证】最新解析及天津市安全员B证实操考试视频&#xff0c;包含天津市安全员B证最新解析答案和解析及天津市安全员B证实操考试视频练习。安全生产模拟考试一点通结合国家天津市安全员B证考试最新大…

C++必修:深入理解继承与虚继承

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. 继承的概念与定义 1.1. 继承的概念 继承(inheritance)机制是面向对象程序设计…

【12321骚扰电话举报受理中心-短信验证安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【HTML入门】第一课 - 网页标签框架

这一节&#xff0c;我们说一下学习前端开发的话&#xff0c;最入门的也是非常重要的一门可成&#xff0c;也就是HTML。HTML标签&#xff0c;是网页的重要组成部分&#xff0c;可以说&#xff0c;你看到网页上的内容&#xff0c;都是基于HTML标签呈现出来的。 这一小节呢&#…

Windows系统安装SSH服务结合内网穿透配置公网地址远程ssh连接

前言 在当今的数字化转型时代&#xff0c;远程连接和管理计算机已成为日常工作中不可或缺的一部分。对于 Windows 用户而言&#xff0c;SSH&#xff08;Secure Shell&#xff09;协议提供了一种安全、高效的远程访问和命令执行方式。SSH 不仅提供了加密的通信通道&#xff0c;…

SalesForce集成案例-获取联系人信息

SalesForce本身比较复杂&#xff0c;涉及的东西比较多&#xff0c;下面以使用REST API接口为例&#xff0c;介绍与SalesForce集成的过程&#xff0c;集成案例&#xff1a;获取联系人信息。 首先需要注册一个免费的开发者帐号&#xff0c;具有完全操作SalesForce的权限。 1、注…

【vmbox centos7 网络配置】【centos7 glances 安装】【centos7 安装MySQL5.7】

文章目录 vmbox centos7 网络配置centos7 修改镜像地址centos7 安装 glancesCentOS 7 上安装 MySQL 5.7 并进行基本的安全配置使用 firewalld 开放 3306 端口 可以远程连接mysql vmbox centos7 网络配置 目前 能组建集群 虚拟机网络互通&#xff0c;虚拟机能访问外网 创建一个…

OpenCV库Windows端编译方法

编译前提 &#xff08;1&#xff09;下载好所需版本的OpenCV源码&#xff0c;点击进入下载地址&#xff0c;此处以OpenCV-2.4.13.6为例&#xff0c;下载页面截图如下图所示&#xff1a; 解压后如下图所示&#xff1a; &#xff08;2&#xff09;安装好CMake软件&#xff0c;点…

数据结构(一)C语言补

数据结构 内存空间划分 一个进程启动后&#xff0c;会生成4G的内存空间 0~3G是用户空间(应用层) 3~4G是内核空间(底层) 0~3G 3~4G 所有的进程都会共享3G~4G的内核空间&#xff0c; 但是每个进程会独立拥有0~3G的用户空间。 栈区 存放数据特点 栈区存放数据的申请空间的先后…

Ecology Letters | 植物多样性-生产力关系的正反馈机制:基于BEF-China的7年大规模实验数据

本文首发于“生态学者”微信公众号&#xff01; 森林提供了丰富的生态系统功能和服务&#xff0c;如生物质生产、碳固存、气候调节、水过滤和防止土壤侵蚀。森林生物多样性丧失的空前速度可能会严重损害世界森林提供基本生态系统功能和服务的能力。因此&#xff0c;了解物种丧失…

【Linux进阶】Linux目录配置,FHS

在了解了每个文件的相关种类与属性&#xff0c;以及了解了如何修改文件属性与权限的相关信息后&#xff0c;再来要了解的就是&#xff0c;为什么每个Linux发行版它们的配置文件、执行文件、每个目录内放置的东西&#xff0c;其实都差不多&#xff1f;原来是有一套标准依据&…

CentralCache中心缓存

目录 一.CentralCache基本结构 1.CentralCache任务 2.基本结构 二.函数调用层次结构/.h文件 三.Span和SpanList的封装 Span:大块内存跨度 PAGE_ID _pageId size_t _objSize _useCount SpanList:管理Span的双链表(桶锁) 四.获取大块内存GetOneSpan 五.FetchRangeObj输…

C语言作业笔记

1. 要找俩个数使其相加等于一个数&#xff0c;那么俩个数从头尾出发&#xff0c;先动一边&#xff0c;假设是尾先动&#xff0c;一开始俩个数相加大于sum&#xff08;小于的话就动头&#xff09;&#xff0c;那么总有一时刻俩数相加小于sum&#xff0c;则就在那一刻停下来&…

MySQL高可用(MHA高可用)

什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过程中最大…

机器学习与模式识别_清华大学出版社

contents 前言第1章 绪论1.1 引言1.2 基本术语1.3 假设空间1.4 归纳偏好1.5 发展历程1.6 应用现状 第2章 模型评估与选择2.1 经验误差与过拟合2.2 评估方法2.3 性能度量2.3.1 回归任务2.3.2 分类任务 2.4 比较检验2.5 偏差与方差2.5.1 偏差-方差分解2.5.2 偏差-方差窘境 第3章 …

In Ictu Oculi: Exposing AI Created Fake Videos by Detecting Eye Blinking

文章目录 In Ictu Oculi: Exposing AI Created Fake Videos by Detecting Eye Blinking背景关键点内容预处理Long-Term Recurrent CNNsLSTM-RNN模型训练实验data启示In Ictu Oculi: Exposing AI Created Fake Videos by Detecting Eye Blinking 会议:2018 IEEE International…

用Vue3和Rough.js绘制一个交互式3D图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 基于Rough.js和GSAP创建交互式SVG图形卡片 应用场景 本代码适用于需要创建动态交互式SVG图形卡片的场景&#xff0c;例如网页设计、数据可视化和交互式艺术作品。 基本功能 该代码利用Rough.js和GSAP库&…

数据分析入门指南:从基础概念到实际应用(一)

随着数字化时代的来临&#xff0c;数据分析在企业的日常运营中扮演着越来越重要的角色。从感知型企业到数据应用系统的演进&#xff0c;数据驱动的业务、智能优化的业务以及数智化转型成为了企业追求的目标。在这一过程中&#xff0c;数据分析不仅是技术的运用&#xff0c;更是…

在 PostgreSQL 中强制执行连接顺序#postgresql认证

让我们首先创建一些表&#xff1a; PgSQL plan# SELECT CREATE TABLE x || id || (id int) FROM generate_series(1, 5) AS id;?column? --------------------------CREATE TABLE x1 (id int)CREATE TABLE x2 (id int)CREATE TABLE x3 (id int)CREATE TABLE…