購物車和訂單的實現
購物車的邏輯寫在taotao-portal中
分析:
1、添加購物車不需要用戶登錄。購物車的數據應該放到cookie中。
2、當向購物車添加同一款商品時,購物車中商品的數量增加。
3、購物車中可以刪除商品
4、購物車中可以修改商品數量。商品的總價需要重新計算。
5、點擊“結算”按鈕要求用戶登錄。
購物車添加商品service.
邏輯:
1、接收商品id
2、從cookie中購物車商品列表
3、從商品列表中查詢列表是否存在此商品
4、如果存在商品的數量加上參數中的商品數量
5、如果不存在,調用rest服務,根據商品id獲得商品數據。
6、把商品數據添加到列表中
7、把購物車商品列表寫入cookie
8、返回TaotaoResult
@Service
public class CartServiceImpl implements CartService {
@Autowired
private ItemService itemService;
@Value("${COOKIE_EXPIRE}")
private Integer COOKIE_EXPIRE;
@Override
public TaotaoResult addCart(Long itemId, Integer num, HttpServletRequest request,
HttpServletResponse response) {
//1.接收商品id
//從cookie中獲取購物車商品列表
List<CartItem> itemList = getCartItemList(request);
//3.從商品列表中查詢列表是否存在此商品
//flag用來判斷是否找到對應的產品
boolean haveFlg = false;
for(CartItem cartItem : itemList) {
//如果商品存在數量相加
//4.如果存在商品的數量加上參數中的商品數量
if(cartItem.getId().longValue() == itemId) {
cartItem.setNum(cartItem.getNum() + num);
haveFlg = true;
break;
}
}
//5.如果不存在,調用rest服務,根據商品id獲得商品數據
if(!haveFlg) {
TbItem item = itemService.getItemById(itemId);
//轉換成CartItem
CartItem cartItem = new CartItem();
cartItem.setId(itemId);
cartItem.setNum(num);
cartItem.setPrice(item.getPrice());
cartItem.setTitle(item.getTitle());
//購物車上只會展示一張圖片
if(StringUtils.isNoneBlank(item.getImage())) {
String image = item.getImage();
String[] strings = image.split(",");
cartItem.setImage(strings[0]);
}
//添加到購物車商品列表
//6.把商品數據添加到列表中
itemList.add(cartItem);
}
//7.把購物車商品列表寫入cookie
CookieUtils.setCookie(request, response, "TT_CART", JsonUtils.objectToJson(itemList), COOKIE_EXPIRE, true);
//返回taotaoResult
return TaotaoResult.ok();
}
/**
* 取購物車商品列表
*/
private List<CartItem> getCartItemList(HttpServletRequest request){
try {
//從cookie中取商品列表
String json = CookieUtils.getCookieValue(request, "TT_CART", true);
//把json轉換成java對象
List<CartItem> list = JsonUtils.jsonToList(json, CartItem.class);
return list == null?new ArrayList<CartItem>() : list;
} catch (Exception e) {
return new ArrayList<CartItem>();
}
}
}
購物車中商品數量的加減按鈕,刪除商品按鈕都是要聯系到cookie和redis的操作
刪除的controller中重定向,點擊刪除按鈕應該重新跳回購物車url
@RequestMapping("/cart/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId,
HttpServletResponse response, HttpServletRequest request) {
TaotaoResult result = cartService.deleteCartItem(itemId, request, response);
return "redirect:/cart/cart.html";
}
更換設備后購物車信息不能同步
解決方案:當用戶登錄后,需要把cookie的購物車信息同步到redis
訂單實現
搭建taotao-order
1、接收json
數據,需要使用@RequestBody注解。對應提交的json數據格式創建一個pojo接收。
需要使用的表:
tb_order 訂單表(一)
tb_order_item 訂單明細表(多)
tb_order_shipping 物流表(一)
可以使用訂單相關的三個表對應的pojo封裝一個pojo接收提交的json數據。注意繼承。
public class OrderInfo 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;
}
}
2、接收json數據后,把數據插入到響應的表中。
3、使用redis的incr命令(redis是單線程,不會重復)
接收json報文,插入三張表數據,返回訂單號的服務Service
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private TbOrderMapper orderMapper;
@Autowired
private TbOrderItemMapper orderItemMapper;
@Autowired
private TbOrderShippingMapper orderShippingMapper;
@Autowired
private JedisClient jedisClient;
@Value("${REDIS_ORDER_GEN_KEY}")
private String REDIS_ORDER_GEN_KEY;
@Value("${ORDER_ID_BEGIN}")
private String ORDER_ID_BEGIN;
@Value("${REDIS_ORDER_DETAIL_GEN_KEY}")
private String REDIS_ORDER_DETAIL_GEN_KEY;
@Override
public TaotaoResult createOrder(OrderInfo orderInfo) {
//一、插入訂單表
//1.接收數據OrderInfo
//2.生成訂單號
//取訂單號
String id = jedisClient.get(REDIS_ORDER_GEN_KEY);
if(StringUtils.isBlank(id)) {
//如果訂單號生成key不存在設置初始值
jedisClient.set(REDIS_ORDER_GEN_KEY, ORDER_ID_BEGIN);
}
Long orderId = jedisClient.incr(REDIS_ORDER_GEN_KEY);
//3.補全字段
orderInfo.setOrderId(orderId.toString());
//狀態:1.未付款2.已付款3.未發貨4.已發貨5.交易成功6.交易關閉
orderInfo.setStatus(1);
Date date = new Date();
orderInfo.setCreateTime(date);
orderInfo.setUpdateTime(date);
//4.插入訂單表
orderMapper.insert(orderInfo);
//二、插入訂單明細
//2.補全字段
List<TbOrderItem> orderItems = orderInfo.getOrderItems();
for(TbOrderItem orderItem : orderItems) {
//1.生成訂單明細id,使用redis的incr命令生成
Long detailId = jedisClient.incr(REDIS_ORDER_DETAIL_GEN_KEY);
orderItem.setId(detailId.toString());
//訂單號
orderItem.setOrderId(orderId.toString());
//3.插入數據
orderItemMapper.insert(orderItem);
}
//三、插入物流表
TbOrderShipping orderShipping = orderInfo.getOrderShipping();
//1.補全字段
orderShipping.setOrderId(orderId.toString());
orderShipping.setCreated(date);
orderShipping.setUpdated(date);
//2.插入數據
orderShippingMapper.insert(orderShipping);
//返回TaotaoResult包裝訂單號
return TaotaoResult.ok(orderId);
}
}
對應的controller,注意@RequestBody
@Controller
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping(value="/order/create", method=RequestMethod.POST)
@ResponseBody
public TaotaoResult createOrder(@RequestBody OrderInfo orderInfo) {
try {
TaotaoResult result = orderService.createOrder(orderInfo);
return result;
} catch (Exception e) {
e.printStackTrace();
return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
}
}
}
taotao-portal的處理
點擊提交訂單按鈕要確認登錄,并且token中有需要的用戶信息
攔截器的request和最后的request是同一個,所以可以把用戶信息放在request中
在訂單確認頁面點擊“提交訂單按鈕”進行提交訂單的處理。把表單的內容提交給taotao-portal的后臺,后臺調用taotao-order發布的服務生成訂單。展示訂單提交成功頁面,并且展示訂單號。
taotao-portal中調用taotao-order的service
@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(OrderInfo orderInfo) {
// 把OrderInfo轉換成json
String json = JsonUtils.objectToJson(orderInfo);
//提交訂單數據
String jsonResult = HttpClientUtils.doPostJson(ORDER_BASE_URL+ORDER_CREATE_URL, json);
//轉換成java對象
TaotaoResult taotaoResult = TaotaoResult.format(jsonResult);
//取訂單號
String orderId = taotaoResult.getData().toString();
return orderId;
}
}
Controller接收提交的訂單信息,使用OrderInfo接收。調用Service創建訂單,跳轉到成功頁面,并且把訂單號傳遞給頁面。
Controller
@RequestMapping(value="/create",method=RequestMethod.POST)
public String createOrder(OrderInfo orderInfo, Model model,HttpServletRequest request) {
//取用戶信息
TbUser user = (TbUser) request.getAttribute("user");
//補全orderInfo的屬性
orderInfo.setUserId(user.getId());
orderInfo.setBuyerNick(user.getUsername());
//調用服務
String orderId = orderService.createOrder(orderInfo);
//把訂單號傳遞給頁面
model.addAttribute("orderId",orderId);
model.addAttribute("payment",orderInfo.getPayment());
DateTime dateTime = new DateTime();
dateTime = dateTime.plusDays(3);
model.addAttribute("date",dateTime.toString("yyyy-MM-dd"));
//返回邏輯視圖
return "success";
}