一、这次系统来做了下购物车的功能模块,以下几个功能吧:

1、查询购物车列表

2、向购物车添加商品

3、删除购物车商品

4、修改购物车商品数量

以上四个是传统的增删改成功能。

5、购物车商品全选功能实现

6、取消全选功能实现

7、购物车商品单选功能实现

8、取消单个商品的选择

9、查询购物车的商品数量功能实现

以上是本次介绍的几个功能模块,这其中涉及到一些小的细节处理问题,今天主要来总结下。

之前写过一个博客介绍了购物车的添加功能模块,通过这个模块我们也封装了购物车的常用方法。

二、购物车功能细节问题明确

(1)当用户打开用户自己的购物车的时候,默认的购物车的商品的没有选的状态,即购物车中总价是为0的。

(2)购物车中的总结计算问题:只有选择的商品才会在计算的总价中。

(3)购物车中的全选功能、非全选功能、单选、取消单选功能的技巧问题。

(4)购物车中商品的数量与库存的问题

三、细节的实现

controller层:

package com.imooc.project.cartcontroller;import com.imooc.project.cartservice.ICartService;
import com.imooc.project.common.Const;
import com.imooc.project.common.ServerResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;/*** 购物车功能模块实现*/
@Api(value = "购物车功能实现",tags = {"imoocProject项目的购物车功能实现"})
@RestController
@RequestMapping("/cart/")
public class CartController {@Autowiredprivate ICartService iCartService;@ApiOperation(value = "向购物车内添加商品")@PostMapping("add.do")@ApiImplicitParams({@ApiImplicitParam(name = "userId",value = "用户id",dataType ="Integer",paramType = "query"),@ApiImplicitParam(name = "productId",value = "商品id",dataType ="Integer",paramType = "query"),@ApiImplicitParam(name = "count",value ="商品数量",dataType ="Integer",paramType = "query")})//这里应该是先判断用户是否登录的,登录之后获取用户的id,然后查询该用户的购物车,在这里模拟用户//购物车功能流程://当用户未登录的状态下,加入购物车,此时商品是保存在cookie中的,用户换台电脑购物车就失效。当用户结算的时候需要用户的登录,这一块的处理也是计算价格库存// 在用户登录的前提下,查询用户购物车中是否有该商品,如果没有,则将商品添加到购物车中(这中间牵扯到库存和商品价格的处理,该商品的总结,该用户购物车最终的总价),如果有该商品,则增加商品的数量,更新用户的购物车,计算价格public ServerResponse addProductCart(HttpServletRequest request,HttpServletResponse response,Integer userId, Integer productId, Integer count){ServerResponse serverResponse;if (userId!=null && userId==21) {serverResponse = iCartService.addProductCart(userId, productId, count);}else{//用户未登录状态下的加入购物车功能serverResponse= iCartService.addProductCookie(request,response,productId,count);}return serverResponse;}@ApiOperation(value = "更新购物车某个产品数量")@PostMapping("update.do'")@ApiImplicitParams({@ApiImplicitParam(name = "productId",value = "商品id",dataType ="Integer",paramType = "query"),@ApiImplicitParam(name = "count",value = "商品数量",dataType ="Integer",paramType = "query"),})public ServerResponse updateCartQuantity(Integer productId, Integer count){Integer userId=21;return iCartService.updateCartQuantity(userId,productId,count);}@ApiOperation(value = "移除购物车某个产品")@DeleteMapping("delete_product.do")@ApiImplicitParam(name = "productIds",value = "商品id集合",dataType ="Integer",paramType = "query")public ServerResponse deleteProduct(Integer[] productIds){Integer userId=21;return iCartService.deleteProductFromCart(userId,productIds);   }//购物车List列表@ApiOperation(value = "展示购物车列表")@GetMapping("list.do")public ServerResponse deleteProduct(){Integer userId=21;return iCartService.showCartList(userId);     }@ApiOperation(value = "购物车选中某个商品")@GetMapping("select.do")@ApiImplicitParam(name = "productId",value = "商品id",dataType ="Integer",paramType = "query")public ServerResponse selectProduct(Integer productId){int userId=21;return  iCartService.selectProduct(userId,productId,Const.CartProperty.CARTCHECKED);}@ApiOperation(value = "购物车取消选中某个商品")@GetMapping("un_select.do")@ApiImplicitParam(name = "productId",value = "商品id",dataType ="Integer",paramType = "query")public ServerResponse unselectProduct(Integer productId){Integer userId=21;return iCartService.unSelectProduct(userId,productId,Const.CartProperty.UN_CHECKED);}@ApiOperation(value = "查询在购物车里的产品数量")@GetMapping("get_cart_product_count.do")public ServerResponse getCartProductCount(){Integer userId=21;return iCartService.getCartProductCount(userId);}@ApiOperation(value = "购物车全选")@GetMapping("select_all.do")public ServerResponse selectAllProduct(){Integer userId=21;return iCartService.selectAllProduct(userId, Const.CartProperty.CARTCHECKED);}@ApiOperation(value = "购物车取消全选")@GetMapping("un_select_all.do")public ServerResponse unselectAllProduct(){Integer userId=21;return iCartService.unselectAllProduct(userId,Const.CartProperty.UN_CHECKED);}}

  

serviceImpl层:

package com.imooc.project.cartserviceImpl;import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.imooc.project.cartVo.CartItmCookieVo;
import com.imooc.project.cartVo.CartProductVoList;
import com.imooc.project.cartVo.CartVo;
import com.imooc.project.cartservice.ICartService;
import com.imooc.project.common.Const;
import com.imooc.project.common.ResponseCode;
import com.imooc.project.common.ServerResponse;
import com.imooc.project.entity.mmall_cart;
import com.imooc.project.entity.mmall_product;
import com.imooc.project.mapper.mmall_cartMapper;
import com.imooc.project.mapper.mmall_productMapper;
import com.imooc.project.util.BigDecimalUtil;
import com.imooc.project.util.CookieUtils;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;/*** 购物车功能模块实现*/
@Service
public class CartServiceImpl implements ICartService {@Autowiredprivate mmall_cartMapper cartMapper;@Autowiredprivate mmall_productMapper productMapper;//购物车功能流程://当用户未登录的状态下,加入购物车,此时商品是保存在cookie中的,用户换台电脑购物车就失效。当用户结算的时候需要用户的登录,这一块的处理也是计算价格库存// 在用户登录的前提下,查询用户购物车中是否有该商品,如果没有,则将商品添加到购物车中(这中间牵扯到库存和商品价格的处理,该商品的总结,该用户购物车最终的总价),如果有该商品,则增加商品的数量,更新用户的购物车,计算价格//这种情况是淘宝网站使用的,只有用户的登录的状态下商品才可以加入购物车,保证了数据的同步@Overridepublic ServerResponse<CartVo> addProductCart(Integer userId,Integer productId,Integer count) {if (productId == null || count == null) {return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());}//查询该用户的购物车中是否有该商品mmall_cart cart = cartMapper.selectProductExit(userId, productId);mmall_product product = productMapper.selectByPrimaryKey(productId);if (cart == null) {//如果购物车为空,则购物车没有此商品,需要插入到购物车mmall_cart cartItem = new mmall_cart();cartItem.setProductId(productId);cartItem.setUserId(userId);cartItem.setQuantity(count);cartItem.setChecked(Const.CartProperty.CARTCHECKED);int i = cartMapper.insert(cartItem);} else {//如果购物车不为空,则已有此商品,需要更新购物车商品的数量int stock = product.getStock();cart.setQuantity(cart.getQuantity() + 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){//封装vo展示给前台,查询用户购物车中的商品展示CartVo cartVo=new CartVo();BigDecimal cartTotalPrice=new BigDecimal("0");List<mmall_cart> cartList=cartMapper.selectProductByUserId(userId);List<CartProductVoList> list= Lists.newArrayList();if (!CollectionUtils.isEmpty(cartList)) {for (mmall_cart cartItem : cartList) {//开始封装这个包装显示类CartProductVoList cartProductVoList = new CartProductVoList();cartProductVoList.setId(cartItem.getId());cartProductVoList.setUserId(userId);cartProductVoList.setProductId(cartItem.getProductId());//根据购物车的商品id来查询该商品的信息mmall_product productItem = productMapper.selectByPrimaryKey(cartItem.getProductId());if (productItem!=null){cartProductVoList.setProductMainImage(productItem.getMainImage());cartProductVoList.setProductName(productItem.getName());cartProductVoList.setProductStatus(productItem.getStatus());cartProductVoList.setProductStock(productItem.getStock());cartProductVoList.setProductSubtitle(productItem.getSubtitle());cartProductVoList.setProductPrice(productItem.getPrice());//商品库存限制这个功能int buyLimitCount = 0;if (cartItem.getQuantity()<= productItem.getStock()) {buyLimitCount=cartItem.getQuantity();cartProductVoList.setLimitQuantity(Const.CartProperty.LIMIT_NUM_SUCCESS);} else {//这一步需要注意,当库存不足时,需要更新购物车库存buyLimitCount = productItem.getStock();cartProductVoList.setLimitQuantity(Const.CartProperty.LIMIT_NUM_FAIL);//购物车中更新有效库存,mmall_cart cartForQuantity = new mmall_cart();cartForQuantity.setId(cartItem.getId());cartForQuantity.setQuantity(buyLimitCount);cartMapper.updateByPrimaryKeySelective(cartForQuantity);}cartProductVoList.setQuantity(buyLimitCount);//购物车总价格的问题:一个是该产品的总价,一个是购物车中最后的商品总价//这个是该商品的总价格:商品价格*商品的数量cartProductVoList.setProductTotalPrice(BigDecimalUtil.mul(productItem.getPrice().doubleValue(),cartItem.getQuantity().doubleValue()));cartProductVoList.setProductChecked(cartItem.getChecked());}//注意这里的理解:购物车中的商品默认是都没有选中的,所以当有商品是选中状态时才会将价格计算到总价中。所以这里如果购物车全选,则计算的全部的价格,如果没有全选,则价格为0,如果选中一个,则只有一个的价格if (cartItem.getChecked()==Const.CartProperty.CARTCHECKED){cartTotalPrice=BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVoList.getProductTotalPrice().doubleValue());}list.add(cartProductVoList);}}cartVo.setCartProductVoLists(list);cartVo.setAllChecked(this.getAllCheckedStatus(userId));//如果全选则返回true,非全选则返回falsecartVo.setCartTotalPrice(cartTotalPrice);return cartVo;}private boolean getAllCheckedStatus(Integer userId){if(userId == null){return false;}//查询购物车中该用户下选中的状态,checked=0,即未被选中状态,如果返回0,则表明购物车中全部选中的状态,返回truereturn cartMapper.selectCartProductCheckedStatusByUserId(userId) == 0;}
//用户未登录的情况下购物车保存到cookie中,京东网站使用的方法@Overridepublic ServerResponse addProductCookie(HttpServletRequest request, HttpServletResponse response, Integer productId, Integer count) {/*添加购物车商品,首先购物车商品是保存在cookie中的,因为我们只要不付款是没有什么作用的。* 如何从cookie中读取购物车列表呢,是利用request来实现的。* 第一步:首先判断cookie中是否存在该商品,如果存在,则商品数量加1,* 如果没有则根据商品id从rest工程中获取该商品,将商品写入cookie。*/CartItmCookieVo cartItmCookieVo=null;//从cookie中读取商品List<CartItmCookieVo> cookieList=this.getProductByCookie(request);List<CartItmCookieVo> list=Lists.newArrayList();//遍历这个列表,查询购物车中是否存在此商品,如果存在则更新,如果不存在则写入cookie中for (CartItmCookieVo cartItem: cookieList) {if (cartItem.getProductId()==productId){cartItem.setQuantity(cartItem.getQuantity()+count);cartItmCookieVo=cartItem;break;}else{cartItmCookieVo=new CartItmCookieVo();mmall_product product=productMapper.selectByPrimaryKey(productId);cartItmCookieVo.setId(cartItem.getId());cartItmCookieVo.setProductId(productId);cartItmCookieVo.setProductName(product.getName());if (product.getStock()>=cartItem.getQuantity()) {cartItmCookieVo.setQuantity(cartItem.getQuantity());}else{cartItmCookieVo.setQuantity(product.getStock());}cartItmCookieVo.setProductPrice(product.getPrice());cartItmCookieVo.setProductMainImage(product.getMainImage());list.add(cartItmCookieVo);CookieUtils.setCookie(request,response,"TT_CART",JSON.toJSONString(list),true);}}return ServerResponse.createBySuccess(list);}//从cookie中读取商品列表private List<CartItmCookieVo> getProductByCookie(HttpServletRequest request) {String cookie=CookieUtils.getCookieValue(request,"TT_CART",true);//因为cookie中存放的是json格式的数据,所以如果需要转换成list形式if (cookie==null){return new ArrayList<>();}else{//这里用到了使用阿里巴巴的fastjson将json转为list集合的形式List<CartItmCookieVo> cartcookieList = JSON.parseArray(cookie, CartItmCookieVo.class);return cartcookieList;}}//更新购物车中商品的数量public ServerResponse updateCartQuantity(Integer userId,Integer productId,Integer count){if(userId==null && productId==null){return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());}//查询用户的购物车中是否有该商品,如果有则更新商品数量,如果没有则提示报错mmall_product product=productMapper.selectByPrimaryKey(productId);if(product!=null){mmall_cart cart=cartMapper.selectProductExit(userId,productId);if(cart!=null){//因为在下面的展示用户的购物车列表的时候会对商品的库存进行比较,重新调整数量,所以这里就直接设置它加的数量即可cart.setQuantity(count);cartMapper.updateByPrimaryKeySelective(cart);return this.list(userId);}else{return ServerResponse.createByErrorMessage("该用户的购物车中无此商品,无法更新商品数量");}}else{return ServerResponse.createByErrorMessage("系统错误");}}//删除购物车中的某个或者某些商品public ServerResponse deleteProductFromCart(Integer userId,Integer[] productIds){if(userId==null && productIds.length==0){return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc()); }List<mmall_cart> cartList=cartMapper.selectProductByUserId(userId);if(!CollectionUtils.isEmpty(cartList)){cartMapper.deleteProductFromCart(userId,productIds);return this.list(userId);}else{return ServerResponse.createByErrorMessage("该用户购物车为空");}   }//展示购物车列表public ServerResponse showCartList(Integer userId){if(userId==null){return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc()); }return this.list(userId);}@Overridepublic ServerResponse<CartVo> selectProduct(Integer userId, Integer productId,Integer checked) {cartMapper.checkOrUnchecked(userId,productId,checked);return this.list(userId);}@Overridepublic ServerResponse unSelectProduct(Integer userId, Integer productId, Integer checked) {cartMapper.checkOrUnchecked(userId,productId,checked);return this.list(userId);}@Overridepublic ServerResponse selectAllProduct(Integer userId, Integer checked) {cartMapper.checkOrUnchecked(userId,null,checked);return this.list(userId);}@Overridepublic ServerResponse unselectAllProduct(Integer userId, Integer checked) {cartMapper.checkOrUnchecked(userId,null,checked);return this.list(userId);}//获取购物车中产品的数量,是指购物车中的的产品的数量总和@Overridepublic ServerResponse getCartProductCount(Integer userId) {if (userId==null){return ServerResponse.createBySuccess(0);}return ServerResponse.createBySuccess(cartMapper.getCartCount(userId));}}

  

mapper的几个文件:

购物车功能完整版12.13相关推荐

