1. Cookie存储购物车
1.1 工程搭建
参考user工程,分别创建pinyougou-cart-interface、pinyougou-cart-service、pinyougou-cart-web三个工程,引入相关依赖和配置
1.2 后端代码
1.2.1 服务层
接口与服务实现类的编写
package com.pinyougou.cart.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.mapper.TbItemMapper;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbOrderItem;
import com.pinyougou.povo.Cart;
/**购物车服务层实现类
* @author Administrator
*
*/
@Service
public class CartServiceImpl implements CartService {
@Resource
private TbItemMapper itemMapper;
/* 添加购物车
*
* 1.根据商品SKU ID查询SKU商品信息
* 2.获取商家ID
* 3.根据商家ID判断购物车列表中是否存在该商家的购物车
* 4.如果购物车列表中不存在该商家的购物车
* 4.1 新建购物车对象
* 4.2 将新建的购物车对象添加到购物车列表
* 5.如果购物车列表中存在该商家的购物车
* 查询购物车明细列表中是否存在该商品
* 5.1. 如果没有,新增购物车明细
* 5.2. 如果有,在原购物车明细上添加数量,更改金额
*
*/
@Override
public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, Integer num) {
//1.根据商品SKU ID查询SKU商品信息
TbItem item = itemMapper.selectByPrimaryKey(itemId);
if(item==null){
throw new RuntimeException("商品不存在");
}
if(!item.getStatus().equals("1")){
throw new RuntimeException("商品状态无效");
}
//2.获取商家ID
String sellerId = item.getSellerId();
//3.根据商家ID判断购物车列表中是否存在该商家的购物车
Cart cart = searchCartBySellerId(cartList,sellerId);
//4.如果购物车列表中不存在该商家的购物车
if(cart==null){
//4.1 新建购物车对象 ,
cart=new Cart();
cart.setSellerId(sellerId);
cart.setSellerName(item.getSeller());
TbOrderItem orderItem = createOrderItem(item,num);
List orderItemList=new ArrayList();
orderItemList.add(orderItem);
cart.setOrderItemList(orderItemList);
//4.2将购物车对象添加到购物车列表
cartList.add(cart);
}else{
//5.如果购物车列表中存在该商家的购物车
// 判断购物车明细列表中是否存在该商品
TbOrderItem orderItem = searchOrderItemByItemId(cart.getOrderItemList(),itemId);
if(orderItem==null){
//5.1. 如果没有,新增购物车明细
orderItem=createOrderItem(item,num);
cart.getOrderItemList().add(orderItem);
}else{
//5.2. 如果有,在原购物车明细上添加数量,更改金额
orderItem.setNum(orderItem.getNum()+num);
orderItem.setTotalFee(new BigDecimal(orderItem.getNum()*orderItem.getPrice().doubleValue()) );
//如果数量操作后小于等于0,则移除
if(orderItem.getNum()<=0){
cart.getOrderItemList().remove(orderItem);//移除购物车明细
}
//如果移除后cart的明细数量为0,则将cart移除
if(cart.getOrderItemList().size()==0){
cartList.remove(cart);
}
}
}
return cartList;
}
/**
* 根据商家ID查询购物车对象
* @param cartList
* @param sellerId
* @return
*/
private Cart searchCartBySellerId(List<Cart> cartList, String sellerId){
for(Cart cart:cartList){
if(cart.getSellerId().equals(sellerId)){
return cart;
}
}
return null;
}
/**
* 根据商品明细ID查询
* @param orderItemList
* @param itemId
* @return
*/
private TbOrderItem searchOrderItemByItemId(List<TbOrderItem> orderItemList ,Long itemId ){
for(TbOrderItem orderItem :orderItemList){
if(orderItem.getItemId().longValue()==itemId.longValue()){
return orderItem;
}
}
return null;
}
/**
* 创建订单明细
* @param item
* @param num
* @return
*/
private TbOrderItem createOrderItem(TbItem item,Integer num){
if(num<=0){
throw new RuntimeException("数量非法");
}
TbOrderItem orderItem=new TbOrderItem();
orderItem.setGoodsId(item.getGoodsId());
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setPicPath(item.getImage());
orderItem.setPrice(item.getPrice());
orderItem.setSellerId(item.getSellerId());
orderItem.setTitle(item.getTitle());
orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue()*num));
return orderItem;
}
}
1.2.2 控制层
package com.pinyougou.cart.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.povo.Cart;
import entity.Result;
import util.CookieUtil;
@RestController
@RequestMapping("/cart")
public class CartController {
@Reference
private CartService cartService;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
/**添加购物车
* @param itemId
* @param num
* @return
*/
@RequestMapping("/addGoodsToCartList")
public Result addGoodsToCartList(Long itemId,Integer num){
try {
List<Cart> cartList =findCartList();//获取购物车列表
cartList = cartService.addGoodsToCartList(cartList, itemId, num);
CookieUtil.setCookie(request, response, "cartList", JSON.toJSONString(cartList),3600*24,"UTF-8");
return new Result(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "添加失败");
}
}
/**
* 购物车列表
* @param request
* @return
*/
@RequestMapping("/findCartList")
public List<Cart> findCartList(){
String cartListString = CookieUtil.getCookieValue(request, "cartList","UTF-8");
if(cartListString==null || cartListString.equals("")){
cartListString="[]";
}
List<Cart> cartList_cookie = JSON.parseArray(cartListString, Cart.class);
return cartList_cookie;
}
}
1.3 前端代码
1.3.1 前端js
1)service层
app.service("cartService",function($http){
this.findCartList = function() {
return $http.get("/cart/findCartList.do");
}
this.addGoodsToCartList = function(itemId,num) {
return $http.get("/cart/addGoodsToCartList.do?itemId="+itemId+"&num="+num);
}
this.sum = function(cartlist) {
var totalObject = {totalNum:0,totalMoney:0};
for(var i = 0 ; i < cartlist.length ; i ++){
var item = cartlist[i]; // 购物车对象
for(var j = 0 ; j < item.orderItemList.length; j++){
var orderItem = item.orderItemList[j];// 购物车明细
totalObject.totalNum += orderItem.num;// 累加数量
totalObject.totalMoney += orderItem.totalFee;// 累加金额
}
}
return totalObject;
}
});
2)controller
app.controller("cartController",function($scope,cartService){
// 查询列表
$scope.findCartList = function() {
cartService.findCartList().success(function(response) {
$scope.cartlist = response;
$scope.totalObject = cartService.sum($scope.cartlist);
});
}
// 添加到购物车
$scope.addGoodsToCartList = function(itemId,num) {
cartService.addGoodsToCartList(itemId,num).success(function(response) {
if(!response.success){
alert(response.message);
} else {
// 添加成功,刷新列表
$scope.findCartList();
}
});
}
});
1.3.2 界面
1)引入头文件
2)指令与数据绑定
测试:
2. Redis存储购物车
2.1 获取登录名
1)修改security的拦截配置
注意:这样配置的原因是,在security中,如果 security="none"配置的话,name该请求就会跳过认证,导致SecurityContextHolder.getContext()得到的上下文是null,所以获取不到用户名,因此,我们需要采用security给我们提供的另一种配置方式,采用匿名登录的方式,匿名登录默认的用户名是anonymousUser
2.2 远程购物车存取
2.2.1 服务层
@Resource
private RedisTemplate redisTemplate;
@Override
public List<Cart> findCartListFromRedis(String username) {
Object object = redisTemplate.boundHashOps("cartList").get(username);
return (List<Cart>) (null == object?new ArrayList<>():object);
}
@Override
public void saveCartListToRedis(String username, List<Cart> cartList) {
redisTemplate.boundHashOps("cartList").put(username, cartList);
}
2.2.2 控制层
修改findCardList方法
/**
* 购物车列表
* @param request
* @return
*/
@RequestMapping("/findCartList")
public List<Cart> findCartList(){
String name = SecurityContextHolder.getContext().getAuthentication().getName();
if("anonymousUser".equals(name)){ // 如果未登陆
String cartListString = CookieUtil.getCookieValue(request, "cartList","UTF-8");
if(cartListString==null || cartListString.equals("")){
cartListString="[]";
}
List<Cart> cartList_cookie = JSON.parseArray(cartListString, Cart.class);
return cartList_cookie;
} else { //如果已登录
return cartService.findCartListFromRedis(name);
}
}
3. 跳板页
1)创建跳板页:pinyougou-cart-web 工程新建login.html ,页面添加脚本
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script type="text/javascript">
location.href="cart.html"
</script>
<body>
</body>
</html>
2)购物车页面链接到跳板页
4. 合并购物车
4.1 服务层
public List<Cart> mergeCartList(List<Cart> cartList1, List<Cart> cartList2) {
System.out.println("合并购物车");
for(Cart cart: cartList2){
for(TbOrderItem orderItem:cart.getOrderItemList()){
cartList1= addGoodsToCartList(cartList1,orderItem.getItemId(),orderItem.getNum());
}
}
return cartList1;
}
4.2 控制层
/**
* 购物车列表
* @param request
* @return
*/
@RequestMapping("/findCartList")
public List<Cart> findCartList(){
String username = SecurityContextHolder.getContext().getAuthentication().getName();
// 从cookie中读取
String cartListString = CookieUtil.getCookieValue(request, "cartList","UTF-8");
if(cartListString==null || cartListString.equals("")){
cartListString="[]";
}
List<Cart> cartList_cookie = JSON.parseArray(cartListString, Cart.class);
if("anonymousUser".equals(username)){ // 如果未登陆
return cartList_cookie;
} else { //如果已登录
List<Cart> cartList_redis =cartService.findCartListFromRedis(username);//从redis中提取
if(cartList_cookie.size()>0){//如果本地存在购物车
//合并购物车
cartList_redis=cartService.mergeCartList(cartList_redis, cartList_cookie);
//清除本地cookie的数据
CookieUtil.deleteCookie(request, response, "cartList");
//将合并后的数据存入redis
cartService.saveCartListToRedis(username, cartList_redis);
}
return cartList_redis;
}
}
来源:CSDN
作者:武汉小喽啰
链接:https://blog.csdn.net/weixin_43318134/article/details/104316975