天天看點

電商項目總結

最近一段時間剛剛學習了一些新的知識,就想拿個項目練練手,然後就在網上找了一個教育訓練的電商項目練習了一下,做了之後學到了很多,學到了項目的很多流程,在這裡總結一下。

一、項目介紹:

   網上商城項目,用于建立網上終端、營銷案線上銷售及相關輔助功能,背景包含商品管理、訂單管理、類目管理、客戶管理、合作商管理、客服管理、支付平台、内容管理等,很大程度上分擔了人工的壓力,前台包括個人中心,購物車,商城首頁,頻道頁,商品詳情頁,送出訂單頁,支付頁面等頁面構成,對提高客戶服務效率和客戶滿意度能夠起到較好的作用。

二、項目所用技術:

1、Jsp,freemarker,jQuery,css+div,jstl标簽,fckEditor, struts-menu

2、Springmvc,spring,mybatis

3、Webservice架構cxf

4、Jersey搭建圖檔伺服器

5、Maven,svn,hudson

6、Oracle

三、開發環境:

1、Eclipse4.3

2、Tomcat7.0

3、Jdk1.7

4、Oracle10g

5、Maven3.1.5

6、Svn

7、hudson

四、系統架構:

這裡使用maven進行依賴管理

電商項目總結

接下來,我把這裡面比較核心的子產品分析一下,進行總結,裡面包括:

背景:

1、品牌管理:包括簡單的增删改查

2、商品管理:裡面有一個比較核心的商品添加到前台的功能,主要的業務包括操作商品表、商品大字段表、商品屬性表、商品的特殊屬性表

3、訂單管理:訂單的增删改查,商品的上架,商品的釋出(通過webService)。

前台:

1、商品的首頁展示:通過多表查詢進行分頁查詢顯示

2、商品的單品頁展示:利用freemaker技術對頁面進行靜态化處理,在背景進行靜态化的釋出,這樣的好處是查詢的時候隻需查詢一次資料庫,靜态化之後不需要再查詢,大大的提高了系統的效率。

3、購物車:使用cookie技術,好處:使用者不需要登入即可操作購物車。

4、訂單流程:這裡使用工作流activiti,這裡對工作流的使用進行了加強。

五、核心子產品的總結:

6.1、商品的添加:

操作商品表、商品大字段表、商品屬性表、商品的特殊屬性表

aaction層:

