e3mall项目:购物车模块

e3mall项目:购物车模块

准备工作:创建服务层子工程:e3-cart,在其工程下创建e3-cart-interface、e3-cart-service。创建表现层子工程:e3-cart-web。创建好包结构,导入相关配置文件和静态资源。



一、服务层相关代码(CartService、CartServiceI,pl)

package cn.e3mall.cart.service;

import cn.e3mall.common.entity.E3Result;
import cn.e3mall.entity.TbItem;

import java.util.List; /**
 * 购物车相关 service层
 * Author: xushuai
 * Date: 2018/5/30
 * Time: 12:41
 * Description:
 */
public interface CartService {

    /**
     * 添加商品到购物车
     * @auther: xushuai
     * @date: 2018/5/30 12:41
     */
    void addProductToCart(Long itemId, Long userId, Integer num);

    /**
     * 将cookie中的商品列表添加到服务端
     * @auther: xushuai
     * @date: 2018/5/30 14:20
     * @return: List<TbItem> 商品列表
     */
    void addProductFromCookie(List<TbItem> items, Long userId);

    /**
     * 更新服务端商品数量
     * @auther: xushuai
     * @date: 2018/5/30 14:57
     */
    void update(Long itemId, Long userId,Integer num);

    /**
     * 删除服务端指定商品
     * @auther: xushuai
     * @date: 2018/5/30 15:35
     */
    void delete(Long itemId, Long userId);

    /**
     * 获取指定用户的购物车信息
     * @auther: xushuai
     * @date: 2018/5/30 16:00
     * @return:
     * @throws:
     */
    List<TbItem> getItemListFromRedis(Long userId);
}
package cn.e3mall.cart.service.impl;

import cn.e3mall.cart.service.CartService;
import cn.e3mall.common.entity.E3Result;
import cn.e3mall.common.redis.JedisClient;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.dao.TbItemMapper;
import cn.e3mall.entity.TbItem;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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

/**
 * 购物车相关 service层实现
 * Author: xushuai
 * Date: 2018/5/30
 * Time: 12:41
 * Description:
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private JedisClient jedisClient;

    @Value("${redis.cart}")
    private String cart;

    @Autowired
    private TbItemMapper itemMapper;

    @Override
    public void addProductToCart(Long itemId, Long userId, Integer num) {
        //生成redis的key
        String key = cart + ":" + userId;
        //生成redis的field
        String field = itemId.toString();

        //判断商品是否已存在
        String json = jedisClient.hget(key, field);
        if(StringUtils.isNotBlank(json)){
            //存在,数量相加
            TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);
            item.setNum(item.getNum() + num);
            //将新的item对象,写入redis
            jedisClient.hset(key,field,JsonUtils.objectToJson(item));
        }
        //不存在,查询该商品信息
        TbItem item = itemMapper.selectByPrimaryKey(itemId);
        item.setNum(num);
        //对图片数据进行处理
        String image = item.getImage();
        if(StringUtils.isNotBlank(image)){
            item.setImage(image.split(",")[0]);
        }
        //将item对象,写入redis
        jedisClient.hset(key,field,JsonUtils.objectToJson(item));

    }

    @Override
    public void addProductFromCookie(List<TbItem> items, Long userId) {
        //遍历商品集合,添加到redis中
        for(TbItem item : items){
            //执行添加操作
            addProductToCart(item.getId(),userId,item.getNum());
        }
    }

    @Override
    public void update(Long itemId, Long userId, Integer num) {
        //生成redis的key
        String key = cart + ":" + userId;
        //生成redis的field
        String field = itemId.toString();
        //获取redis中的商品
        String json = jedisClient.hget(key, field);
        TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);
        //修改商品数量
        item.setNum(num);
        //然后重新写入
        jedisClient.hset(key,field,JsonUtils.objectToJson(item));
    }

    @Override
    public void delete(Long itemId, Long userId) {
        //执行删除
        jedisClient.hdel(cart+":"+userId,itemId.toString());
    }

    /**
     * 获取指定用户的购物车商品列表
     * @auther: xushuai
     * @date: 2018/5/30 14:42
     * @param: userId 用户ID
     * @return: List<TbItem> 商品列表
     */
    @Override
    public List<TbItem> getItemListFromRedis(Long userId) {
        //使用用户ID生成redis的key
        String key = cart + ":" + userId;
        //获取该key中所有的值
        List<String> stringList = jedisClient.hvals(key);
        //遍历集合,生成商品列表
        List<TbItem> itemList = new ArrayList<>();
        for(String json : stringList){
            TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);
            itemList.add(item);
        }

        //返回商品列表
        return itemList;
    }
}

二、表现层相关代码(CartController、LoginInterceptor)

package cn.e3mall.cart.controller;

import cn.e3mall.cart.service.CartService;
import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.entity.TbItem;
import cn.e3mall.entity.TbUser;
import cn.e3mall.service.ItemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

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

