购物车逻辑分析及代码

一定要看懂了图再写 看懂了图再写 看懂了图再写

 //4.a.如果未登录, 则将购物车列表存入cookie中 只能存字符串 要转义
            String carListJsonStr = JSON.toJSONString(cartList);
            CookieUtil.setCookie(request, response, Constants.COOKIE_CARTLIST, carListJsonStr, 3600 * 24 * 30, "utf-8");

Constants

package cn.itcast.core.util;

/**
 * 常量
 */
public interface Constants {

    public final static String REDIS_CONTENT_LIST = "contentList";

    public final static String REDIS_CATEGORYLIST = "categoryList";
    public final static String REDIS_BRANDLIST = "brandList";
    public final static String REDIS_SPECLIST = "specList";
    public final static String COOKIE_CARTLIST = "pyg_cartList";
    public final static String REDIS_CARTLIST = "pyg_cartList";
}

CookieUtil

package cn.itcast.core.util;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;


/**
 * 
 * Cookie 工具类
 *
 */
public final class CookieUtil {

    /**
     * 得到Cookie的值, 不编码
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    /**
     * 设置Cookie的值 在指定时间内生效,但不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    /**
     * 设置Cookie的值 不设置生效时间,但编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    /**
     * 删除Cookie带cookie域名
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName) {
        doSetCookie(request, response, cookieName, "", -1, false);
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
                String domainName = getDomainName(request);
                System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                    cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
             e.printStackTrace();
        }
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
                String domainName = getDomainName(request);
                System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                    cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
             e.printStackTrace();
        }
    }

    /**
     * 得到cookie的域名
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;

        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                // www.xxx.com.cn
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }

        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        return domainName;
    }

}

CartController

package cn.itcast.core.controller;

import cn.itcast.core.pojo.entity.BuyerCart;
import cn.itcast.core.pojo.entity.Result;
import cn.itcast.core.service.BuyerCartService;
import cn.itcast.core.util.Constants;
import cn.itcast.core.util.CookieUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 购物车业务
 */
@RestController
@RequestMapping("/cart")
public class CartController {

    @Reference
    private BuyerCartService buyerCartService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    /**
     * 添加商品到购物车中
     * @param itemId    购买商品的库存id
     * @param num       购买数量
     * @return
     */
    @RequestMapping("/addGoodsToCartList")
    //解决跨域访问, origins="http://localhost:8086"指定响应返回到哪台服务器
    @CrossOrigin(origins="http://localhost:8086",allowCredentials="true")
    public Result addGoodsToCartList(Long itemId, Integer num) {
        //1. 获取当前登录用户名称
        String userName = SecurityContextHolder.getContext().getAuthentication().getName();
        //2. 获取购物车列表
        List<BuyerCart> cartList = findCartList();
        //3. 将当前商品加入到购物车列表
        cartList = buyerCartService.addItemToCartList(cartList, itemId, num);
        //4. 判断当前用户是否登录, 未登录用户名为"anonymousUser"
        if ("anonymousUser".equals(userName)) {
            //4.a.如果未登录, 则将购物车列表存入cookie中
            String carListJsonStr = JSON.toJSONString(cartList);
            CookieUtil.setCookie(request, response, Constants.COOKIE_CARTLIST, carListJsonStr, 3600 * 24 * 30, "utf-8");
        } else {
            //4.b.如果已登录, 则将购物车列表存入redis中
            buyerCartService.setCartListToRedis(userName, cartList);
        }
        return new Result(true, "添加成功!");
    }