  1. appinventor mysql_利用AppInventor实现登录功能(完整版).docx

    利用AppInventor实现登录功能(完整版) 上次教程,我们已经在SAE的共享型MySQL中新建了数据表,并且通过APP向数据表中写入了用户的信息(用户名.密码.昵称),如下图所示: ?????? ...

  2. android应用版本更新功能---完整版

    源码下载地址:csdn下载地址:http://download.csdn.net/download/csdn576038874/9526085 博客园下载地址:http://files.cnblogs ...

  3. wangEditor 修改 “视频”菜单 的实现方式,达到上传视频的功能---完整版

    //经测,没能实现我的需求,我经二次修改实现,仅先修改了构造函数 UploadVideo 里面的些许判断,下面链接为我改过的 https://blog.csdn.net/m0_37885651/art ...

  4. springboot 微信小程序 对接微信支付功能(完整版)

    微信小程序对接微信支付功能 业务流程时序图 JAVA版 1. 项目架构 2. pom.xml配置文件 3. 小程序账号参数配置类 4.JAVA 通用代码 4.1 工具类 4.1.1 IdGen (id ...

  5. 《真三国无双5》全人研究完整版

    <真三国无双5>全人研究完整版 2010-01-29 13:21 蜀国 赵云 系列传统主角 本作走的依然是平均路线 先说说子龙的优点吧 无双很赞 无双终结技很实用 无双连舞时攻击速度不错 ...

  6. codeblocks 13.12中文完整版(带GNW编译器)

         codeblocks 是一个开放源码且功能全面的跨平台C/C++集成开发环境(IDE),采用c++语言开发,使用了蓍名的图形界面库wxWidgets,目前发布了windows版.mac版.l ...

  7. 易企秀 伪静态 linux,最新仿易企秀V15.1完整版开源版源码分享,修复采集功能,新增同行站模板采集功能等等...

    源码说明:0 j; j/ T/ g! d* a& [ 易企秀是一款针对移动互联网营销的手机网页DIY制作工具,用户可以编辑手机网页,分享到社交网络,通过报名表单收集潜在客户或其他反馈信息.用户 ...

  8. Aspen Plus 2004.2_完整版全功能好用\

    华铸CAE全套教程.rar Aquaveo GMS 6.5.3 (地下水资源和地下水污染模拟软件)\ Aquaveo SMS v10.0.10 (水面塑造系统)\ CAESAR_II_5.10 最新版 ...

  9. 13新功能_再聊聊灵感盒 -Marginnote 3.6.12/13新功能

    我是夜雨,水群最多的一类人 本文主要BB了我对灵感盒的理解 Marginnote 3.6.12/13 个人之前对灵感盒的理解 在此强调开发者的一句话 不要对灵感盒做太多高大上的引申 灵感盒只不过是新的 ...

最新文章

  1. 小型软件项目开发流程探讨
  2. Windows文件目录DOS窗口
  3. VMWare中修改CentOS虚拟机静态IP后主机没法访问虚拟机
  4. Servlet异常处理
  5. Github pull request 工作流总结
  6. java excel解析 poi_Java解析Excel之POI(一)
  7. linux内核源码目录结构分析
  8. 正则表达式 正整数_史上最全的正则表达式 (1) -- 校验数字的表达式
  9. ios传感器应用开发最佳实践_同构 javascript 应用开发的最佳实践(Four)
  10. 高斯列元素消去法c语言,【大神在哪里】高斯-列主元消去法
  11. 安卓中为什么onkeydown没有相应_为什么今年在园区注册个人独资企业能将企业总税率降低至3%?...
  12. spring_redis整合
  13. mysql省市区递归查询_mysql递归查询
  14. asp.net学习心得总结
  15. android+发短信示例,【Android】如何实现Android发送短信(示例代码)
  16. Surface Pro 4 无限重启的解决方法
  17. 数据结构与程序设计——C++语言描述(Data Structures Program Design in C++) by Robert L.Kruse Alexander J.Ryb
  18. CSS阴影效果(Box-shadow)用法趣味讲解
  19. linux检查邮件命令,linux下mail 邮件查看命令
  20. GitHub分享的微软开源计算器项目

热门文章

  1. ios标签控制器怎么用_带故事板的iOS标签栏控制器
  2. easymock使用方法_EasyMock最终方法– PowerMock,JUnit 4,TestNG
  3. swift 可选链_Swift可选链
  4. unix进程的环境--unix环境高级编程读书笔记
  5. Java新职篇:面向对象编程的3个原则是什么?
  6. 大数据高地,这样炼成!
  7. linux应用之Lamp(apache+mysql+php)的源码安装(centos)
  8. 交互设计[小插曲]--网站UI配色
  9. Android用户界面开发:控件集合
  10. 【廖雪峰官方网站/Java教程】注解