尚品汇-购物车列表、临时用户购物车与登录用户购物车合并实现(三十七)

news2024/11/15 11:51:49

目录:

(1)功能—展示购物车列表

(2)在web-all添加前端实现

(3)功能--合并购物车

(1)功能—展示购物车列表

购物车列表接口:CartService

/**
 * 通过用户Id 查询购物车列表
 * @param userId
 * @param userTempId
 * @return
 */
List<CartInfo> getCartList(String userId, String userTempId);

 实现类:CartServiceImpl

@Override
public List<CartInfo> getCartList(String userId, String userTempId) {
    //获取临时用户购物车数据
    List<CartInfo> cartInfoList = null;
    if(!StringUtils.isEmpty(userTempId)){
        BoundHashOperations<String, String, CartInfo> boundHashOps = this.redisTemplate.boundHashOps(this.getCartKey(userTempId));
        cartInfoList = boundHashOps.values();
    }

    //获取用户购物车数据
    if(!StringUtils.isEmpty(userId)){
        BoundHashOperations<String, String, CartInfo> boundHashOps = this.redisTemplate.boundHashOps(this.getCartKey(userId));
        cartInfoList = boundHashOps.values();
    }

    if(!CollectionUtils.isEmpty(cartInfoList)){
        //  展示购物车列表的时候应该有顺序! 京东:按照更新时间! 苏宁:创建时间!
        cartInfoList.sort((o1,o2)->{
            //  使用时间进行比较
            return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
        });
    }
    return cartInfoList;
}

 

 

控制器:CartApiController

/**
 * 查询购物车
 *
 * @param request
 * @return
 */
@GetMapping("cartList")
public Result cartList(HttpServletRequest request) {
    // 获取用户Id
    String userId = AuthContextHolder.getUserId(request);
    // 获取临时用户Id
    String userTempId = AuthContextHolder.getUserTempId(request);
    List<CartInfo> cartInfoList = cartService.getCartList(userId, userTempId);
    return Result.ok(cartInfoList);
}

 在Web-all模块添加一个Controller:

(2)在web-all添加前端实现

添加依赖和配置网关

<dependency>
      <groupId>com.atguigu.gmall</groupId>
      <artifactId>service-cart-client</artifactId>
      <version>1.0</version>
   </dependency>

在nacos的配置网关中添加 

- id: web-cart
 
uri: lb://web-all
 
predicates:
  - Host=cart.gmall.com

- id: service-cart
 
uri: lb://service-cart
 
predicates:
  - Path=/*/cart/**

 controller实现:

添加跳转到购物车详情页面的controller

package com.atguigu.gmall.all.controller;

/**
 * <p>
 * 购物车页面
 * </p>
 *
 */
@Controller
public class CartController {

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private ProductFeignClient productFeignClient;

    /**
     * 查看购物车
     * @param request
     * @return
     */
    @RequestMapping("cart.html")
    public String index(){
        return "cart/index";
    }

    /**
     * 添加购物车
     * @param skuId
     * @param skuNum
     * @param request
     * @return
     */
    @RequestMapping("addCart.html")
    public String addCart(@RequestParam(name = "skuId") Long skuId,
                          @RequestParam(name = "skuNum") Integer skuNum,
                          HttpServletRequest request){
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
        request.setAttribute("skuInfo",skuInfo);
        request.setAttribute("skuNum",skuNum);
        return "cart/addCart";
    }
}

 

(3)功能--合并购物车

功能分析:

  1. 当用户登录以后,先判断未登录的时候,用户是否购买了商品。
    1. 如果用户购买了商品,则找到对应的商品Id,对数量进行合并。
    2. 没有找到的商品,则直接添加到数据。
  2. 合并完成之后,删除未登录数据。

 

更改实现类:CartServiceImpl:cartList的实现

@Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        /*
            1.  判断是否登录,根据判断结果查询不同的购物车!
            2.  查询的结果需要排序!
            3.  有可能需要合并!
                    在登录的情况下
                    .  未登录 ---> 登录合并!
                        合并完成之后,需要删除未登录购物车数据!
                     case1: 有userId ,没有userTempId
                     case2: 没有userId ,有userTempId   return noLoginCartInfoList
                     case3: 有userId ,有userTempId
                        登录情况下合并购物车:
                            先判断未登录购物车集合有数据!
                                true: 有数据
                                    合并
                                false: 没有数据
                                    只需要登录购物车数据
                            删除未登录购物车!
         */
        //  声明一个集合来存储未登录数据
        List<CartInfo> noLoginCartInfoList = null;

        //  完成case2 业务逻辑
        //  属于未登录
        if (!StringUtils.isEmpty(userTempId)){
            String cartKey = this.getCartKey(userTempId);
            //  获取登录的购物车集合数据!
            //  noLoginCartInfoList = this.redisTemplate.boundHashOps(cartKey).values();
            noLoginCartInfoList  = this.redisTemplate.opsForHash().values(cartKey);
        }
        //  这个是集合的排序
        if (StringUtils.isEmpty(userId)){
            if (!CollectionUtils.isEmpty(noLoginCartInfoList)){
                noLoginCartInfoList.sort((o1,o2)->{
                    //  按照更新时间:
                    return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
                });
            }
            //  返回未登录数据!
            return noLoginCartInfoList;
        }
        //  ----------------------case 1 and case3 -----------------
        /*
        demo:
            登录:
                17  1
                18  1

            未登录:
                17  1
                18  1
                19  2

             合并:
                17  2
                18  2
                19  2
         */
        //  属于登录
        List<CartInfo> LoginCartInfoList = null;
        //  先获取到登录购物车的key
        String cartKey = this.getCartKey(userId);
        //  hset key field value;  hget key field;  hvals key ; hmset key field value field value;  hmset key map;
        //  合并思路二:
        BoundHashOperations<String, String, CartInfo>  boundHashOperations = this.redisTemplate.boundHashOps(cartKey);
        //  判断购物车中的field
        //  boundHashOperations.hasKey(skuId.toString);
        if (!CollectionUtils.isEmpty(noLoginCartInfoList)){
            //  循环遍历未登录购物车集合
            noLoginCartInfoList.stream().forEach(cartInfo -> {
                //  在未登录购物车中的skuId 与登录的购物车skuId 相对  skuId = 17 18
                if (boundHashOperations.hasKey(cartInfo.getSkuId().toString())){
                    //  合并业务逻辑 : skuNum + skuNum 更新时间
                    CartInfo loginCartInfo = boundHashOperations.get(cartInfo.getSkuId().toString());
                 //更新数量
                    loginCartInfo.setSkuNum(loginCartInfo.getSkuNum()+cartInfo.getSkuNum());
                    loginCartInfo.setUpdateTime(new Date());
                    //  最新价格
      loginCartInfo.setSkuPrice(productFeignClient.getSkuPrice(cartInfo.getSkuId()));

                    //  选中状态合并!
                    if (cartInfo.getIsChecked().intValue()==1){
//                        if (loginCartInfo.getIsChecked().intValue()==0){
//                            loginCartInfo.setIsChecked(1);
//                        }
                        loginCartInfo.setIsChecked(1);
                    }
                    //  修改缓存的数据:    hset key field value
                    boundHashOperations.put(cartInfo.getSkuId().toString(),loginCartInfo);
                }else {
                    //  直接添加到缓存!    skuId = 19
                    cartInfo.setUserId(userId);
                    cartInfo.setCreateTime(new Date());
                    cartInfo.setUpdateTime(new Date());
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            });
            //  删除未登录购物车数据!
            this.redisTemplate.delete(this.getCartKey(userTempId));
        }

        //  获取到合并之后的数据:
        LoginCartInfoList = this.redisTemplate.boundHashOps(cartKey).values();
        if (CollectionUtils.isEmpty(LoginCartInfoList)){
            return new ArrayList<>();
        }
        //  设置合并之后的排序结果!
        LoginCartInfoList.sort(((o1, o2) -> {
            return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
        }));
        return LoginCartInfoList;
    }

 未登录时:

 

登录的数据:

