知行合一

博客园 首页 新随笔 联系 订阅 管理

一、购物车的存储形式

1、cookie存放数据

         无须登录、无须查库、保存在浏览器端

         优点:性能好、访问快、没有和数据库交互。

          缺点1:换浏览器购物车数据会丢失。

          缺点2:电脑被他人使用,存在隐私安全。

2、session存放数据

         用户登录后,购物车数据放入用户会话

         优点:初期性能较好、访问快。

          缺点1:session基于内存、用户量庞大影响服务器性能。

          缺点2:只能存在于当前回话,不适用集群与分布式系统。

3、数据库存放数据

         用户登录后,购物车数据存入数据库

        优点:数据持久化,可在任何地点任何时间访问。

         缺点:频繁读写数据库,造成数据库压力。

4、Redis存放数据

          用户登录后,购物车数据存入redis缓存

        优点1:数据持久化,可以在任何地点任何时间访问。

       优点2:频繁读写只基于缓存,不会造成数据库压力。

       优点3:适用于集群与分布式系统,可扩展性强

 

系统使用的是cookie+redis的形式,用户未登陆用的是cookie,登陆后用的cookie+redis相互结合

 

二、未登录已登录加入购物车业务代码

    1、前端vue构建购物车的商品对象

         

     2、前端购物车的数据覆盖本地的cookie

          

    3、前端是在这里调用后端服务的。传递了shopcartItem这个对象。

     

     3、服务端

          1) 创建ShopcartBO对象

          

        

package com.imooc.pojo.bo;

public class ShopcartBO {

    private  String itemId;
    private  String itemImgUrl;
    private  String itemName;
    private  String specId;
    private  String specName;
    private  Integer buyCounts;
    private  String priceDiscount;
    private  String priceNormal;

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getItemImgUrl() {
        return itemImgUrl;
    }

    public void setItemImgUrl(String itemImgUrl) {
        this.itemImgUrl = itemImgUrl;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getSpecId() {
        return specId;
    }

    public void setSpecId(String specId) {
        this.specId = specId;
    }

    public String getSpecName() {
        return specName;
    }

    public void setSpecName(String specName) {
        this.specName = specName;
    }

    public Integer getBuyCounts() {
        return buyCounts;
    }

    public void setBuyCounts(Integer buyCounts) {
        this.buyCounts = buyCounts;
    }

    public String getPriceDiscount() {
        return priceDiscount;
    }

    public void setPriceDiscount(String priceDiscount) {
        this.priceDiscount = priceDiscount;
    }

    public String getPriceNormal() {
        return priceNormal;
    }

    public void setPriceNormal(String priceNormal) {
        this.priceNormal = priceNormal;
    }

    @Override
    public String toString() {
        return "ShopcartBO{" +
                "itemId='" + itemId + '\'' +
                ", itemImgUrl='" + itemImgUrl + '\'' +
                ", itemName='" + itemName + '\'' +
                ", specId='" + specId + '\'' +
                ", specName='" + specName + '\'' +
                ", buyCounts=" + buyCounts +
                ", priceDiscount='" + priceDiscount + '\'' +
                ", priceNormal='" + priceNormal + '\'' +
                '}';
    }
}
View Code

      2)添加商品到购物车

         

       3、  后端方法设计到cookie。那么就会用到request对象。

         

package com.imooc.controller;

import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.utils.IMOOCJSONResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


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

    @ApiOperation(value = "添加商品到购物车",notes = "添加商品到购物车",httpMethod = "POST")
    @PostMapping("/add")
    public IMOOCJSONResult add(
            @RequestParam String userId,
            @RequestBody ShopcartBO shopcartBO,
            HttpServletRequest request,
            HttpServletResponse response
            ) {
           if (StringUtils.isBlank(userId)) {
             return   IMOOCJSONResult.errorMsg("");
           }
        System.out.println(shopcartBO);
           //TODO 前端用户在登录的情况下,添加商品到购物车,会同时在后端同步购物车到redis缓存

        return IMOOCJSONResult.ok();

    }

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

        //TODO 用户在页面删除购物车中的商品数据,如果此时用户已经登录,则需要同步删除后端购物车中的数据

        return IMOOCJSONResult.ok();

    }
}
View Code

      

   待完善方法体

        登陆后后端的接口要判断相应的权限等等,那么这个权限又和redis,分布式会话有关,并且还涉及到拦截器。这些内容我们都会在分布式缓存里面所涉及到。

   完善用户登陆的TODO

   

  

