电子商城购物车初步分析

本文原地址来自于我的个人博客:www.endless365.com,希望得到各位的关注。

本文详细地址出自于:http://www.endless365.com/article/get?type=tec&id=150


购物车是一个比较复杂的系统,一般会和订单、商品、库存、会员、促销等模块有关系,按照电子商城的功能需求,购物车模块可大可小,所以按照功能需求做的同时考虑后期的扩展,以下对一个比较简单购物车进行初步分析,如果有什么问题或者愿意和我交流的,请联系评论或者email我,我的email是[email protected]

    我从几个方面去分析:

    1、什么是购物车。

    2、购物车的入口。

    3、购物车的出口。

    4、购物车的状态和管理。

    5、购物车的存储。

    

    1、购物车

    简单的理解,方便用户将自己心仪的商品放在一个可展示和保存的集合里面,在选购完以后用于集中处理购买。

    2、购物车的入口

    作为电子商务网站,最重要的目的就是诱导顾客购买自己的产品,所以恰当的购物车入口是非常重要的,常见的购物车入口有:商品详情页面、收藏夹页面、推荐商品页面、以购买成功的订单页面、已取消订单商品的页面、排行推荐的页面等。

    3、购物车的出口

    常见的购物车出口有:结算、删除、加入收藏等

    4、购物车的状态和管理

    状态:

                登陆前购物车

                        价格,数量,是否过期,是否存在库存等

                登陆后购物车

                        价格,数量,折扣,优惠券,是否过期,是否存在库存等

    管理:

            可以通过下图来表示:

            电子商城购物车初步分析_第1张图片

    5、购物车的存储。

        在对购物车的代码实现方面这一块非常的重要。

        按照我的里面,我将购物车分为登陆前购物车、登陆后购物车和登陆后两种购物车的合并。

        对于存储当然就存在以下几个比较常见的疑问:

                1、加入购物车后的商品,等到第二次登陆该网站的时候,商品却消失了?

                2、为什么我还一台电脑,购物车的商品却没有了?

                3、我没有往购物车添加商品,为什么我的购物车里面有了商品?

                4、我在网站上将商品添加到了购物车,我下次登陆,或者更换电脑登陆是否同样能够看到我加入购物车的东西,不管我是否加入购物车有没有登陆?

                ......

                根据以上几种疑问衍生出购物车商品的存储。

                cookie存储,会话session存储,本地存储,数据库存储,本地数据库存储。

                针对这些存储介绍一下他们的特点。

                cookie存储:

                        大多数浏览器支持最大为 4096 字节的 Cookie;

                        浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;

                        如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个;

                        Cookie默认情况都会随着Http请求发送到后台服务器,但并不是所有请求都需要Cookie的,比如:js、css、图片等请求则不需要cookie;

                        Cookie可以通过一些设置来管理他的过期时间等,一旦过期,所保存的信息将丢失

                        浏览器有可能禁止cookies。

            会话session存储:

                        所有保存的信息都存放在session当中,一旦会话结束,下次再次登陆网站,保存信息将丢失

            本地存储:

                        会话级别本地存储sessionStorage和永久本地存储localStorage

                        sessionStorage:通过此对象可以直接操作存储在浏览器中的会话级别的WebStorage。存储在sessionStorage中的数据首先是Key-Value形式的,另外就是它跟浏览器当前会话相关,当会话结束后,数据会自动清除,跟未设置过期时间的Cookie类似。

                        localStorage:便于用户存储永久存储的Web端的数据。而且数据不会随着Http请求发送到后台服务器,而且存储数据的大小机会不用考虑,因为在HTML5的标准中要求浏览器至少要支持到4MB.所以,这完全是颠覆了Cookie的限制,为Web应用在本地存储复杂的用户痕迹数据提供非常方便的技术支持。

            数据库存储:

                        将所有的信息都存储在服务器数据库中,该种方式购物车信息被永久存储,但是需要额外的表进行存储并需要和服务器频繁的打交道。

            本地数据库存储:

                        Html5提供了一个浏览器端的数据库支持,允许我们直接通JS的API在浏览器端创建一个本地的数据库,而且支持标准的SQL的CRUD操作,让离线的Web应用更加方便的存储结构化的数据。


        根据这次开发的功能,我选择了localStorage来保存登陆前的购物车。

        首先简单的介绍一下localStroage的使用:

        localStorage存储数据类似于key-value形式,提供了四个方法来辅助我们进行对本地存储做相关操作。
        (1)setItem(key,value):添加本地存储数据。两个参数,非常简单就不说了。
        (2)getItem(key):通过key获取相应的Value。
        (3)removeItem(key):通过key删除本地数据。
        (4)clear():清空数据。

        由于在开发过程中使用了百度ueditor进行商品信息的编辑,发现ueditor也将一些缓存信息和配置等放在了localStroage中,所以对于购物车的商品信息和其他应用存放在localStroage导致一些混淆,以至于localStorage不能只被购物车所使用,所有考虑了两种方法出去处理,一种是将购物车封装成一个独有key和数据value进行处理,这样所有的购物车信息都只存在于这个独有key的value中;另外一种方式就是给每一个购物车的key加上特有的标识,这样通过标识可以唯一的获取到购物车的信息。

        以下是我对localStorage的一些操作。

    //获取本地购物车的json字符串
    function getLocalCartParam(){
        var param = "[";
        var storage = window.localStorage;
        for (var i = 0, len = storage.length; i < len; i++) {
            var key = storage.key(i);
            if(key.indexOf("THX") == -1){
                continue;
            }
            var item = storage.getItem(key);
            param += ("{\"productId\":" + key + ",\"count\":" + item + "},");
        }
        param += "]";
        return param;
    }
    //获取本地购物车的数量
    function getLocalCartCount(){
        var storage = window.localStorage;
        var count = 0;
        for (var i = 0, len = storage.length; i < len; i++) {
            var key = storage.key(i);
            if(key.indexOf("THX") != -1){
                count ++;    
            }
        }    
        return count;
    }
    //保存商品到购物车中
    function setLocalCart(productId){
        var storage = window.localStorage;
        var bl = true;
        var tempProductId = "THX"+productId;
        for (var i = 0, len = storage.length; i < len; i++) {
            var key = storage.key(i);
            if (tempProductId == key) {
                var value = storage.getItem(key);
                localStorage.setItem(tempProductId, parseInt(value) + 1);
                bl = false;
                break;
            }
        }
        if (bl) {
            localStorage.setItem(tempProductId, 1);
        }
        var count = getLocalCartCount();
        setCartNumber(count);
    }

        登陆后,所有的购物车信息存储到数据库中

        以下代码是对于购物车管理的serviceImpl的实现简单代码

