商城專案實戰37:訂單系統最小實現介面文件及實現
1 建立訂單
使用者使用portal建立訂單、android、ios、微信商城提交訂單時使用。
請求方法 |
POST |
URL |
http://order.taotao.com/order/create |
引數說明 |
提交的資料格式: { "payment": 5288, "postFee": 0, "userId": "3", "buyerMessage": null, "buyerNick": "zhang123", "orderItems": [ { "itemId": "9", "num": 1, "title": "蘋果(Apple)iPhone 6 (A1586) 16GB 金色 移動聯通電信4G手機3", "price": 5288, "totalFee": 5288, "picPath": "http://image.taotao.com/images/2015/03/06/2015030610045320609720.jpg" } ], "orderShipping": { "receiverName": "張三", "receiverPhone": "", "receiverMobile": "15800000000", "receiverState": "上海", "receiverCity": "上海", "receiverDistrict": "閔行區", "receiverAddress": "三魯公路3279號 明浦廣場 3號樓 205室", "receiverZip": "200000" } } |
示例 |
|
返回值 |
{ status: 200 //200 成功 msg: "OK" // 返回資訊訊息 data: 100544// 返回訂單號 } |
2 根據訂單ID查詢訂單
請求方法 |
GET |
URL |
http://order.taotao.com/order/info/{orderId} |
引數說明 |
orderId:訂單編號 |
示例 |
http://order.taotao.com/order/info/31414485440695 |
返回值 |
{ "status": 200, "msg": "OK", "data": { "orderId":"100544", "payment": 5288, "paymentType":1 "status":1 "createTime":"2015-01-01 08:22:14" "postFee": 0, "userId": "3", "buyerMessage": null, "buyerNick": "zhang123", "orderItems": [ { "itemId": "9", "num": 1, "title": "蘋果(Apple)iPhone 6 (A1586) 16GB 金色 移動聯通電信4G手機3", "price": 5288, "totalFee": 5288, "picPath": "http://image.taotao.com/images/2015/03/06/2015030610045320609720.jpg" } ], "orderShipping": { "receiverName": "張三", "receiverPhone": "", "receiverMobile": "15800000000", "receiverState": "上海", "receiverCity": "上海", "receiverDistrict": "閔行區", "receiverAddress": "三魯公路3279號 明浦廣場 3號樓 205室", "receiverZip": "200000" } } } |
3 根據使用者分頁查詢訂單
請求方法 |
GET |
URL |
http://order.taotao.com/order/list/{userID}/{page}/{count} |
引數說明 |
userID:使用者ID Page:請求的頁碼 Count:每頁顯示的記錄數 |
示例 |
http://order.taotao.com/order/list/zhang123/1/5 |
返回值 |
{ "status": 200, "msg": "OK", "data": [{ "orderId":"100544", "payment": 5288, "paymentType":1 "status":1 "createTime":"2015-01-01 08:22:14" "postFee": 0, "userId": "3", "buyerMessage": null, "buyerNick": "zhang123", },{ "orderId":"100545", "payment": 5288, "paymentType":1 "status":1 "createTime":"2015-01-01 08:22:15" "postFee": 0, "userId": "3", "buyerMessage": null, "buyerNick": "zhang123", },{ "orderId":"100546", "payment": 5288, "paymentType":1 "status":1 "createTime":"2015-01-01 08:22:16" "postFee": 0, "userId": "3", "buyerMessage": null, "buyerNick": "zhang123", }] } |
4 修改訂單狀態
請求方法 |
POST |
URL |
http://order.taotao.com/order/changeStatus |
引數說明 |
{ "orderId": "100544",//訂單編號 "status": 2, //訂單狀態 "paymentTime": "1414489420444" //付款時間 } |
示例 |
http://sso.taotao.com/user/check/zhangsan;t=1 |
返回值 |
{ status: 200 //200 成功 msg: "OK" // 返回資訊訊息 data: null// 返回資料 } |
1.1.1 Dao層
要對三個表進行操作。都是插入操作。可以使用逆向工程生成的程式碼。
1.1.2 Service層
功能:接收三個引數,
1、對應訂單表的pojo。
2、訂單明細表對應的商品列表。每個元素是訂單明細表對應的pojo
3、物流表對應的pojo
訂單號的生成:
解決方案一(不能使用):
使用mysql的自增長。
優點:不需要我們自己生成訂單號,mysql會自動生成。
缺點:如果訂單表數量太大時需要分庫分表,此時訂單號會重複。如果資料備份後再恢復,訂單號會變。
方案二:日期+隨機數
採用毫秒+隨機數。
缺點:仍然有重複的可能。不建議採用此方案。在沒有更好的解決方案之前可以使用。
方案三:使用UUID
優點:不會重複。
缺點:長。可讀性查。不建議使用。
方案四:可讀性好,不能太長。一般訂單都是全數字的。可以使用redis的incr命令生成訂單號。
優點:可讀性好,不會重複
缺點:需要搭建redis伺服器。
返回值:TaotaoResult
@Service public class OrderServiceImpl implements OrderService { @Autowired private TbOrderMapper orderMapper; @Autowired private TbOrderItemMapper orderItemMapper; @Autowired private TbOrderShippingMapper orderShippingMapper; @Autowired private JedisClient jedisClient; @Value("${ORDER_GEN_KEY}") private String ORDER_GEN_KEY; @Value("${ORDER_INIT_ID}") private String ORDER_INIT_ID; @Value("${ORDER_DETAIL_GEN_KEY}") private String ORDER_DETAIL_GEN_KEY; @Override public TaotaoResult createOrder(TbOrder order, List<TbOrderItem> itemList, TbOrderShipping orderShipping) { //向訂單表中插入記錄 //獲得訂單號 String string = jedisClient.get(ORDER_GEN_KEY); if (StringUtils.isBlank(string)) { jedisClient.set(ORDER_GEN_KEY, ORDER_INIT_ID); } long orderId = jedisClient.incr(ORDER_GEN_KEY); //補全pojo的屬性 order.setOrderId(orderId + ""); //狀態:1、未付款,2、已付款,3、未發貨,4、已發貨,5、交易成功,6、交易關閉 order.setStatus(1); Date date = new Date(); order.setCreateTime(date); order.setUpdateTime(date); //0:未評價 1:已評價 order.setBuyerRate(0); //向訂單表插入資料 orderMapper.insert(order); //插入訂單明細 for (TbOrderItem tbOrderItem : itemList) { //補全訂單明細 //取訂單明細id long orderDetailId = jedisClient.incr(ORDER_DETAIL_GEN_KEY); tbOrderItem.setId(orderDetailId + ""); tbOrderItem.setOrderId(orderId + ""); //向訂單明細插入記錄 orderItemMapper.insert(tbOrderItem); } //插入物流表 //補全物流表的屬性 orderShipping.setOrderId(orderId + ""); orderShipping.setCreated(date); orderShipping.setUpdated(date); orderShippingMapper.insert(orderShipping); return TaotaoResult.ok(orderId); } } |
1.1.3 Controller層
接收一個json格式的字串作為引數。需要使用@RequestBody註解。需要使用一個pojo接收引數。建立一個對應json格式的pojo。
package com.taotao.order.pojo; import java.util.List; import com.taotao.pojo.TbOrder; import com.taotao.pojo.TbOrderItem; import com.taotao.pojo.TbOrderShipping; public class Order extends TbOrder { private List<TbOrderItem> orderItems; private TbOrderShipping orderShipping; public List<TbOrderItem> getOrderItems() { return orderItems; } public void setOrderItems(List<TbOrderItem> orderItems) { this.orderItems = orderItems; } public TbOrderShipping getOrderShipping() { return orderShipping; } public void setOrderShipping(TbOrderShipping orderShipping) { this.orderShipping = orderShipping; } } |
Controller
@Controller public class OrderController { @Autowired private OrderService orderService; @RequestMapping("/create") @ResponseBody public TaotaoResult createOrder(@RequestBody Order order) { try { TaotaoResult result = orderService.createOrder(order, order.getOrderItems(), order.getOrderShipping()); returnresult; } catch (Exception e) { e.printStackTrace(); return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e)); } } } |
2 在前臺系統生成訂單
在taotao-portal系統中新增商品至購物車後,點選提交訂單呼叫taotao-order的服務生成訂單。向用戶展示訂單號。提示建立訂單成功。
2.1 點選購物車“去結算”按鈕
點選“去結算”按鈕跳轉到訂單確認頁面。
展示url:/order/order-cart.html
@Controller @RequestMapping("/order") public class OrderController { @RequestMapping("/order-cart") public String showOrderCart() { return"order-cart"; } } |
2.2 訂單確認頁面
1、要求使用者登入。
2、根據使用者id查詢使用者的收貨地址列表。
3、在此頁面展示購物車的商品列表。
4、需要計算訂單的總金額(包括運費)展示給使用者。
2.2.1 要求使用者登入
修改springmvc.xml攔截所有以:/order/**形式的url
2.2.2 根據使用者id查詢使用者的收貨地址列表。
在實際的商城中是必須有此功能,需要taotao-rest釋出服務,由taotao-portal根據使用者查詢使用者的收貨地址列表。
在此,使用靜態資料模擬。
2.2.3 展示購物車的商品列表
需要從cookie中把購物車商品列表取出,傳遞給order-cart.jsp。
可以直接使用購物車服務。
@Controller @RequestMapping("/order") public class OrderController { @Autowired private CartService cartService; @RequestMapping("/order-cart") public String showOrderCart(HttpServletRequest request, HttpServletResponse response, Model model) { //取購物車商品列表 List<CartItem> list = cartService.getCartItemList(request, response); //傳遞給頁面 model.addAttribute("cartList", list); return "order-cart"; } } |
2.3 提交訂單
點選“提交訂單”按鈕把使用者已經確認的訂單資訊,提交給後臺。提交一個隱藏的表單,其中包含訂單基本資訊,訂單名稱以及配送資訊。需要使用一個包裝的pojo接收表單中的內容。
請求的url:/order/create.html
引數:表單中的內容。使用Order接收表單的內容。
返回值:返回一個jsp頁面。
2.3.1 Service層
接收Order物件,呼叫taotao-order提供的服務,提交訂單。需要把pojo轉換成json資料。呼叫taotao-order提供的服務返回taotaoResult,包含訂單號。
引數:Order
返回值:String(訂單號)
@Service public class OrderServiceImpl implements OrderService { @Value("${ORDER_BASE_URL}") private String ORDER_BASE_URL; @Value("${ORDER_CREATE_URL}") private String ORDER_CREATE_URL; @Override public String createOrder(Order order) { //呼叫taotao-order的服務提交訂單。 String json = HttpClientUtil.doPostJson(ORDER_BASE_URL + ORDER_CREATE_URL, JsonUtils.objectToJson(order)); //把json轉換成taotaoResult TaotaoResult taotaoResult = TaotaoResult.format(json); if (taotaoResult.getStatus() == 200) { Long orderId = (Long) taotaoResult.getData(); return orderId.toString(); } return ""; } } |
2.3.2 Controller層
接收頁面提交的表單的內容,呼叫Service建立訂單。返回成功頁面。
@Controller @RequestMapping("/order") public class OrderController { @Autowired private CartService cartService; @Autowired private OrderService orderService; @RequestMapping("/order-cart") public String showOrderCart(HttpServletRequest request, HttpServletResponse response, Model model) { //取購物車商品列表 List<CartItem> list = cartService.getCartItemList(request, response); //傳遞給頁面 model.addAttribute("cartList", list); return "order-cart"; } @RequestMapping("/create") public String createOrder(Order order, Model model) { String orderId = orderService.createOrder(order); model.addAttribute("orderId", orderId); model.addAttribute("payment", order.getPayment()); model.addAttribute("date", new DateTime().plusDays(3).toString("yyyy-MM-dd")); return"success"; } } |