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

目录:

(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数据页进行了清楚

相关推荐
考虑考虑1 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261352 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊3 小时前
Java学习第22天 - 云原生与容器化
java
渣哥5 小时前
原来 Java 里线程安全集合有这么多种
java
间彧5 小时前
Spring Boot集成Spring Security完整指南
java
间彧5 小时前
Spring Secutiy基本原理及工作流程
java
Java水解6 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆8 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学9 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole9 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端