package com.liveman.shop.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.liveman.shop.dao.order.CartMapper;
import com.liveman.shop.entity.order.Cart;
import com.liveman.shop.entity.order.CartJson;
import com.liveman.shop.entity.order.CartVO;
import com.liveman.shop.entity.product.Product;
import com.liveman.shop.global.DateTool;
import com.liveman.shop.service.CartService;
import com.liveman.shop.service.ProductService;

/**
 * 
 * @author sunny
 *
 */
@Component("cartService")
public class CartServiceImpl implements CartService{
    
    @Resource
    CartMapper dao;
    @Autowired
    ProductService productService;
    
    @Override
    public int insertCart(Cart cart) {
        Cart temp = dao.findCartByProductId(cart);
        if(temp != null){
            int productCount = temp.getProductCount();
            temp.setProductCount(productCount+cart.getProductCount());
            dao.updateCartById(temp);
        }else{
            dao.insertCart(cart);
        }
        int count = dao.findCartCount(cart.getUserId());
        return count;
        
    }

    @Override
    public void deleteCartByIds(List<Integer> ids) {
        if(ids.size()!=0){
            dao.deleteCartByIds(ids);
        }
    }

    @Override
    public void updateCartById(int id, int count) {
        Cart temp = dao.findCartById(id);
        temp.setProductCount(count);
        dao.updateCartById(temp);
    }