package com.imooc.controller;
import com.imooc.pojo.Users;
import com.imooc.pojo.bo.UserBO;
import com.imooc.service.UserService;
import com.imooc.utils.CookieUtils;
import com.imooc.utils.IMOOCJSONResult;
import com.imooc.utils.JsonUtils;
import com.imooc.utils.MD5Utils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Api(value = "注册登录",tags = "用于注册和登录的相关接口")
@RestController
@RequestMapping("passport")
public class PassportController {

    @Autowired
    private UserService userService;

    @ApiOperation(value="用户名是否存在",notes = "用户名是否存在",httpMethod = "GET")
    @GetMapping("/usernameIsExist")
    public IMOOCJSONResult usernameIsExist(@RequestParam String username){
         //1.
        if(StringUtils.isBlank(username)) {
            return IMOOCJSONResult.errorMsg("用户名不能为空");
        }
        //2.
        boolean isExist=userService.queryUsernameIsExist(username);
        if (isExist) {
            return IMOOCJSONResult.errorMsg("用户名已经存在");
        }
        //3.请求成功
        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value="用户注册",notes = "用户注册",httpMethod = "POST")
    @PostMapping("/regist")
    public IMOOCJSONResult regist(@RequestBody UserBO userBO){
        String username = userBO.getUsername();
        String password = userBO.getPassword();
        String confirmPwd=userBO.getConfirmPassword();

          //0
        if(StringUtils.isBlank(username) ||
                StringUtils.isBlank(password)||
                StringUtils.isBlank(confirmPwd)){
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }

         //1
        boolean isExist=userService.queryUsernameIsExist(username);
        if (isExist) {
            return IMOOCJSONResult.errorMsg("用户名已经存在");
        }
        //2
          if(password.length()<6) {
              return IMOOCJSONResult.errorMsg("用户密码不能少于6位");
          }
        //3
        //2
        if(!password.equals(confirmPwd)) {
            return IMOOCJSONResult.errorMsg("两次密码不一致");
        }
        //4
         userService.creatUser(userBO);

        //TODO 生成用户token,存入redis
        //TODO 同步购物车数据

        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value="用户登录",notes = "用户登录",httpMethod = "POST")
    @PostMapping("/login")
    public IMOOCJSONResult login(@RequestBody UserBO userBO,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception{
        String username = userBO.getUsername();
        String password = userBO.getPassword();
        //String confirmPwd=userBO.getConfirmPassword();

        //0
        if(StringUtils.isBlank(username) ||
                StringUtils.isBlank(password)
                ){
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }
       Users user= userService.queryUserForLogin(username,
               MD5Utils.getMD5Str(password));

        if(user==null) {
            return IMOOCJSONResult.errorMsg("用户名和密码不正确");
        }

        user=setNullProperty(user);

        CookieUtils.setCookie(request, response,"user",
                JsonUtils.objectToJson(user),true);

        //TODO 生成用户token,存入redis
        //TODO 同步购物车数据
        return IMOOCJSONResult.ok(user);
    }

    @ApiOperation(value="用户退出登录",notes = "用户退出登录",httpMethod = "POST")
    @PostMapping("/logout")
    public IMOOCJSONResult logout(@RequestParam String userId,HttpServletRequest request, HttpServletResponse response){

        //1
        CookieUtils.deleteCookie(request, response, "user");
        //TODO 用户退出登录,需要清空购物车
        //TODO 分布式会话中需要清除用户数据
        //2
        return IMOOCJSONResult.ok();
    }
     private  Users setNullProperty(Users user)
     {
         user.setPassword(null);
         user.setNickname(null);
         user.setCreatedTime(null);
         return user;

     }

}
View Code

 

三、刷新购物车