在购物车页面点击登录:或者结算时会跳转登录

 数据进行了合并,临时id数据页进行了清楚

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

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

相关文章

Ps:高速缓存机制

Photoshop 的高速缓存 Cache技术利用缓存和分块的方法处理图像数据&#xff0c;通过合理设置高速缓存级别和拼贴大小&#xff0c;可以有效地提升软件在处理图像时的性能。 Ps菜单&#xff1a;编辑/首选项 Edit/Preferences “首选项”中提供了 8 种高速缓存级别。 增加高速缓存…

一文带你读懂反向代理服务器

文章目录 一、什么是反向代理&#xff1f;二、反向代理的主要特点2.1 负载均衡2.2 隐藏IP2.3 响应加速2.4 过滤非法请求 三、反向代理的应用场景3.1 负载均衡3.2 SSL/TLS终止3.3 日志记录3.4 URL重写3.5 API网关3.6 CDN服务 四、区分反向代理和正向代理4.1 从工作原理上4.2 从安…

Memcached:单节点、集群案例;概念、工作原理

目录 案例前置知识点 Memcached 概念 部署场景 Memcached常用架构 流程 Memcached Memcached API 数据存储方式 数据过期方式 LRU Lazy Expiration Memcached缓存机制 Memcached路由算法 求余数hash算法 一致性hash算法 Memcached分布式 案例 单节点Memcach…

2024电工杯B题完整论文

大学生平衡膳食食谱的优化设计及评价 摘要 大学阶段是学生获取知识和身体发育的关键时期&#xff0c;也是形成良好饮食习惯的重要阶段。然而&#xff0c;当前大学生中存在饮食结构不合理和不良饮食习惯的问题&#xff0c;主要表现为不吃早餐或早餐吃得马虎&#xff0c;经常食…

如果这10道关于数据库的测试题你都会,面试必过!

一、什么是数据库测试&#xff1f; 数据库测试也称为后端测试。数据库测试分为四个不同的类别。 [if !supportLists] [endif]数据完整性测试 [if !supportLists] [endif]数据有效性测试 [if !supportLists] [endif]数据库相关的性能 [if !supportLists] [endif]测试功能&a…

【数据结构】二叉树顺序结构之堆的实现

1. 前言 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆 ( 一种二叉树 ) 使用顺序结构的数组来存储&#xff0c;需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两回事&…

【Python机器学习】NLP分词——利用分词器构建词汇表(二)——点积

在自然语言处理中将会有多处用到点积&#xff0c;点积也被称为内积&#xff0c;这是因为两个向量&#xff08;每个向量中的元素个数&#xff09;或矩阵&#xff08;第一个矩阵的行数和第二个矩阵的列数&#xff09;的“内部”维度必须一样&#xff0c;这种情况下才能相乘。这个…

【Docker】以思源笔记为例,谈谈什么是端到端加密

本文首发于 ❄️慕雪的寒舍。 链滴&#xff08;思源笔记社区&#xff09;里面有不少老哥似乎不太了解思源使用的端到端加密功能&#xff0c;以及云同步功能背后的机制。本文将以思源笔记为例&#xff0c;谈谈什么是端到端加密&#xff0c;以及思源的同步功能中用到了什么计算机…

JavaSE基础(12)——文件、递归、IO流

1、IO流 Input&#xff1a;输入&#xff0c;写数据&#xff0c;数据从磁盘加载到内存&#xff08;程序&#xff09;中。 Output&#xff1a;输出&#xff0c;读数据&#xff0c;数据从内存&#xff08;程序&#xff09;存储到磁盘中。 流&#xff1a;不管是读还是写&#xf…

html一文入门---标签大合集

一、文档结构标签 <!DOCTYPE html>: 声明文档类型和 HTML 版本&#xff0c;告诉浏览器使用 HTML5 解析文档。<html>: HTML 文档的根元素。<head>: 包含文档的元数据&#xff08;如标题、字符集、样式表链接&#xff09;。<title>: 定义文档的标题&…

这本书已经无敌!一本书学懂NLP自然语言(附PDF文档)

