购物车管理模块是属于用户侧模块,主要有7个接口:添加商品到购物车、更新购物车商品数、移除购物车商品、查看购物车当中list、购物车全选/反选、购物车单选/购物车单反选、查询购物车中产品数量。
1.添加商品到购物车逻辑:首先根据productId、userId检查购物车当中已经存在该商品,如果已经存在,更新产品数量,如果不存在,加入商品到购物车,更新数量。
此时需要做的是检查购物车当中产品数量和产品的库存量,如果库存>=购物车当中数量,则在返回值当中提示成功,如果库存<购物车当中数量,则更新购物车当中的产品数量为库存量,并在返回值当中提示不成功。
在整个购物车管理模块当中真正的核心就是购物车当中产品数量和产品的库存量的校验。在本文当中使用assembleCartVoLimit来作为返回给用户的显示对象,assembleCartVoLimit需要对cart和product进行封装。assembleCartVoLimit首先对cart进行了封装,并且在对product进行封装的时候进行了库存的校验。
//CartProductVo由cart和product组合组成
private CartVo assembleCartVoLimit(Integer userId){
CartVo cartVo=new CartVo();
List<Cart> cartList=cartMapper.selectCartByUserId(userId);
BigDecimal cartTotalPrice=new BigDecimal("0.0");//选中cart总价
List<CartProductVo> cartProductVoList= Lists.newArrayList();
if(CollectionUtils.isNotEmpty(cartList)){
for(Cart cartItem:cartList){
CartProductVo cartProductVo=new CartProductVo();
cartProductVo.setId(cartItem.getId());
cartProductVo.setUserId(cartItem.getUserId());
cartProductVo.setProductId(cartItem.getProductId());
Product product=productMapper.selectByPrimaryKey(cartItem.getProductId());
if(product !=null){
cartProductVo.setProductSubTitle(product.getSubtitle());
cartProductVo.setProductMainImage(product.getMainImage());
cartProductVo.setProductName(product.getName());
cartProductVo.setProductStatus(product.getStatus());
cartProductVo.setProductPrice(product.getPrice());
cartProductVo.setProductStock(product.getStock());
//判断库存
int buyLimitCount=0;
if(product.getStock()>=cartItem.getQuantity()){
buyLimitCount=cartItem.getQuantity();
cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_SUCCESS);
}else {
buyLimitCount=product.getStock();
cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_FAIL);
//由于购物车当中的产品数量超出库存,所以要更新购物车当中的产品数量就为库存
Cart cartForQuantity=new Cart();
cartForQuantity.setId(cartItem.getId());
cartForQuantity.setQuantity(buyLimitCount);
cartMapper.updateByPrimaryKeySelective(cartForQuantity);
}
//设置购物车当中的产品数量
cartProductVo.setQuantity(buyLimitCount);
//单个cart计算总价
cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(buyLimitCount,product.getPrice().doubleValue()));
cartProductVo.setProductChecked(cartItem.getChecked());
}
//判断该用户的cart是够选中
if(cartItem.getChecked()==Const.Cart.CHECKED){
cartTotalPrice=BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVo.getProductTotalPrice().doubleValue());
}
cartProductVoList.add(cartProductVo);
}
}
cartVo.setCartTotalPrice(cartTotalPrice);//总价
cartVo.setCartProductVoList(cartProductVoList);//控制是否全选
cartVo.setAllChecked(this.getAllCheckedStatus(userId));
cartVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
return cartVo;
}
//判断是否是全选,
private boolean getAllCheckedStatus(Integer userId){
if(userId==null){
return false;
}
return cartMapper.selectCartProductCheckedStatus(userId)==0;
}
***********************controller********************************
package com.mall.controller.portal;
import com.mall.common.Const;
import com.mall.common.ResponseCode;
import com.mall.common.ServerResponse;
import com.mall.pojo.User;
import com.mall.service.ICartService;
import com.mall.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/cart/")
public class CartController {
@Autowired
private ICartService iCartService;
@ResponseBody
@RequestMapping("add.do")
public ServerResponse<CartVo> add(HttpSession session, Integer count, Integer productId){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.add(user.getId(),productId,count);
}
@ResponseBody
@RequestMapping("update.do")
public ServerResponse<CartVo> update(HttpSession session, Integer count, Integer productId){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.updateCart(user.getId(),count,productId);
}
@ResponseBody
@RequestMapping("delete_product.do")
public ServerResponse<CartVo> delete(HttpSession session,String productIds){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.deleteCart(user.getId(),productIds);
}
@ResponseBody
@RequestMapping("list.do")
public ServerResponse<CartVo> list(HttpSession session){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.listCart(user.getId());
}
//全选
@ResponseBody
@RequestMapping("select_all.do")
public ServerResponse<CartVo> selectAll(HttpSession session){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.selectOrUnSelect(user.getId(),null,Const.Cart.CHECKED);
}
//全反选
@ResponseBody
@RequestMapping("un_select_all.do")
public ServerResponse<CartVo> UnselectAll(HttpSession session){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.selectOrUnSelect(user.getId(),null,Const.Cart.UN_CHECKED);
}
//单独选
@ResponseBody
@RequestMapping("select.do")
public ServerResponse<CartVo> select(HttpSession session,Integer productId,Integer checked){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.selectOrUnSelect(user.getId(),productId,Const.Cart.CHECKED);
}
//单独反选
@ResponseBody
@RequestMapping("un_select.do")
public ServerResponse<CartVo> Unselect(HttpSession session,Integer productId,Integer checked){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return iCartService.selectOrUnSelect(user.getId(),productId,Const.Cart.UN_CHECKED);
}
//查询当前用户的购物车当中的产品数量,所有cart当中quantity组合
@ResponseBody
@RequestMapping("get_cart_product_count.do")
public ServerResponse<Integer> getCartProductCount(HttpSession session,Integer productId,Integer checked){
User user=(User) session.getAttribute(Const.CURRENT_USER);
if(user==null){
return ServerResponse.createBySuccess(0);
}
return iCartService.getCartProductCount(user.getId());
}
}
***********************service********************************
package com.mall.service.impl;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.mall.common.Const;
import com.mall.common.ResponseCode;
import com.mall.common.ServerResponse;
import com.mall.dao.CartMapper;
import com.mall.dao.ProductMapper;
import com.mall.pojo.Cart;
import com.mall.pojo.Product;
import com.mall.service.ICartService;
import com.mall.util.BigDecimalUtil;
import com.mall.util.PropertiesUtil;
import com.mall.vo.CartProductVo;
import com.mall.vo.CartVo;
import java.math.BigDecimal;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("iCartService")
public class CartServiceImpl implements ICartService {
@Autowired
private CartMapper cartMapper;
@Autowired
private ProductMapper productMapper;
//添加购物车
public ServerResponse<CartVo> add(Integer userId,Integer productId,Integer count){
if(productId==null || count==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
Cart cart=cartMapper.selectCartByUserIdProductId(userId,productId);
if(cart ==null){
//此时该产品不再购物车当中,需要新增产品
Cart cartItem=new Cart();
cartItem.setProductId(productId);
cartItem.setQuantity(count);//后面考虑库存
cartItem.setChecked(Const.Cart.CHECKED);
cartItem.setUserId(userId);
cartMapper.insert(cartItem);
}else{
//产品以存在,更新数量即可,需要判断库存是否足够
count=cart.getQuantity()+count;
cart.setQuantity(count);
cartMapper.updateByPrimaryKeySelective(cart);
}
CartVo cartVo=this.assembleCartVoLimit(userId);//在这个方法当中对数量进行限制
return ServerResponse.createBySuccess(cartVo);
}
//CartProductVo由cart和product组合组成
private CartVo assembleCartVoLimit(Integer userId){
CartVo cartVo=new CartVo();
List<Cart> cartList=cartMapper.selectCartByUserId(userId);
BigDecimal cartTotalPrice=new BigDecimal("0.0");//选中cart总价
List<CartProductVo> cartProductVoList= Lists.newArrayList();
if(CollectionUtils.isNotEmpty(cartList)){
for(Cart cartItem:cartList){
CartProductVo cartProductVo=new CartProductVo();
cartProductVo.setId(cartItem.getId());
cartProductVo.setUserId(cartItem.getUserId());
cartProductVo.setProductId(cartItem.getProductId());
Product product=productMapper.selectByPrimaryKey(cartItem.getProductId());
if(product !=null){
cartProductVo.setProductSubTitle(product.getSubtitle());
cartProductVo.setProductMainImage(product.getMainImage());
cartProductVo.setProductName(product.getName());
cartProductVo.setProductStatus(product.getStatus());
cartProductVo.setProductPrice(product.getPrice());
cartProductVo.setProductStock(product.getStock());
//判断库存
int buyLimitCount=0;
if(product.getStock()>=cartItem.getQuantity()){
buyLimitCount=cartItem.getQuantity();
cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_SUCCESS);
}else {
buyLimitCount=product.getStock();
cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_FAIL);
//由于购物车当中的产品数量超出库存,所以要更新购物车当中的产品数量就为库存
Cart cartForQuantity=new Cart();
cartForQuantity.setId(cartItem.getId());
cartForQuantity.setQuantity(buyLimitCount);
cartMapper.updateByPrimaryKeySelective(cartForQuantity);
}
//设置购物车当中的产品数量
cartProductVo.setQuantity(buyLimitCount);
//单个cart计算总价
cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(buyLimitCount,product.getPrice().doubleValue()));
cartProductVo.setProductChecked(cartItem.getChecked());
}
//判断该用户的cart是够选中
if(cartItem.getChecked()==Const.Cart.CHECKED){
cartTotalPrice=BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVo.getProductTotalPrice().doubleValue());
}
cartProductVoList.add(cartProductVo);
}
}
cartVo.setCartTotalPrice(cartTotalPrice);//总价
cartVo.setCartProductVoList(cartProductVoList);//控制是否全选
cartVo.setAllChecked(this.getAllCheckedStatus(userId));
cartVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
return cartVo;
}
//判断是否是全选,
private boolean getAllCheckedStatus(Integer userId){
if(userId==null){
return false;
}
return cartMapper.selectCartProductCheckedStatus(userId)==0;
}
public ServerResponse<CartVo> updateCart(Integer userId,Integer count,Integer productId){
if(productId==null || count==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
Cart cart=cartMapper.selectCartByUserIdProductId(userId,productId);
if(cart != null){
cart.setQuantity(count);
cartMapper.updateByPrimaryKeySelective(cart);
}
CartVo cartVo=this.assembleCartVoLimit(userId);//库存限制
return ServerResponse.createBySuccess(cartVo);
}
public ServerResponse<CartVo> deleteCart(Integer userId,String productIds){
//使用guava的Splitter工具,将字符串转换为集合
List<String> productIdList= Splitter.on(",").splitToList(productIds);
if(CollectionUtils.isEmpty(productIdList)){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
cartMapper.deleteByUserIds(userId,productIdList);
CartVo cartVo=this.assembleCartVoLimit(userId);//库存限制
return ServerResponse.createBySuccess(cartVo);
}
public ServerResponse<CartVo> listCart(Integer userId){
CartVo cartVo=this.assembleCartVoLimit(userId);//库存限制
return ServerResponse.createBySuccess(cartVo);
}
public ServerResponse<CartVo> selectOrUnSelect(Integer userId,Integer productId,Integer checked){
cartMapper.CheckOrUnCheckedProduct(userId,productId,checked);
return this.listCart(userId);
}
public ServerResponse<Integer> getCartProductCount(Integer userId){
if(userId==null){
return ServerResponse.createByErrorCodeMsg(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());
}
return ServerResponse.createBySuccess(cartMapper.selectCartProductCount(userId));
}
}
***********************xml********************************
<?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.mall.dao.CartMapper" >
<resultMap id="BaseResultMap" type="com.mall.pojo.Cart" >
<constructor >
<idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="user_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="product_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="quantity" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="checked" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
<arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
</constructor>
</resultMap>
<sql id="Base_Column_List" >
id, user_id, product_id, quantity, checked, create_time, update_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from mmall_cart
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from mmall_cart
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.mall.pojo.Cart" >
insert into mmall_cart (id, user_id, product_id,
quantity, checked, create_time,
update_time)
values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER}, #{productId,jdbcType=INTEGER},
#{quantity,jdbcType=INTEGER}, #{checked,jdbcType=INTEGER}, now(),
now())
</insert>
<insert id="insertSelective" parameterType="com.mall.pojo.Cart" >
insert into mmall_cart
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="userId != null" >
user_id,
</if>
<if test="productId != null" >
product_id,
</if>
<if test="quantity != null" >
quantity,
</if>
<if test="checked != null" >
checked,
</if>
<if test="createTime != null" >
create_time,
</if>
<if test="updateTime != null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="userId != null" >
#{userId,jdbcType=INTEGER},
</if>
<if test="productId != null" >
#{productId,jdbcType=INTEGER},
</if>
<if test="quantity != null" >
#{quantity,jdbcType=INTEGER},
</if>
<if test="checked != null" >
#{checked,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
now(),
</if>
<if test="updateTime != null" >
now(),
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.mall.pojo.Cart" >
update mmall_cart
<set >
<if test="userId != null" >
user_id = #{userId,jdbcType=INTEGER},
</if>
<if test="productId != null" >
product_id = #{productId,jdbcType=INTEGER},
</if>
<if test="quantity != null" >
quantity = #{quantity,jdbcType=INTEGER},
</if>
<if test="checked != null" >
checked = #{checked,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
update_time = now(),
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.mall.pojo.Cart" >
update mmall_cart
set user_id = #{userId,jdbcType=INTEGER},
product_id = #{productId,jdbcType=INTEGER},
quantity = #{quantity,jdbcType=INTEGER},
checked = #{checked,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = now()
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectCartByUserIdProductId" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from mmall_cart
where user_id=#{userId} and product_id=#{productId}
</select>
<select id="selectCartByUserId" parameterType="int" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from mmall_cart
where user_id=#{userId}
</select>
<!--如果查出有checked =0,则说明有未勾选的-->
<select id="selectCartProductCheckedStatus" parameterType="int" resultType="int">
select count(1)
from mmall_cart
where checked =0 and user_id=#{userId}
</select>
<delete id="deleteByUserIds" parameterType="map" >
delete from mmall_cart
where user_id=#{userId}
<if test="productIds != null">
and product_id in
<foreach collection="productIds" item="item" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</delete>
<update id="CheckOrUnCheckedProduct" parameterType="map" >
update mmall_cart
set checked = #{checked} , update_time = now()
where user_id = #{userId}
<if test="productId !=null" >
and product_id=#{productId}
</if>
</update>
<select id="selectCartProductCount" parameterType="int" resultType="int">
<!--此处有个问题:mapper.java当中我们设置的返回值是int,但是此处查询的结果sum(quantity)可能是null,null不能赋值给int,会报空指针异常-->
<!--解决办法:1.mapper.java当中的int改为Integer 2.使用如下的格式-->
select NULLIF(sum(quantity),0) from mmall_cart where and user_id=#{userId}
</select>
</mapper>
xml当中需要注意的地方是:
<select id="selectCartProductCount" parameterType="int" resultType="int">
<!--此处有个问题:mapper.java当中我们设置的返回值是int,但是此处查询的结果sum(quantity)可能是null,null不能赋值给int,会报空指针异常-->
<!--解决办法:1.mapper.java当中的int改为Integer 2.使用如下的格式-->
select NULLIF(sum(quantity),0) from mmall_cart where and user_id=#{userId}
</select>
int selectCartProductCount(Integer userId);
网友评论