    /**
     * 查询当前用户的购物车列表数据并返回
     * @return
     */
    @RequestMapping("/findCartList")
    public List<BuyerCart> findCartList() {
        //1. 获取当前登录用户名称
        String userName = SecurityContextHolder.getContext().getAuthentication().getName();
        //2. 从cookie中获取购物车列表json格式字符串
        String cookieCartListJsonStr = CookieUtil.getCookieValue(request, Constants.COOKIE_CARTLIST, "utf-8");
        //3. 如果购物车列表json串为空则返回"[]"
        if (cookieCartListJsonStr == null || "".equals(cookieCartListJsonStr)) {
            cookieCartListJsonStr = "[]";
        }
        //4. 将购物车列表json转换为对象
        List<BuyerCart> cookieCartList = JSON.parseArray(cookieCartListJsonStr, BuyerCart.class);
        //5. 判断用户是否登录, 未登录用户为"anonymousUser"
        if ("anonymousUser".equals(userName)) {
            //5.a. 未登录, 返回cookie中的购物车列表对象
            return cookieCartList;
        } else {
            //5.b.1.已登录, 从redis中获取购物车列表对象
            List<BuyerCart> redisCartList = buyerCartService.getCartListFromRedis(userName);
            //5.b.2.判断cookie中是否存在购物车列表
            if (cookieCartList != null && cookieCartList.size() > 0) {
                //如果cookie中存在购物车列表则和redis中的购物车列表合并成一个对象
                redisCartList = buyerCartService.mergeCookieCartListToRedisCartList(cookieCartList, redisCartList);
                //删除cookie中购物车列表
                CookieUtil.deleteCookie(request, response, Constants.COOKIE_CARTLIST);
                //将合并后的购物车列表存入redis中
                buyerCartService.setCartListToRedis(userName, redisCartList);
            }
            //5.b.3.返回购物车列表对象
            return redisCartList;
        }
    }
}

BuyerCartService

package cn.itcast.core.service;

import cn.itcast.core.pojo.entity.BuyerCart;

import java.util.List;

public interface BuyerCartService {
    //添加商品到购物车列表Service方法业务如下:
    List<BuyerCart> addItemToCartList(List<BuyerCart> cartList, Long itemId, Integer num);

    //将购物车列表添加到redis中
    void setCartListToRedis(String userName, List<BuyerCart> cartList);

    //将购物车列表从redis中取出
    List<BuyerCart> getCartListFromRedis(String userName);

    //将cookie中的购物车集合 合并到redis的购物车集合中返回
    List<BuyerCart> mergeCookieCartListToRedisCartList(List<BuyerCart> cookieCartList, List<BuyerCart> redisCartList);
}
BuyerCartServiceImpl
package cn.itcast.core.service;

import cn.itcast.core.dao.item.ItemDao;
import cn.itcast.core.pojo.entity.BuyerCart;
import cn.itcast.core.pojo.item.Item;
import cn.itcast.core.pojo.order.OrderItem;
import cn.itcast.core.util.Constants;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Service
public class BuyerCartServiceImpl implements BuyerCartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ItemDao itemDao;




