Search in sources :

Example 1 with ResponseResult

use of com.whoiszxl.bean.ResponseResult in project shopzz by whoiszxl.

the class OrderServiceImpl method submitOrder.

@Override
@Transactional
public String submitOrder(OrderSubmitVO orderSubmitVo) {
    // 0. 获取当前登录用户的信息
    MemberDetailDTO memberDetailDTO = memberFeignClient.getMemberInfo();
    // 1. 创建订单和订单详细条目
    OrderCreateInfo orderCreateInfo = createOrderInfo(memberDetailDTO, orderSubmitVo);
    // 2. 验证提交的价格和计算的价格是否一致
    if (orderSubmitVo.getTotalAmount().compareTo(orderCreateInfo.getPayPrice()) != 0) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError("价格计算异常"));
    }
    // 3. 订单与订单详细条目入库
    Order order = orderCreateInfo.getOrder();
    this.save(order);
    orderItemService.saveBatch(orderCreateInfo.getOrderItemList());
    // 4. 创建一个操作日志订单状态管理器,在订单状态流转到待付款状态时记录操作记录
    orderStateManager.create(order);
    // 5. 通知库存中心订单提交了,锁定库存中心的SKU库存
    OrderCreateInfoDTO orderRequestParam = orderCreateInfo.clone(OrderCreateInfoDTO.class);
    ResponseResult updateInventoryResult = inventoryFeignClient.notifySubmitOrderEvent(orderRequestParam);
    if (!updateInventoryResult.isOk()) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError("库存不足"));
    }
    // 6. 使用优惠券
    ResponseResult<Boolean> useCouponResult = promotionFeignClient.useCoupon(orderSubmitVo.getCouponId());
    if (!useCouponResult.isOk()) {
        log.error("优惠券使用失败:{}", useCouponResult.getMessage());
    }
    // 7. 发送Kafka消息到WMS中心进行处理
    // 7.1 通过商品的SKU ID查询到货位库存的明细条目,并进行遍历,一个SKU可能在多个货位上
    // 7.2 创建出需要拣货的条目和发货的条目并进行批量入库
    // 7.4 更新wms中心的库存
    OrderCreateInfoDTO orderCreateInfoDTO = new OrderCreateInfoDTO();
    BeanCopierUtils.copyProperties(orderCreateInfo, orderCreateInfoDTO);
    MQSender kafkaSender = mqSenderFactory.get(MQEnum.KAFKA);
    kafkaSender.send(MQConstants.SUBMIT_ORDER_QUEUE, JsonUtil.toJson(orderCreateInfoDTO));
    return order.getOrderSn();
}
Also used : Order(com.whoiszxl.entity.Order) MQSender(com.whoiszxl.mq.MQSender) OrderCreateInfoDTO(com.whoiszxl.dto.OrderCreateInfoDTO) OrderCreateInfo(com.whoiszxl.entity.vo.OrderCreateInfo) ResponseResult(com.whoiszxl.bean.ResponseResult) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with ResponseResult

use of com.whoiszxl.bean.ResponseResult in project shopzz by whoiszxl.

the class OrderServiceImpl method checkOrder.

/**
 * 校验订单
 * @param orderSubmitCommand 订单提交命令
 * @return
 */
