欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

电商平台搭建--购物车功能模块开发(一)

程序员文章站 2022-04-14 21:05:10
...

Hi,大家好,新年已经过完了,伴随着我们的是又要开始工作了。祝愿大家在新的一年里工作顺利,生活愉快,年薪升的比火箭还快。

一、购物车模块-概括

      在正是进入开发之前我们先来看一下购物车模块都有哪些功能:

电商平台搭建--购物车功能模块开发(一)

    可以见得,购物车模块的功能还是比较多的,所以我会分较长的篇幅来讲解,力求大家都能看懂。要想封装好一个高复用的购物车模块,就要对购物车的功能有本质上的理解。其实不管是怎么样的购物车,PC端也好移动端也罢,它的核心功能是购物车中商品价格的计算。说道价格的计算,无论你使用哪种后端语言进行开发,都需要考虑在计算购物车中商品价格时丢失计算精度的问题,如果没有把这点考虑好,往往会因为一个小数造成无法下单,更有甚的会引起整个企业出现问题。在解决了价格计算中丢失精度的问题之后,还有一个问题就是通用购物车方法的封装,这个方法会根据商品的价格来进行封装,其中里面封装好了对商品库存的处理,以及再次计算购物车中商品的总价或者单价,并供其他方法进行调用。这两点是写任何一个购物车时必须要考虑到的,如果没有充分考虑这两点,那么在开发中会造成难以预料的错误,在后期调试的时候也会无从下手。

二、购物车模块-开发之前的问题解决

(1)购物车中在计算商品价格时丢失计算精度问题的解决

        在Java中,或者在SSM框架中,解决丢失计算精度问题是使用Java中自带的BigDecimal类,该类继承了Number父类并实现了Comparable<BigDecimal>接口,在项目中是怎么使用的,看下面:

public class BigDecimalUtil {

    private BigDecimalUtil(){

    }


    public static BigDecimal add(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }

    public static BigDecimal sub(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2);
    }


    public static BigDecimal mul(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2);
    }

    public static BigDecimal div(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2,2,BigDecimal.ROUND_HALF_UP);//四舍五入,保留2位小数
    }
}

    新建一个BigDecimalUtil类开始写项目中需要使用的BigDecimal,根据购物车的功能,价格的计算分为四中:增加价格、减少价格、商品数量和价格相乘批量计算商品总价等。在这里是把加减乘除全部写出来了,以防后期调用。在使用BigDecimal的时候先要把它的构造方法写出来而且是空的无参数的,然后分别写add等方法,注意参数的处理,要全部转换为String类型才能使用BigDecimal中内置的add等方法。

(2)购物车中通用方法问题的解决

private CartVo getCartVoLimit(Integer userId){
        CartVo cartVo = new CartVo();
        List<Cart> cartList = cartMapper.selectCartByUserId(userId);
        List<CartProductVo> cartProductVoList = Lists.newArrayList();

        BigDecimal cartTotalPrice = new BigDecimal("0");
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(cartList)){
            for(Cart cartItem : cartList){
                CartProductVo cartProductVo = new CartProductVo();
                cartProductVo.setId(cartItem.getId());
                cartProductVo.setUserId(userId);
                cartProductVo.setProductId(cartItem.getProductId());

                Product product = productMapper.selectByPrimaryKey(cartItem.getProductId());
                if(product != null){
                    cartProductVo.setProductMainImage(product.getMainImage());
                    cartProductVo.setProductName(product.getName());
                    cartProductVo.setProductSubtitle(product.getSubtitle());
                    cartProductVo.setProductStatus(product.getStatus());
                    cartProductVo.setProductPrice(product.getPrice());
                    cartProductVo.setProductStock(product.getStock());
//                    判断库存
                    int buyLimitCount = 0;
                    if(product.getStock() >= cartItem.getQuantity()){
//                        说明库存充足
                        buyLimitCount = cartItem.getQuantity();
                        cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_SUCCESS);
                    }else{
//                        库存不充足的时候
                        buyLimitCount = product.getStock();
                        cartProductVo.setLimitQuantity(Const.Cart.LIMIT_NUM_FAIL);
                        //购物车中更新有效库存
                        Cart cartForQuantity = new Cart();
                        cartForQuantity.setId(cartItem.getId());
                        cartForQuantity.setQuantity(buyLimitCount);
                        cartMapper.updateByPrimaryKeySelective(cartForQuantity);
                    }
                    cartProductVo.setQuantity(buyLimitCount);
                    //计算总价
                    cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),cartProductVo.getQuantity()));
                    cartProductVo.setProductChecked(cartItem.getChecked());
                }
                if(cartItem.getChecked() == Const.Cart.CHECKED){
                    //如果已经勾选,增加到整个的购物车总价中
                    cartTotalPrice = BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVo.getProductTotalPrice().doubleValue());
                }
                cartProductVoList.add(cartProductVo);
            }
        }
        cartVo.setCartTotalPrice(cartTotalPrice);
        cartVo.setCartProductVoList(cartProductVoList);
        cartVo.setAllChecked(this.getAllCheckedStatus(userId));
        cartVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));

        return cartVo;
    }

    该方法对库存和商品的选择进行了逻辑处理,在后面的方法中会重复使用该方法。