/**
 * 购物车 web层
 * Author: xushuai
 * Date: 2018/5/29
 * Time: 21:05
 * Description:
 */
@Controller
public class CartController {

    @Autowired
    private ItemService itemService;

    @Autowired
    private CartService cartService;

    @Value("${cookie.timeout}")
    private Integer cookieTimeout;

    /**
     * 添加指定商品到购物车
     * @auther: xushuai
     * @date: 2018/5/29 21:06
     */
    @RequestMapping("/cart/add/{itemId}")
    public String addToCart(@PathVariable Long itemId,
                            @RequestParam(defaultValue = "1") Integer num,
                            HttpServletRequest request, HttpServletResponse response){
        //判断当前是否为登录状态
        TbUser user = (TbUser) request.getAttribute("user");
        if(user != null){
            //为登录状态
            //调用service保存商品数据
            cartService.addProductToCart(itemId,user.getId(),num);

            //保存成功,返回
            return "cartSuccess";
        }
        //获取cookie中的购物车列表
        List<TbItem> items = getProductListByCart(request);
        //校验当前添加商品是否在购物车中已存在
        boolean flag = false;
        for (TbItem item : items){
            //已存在
            if(item.getId() == itemId.longValue()){
                //对数量进行增加
                item.setNum(item.getNum() + num);
                //修改标志,并退出循环
                flag = true;
                break;
            }
        }
        //通过标志判断购物车是否存在该商品
        if(!flag){
            //不存在,按ID查询商品信息
            TbItem item = (TbItem) itemService.load(itemId).getData();
            item.setNum(num);
            //处理图片数据
            String image = item.getImage();
            if(StringUtils.isNotBlank(image)){
                item.setImage(image.split(",")[0]);
            }
            items.add(item);
        }
        //将最新的购物车列表写入cookie
        CookieUtils.setCookie(request,response,
                "CART",JsonUtils.objectToJson(items),cookieTimeout,true);

        return "cartSuccess";
    }

    /**
     * 展示购物车
     * @auther: xushuai
     * @date: 2018/5/29 22:32
     * @return:
     * @throws:
     */
    @RequestMapping("/cart/cart")
    public String showCart(HttpServletRequest request, HttpServletResponse response, Model model){
        //判断当前是否为登录状态
        TbUser user = (TbUser) request.getAttribute("user");
        if(user != null){
            //为登录状态,同步cookie中的数据到服务端
            List<TbItem> items = getProductListByCart(request);
            if(items != null){
                //执行同步操作
                cartService.addProductFromCookie(items, user.getId());
                //删除cookie中的数据
                CookieUtils.deleteCookie(request,response,"CART");
                //查询服务端购物车数据
                List<TbItem> itemList = cartService.getItemListFromRedis(user.getId());
                //保存同步后的商品列表
                model.addAttribute("cartList",itemList);

                return "cart";
            }
        }
        //为离线状态
        //从cookie中取出购物车商品列表
        List<TbItem> items = getProductListByCart(request);
        //将购物车商品列表保存,发送到页面
        model.addAttribute("cartList",items);

        return "cart";
    }

    /**
     * 更新购物车内指定商品数量
     * @auther: xushuai
     * @date: 2018/5/30 12:12
     */
    @RequestMapping("/cart/update/num/{itemId}/{num}")
    @ResponseBody
    public String updateNum(@PathVariable Long itemId,@PathVariable Integer num,
                            HttpServletRequest request,HttpServletResponse response){
        //判断当前是否为登录状态
        TbUser user = (TbUser) request.getAttribute("user");
        if(user != null){
            //为登录状态,修改服务端对应商品数量
            cartService.update(itemId,user.getId(),num);
            //修改完成,返回
            return itemId.toString();
        }

        //从cookie中取出购物车信息
        List<TbItem> items = getProductListByCart(request);
        //遍历商品列表,进行商品数量更新
        boolean flag = false;
        if(items != null && items.size() > 0){
            for(TbItem item : items){
                //如果存在该商品进行数量更新
                if(item.getId() == itemId.longValue()){
                    item.setNum(num);
                    //修改标志为true
                    flag = true;
                    break;
                }
            }
        }
        //根据标志位判断是否做了修改
        if(flag){
            //做了修改,将新的购物车信息写入cookie
            CookieUtils.setCookie(request,response,
                    "CART",JsonUtils.objectToJson(items),cookieTimeout,true);
        }
        //没有修改不做任何操作,返回即可
        return itemId.toString();
    }