    /**
     * 将购物车列表添加到redis中
     *
     * @param userName 登录用户的用户名
     * @param cartList 购物车列表
     */
    @Override
    public void setCartListToRedis(String userName, List<BuyerCart> cartList) {
        redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).put(userName, cartList);
    }

    /**
     * 将购物车列表从redis中取出
     * @param userName  登录用户的用户名
     */
    @Override
    public List<BuyerCart> getCartListFromRedis(String userName) {
        List<BuyerCart> cartList = (List<BuyerCart>) redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).get(userName);
        if (cartList == null) {
            cartList = new ArrayList<BuyerCart>();
        }
        return cartList;

    }

    /**
     * 将cookie中的购物车集合 合并到redis的购物车集合中返回
     *
     * @param cookieCartList cookie中的购物车集合
     * @param redisCartList  redis的购物车集合
     * @return
     */
    @Override
    public List<BuyerCart> mergeCookieCartListToRedisCartList(List<BuyerCart> cookieCartList, List<BuyerCart> redisCartList) {
        if (cookieCartList != null) {
            //遍历ookie中的购物车集合
            for (BuyerCart Cart : cookieCartList) {
                List<OrderItem> orderItemList = Cart.getOrderItemList();
                if (orderItemList != null) {
                    //遍历cookie中的购物项集合
                    for (OrderItem orderItem : orderItemList) {
                        //把cookie中的购物项添加到redis的购物项集合中
                      redisCartList = addItemToCartList(redisCartList, orderItem.getItemId(), orderItem.getNum());
                    }
                }
            }
        }
        return redisCartList;
    }

    /**
     * 添加商品到这个人拥有的购物购物车列表中
     *
     * @param cartList 现在所拥有的购物车列表
     * @param itemId   库存id
     * @param num      购买数量
     * @return 返回添加完后的购物车列表
     */
    @Override
    public List<BuyerCart> addItemToCartList(List<BuyerCart> cartList, Long itemId, Integer num) {

        //1. 根据商品SKU ID查询SKU商品信息
        Item item = itemDao.selectByPrimaryKey(itemId);
        //2. 判断商品是否存在不存在, 抛异常
        if (item == null) {
            throw new RuntimeException("您购买的商品不存在");
        }

        //3. 判断商品状态是否为1已审核, 状态不对抛异常
        if (!"1".equals(item.getStatus())) {
            throw new RuntimeException("您购买的商品非法");
        }
        //4.获取商家ID sellerId
        String sellerId = item.getSellerId();
        //5.根据商家ID查询购物车列表中是否存在该商家的购物车
        BuyerCart buyerCart = findCartBySellerId(sellerId, cartList);
        //6.判断如果购物车列表中不存在该商家的购物车
        if (buyerCart == null) {
            //6.a.1 新建购物车对象
            buyerCart = new BuyerCart();
            //向购物车加入卖家id
            buyerCart.setSellerId(sellerId);
            //向购物车加入卖家名字Seller()
            buyerCart.setSellerName(item.getSeller());
            //创建购物车中需要的购物项集合
            List<OrderItem> orderItemList = new ArrayList<>();
            //创建购物项对象
            OrderItem orderItem = creatOrderItem(item, num);
            //将购物项数据一个个加入

            //将购物项加入到购物项集合中
            orderItemList.add(orderItem);
            //向购物车加入购物项集合
            buyerCart.setOrderItemList(orderItemList);
            //6.a.2 将新建的购物车对象添加到购物车列表
            cartList.add(buyerCart);
        } else {

            //6.b.1如果购物车列表中存在该商家的购物车 (查询购物车明细列表中是否存在该商品)
            List<OrderItem> orderItemList = buyerCart.getOrderItemList();
            OrderItem orderItem = findOrderItemByItemId(orderItemList, itemId);
            //6.b.2判断购物车明细是否为空
            if (orderItem == null) {
                //6.b.3为空,新增购物车明细
                orderItem = creatOrderItem(item, num);
                //将新建的购物项对象放到购物项集合中
                orderItemList.add(orderItem);
            } else {
                //6.b.4不为空,在原购物车明细上添加数量,更改金额
                orderItem.setNum(orderItem.getNum() + num);
                orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(orderItem.getNum())));

            }
            //6.b.5如果购物车明细中数量操作后小于等于0,则移除
            if (orderItem.getNum() <= 0) {
                orderItemList.remove(orderItem);
            }
            //6.b.6如果购物车中购物车明细列表为空,则移除
            if (orderItemList.size() == 0) {
                cartList.remove(buyerCart);
            }

        }



        //7. 返回购物车列表对象
        return cartList;
    }

    /**
     * 从购物项集合中找符合itemId的同款购物项
     * @param orderItemList 购物项集合
     * @param itemId        库存id
     * @return
     */
    private OrderItem findOrderItemByItemId(List<OrderItem> orderItemList, Long itemId) {
        if (orderItemList != null) {
            for (OrderItem orderItem : orderItemList) {
                if (itemId.equals(orderItem.getItemId())) {
                    return orderItem;
                }
            }
        }
        return null;
    }

    /**
     * 从购物车列表中获取这个卖家的购物车
     *
     * @param sellerId
     * @param cartList
     * @return
     */
    private BuyerCart findCartBySellerId(String sellerId, List<BuyerCart> cartList) {
        //5.根据商家ID查询购物车列表中是否存在该商家的购物车
        if (cartList != null) {
            for (BuyerCart Cart : cartList) {
                if (sellerId.equals(Cart.getSellerId())) {
                    return Cart;
                }
            }
        }
        return null;
    }

    /**
     * 创建购物项对象
     * @param item  库存对象
     * @param num   购买数量
     * @return
     */

    private OrderItem creatOrderItem(Item item, Integer num) {
        if (num == null || num <= 0) {
            throw new RuntimeException("购买数量非法");
        }
        OrderItem orderItem = new OrderItem();
        //库存标题
        orderItem.setTitle(item.getTitle());
        //购买数量
        orderItem.setNum(num);
        //商品id
        orderItem.setGoodsId(item.getGoodsId());
        //库存id
        orderItem.setItemId(item.getId());
        //卖家id
        orderItem.setSellerId(item.getSellerId());
        //示例图片地址
        orderItem.setPicPath(item.getImage());
        //商品单价
        orderItem.setPrice(item.getPrice());
        //总价 = 单价 * 购买数量
        orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(orderItem.getNum())));

        return orderItem;
    }


}

猜你喜欢

转载自www.cnblogs.com/lei0913/p/10887060.html