订单服务 - raymond-zhao/cat-mall GitHub Wiki

订单服务

防重操作

下单操作

@Transactional
@Override
public SubmitOrderResponseVO submitOrder(OrderSubmitVO submitVO) {
    confirmVOThreadLocal.set(submitVO);
    SubmitOrderResponseVO responseVO = new SubmitOrderResponseVO();
    MemberResponseVO memberResponseVO = LoginUserInterceptor.loginUser.get();
    responseVO.setCode(0);
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    String orderToken = submitVO.getOrderToken();
    // 原子性操作验证和删除令牌
    Long result = stringRedisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
                                              Collections.singletonList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVO.getId()), orderToken);
    if (result == 0) {
        // 令牌验证失败
        responseVO.setCode(1);
        return responseVO;
    } else {
        // 验证成功 下单 去创建订单 验证令牌 核算价格 锁定库存
        OrderCreateTO orderCreateTO = createOrder();
        // 验价
        BigDecimal payAmount = orderCreateTO.getOrderEntity().getPayAmount();
        BigDecimal payPrice = submitVO.getPayPrice();
        if (Math.abs(payAmount.subtract(payPrice).doubleValue()) < 0.01) {
            // 金额对比
            // 保存订单
            saveOrder(orderCreateTO);
            // 锁定库存 只要有异常就回滚数据
            WareSkuLockVO lockVO = new WareSkuLockVO();
            lockVO.setOrderSn(orderCreateTO.getOrderEntity().getOrderSn());
            List<OrderItemVO> locks = orderCreateTO.getOrderItems().stream().map(o -> {
                OrderItemVO itemVO = new OrderItemVO();
                itemVO.setSkuId(o.getSkuId());
                itemVO.setCount(o.getSkuQuantity());
                itemVO.setTitle(o.getSkuName());
                return itemVO;
            }).collect(Collectors.toList());
            lockVO.setLocks(locks);
            R r = wareFeign.lockOrder(lockVO);
            if (r.getCode() == 0) {
                // 锁定成功
                responseVO.setOrderEntity(orderCreateTO.getOrderEntity());
                rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", orderCreateTO.getOrderEntity());
                return responseVO;
            } else {
                // 锁定失败
                throw new NoStockException((String) r.get("msg"));
            }
        } else {
            responseVO.setCode(2);
            return  responseVO;
        }
    }
}