最近一段時間剛剛學習了一些新的知識,就想拿個項目練練手,然後就在網上找了一個教育訓練的電商項目練習了一下,做了之後學到了很多,學到了項目的很多流程,在這裡總結一下。
一、項目介紹:
網上商城項目,用于建立網上終端、營銷案線上銷售及相關輔助功能,背景包含商品管理、訂單管理、類目管理、客戶管理、合作商管理、客服管理、支付平台、内容管理等,很大程度上分擔了人工的壓力,前台包括個人中心,購物車,商城首頁,頻道頁,商品詳情頁,送出訂單頁,支付頁面等頁面構成,對提高客戶服務效率和客戶滿意度能夠起到較好的作用。
二、項目所用技術:
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