@RequestMapping("/addItem.do")
    public String addItem(EbItem item, EbItemClob itemClob, HttpServletRequest request,Integer divNum){
        item.setItemNo(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
        List<EbFeature> commList = featureService.selectCommFeature();
        List<EbParaValue> paraList = new ArrayList<EbParaValue>();        for(EbFeature feature: commList){            //獲得屬性的id也就是普通屬性在頁面上的name
            Long featureId = feature.getFeatureId();            if(feature.getInputType() == 3){                String [] paraArr = request.getParameterValues(featureId+"");                if(paraArr != null && paraArr.length > 0){                    String paraVals = "";                    for(String val : paraArr){
                        paraVals = paraVals + val + ",";
                    }
                    paraVals = paraVals.substring(0, paraVals.length() - 1);
                    EbParaValue pv = new EbParaValue();
                    pv.setFeatureId(featureId);
                    pv.setParaValue(paraVals);
                    paraList.add(pv);
                }

            }else{                String paraVal = request.getParameter(featureId+"");                if(StringUtils.isNotBlank(paraVal)){
                    EbParaValue pv = new EbParaValue();
                    pv.setFeatureId(featureId);
                    pv.setParaValue(paraVal);
                    paraList.add(pv);
                }
            }
        }
        List<EbSku> skuList = new ArrayList<EbSku>();
        List<EbFeature> specList = featureService.selectSpecFeature();        //skuType1   showStatus1   sort1     skuPrice1  marketPrice1  stockInventory1  skuUpperLimit1  sku1  location1
        //周遊div數量
        for(int i = 1; i <= divNum; i++){            //獲得商城價和庫存,他們是必填的字段
            String skuPrice = request.getParameter("skuPrice"+i);            String stock = request.getParameter("stockInventory"+i);            //如果上面的必填字段不是空說明資料有效
            if(StringUtils.isNotBlank(skuPrice) && StringUtils.isNotBlank(stock)){                String skuType = request.getParameter("skuType"+i);                String showStatus = request.getParameter("showStatus"+i);                String sort = request.getParameter("sort"+i);                String marketPrice = request.getParameter("marketPrice"+i);                String skuUpperLimit = request.getParameter("skuUpperLimit"+i);                String sku = request.getParameter("sku"+i);                String location = request.getParameter("location"+i);                //建立最小銷售單元的對象,并且指派
                EbSku skuObj = new EbSku();
                skuObj.setSkuPrice(new BigDecimal(skuPrice));
                skuObj.setStockInventory(new Integer(stock));                if(StringUtils.isNotBlank(skuType) && !StringUtils.equals(skuType, "")){
                    skuObj.setSkuType(new Short(skuType));
                }                if(StringUtils.isNotBlank(showStatus) && !StringUtils.equals(showStatus, "")){
                    skuObj.setShowStatus(new Short(showStatus));
                }                if(StringUtils.isNotBlank(sort) && !StringUtils.equals(sort, "")){
                    skuObj.setSkuSort(new Integer(sort));
                }                if(StringUtils.isNotBlank(marketPrice) && !StringUtils.equals(marketPrice, "")){
                    skuObj.setMarketPrice(new BigDecimal(marketPrice));
                }                if(StringUtils.isNotBlank(skuUpperLimit) && !StringUtils.equals(skuUpperLimit, "")){
                    skuObj.setSkuUpperLimit(new Integer(skuUpperLimit));
                }
                skuObj.setSku(sku);
                skuObj.setLocation(location);

                List<EbSpecValue> specValList = new ArrayList<EbSpecValue>();                //獲得每個最小銷售單元所擁有的規格屬性值,
                //周遊規格屬性
                for(EbFeature feature : specList){
                    Long featureId = feature.getFeatureId();                    //獲得所選規格屬性的值
                    String specVal = request.getParameter(featureId+"specradio"+i);                    //建立規格對象
                    EbSpecValue spec = new EbSpecValue();
                    spec.setFeatureId(featureId);
                    spec.setSpecValue(specVal);
                    specValList.add(spec);
                }
                skuObj.setSpecList(specValList);
                skuList.add(skuObj);
            }

        }
        itemService.saveItem(item, itemClob, paraList, skuList);        return "redirect:listItem.do?showStatus=1&auditStatus=1";
    }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091921234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192      

service層:

public void saveItem(EbItem item, EbItemClob itemClob,
            List<EbParaValue> paraList, List<EbSku> skuList) {
        itemDao.saveItem(item);
        paraValueDao.saveParaValue(paraList, item.getItemId());
        itemClobDao.saveItemClob(itemClob, item.getItemId());
        skuDao.saveSku(skuList, item.getItemId());

    }1234567812345678      

6.2、商品分頁sql

<!-- 

    分頁查詢的結果集

   -->

  <select id="selectItemByCondition" parameterType="com.rl.ecps.model.QueryCondition" resultMap="BaseResultMap">

  select *

  from (select rownum rw, a.*

          from (

          select * from eb_item t          <where>

            <if test="brandId != null">

                t.brand_id = #{brandId}            </if>

            <if test="auditStatus != null">

                and t.audit_status = #{auditStatus}            </if>

            <if test="showStatus != null">

                and t.show_status = #{showStatus}            </if>

            <if test="itemName != null">

                and t.item_name like '%${itemName}%'            </if>

          </where>

          order by t.item_id desc          <![CDATA[

          ) a

         where rownum < #{endNum}) b

 where b.rw > #{startNum}

 ]]>

  </select>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575812345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758      

6.3、商品的首頁查詢篩選

6.3.1、sql

<!-- 

    map.put("minPrice", 4000);

    map.put("maxPrice", 4999);

    map.put("brandId", 1003);

    map.put("paraList", String[] paraList)

   -->

  <select id="listItem" parameterType="map" resultMap="listItemRM">

    select min(es.sku_price) sku_price, ei.*

  from eb_item ei, eb_sku es

  <where>

    ei.item_id = es.item_id

    <if test="minPrice != null">        and es.sku_price between #{minPrice} and #{maxPrice}

    </if>

    <if test="brandId != null">         and ei.brand_id = #{brandId}

    </if>

    <if test="paraList != null">

        <foreach collection="paraList" item="paraValue">            and exists (select *

              from eb_para_value t

             where ei.item_id = t.item_id               and t.para_value = #{paraValue})

        </foreach>

    </if>

  </where>

 group by ei.ITEM_ID,

          ei.ITEM_NAME,

          ei.ITEM_NO,

          ei.BRAND_ID,

          ei.CAT_ID,

          ei.TAG_IMG_ID,

          ei.TAG_IMG,

          ei.IS_NEW,

          ei.IS_GOOD,

          ei.IS_HOT,

          ei.PROMOTION,

          ei.AUDIT_STATUS,

          ei.SHOW_STATUS,

          ei.IMGS,

          ei.KEYWORDS,

          ei.PAGE_DESC,

          ei.ITEM_RECYCLE,

          ei.ON_SALE_TIME,

          ei.CHECK_TIME,

          ei.UPDATE_TIME,

          ei.UPDATE_USER_ID,

          ei.CREATE_TIME,

          ei.CHECKER_USER_ID,

          ei.FULL_PATH_DEPLOY,

         ei.FULL_PATH_DEPLOY_OFFER,

          ei.ORIGINAL_ITEM_ID,

          ei.LAST_STATUS,

          ei.MERCHANT_ID,

          ei.ITEM_SORT,

          ei.SALES,

          ei.CREATE_USER_ID,

          ei.SIM_LEVEL,

          ei.GIFT_DESC,

          ei.GIFT_IMG,

          ei.GIFT_SHOW_TYPE,

          ei.IMG_SIZE1

          order by ei.item_id desc

  </select>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127      

7、商品頁靜态化

主要将jsp改為靜态的html頁面,利用freemaker文法。

8、購物車

購物車利用cookie存儲在浏覽器,在背景拿到cookie進行資料操作。

購物車子產品:

接口:

/**
     * 查詢購物車所有商品
     * @param request 
     * @param response
     * @return
     */
    public List<EbCart> listCart(HttpServletRequest request, HttpServletResponse response);    /**
     * 添加購物車
     * @param request
     * @param response
     * @param skuId 最小銷售單元id
     * @param quantity 商品數量
     */
    public void addCart(HttpServletRequest request, HttpServletResponse response, Long skuId, Integer quantity);    /**
     * 根據商品id商品數量加一
     * @param request
     * @param response
     * @param skuId 最小銷售單元id
     */
    public void addNum(HttpServletRequest request, HttpServletResponse response, Long skuId);    /**
     * 根據商品id商品數量減一
     * @param request
     * @param response
     * @param skuId 最小銷售單元id
     */
    public void reduceNum(HttpServletRequest request, HttpServletResponse response, Long skuId);    public void deleteCart(HttpServletRequest request, HttpServletResponse response, Long skuId);    public void clearCart(HttpServletRequest request, HttpServletResponse response);    public String validCookie(HttpServletRequest request, HttpServletResponse response);    public String validCar(HttpServletRequest request, HttpServletResponse response);1234567891011121314151617181920212223242526272829303132333435363738394012345678910111213141516171819202122232425262728293031323334353637383940      

實作類:

public List<EbCart> listCart(HttpServletRequest request,
            HttpServletResponse response) {
        List<EbCart> cartList = new ArrayList<EbCart>();        //擷取浏覽器所有cookie
        Cookie[] cookies = request.getCookies();        //[{skuId:1,quantity:2},{}]
        if(cookies != null && cookies.length > 0){            for (Cookie cookie : cookies) {                String code = ECPSUtils.readProp("cookie_ecps_code");                String name = cookie.getName();                if(StringUtils.equals(name, code)){                    String result = cookie.getValue();                    //對其進行解碼,防止中文亂碼
                    result = URLDecoder.decode(result);
                    JSONArray ja = JSONArray.fromObject(result);
                    JsonConfig jc = new JsonConfig();                    //設定要轉換的類
                    jc.setRootClass(EbCart.class);                    //排除類裡面的屬性
                    jc.setExcludes(new String[]{"sku"});
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    //根據skuid設定購物車對象的EbSku對象
                    for (EbCart cart : cartList) {
                        EbSku sku = skuDao.getSkuDetailById(cart.getSkuId());
                        cart.setSku(sku);
                    }
                }
            }
        }        return cartList;
    }

    public void addCart(HttpServletRequest request,
            HttpServletResponse response, Long skuId, Integer quantity) {
        List<EbCart> cartList = new ArrayList<EbCart>();        //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 cookie : cookies){                String name = cookie.getName();                String cookieKey = ECPSUtils.readProp("cookie_ecps_code");                if(StringUtils.equals(name, cookieKey)){                    //獲得cookie的值
                    String result = cookie.getValue();                    //[{skuId:1002, quantity:2}, {skuId:1003, quantity:3},....]
                    result = URLDecoder.decode(result);                    //把json格式的字元串轉換成json數組對象
                    JSONArray ja = JSONArray.fromObject(result);                    //把json的數組轉換成java集合
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);

                    boolean isExsits = false;                    //1.如果存在對應商品,則在基礎上數量加一
                    for(EbCart cart: cartList){                        if(cart.getSkuId().longValue() == skuId.longValue()){
                            cart.setQuantity(cart.getQuantity() + quantity);
                            isExsits = true;
                        }
                    }                    //2.如果不存在,則建立新的對象
                    if(!isExsits){
                        EbCart cartObj = new EbCart();
                        cartObj.setSkuId(skuId);
                        cartObj.setQuantity(quantity);
                        cartList.add(cartObj);
                    }

                }
            }
        }        //3.如果沒有建立過cookie對象,則建立
        if(cartList.size() == 0){
            EbCart cartObj = new EbCart();
            cartObj.setSkuId(skuId);
            cartObj.setQuantity(quantity);
            cartList.add(cartObj);
        }        //将java對象再次轉換為字元串存到cookie中
        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();
        result = URLEncoder.encode(result);
        Cookie cookie = new Cookie("cookie_ecps_code", result);
        cookie.setMaxAge(Integer.MAX_VALUE);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public void addNum(HttpServletRequest request,
            HttpServletResponse response, Long skuId) {
        List<EbCart> cartList = new ArrayList<EbCart>();        //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 cookie : cookies){                String name = cookie.getName();                String cookieKey = ECPSUtils.readProp("cookie_ecps_code");                if(StringUtils.equals(name, cookieKey)){                    //獲得cookie的值
                    String result = cookie.getValue();                    //[{skuId:1002, quantity:2}, {skuId:1003, quantity:3},....]
                    result = URLDecoder.decode(result);                    //把json格式的字元串轉換成json數組對象
                    JSONArray ja = JSONArray.fromObject(result);                    //把json的數組轉換成java集合
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    for(EbCart cart: cartList){                        if(cart.getSkuId().longValue() == skuId.longValue()){
                            cart.setQuantity(cart.getQuantity() + 1);
                        }
                    }

                }
            }
        }        //将java對象再次轉換為字元串存到cookie中
        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();
        result = URLEncoder.encode(result);
        Cookie cookie = new Cookie("cookie_ecps_code", result);
        cookie.setMaxAge(Integer.MAX_VALUE);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    @SuppressWarnings("deprecation")
    public void reduceNum(HttpServletRequest request,
            HttpServletResponse response, Long skuId) {
        List<EbCart> cartList = new ArrayList<EbCart>();
        Cookie[] cookies = request.getCookies();
        JsonConfig jc = new JsonConfig();
        jc.setRootClass(EbCart.class);
        jc.setExcludes(new String[]{"sku"});        if(cookies != null && cookies.length > 0){            for (Cookie cookie : cookies) {                String name = cookie.getName();                String code = ECPSUtils.readProp("cookie_ecps_code");                if(StringUtils.equals(name, code)){                    String result = cookie.getValue();                    //将html編碼解碼
                    result = URLDecoder.decode(result);
                    JSONArray ja = JSONArray.fromObject(result);
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    for(EbCart cart : cartList){                        if(cart.getSkuId().longValue() == skuId.longValue()){
                            cart.setQuantity(cart.getQuantity() - 1);
                        }
                    }
                }
            }
        }        //将java對象再次轉換為字元串存到cookie中
        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();
        result = URLEncoder.encode(result);
        Cookie cookie = new Cookie("cookie_ecps_code", result);
        cookie.setMaxAge(Integer.MAX_VALUE);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public void deleteCart(HttpServletRequest request,
            HttpServletResponse response, Long skuId) {
        List<EbCart> cartList = new ArrayList<EbCart>();        //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 cookie : cookies){                String name = cookie.getName();                String cookieKey = ECPSUtils.readProp("cookie_ecps_code");                if(StringUtils.equals(name, cookieKey)){                    //獲得cookie的值
                    String result = cookie.getValue();                    //[{skuId:1002, quantity:2}, {skuId:1003, quantity:3},....]
                    result = URLDecoder.decode(result);                    //把json格式的字元串轉換成json數組對象
                    JSONArray ja = JSONArray.fromObject(result);                    //把json的數組轉換成java集合
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    for(EbCart cart: cartList){                        if(cart.getSkuId().longValue() == skuId.longValue()){
                            cartList.remove(cart);
                        }
                    }

                }
            }
        }        //将java對象再次轉換為字元串存到cookie中
        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();
        result = URLEncoder.encode(result);
        Cookie cookie = new Cookie("cookie_ecps_code", result);
        cookie.setMaxAge(Integer.MAX_VALUE);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public void clearCart(HttpServletRequest request,
            HttpServletResponse response) {
        List<EbCart> cartList = new ArrayList<EbCart>();        //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 cookie : cookies){                String name = cookie.getName();                String cookieKey = ECPSUtils.readProp("cookie_ecps_code");                if(StringUtils.equals(name, cookieKey)){                    //獲得cookie的值
                    String result = cookie.getValue();                    //[{skuId:1002, quantity:2}, {skuId:1003, quantity:3},....]
                    result = URLDecoder.decode(result);                    //把json格式的字元串轉換成json數組對象
                    JSONArray ja = JSONArray.fromObject(result);                    //把json的數組轉換成java集合
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);
                    cartList.clear();
                }
            }
        }

        JSONArray ja = JSONArray.fromObject(cartList, jc);        String result = ja.toString();
        result = URLEncoder.encode(result);
        Cookie cookie = new Cookie("cookie_ecps_code", result);
        cookie.setMaxAge(Integer.MAX_VALUE);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public String validCookie(HttpServletRequest request,
            HttpServletResponse response) {        /**
         * 1.建立cookie設定到浏覽器
         * 2.取cookie,看是否能拿到,如果拿到,說明浏覽器cookie正常,否則,關閉了
         */
        Cookie cookie = new Cookie("test", "test");
        response.addCookie(cookie);
        Cookie[] cookies = request.getCookies();        String result = "yes";//預設為cookie可用
        if(cookies != null && cookies.length > 0){            for (Cookie cookie2 : cookies) {                String name = cookie2.getName();                String value = cookie2.getValue();
                System.out.println(name+"="+value);                if((StringUtils.equals("test", name) && StringUtils.equals("test", value))){
                    result = "no";
                }
            }
        }
        System.out.println(result);        return "yes";
    }

    public String validCar(HttpServletRequest request,
            HttpServletResponse response) {        String result1 = "success";
        List<EbCart> cartList = new ArrayList<EbCart>();        //獲得目前網站的cookie
        Cookie[] cookies = request.getCookies();        if(cookies != null&&cookies.length > 0){            for(Cookie cookie : cookies){                String name = cookie.getName();                String cookieKey = ECPSUtils.readProp("cart_key");                if(StringUtils.equals(name, cookieKey)){                    //獲得cookie的值
                    String result = cookie.getValue();                    //[{skuId:1002, quantity:2}, {skuId:1003, quantity:3},....]
                    result = URLDecoder.decode(result);                    //把json格式的字元串轉換成json數組對象
                    JSONArray ja = JSONArray.fromObject(result);                    //json的配置對象
                    JsonConfig jc = new JsonConfig();                    //設定要轉換的類
                    jc.setRootClass(EbCart.class);                    //設定不需要轉換的屬性
                    jc.setExcludes(new String[]{"sku"});                    //把json的數組轉換成java集合
                    cartList = (List<EbCart>) JSONSerializer.toJava(ja, jc);                    for (EbCart cart : cartList) {                        //判斷庫存商品數量是否大于購買數量
                        EbSku sku = skuDao.getSkuDetailById(cart.getSkuId());                        if(sku.getStockInventory().intValue() < cart.getQuantity().intValue()){                            //提示資訊:哪個商品什麼規格不足多少
                            result1 = sku.getItem().getItemName();//哪個商品
                            for(EbSpecValue spec : sku.getSpecList()){
                                result1 = result1 + spec.getSpecValue();//哪個規格
                            }
                            result1 = result1 + "不足" + cart.getQuantity();//不足多少
                            break;//循環到庫存不足的商品就跳出
                        }
                    }
                }
            }
        }        return result1;
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324      

9、訂單送出

訂單送出的時候,注意每一次送出都要驗證庫存是否足夠

頁面:

//訂單送出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("系統錯誤");
        }
    })
}//購買數量減一function reduceNum(skuId, quantity){

    var jsonObj = validStock(skuId, quantity);    if(jsonObj.result == "no"){        var newQuantity = quantity - 1;
        alert("目前的庫存數量不足"+newQuantity+"個,僅有"+jsonObj.stock+"個");        return;
    }    if(quantity == 1){        if(confirm("是否把該商品從購物車中删除?")){
            window.location.href = "${path}/cart/deleteCart.do?skuId="+skuId;
        }
    }else{
        window.location.href = "${path}/cart/reduceNum.do?skuId="+skuId;
    }
}//驗證庫存數量function validStock(skuId, quantity){
    quantity--;    var jsonObj = null;
    $.ajax({
        url:"${path}/cart/validStockCar.do",
        type:"post",
        dataType:"text",
        async:false,
        data:{
            skuId:skuId,
            quantity:quantity
        },
        success:function(responseText){
            jsonObj = $.parseJSON(responseText);
        },
        error:function(){
            alert("系統錯誤");
        }

    })    return jsonObj;
}function changeImage(){
    var path = "${path}/user/getImage.do?date="+new Date();
    $("#captchaImage").attr("src", path);
}//送出訂單異步登入function loginAjax(){
    var username = $("#username").val();    var password = $("#password").val();    var captcha = $("#captcha").val();
    $.ajax({
        url:"${path}/user/loginAjax.do",
        type:"post",
        dataType:"text",
        data:{
            username:username,
            password:password,
            captcha:captcha
        },
        success:function(responseText){
            if(responseText == "caperror"){
                $("#errorName").html("驗證碼錯誤");
                $("#errorName").show(500);
            }else if(responseText == "userpasserror"){
                $("#errorName").html("使用者名或者密碼錯誤");
                $("#errorName").show(500);
            }else if(responseText == "success"){
                $("#loginAlertIs").html(username);
                tipHide("#loginAlert");                //校驗庫存
                var result = validCar();                if(result == "success"){
                    window.location.href = "${path}/order/toSubmitOrder.do";
                }else{
                    alert(result);
                }
            }
        },
        error:function(){
            alert("系統錯誤");
        }

    })
}//驗證庫存是否足夠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;
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130      