 cookie中的数据拿出来在页面上做渲染是可以的吗?答案是不可以。这是因为我们的数据保存在前端,它只是一种临时的数据。购物车里面的数据,它不可能马上去结算去买单的。他有可能明天后天甚至过一个礼拜再打开。那么再打开购物车的时候,价格还是cookie里面的价格。当用户进入到购物车这个页面的时候,我们一定要刷新一下购物车里面的商品数据。如果说价格发生了更改,商品的图片、规则、名称都发生更改的话,我们就需要重新的刷新相关的数据。商品的数量是不需要做更新。尤其是金额需要做刷新。所以我们要把相应的数据,尤其是购物车里规格的id发发送到后端。让后端去查询出来购物车相关的数据,再放到页面上展示。

  1、前端业务

      (1)在声明周期函数里面找到renderShopcart方法,首先获取cookie中购物车的数据,如果没有就返回空

           

       (2)for循环拼接购物车的数据

            

     拼接完就是以逗号分隔开的字符串,如下: 1001,1002,3003,4004

    (3)请求后端的接口

        

   2、后端接口

        (1)我们要查的就是购物车里面的对象。除了buyCounts其余的内容我们都需要。

            

     (2)自定义sql查询语句

           

          

SELECT
    i.id AS itemId,
    ii.url AS itemImgUrl,
    i.item_name AS itemName,
    sp.id AS specId,
    sp.`name` AS specName,
    sp.price_discount AS priceDiscount,
    sp.price_normal AS priceNormal 
FROM
    items_spec sp
    LEFT JOIN items i ON i.id = sp.item_id
    LEFT JOIN items_img ii ON i.id = ii.item_id 
WHERE
    ii.is_main = 1 
    AND sp.id IN (
        'bingan-1001-spec-1',
    'bingan-1001-spec-2',
    'bingan-1001-spec-3')
View Code

       (3)把sql复制到自定义的mapper里面。我们要返回的VO类型和之前写好的ShopcartBO基本是一样的,除了bugCounts这个属性没有。

传入的结合对象命名为paramsList,标签的闭合,循环的内容要在括号内部。里面的每一项元素使用逗号进行间隔。

       

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.imooc.mapper.ItemsMapperCustom" >
  <select id="queryItemComments" parameterType="Map" resultType="com.imooc.pojo.vo.ItemCommentVO">
      SELECT
          ic.comment_level AS commentLevel,
          ic.content AS content,
          ic.sepc_name AS specName,
          ic.created_time AS createdTime,
          u.face AS userFace,
          u.nickname AS nickName
      FROM
          items_comments ic
          LEFT JOIN users u ON ic.user_id = u.id
      WHERE
          ic.item_id = #{paramsMap.itemId}
        <if test=" paramsMap.level !=null and paramsMap.level !='' ">
          AND ic.comment_level = #{paramsMap.level}
        </if>
  </select>

    <select id="searchItems" parameterType="Map" resultType="com.imooc.pojo.vo.SearchItemsVO">
            SELECT
                i.id AS itemId,
                i.item_name AS itemName,
                i.sell_counts AS sellCounts,
                ii.url AS imgUrl,
                tempSpec.priceDiscount AS price
            FROM
                items i
                LEFT JOIN items_img ii ON i.id = ii.item_id
                LEFT JOIN ( SELECT item_id, MIN( price_discount ) AS priceDiscount FROM items_spec GROUP BY item_id ) tempSpec
                ON i.id = tempSpec.item_id
            WHERE
                ii.is_main = 1
                <if test=" paramsMap.keywords !=null and paramsMap.keywords !='' ">
                    AND i.item_name like  '%${paramsMap.keywords}%'
                </if>
                    order by
               <choose>
                   <when test=" paramsMap.sort == &quot;c &quot;  ">
                      i.sell_counts desc
                   </when>
                   <when test=" paramsMap.sort ==  &quot;p &quot;  ">
                       tempSpec.priceDiscount desc
                   </when>
                   <otherwise>
                       i.item_name asc
                   </otherwise>
               </choose>
    </select>

