【项目学习】谷粒商城学习记录8 - 购物车

【项目学习】谷粒商城学习记录8 - 购物车

本节起将不对一些重复细节进行详细说明


一、环境搭建 & 准备工作

1.1. 创建新模块

  • 注意java版本信息后面在pom.xml文件里修改

  • 导入公共模块依赖
  • 写配置信息
  • 启动类加上注册发现和Feign功能
  • 修改网关
    - id: gulimall_cart_route
      uri: lb://gulimall-cart
      predicates:
      	- Host=cart.gulimall.cn
    

1.2. 静态页面搭建

  • 设置域名
  • 将注册页面和登录页面放在服务资源目录下
  • 登录、注册页面动静分离,将静态资源移到nginx下
  • 修改页面内的路径
  • 测试:

1.3. 数据存储结构:

1.4. 完善页面细节,实现页面跳转

二、ThreadLocal 用户身份鉴别

  • 创建service.CartService和impl.CartServiceImpl

  • 创建拦截器interceptor.CartInterceptor

  • 实现拦截器在业务执行前的功能:

    public class CartInterceptor implements HandlerInterceptor {
      public static ThreadLocal<UserInfoTo> threadLocal = new ThreadLocal<>();
    
      /**
       * 目标方法执行之前
       * @param request
       * @param response
       * @param handler
       * @return
       * @throws Exception
       */
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
          UserInfoTo userInfoTo = new UserInfoTo();
    
          HttpSession session = request.getSession();
          MemberRespVo member = (MemberRespVo) session.getAttribute(AuthServerConstant.LOGIN_USER);
          if(member != null) {
              //用户登录了
              userInfoTo.setUserId(member.getId());
          }
    
          Cookie[] cookies = request.getCookies();
          if(cookies != null && cookies.length > 0) {
              for (Cookie cookie : cookies) {
                  //user-key
                  String name = cookie.getName();
                  if(name.equals(CartConstant.TEMP_USER_COOKIE_NAME)) {
                      userInfoTo.setUserKey(cookie.getValue());
                      userInfoTo.setTempUser(true);
                  }
              }
          }
    
          //如果没有临时用户一定分配一个临时用户
          if(StringUtils.isEmpty(userInfoTo.getUserKey())) {
              String uuid = UUID.randomUUID().toString();
              userInfoTo.setUserKey(uuid);
          }
          //目标方法执行之前
          threadLocal.set(userInfoTo);
          return true;
      }
    }
    
  • ThreadLocal能够在整个线程内共享数据

  • 测试:

  • 实现拦截器在业务处理后的功能

    /**
     * 业务执行之后,分配临时用户,让浏览器保存
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        UserInfoTo userInfoTo = threadLocal.get();
        if(!userInfoTo.isTempUser()) {
            Cookie cookie = new Cookie(CartConstant.TEMP_USER_COOKIE_NAME, userInfoTo.getUserKey());
            cookie.setDomain("gulimall.com");
            cookie.setMaxAge(CartConstant.TEMP_USER_COOKIE_TIMEOUT);
            response.addCookie(cookie);
        }
    }
    
  • 测试:

三、实现添加购物车功能

  • 商品详情页点击添加购物车后,将传递skuId和numInput两个参数

  • 测试


    登陆后不再使用临时用户

  • 为了避免链接被多次刷新,使用页面重定向的方式。即添加后重定向到展示页面

    • 代码
      /**
       * 添加商品到购物车
       * @return
       */
      @GetMapping("/addToCart")
      public String addToCart(@RequestParam("skuId") Long skuId,
                              @RequestParam("num") Integer num,
                              RedirectAttributes ra) throws ExecutionException, InterruptedException {
      
          cartService.addToCart(skuId, num);
          ra.addAttribute("skuId", skuId);
          return "redirect:/addToCartSuccess.html";
      }
      
      @GetMapping("/addToCartSuccess.html")
      public String addToCartSuccessPage(@RequestParam("skuId") Long skuId, Model model) {
          //重定向到成功页面,查询购物车数据
          CartItem cartItem = cartService.getCartItem(skuId);
          model.addAttribute("item", cartItem);
          return "success";
      }
      
    • getCartItem方法具体实现
      @Override
      public CartItem getCartItem(Long skuId) {
          BoundHashOperations<String, Object, Object> cartOps = getCartOps();
          String str = (String) cartOps.get(skuId.toString());
          CartItem cartItem = JSON.parseObject(str, CartItem.class);
          return cartItem;
      }
      
  • 实现获取购物车,合并购物车功能

    • 测试:

      实现购物车合并成功
  • 实现修改购物车状态

    • 前端页面绑定点击事件
      $(".itemCheck").click(function () {
          var skuId = $(this).attr("skuId");
          var check = $(this).prop("checked");
          location.href = "http://cart.gulimall.com/checkItem?skuId="+skuId+"&check="+(check ? 1 : 0);
      })
      
    • controller层
      /**
       * 修改购物项选择状态
       * @param skuId
       * @param check
       * @return
       */
      @GetMapping("/checkItem")
      public String checkItem(@RequestParam("skuId") Long skuId,
                              @RequestParam("check") Integer check) {
          cartService.checkItem(skuId, check);
      
          return "redirect:http://cart.gulimall.com/cart.html";
      }
      
    • 具体实现
      @Override
      public void checkItem(Long skuId, Integer check) {
          BoundHashOperations<String, Object, Object> cartOps = getCartOps();
          CartItem cartItem = getCartItem(skuId);
          cartItem.setCheck(check == 1);
          String s = JSON.toJSONString(cartItem);
          cartOps.put(skuId.toString(), s);
      }
      
  • 实现增减购物车选项数量

    • 前端修改
      $(".countOpsBtn").click(function () {
          var skuId = $(this).parent().attr("skuId");
          var num = $(this).parent().find(".countOpsNum").text();
          location.href = "http://cart.gulimall.com/countItem?skuId="+skuId+"&num="+num;
      })
      
    • controller层
      /**
       * 修改购物车选项数量
       * @param skuId
       * @param num
       * @return
       */
      @GetMapping("/countItem")
      public String countItem(@RequestParam("skuId") Long skuId,
                              @RequestParam("num") Integer num) {
          cartService.changeItemCount(skuId, num);
          return "redirect:http://cart.gulimall.com/cart.html";
      }
      
    • 具体实现
      /**
       * 修改购物选项数量
       * @param skuId
       * @param num
       */
      @Override
      public void changeItemCount(Long skuId, Integer num) {
          BoundHashOperations<String, Object, Object> cartOps = getCartOps();
          CartItem cartItem = getCartItem(skuId);
          cartItem.setCount(num);
          String s = JSON.toJSONString(cartItem);
          cartOps.put(skuId.toString(), s);
      }
      
  • 实现删除购物车选项功能

    • 前端修改:

      var deleteId = 0;
      //删除购物项
      function deleteItem() {
         location.href = "http://cart.gulimall.com/deleteItem?skuId="+deleteId;
      }
      
      $(".deleteItemBtn").click(function () {
         deleteId = $(this).attr("skuId");
      })
      
    • controller
      /**
       * 删除购物车选项
       * @param skuId
       * @return
       */
      @GetMapping("/deleteItem")
      public String deleteItem(@RequestParam("skuId") Long skuId) {
          cartService.deleteItem(skuId);
          return "redirect:http://cart.gulimall.com/cart.html";
      }
      
    • 具体实现
      /**
       * 删除购物车选项
       * @param skuId
       */
      @Override
      public void deleteItem(Long skuId) {
          BoundHashOperations<String, Object, Object> cartOps = getCartOps();
          cartOps.delete(skuId.toString());
      }
      
posted @ 2023-12-19 21:42  A_sc  阅读(26)  评论(0编辑  收藏  举报