    @Override
    public List<CartVO> findCartsByUserId(int userId) {
        List<CartVO> carts = dao.findCartsByUserId(userId);
        return carts;
    }

    @Override
    public void deleteAllCartsByUserId(int userId) {
        dao.deleteAllCartsByUserId(userId);
    }

    @Override
    public int getCartCount(int userId) {
        int count = dao.findCartCount(userId);
        return count;
    }

    @Override
    public List<CartVO> findCartsByProductIds(int userId, List<Integer> ids) {
        List<CartVO> vos = new ArrayList<>();
        if(ids.size() !=0){
            vos = dao.findCartsByProductIds(userId, ids);
        }
        return vos;
    }

    @Override
    public List<CartVO> findCartsByProductIds(String jsons) {
        if(jsons == null ||"".equals(jsons.trim())){
            return new ArrayList<CartVO>();
        }
        List<CartJson> cartJsons = jsonToList(jsons);
        List<Integer> productIds = new ArrayList<>();
         for(CartJson json : cartJsons){
             productIds.add(json.getProductId());
         }
        Map<Integer,Product> maps = productService.getSimpleProductByIds(productIds);
        List<CartVO> vos = new ArrayList<>();
        for(CartJson json : cartJsons){
            CartVO vo = new CartVO();
            Cart cart = new Cart();
            cart.setProductId(json.getProductId());
            cart.setProductCount(json.getCount());
            vo.setCart(cart);
            vo.setProduct(maps.get(json.getProductId()));
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public void mergeCart(int userId,String jsons) {
        if(jsons == null ||"".equals(jsons.trim())){
            return;
        }
        List<CartJson> cartJsons = jsonToList(jsons);
        Cart cart = new Cart();
         for(CartJson json : cartJsons){
             cart.setCreateTime(DateTool.getCurrentDateCN());
             cart.setUserId(userId);
             cart.setProductCount(json.getCount());
             cart.setProductId(json.getProductId());
             insertCart(cart);
         }
    }
    
    private List<CartJson> jsonToList(String jsons){
        jsons = jsons.replace("THX", "");
        jsons = jsons.substring(0, jsons.lastIndexOf(",")) +"]";
        ObjectMapper mapper = new ObjectMapper();  
        List<CartJson> cartJsons = new ArrayList<>();
         try {
             cartJsons = mapper.readValue(jsons, new TypeReference<List<CartJson>>() {});
        } catch (Exception e) {
            e.printStackTrace();
        }
         return cartJsons;
    }

}

    当用户登录的时候,牵扯到了未登录购物车和登陆购物车的合并,当用户登录后,将未登录购物车里面的信息合并到用户登录后购物车中,成功以后,清除localStorage里面的购物车信息。

    我的实现思路是当数据合并后,通过springmvc的转向跳转到前台清理页面,清理完成以后跳转到需要的页面。

后台跳转代码:
@RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(HttpSession session, String email, String password,String hiddenCarts) {
        ReturnStatus rs = userService.login(email, password);
        if (rs.getCode() == 1) {
            User user = (User) rs.getUserData();
            session.setAttribute("user", user);
            cartService.mergeCart(user.getId(), hiddenCarts);
            ModelAndView m = new ModelAndView("order/clearTempCart");
            m.addObject("count",cartService.getCartCount(user.getId()));
            return m ;
        } else {
            ModelAndView m = new ModelAndView("login");
            m.addObject("email", email);
            m.addObject("password", password);
            m.addObject("errorMessage", "邮箱或者密码不正确");
            return m;
        }
    }


前台清理:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="../js/jquery.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script>
    $(document).ready(function() {
        localStorage.clear();
        location.href="/Shop";
    });
</script>
</head>
<body>
</body>
</html>

    在网络上看到一个购物车系统描述的比较好的图,贴出来大家可以参考:

        电子商城购物车初步分析_第2张图片

以上总结算是自己对购物车的一点处理理解吧,如果有任何的问题,请大家指正!

你可能感兴趣的:(电子商城购物车初步分析)