请求接口都需要携带token
获取token
一、购物车的存储形式
1、cookie存放数据
无须登录、无须查库、保存在浏览器端
优点:性能好、访问快、没有和数据库交互。
缺点1:换浏览器购物车数据会丢失。
缺点2:电脑被他人使用,存在隐私安全。
2、session存放数据
用户登录后,购物车数据放入用户会话
优点:初期性能较好、访问快。
缺点1:session基于内存、用户量庞大影响服务器性能。
缺点2:只能存在于当前回话,不适用集群与分布式系统。
3、数据库存放数据
用户登录后,购物车数据存入数据库
优点:数据持久化,可在任何地点任何时间访问。
缺点:频繁读写数据库,造成数据库压力。
4、Redis存放数据
用户登录后,购物车数据存入redis缓存
优点1:数据持久化,可以在任何地点任何时间访问。
优点2:频繁读写只基于缓存,不会造成数据库压力。
优点3:适用于集群与分布式系统,可扩展性强
系统使用的是cookie+redis的形式,用户未登陆用的是cookie,登陆后用的cookie+redis相互结合
二、未登录已登录加入购物车业务代码
1、前端vue构建购物车的商品对象
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 + '\'' + '}'; }
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(); }
待完善方法体
登陆后后端的接口要判断相应的权限等等,那么这个权限又和redis,分布式会话有关,并且还涉及到拦截器。这些内容我们都会在分布式缓存里面所涉及到。
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; }
三、刷新购物车
cookie中的数据拿出来在页面上做渲染是可以的吗?答案是不可以。这是因为我们的数据保存在前端,它只是一种临时的数据。购物车里面的数据,它不可能马上去结算去买单的。他有可能明天后天甚至过一个礼拜再打开。那么再打开购物车的时候,价格还是cookie里面的价格。当用户进入到购物车这个页面的时候,我们一定要刷新一下购物车里面的商品数据。如果说价格发生了更改,商品的图片、规则、名称都发生更改的话,我们就需要重新的刷新相关的数据。商品的数量是不需要做更新。尤其是金额需要做刷新。所以我们要把相应的数据,尤其是购物车里规格的id发发送到后端。让后端去查询出来购物车相关的数据,再放到页面上展示。
1、前端业务
(1)在声明周期函数里面找到renderShopcart方法,首先获取cookie中购物车的数据,如果没有就返回空
2)for循环拼接购物车的数据
拼接完就是以逗号分隔开的字符串,如下: 1001,1002,3003,4004
(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’)
(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 == "c " ">
i.sell_counts desc
</when>
<when test=" paramsMap.sort == "p " ">
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 == "c " ">
i.sell_counts desc
</when>
<when test=" paramsMap.sort == "p " ">
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>
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;
}
}
(4)定义接口方法
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);
}
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);
}
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);
}
}
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);
}
}
购物车内商品的删除,考虑两种情况,一个是用户未登陆,一个是用户已登录。
如果未登陆直接在前端删除,如果用户已登录,那么就要拿着这条数据到后端的购物车里面删除。这样也是保证我们前后端数据的同步。
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();
}
}