品优购15——购物车解决方案

假如想象 提交于 2020-03-17 06:29:05

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;

	}
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!