购物车

购物车功能

分析:

购物车功能实现思路:

前提:不管有没有登录,购物车数据都是存在Redis里面

未登录时根据session作为id或者随机字符串作为存储redis的key

登录后是把用户名作为redis的key存储

未登录状态:

1.添加购物车的时候,

1)先判断要添加的商品所属的商家在不在购物车里面,

要是存在该商家,再判断是否存在该商品 ,要是存在该商品,直接修改数量和总价就OK,

要是不存在新建一个商品。

2)要是不存在该商家 创建商家 创建商品

登录状态:

1)先查询未登录时的购物车是否有商品,

没有商品,再根据用户名去Redis里面查,然后返回结果

2)要是有商品,把未登录之前的购物车商品和登录后根据用户名查询的商品数据合并,

然后删除未登录之前的购物车

3)然后重新把合并后的数据提交到Redis里面

代码:
@RestController
@RequestMapping("/cart")
public class CartController {
   @Autowired
   private HttpSession session;
   @Autowired
   private HttpServletRequest request;
   @Autowired
   private HttpServletResponse response;
   @Reference
   private CartService cartService;

   // http://cart.gouwu.com/cart/findCartList 查询购物车
   // 从Redis里面查 key是Cookie里的user-key ,user-key是UUID生成的字符串
   // 把sessionId或UUID作为redis的key,还需要把key存放到cookie中
   private String getUserkey() {
       String userKey = null;
       Cookie[] cookies = request.getCookies();
       if (cookies == null) {
           UUID uuid = UUID.randomUUID();
           Cookie cookie = new Cookie("user-key", uuid.toString());
           response.addCookie(cookie);
       } else {
           for (int i = 0; i < cookies.length; i++) {
               Cookie cookie = cookies[i];
               if (cookie.getName().equals("user-key")) {
                   userKey = cookies[i].getValue(); // 从cookie获取value
               }
           }
       }
       return userKey;
     /* 使用工具类的代码
      String sessionId = session.getId();
       //从cookie中获取userkey
       String userkey = CookieUtil.getCookieValue(request, "user-key");
       //如果没有 新建后再放入cookie中
       if(userkey==null){
           userkey = UUID.randomUUID().toString();
           CookieUtil.setCookie(request,response,"user-key",userkey);
       }
       return userkey;*/
   }
   /**
    * 查询购物车的思路:
    * 先查询未登录时的购物车数据
    * 然后判断是否有登录人
    * 如果没有登录人 直接返回当前的购物车数据
    * 如果有登录人  根据userID查询购物车数据
    * 然后查询未登录的时候是否有数据
    * 如果没有数据 直接返回根据userID查到的数据
    * 如果有数据 合并数据
    * 然后 清空未登录时查询的购物车数据
    * 然后重新把合并后的数据提交到Redis里面
    */
   @RequestMapping("/findCartList")
   public List<Cart> findCartList() {
       List<Cart> cartList = cartService.findCartList(getUserkey()); // 未登录时的购物车数据
       String userId = SecurityContextHolder.getContext().getAuthentication().getName();
       if (userId.equals("anonymousUser")) { // 未登录
           return cartList;
       } else { // 已登录
           List<Cart> userIdCartList = cartService.findCartList(userId);  // 根据登录名userId查询购物车数据
           if (cartList.size() == 0) { // 判断未登录时的购物车是否有数据
               return userIdCartList;
           } else { // 有数据
               userIdCartList = cartService.mergeCartList(cartList, userIdCartList); // 两个购物车合并
               cartService.deleteCartListByKey(getUserkey()); // 清空未登录时的购物车数据 因为要删除Redis里面的数据 所以这里传入未登录时候存入Cookie里的随机字符串user-key的值
               cartService.saveCartListToRedis(userId, userIdCartList); //  把合并后的数据放入到redis中
           }
       }
       return cartList;
   }