    @RequestMapping("/cart/delete/{itemId}")
    public String delete(@PathVariable Long itemId,HttpServletRequest request,HttpServletResponse response){
        //判断当前是否为登录状态
        TbUser user = (TbUser) request.getAttribute("user");
        if(user != null){
            //登录状态,删除服务端指定商品
            cartService.delete(itemId,user.getId());
            //重定向到购物车列表
            return "redirect:/cart/cart.html";
        }else{
            //未登录状态
            //从cookie中取出购物车商品列表
            List<TbItem> items = getProductListByCart(request);
            //操作标志
            boolean flag = false;
            //健壮性判断
            if(items != null && items.size() > 0){
                //遍历商品列表,删除指定ID的商品
                for(TbItem item : items){
                    if(item.getId() == itemId.longValue()){
                        //从cookie中删除该商品
                        items.remove(item);
                        //修改操作标志为true
                        flag = true;
                        //退出循环
                        break;
                    }
                }
            }
            //判断操作标志
            if(flag){
                //进行了数据操作,将新的商品列表写入cookie
                CookieUtils.setCookie(request,response,
                        "CART",JsonUtils.objectToJson(items),cookieTimeout,true);
            }
        }
        //没有进行数据操作,不做任何处理
        //重定向到购物车列表
        return "redirect:/cart/cart.html";
    }

    /**
     * 从cookie中获取购物车列表
     * @auther: xushuai
     * @date: 2018/5/29 21:37
     */
    private List<TbItem> getProductListByCart(HttpServletRequest request) {
        //从cookie中取数据
        String value = CookieUtils.getCookieValue(request, "CART", true);
        //如果json为空,返回一个空集合
        if(StringUtils.isBlank(value)){
            return new ArrayList<>();
        }
        //不为空,将json字符串转换为list集合
        return JsonUtils.jsonToList(value,TbItem.class);
    }


}
package cn.e3mall.cart.interceptor;

import cn.e3mall.common.entity.E3Result;
import cn.e3mall.common.redis.JedisClient;
import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.entity.TbUser;
import cn.e3mall.sso.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录状态判断拦截器
 * Author: xushuai
 * Date: 2018/5/30
 * Time: 12:24
 * Description:
 */
public class LoginInterceptor implements HandlerInterceptor{

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //从cookie中取出token信息
        String token = CookieUtils.getCookieValue(httpServletRequest, "token");
        //判断token是否为空
        if(StringUtils.isBlank(token)){
            //为空,直接放行
            return true;
        }
        //不为空,使用token获取登录用户信息
        E3Result e3Result = userService.getLoginUser(token);
        //如果e3result中的status属性不是200,说明该登录状态为已过期,直接放行
        if(e3Result.getStatus() != 200){
            return true;
        }
        //登录状态正常,进行处理
        //获取用户数据
        TbUser user = (TbUser) e3Result.getData();
        //将user保存到request中
        httpServletRequest.setAttribute("user",user);

        //放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}


三、页面修改及其js修改

(1)设置小计处的id

(2)cart.js修改

var CART = {
	itemNumChange : function(){
		$(".increment").click(function(){//+
			var _thisInput = $(this).siblings("input");
			_thisInput.val(eval(_thisInput.val()) + 1);
			$.post("/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val() + ".action?r=" + Math.random(),function(data){
				CART.refreshTotalPrice(data);
			});
		});
		$(".decrement").click(function(){//-
			var _thisInput = $(this).siblings("input");
			if(eval(_thisInput.val()) == 1){
				return ;
			}
			_thisInput.val(eval(_thisInput.val()) - 1);
			$.post("/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val() + ".action?r=" + Math.random(),function(data){
				CART.refreshTotalPrice(data);
			});
		});
		/*$(".itemnum").change(function(){
			var _thisInput = $(this);
			$.post("/service/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val(),function(data){
				CART.refreshTotalPrice();
			});
		});*/
	},
	refreshTotalPrice : function(itemId){ //重新计算总价
		var total = 0;
		$(".itemnum").each(function(i,e){
			var _this = $(e);
			total += (eval(_this.attr("itemPrice")) * 10000 * eval(_this.val())) / 10000;
		});
		$("#allMoney2").html(new Number(total/100).toFixed(2)).priceFormat({ //价格格式化插件
			 prefix: '¥',
			 thousandsSeparator: ',',
			 centsLimit: 2
		});
		total = 0;
        $(".itemnum").each(function(i,e){
            var _this = $(e);
            // alert(_this.attr("itemId"));
            // alert(itemId);
            if(_this.attr("itemId") == itemId){
                total += (eval(_this.attr("itemPrice")) * 10000 * eval(_this.val())) / 10000;
            }
        });
        $("#total_price"+itemId).html(new Number(total/100).toFixed(2)).priceFormat({ //价格格式化插件
            prefix: '¥',
            thousandsSeparator: ',',
            centsLimit: 2
        });
	}
};

$(function(){
	CART.itemNumChange();
});

(3)修改内容(对上方js修改进行说明)



猜你喜欢

转载自blog.csdn.net/qq1031893936/article/details/80522164