自然语言处理被誉为“人工智能皇冠上的明珠”。深度学习等技术的引入为自然语言处理技术带来了一场革命&#xff0c;尤其是近年来出现的基于预训练模型的方法&#xff0c;已成为研究自然语言处理的新范式。而今天给大家推荐的这本《自然语言处理&#xff1a;基于预训练模型的方…

详细的爱剪辑官网免费版下载步骤,还有四款剪辑工具推荐!

在当下这个数字化、自媒体蓬勃发展的时代&#xff0c;视频剪辑已成为大家日常中的一项不可或缺的技能。面对市面上丰富多样的剪辑工具&#xff0c;许多初学者往往感到困惑&#xff0c;不知道该如何选择。今天接这篇文章给大家详细解析五款常用的视频剪辑软件&#xff0c;包括还…

数字工厂管理系统与MES系统集成后有哪些作用

在当今智能制造的浪潮中&#xff0c;数字工厂管理系统与MES管理系统的深度融合与集成&#xff0c;已成为推动企业转型升级、提升生产效率与竞争力的关键路径。两者协同工作&#xff0c;不仅实现了生产过程的透明化、智能化管理&#xff0c;还促进了资源优化配置与决策支持能力的…

Python读取fasta格式数据成为字典形式。

本团队提供生物医学领域专业的AI&#xff08;机器学习、深度学习&#xff09;技术支持服务。如果您有需求&#xff0c;请扫描文末二维码关注我们。 Python读取fasta格式数据成为字典形式。 def read_fasta(file_path):"""读取FASTA格式文件&#xff0c;并返回一…

基于vue框架的毕业设计管理系统5n36i(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,教师,课题信息,题目分类,选题信息,任务书,中期检查,提交论文,论文成绩,答辩成绩,校园公告,教研主任,申报课题 开题报告内容 基于Vue框架的毕业设计管理系统开题报告 一、引言 随着高等教育的不断发展&#xff0c;毕业设计作为培…

2024年中科院SCI期刊牛顿-拉夫逊优化算法NRBO优化Transformer-LST模型的多变量时间序列预测

matlab R2024a以上 一、数据集 二、2024年中科院SCI期刊牛顿-拉夫逊优化算法NRBO 牛顿-拉夫逊优化算法(Newton-Raphson-based optimizer, NBRO)是一种新型的元启发式算法&#xff08;智能优化算法&#xff09;&#xff0c;该成果由Sowmya等人于2024年2月发表在中科院2区Top SC…

OpenHarmony开发实战: 一种应用界面UI自动化测试方法

前言&#xff1a; 随着 OpenHarmony 版本更新&#xff0c;应用生态繁荣&#xff0c;如何对应用界面进行自动化测试成为一个迫切的问题。一般情况&#xff0c;对应用的界面测试都是通过人工进行&#xff0c;效率低&#xff0c;误判率高&#xff0c;本文将介绍一种通过图片对比进…

OpenCV Lesson 2: 如何使用OpenCV扫描图像、查找表和时间测量

How to scan images, lookup tables and time measurement with OpenCV Goal目标Our test case我们的测试用例How is the image matrix stored in memory? Goal We’ll seek answers for the following questions: How to go through each and every pixel of an image? How…

Redis远程字典服务器(8)—— zset类型详解

目录 一&#xff0c;基本情况 二&#xff0c;常用命令 2.1 zadd 2.2 zcard&#xff0c;zcount 2.3 zrange&#xff0c;zrevrange&#xff0c;zrangebyscore 2.4 zpopmax&#xff0c;bzpopmax 2.5 zpopmin&#xff0c;bzpopmin 2.6 zrank&#xff0c;zrevrank&#xff0…

跨界合作:联想拯救者Y9000P《黑神话:悟空》联名版震撼发布

在科技与文化的交汇点&#xff0c;联想拯救者与备受瞩目的国产单机游戏《黑神话&#xff1a;悟空》携手&#xff0c;共同推出了令人瞩目的Y9000P联名定制版笔记本。 这款笔记本不仅承载着联想拯救者对于极致性能的追求&#xff0c;更融入了《黑神话&#xff1a;悟空》深厚的文…