    <select id="searchItemsByThirdCat" parameterType="Map" resultType="com.imooc.pojo.vo.SearchItemsVO">
        SELECT
        i.id AS itemId,
        i.item_name AS itemName,
        i.sell_counts AS sellCounts,
        ii.url AS imgUrl,
        tempSpec.priceDiscount AS price
        FROM
        items i
        LEFT JOIN items_img ii ON i.id = ii.item_id
        LEFT JOIN ( SELECT item_id, MIN( price_discount ) AS priceDiscount FROM items_spec GROUP BY item_id ) tempSpec
        ON i.id = tempSpec.item_id
        WHERE
        ii.is_main = 1
          AND i.cat_id = #{paramsMap.catId}
          order by
        <choose>
            <when test=" paramsMap.sort == &quot;c &quot;  ">
                i.sell_counts desc
            </when>
            <when test=" paramsMap.sort ==  &quot;p &quot;  ">
                 tempSpec.priceDiscount desc
            </when>
            <otherwise>
                i.item_name asc
            </otherwise>
        </choose>
    </select>
    <!-- k:默认,代表默认排序,根据name -->
    <!-- c:根据销量排序 -->
    <!-- p:根据价格排序 -->

    <select id="queryItemsBySpecIds" parameterType="List" resultType="com.imooc.pojo.vo.ShopcartVO">
        SELECT
            i.id AS itemId,
            ii.url AS itemImgUrl,
            i.item_name AS itemName,
            sp.id AS specId,
            sp.`name` AS specName,
            sp.price_discount AS priceDiscount,
            sp.price_normal AS priceNormal
        FROM
            items_spec sp
            LEFT JOIN items i ON i.id = sp.item_id
            LEFT JOIN items_img ii ON i.id = ii.item_id
        WHERE
            ii.is_main = 1
            AND sp.id IN
            <foreach collection="paramsList" index="index" item="specId" open="(" separator="," close=")">
                 #{specId}
            </foreach>

    </select>

</mapper>
View Code

 

package com.imooc.pojo.vo;

public class ShopcartVO {

    private  String itemId;
    private  String itemImgUrl;
    private  String itemName;
    private  String specId;
    private  String specName;
    private  String priceDiscount;
    private  String priceNormal;

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getItemImgUrl() {
        return itemImgUrl;
    }

    public void setItemImgUrl(String itemImgUrl) {
        this.itemImgUrl = itemImgUrl;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getSpecId() {
        return specId;
    }

    public void setSpecId(String specId) {
        this.specId = specId;
    }

    public String getSpecName() {
        return specName;
    }

    public void setSpecName(String specName) {
        this.specName = specName;
    }

    public String getPriceDiscount() {
        return priceDiscount;
    }

    public void setPriceDiscount(String priceDiscount) {
        this.priceDiscount = priceDiscount;
    }

    public String getPriceNormal() {
        return priceNormal;
    }

    public void setPriceNormal(String priceNormal) {
        this.priceNormal = priceNormal;
    }

}
View Code

 (4)定义接口方法

      注意参数名称和xml内保持一致

         

       

package com.imooc.mapper;

import com.imooc.pojo.vo.ItemCommentVO;
import com.imooc.pojo.vo.SearchItemsVO;
import com.imooc.pojo.vo.ShopcartVO;
import org.apache.ibatis.annotations.Param;


import java.util.List;
import java.util.Map;

public interface ItemsMapperCustom  {

    public List<ItemCommentVO> queryItemComments (@Param("paramsMap") Map<String, Object> map);

    public List<SearchItemsVO> searchItems(@Param("paramsMap") Map<String, Object> map);