private OrderCheckDTO checkOrder(OrderSubmitCommand orderSubmitCommand) {
    OrderCheckDTO orderCheckDTO = new OrderCheckDTO();
    // 1. 获取用户登录信息
    Long memberId = AuthUtils.getMemberId();
    // 2. 获取购物车中选中的sku信息
    CartDetailApiResponse cartDetail = cartService.getCartDetail();
    List<CartItemVO> cartItemList = cartDetail.getCartItemVOList();
    if (ObjectUtils.isEmpty(cartItemList)) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError("购物车不存在选中商品"));
    }
    List<Long> skuIds = cartItemList.stream().map(CartItemVO::getSkuId).collect(Collectors.toList());
    String feignParams = ParamUtils.array2Str(skuIds);
    ResponseResult<List<SkuFeignDTO>> skuListResult = productFeignClient.getSkuListBySkuIdList(feignParams);
    if (!skuListResult.isOk()) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError(skuListResult.getMessage()));
    }
    List<SkuFeignDTO> skuFeignDTOList = skuListResult.getData();
    // 2.1 校验订单中是否存在下架的SKU
    // 2.2 校验订单中的商品库存是否足够
    ResponseResult<List<SkuStockFeignDTO>> skuStockResult = productFeignClient.getStockBySkuIdList(feignParams);
    if (!skuStockResult.isOk()) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError(skuStockResult.getMessage()));
    }
    List<SkuStockFeignDTO> skuStockList = skuStockResult.getData();
    skuStockList.forEach(stock -> cartItemList.forEach(cartItemVO -> {
        if (stock.getSkuId().equals(cartItemVO.getSkuId())) {
            if (stock.getSaleStockQuantity() < cartItemVO.getQuantity()) {
                ExceptionCatcher.catchValidateEx(ResponseResult.buildError("返回刷新下吧,有SKU库存不够了"));
            }
        }
    }));
    BigDecimal serverFinalPrice = BigDecimal.ZERO;
    for (SkuFeignDTO skuFeignDTO : skuFeignDTOList) {
        for (CartItemVO cartItemVO : cartItemList) {
            if (skuFeignDTO.getId().equals(cartItemVO.getSkuId())) {
                serverFinalPrice = serverFinalPrice.add(skuFeignDTO.getPromotionPrice().multiply(new BigDecimal(cartItemVO.getQuantity())));
            }
        }
    }
    orderCheckDTO.setFinalPrice(serverFinalPrice);
    orderCheckDTO.setFinalDiscountPrice(serverFinalPrice);
    // 3. 已使用优惠券逻辑
    Long couponId = orderSubmitCommand.getCouponId();
    if (couponId != null) {
        // 3.1 校验优惠券是否有效
        ResponseResult<CouponFeignDTO> couponResult = promotionFeignClient.getCoupon(couponId);
        if (!couponResult.isOk()) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("优惠券无效"));
        }
        CouponFeignDTO couponDTO = couponResult.getData();
        LocalDateTime now = LocalDateTime.now();
        if (couponDTO.getStartTime().isBefore(now)) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("未到使用时间"));
        }
        if (couponDTO.getEndTime().isAfter(now)) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("优惠券已过期"));
        }
        // 3.2 校验是否领取过、使用过
        ResponseResult<Boolean> isUsedResponse = promotionFeignClient.checkCouponIsUsed(couponId);
        if (!isUsedResponse.isOk()) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("优惠券已领取过或使用过"));
        }
        // 3.3 校验订单是否满足使用阈值,如果是满减券或满减折扣券,并且是全场使用券,并且订单金额小于了使用阈值
        if ((couponDTO.getType().equals(CouponTypeEnum.FULL_DISCOUNT.getCode()) || couponDTO.getType().equals(CouponTypeEnum.FULL_RATE.getCode())) && couponDTO.getFullLimited().equals(CouponFullLimitedEnum.NOT_LIMIT.getCode()) && serverFinalPrice.compareTo(couponDTO.getUseThreshold()) < 0) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("未达到优惠券使用阈值"));
        }
        // 3.4 校验订单是否满足使用阈值,如果是满减券或满减折扣券,并且是限制类目使用券
        if ((couponDTO.getType().equals(CouponTypeEnum.FULL_DISCOUNT.getCode()) || couponDTO.getType().equals(CouponTypeEnum.FULL_RATE.getCode())) && couponDTO.getFullLimited().equals(CouponFullLimitedEnum.LIMIT.getCode())) {
            // 获取到优惠券能使用的分类
            List<Long> categoryIdList = couponDTO.getCategoryIdList();
            BigDecimal categoryPrice = BigDecimal.ZERO;
            for (SkuFeignDTO skuFeignDTO : skuFeignDTOList) {
                if (categoryIdList.contains(skuFeignDTO.getCategoryId())) {
                    CartItemVO cartItemVO = cartItemList.stream().filter(e -> e.getSkuId().equals(skuFeignDTO.getId())).findFirst().get();
                    BigDecimal skuPrice = skuFeignDTO.getPromotionPrice().multiply(new BigDecimal(cartItemVO.getQuantity()));
                    categoryPrice = categoryPrice.add(skuPrice);
                }
            }
            if (categoryPrice.compareTo(couponDTO.getUseThreshold()) < 0) {
                ExceptionCatcher.catchValidateEx(ResponseResult.buildError("未达到优惠券使用阈值"));
            }
        }
        // 4. 计算前端传入最终金额是否与服务端计算金额一致
        BigDecimal finalDiscountPrice = serverFinalPrice;
        if (CouponTypeEnum.FULL_DISCOUNT.getCode().equals(couponDTO.getType()) || CouponTypeEnum.UNLIMITED.getCode().equals(couponDTO.getType())) {
            // 满减和无门槛券直接减去折扣
            finalDiscountPrice = serverFinalPrice.subtract(couponDTO.getDiscountAmount());
            if (finalDiscountPrice.compareTo(orderSubmitCommand.getFinalPrice()) != 0) {
                ExceptionCatcher.catchValidateEx(ResponseResult.buildError("价格错误"));
            }
        }
        if (CouponTypeEnum.FULL_RATE.getCode().equals(couponDTO.getType())) {
            // 满减折扣直接乘以折扣比率
            finalDiscountPrice = serverFinalPrice.multiply(couponDTO.getDiscountRate());
            if (finalDiscountPrice.compareTo(orderSubmitCommand.getFinalPrice()) != 0) {
                ExceptionCatcher.catchValidateEx(ResponseResult.buildError("价格错误"));
            }
        }
        orderCheckDTO.setFinalDiscountPrice(finalDiscountPrice);
    }
    return orderCheckDTO;
}
Also used : ResponseResult(com.whoiszxl.bean.ResponseResult) CartService(com.whoiszxl.service.CartService) LocalDateTime(java.time.LocalDateTime) Autowired(org.springframework.beans.factory.annotation.Autowired) CartDetailApiResponse(com.whoiszxl.cqrs.response.CartDetailApiResponse) CouponFullLimitedEnum(com.whoiszxl.enums.promotion.CouponFullLimitedEnum) OrderService(com.whoiszxl.service.OrderService) LambdaQueryWrapper(com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper) CouponTypeEnum(com.whoiszxl.enums.promotion.CouponTypeEnum) ArrayList(java.util.ArrayList) OrderSubmitCommand(com.whoiszxl.cqrs.command.OrderSubmitCommand) OrderItem(com.whoiszxl.entity.OrderItem) PromotionFeignClient(com.whoiszxl.feign.PromotionFeignClient) BigDecimal(java.math.BigDecimal) ObjectUtils(org.apache.commons.lang3.ObjectUtils) Service(org.springframework.stereotype.Service) OrderItemService(com.whoiszxl.service.OrderItemService) LoggerOrderStateManager(com.whoiszxl.state.LoggerOrderStateManager) DcPayInfoService(com.whoiszxl.service.DcPayInfoService) OrderCreateInfoDTO(com.whoiszxl.cqrs.dto.OrderCreateInfoDTO) com.whoiszxl.dto(com.whoiszxl.dto) ServiceImpl(com.baomidou.mybatisplus.extension.service.impl.ServiceImpl) OrderCheckDTO(com.whoiszxl.cqrs.dto.OrderCheckDTO) DozerUtils(com.whoiszxl.dozer.DozerUtils) OrderMapper(com.whoiszxl.mapper.OrderMapper) PayInfoDc(com.whoiszxl.entity.PayInfoDc) com.whoiszxl.utils(com.whoiszxl.utils) CartItemVO(com.whoiszxl.cqrs.response.CartItemVO) MemberFeignClient(com.whoiszxl.feign.MemberFeignClient) OrderPayCommand(com.whoiszxl.cqrs.command.OrderPayCommand) Order(com.whoiszxl.entity.Order) OrderStatusConstants(com.whoiszxl.constants.OrderStatusConstants) Collectors(java.util.stream.Collectors) PayInfoDcBuilder(com.whoiszxl.entity.PayInfoDcBuilder) ProductFeignClient(com.whoiszxl.feign.ProductFeignClient) List(java.util.List) OrderPayTypeConstants(com.whoiszxl.constants.OrderPayTypeConstants) ExceptionCatcher(com.whoiszxl.exception.ExceptionCatcher) CreateDcAddressFactory(com.whoiszxl.factory.CreateDcAddressFactory) Transactional(org.springframework.transaction.annotation.Transactional) LocalDateTime(java.time.LocalDateTime) OrderCheckDTO(com.whoiszxl.cqrs.dto.OrderCheckDTO) BigDecimal(java.math.BigDecimal) CartItemVO(com.whoiszxl.cqrs.response.CartItemVO) CartDetailApiResponse(com.whoiszxl.cqrs.response.CartDetailApiResponse) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with ResponseResult

