【項目學習】穀粒商城學習記錄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());
      }
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章