移动商城第七篇【购物车增删改查、提交订单】

 
 

把商品加入购物车

接下来我们要做的就是将商品加入到购物车中。我们这次使用的是Cookie来将用户的信息存储起来。那为什么要用cookie呢??

那我们现在决定将购物车存储在Cookie中了,那Cookie中保存的是怎么样的字符串数据呢???

JSON能够很好地将字符串转成Java对象,将Java对象转成JSON给浏览器进行显示!

看回我们的加入购物车,将什么数据加入进去呢???

640?wx_fmt=png

我们可以将数量和SkuId加入进去就行了。有了SkuId就可以获取商品类的所有数据了!

加入购物车之前

在加入购物车之前我们需要做两件事:

在页面上通过class属性和自定义id来获取页面上的库存和数量!

640?wx_fmt=png

前台页面的代码如下:

        //加入购物车之前,判断库存和cookie        function addCart() {            var cookieResult = validateCookie();            if (cookieResult == "ban") {                alert("Cookie被禁用了,无法加入购物车");                return;            }            //在页面上获取得到对应的skuId和数量            var skuId = null ;            $("#skuChange a").each(function(){                var clazz = $(this).attr("class");                if(clazz == "here"){                    skuId = $(this).attr("skuId");                }            });            var quantity = $("#quantity").val();            var StockResult = validateStock(skuId,quantity);            if (StockResult == "noStock") {                alert("库存已经不足,无法加入购物车");                return;            }            window.location.href = "http://localhost:8080/portal/cart/addCart.do";        }        function validateCookie() {            var result = "";            $.ajax({                url: "http://localhost:8080/portal/cart/validateCookie.do",                type: "post",                async:false,                success:function (responseText) {                    result =  responseText                },                error:function () {                    alert("系统错误");                }            });            return result;        }        function validateStock(skuId,quantity) {            var result = "";            $.ajax({                url: "http://localhost:8080/portal/cart/validateStock.do",                data:{                    skuId:skuId,                    quantity:quantity                },                type: "post",                async:false,                success:function (responseText) {                    result =  responseText                },                error:function () {                    alert("系统错误");                }            });            return result;        }
       function addCart() {

           var cookieResult = validateCookie();
           if (cookieResult == "ban") {
               alert("Cookie被禁用了,无法加入购物车");
               return;
           }
           //在页面上获取得到对应的skuId和数量
           var skuId = null ;
           $("#skuChange a").each(function(){
               var clazz = $(this).attr("class");
               if(clazz == "here"){
                   skuId = $(this).attr("skuId");
               }
           });
           var quantity = $("#quantity").val();
           var StockResult = validateStock(skuId,quantity);
           if (StockResult == "noStock") {
               alert("库存已经不足,无法加入购物车");
               return;
           }
           window.location.href = "http://localhost:8080/portal/cart/addCart.do";
       }
       function validateCookie() {
           var result = "";
           $.ajax({
               url: "http://localhost:8080/portal/cart/validateCookie.do",
               type: "post",
               async:false,
               success:function (responseText) {
                   result =  responseText
               },
               error:function () {
                   alert("系统错误");
               }
           });
           return result;
       }
       function validateStock(skuId,quantity) {
           var result = "";
           $.ajax({
               url: "http://localhost:8080/portal/cart/validateStock.do",
               data:{
                   skuId:skuId,
                   quantity:quantity
               },
               type: "post",
               async:false,
               success:function (responseText) {
                   result =  responseText
               },
               error:function () {
                   alert("系统错误");
               }
           });
           return result;
       }

将数据拼接成Cookie保存起来

在前台中已经通过ajax调用service来判断是否有库存和cookie是否被禁用了。接下来就将我们的skuId和quantity拼接成Cookie保存起来。也是使用ajax来将数据带过去

            //将skuId和quantity带过去给服务器            $.ajax({                url: "http://localhost:8080/portal/cart/addCart.do",                data:{                    skuId:skuId,                    quantity:quantity                },                type: "post",                success:function (responseText) {                     if(responseText=="addSuccess"){                         alert("成功添加到购物车中!");                     }                },                error:function () {                    alert("系统错误");                }            });
           $.ajax({
               url: "http://localhost:8080/portal/cart/addCart.do",
               data:{
                   skuId:skuId,
                   quantity:quantity
               },
               type: "post",
               success:function (responseText) {
                    if(responseText=="addSuccess"){
                        alert("成功添加到购物车中!");
                    }
               },
               error:function () {
                   alert("系统错误");
               }
           });

编写service添加购物车

    /**     * 添加购物车,使用Cookie保存起来!     *     * 使用到Cookie的话,那么就需要用到request和response对象了。     * @param request     * @param response     */    void  addCart(HttpServletRequest request, HttpServletResponse response,Long skuId, Integer quantity);
   void  addCart(HttpServletRequest request, HttpServletResponse response,Long skuId, Integer quantity);

把商品添加购物车中也有好几种情况:

接下来我们来去看看购物车页面是怎么样的:

640?wx_fmt=png

只有知道了购物车展示页面我们才知道我们的购物车实体是怎么设计的

640?wx_fmt=png

从图上我们可以知道大多数的数据都是Sku中的,还有商品的编号和商品的名称。

于是,我们可以使用Sku作为主体,与Item来进行关联就行了。于是乎,我们可以设计购物车实体是这样的:

public class EbCart {    private Long skuId;    private Integer quantity;    private EbSku sku;    public Long getSkuId() {        return skuId;    }    public void setSkuId(Long skuId) {        this.skuId = skuId;    }    public Integer getQuantity() {        return quantity;    }    public void setQuantity(Integer quantity) {        this.quantity = quantity;    }    public EbSku getSku() {        return sku;    }    public void setSku(EbSku sku) {        this.sku = sku;    }}class EbCart {

   private Long skuId;
   private Integer quantity;

   private EbSku sku;

   public Long getSkuId() {
       return skuId;
   }
   public void setSkuId(Long skuId) {
       this.skuId = skuId;
   }

   public Integer getQuantity() {
       return quantity;
   }

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

   public EbSku getSku() {
       return sku;
   }

   public void setSku(EbSku sku) {
       this.sku = sku;
   }
}

sku实体要与Item进行关联:

    //与Item进行关联    private EbItem item;    public EbItem getItem() {        return item;    }    public void setItem(EbItem item) {        this.item = item;    }
   private EbItem item;
   public EbItem getItem() {
       return item;
   }
   public void setItem(EbItem item) {
       this.item = item;
   }

