云计算百科
云计算领域专业知识百科平台

苍穹外卖下单业务的漏洞

问题

苍穹外卖这一块业务,是直接拿购物车的快照去结算,如果在加入购物车之后的时间,商家修改了商品信息,会出现问题。

以下是苍穹外卖下单业务源代码:

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() + " 价格有变动,请重新确认");
}
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » 苍穹外卖下单业务的漏洞
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!