use of com.whoiszxl.bean.ResponseResult in project shopzz by whoiszxl.

the class OrderFeignClientImpl method notifyDcPaySuccess.

@Override
public ResponseResult<Boolean> notifyDcPaySuccess(List<Long> orderIds) {
    // 1. 更新订单到发货状态
    List<Order> orderList = orderIds.stream().map(orderId -> {
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(OrderStatusConstants.WAIT_FOR_DELIVERY);
        order.setUpdatedBy("system");
        return order;
    }).collect(Collectors.toList());
    boolean updateFlag = orderService.updateBatchById(orderList);
    for (Long orderId : orderIds) {
        OrderInfoDTO orderInfo = orderService.getOrderInfo(orderId);
        // 通知商品中心更新库存
        ResponseResult result = productFeignClient.paySuccessUpdateStock(orderInfo);
        if (!result.isOk()) {
            log.info("库存更新失败");
        }
    // TODO 通知WMS订单支付成功,更新WMS中心库存,WMS新增出库单
    // TODO 更新会员中心等级与积分
    }
    return ResponseResult.buildByFlag(updateFlag);
}
Also used : Order(com.whoiszxl.entity.Order) ResponseResult(com.whoiszxl.bean.ResponseResult) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Autowired(org.springframework.beans.factory.annotation.Autowired) OrderInfoDTO(com.whoiszxl.dto.OrderInfoDTO) Order(com.whoiszxl.entity.Order) OrderService(com.whoiszxl.service.OrderService) OrderStatusConstants(com.whoiszxl.constants.OrderStatusConstants) RestController(org.springframework.web.bind.annotation.RestController) Collectors(java.util.stream.Collectors) ResponseResult(com.whoiszxl.bean.ResponseResult) OrderInfoDTO(com.whoiszxl.dto.OrderInfoDTO)