根据cookie的三种情况写service业务逻辑

 public void addCart(HttpServletRequest request, HttpServletResponse response, Long skuId, Integer quantity) {        List<EbCart> cartList = null;        //json的配置对象        JsonConfig jc = new JsonConfig();        //设置要转换的类        jc.setRootClass(EbCart.class);        //设置不需要转换的属性        jc.setExcludes(new String[]{"sku"});        Cookie[] cookies = request.getCookies();        if (cookies != null && cookies.length > 0) {            for (Cookie c : cookies) {                String name = c.getName();                //读取购物车的key,在配置文件中保存起来了。                String cart_key = ResourcesUtils.readProp("cart_key");                if (StringUtils.equalsIgnoreCase(name, cart_key)) {                    //得到cookie里边的值【JSON格式的数组】                    String value = c.getValue();                    //将JSON数组转成是Java对象                    JSONArray ja = JSONArray.fromObject(value);                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    //判断要添加的商品在购物车是否存在                    String result = "noExist";                    for (EbCart cart : cartList) {                        //购物车中已存在                        if (cart.getSkuId() == skuId) {                            cart.setQuantity(cart.getQuantity() + quantity);                            result = "exist";                        }                    }                    //购物车中的商品不存在                    if (StringUtils.equalsIgnoreCase("noExist", result)) {                        EbCart ebCart = new EbCart();                        ebCart.setQuantity(quantity);                        ebCart.setSkuId(skuId);                        cartList.add(ebCart);                    }                }            }        }        //上边已经判断了购物车存在,商品是否存在的两种情况了。以下是判断购物车是否存在的问题        //如果上边的cookie为null,转换不了List集合的话,那么我们的List集合是为空的。List集合为空的话,那么我们的购物车是不存在的。        if (cartList == null || cartList.size() == 0) {            cartList = new ArrayList<EbCart>();            EbCart ebCart = new EbCart();            ebCart.setQuantity(quantity);            ebCart.setSkuId(skuId);            cartList.add(ebCart);        }        //最后将我们的Java对象重新转成JSON,将Cookie更新           JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();        Cookie cookie = new Cookie("cart_key", result);        cookie.setMaxAge(Integer.MAX_VALUE);        cookie.setPath("/");        response.addCookie(cookie);    }

       List<EbCart> cartList = null;

       //json的配置对象
       JsonConfig jc = new JsonConfig();
       //设置要转换的类
       jc.setRootClass(EbCart.class);
       //设置不需要转换的属性
       jc.setExcludes(new String[]{"sku"});

       Cookie[] cookies = request.getCookies();
       if (cookies != null && cookies.length > 0) {
           for (Cookie c : cookies) {
               String name = c.getName();

               //读取购物车的key,在配置文件中保存起来了。
               String cart_key = ResourcesUtils.readProp("cart_key");
               if (StringUtils.equalsIgnoreCase(name, cart_key)) {
                   //得到cookie里边的值【JSON格式的数组】
                   String value = c.getValue();

                   //将JSON数组转成是Java对象
                   JSONArray ja = JSONArray.fromObject(value);
                   cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);

                   //判断要添加的商品在购物车是否存在
                   String result = "noExist";
                   for (EbCart cart : cartList) {
                       //购物车中已存在
                       if (cart.getSkuId() == skuId) {
                           cart.setQuantity(cart.getQuantity() + quantity);
                           result = "exist";
                       }
                   }
                   //购物车中的商品不存在
                   if (StringUtils.equalsIgnoreCase("noExist", result)) {
                       EbCart ebCart = new EbCart();
                       ebCart.setQuantity(quantity);
                       ebCart.setSkuId(skuId);
                       cartList.add(ebCart);
                   }
               }
           }
       }
       //上边已经判断了购物车存在,商品是否存在的两种情况了。以下是判断购物车是否存在的问题
       //如果上边的cookie为null,转换不了List集合的话,那么我们的List集合是为空的。List集合为空的话,那么我们的购物车是不存在的。
       if (cartList == null || cartList.size() == 0) {
           cartList = new ArrayList<EbCart>();
           EbCart ebCart = new EbCart();
           ebCart.setQuantity(quantity);
           ebCart.setSkuId(skuId);
           cartList.add(ebCart);
       }

       //最后将我们的Java对象重新转成JSON,将Cookie更新
          JSONArray ja = JSONArray.fromObject(cartList, jc);
       String result = ja.toString();
       Cookie cookie = new Cookie("cart_key", result);
       cookie.setMaxAge(Integer.MAX_VALUE);
       cookie.setPath("/");
       response.addCookie(cookie);

   }
640?wx_fmt=png

查看购物车

查看购物车并不难,和添加购物车一样。都是将Cookie的值转成是Java对象,然后将Java对象返回给页面做展示就行了

通过skuId查询出具体的商品信息。

    EbSku selectByPrimaryKeyForDetail(Long skuId);

mapper:

  <resultMap id="detailMap" type="com.rl.ecps.model.EbSku" extends="BaseResultMap">    <association property="item" javaType="com.rl.ecps.model.EbItem">      <id column="ITEM_ID" property="itemId" jdbcType="DECIMAL"/>      <result column="ITEM_NAME" property="itemName" jdbcType="VARCHAR"/>      <result column="ITEM_NO" property="itemNo" jdbcType="VARCHAR"/>      <result column="BRAND_ID" property="brandId" jdbcType="DECIMAL"/>      <result column="CAT_ID" property="catId" jdbcType="DECIMAL"/>      <result column="TAG_IMG_ID" property="tagImgId" jdbcType="DECIMAL"/>      <result column="TAG_IMG" property="tagImg" jdbcType="DECIMAL"/>      <result column="IS_NEW" property="isNew" jdbcType="DECIMAL"/>      <result column="IS_GOOD" property="isGood" jdbcType="DECIMAL"/>      <result column="IS_HOT" property="isHot" jdbcType="DECIMAL"/>      <result column="PROMOTION" property="promotion" jdbcType="VARCHAR"/>      <result column="AUDIT_STATUS" property="auditStatus" jdbcType="DECIMAL"/>      <result column="SHOW_STATUS" property="showStatus" jdbcType="DECIMAL"/>      <result column="IMGS" property="imgs" jdbcType="VARCHAR"/>      <result column="KEYWORDS" property="keywords" jdbcType="VARCHAR"/>      <result column="PAGE_DESC" property="pageDesc" jdbcType="VARCHAR"/>      <result column="ITEM_RECYCLE" property="itemRecycle" jdbcType="DECIMAL"/>      <result column="ON_SALE_TIME" property="onSaleTime" jdbcType="TIMESTAMP"/>      <result column="CHECK_TIME" property="checkTime" jdbcType="TIMESTAMP"/>      <result column="UPDATE_TIME" property="updateTime" jdbcType="TIMESTAMP"/>      <result column="UPDATE_USER_ID" property="updateUserId" jdbcType="DECIMAL"/>      <result column="CREATE_TIME" property="createTime" jdbcType="TIMESTAMP"/>      <result column="CHECKER_USER_ID" property="checkerUserId" jdbcType="DECIMAL"/>      <result column="FULL_PATH_DEPLOY" property="fullPathDeploy" jdbcType="VARCHAR"/>      <result column="FULL_PATH_DEPLOY_OFFER" property="fullPathDeployOffer" jdbcType="VARCHAR"/>      <result column="ORIGINAL_ITEM_ID" property="originalItemId" jdbcType="DECIMAL"/>      <result column="LAST_STATUS" property="lastStatus" jdbcType="DECIMAL"/>      <result column="MERCHANT_ID" property="merchantId" jdbcType="DECIMAL"/>      <result column="ITEM_SORT" property="itemSort" jdbcType="DECIMAL"/>      <result column="SALES" property="sales" jdbcType="DECIMAL"/>      <result column="CREATE_USER_ID" property="createUserId" jdbcType="DECIMAL"/>      <result column="SIM_LEVEL" property="simLevel" jdbcType="DECIMAL"/>      <result column="GIFT_DESC" property="giftDesc" jdbcType="VARCHAR"/>      <result column="GIFT_IMG" property="giftImg" jdbcType="VARCHAR"/>      <result column="GIFT_SHOW_TYPE" property="giftShowType" jdbcType="VARCHAR"/>      <result column="IMG_SIZE1" property="imgSize1" jdbcType="VARCHAR"/>    </association>  </resultMap>  <select id="selectByPrimaryKeyForDetail" parameterType="long" resultMap="detailMap">    SELECT *    FROM EB_SKU sku, EB_ITEM item    WHERE item.ITEM_ID = sku.ITEM_ID          AND sku.SKU_ID = #{skuId}  </select>
   <association property="item" javaType="com.rl.ecps.model.EbItem">
     <id column="ITEM_ID" property="itemId" jdbcType="DECIMAL"/>
     <result column="ITEM_NAME" property="itemName" jdbcType="VARCHAR"/>
     <result column="ITEM_NO" property="itemNo" jdbcType="VARCHAR"/>
     <result column="BRAND_ID" property="brandId" jdbcType="DECIMAL"/>
     <result column="CAT_ID" property="catId" jdbcType="DECIMAL"/>
     <result column="TAG_IMG_ID" property="tagImgId" jdbcType="DECIMAL"/>
     <result column="TAG_IMG" property="tagImg" jdbcType="DECIMAL"/>
     <result column="IS_NEW" property="isNew" jdbcType="DECIMAL"/>
     <result column="IS_GOOD" property="isGood" jdbcType="DECIMAL"/>
     <result column="IS_HOT" property="isHot" jdbcType="DECIMAL"/>
     <result column="PROMOTION" property="promotion" jdbcType="VARCHAR"/>
     <result column="AUDIT_STATUS" property="auditStatus" jdbcType="DECIMAL"/>
     <result column="SHOW_STATUS" property="showStatus" jdbcType="DECIMAL"/>
     <result column="IMGS" property="imgs" jdbcType="VARCHAR"/>
     <result column="KEYWORDS" property="keywords" jdbcType="VARCHAR"/>
     <result column="PAGE_DESC" property="pageDesc" jdbcType="VARCHAR"/>
     <result column="ITEM_RECYCLE" property="itemRecycle" jdbcType="DECIMAL"/>
     <result column="ON_SALE_TIME" property="onSaleTime" jdbcType="TIMESTAMP"/>
     <result column="CHECK_TIME" property="checkTime" jdbcType="TIMESTAMP"/>
     <result column="UPDATE_TIME" property="updateTime" jdbcType="TIMESTAMP"/>
     <result column="UPDATE_USER_ID" property="updateUserId" jdbcType="DECIMAL"/>
     <result column="CREATE_TIME" property="createTime" jdbcType="TIMESTAMP"/>
     <result column="CHECKER_USER_ID" property="checkerUserId" jdbcType="DECIMAL"/>
     <result column="FULL_PATH_DEPLOY" property="fullPathDeploy" jdbcType="VARCHAR"/>
     <result column="FULL_PATH_DEPLOY_OFFER" property="fullPathDeployOffer" jdbcType="VARCHAR"/>
     <result column="ORIGINAL_ITEM_ID" property="originalItemId" jdbcType="DECIMAL"/>
     <result column="LAST_STATUS" property="lastStatus" jdbcType="DECIMAL"/>
     <result column="MERCHANT_ID" property="merchantId" jdbcType="DECIMAL"/>
     <result column="ITEM_SORT" property="itemSort" jdbcType="DECIMAL"/>
     <result column="SALES" property="sales" jdbcType="DECIMAL"/>
     <result column="CREATE_USER_ID" property="createUserId" jdbcType="DECIMAL"/>
     <result column="SIM_LEVEL" property="simLevel" jdbcType="DECIMAL"/>
     <result column="GIFT_DESC" property="giftDesc" jdbcType="VARCHAR"/>
     <result column="GIFT_IMG" property="giftImg" jdbcType="VARCHAR"/>
     <result column="GIFT_SHOW_TYPE" property="giftShowType" jdbcType="VARCHAR"/>
     <result column="IMG_SIZE1" property="imgSize1" jdbcType="VARCHAR"/>
   </association>
 </resultMap>

 <select id="selectByPrimaryKeyForDetail" parameterType="long" resultMap="detailMap">

   SELECT *
   FROM EB_SKU sku, EB_ITEM item
   WHERE item.ITEM_ID = sku.ITEM_ID
         AND sku.SKU_ID = #{skuId}
 </select>

