在 foodie-dev-pojo 模块中的 com.imooc.pojo.vo 包内创建 ShopcartVO 类

    1. package com.imooc.pojo.vo;
    2. /**
    3. * Created by 92578 on 2020/8/16 13:57
    4. **/
    5. public class ShopcartVO {
    6. private String itemId;
    7. private String itemImgUrl;
    8. private String itemName;
    9. private String specId;
    10. private String specName;
    11. private String priceDiscount;
    12. private String priceNormal;
    13. public String getItemId() {
    14. return itemId;
    15. }
    16. public void setItemId(String itemId) {
    17. this.itemId = itemId;
    18. }
    19. public String getItemImgUrl() {
    20. return itemImgUrl;
    21. }
    22. public void setItemImgUrl(String itemImgUrl) {
    23. this.itemImgUrl = itemImgUrl;
    24. }
    25. public String getItemName() {
    26. return itemName;
    27. }
    28. public void setItemName(String itemName) {
    29. this.itemName = itemName;
    30. }
    31. public String getSpecId() {
    32. return specId;
    33. }
    34. public void setSpecId(String specId) {
    35. this.specId = specId;
    36. }
    37. public String getSpecName() {
    38. return specName;
    39. }
    40. public void setSpecName(String specName) {
    41. this.specName = specName;
    42. }
    43. public String getPriceDiscount() {
    44. return priceDiscount;
    45. }
    46. public void setPriceDiscount(String priceDiscount) {
    47. this.priceDiscount = priceDiscount;
    48. }
    49. public String getPriceNormal() {
    50. return priceNormal;
    51. }
    52. public void setPriceNormal(String priceNormal) {
    53. this.priceNormal = priceNormal;
    54. }
    55. }

    在 foodie-dev-mapper 模块中完善 ItemsMapperCustom.xml 文件,新增 queryItemsBySpecIds 查询方法

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="com.imooc.mapper.ItemsMapperCustom">
    4. <select id="queryItemComments" parameterType="Map" resultType="com.imooc.pojo.vo.ItemCommentVO">
    5. select ic.comment_level as commentLevel,
    6. ic.content as content,
    7. ic.sepc_name as sepcName,
    8. ic.created_time as createdTime,
    9. u.face as userFace,
    10. u.nickname as nickname
    11. from items_comments as ic
    12. left join users as u on ic.user_id = u.id
    13. where ic.item_id = #{paramsMap.itemId}
    14. <if test=" paramsMap.level != null and paramsMap.level != '' ">
    15. and ic.comment_level = #{paramsMap.level}
    16. </if>
    17. </select>
    18. <select id="searchItems" parameterType="Map" resultType="com.imooc.pojo.vo.SearchItemsVO">
    19. SELECT
    20. i.id AS itemId,
    21. i.item_name AS itemName,
    22. i.sell_counts AS sellCounts,
    23. ii.url AS imgUrl,
    24. tempSpec.price_discount AS price
    25. FROM
    26. items i
    27. LEFT JOIN items_img ii ON i.id = ii.item_id
    28. LEFT JOIN ( SELECT item_id, MIN( price_discount ) AS price_discount FROM items_spec GROUP BY item_id ) tempSpec
    29. ON i.id = tempSpec.item_id
    30. WHERE
    31. ii.is_main = 1
    32. <if test=" paramsMap.keywords != null and paramsMap.keywords != '' ">
    33. and i.item_name like '%${paramsMap.keywords}%'
    34. </if>
    35. order by
    36. <choose>
    37. <when test=" paramsMap.sort == &quot;c&quot; ">
    38. i.sell_counts desc
    39. </when>
    40. <when test=" paramsMap.sort == &quot;p&quot; ">
    41. tempSpec.price_discount asc
    42. </when>
    43. <otherwise>
    44. i.item_name asc
    45. </otherwise>
    46. </choose>
    47. </select>
    48. <select id="searchItemsByThirdCat" parameterType="Map" resultType="com.imooc.pojo.vo.SearchItemsVO">
    49. SELECT
    50. i.id AS itemId,
    51. i.item_name AS itemName,
    52. i.sell_counts AS sellCounts,
    53. ii.url AS imgUrl,
    54. tempSpec.price_discount AS price
    55. FROM
    56. items i
    57. LEFT JOIN items_img ii ON i.id = ii.item_id
    58. LEFT JOIN ( SELECT item_id, MIN( price_discount ) AS price_discount FROM items_spec GROUP BY item_id ) tempSpec
    59. ON i.id = tempSpec.item_id
    60. WHERE
    61. ii.is_main = 1
    62. and i.cat_id = #{paramsMap.catId}
    63. order by
    64. <choose>
    65. <when test=" paramsMap.sort == &quot;c&quot; ">
    66. i.sell_counts desc
    67. </when>
    68. <when test=" paramsMap.sort == &quot;p&quot; ">
    69. tempSpec.price_discount asc
    70. </when>
    71. <otherwise>
    72. i.item_name asc
    73. </otherwise>
    74. </choose>
    75. </select>
    76. <select id="queryItemsBySpecIds" parameterType="List" resultType="com.imooc.pojo.vo.ShopcartVO">
    77. SELECT
    78. t_items.id AS itemId,
    79. t_items.item_name AS itemName,
    80. t_items_img.url AS itemImgUrl,
    81. t_items_spec.id AS specId,
    82. t_items_spec.`name` AS specName,
    83. t_items_spec.price_discount AS priceDiscount,
    84. t_items_spec.price_normal AS priceNormal
    85. FROM
    86. items_spec t_items_spec
    87. LEFT JOIN items t_items ON t_items.id = t_items_spec.item_id
    88. LEFT JOIN items_img t_items_img ON t_items_img.item_id = t_items.id
    89. WHERE
    90. t_items_img.is_main = 1
    91. AND t_items_spec.id IN
    92. <foreach collection="paramsList" index="index" item="specId" open="(" separator="," close=")">
    93. #{specId}
    94. </foreach>
    95. </select>
    96. </mapper>

    在 foodie-dev-mapper 模块中完善 ItemsMapperCustom 类,新增 queryItemsBySpecIds 方法

    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> specIdList);
    }
    

    在 foodie-dev-service 模块中完善 ItemService 接口,新增 queryItemsBySpecIds 方法

    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.ShopcartVO;
    import com.imooc.utils.PagedGridResult;
    
    import java.util.List;
    
    /**
     * Created by 92578 on 2020/8/22 16:17
     **/
    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 queryItemsParam(String itemId);
    
        /**
         * 根据商品 id 查询商品的评价等级数量
         *
         * @param itemId
         */
        public CommentLevelCountsVO queryCommentCounts(String itemId);
    
        /**
         * 根据商品 id 查询商品的评价(分页)
         *
         * @param itemId
         * @param level
         * @return
         */
        public PagedGridResult queryPagedComments(String itemId, Integer level, Integer page, Integer pageSize);
    
        /**
         * 搜索商品列表
         *
         * @param keywords
         * @param sort
         * @param page
         * @param pageSize
         * @return
         */
        public PagedGridResult searchItems(String keywords, String sort, Integer page, Integer pageSize);
    
        /**
         * 根据分类 id 搜索商品列表
         *
         * @param catId
         * @param sort
         * @param page
         * @param pageSize
         * @return
         */
        public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize);
    
        /**
         * 根据规格 ids 查询最新的购物车中商品数据(用于刷新渲染购物车中的商品数据)
         *
         * @param specIds
         * @return
         */
        public List<ShopcartVO> queryItemsBySpecIds(String specIds);
    }
    

    在 foodie-dev-service 模块中完善 ItemServiceImpl 类,实现 queryItemsBySpecIds 方法

    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 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.*;
    
    /**
     * Created by 92578 on 2020/8/22 16:18
     **/
    @Service
    public class ItemServiceImpl implements ItemService {
    
        @Autowired
        private ItemsMapper itemsMapper;
    
        @Autowired
        private ItemsImgMapper itemsImgMapper;
    
        @Autowired
        private ItemsSpecMapper itemsSpecMapper;
    
        @Autowired
        private ItemsParamMapper itemsParamMapper;
    
        @Autowired
        private ItemsCommentsMapper itemsCommentsMapper;
    
        @Autowired
        private ItemsMapperCustom itemsMapperCustom;
    
        /**
         * 根据商品 id 查询详情
         *
         * @param itemId
         * @return
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public Items queryItemById(String itemId) {
            return itemsMapper.selectByPrimaryKey(itemId);
        }
    
        /**
         * 根据商品 id 查询商品图片列表
         *
         * @param itemId
         * @return
         */
        @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);
        }
    
        /**
         * 根据商品 id 查询商品规格
         *
         * @param itemId
         * @return
         */
        @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);
        }
    
        /**
         * 根据商品 id 查询商品参数
         *
         * @param itemId
         * @return
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public ItemsParam queryItemsParam(String itemId) {
            Example itemsParamExp = new Example(ItemsParam.class);
            Example.Criteria criteria = itemsParamExp.createCriteria();
            criteria.andEqualTo("itemId", itemId);
    
            return itemsParamMapper.selectOneByExample(itemsParamExp);
        }
    
        /**
         * 根据商品 id 查询商品的评价等级数量
         *
         * @param itemId
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public CommentLevelCountsVO queryCommentCounts(String 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 countsVO = new CommentLevelCountsVO();
            countsVO.setTotalCounts(totalCounts);
            countsVO.setGoodCounts(goodCounts);
            countsVO.setNormalCounts(normalCounts);
            countsVO.setBadCounts(badCounts);
    
            return countsVO;
        }
    
        /**
         * 根据商品 id 查询商品的评价(分页)
         *
         * @param itemId
         * @param level
         * @return
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public PagedGridResult queryPagedComments(String itemId, Integer level, Integer page, Integer pageSize) {
            Map<String, Object> map = new HashMap<>();
            map.put("itemId", itemId);
            map.put("level", level);
    
            /**
             * page: 第几页
             * pageSize: 每页显示条数
             */
            PageHelper.startPage(page, pageSize);
    
            List<ItemCommentVO> list = itemsMapperCustom.queryItemComments(map);
            for (ItemCommentVO vo : list) {
                vo.setNickname(DesensitizationUtil.commonDisplay(vo.getNickname()));
            }
    
            return setterPagedGrid(list, page);
        }
    
        /**
         * 搜索商品列表
         *
         * @param keywords
         * @param sort
         * @param page
         * @param pageSize
         * @return
         */
        @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);
    
            PageHelper.startPage(page, pageSize);
            List<SearchItemsVO> list = itemsMapperCustom.searchItems(map);
    
            return setterPagedGrid(list, page);
        }
    
        /**
         * 根据分类 id 搜索商品列表
         *
         * @param catId
         * @param sort
         * @param page
         * @param pageSize
         * @return
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize) {
            Map<String, Object> map = new HashMap<>();
            map.put("catId", catId);
            map.put("sort", sort);
    
            PageHelper.startPage(page, pageSize);
            List<SearchItemsVO> list = itemsMapperCustom.searchItemsByThirdCat(map);
    
            return setterPagedGrid(list, page);
        }
    
        /**
         * 根据规格 ids 查询最新的购物车中商品数据(用于刷新渲染购物车中的商品数据)
         *
         * @param specIds
         * @return
         */
        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public List<ShopcartVO> queryItemsBySpecIds(String specIds) {
            String ids[] = specIds.split(",");
            List<String> specIdsList = new ArrayList<>();
            Collections.addAll(specIdsList, ids);
    
            return itemsMapperCustom.queryItemsBySpecIds(specIdsList);
        }
    
        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)
        Integer getCommentCounts(String itemId, Integer level) {
            ItemsComments condition = new ItemsComments();
            condition.setItemId(itemId);
            if (level != null) {
                condition.setCommentLevel(level);
            }
    
            return itemsCommentsMapper.selectCount(condition);
        }
    }
    

    在 foodie-dev-api 模块中完善 ItemsController 类,新增 refresh 方法

    package com.imooc.controller;
    
    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.ItemInfoVO;
    import com.imooc.pojo.vo.ShopcartVO;
    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;
    
    /**
     * Created by 92578 on 2020/8/22 16:30
     **/
    @Api(value = "商品接口", tags = {"商品信息展示的相关接口"})
    @RestController
    @RequestMapping("items")
    public class ItemsController extends BaseController {
    
        @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(null);
            }
    
            Items item = itemService.queryItemById(itemId);
            List<ItemsImg> itemsImgList = itemService.queryItemImgList(itemId);
            List<ItemsSpec> itemsSpecList = itemService.queryItemSpecList(itemId);
            ItemsParam itemsParam = itemService.queryItemsParam(itemId);
    
            ItemInfoVO itemInfoVO = new ItemInfoVO();
            itemInfoVO.setItem(item);
            itemInfoVO.setItemImgList(itemsImgList);
            itemInfoVO.setItemSpecList(itemsSpecList);
            itemInfoVO.setItemParams(itemsParam);
    
            return IMOOCJSONResult.ok(itemInfoVO);
        }
    
        @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(null);
            }
    
            CommentLevelCountsVO countsVO = itemService.queryCommentCounts(itemId);
    
            return IMOOCJSONResult.ok(countsVO);
        }
    
        @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(null);
            }
    
            if (page == null) {
                page = 1;
            }
    
            if (pageSize == null) {
                pageSize = COMMENT_PAGE_SIZE;
            }
    
            PagedGridResult grid = itemService.queryPagedComments(itemId, level, page, pageSize);
    
            return IMOOCJSONResult.ok(grid);
        }
    
        @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(null);
            }
    
            if (page == null) {
                page = 1;
            }
    
            if (pageSize == null) {
                pageSize = PAGE_SIZE;
            }
    
            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(null);
            }
    
            if (page == null) {
                page = 1;
            }
    
            if (pageSize == null) {
                pageSize = PAGE_SIZE;
            }
    
            PagedGridResult grid = itemService.searchItems(catId, sort, page, pageSize);
    
            return IMOOCJSONResult.ok(grid);
        }
    
        /**
         * 用于用户长时间未登录网站,刷新购物车中的数据(主要是商品价格),类似京东淘宝
         *
         * @param itemSpecIds
         * @return
         */
        @ApiOperation(value = "根据商品规格 ids 查找最新的商品数据", notes = "根据商品规格 ids 查找最新的商品数据", httpMethod = "GET")
        @GetMapping("/refresh")
        public IMOOCJSONResult refresh(
                @ApiParam(name = "itemSpecIds", value = "拼接的规格 ids", required = true, example = "1001,1003,1005")
                @RequestParam String itemSpecIds) {
            if (StringUtils.isBlank(itemSpecIds)) {
                return IMOOCJSONResult.ok();
            }
    
            List<ShopcartVO> list = itemService.queryItemsBySpecIds(itemSpecIds);
    
            return IMOOCJSONResult.ok(list);
        }
    }
    

    启动项目,打开浏览器,访问 http://localhost:8080/foodie-shop/
    输入用户名“imooc”,密码“123123”进行登录
    随便添加两样商品到购物车,点击购物车
    image.png
    image.png
    再次添加商品到购物车,随后刷新购物车页面,添加的商品也显示在购物车中
    image.png