在 foodie-dev-pojo 模块中的 com.imooc.pojo.vo 包内创建 SearchItemsVO 类
package com.imooc.pojo.vo;
/**
* 用于展示商品搜索列表结果的 VO
* Created by 92578 on 2020/8/22 21:28
**/
public class SearchItemsVO {
private String itemId;
private String itemName;
private int sellCounts;
private String imgUrl;
private int price;
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getSellCounts() {
return sellCounts;
}
public void setSellCounts(int sellCounts) {
this.sellCounts = sellCounts;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
【注意】
涉及到金额都是以“分”为单位,保证金额不会有任何差错,因为以“元”为单位在计算的时候会有四舍五入的问题
在 foodie-dev-mapper 模块中完善 ItemsMapperCustom.xml,添加 searchItems 查询语句
k:默认,代表默认排序,根据 name
c:根据销量排序
p:根据价格排序
<?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>
</mapper>
【注意】
如果单引号识别不了,需要对其进行转义
在 foodie-dev-service 模块中完善 ItemService 接口,添加 searchItems 方法
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.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);
}
在 foodie-dev-mapper 模块中完善 ItemsMapperCustom 接口,添加 searchItems 方法
package com.imooc.mapper;
import com.imooc.pojo.vo.ItemCommentVO;
import com.imooc.pojo.vo.SearchItemsVO;
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);
}
在 foodie-dev-service 模块中完善 ItemServiceImpl 类,添加 searchItems 方法
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.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.HashMap;
import java.util.List;
import java.util.Map;
/**
* 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);
}
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 类,添加 search 方法
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.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);
}
}
在 foodie-dev-api 模块中完善 BaseController 类,添加 PAGE_SIZE 常量
package com.imooc.controller;
import org.springframework.stereotype.Controller;
/**
* @author 92578
* @since 1.0
*/
@Controller
public class BaseController {
public static final Integer COMMENT_PAGE_SIZE = 10;
public static final Integer PAGE_SIZE = 20;
}
启动项目,访问 http://localhost:8088/doc.html
找到商品信息展示的相关接口——搜索商品列表
访问 http://localhost:8080/foodie-shop/
搜索“好吃”
点击“销量排序”
点击“价格排序”
搜索“网红”