service查询购物车数据:

    public List<EbCart> listCart(HttpServletRequest request, HttpServletResponse response) {        List<EbCart> cartList = null;        //json的配置对象        JsonConfig jc = new JsonConfig();        //设置要转换的类        jc.setRootClass(EbCart.class);        //设置不需要转换的属性        jc.setExcludes(new String[]{"sku"});        Cookie[] cookies = request.getCookies();        if (cookies != null && cookies.length > 0) {            for (Cookie c : cookies) {                String name = c.getName();                //读取购物车的key,在配置文件中保存起来了。                String cart_key = ResourcesUtils.readProp("cart_key");                if (StringUtils.equalsIgnoreCase(name, cart_key)) {                    //得到cookie里边的值【JSON格式的数组】                    String value = c.getValue();                    //将JSON数组转成是Java对象                    JSONArray ja = JSONArray.fromObject(value);                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    //根据购物车中商品的id获取详细信息                    for (EbCart cart : cartList) {                        Long skuId = cart.getSkuId();                        EbSku sku = skuService.selectByPrimaryKeyForDetail(skuId);                        cart.setSku(sku);                    }                }            }        }        return cartList;    }

       List<EbCart> cartList = null;

       //json的配置对象
       JsonConfig jc = new JsonConfig();
       //设置要转换的类
       jc.setRootClass(EbCart.class);
       //设置不需要转换的属性
       jc.setExcludes(new String[]{"sku"});

       Cookie[] cookies = request.getCookies();
       if (cookies != null && cookies.length > 0) {
           for (Cookie c : cookies) {
               String name = c.getName();

               //读取购物车的key,在配置文件中保存起来了。
               String cart_key = ResourcesUtils.readProp("cart_key");
               if (StringUtils.equalsIgnoreCase(name, cart_key)) {
                   //得到cookie里边的值【JSON格式的数组】
                   String value = c.getValue();

                   //将JSON数组转成是Java对象
                   JSONArray ja = JSONArray.fromObject(value);
                   cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);

                   //根据购物车中商品的id获取详细信息
                   for (EbCart cart : cartList) {
                       Long skuId = cart.getSkuId();
                       EbSku sku = skuService.selectByPrimaryKeyForDetail(skuId);
                       cart.setSku(sku);
                   }
               }
           }
       }
       return cartList;

   }

controller查询出商品的数量、购物车总价、返回给页面展示:

    @RequestMapping("/listCart.do")    public String listCart(HttpServletRequest request, HttpServletResponse response, Model model) {        List<EbCart> carts = cartService.listCart(request, response);        //算出购物车总价和商品数量        int itemNum = 0;        BigDecimal totalPrice = new BigDecimal(0);        for (EbCart cart : carts) {            totalPrice = totalPrice.add(cart.getSku().getSkuPrice().multiply(new BigDecimal(cart.getQuantity())));            itemNum++;        }        model.addAttribute("carts", carts);        model.addAttribute("totalPrice",totalPrice);        model.addAttribute("itemNum",itemNum);        return "shop/car";    }"/listCart.do")
   public String listCart(HttpServletRequest request, HttpServletResponse response, Model model) {

       List<EbCart> carts = cartService.listCart(request, response);

       //算出购物车总价和商品数量
       int itemNum = 0;
       BigDecimal totalPrice = new BigDecimal(0);
       for (EbCart cart : carts) {
           totalPrice = totalPrice.add(cart.getSku().getSkuPrice().multiply(new BigDecimal(cart.getQuantity())));

           itemNum++;
       }
       model.addAttribute("carts", carts);
       model.addAttribute("totalPrice",totalPrice);
       model.addAttribute("itemNum",itemNum);
       return "shop/car";
   }

页面展示效果:

640?wx_fmt=png

微调数量

我们可以在页面上微调数量的。

640?wx_fmt=png

当点击+号的时候,数量+1,当点击-号的时候,数量-1

由于我们数量的改变会导致金钱的改变,可以直接就使用页面刷新的方法来干了!因为使用Ajax的话还要去替换那些值。

对其绑定事件、交由Controller处理

function reduceNum(skuId,quantity) {    //在减少之前,校验一下库存    //得到对应数量框    var val = $("#quantity").val();    val--;    var validateResult = validateStock(skuId,val);    console.log(validateResult);    if(validateResult=="noStock"){        alert("没有库存了!");        return ;    }    $("#quantity").val(val);    //返回给后台进行页面刷新。    window.location.href = "${path}/cart/updateQuantity.do?skuId="+skuId+"&quantity="+val;}function addNum(skuId,quantity) {    //在减少之前,校验一下库存    //得到对应数量框    var val = $("#quantity").val();    val++;    var validateResult = validateStock(skuId,val);    console.log(validateResult);    if(validateResult=="noStock"){        alert("没有库存了!");        return ;    }    $("#quantity").val(val);    //返回给后台进行页面刷新。    window.location.href = "${path}/cart/updateQuantity.do?skuId="+skuId+"&quantity="+val;}

   //在减少之前,校验一下库存
   //得到对应数量框
   var val = $("#quantity").val();
   val--;

   var validateResult = validateStock(skuId,val);

   console.log(validateResult);
   if(validateResult=="noStock"){
       alert("没有库存了!");
       return ;
   }
   $("#quantity").val(val);


   //返回给后台进行页面刷新。
   window.location.href = "${path}/cart/updateQuantity.do?skuId="+skuId+"&quantity="+val;
}
function addNum(skuId,quantity) {

   //在减少之前,校验一下库存
   //得到对应数量框
   var val = $("#quantity").val();
   val++;

   var validateResult = validateStock(skuId,val);

   console.log(validateResult);
   if(validateResult=="noStock"){
       alert("没有库存了!");
       return ;
   }
   $("#quantity").val(val);


   //返回给后台进行页面刷新。
   window.location.href = "${path}/cart/updateQuantity.do?skuId="+skuId+"&quantity="+val;
}

编写更新数量的service方法:

    public void updateQuantity(HttpServletRequest request, HttpServletResponse response, Long skuId, Integer quantity) {        List<EbCart> cartList = null;        //json的配置对象        JsonConfig jc = new JsonConfig();        //设置要转换的类        jc.setRootClass(EbCart.class);        //设置不需要转换的属性        jc.setExcludes(new String[]{"sku"});        Cookie[] cookies = request.getCookies();        if (cookies != null && cookies.length > 0) {            for (Cookie c : cookies) {                String name = c.getName();                //读取购物车的key,在配置文件中保存起来了。                String cart_key = ResourcesUtils.readProp("cart_key");                if (StringUtils.equalsIgnoreCase(name, cart_key)) {                    //得到cookie里边的值【JSON格式的数组】                    String value = c.getValue();                    //将JSON数组转成是Java对象                    JSONArray ja = JSONArray.fromObject(value);                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    //根据购物车中商品的id获取详细信息                    for (EbCart cart : cartList) {                        Long cartSkuId = cart.getSkuId();                        //找到对应购物车中的商品,这里要使用longValue对数值进行比较。直接双等于是没有用的。                        if (skuId.longValue() == cartSkuId.longValue()) {                            cart.setQuantity(quantity);                        }                    }                }            }        }        //最后将我们的Java对象重新转成JSON,将Cookie更新        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();        Cookie cookie = new Cookie("cart_key", result);        cookie.setMaxAge(Integer.MAX_VALUE);        cookie.setPath("/");        response.addCookie(cookie);    }

       List<EbCart> cartList = null;

       //json的配置对象
       JsonConfig jc = new JsonConfig();
       //设置要转换的类
       jc.setRootClass(EbCart.class);
       //设置不需要转换的属性
       jc.setExcludes(new String[]{"sku"});

       Cookie[] cookies = request.getCookies();
       if (cookies != null && cookies.length > 0) {
           for (Cookie c : cookies) {
               String name = c.getName();

               //读取购物车的key,在配置文件中保存起来了。
               String cart_key = ResourcesUtils.readProp("cart_key");
               if (StringUtils.equalsIgnoreCase(name, cart_key)) {
                   //得到cookie里边的值【JSON格式的数组】
                   String value = c.getValue();

                   //将JSON数组转成是Java对象
                   JSONArray ja = JSONArray.fromObject(value);
                   cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);

                   //根据购物车中商品的id获取详细信息
                   for (EbCart cart : cartList) {
                       Long cartSkuId = cart.getSkuId();

                       //找到对应购物车中的商品,这里要使用longValue对数值进行比较。直接双等于是没有用的。
                       if (skuId.longValue() == cartSkuId.longValue()) {
                           cart.setQuantity(quantity);
                       }
                   }
               }
           }
       }
       //最后将我们的Java对象重新转成JSON,将Cookie更新
       JSONArray ja = JSONArray.fromObject(cartList, jc);
       String result = ja.toString();
       Cookie cookie = new Cookie("cart_key", result);
       cookie.setMaxAge(Integer.MAX_VALUE);
       cookie.setPath("/");
       response.addCookie(cookie);


   }