action:

//訂單送出
    @RequestMapping("/submitOrder.do")
    public String submitOrder(HttpServletResponse response, HttpServletRequest request,EbOrder order,
            HttpSession session, String address, Model model) throws Exception{
        TsPtlUser user = (TsPtlUser) session.getAttribute("user");
        if(user != null){
            order.setPtlUserId(user.getPtlUserId());
            order.setUsername(user.getUsername());
        }
        order.setOrderNum(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        //1.如果不是新添加的位址,則通過位址的id查詢當前的位址
        //2.新添加的位址,會自動的賦值給order對象
        if(!StringUtils.equals("add", address)){
            EbShipAddr addr = shipAddrService.selectAddrByShipAddrId(new Long(address));
            BeanUtils.copyProperties(order, addr);
        }
        List<EbCart> cartList = cartService.listCart(request, response);
        List<EbOrderDetail> detailList = new ArrayList<EbOrderDetail>();
        for(EbCart cart:cartList){
            EbOrderDetail detail = new EbOrderDetail();
            detail.setItemId(cart.getSku().getItem().getItemId());
            detail.setItemName(cart.getSku().getItem().getItemName());
            detail.setItemNo(cart.getSku().getItem().getItemNo());
            detail.setSkuId(cart.getSkuId());
            String specVal = "";
            List<EbSpecValue> specList = cart.getSku().getSpecList();
            for(EbSpecValue spec : specList){
                specVal = specVal + spec.getSpecValue()+",";
            }
            specVal = specVal.substring(0, specVal.length() - 1);
            detail.setSkuSpec(specVal);
            detail.setQuantity(cart.getQuantity());
            detail.setSkuPrice(cart.getSku().getSkuPrice());
            detail.setMarketPrice(cart.getSku().getMarketPrice());
            detailList.add(detail);
        }
        try {
            String processInstanceId = orderService.saveOrder(response, request, order, detailList);
            model.addAttribute("order", order);
            model.addAttribute("processInstanceId", processInstanceId);
        } catch (Exception e) {
            if(e instanceof EbStockException){
                model.addAttribute("tip", "stock_error");
            }
        }
        return "shop/confirmProductCase2";
    }    /**
     * 訂單支付
     */
    @RequestMapping("/pay.do")
    public void pay(String processInstanceId, Long orderId, PrintWriter out){
        orderService.pay(processInstanceId, orderId);
        out.write("success");
    }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455561234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556      

service:

public String saveOrder(HttpServletResponse response, HttpServletRequest request,
            EbOrder order, List<EbOrderDetail> detailList)throws EbStockException {
        orderDao.saveOrder(order);        Map<String,Object> map = new HashMap<String,Object>();
        for(EbOrderDetail detail : detailList){            //給訂單詳情設置訂單id
            detail.setOrderId(order.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());            //為了防止并發問題,這裡可以使用:
            //1.悲觀鎖:對查詢語句進行鎖,即for update
            //2.樂觀鎖:對修改語句進行鎖,即條件加判斷條件:會傳回影響數量
            int flag = skuDao.updateStock(map);            if(flag == 0){
                throw new EbStockException("庫存不足");
            }

        }        //儲存訂單時,開啟一個流程執行個體
        String processInstanceId = flowService.startProcess(order.getOrderId());
        cartService.clearCart(request, response);        return processInstanceId;
    }    public void pay(String processInstanceId, Long orderId){        //修改訂單支付狀态
        EbOrder order = new EbOrder();        order.setOrderId(orderId);        order.setIsPaid((short)1);
        orderDao.updateOrder(order);        //完成訂單支付節點
        flowService.completeTaskByPId(processInstanceId, "支付");
    }    public List<TaskBean> listNoPayOrder(Short isCall, String assignee) {        /**
         * 1.根據辦理人查詢到task和businesskey
         * 2.根據businesskey查詢訂單
         * 3.根據iscall查詢未支付的訂單
         */
        List<TaskBean> tbList1 = new ArrayList<TaskBean>();        List<TaskBean> tbList = flowService.selectTaskBeanByAssignee(assignee);
        for (TaskBean tb : tbList) {
            EbOrder order = orderDao.selectOrderById(tb.getBusinessKey());            //查詢沒有付款的訂單
            if(order.getIsCall().shortValue() == isCall.shortValue()){
                tb.setOrder(order);
                tbList1.add(tb);
            }
        }        return tbList1;
    }    public EbOrder selectOrderAndDetailById(Long orderId) {        return orderDao.selectOrderAndDetailById(orderId);
    }    public void updateOrder(Long orderId) {
        EbOrder order = new EbOrder();        order.setOrderId(orderId);        order.setIsCall((short)1);
        orderDao.updateOrder(order);
    }    public List<TaskBean> listPaidOrder(String assignee) {        /**
         * 1.根據辦理人查詢到task和businesskey
         * 2.根據businesskey查詢訂單
         * 3.根據iscall查詢未支付的訂單
         */
        List<TaskBean> tbList = flowService.selectTaskBeanByAssignee(assignee);
        for (TaskBean tb : tbList) {
            EbOrder order = orderDao.selectOrderById(tb.getBusinessKey());            //查詢沒有付款的訂單
            tb.setOrder(order);
        }        return tbList;
    }    public TaskBean selectTaskBeanByOrderIdAndTaskId(Long orderId, String taskId) {
        EbOrder order = orderDao.selectOrderAndDetailById(orderId);
        TaskBean tb = flowService.selectTaskBeanByTaskId(taskId);
        tb.setOrder(order);        return tb;
    }    public void compeleTask(String taskId, String outcome, Long orderId) {
        EbOrder order = new EbOrder();        order.setOrderId(orderId);        order.setUpdateTime(new Date());
        flowService.compeleTaskByTaskId(taskId, outcome);
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100      

10、訂單流程

這裡采用工作流activiti整合ssm

10.1、業務流程圖

public void deployFlow() {
        DeploymentBuilder db = repositoryService.createDeployment();
        db.addClasspathResource("com/sihai/ecps/diagrams/OrderFlow.bpmn")          .addClasspathResource("com/sihai/ecps/diagrams/OrderFlow.png");
        db.deploy();
    }    public String startProcess(Long orderId) {
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("OrderFlow", orderId+"");        return pi.getId();
    }    public void completeTaskByPId(String processInstanceId, String outcome) {        Map<String, Object> map = new HashMap<String, Object>();        map.put("outcome", outcome);
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        taskService.complete(task.getId(), map);
    }    public List<TaskBean> selectTaskBeanByAssignee(String assignee) {        //根據辦理人查詢任務清單
        List<Task> tList = taskService.createTaskQuery()        .processDefinitionKey("OrderFlow")        .taskAssignee(assignee)        .orderByTaskCreateTime()        .desc()        .list();        List<TaskBean> tbList = new ArrayList<TaskBean>();
        for (Task task : tList) {            //設定任務和businesskey
            TaskBean tb = new TaskBean();
            tb.setTask(task);
            ProcessInstance pi = runtimeService.createProcessInstanceQuery()                    .processDefinitionKey("OrderFlow")                    .processInstanceId(task.getProcessInstanceId())                    .singleResult();            String businessKey = pi.getBusinessKey();
            tb.setBusinessKey(businessKey);
            tbList.add(tb);
        }        return tbList;
    }    public TaskBean selectTaskBeanByTaskId(String taskId) {
        Task task = taskService.createTaskQuery().processDefinitionKey("OrderFlow").taskId(taskId).singleResult();
        TaskBean tb = new TaskBean();
        tb.setTask(task);        List<String> outcomes = this.getOutcomes(task);
        tb.setOutcomes(outcomes);        return tb;
    }    public List<String> getOutcomes(Task task){        List<String> outcomes = new ArrayList<String>();        //獲得流程定義的對象
        ProcessDefinitionEntity pe = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(task.getProcessDefinitionId());        //獲得流程執行個體對象
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processDefinitionKey("OrderFlow")        .processInstanceId(task.getProcessInstanceId()).singleResult();
        ActivityImpl ai = pe.findActivity(pi.getActivityId());        //獲得往外面走的線路的對象
        List<PvmTransition> ptList = ai.getOutgoingTransitions();

        for(PvmTransition pt : ptList){            String name = (String) pt.getProperty("name");
            outcomes.add(name);
        }        return outcomes;
    }    public void compeleTaskByTaskId(String taskId, String outcome) {        Map<String,Object> map = new HashMap<String,Object>();        map.put("outcome", outcome);
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        taskService.complete(task.getId(), map);
    }1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787912345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879      

繼續閱讀