    public List<SearchItemsVO> searchItemsByThirdCat(@Param("paramsMap") Map<String, Object> map);

    public List<ShopcartVO> queryItemsBySpecIds(@Param("paramsList") List<String> specIds);


}
View Code

   (5)service层

            

          

package com.imooc.service;


import com.imooc.pojo.Items;
import com.imooc.pojo.ItemsImg;
import com.imooc.pojo.ItemsParam;
import com.imooc.pojo.ItemsSpec;
import com.imooc.pojo.vo.CommentLevelCountsVO;
import com.imooc.pojo.vo.ItemCommentVO;
import com.imooc.pojo.vo.SearchItemsVO;
import com.imooc.pojo.vo.ShopcartVO;
import com.imooc.utils.PagedGridResult;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface ItemService {

    /**
     * 根据商品ID查询详情
     * @param itemId
     * @return
     */
    public Items queryItemById(String itemId);

    /**
     * 根据商品ID查询图片列表
     * @param itemId
     * @return
     */
    public List<ItemsImg> queryItemImgList(String itemId);

    /**
     * 根据商品ID查询商品规格列表
     * @param itemId
     * @return
     */
    public List<ItemsSpec> queryItemSpecList(String itemId);

    /**
     * 根据商品ID查询商品参数
     * @param itemId
     * @return
     */
    public ItemsParam queryItemParam(String itemId);

    /**
     * 根据商品id查询商品的评价等级数量
     * @param itemId
     */
    public CommentLevelCountsVO queryItemCommentCounts(String itemId);

    /**
     * 根据商品id查询商品评价(分页)
     * @param itemId
     * @param leve
     * @return
     */
    public PagedGridResult queryPagedComments (String itemId, Integer leve,Integer page,Integer pageSize);

    /**
     * 搜索商品列表
     * @param keyWords
     * @param sort
     * @param page
     * @param pageSize
     * @return
     */
    public PagedGridResult searchItems(String keyWords,String sort,Integer page,Integer pageSize);

    /**
     * 三级分类商品列表
     * @param catId
     * @param sort
     * @param page
     * @param pageSize
     * @return
     */
    public PagedGridResult searchItemsByThirdCat(Integer catId,String sort,Integer page,Integer pageSize);

    /**
     * 根据规格ids查询最新的购物车中商品数据(用于刷新渲染购物车中的商品数据)
     * @param specIds
     * @return
     */
    public List<ShopcartVO> queryItemsBySpecIds(String specIds);

}
View Code

 

            

       

package com.imooc.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imooc.enums.CommentLevel;
import com.imooc.mapper.*;
import com.imooc.pojo.*;
import com.imooc.pojo.vo.CommentLevelCountsVO;
import com.imooc.pojo.vo.ItemCommentVO;
import com.imooc.pojo.vo.SearchItemsVO;
import com.imooc.pojo.vo.ShopcartVO;
import com.imooc.service.ItemService;
import com.imooc.utils.DesensitizationUtil;
import com.imooc.utils.PagedGridResult;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Service
public class ItemServiceImpl implements ItemService {
    @Autowired
    ItemsMapper itemsMapper;

    @Autowired
    ItemsImgMapper itemsImgMapper;

    @Autowired
    ItemsSpecMapper itemsSpecMapper;

    @Autowired
    ItemsParamMapper itemsParamMapper;

    @Autowired
    ItemsCommentsMapper itemsCommentsCommentsMapper;