   /**
    * Cart类 是购物车对象 里面有
    * sellerName 商家名称
    * sellerId 商家ID
    * List<TbOrderItem> orderItemList 购物车明细
    */
   // 添加购物车
   // 实现思路:
   // 先判断要添加的商品所属于的商家在不在cartList里面
   //   如果存在 判断添加的商品是否已经在购物车里面存在了 如果存在 数量+1 总金额也得变化 如果不存在 添加一个新商品
   //   如果不存在 添加一个新商家 添加一个新商品
   /** cart.gouwu.com/cart/addGoodsToCartList?itemId=XX&num=XX
    *  @CrossOrigin(origins="http://item.gouwu.com") //允许http://item.pinyougou.com跨域访问此方法
    *  @CrossOrigin(origins={"http://item.gouwu.com","http://www.gouwu.com"}) 允许http://item.gouwu.com和http://www.gouwu.com跨域访问此方法
    *  页面需要在URL上加上{'withCredentials':true}
    * * */
   @CrossOrigin(origins = "*") //允许所有网站跨域访问此方法
   @RequestMapping("/addGoodsToCartList")
   public Result addGoodsToCartList(Long itemId, int num) {
       try {
           List<Cart> cartList = findCartList(); // 原来的购物车
           cartList = cartService.addGoodsToCartList(cartList, itemId, num);
           String userId = SecurityContextHolder.getContext().getAuthentication().getName();
           if (userId.equals("anonymousUser")) { // 未登录
               cartService.saveCartListToRedis(getUserkey(), cartList);
           } else { // 已登录
               cartService.saveCartListToRedis(userId, cartList);
           }
           return new Result(true, "");
       } catch (RuntimeException e) {
           return new Result(false, e.getMessage());
       } catch (Exception e) {
           e.printStackTrace();
           return new Result(false, "添加失败");
       }
   }
}
Service:
@Service
public class CartServiceImpl implements CartService {
   @Autowired
   private RedisTemplate redisTemplate;
   @Autowired
   private TbItemMapper itemMapper;
 
   // 从Redis查询购物车数据
   @Override
   public List<Cart> findCartList(String userKey) {
       List<Cart> cartList = (List<Cart>) redisTemplate.boundHashOps("cartList").get(userKey);
       if (cartList == null) {
           // return null;
           cartList = new ArrayList<Cart>(); // 如果查不到 返回一个空的集合
       }
       return cartList;
   }

   // 判断要添加的商品所属的商家是否已经存在购物车 如果有返回该Cart对象
   private Cart isSellerIdInCart(List<Cart> cartList, String sellerId) {
       for (Cart cart : cartList) {
           if (cart.getSellerId().equals(sellerId)) {
               return cart;
           }
       }
       return null;
   }

   // 判断要添加的商品是否已经存在购物车 如果有返回商品orderItem对象
   private TbOrderItem isGoodsInCartOrderItemList(List<TbOrderItem> orderItemList, Long itemId) {
       for (TbOrderItem orderItem : orderItemList) {
           if (itemId.longValue() == orderItem.getItemId().longValue()) {
               return orderItem;
           }
       }
       return null;
   }

