问题
苍穹外卖这一块业务,是直接拿购物车的快照去结算,如果在加入购物车之后的时间,商家修改了商品信息,会出现问题。
以下是苍穹外卖下单业务源代码:
package com.sky.service.impl; import com.sky.constant.MessageConstant; import com.sky.context.BaseContext; import com.sky.dto.OrdersSubmitDTO; import com.sky.entity.AddressBook; import com.sky.entity.OrderDetail; import com.sky.entity.Orders; import com.sky.entity.ShoppingCart; import com.sky.exception.AddressBookBusinessException; import com.sky.exception.ShoppingCartBusinessException; import com.sky.mapper.AddressBookMapper; import com.sky.mapper.OrderDetailMapper; import com.sky.mapper.OrderMapper; import com.sky.mapper.ShoppingCartMapper; import com.sky.service.OrderService; import com.sky.vo.OrderSubmitVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Service @Slf4j public class OrderServiceImpl implements OrderService { @Autowired private OrderMapper orderMapper; @Autowired private OrderDetailMapper orderDetailMapper; @Autowired private AddressBookMapper addressBookMapper; @Autowired private ShoppingCartMapper shoppingCartMapper; /** * 用户下单 * @param ordersSubmitDTO * @return */ @Override public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) { // 判空(地址簿,购物车) AddressBook add = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId()); if(add == null){ throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL); } ShoppingCart shoppingCart = new ShoppingCart(); shoppingCart.setUserId(BaseContext.getCurrentId()); List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart); if(list.isEmpty() || list == null){ throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL); } // 向订单表插入一条订单数据 Orders orders = new Orders(); BeanUtils.copyProperties(ordersSubmitDTO,orders); orders.setOrderTime(LocalDateTime.now()); orders.setPayStatus(Orders.UN_PAID); orders.setStatus(Orders.PENDING_PAYMENT); orders.setNumber(String.valueOf(System.currentTimeMillis())); orders.setPhone(add.getPhone()); orders.setConsignee(add.getConsignee()); orders.setUserId(BaseContext.getCurrentId()); orderMapper.insert(orders); // 向订单明细表批量插入多条数据 List<OrderDetail> detailList = new ArrayList<>(); for (ShoppingCart cart : list) { OrderDetail orderDetail = new OrderDetail(); BeanUtils.copyProperties(cart,orderDetail); orderDetail.setOrderId(orders.getId()); detailList.add(orderDetail); } orderDetailMapper.insertBatch(detailList); // 清空购物车 shoppingCartMapper.clearByUserId(BaseContext.getCurrentId()); // 返回VO OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder() .id(orders.getId()) .orderNumber(orders.getNumber()) .orderAmount(orders.getAmount()) .orderTime(orders.getOrderTime()) .build(); return orderSubmitVO; } }解决方法
如果商家修改商品信息后直接更改购物车信息,会涉及多表查询,而且如果用户量大的话,处理起来非常的麻烦,那么争对苍穹外卖这个模块,可以在结算的时候再做一次校验:
for (ShoppingCart cartItem : shoppingCartList) { // 1. 查最新的菜品/套餐数据 Dish dish = dishMapper.getById(cartItem.getDishId()); // 2. 检查是否还在售 if (dish.getStatus() == 0) { throw new OrderBusinessException(dish.getName() + " 已下架"); } // 3. 检查价格是否变动 if (!dish.getPrice().equals(cartItem.getAmount())) { // 直接抛异常,提示用户刷新购物车 throw new OrderBusinessException(dish.getName() + " 价格有变动,请重新确认"); } }