Java电商项目面试--购物车模块
购物车模块技术要点:
1、商品总价计算复用封装
2、高复用的逻辑方法封装思想
3、解决商业运算丢失精度的坑
一、购物车模块功能
1、购物车添加商品
2、更新商品数量
3、查询商品数量
4、移除购物车中商品
5、单选/全选
二、购物车添加商品
Controller层:
//购物车添加商品
@RequestMapping("add.do")
@ResponseBody
public ServerResponse<CartVo> add(HttpSession session, Integer count, Integer productId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
}
return iCartService.add(user.getId(),productId,count);
}
Service层:
//购物车添加商品
public ServerResponse<CartVo> add(Integer userId,Integer productId,Integer count){
if(productId == null || count == null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());
}
Cart cart = cartMapper.selectCartByUserIdProductId(userId,productId);
if(cart == null){
//这个产品不在这个购物车里,需要新增一个这个产品的记录
Cart cartItem = new Cart();
cartItem.setQuantity(count);
cartItem.setChecked(Const.Cart.CHECKED);
cartItem.setProductId(productId);
cartItem.setUserId(userId);
cartMapper.insert(cartItem);
}else{
//这个产品已经在购物车里了.
//如果产品已存在,数量相加
count = cart.getQuantity() + count;
cart.setQuantity(count);
cartMapper.updateByPrimaryKeySelective(cart);
}
return this.list(userId);
}
//返回之前需要判断一下(这里将这个函数封装了一下)
public ServerResponse<CartVo> list (Integer userId){
CartVo cartVo = this.getCartVoLimit(userId);
return ServerResponse.createBySuccess(cartVo);
}
//限制购物车中商品数量
private CartVo getCartVoLimit(Integer userId){
CartVo cartVo = new CartVo();
//从购物车中取出该用户的所有购买商品
List<Cart> cartList = cartMapper.selectCartByUserId(userId);
List<CartProductVo> cartProductVoList = Lists.newArrayList();
BigDecimal cartTotalPrice = new BigDecimal("0"); //初始化购物总价为0
if(CollectionUtils.isNotEmpty(cartList)){
for(Cart cartItem : cartList){ //购物车中的每一项
//将该商品封装一下
CartProductVo cartProductVo = new CartProductVo();
cartProductVo.setId(cartItem.getId());
cartProductVo.setUserId(userId);
cartProductVo.setProductId(cartItem.getProductId());
//查询该商品
Product product = productMapper.selectByPrimaryKey(cartItem.getProductId());
if(product != null){ //将该商品封装一下
cartProductVo.setProductMainImage(product.getMainImage());
cartProductVo.setProductName(product.getName());
cartProductVo.setProductSubtitle(product.getSubtitle());
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);
//计算该项商品总价
cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),cartProductVo.getQuantity()));
cartProductVo.setProductChecked(cartItem.getChecked());
}
//如果该项已经勾选,增加到整个的购物车总价中
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;
}
CartProductVo
单个商品的信息,限制商品数量以及计算某项商品的总价描述
public class CartProductVo {
//结合了产品和购物车的一个抽象对象
private Integer id;
private Integer userId;
private Integer productId;
private Integer quantity; //购物车中此商品的数量
private String productName;
private String productSubtitle;
private String productMainImage;
private BigDecimal productPrice;
private Integer productStatus;
private BigDecimal productTotalPrice;
private Integer productStock;
private Integer productChecked;//此商品是否勾选
private String limitQuantity; //限制数量的一个返回结果
}
CartProductVo
用来描述购物车中的情况,封装所有商品总价,全选描述
public class CartVo {
private List<CartProductVo> cartProductVoList;
private BigDecimal cartTotalPrice;
private Boolean allChecked; //是否已经都勾选
private String imageHost;
}
解决商业运算丢失精度的坑
在计算总价的时候会出现浮点数精度丢失的问题可以参考我的这篇博客:Java电商项目面试–浮点型商业运算中丢失精度问题
三、更新商品数量
Controller层:
//更新购物车
@RequestMapping("update.do")
@ResponseBody
public ServerResponse<CartVo> update(HttpSession session, Integer count, Integer productId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
return iCartService.update(user.getId(),productId,count);
}
Service层:
//更新购物车
public ServerResponse<CartVo> update(Integer userId,Integer productId,Integer count){
if(productId == null || count == null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());
Cart cart = cartMapper.selectCartByUserIdProductId(userId,productId); //查询出购物车中的该项
if(cart != null)
cart.setQuantity(count);
cartMapper.updateByPrimaryKey(cart);
return this.list(userId);
}
四、移除购物车中商品
Controller层:
//购物车中删除商品
@RequestMapping("delete_product.do")
@ResponseBody
//和前端约定,删除多项,则用逗号分割
public ServerResponse<CartVo> deleteProduct(HttpSession session,String productIds){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
return iCartService.deleteProduct(user.getId(),productIds);
}
Service层:
public ServerResponse<CartVo> deleteProduct(Integer userId,String productIds){
//使用guava的Splitter方法( 用逗号分割,转成list集合 )
//和前端约定,删除多项,则用逗号分割
List<String> productList = Splitter.on(",").splitToList(productIds);
if(CollectionUtils.isEmpty(productList))
return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());
cartMapper.deleteByUserIdProductIds(userId,productList);
return this.list(userId);
}
Mapper.xml:
<delete id="deleteByUserIdProductIds" parameterType="map">
delete from mmall_cart
where user_id = #{userId}
<if test="productIdList != null">
and product_id in
<foreach collection="productIdList" item="item" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</delete>
五、单选全选
Controller层:
//全反选
@RequestMapping("un_select_all.do")
@ResponseBody
public ServerResponse<CartVo> unSelectAll(HttpSession session){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
return iCartService.selectOrUnSelect(user.getId(),null,Const.Cart.UN_CHECKED);
}
//单独选
@RequestMapping("select.do")
@ResponseBody
public ServerResponse<CartVo> select(HttpSession session,Integer productId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
return iCartService.selectOrUnSelect(user.getId(),productId,Const.Cart.CHECKED);
}
//单独反选
@RequestMapping("un_select.do")
@ResponseBody
public ServerResponse<CartVo> unSelect(HttpSession session,Integer productId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
return iCartService.selectOrUnSelect(user.getId(),productId,Const.Cart.UN_CHECKED);
}
Service层:
//选择或者反选
public ServerResponse<CartVo> selectOrUnSelect (Integer userId,Integer productId,Integer checked){
cartMapper.checkedOrUncheckedProduct(userId,productId,checked);
return this.list(userId);
}
//是否全选,即全选是否购物车中的所有项都被选择了
private boolean getAllCheckedStatus(Integer userId){
if(userId == null)
return false;
return cartMapper.selectCartProductCheckedStatusByUserId(userId) == 0;
}
Mapper.xml:
<!-- 选择或者不选 -->
<update id="checkedOrUncheckedProduct" 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="selectCartProductCheckedStatusByUserId" resultType="int" parameterType="int">
SELECT count(1) from mmall_cart where checked = 0 and user_id = #{userId}
</select>
Java面试的完整博客目录如下:Java笔试面试目录
转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916 如果觉得本文对您有帮助,请点击顶支持一下,您的支持是我写作最大的动力,谢谢。
还没有评论,来说两句吧...