在 foodie-dev-pojo 模块中的 com.imooc.pojo.vo 包内创建 ShopcartVO 类
package com.imooc.pojo.vo;
/**
* Created by 92578 on 2020/8/16 13:57
**/
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;
}
}
在 foodie-dev-mapper 模块中完善 ItemsMapperCustom.xml 文件,新增 queryItemsBySpecIds 查询方法
<?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 sepcName,
ic.created_time as createdTime,
u.face as userFace,
u.nickname as nickname
from items_comments as ic
left join users as 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.price_discount 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 price_discount 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 == "c" ">
i.sell_counts desc
</when>
<when test=" paramsMap.sort == "p" ">
tempSpec.price_discount asc
</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.price_discount 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 price_discount 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 == "c" ">
i.sell_counts desc
</when>
<when test=" paramsMap.sort == "p" ">
tempSpec.price_discount asc
</when>
<otherwise>
i.item_name asc
</otherwise>
</choose>
</select>
<select id="queryItemsBySpecIds" parameterType="List" resultType="com.imooc.pojo.vo.ShopcartVO">
SELECT
t_items.id AS itemId,
t_items.item_name AS itemName,
t_items_img.url AS itemImgUrl,
t_items_spec.id AS specId,
t_items_spec.`name` AS specName,
t_items_spec.price_discount AS priceDiscount,
t_items_spec.price_normal AS priceNormal
FROM
items_spec t_items_spec
LEFT JOIN items t_items ON t_items.id = t_items_spec.item_id
LEFT JOIN items_img t_items_img ON t_items_img.item_id = t_items.id
WHERE
t_items_img.is_main = 1
AND t_items_spec.id IN
<foreach collection="paramsList" index="index" item="specId" open="(" separator="," close=")">
#{specId}
</foreach>
</select>
</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”进行登录
随便添加两样商品到购物车,点击购物车
再次添加商品到购物车,随后刷新购物车页面,添加的商品也显示在购物车中