    @Autowired
    ItemsMapperCustom itemsMapperCustom;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Items queryItemById(String itemId) {
        return itemsMapper.selectByPrimaryKey(itemId);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ItemsImg> queryItemImgList(String itemId) {
        Example itemsImgExp = new Example(ItemsImg.class);
        Example.Criteria criteria =itemsImgExp.createCriteria();
        criteria.andEqualTo("itemId",itemId);
        return itemsImgMapper.selectByExample(itemsImgExp);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ItemsSpec> queryItemSpecList(String itemId) {
        Example itemsSpecExp = new Example(ItemsSpec.class);
        Example.Criteria criteria =itemsSpecExp.createCriteria();
        criteria.andEqualTo("itemId",itemId);
        return itemsSpecMapper.selectByExample(itemsSpecExp);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ItemsParam queryItemParam(String itemId) {
        Example itemsParamExp = new Example(ItemsParam.class);
        Example.Criteria criteria =itemsParamExp.createCriteria();
        criteria.andEqualTo("itemId",itemId);
        return itemsParamMapper.selectOneByExample(itemsParamExp);
    }



    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public CommentLevelCountsVO queryItemCommentCounts(String itemId) {

       //Integer totalCounts=getCommentCounts(itemId);
        Integer goodCounts=getCommentCounts(itemId, CommentLevel.Good.type);
        Integer normalCounts=getCommentCounts(itemId, CommentLevel.NORMAL.type);
        Integer badCounts=getCommentCounts(itemId, CommentLevel.BAD.type);
        Integer totalCounts=goodCounts+normalCounts+badCounts;

        CommentLevelCountsVO commentLevelCountsVO=new CommentLevelCountsVO();
        commentLevelCountsVO.setTotalCounts(totalCounts);
        commentLevelCountsVO.setGoodCounts(goodCounts);
        commentLevelCountsVO.setNormalCounts(normalCounts);
        commentLevelCountsVO.setBadCounts(badCounts);
        return commentLevelCountsVO;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
     Integer getCommentCounts(String itemId,Integer level){

        ItemsComments confdition =new ItemsComments();
        confdition.setItemId(itemId);
        if (level != null) {
            confdition.setCommentLevel(level);
        }

      return   itemsCommentsCommentsMapper.selectCount(confdition);

    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult queryPagedComments(String itemId,
                                                  Integer level,
                                                  Integer page,
                                                  Integer pageSzie) {
        Map<String,Object> map =new HashMap<>();
        map.put("itemId",itemId);
        map.put("level",level);
        /**
         * page:第几页
         * pageSize:每页显示多少条
         */
        PageHelper.startPage(page,pageSzie);
        List<ItemCommentVO> list=itemsMapperCustom.queryItemComments(map);
        for (ItemCommentVO vo : list
             ) {
              vo.setNickName(DesensitizationUtil.commonDisplay(vo.getNickName()));
        }
        return setterPagedGrid(list,page);

    }

    private PagedGridResult setterPagedGrid(List<?> list,Integer page){

        PageInfo<?> pageList = new PageInfo<>(list);
        PagedGridResult grid = new PagedGridResult();
        grid.setPage(page);
        grid.setRows(list);
        grid.setTotal(pageList.getPages());
        grid.setRecords(pageList.getTotal());
        return grid;

    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult searchItems(String keywords, String sort, Integer page, Integer pageSize) {
        Map<String,Object> map =new HashMap<>();
        map.put("keywords",keywords);
        map.put("sort",sort);
        /**
         * page:第几页
         * pageSize:每页显示多少条
         */
        PageHelper.startPage(page,pageSize);
        List<SearchItemsVO> list=itemsMapperCustom.searchItems(map);
        return setterPagedGrid(list,page);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult searchItemsByThirdCat(Integer catId, String sort, Integer page, Integer pageSize) {
        Map<String,Object> map =new HashMap<>();
        map.put("catId",catId);
        map.put("sort",sort);
        /**
         * page:第几页
         * pageSize:每页显示多少条
         */
        PageHelper.startPage(page,pageSize);
        List<SearchItemsVO> list=itemsMapperCustom.searchItemsByThirdCat(map);
        return setterPagedGrid(list,page);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ShopcartVO> queryItemsBySpecIds(String specIds) {

        String ids[] =specIds.split(",");
        List<String> specIdList = new ArrayList<>();
        Collections.addAll(specIdList,ids);
        return itemsMapperCustom.queryItemsBySpecIds(specIdList);

    }
}
View Code

 (6)Api子模块 (controller层)

     

         

package com.imooc.controller;

import com.imooc.enums.YesOrNo;
import com.imooc.pojo.*;
import com.imooc.pojo.vo.*;
import com.imooc.service.CarouselService;
import com.imooc.service.CategoryService;
import com.imooc.service.ItemService;
import com.imooc.utils.IMOOCJSONResult;
import com.imooc.utils.PagedGridResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(value = "商品接口",tags = "商品信息展示的相关接口")
@RestController
@RequestMapping("item")
public class ItemController {

    @Autowired
     private ItemService itemService;

    @ApiOperation(value="查询商品详情",notes = "查询商品详情",httpMethod = "GET")
    @GetMapping("/info/{itemId}")
    public IMOOCJSONResult info(
            @ApiParam(name = "itemId",value = "商品ID",required = true)
            @PathVariable() String itemId) {
         if (StringUtils.isBlank(itemId)) {

             return IMOOCJSONResult.errorMsg("");

         }


        Items item = itemService.queryItemById(itemId);
        List<ItemsImg> itemImgList=itemService.queryItemImgList(itemId);
        List<ItemsSpec> itemSpecList=itemService.queryItemSpecList(itemId);
        ItemsParam itemParam=itemService.queryItemParam(itemId);
        ItemInfoVO itemInfoVO=new ItemInfoVO();
        itemInfoVO.setItem(item);
        itemInfoVO.setItemImgList(itemImgList);
        itemInfoVO.setItemSpecList(itemSpecList);
        itemInfoVO.setItemParam(itemParam);

        return IMOOCJSONResult.ok(itemInfoVO);
    }


    @ApiOperation(value="查询商品评价分页",notes = "查询商品评价分页",httpMethod = "GET")
    @GetMapping("/comments")
    public IMOOCJSONResult comments(
            @ApiParam(name = "itemId",value = "商品ID",required = true)
            @RequestParam() String itemId,
            @ApiParam(name = "level",value = "评价等级",required = false)
            @RequestParam() Integer level,
            @ApiParam(name = "page",value = "查询下一页的第几页",required = false)
            @RequestParam() Integer page,
            @ApiParam(name = "pageSize",value = "分页每一页显示的条数",required = false)
            @RequestParam() Integer pageSize
            ) {
        if (StringUtils.isBlank(itemId)) {

            return IMOOCJSONResult.errorMsg("");
        }
        if(page==null) {
            page=1;
        }
        if(pageSize==null) {
            pageSize=10;
        }


        PagedGridResult grid = itemService.queryPagedComments(itemId,level,page,pageSize);
        return IMOOCJSONResult.ok(grid);
    }

    @ApiOperation(value="查询商品评价等级",notes = "查询商品评价等级",httpMethod = "GET")
    @GetMapping("/commentLevel")
    public IMOOCJSONResult commentLevel(
            @ApiParam(name = "itemId",value = "商品ID",required = true)
            @RequestParam() String itemId) {
        if (StringUtils.isBlank(itemId)) {

            return IMOOCJSONResult.errorMsg("");

        }
        CommentLevelCountsVO countsVO = itemService.queryItemCommentCounts(itemId);
        return IMOOCJSONResult.ok(countsVO);
    }

    @ApiOperation(value="搜索商品列表分页",notes = "搜索商品列表分页",httpMethod = "GET")
    @GetMapping("/search")
    public IMOOCJSONResult search(
            @ApiParam(name = "keywords",value = "关键字",required = true)
            @RequestParam() String keywords,
            @ApiParam(name = "sort",value = "排序",required = false)
            @RequestParam() String sort,
            @ApiParam(name = "page",value = "查询下一页的第几页",required = false)
            @RequestParam() Integer page,
            @ApiParam(name = "pageSize",value = "分页每一页显示的条数",required = false)
            @RequestParam() Integer pageSize
    ) {
        if (StringUtils.isBlank(keywords)) {

            return IMOOCJSONResult.errorMsg("");
        }
        if (page == null) {
            page = 1;
        }

        if(pageSize==null) {
            pageSize=20;
        }

        PagedGridResult grid = itemService.searchItems(keywords,sort,page,pageSize);
        return IMOOCJSONResult.ok(grid);
    }

    @ApiOperation(value="通过三级分类Id搜索商品列表分页",notes = "通过三级分类Id搜索商品列表分页",httpMethod = "GET")
    @GetMapping("/catItems")
    public IMOOCJSONResult catItems(
            @ApiParam(name = "catId",value = "三级分类id",required = true)
            @RequestParam() Integer catId,
            @ApiParam(name = "sort",value = "排序",required = false)
            @RequestParam() String sort,
            @ApiParam(name = "page",value = "查询下一页的第几页",required = false)
            @RequestParam() Integer page,
            @ApiParam(name = "pageSize",value = "分页每一页显示的条数",required = false)
            @RequestParam() Integer pageSize
    ) {
        if (catId==null) {

            return IMOOCJSONResult.errorMsg("");
        }
        if (page == null) {
            page = 1;
        }

        if(pageSize==null) {
            pageSize=20;
        }

        PagedGridResult grid = itemService.searchItemsByThirdCat(catId,sort,page,pageSize);
        return IMOOCJSONResult.ok(grid);
    }

    //用于用户长时间未登录网站,刷新购物车中的数据(主要是商品价格),类似京东淘宝
    @ApiOperation(value="根据规格ids查询最新的购物车中商品数据",notes = "根据规格ids查询最新的购物车中商品数据",httpMethod = "GET")
    @GetMapping("/refresh")
    public IMOOCJSONResult refresh(
            @ApiParam(name = "itemSpecIds",value = "拼接的规格ids",required = true,example = "1001,1002,1103")
            @RequestParam() String itemSpecIds

    ) {
        if(StringUtils.isBlank(itemSpecIds)) {
            return IMOOCJSONResult.ok();
        }
        List<ShopcartVO> list=itemService.queryItemsBySpecIds(itemSpecIds);
        return IMOOCJSONResult.ok(list);
    }
}
View Code

     7、前端代码

          

          

四、删除商品

  购物车内商品的删除,考虑两种情况,一个是用户未登陆,一个是用户已登录。

  如果未登陆直接在前端删除,如果用户已登录,那么就要拿着这条数据到后端的购物车里面删除。这样也是保证我们前后端数据的同步。

      1、前端代码分析

          删除的方法传入的是商品的规格id。购物车里面,商品是以规格作为单位的。

        

 删除前端对象中的这个规格的商品

 新的list重新放到cookie里面

  

 

  2、用户登陆的情况,把商品的规格id传递到后端

3.后端接口

  

  

package com.imooc.controller;

import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.utils.IMOOCJSONResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


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

    @ApiOperation(value = "添加商品到购物车",notes = "添加商品到购物车",httpMethod = "POST")
    @PostMapping("/add")
    public IMOOCJSONResult add(
            @RequestParam String userId,
            @RequestBody ShopcartBO shopcartBO,
            HttpServletRequest request,
            HttpServletResponse response
            ) {
           if (StringUtils.isBlank(userId)) {
             return   IMOOCJSONResult.errorMsg("");
           }
        System.out.println(shopcartBO);
           //TODO 前端用户在登录的情况下,添加商品到购物车,会同时在后端同步购物车到redis缓存

        return IMOOCJSONResult.ok();

    }

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

        //TODO 用户在页面删除购物车中的商品数据,如果此时用户已经登录,则需要同步删除后端购物车中的数据

        return IMOOCJSONResult.ok();

    }
}
View Code

 五、提交购物车至结算页

  

判断用户是否登陆

  

支付页面的声明周期函数

 

最终的商品数据

posted on 2021-03-07 21:23  callbin  阅读(1936)  评论(0编辑  收藏  举报