controller调用service的方法,重定向到购物车页面。那么我们的购物车页面拿到的就是最新的数据!

    @RequestMapping("/updateQuantity.do")    public String updateQuantity(Long skuId, Integer quantity,HttpServletRequest request, HttpServletResponse response) {        cartService.updateQuantity(request, response, skuId, quantity);        return "redirect:/cart/listCart.do";    }"/updateQuantity.do")
   public String updateQuantity(Long skuId, Integer quantity,HttpServletRequest request, HttpServletResponse response) {
       cartService.updateQuantity(request, response, skuId, quantity);

       return "redirect:/cart/listCart.do";
   }

结算

当我们点击结算的时候,我们要做什么事情呢??

640?wx_fmt=png

登陆了

没登陆

通过AJAX获取用户的信息,如果没有获取得到,那么说明用户还没有登陆。于是就要弹出登陆窗口

如果获取得到用户的信息了,那么就对其进行库存校验
在对购物车的商品库存校验,我们并不一定要通过前台把数据传递给后台进行处理

function trueBuy(){    //弹出框来对其登陆    $.ajax({        url:"${path}/user/getUser.do",        type:"post",        dataType:"text",        success:function(responseText){            var userObj  = $.parseJSON(responseText);            if(userObj.user != null){                var result = validCar();                if(result == "success"){                    window.location.href = "${path}/order/toSubmitOrder.do";                }else{                    alert(result);                }            }else{                tipShow("#loginAlert");            }        },        error:function(){            alert("系统错误");        }    })}

   //弹出框来对其登陆
   $.ajax({
       url:"${path}/user/getUser.do",
       type:"post",
       dataType:"text",
       success:function(responseText){
           var userObj  = $.parseJSON(responseText);
           if(userObj.user != null){
               var result = validCar();
               if(result == "success"){
                   window.location.href = "${path}/order/toSubmitOrder.do";
               }else{
                   alert(result);
               }
           }else{
               tipShow("#loginAlert");
           }
       },
       error:function(){
           alert("系统错误");
       }
   })

}

验证购物车库存是否足够

我们并不需要外界传递id和数据进来,直接使用Cookie来对其判断就行了。因为我们的数据本来就是从Cookie来的。!

function validCar(){    var result = "success";    $.ajax({        url:"${path}/cart/validCar.do",        type:"post",        dataType:"text",        async:false,        success:function(responseText){            result = responseText;        },        error:function(){            alert("系统错误");        }    })    return result;}
   var result = "success";
   $.ajax({
       url:"${path}/cart/validCar.do",
       type:"post",
       dataType:"text",
       async:false,
       success:function(responseText){
           result = responseText;
       },
       error:function(){
           alert("系统错误");
       }

   })
   return result;
}
public String validateCar(HttpServletRequest request, HttpServletResponse response) {        List<EbCart> cartList = null;        StringBuilder builder = null;        //json的配置对象        JsonConfig jc = new JsonConfig();        //设置要转换的类        jc.setRootClass(EbCart.class);        //设置不需要转换的属性        jc.setExcludes(new String[]{"sku"});        Cookie[] cookies = request.getCookies();        if (cookies != null && cookies.length > 0) {            for (Cookie c : cookies) {                String name = c.getName();                //读取购物车的key,在配置文件中保存起来了。                String cart_key = ResourcesUtils.readProp("cart_key");                if (StringUtils.equalsIgnoreCase(name, cart_key)) {                    //得到cookie里边的值【JSON格式的数组】                    String value = c.getValue();                    //将JSON数组转成是Java对象                    JSONArray ja = JSONArray.fromObject(value);                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    //遍历购物车中的数据与库存做比较                    for (EbCart cart : cartList) {                        int cartQuantity = cart.getQuantity().intValue();                        //根据购物车中商品的id获取详细信息                        Long skuId = cart.getSkuId();                        EbSku sku = skuService.selectByPrimaryKeyForDetail(skuId);                        if (cartQuantity > sku.getStockInventory().intValue()) {                            builder = new StringBuilder();                            //这个商品的库存不足                            String itemName = sku.getItem().getItemName();                            builder.append(itemName);                            List<EbSpecValue> specList = sku.getSpecList();                            for (EbSpecValue ebSpecValue : specList) {                                builder.append(ebSpecValue.getSpecValue());                            }                            builder.append("库存不足");                            return builder.toString();                        }                    }                }            }        }        return "success";    }

       List<EbCart> cartList = null;


       StringBuilder builder = null;
       //json的配置对象
       JsonConfig jc = new JsonConfig();
       //设置要转换的类
       jc.setRootClass(EbCart.class);
       //设置不需要转换的属性
       jc.setExcludes(new String[]{"sku"});

       Cookie[] cookies = request.getCookies();
       if (cookies != null && cookies.length > 0) {
           for (Cookie c : cookies) {
               String name = c.getName();

               //读取购物车的key,在配置文件中保存起来了。
               String cart_key = ResourcesUtils.readProp("cart_key");
               if (StringUtils.equalsIgnoreCase(name, cart_key)) {
                   //得到cookie里边的值【JSON格式的数组】
                   String value = c.getValue();

                   //将JSON数组转成是Java对象
                   JSONArray ja = JSONArray.fromObject(value);
                   cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);

                   //遍历购物车中的数据与库存做比较
                   for (EbCart cart : cartList) {

                       int cartQuantity = cart.getQuantity().intValue();

                       //根据购物车中商品的id获取详细信息
                       Long skuId = cart.getSkuId();
                       EbSku sku = skuService.selectByPrimaryKeyForDetail(skuId);

                       if (cartQuantity > sku.getStockInventory().intValue()) {

                           builder = new StringBuilder();

                           //这个商品的库存不足
                           String itemName = sku.getItem().getItemName();

                           builder.append(itemName);
                           List<EbSpecValue> specList = sku.getSpecList();
                           for (EbSpecValue ebSpecValue : specList) {
                               builder.append(ebSpecValue.getSpecValue());
                           }
                           builder.append("库存不足");
                           return builder.toString();
                       }
                   }
               }
           }
       }
       return "success";
   }

订单预备提交

当结算完之后会跳转到订单提交页面。首先我们来看一下订单提交页面是怎么样的:

640?wx_fmt=png

我们需要把用户的地址、商品的信息查询出来在页面上展示!