三、购物车模块-涉及到的Value-Object(VO)

(1)CartVo

public class CartVo {
    private List<CartProductVo> cartProductVoList;
    private BigDecimal cartTotalPrice;
    private Boolean allChecked;
    private String imageHost;

    public List<CartProductVo> getCartProductVoList() {
        return cartProductVoList;
    }

    public void setCartProductVoList(List<CartProductVo> cartProductVoList) {
        this.cartProductVoList = cartProductVoList;
    }

    public BigDecimal getCartTotalPrice() {
        return cartTotalPrice;
    }

    public void setCartTotalPrice(BigDecimal cartTotalPrice) {
        this.cartTotalPrice = cartTotalPrice;
    }

    public Boolean getAllChecked() {
        return allChecked;
    }

    public void setAllChecked(Boolean allChecked) {
        this.allChecked = allChecked;
    }

    public String getImageHost() {
        return imageHost;
    }

    public void setImageHost(String imageHost) {
        this.imageHost = imageHost;
    }
}

    里面封装了获取商品列表、商品总价、商品全选和商品的图片服务器。

(2)CartProductVo

public class CartProductVo {
    private Integer id;
    private Integer userId;
    private Integer productId;
//            商品数量
    private Integer quantity;
    private String productName;
    private String productSubtitle;
    private String productMainImage;
    private BigDecimal productPrice;
    private Integer productStatus;
    private BigDecimal productTotalPrice;
    private Integer productStock;
    private Integer productChecked;
    private String limitQuantity;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getProductId() {
        return productId;
    }

    public void setProductId(Integer productId) {
        this.productId = productId;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSubtitle() {
        return productSubtitle;
    }

    public void setProductSubtitle(String productSubtitle) {
        this.productSubtitle = productSubtitle;
    }

    public String getProductMainImage() {
        return productMainImage;
    }

    public void setProductMainImage(String productMainImage) {
        this.productMainImage = productMainImage;
    }

    public BigDecimal getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(BigDecimal productPrice) {
        this.productPrice = productPrice;
    }

    public Integer getProductStatus() {
        return productStatus;
    }

    public void setProductStatus(Integer productStatus) {
        this.productStatus = productStatus;
    }

    public BigDecimal getProductTotalPrice() {
        return productTotalPrice;
    }

    public void setProductTotalPrice(BigDecimal productTotalPrice) {
        this.productTotalPrice = productTotalPrice;
    }

    public Integer getProductStock() {
        return productStock;
    }

    public void setProductStock(Integer productStock) {
        this.productStock = productStock;
    }

    public Integer getProductChecked() {
        return productChecked;
    }

    public void setProductChecked(Integer productChecked) {
        this.productChecked = productChecked;
    }

    public String getLimitQuantity() {
        return limitQuantity;
    }

    public void setLimitQuantity(String limitQuantity) {
        this.limitQuantity = limitQuantity;
    }
}

    这里封装了和商品有关的所有商品信息字段。

两个VO结合起来就可以对购物车中的商品进行逻辑操作了

写到这里,差不多本篇博文就写完了。在本篇博文中我们搭建好了一个购物车的开发环境,为接下来的功能开发提供了开发基础,在后面博文中,我会加快开发进度,希望大家跟上进度。下期再见!!