架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)

Redis 优化购物车(cookie+redis)

1. 同步商品信息到后端Redis (添加商品和删除商品功能)

架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)_第1张图片
核心代码:

package com.beyond.controller;

import com.beyond.pojo.bo.ShopcartBO;
import com.beyond.utils.BEYONDJSONResult;
import com.beyond.utils.JsonUtils;
import com.beyond.utils.RedisOperator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Api(value = "购物车接口controller", tags = {
     "购物车接口的相关api"})
@RequestMapping("shopcart")
@RestController
public class ShopcatController extends BaseController {
     

    @Autowired
    private RedisOperator redisOperator;

    @ApiOperation(value = "同步购物车到后端", notes = "同步购物车到后端", httpMethod = "POST")
    @PostMapping("/add")
    public BEYONDJSONResult add(
            @RequestParam String userId,
            @RequestBody ShopcartBO shopcartBO,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
     
        if (StringUtils.isBlank(userId)) {
     
            return BEYONDJSONResult.errorMsg("");
        }
        System.out.println(shopcartBO);

        // 前端用户在登录的情况下添加商品到购物车,会同时在后端同步到redis 缓存
        // 需要判断当前购物车中已经包含已经存在的商品, 如果存在则累加购买数量
        String shopcartJson = redisOperator.get(FOODIE_SHOPCART + ":" + userId);
        List<ShopcartBO> shopcartList = null;
        if (StringUtils.isNotBlank(shopcartJson)) {
     
            // redis 中已经有购物车了
            shopcartList = JsonUtils.jsonToList(shopcartJson, ShopcartBO.class);
            // 判断购物车中是否存在已有商品, 如果有的话 counts 累加
            boolean isHaving = false;
            for (ShopcartBO sc : shopcartList) {
     
                String tmpSpecId = sc.getSpecId();
                if (tmpSpecId.equals(shopcartBO.getSpecId())) {
     
                    sc.setBuyCounts(sc.getBuyCounts() + shopcartBO.getBuyCounts());
                    isHaving = true;
                }
            }
            if (!isHaving) {
     
                shopcartList.add(shopcartBO);
            }
        } else {
     
            // redis 中没有数据
            shopcartList = new ArrayList<>();
            shopcartList.add(shopcartBO);
        }
        // 覆盖现有 redis 中的购物车
        redisOperator.set(FOODIE_SHOPCART + ":" + userId, JsonUtils.objectToJson(shopcartList));
        return BEYONDJSONResult.ok();

    }

    @ApiOperation(value = "从购物车中删除商品", notes = "从购物车中删除商品", httpMethod = "POST")
    @PostMapping("/del")
    public BEYONDJSONResult del(
            @RequestParam String userId,
            @RequestParam String itemSpecId,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
     
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(itemSpecId)) {
     
            return BEYONDJSONResult.errorMsg("参数不能为空~~");
        }

        // 用户在页面删除购物车的商品数据, 如果此时用户已经登录, 则需要同步删除后端购物车的商品
        String shopcartJson = redisOperator.get(FOODIE_SHOPCART + ":" + userId);
        if (StringUtils.isNotBlank(shopcartJson)){
     
            // redis 中已经有购物车了
            List<ShopcartBO> list = JsonUtils.jsonToList(shopcartJson, ShopcartBO.class);
            // 判断购物车中是否存在已有商品, 如果有的话则删除
            for (ShopcartBO sc : list){
     
                String tmpSpecId = sc.getSpecId();
                if (tmpSpecId.equals(itemSpecId)){
     
                    list.remove(sc);
                    break;
                }
            }
            // 覆盖现有redis中的购物车
            redisOperator.set(FOODIE_SHOPCART+":"+userId, JsonUtils.objectToJson(list));
        }

        return BEYONDJSONResult.ok();

    }

}

2. 更新购买数量功能整合Redis

架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)_第2张图片
架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)_第3张图片

1. controller 核心补充

 String shopcartJson = redisOperator.get(FOODIE_SHOPCART + ":" + submitOrderBO.getUserId());
        if (StringUtils.isBlank(shopcartJson)){
     
            return BEYONDJSONResult.errorMsg("购物车数据不正确");
        }

        List<ShopcartBO> shopcartList = JsonUtils.jsonToList(shopcartJson, ShopcartBO.class);

2. serviceImpl 核心补充

 // 整合 redis后, 商品购买的数量重新从redis的购物车中获取
            ShopcartBO cartItem = getBuyCountsFromShopcart(shopcartList, itemSpecId);
            int buyCounts = cartItem.getBuyCounts();


/**
     * 从 Redis 的购物车里获取商品, 目的是为 counts 服务
     *
     * @param shopcartList
     * @param specId
     * @return
     */
    private ShopcartBO getBuyCountsFromShopcart(List<ShopcartBO> shopcartList, String specId) {
     
        for (ShopcartBO sc : shopcartList) {
     
            if (sc.getSpecId().equals(specId)) {
     
                return sc;
            }
        }
        return null;

    }

架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)_第4张图片
架构师成长记_第六周_04_Redis 优化购物车 (Cookie + Redis)_第5张图片

3. 清理已经结算商品功能整合redis

1. service 核心补充

 List<ShopcartBO> toBeRemovedShopcartList = new ArrayList<>();

        for (String itemSpecId : itemSpecIdArr) {
     
            // 整合 redis后, 商品购买的数量重新从redis的购物车中获取
            ShopcartBO cartItem = getBuyCountsFromShopcart(shopcartList, itemSpecId);
            int buyCounts = cartItem.getBuyCounts();
            toBeRemovedShopcartList.add(cartItem);

2. controller 核心补充

 // 清理覆盖现有的redis汇总的购物车数据
  shopcartList.removeAll(orderVO.getToBeRemovedShopcartList());
  // 更新redis
  redisOperator.set(FOODIE_SHOPCART + ":" + submitOrderBO.getUserId(), JsonUtils.objectToJson(shopcartList));

 // 整合redis之后, 完善购物车中已结算商品清除, 并且同步到前端的cookie
 CookieUtils.setCookie(request, response, COOKIE_SHOPCART, JsonUtils.objectToJson(shopcartList), true);

PS: 开发小技巧

  1. 我们通过扩展service中的返回类型BO, 来向controller提供服务.
  2. 我们可以扩展service中的参数, 让controller更多的需求提交给service来实现扩展.

你可能感兴趣的:(You,Are,the,Architect,redis,分布式)