   // 添加购物车
   // 实现思路:
   // 先判断要添加的商品所属于的商家在不在cartList里面
   //   如果存在 判断添加的商品是否已经在购物车里面存在了 如果存在 数量+1 总金额也得变化 如果不存在 添加一个新商品
   //   如果不存在 添加一个新商家 添加一个新商品
   // cart.pinyougou.com/cart/addGoodsToCartList?itemId=XX&num=XX
   @Override
   public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, int num) {
       TbItem tbItem = itemMapper.selectByPrimaryKey(itemId); // 去sku表查询 是否有该商品
       if (tbItem == null) {
           throw new RuntimeException("该商品不存在!");
       }
       Cart cart = isSellerIdInCart(cartList, tbItem.getSellerId()); // 判断要添加的商品所属的商家是否已经存在购物车
       if (cart != null) { // 如果存在该商家
           List<TbOrderItem> orderItemList = cart.getOrderItemList(); // 从Cart里获取商品 orderItemList
           TbOrderItem orderItem = isGoodsInCartOrderItemList(orderItemList, itemId); // 判断要添加的商品是否已经存在购物车
           if (orderItem != null) { // 如果该商品已经存在
               Integer nums = orderItem.getNum() + num;
               orderItem.setNum(nums);
               double totalFee = orderItem.getPrice().doubleValue() * orderItem.getNum(); //小计金额
               orderItem.setTotalFee(new BigDecimal(totalFee));
               if (orderItem.getNum() <= 0) {  //考虑减数量的情况
                   // 把该商品orderItem从orderItemList中移除
                   orderItemList.remove(orderItem);
                   // 判断此购物车对象中是否有商品
                   if (orderItemList.size() == 0) {  //如果一个商家中没有商品了 应该移除此购物车对象
                       cartList.remove(cart);
                   }
               }
           } else { // 如果没有该商品 添加商品
               orderItem = new TbOrderItem();
               orderItem.setNum(num);
               orderItem.setPrice(tbItem.getPrice());
               double totalFee = orderItem.getPrice().doubleValue() * orderItem.getNum(); //小计金额
               orderItem.setTotalFee(new BigDecimal(totalFee));
               // orderItem.setId();  // TODO 插入到mysql时考虑id
               // orderItem.setOrderId(); // TODO 插入到mysql时考虑id
               orderItem.setTitle(tbItem.getTitle());
               orderItem.setSellerId(tbItem.getSellerId());
               orderItem.setPicPath(tbItem.getImage());
               orderItem.setItemId(tbItem.getId());
               orderItem.setGoodsId(tbItem.getGoodsId());
               orderItemList.add(orderItem); //添加的商品追加到 Cart -> orderItemList
           }

       } else { // 如果不存在该商家
           cart = new Cart();
           cart.setSellerId(tbItem.getSellerId());
           cart.setSellerName(tbItem.getSeller());
           List<TbOrderItem> orderItemList = new ArrayList<TbOrderItem>();
           TbOrderItem orderItem = new TbOrderItem();
           orderItem.setNum(num);
           orderItem.setPrice(tbItem.getPrice());
           double totalFee = orderItem.getPrice().doubleValue() * orderItem.getNum(); //小计金额
           orderItem.setTotalFee(new BigDecimal(totalFee));
           // orderItem.setId();  // TODO 插入到mysql时考虑id
           // orderItem.setOrderId(); // TODO 插入到mysql时考虑id
           orderItem.setTitle(tbItem.getTitle());
           orderItem.setSellerId(tbItem.getSellerId());
           orderItem.setPicPath(tbItem.getImage());
           orderItem.setItemId(tbItem.getId());
           orderItem.setGoodsId(tbItem.getGoodsId());
           orderItemList.add(orderItem); //添加的商品追加到 Cart -> orderItemList
           cart.setOrderItemList(orderItemList);
           // 把新创建的cart放入到cartList中
           cartList.add(cart);

       }
       return cartList;
   }

   // 添加数据到Redis
   @Override
   public void saveCartListToRedis(String userkey, List<Cart> cartList) {
       redisTemplate.boundHashOps("cartList").put(userkey, cartList);
   }

   // 合并购物车数据
   @Override
   public List<Cart> mergeCartList(List<Cart> cartList, List<Cart> userIdCartList) {
      /* 错误写法
       List<Cart> list = new ArrayList<Cart>();
       list.add(cartList);
       */
       // 把登录之前的购物车数据合并到登录后的购物车数据
       for (Cart cart : cartList) {
           List<TbOrderItem> orderItemList = cart.getOrderItemList(); // 获取Cart类里面所有商品
           for (TbOrderItem orderItem : orderItemList) {
               userIdCartList = addGoodsToCartList(userIdCartList, orderItem.getItemId(), orderItem.getNum());
           }
       }
       return userIdCartList;
   }

   // 删除Redis数据
   @Override
   public void deleteCartListByKey(String userkey) {
       redisTemplate.boundHashOps("cartList").delete(userkey);
   }
}

发表评论