Example 4 with ResponseResult

use of com.whoiszxl.bean.ResponseResult in project shopzz by whoiszxl.

the class ExceptionCatchAdvice method exception.

// 捕获Exception此类异常
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception exception) {
    // 记录日志
    log.error("全局异常捕捉:{}", exception);
    if (exceptions == null) {
        // EXCEPTIONS构建成功
        exceptions = builder.build();
    }
    // 从EXCEPTIONS中找异常类型所对应的错误代码,如果找到了将错误代码响应给用户,如果找不到给用户响应异常
    ResponseResult result = exceptions.get(exception.getClass());
    if (result != null) {
        return result;
    } else {
        // 返回报错
        return ResponseResult.buildError();
    }
}
Also used : ResponseResult(com.whoiszxl.bean.ResponseResult) ExceptionHandler(org.springframework.web.bind.annotation.ExceptionHandler) ResponseBody(org.springframework.web.bind.annotation.ResponseBody)

Example 5 with ResponseResult

use of com.whoiszxl.bean.ResponseResult in project shopzz by whoiszxl.

the class SSLogAspect method doAfterReturning.

/**
 * 返回通知
 *
 * @param ret
 * @throws Throwable
 */
@AfterReturning(returning = "ret", pointcut = "ssLogAspect()")
public void doAfterReturning(Object ret) {
    tryCatch((aaa) -> {
        ResponseResult r = Convert.convert(ResponseResult.class, ret);
        OptLogDTO sysLog = get();
        if (r == null) {
            sysLog.setType("OPT");
        } else {
            if (r.isOk()) {
                sysLog.setType("OPT");
            } else {
                sysLog.setType("EX");
                sysLog.setExDetail(r.getMessage());
            }
            sysLog.setResult(getText(r.toString()));
        }
        publishEvent(sysLog);
    });
}
Also used : ResponseResult(com.whoiszxl.bean.ResponseResult) OptLogDTO(com.whoiszxl.logger.entity.OptLogDTO)

Aggregations

ResponseResult (com.whoiszxl.bean.ResponseResult)7 Order (com.whoiszxl.entity.Order)4 List (java.util.List)4 OrderStatusConstants (com.whoiszxl.constants.OrderStatusConstants)3 OrderService (com.whoiszxl.service.OrderService)3 Collectors (java.util.stream.Collectors)3 Autowired (org.springframework.beans.factory.annotation.Autowired)3 OrderInfoDTO (com.whoiszxl.dto.OrderInfoDTO)2 Transactional (org.springframework.transaction.annotation.Transactional)2 LambdaQueryWrapper (com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper)1 ServiceImpl (com.baomidou.mybatisplus.extension.service.impl.ServiceImpl)1 OrderPayTypeConstants (com.whoiszxl.constants.OrderPayTypeConstants)1 OrderPayCommand (com.whoiszxl.cqrs.command.OrderPayCommand)1 OrderSubmitCommand (com.whoiszxl.cqrs.command.OrderSubmitCommand)1 OrderCheckDTO (com.whoiszxl.cqrs.dto.OrderCheckDTO)1 OrderCreateInfoDTO (com.whoiszxl.cqrs.dto.OrderCreateInfoDTO)1 CartDetailApiResponse (com.whoiszxl.cqrs.response.CartDetailApiResponse)1 CartItemVO (com.whoiszxl.cqrs.response.CartItemVO)1 DozerUtils (com.whoiszxl.dozer.DozerUtils)1 com.whoiszxl.dto (com.whoiszxl.dto)1