那么在跳转到确认页面的时候,我们把数据查询出来即可!

    @RequestMapping("/toSubmitOrder.do")    public String toSubmitOrder(HttpSession session, Model model, HttpServletRequest request,HttpServletResponse response) {        //查询用户的地址        TsPtlUser user = (TsPtlUser) session.getAttribute("user");        List<EbShipAddr> userAddress = addrService.findUserAddress(user.getPtlUserId());        //查询购物车清单的信息        List<EbCart> carts = cartService.listCart(request, response);        //算出购物车总价和商品数量        int itemNum = 0;        BigDecimal totalPrice = new BigDecimal(0);        for (EbCart cart : carts) {            totalPrice = totalPrice.add(cart.getSku().getSkuPrice().multiply(new BigDecimal(cart.getQuantity())));            itemNum++;        }        model.addAttribute("carts", carts);        model.addAttribute("totalPrice",totalPrice);        model.addAttribute("itemNum",itemNum);        model.addAttribute("userAddress", userAddress);        return "shop/confirmProductCase";    }"/toSubmitOrder.do")
   public String toSubmitOrder(HttpSession session, Model model, HttpServletRequest request,HttpServletResponse response) {

       //查询用户的地址
       TsPtlUser user = (TsPtlUser) session.getAttribute("user");
       List<EbShipAddr> userAddress = addrService.findUserAddress(user.getPtlUserId());

       //查询购物车清单的信息
       List<EbCart> carts = cartService.listCart(request, response);

       //算出购物车总价和商品数量
       int itemNum = 0;
       BigDecimal totalPrice = new BigDecimal(0);
       for (EbCart cart : carts) {
           totalPrice = totalPrice.add(cart.getSku().getSkuPrice().multiply(new BigDecimal(cart.getQuantity())));
           itemNum++;
       }

       model.addAttribute("carts", carts);
       model.addAttribute("totalPrice",totalPrice);
       model.addAttribute("itemNum",itemNum);
       model.addAttribute("userAddress", userAddress);
       return "shop/confirmProductCase";

   }
640?wx_fmt=png

查看订单的数据库表

DROP TABLE EB_ORDER CASCADE CONSTRAINTS;CREATE TABLE EB_ORDER  (   ORDER_ID             NUMBER(11)                      NOT NULL,   PTL_USER_ID          NUMBER(11),   "USERNAME"           VARCHAR2(100),   ORDER_NUM            VARCHAR2(80),   PAYMENT              NUMBER(1),   PAY_PLATFORM         NUMBER(2),   DELIVERY             NUMBER(1),   IS_CONFIRM           NUMBER(1),   ORDER_SUM            NUMBER(20,2),   SHIP_FEE             NUMBER(20,2),   IS_PAID              NUMBER(1),   ORDER_STATE          NUMBER(2),   PAYMENT_CASH         NUMBER(1),   DISTRI_ID            NUMBER(11),   DELIVERY_METHOD      NUMBER(1),   PAYMENT_NO           VARCHAR2(30),   ORDER_TIME           TIMESTAMP,   PAY_TIME             TIMESTAMP,   DEPOSIT_TIME         TIMESTAMP,   SUCCESS_TIME         TIMESTAMP,   UPDATE_TIME          TIMESTAMP,   SRV_TYPE             NUMBER(2),   SELF_COLLECT_SITE    VARCHAR2(200),   IS_DELETED           NUMBER(1)                      DEFAULT 0,   IS_DISPLAY           NUMBER(1),   NOTES                VARCHAR2(400),   SHIP_NAME            VARCHAR2(80)                    NOT NULL,   PROVINCE             VARCHAR2(40)                    NOT NULL,   CITY                 VARCHAR2(40)                    NOT NULL,   DISTRICT             VARCHAR2(40)                    NOT NULL,   ZIP_CODE             VARCHAR2(40),   ADDR                 VARCHAR2(400)                   NOT NULL,   PHONE                VARCHAR2(60)                    NOT NULL,   PAYABLE              NUMBER(1),   COMPANY              VARCHAR2(240),   CONTENTS             NUMBER(2),   IS_CALL              NUMBER(1)                      DEFAULT 0,   DELIVERY_NO          VARCHAR2(300),   AREA_CODE            VARCHAR2(50),   AREA_NAME            VARCHAR2(50),   IS_PRINT             NUMBER(1)                      DEFAULT 0,   CRM_CALLS_TIME       TIMESTAMP,   IS_OFFER_RELEASE     NUMBER(1)                      DEFAULT 0,   JOB_NUM              VARCHAR2(300),   CONSTRAINT PK_EB_ORDER PRIMARY KEY (ORDER_ID));COMMENT ON TABLE EB_ORDER IS'订单。包括实体商品和虚拟商品的订单';COMMENT ON COLUMN EB_ORDER.ORDER_ID IS'订单主键';COMMENT ON COLUMN EB_ORDER.PTL_USER_ID IS'前台用户主键';COMMENT ON COLUMN EB_ORDER."USERNAME" IS'冗余前台用户名称,只允许以Email地址注册,不可重复,注册后不可修改。大于0小于等于50个字符,必须包含一个并且只有一个符号@ ;第一个字符不得是@或者. ;不允许出现@.或者.@;结尾不得用户账号:只允许以Email地址注册,不可重复,注册后不可修改';COMMENT ON COLUMN EB_ORDER.ORDER_NUM IS'订单号:订单号规则:订单生成日期+6位数,递增. 订单起始编号:111024000001. 后六位数一旦满,则后六位数递增为七位数';COMMENT ON COLUMN EB_ORDER.PAYMENT IS'支付方式:1: 在线支付;2: 货到付款;3: 营业厅自取;4:邮局汇款';COMMENT ON COLUMN EB_ORDER.PAY_PLATFORM IS'支付平台:1: 工商银行; 2: 建设银行; 3: 招商银行';COMMENT ON COLUMN EB_ORDER.DELIVERY IS'送货时间:1: 只工作日送货(双休日,假日不用送); 2: 工作日、双休日、假日均可送货; 3: 只双休日、假日送货(工作日送货)';COMMENT ON COLUMN EB_ORDER.IS_CONFIRM IS'送货前电话确认:0: 否; 1: 是';COMMENT ON COLUMN EB_ORDER.ORDER_SUM IS'订单总金额:各订单项的售价之和,包括运费等。';COMMENT ON COLUMN EB_ORDER.SHIP_FEE IS'运费';COMMENT ON COLUMN EB_ORDER.IS_PAID IS'是否已支付:0: 未付款; 1: 已付款';COMMENT ON COLUMN EB_ORDER.ORDER_STATE IS'订单状态。参见类EbOrderStateConstants.java';COMMENT ON COLUMN EB_ORDER.PAYMENT_CASH IS'货到付款方式:1: 现金;2: POS刷卡; 3: 支票';COMMENT ON COLUMN EB_ORDER.DISTRI_ID IS'配送商ID';COMMENT ON COLUMN EB_ORDER.DELIVERY_METHOD IS'送货方式:1:快递;2:EMS;3:平邮';COMMENT ON COLUMN EB_ORDER.PAYMENT_NO IS'支付号';COMMENT ON COLUMN EB_ORDER.ORDER_TIME IS'下单时间';COMMENT ON COLUMN EB_ORDER.PAY_TIME IS'付款时间';COMMENT ON COLUMN EB_ORDER.DEPOSIT_TIME IS'到帐时间';COMMENT ON COLUMN EB_ORDER.SUCCESS_TIME IS'成功时间';COMMENT ON COLUMN EB_ORDER.SRV_TYPE IS'业务类型,0:无业务;1:需要写卡;2:需要办理CRM;3:需要写卡和办理CRM';COMMENT ON COLUMN EB_ORDER.SELF_COLLECT_SITE IS'商品自提点名称';COMMENT ON COLUMN EB_ORDER.IS_DELETED IS'前台用户删除订单标记。1:是;0:否';COMMENT ON COLUMN EB_ORDER.IS_DISPLAY IS'前台用户删除订单标记。1:是;0:否';COMMENT ON COLUMN EB_ORDER.NOTES IS'备注';COMMENT ON COLUMN EB_ORDER.SHIP_NAME IS'收货人姓名';COMMENT ON COLUMN EB_ORDER.PROVINCE IS'省份';COMMENT ON COLUMN EB_ORDER.CITY IS'城市';COMMENT ON COLUMN EB_ORDER.DISTRICT IS'地区';COMMENT ON COLUMN EB_ORDER.ZIP_CODE IS'邮编';COMMENT ON COLUMN EB_ORDER.ADDR IS'街道地址';COMMENT ON COLUMN EB_ORDER.PHONE IS'联系电话';COMMENT ON COLUMN EB_ORDER.PAYABLE IS'发票抬头:1: 个人;2: 单位';COMMENT ON COLUMN EB_ORDER.COMPANY IS'单位名称';COMMENT ON COLUMN EB_ORDER.CONTENTS IS'发票内容:1: 明细;2: 办公用品';COMMENT ON COLUMN EB_ORDER.IS_CALL IS'是否外呼过。0:未外呼;1:已外呼';COMMENT ON COLUMN EB_ORDER.DELIVERY_NO IS'物流编号。';COMMENT ON COLUMN EB_ORDER.AREA_CODE IS'市区代码(冗余自EB_CITY_AREA表)';COMMENT ON COLUMN EB_ORDER.AREA_NAME IS'市区名称(冗余自EB_CITY_AREA表)';COMMENT ON COLUMN EB_ORDER.IS_PRINT IS'是否需要打印发票。0-不需要打印;1-需要打印;';COMMENT ON COLUMN EB_ORDER.CRM_CALLS_TIME IS'crm办理成功或失败的时间';COMMENT ON COLUMN EB_ORDER.IS_OFFER_RELEASE IS'是否营销案解约。0-否;1-是;';COMMENT ON COLUMN EB_ORDER.JOB_NUM IS'工单号,由crm接口返回';TABLE EB_ORDER CASCADE CONSTRAINTS;

CREATE TABLE EB_ORDER  (
  ORDER_ID             NUMBER(11)                      NOT NULL,
  PTL_USER_ID          NUMBER(11),
  "USERNAME"           VARCHAR2(100),
  ORDER_NUM            VARCHAR2(80),
  PAYMENT              NUMBER(1),
  PAY_PLATFORM         NUMBER(2),
  DELIVERY             NUMBER(1),
  IS_CONFIRM           NUMBER(1),
  ORDER_SUM            NUMBER(20,2),
  SHIP_FEE             NUMBER(20,2),
  IS_PAID              NUMBER(1),
  ORDER_STATE          NUMBER(2),
  PAYMENT_CASH         NUMBER(1),
  DISTRI_ID            NUMBER(11),
  DELIVERY_METHOD      NUMBER(1),
  PAYMENT_NO           VARCHAR2(30),
  ORDER_TIME           TIMESTAMP,
  PAY_TIME             TIMESTAMP,
  DEPOSIT_TIME         TIMESTAMP,
  SUCCESS_TIME         TIMESTAMP,
  UPDATE_TIME          TIMESTAMP,
  SRV_TYPE             NUMBER(2),
  SELF_COLLECT_SITE    VARCHAR2(200),
  IS_DELETED           NUMBER(1)                      DEFAULT 0,
  IS_DISPLAY           NUMBER(1),
  NOTES                VARCHAR2(400),
  SHIP_NAME            VARCHAR2(80)                    NOT NULL,
  PROVINCE             VARCHAR2(40)                    NOT NULL,
  CITY                 VARCHAR2(40)                    NOT NULL,
  DISTRICT             VARCHAR2(40)                    NOT NULL,
  ZIP_CODE             VARCHAR2(40),
  ADDR                 VARCHAR2(400)                   NOT NULL,
  PHONE                VARCHAR2(60)                    NOT NULL,
  PAYABLE              NUMBER(1),
  COMPANY              VARCHAR2(240),
  CONTENTS             NUMBER(2),
  IS_CALL              NUMBER(1)                      DEFAULT 0,
  DELIVERY_NO          VARCHAR2(300),
  AREA_CODE            VARCHAR2(50),
  AREA_NAME            VARCHAR2(50),
  IS_PRINT             NUMBER(1)                      DEFAULT 0,
  CRM_CALLS_TIME       TIMESTAMP,
  IS_OFFER_RELEASE     NUMBER(1)                      DEFAULT 0,
  JOB_NUM              VARCHAR2(300),
  CONSTRAINT PK_EB_ORDER PRIMARY KEY (ORDER_ID)
);

COMMENT ON TABLE EB_ORDER IS
'订单。包括实体商品和虚拟商品的订单';

COMMENT ON COLUMN EB_ORDER.ORDER_ID IS
'订单主键';

COMMENT ON COLUMN EB_ORDER.PTL_USER_ID IS
'前台用户主键';

COMMENT ON COLUMN EB_ORDER."USERNAME" IS
'冗余前台用户名称,只允许以Email地址注册,不可重复,注册后不可修改。大于0小于等于50个字符,必须包含一个并且只有一个符号@ ;第一个字符不得是@或者. ;不允许出现@.或者.@;结尾不得用户账号:只允许以Email地址注册,不可重复,注册后不可修改';

COMMENT ON COLUMN EB_ORDER.ORDER_NUM IS
'订单号:订单号规则:订单生成日期+6位数,递增. 订单起始编号:111024000001. 后六位数一旦满,则后六位数递增为七位数';

COMMENT ON COLUMN EB_ORDER.PAYMENT IS
'支付方式:1: 在线支付;2: 货到付款;3: 营业厅自取;4:邮局汇款';

COMMENT ON COLUMN EB_ORDER.PAY_PLATFORM IS
'支付平台:1: 工商银行; 2: 建设银行; 3: 招商银行';

COMMENT ON COLUMN EB_ORDER.DELIVERY IS
'送货时间:1: 只工作日送货(双休日,假日不用送); 2: 工作日、双休日、假日均可送货; 3: 只双休日、假日送货(工作日送货)';

COMMENT ON COLUMN EB_ORDER.IS_CONFIRM IS
'送货前电话确认:0: 否; 1: 是';

COMMENT ON COLUMN EB_ORDER.ORDER_SUM IS
'订单总金额:各订单项的售价之和,包括运费等。';

COMMENT ON COLUMN EB_ORDER.SHIP_FEE IS
'运费';

COMMENT ON COLUMN EB_ORDER.IS_PAID IS
'是否已支付:0: 未付款; 1: 已付款';

COMMENT ON COLUMN EB_ORDER.ORDER_STATE IS
'订单状态。参见类EbOrderStateConstants.java';

COMMENT ON COLUMN EB_ORDER.PAYMENT_CASH IS
'货到付款方式:1: 现金;2: POS刷卡; 3: 支票';

COMMENT ON COLUMN EB_ORDER.DISTRI_ID IS
'配送商ID';

COMMENT ON COLUMN EB_ORDER.DELIVERY_METHOD IS
'送货方式:1:快递;2:EMS;3:平邮';

COMMENT ON COLUMN EB_ORDER.PAYMENT_NO IS
'支付号';

COMMENT ON COLUMN EB_ORDER.ORDER_TIME IS
'下单时间';

COMMENT ON COLUMN EB_ORDER.PAY_TIME IS
'付款时间';

COMMENT ON COLUMN EB_ORDER.DEPOSIT_TIME IS
'到帐时间';

COMMENT ON COLUMN EB_ORDER.SUCCESS_TIME IS
'成功时间';

COMMENT ON COLUMN EB_ORDER.SRV_TYPE IS
'业务类型,0:无业务;1:需要写卡;2:需要办理CRM;3:需要写卡和办理CRM';

COMMENT ON COLUMN EB_ORDER.SELF_COLLECT_SITE IS
'商品自提点名称';

COMMENT ON COLUMN EB_ORDER.IS_DELETED IS
'前台用户删除订单标记。1:是;0:否';

COMMENT ON COLUMN EB_ORDER.IS_DISPLAY IS
'前台用户删除订单标记。1:是;0:否';

COMMENT ON COLUMN EB_ORDER.NOTES IS
'备注';

COMMENT ON COLUMN EB_ORDER.SHIP_NAME IS
'收货人姓名';

COMMENT ON COLUMN EB_ORDER.PROVINCE IS
'省份';

COMMENT ON COLUMN EB_ORDER.CITY IS
'城市';

COMMENT ON COLUMN EB_ORDER.DISTRICT IS
'地区';

COMMENT ON COLUMN EB_ORDER.ZIP_CODE IS
'邮编';

COMMENT ON COLUMN EB_ORDER.ADDR IS
'街道地址';

COMMENT ON COLUMN EB_ORDER.PHONE IS
'联系电话';

COMMENT ON COLUMN EB_ORDER.PAYABLE IS
'发票抬头:1: 个人;2: 单位';

COMMENT ON COLUMN EB_ORDER.COMPANY IS
'单位名称';

COMMENT ON COLUMN EB_ORDER.CONTENTS IS
'发票内容:1: 明细;2: 办公用品';

COMMENT ON COLUMN EB_ORDER.IS_CALL IS
'是否外呼过。0:未外呼;1:已外呼';

COMMENT ON COLUMN EB_ORDER.DELIVERY_NO IS
'物流编号。';

COMMENT ON COLUMN EB_ORDER.AREA_CODE IS
'市区代码(冗余自EB_CITY_AREA表)';

COMMENT ON COLUMN EB_ORDER.AREA_NAME IS
'市区名称(冗余自EB_CITY_AREA表)';

COMMENT ON COLUMN EB_ORDER.IS_PRINT IS
'是否需要打印发票。0-不需要打印;1-需要打印;';

COMMENT ON COLUMN EB_ORDER.CRM_CALLS_TIME IS
'crm办理成功或失败的时间';

COMMENT ON COLUMN EB_ORDER.IS_OFFER_RELEASE IS
'是否营销案解约。0-否;1-是;';

COMMENT ON COLUMN EB_ORDER.JOB_NUM IS
'工单号,由crm接口返回';

订单明细表:

DROP TABLE EB_ORDER_DETAIL CASCADE CONSTRAINTS;CREATE TABLE EB_ORDER_DETAIL  (   ORDER_DETAIL_ID      NUMBER(11)                      NOT NULL,   ORDER_ID             NUMBER(11),   ITEM_ID              NUMBER(11),   ITEM_NAME            VARCHAR2(400),   ITEM_NO              VARCHAR2(120),   SKU_ID               NUMBER(11),   SKU                  VARCHAR2(80),   SKU_IMG              VARCHAR2(80),   SKU_NAME             VARCHAR2(500),   SKU_CAT_TYPE         NUMBER(5),   SKU_SPEC             VARCHAR2(1000),   MARKET_PRICE         NUMBER(20,2),   SKU_DISCOUNT         NUMBER(20,2),   SKU_PRICE            NUMBER(20,2),   OFFER_GROUP_ID       NUMBER(11),   OFFER_GROUP_NAME     VARCHAR2(200),   OFFER_TYPE           NUMBER(2),   SHORT_NAME           VARCHAR2(80),   OFFER_ID             NUMBER(11),   OFFER_NAME           VARCHAR2(800),   OFFER_NO             VARCHAR2(120),   SHORT_NAME2          VARCHAR2(50),   OFFER_TERM           NUMBER(2),   COMMIT_MONTHLY       NUMBER(20,2),   PREPAID              NUMBER(20,2),   PERIOD               NUMBER(2),   REFUND_MONTHLY       NUMBER(20,2),   REFUND_1ST_MONTH     NUMBER(20,2),   REFUND_LAST_MONTH    NUMBER(20,2),   ORDER_DETAIL_TYPE    NUMBER(2),   MERCHANT_ID          NUMBER(11),   QUANTITY             NUMBER(5),   PRICE                NUMBER(20,2),   SERIESCODE           VARCHAR2(3000),   OFFER_GROUP_NO       VARCHAR2(300),   PROMO_TYPE           NUMBER(4),   COND_ID              NUMBER(8),   CONSTRAINT PK_EB_ORDER_DETAIL PRIMARY KEY (ORDER_DETAIL_ID));COMMENT ON TABLE EB_ORDER_DETAIL IS'3-10是商品的冗余数据11-26是营销案的冗余数据营销案的时候,根据SKU存多条,每条SKU的营销案信息一致备注:当订单中包含offer,offer里包含sku的时候,在保存offer内的sku信息时,会冗余offer信息到该条记录中,便于订单的查询。';COMMENT ON COLUMN EB_ORDER_DETAIL.ORDER_ID IS'订单主键';COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_ID IS'商品主键';COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_NAME IS'商品名称';COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_NO IS'商品编号:自动生成,不可重复,添加完成后不可修改。编号规则:一级目录数字“1”+7位数递增,裸机起始编号   10000001。7位数递增满时自动升为8位数。编号根据EB_ITEM.CAT_TYPE获得,如实体商品为1(EB_ITEM.CAT_TYPE=1)(删除--实体起始编号:   10000001 虚拟起始编号:   20000001。--注意:商品是否为手机或号卡,用其所属的类目来区分,CAT_ID为1的为手机,CAT_ID为2的为号卡。)';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_ID IS'最小销售单元主键';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU IS'货号';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_IMG IS'图片存储位置,1~5';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_NAME IS'SKU名称';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_CAT_TYPE IS'冗余EB_CAT里边的CAT_TYPE字段值,用以标示:0、不分类;1、实体;2、号卡;3、虚拟商品';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_SPEC IS'规格1:规格2:规格3。。。规格N,格式参见订单需求文档';COMMENT ON COLUMN EB_ORDER_DETAIL.MARKET_PRICE IS'(以分币为单位)市场价:所有价格相关的字段限定为9位有效数字以内(即1234567.89,相当于千万元以内),给前端用户显示时,小数永远保持2位,即整数价格后面显示为.00;若小数价格多于2位小数,则直接截掉2位小数右边的小数(不用四舍五入);若小数为1位,如1元9角,则显示1.90';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_DISCOUNT IS'优惠额';COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_PRICE IS'sku销售价';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_GROUP_NAME IS'活动名称';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_TYPE IS'活动类型:1:购物送礼;2:优惠购机;3:购机返话费';COMMENT ON COLUMN EB_ORDER_DETAIL.SHORT_NAME IS'活动简称。用字母代表,如A1中的A';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_ID IS'促销活动主键';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_NAME IS'活动档次简介';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_NO IS'活动档次编号:起始编号: 50000001';COMMENT ON COLUMN EB_ORDER_DETAIL.SHORT_NAME2 IS'活动档次数字编号,如A1中的1';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_TERM IS'业务协议期:1:6个月;2:12个月;3:18个月;4:24个月';COMMENT ON COLUMN EB_ORDER_DETAIL.COMMIT_MONTHLY IS'(以分币为单位)月承诺消费金额。大于0小于10000的整数';COMMENT ON COLUMN EB_ORDER_DETAIL.PREPAID IS'(以分币为单位)预存话费金额。大于0小于10000的整数';COMMENT ON COLUMN EB_ORDER_DETAIL.PERIOD IS'返还期。1:立即到帐;2:6个月;3:12个月;4:18个月;5:24个月';COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_MONTHLY IS'(以分币为单位)月返还金额。大于0小于10000的整数';COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_1ST_MONTH IS'(以分币为单位)首月返还金额。大于0小于10000的整数';COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_LAST_MONTH IS'(以分币为单位)末月返还金额。大于0小于10000的整数';COMMENT ON COLUMN EB_ORDER_DETAIL.ORDER_DETAIL_TYPE IS'1、SKU;2、OFFER;3、营销案的SKU';COMMENT ON COLUMN EB_ORDER_DETAIL.QUANTITY IS'数量';COMMENT ON COLUMN EB_ORDER_DETAIL.PRICE IS'(以分币为单位)成交价格(即实际购买价格)。若是营销活动,则按公式sku_price+prepaid-sku_discount计算';COMMENT ON COLUMN EB_ORDER_DETAIL.SERIESCODE IS'串号,逗号分割';COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_GROUP_NO IS'活动编号,用来存储从crm过来的编号';COMMENT ON COLUMN EB_ORDER_DETAIL.PROMO_TYPE IS'活动类型,用来存储从crm返回的活动类型,在营销案开通接口中使用';COMMENT ON COLUMN EB_ORDER_DETAIL.COND_ID IS'活动档次编码,从crm传过来的';TABLE EB_ORDER_DETAIL CASCADE CONSTRAINTS;

CREATE TABLE EB_ORDER_DETAIL  (
  ORDER_DETAIL_ID      NUMBER(11)                      NOT NULL,
  ORDER_ID             NUMBER(11),
  ITEM_ID              NUMBER(11),
  ITEM_NAME            VARCHAR2(400),
  ITEM_NO              VARCHAR2(120),
  SKU_ID               NUMBER(11),
  SKU                  VARCHAR2(80),
  SKU_IMG              VARCHAR2(80),
  SKU_NAME             VARCHAR2(500),
  SKU_CAT_TYPE         NUMBER(5),
  SKU_SPEC             VARCHAR2(1000),
  MARKET_PRICE         NUMBER(20,2),
  SKU_DISCOUNT         NUMBER(20,2),
  SKU_PRICE            NUMBER(20,2),
  OFFER_GROUP_ID       NUMBER(11),
  OFFER_GROUP_NAME     VARCHAR2(200),
  OFFER_TYPE           NUMBER(2),
  SHORT_NAME           VARCHAR2(80),
  OFFER_ID             NUMBER(11),
  OFFER_NAME           VARCHAR2(800),
  OFFER_NO             VARCHAR2(120),
  SHORT_NAME2          VARCHAR2(50),
  OFFER_TERM           NUMBER(2),
  COMMIT_MONTHLY       NUMBER(20,2),
  PREPAID              NUMBER(20,2),
  PERIOD               NUMBER(2),
  REFUND_MONTHLY       NUMBER(20,2),
  REFUND_1ST_MONTH     NUMBER(20,2),
  REFUND_LAST_MONTH    NUMBER(20,2),
  ORDER_DETAIL_TYPE    NUMBER(2),
  MERCHANT_ID          NUMBER(11),
  QUANTITY             NUMBER(5),
  PRICE                NUMBER(20,2),
  SERIESCODE           VARCHAR2(3000),
  OFFER_GROUP_NO       VARCHAR2(300),
  PROMO_TYPE           NUMBER(4),
  COND_ID              NUMBER(8),
  CONSTRAINT PK_EB_ORDER_DETAIL PRIMARY KEY (ORDER_DETAIL_ID)
);

COMMENT ON TABLE EB_ORDER_DETAIL IS
'3-10是商品的冗余数据
11-26是营销案的冗余数据

营销案的时候,根据SKU存多条,每条SKU的营销案信息一致


备注:
当订单中包含offer,offer里包含sku的时候,
在保存offer内的sku信息时,会冗余offer信息到该条记录中,便于订单的查询。'
;

COMMENT ON COLUMN EB_ORDER_DETAIL.ORDER_ID IS
'订单主键';

COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_ID IS
'商品主键';

COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_NAME IS
'商品名称';

COMMENT ON COLUMN EB_ORDER_DETAIL.ITEM_NO IS
'商品编号:自动生成,不可重复,添加完成后不可修改。编号规则:一级目录数字“1”+7位数递增,裸机起始编号   10000001。7位数递增满时自动升为8位数。
编号根据EB_ITEM.CAT_TYPE获得,如实体商品为1(EB_ITEM.CAT_TYPE=1)


(删除
--实体起始编号:   10000001 虚拟起始编号:   20000001。
--注意:商品是否为手机或号卡,用其所属的类目来区分,CAT_ID为1的为手机,CAT_ID为2的为号卡。)
'
;

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_ID IS
'最小销售单元主键';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU IS
'货号';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_IMG IS
'图片存储位置,1~5';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_NAME IS
'SKU名称';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_CAT_TYPE IS
'冗余EB_CAT里边的CAT_TYPE字段值,用以标示:0、不分类;1、实体;2、号卡;3、虚拟商品';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_SPEC IS
'规格1:规格2:规格3。。。规格N,格式参见订单需求文档';

COMMENT ON COLUMN EB_ORDER_DETAIL.MARKET_PRICE IS
'(以分币为单位)市场价:所有价格相关的字段限定为9位有效数字以内(即1234567.89,相当于千万元以内),给前端用户显示时,小数永远保持2位,即整数价格后面显示为.00;若小数价格多于2位小数,则直接截掉2位小数右边的小数(不用四舍五入);若小数为1位,如1元9角,则显示1.90';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_DISCOUNT IS
'优惠额';

COMMENT ON COLUMN EB_ORDER_DETAIL.SKU_PRICE IS
'sku销售价';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_GROUP_NAME IS
'活动名称';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_TYPE IS
'活动类型:1:购物送礼;2:优惠购机;3:购机返话费';

COMMENT ON COLUMN EB_ORDER_DETAIL.SHORT_NAME IS
'活动简称。用字母代表,如A1中的A';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_ID IS
'促销活动主键';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_NAME IS
'活动档次简介';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_NO IS
'活动档次编号:起始编号: 50000001';

COMMENT ON COLUMN EB_ORDER_DETAIL.SHORT_NAME2 IS
'活动档次数字编号,如A1中的1';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_TERM IS
'业务协议期:1:6个月;2:12个月;3:18个月;4:24个月';

COMMENT ON COLUMN EB_ORDER_DETAIL.COMMIT_MONTHLY IS
'(以分币为单位)月承诺消费金额。大于0小于10000的整数';

COMMENT ON COLUMN EB_ORDER_DETAIL.PREPAID IS
'(以分币为单位)预存话费金额。大于0小于10000的整数';

COMMENT ON COLUMN EB_ORDER_DETAIL.PERIOD IS
'返还期。1:立即到帐;2:6个月;3:12个月;4:18个月;5:24个月';

COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_MONTHLY IS
'(以分币为单位)月返还金额。大于0小于10000的整数';

COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_1ST_MONTH IS
'(以分币为单位)首月返还金额。大于0小于10000的整数';

COMMENT ON COLUMN EB_ORDER_DETAIL.REFUND_LAST_MONTH IS
'(以分币为单位)末月返还金额。大于0小于10000的整数';

COMMENT ON COLUMN EB_ORDER_DETAIL.ORDER_DETAIL_TYPE IS
'1、SKU;2、OFFER;3、营销案的SKU';

COMMENT ON COLUMN EB_ORDER_DETAIL.QUANTITY IS
'数量';

COMMENT ON COLUMN EB_ORDER_DETAIL.PRICE IS
'(以分币为单位)成交价格(即实际购买价格)。若是营销活动,则按公式sku_price+prepaid-sku_discount计算';

COMMENT ON COLUMN EB_ORDER_DETAIL.SERIESCODE IS
'串号,逗号分割';

COMMENT ON COLUMN EB_ORDER_DETAIL.OFFER_GROUP_NO IS
'活动编号,用来存储从crm过来的编号';

COMMENT ON COLUMN EB_ORDER_DETAIL.PROMO_TYPE IS
'活动类型,用来存储从crm返回的活动类型,在营销案开通接口中使用';

COMMENT ON COLUMN EB_ORDER_DETAIL.COND_ID IS
'活动档次编码,从crm传过来的';

我们对这两张表逆向工程!

640?wx_fmt=png

Service流程步骤

用户提交了订单的话,那么我们要做什么事呢???

库存的数据减少这里涉及到了并发的问题:

于是我们就需要对这个操作“上锁”

锁有两种:

悲观锁:

640?wx_fmt=png

乐观锁:

640?wx_fmt=png

但其实我们现在这个操作并不需要用到悲观锁和乐观锁。因为我们查询出来的数据不用做另一番操作

  <update id="updateStock" parameterType="map">      update eb_sku t  set t.stock_inventory = t.stock_inventory - #{quantity} where sku_id = #{skuId}       and t.stock_inventory > =#{quantity}  </update>
     update eb_sku t  set t.stock_inventory = t.stock_inventory - #{quantity} where sku_id = #{skuId}
     and t.stock_inventory > =#{quantity}
 </update>

service编写:

   public void addOrder(EbOrder ebOrder, List<EbOrderDetail> details, HttpServletRequest request, HttpServletResponse response) {        orderDao.saveOrder(ebOrder);        Map<String,Object> map = new HashMap<String,Object>();        for(EbOrderDetail detail : details){            detail.setOrderId(ebOrder.getOrderId());            detailDao.saveOrderDetail(detail);            /*EbSku sku = skuDao.getSkuById(detail.getSkuId());            sku.setStockInventory(sku.getStockInventory() - detail.getQuantity());            skuDao.update(sku);*/            map.put("skuId", detail.getSkuId());            map.put("quantity", detail.getQuantity());            int flag = skuDao.updateStock(map);            if(flag == 0){                throw new EbStockException("库存不足");            }        }        cartService.clearCar(request, response);    }

       orderDao.saveOrder(ebOrder);

       Map<String,Object> map = new HashMap<String,Object>();
       for(EbOrderDetail detail : details){
           detail.setOrderId(ebOrder.getOrderId());
           detailDao.saveOrderDetail(detail);

           /*EbSku sku = skuDao.getSkuById(detail.getSkuId());

           sku.setStockInventory(sku.getStockInventory() - detail.getQuantity());
           skuDao.update(sku);*/

           map.put("skuId", detail.getSkuId());
           map.put("quantity", detail.getQuantity());
           int flag = skuDao.updateStock(map);
           if(flag == 0){
               throw new EbStockException("库存不足");
           }

       }
       cartService.clearCar(request, response);
   }

走一遍流程:

640?wx_fmt=gif

总结


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值