| package cc.mrbird.febs.mall.service.impl; | 
|   | 
| import cc.mrbird.febs.common.enumerates.*; | 
| import cc.mrbird.febs.common.exception.FebsException; | 
| import cc.mrbird.febs.common.utils.AppContants; | 
| import cc.mrbird.febs.common.utils.LoginUserUtil; | 
| import cc.mrbird.febs.common.utils.MallUtils; | 
| import cc.mrbird.febs.common.utils.RedisUtils; | 
| import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion; | 
| import cc.mrbird.febs.mall.conversion.MallOrderRefundConversion; | 
| import cc.mrbird.febs.mall.dto.*; | 
| import cc.mrbird.febs.mall.entity.*; | 
| import cc.mrbird.febs.mall.mapper.*; | 
| import cc.mrbird.febs.mall.service.IApiMallMemberService; | 
| import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; | 
| import cc.mrbird.febs.mall.service.IApiMallOrderInfoService; | 
| import cc.mrbird.febs.mall.service.MallMemberService; | 
| import cc.mrbird.febs.mall.vo.OrderDetailVo; | 
| import cc.mrbird.febs.mall.vo.OrderListVo; | 
| import cc.mrbird.febs.mall.vo.OrderRefundVo; | 
| import cc.mrbird.febs.pay.service.IPayService; | 
| import cc.mrbird.febs.rabbit.producter.AgentProducer; | 
| import cn.hutool.core.collection.CollUtil; | 
| import cn.hutool.core.date.DateUnit; | 
| import cn.hutool.core.date.DateUtil; | 
| import cn.hutool.core.util.StrUtil; | 
| import cn.hutool.crypto.SecureUtil; | 
| import com.baomidou.mybatisplus.core.metadata.IPage; | 
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | 
| import lombok.RequiredArgsConstructor; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.transaction.annotation.Transactional; | 
|   | 
| import java.math.BigDecimal; | 
| import java.text.SimpleDateFormat; | 
| import java.util.*; | 
|   | 
| /** | 
|  * @author wzy | 
|  * @date 2021-09-18 | 
|  **/ | 
| @Slf4j | 
| @Service | 
| @RequiredArgsConstructor | 
| public class ApiMallOrderInfoServiceImpl extends ServiceImpl<MallOrderInfoMapper, MallOrderInfo> implements IApiMallOrderInfoService { | 
|   | 
|     private final MallGoodsMapper mallGoodsMapper; | 
|     private final MallGoodsSkuMapper mallGoodsSkuMapper; | 
|     private final MallAddressInfoMapper mallAddressInfoMapper; | 
|     private final MallOrderItemMapper mallOrderItemMapper; | 
|     private final MallMemberMapper memberMapper; | 
|     private final IApiMallMemberWalletService memberWalletService; | 
|     private final MallExpressInfoMapper expressInfoMapper; | 
|     private final MallOrderRefundMapper mallOrderRefundMapper; | 
|     private final MallOrderRefundOperationMapper mallOrderRefundOperationMapper; | 
|     private final MallShoppingCartMapper mallShoppingCartMapper; | 
|     private final IApiMallMemberService memberService; | 
|     private final RedisUtils redisUtils; | 
|   | 
|     private final AgentProducer agentProducer; | 
|     private final IPayService payService; | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public Long createOrder(AddOrderDto addOrderDto) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|   | 
|         MallAddressInfo address = mallAddressInfoMapper.selectAddressInfoByMemberIdAndId(member.getId(), addOrderDto.getAddressId()); | 
|         if (address == null) { | 
|             throw new FebsException("地址不存在"); | 
|         } | 
|   | 
|         String orderNo = MallUtils.getOrderNum(); | 
|         MallOrderInfo orderInfo = new MallOrderInfo(); | 
|         orderInfo.setOrderNo(orderNo); | 
|         orderInfo.setOrderTime(new Date()); | 
|         orderInfo.setMemberId(member.getId()); | 
|         orderInfo.setStatus(OrderStatusEnum.WAIT_PAY.getValue()); | 
|         orderInfo.setName(address.getName()); | 
|         orderInfo.setAddress(address.getArea() + address.getAddress()); | 
|         orderInfo.setPhone(address.getPhone()); | 
|         orderInfo.setLatitude(address.getLatitude()); | 
|         orderInfo.setLongitude(address.getLongitude()); | 
|         orderInfo.setRemark(addOrderDto.getRemark()); | 
|   | 
|         if (CollUtil.isEmpty(addOrderDto.getItems())) { | 
|             throw new FebsException("参数错误"); | 
|         } | 
|   | 
|         this.baseMapper.insert(orderInfo); | 
|         BigDecimal total = BigDecimal.ZERO; | 
|         for (AddOrderItemDto item : addOrderDto.getItems()) { | 
|             MallGoodsSku sku = mallGoodsSkuMapper.selectSkuInfoById(item.getSkuId()); | 
|             if (sku == null) { | 
|                 throw new FebsException("购买商品或sku不存在"); | 
|             } | 
|   | 
|             if (sku.getStock() < item.getCnt()) { | 
|                 throw new FebsException(sku.getSkuName() + "库存不足"); | 
|             } | 
|   | 
|             MallGoods mallGoods = mallGoodsMapper.selectById(sku.getGoodsId()); | 
|             if (MallGoods.ISSALE_STATUS_DISABLED.equals(mallGoods.getIsSale())) { | 
|                 throw new FebsException(mallGoods.getGoodsName() + "已下架"); | 
|             } | 
|   | 
|             MallOrderItem orderItem = new MallOrderItem(); | 
|             BigDecimal amount = sku.getPresentPrice().multiply(BigDecimal.valueOf(item.getCnt())); | 
|             orderItem.setAmount(amount); | 
|             orderItem.setCnt(item.getCnt()); | 
|             orderItem.setOrderId(orderInfo.getId()); | 
|             orderItem.setPrice(sku.getPresentPrice()); | 
|             orderItem.setGoodsId(sku.getGoodsId()); | 
|             orderItem.setGoodsName(sku.getGoodsName()); | 
|             orderItem.setSkuId(sku.getId()); | 
|             orderItem.setStyleName(sku.getStyleName()); | 
|             orderItem.setSkuName(sku.getSkuName()); | 
|             orderItem.setSkuImage(sku.getSkuImage()); | 
|   | 
|             total = total.add(amount); | 
|             mallOrderItemMapper.insert(orderItem); | 
|   | 
|             sku.setStock(sku.getStock() - item.getCnt()); | 
|             sku.setSkuVolume(sku.getSkuVolume() + item.getCnt()); | 
|             mallGoodsSkuMapper.updateById(sku); | 
|   | 
|             if (addOrderDto.getType() == 1) { | 
|                 mallShoppingCartMapper.delBySkuId(sku.getId(), member.getId()); | 
|             } | 
|         } | 
|   | 
|         orderInfo.setAmount(total); | 
|         this.baseMapper.updateById(orderInfo); | 
|   | 
|         agentProducer.sendOrderCancelDelayMsg(orderInfo.getId(), 15 * 60 * 1000L); | 
|         return orderInfo.getId(); | 
|     } | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public void cancelOrder(Long id) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         MallOrderInfo orderInfo = this.baseMapper.selectOrderByMemberIdAndId(member.getId(), id); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         if (OrderStatusEnum.WAIT_PAY.getValue() != orderInfo.getStatus()) { | 
|             throw new FebsException("订单不是待付款, 无法取消"); | 
|         } | 
|   | 
|         orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); | 
|         orderInfo.setCancelType(MallOrderInfo.CANCEL_BY_SELF); | 
|         this.baseMapper.updateById(orderInfo); | 
|     } | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public Map<String, Object> payOrder(PayOrderDto payOrderDto) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         MallOrderInfo orderInfo = this.baseMapper.selectOrderByMemberIdAndId(member.getId(), payOrderDto.getId()); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         if (OrderStatusEnum.WAIT_PAY.getValue() != orderInfo.getStatus()) { | 
|             throw new FebsException("订单状态不能支付"); | 
|         } | 
|   | 
|         String payResultStr = ""; | 
|         switch (payOrderDto.getType()) { | 
|             case "1": | 
| //                orderInfo.setPayOrderNo(payOrderDto.getPayOrderNo()); | 
| //                orderInfo.setPayImage(payOrderDto.getPayImage()); | 
|                 orderInfo.setPayMethod("微信支付"); | 
|                 break; | 
|             case "2": | 
|                 if (StrUtil.isNotBlank(orderInfo.getPayOrderNo())) { | 
|                     payResultStr = orderInfo.getPayOrderNo(); | 
|                 } else { | 
|                     payResultStr = payService.aliPay(orderInfo); | 
|                 } | 
|   | 
|                 orderInfo.setPayOrderNo(payResultStr); | 
|                 orderInfo.setPayMethod("支付宝支付"); | 
|                 break; | 
|             case "3": | 
|                 payResultStr = balancePay(orderInfo, payOrderDto.getTradePwd()); | 
|   | 
|                 orderInfo.setPayOrderNo(orderInfo.getOrderNo()); | 
|                 orderInfo.setPayMethod("余额支付"); | 
|                 orderInfo.setStatus(OrderStatusEnum.WAIT_SHIPPING.getValue()); | 
|                 orderInfo.setPayTime(new Date()); | 
|                 orderInfo.setPayResult("1"); | 
|   | 
| //                MallMember mallMember = memberMapper.selectById(member.getId()); | 
| //                if (AgentLevelEnum.ZERO_LEVEL.name().equals(mallMember.getLevel())) { | 
| //                    mallMember.setLevel(AgentLevelEnum.FIRST_LEVEL.name()); | 
| //                    memberMapper.updateById(mallMember); | 
| //                } | 
|   | 
|                 // 静态倍数 | 
|                 List<MallOrderItem> orderItems = this.baseMapper.getMallOrderItemByOrderId(orderInfo.getId()); | 
|                 if (CollUtil.isNotEmpty(orderItems)) { | 
|                     for (MallOrderItem orderItem : orderItems) { | 
|                         MallGoods mallGoods = mallGoodsMapper.selectById(orderItem.getGoodsId()); | 
|   | 
|                         MallGoodsSku sku = mallGoodsSkuMapper.selectById(orderItem.getSkuId()); | 
|                         BigDecimal score = sku.getOriginalPrice().multiply(mallGoods.getStaticMultiple()); | 
|   | 
|                         memberWalletService.add(score, member.getId(), "score"); | 
|                         memberService.addMoneyFlow(member.getId(), score, MoneyFlowTypeEnum.STATIC_BONUS.getValue(), orderInfo.getOrderNo(), null, null, null, null, FlowTypeEnum.SCORE.getValue()); | 
|                     } | 
|                 } | 
|   | 
|                 memberService.addMoneyFlow(member.getId(), orderInfo.getAmount().negate(), MoneyFlowTypeEnum.PAY.getValue(), orderInfo.getOrderNo(), null, null, null, null, FlowTypeEnum.BALANCE.getValue()); | 
| //                agentProducer.sendAutoLevelUpMsg(member.getId()); | 
| //                agentProducer.sendReturnMoneyMsg(orderInfo.getId()); | 
|   | 
|             default: | 
|   | 
|         } | 
|   | 
|         this.baseMapper.updateById(orderInfo); | 
|   | 
|         Map<String, Object> map = new HashMap<>(); | 
|         map.put("orderInfo", payResultStr); | 
|         map.put("orderNo", orderInfo.getOrderNo()); | 
|         map.put("orderId", orderInfo.getId()); | 
|   | 
|         return map; | 
|     } | 
|   | 
|     private String balancePay(MallOrderInfo orderInfo, String tradePwd) { | 
|         if (StrUtil.isBlank(tradePwd)) { | 
|             throw new FebsException("支付密码错误"); | 
|         } | 
|   | 
|         MallMember mallMember = memberMapper.selectById(orderInfo.getMemberId()); | 
|   | 
|         if (StrUtil.isBlank(mallMember.getTradePassword())) { | 
|             throw new FebsException("未设置支付密码"); | 
|         } | 
|   | 
|         if (!SecureUtil.md5(tradePwd).equals(mallMember.getTradePassword())) { | 
|             throw new FebsException("支付密码错误"); | 
|         } | 
|   | 
|         memberWalletService.reduce(orderInfo.getAmount(), mallMember.getId(), "balance"); | 
|   | 
|         return orderInfo.getOrderNo(); | 
|     } | 
|   | 
|   | 
|     @Override | 
|     public List<OrderListVo> findOrderList(OrderListDto orderListDto) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         IPage<MallOrderInfo> page = new Page<>(orderListDto.getPageNum(), orderListDto.getPageSize()); | 
|   | 
|         orderListDto.setMemberId(member.getId()); | 
|         IPage<MallOrderInfo> mallOrderInfos = this.baseMapper.selectApiOrderListInPage(page, orderListDto); | 
|         return MallOrderInfoConversion.INSTANCE.entitysToVos(mallOrderInfos.getRecords()); | 
|     } | 
|   | 
|     @Override | 
|     public OrderDetailVo findOrderDetailsById(Long id) { | 
|         MallOrderInfo orderInfo = this.baseMapper.selectOrderDetailsById(id); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         OrderDetailVo orderDetailVo = MallOrderInfoConversion.INSTANCE.entityToDetailVo(orderInfo); | 
|   | 
|         if (orderInfo.getStatus() == OrderStatusEnum.WAIT_FINISH.getValue()) { | 
|             MallExpressInfo expressInfo = expressInfoMapper.selectByOrderId(orderInfo.getId()); | 
|             orderDetailVo.setExpressNo(expressInfo.getExpressNo()); | 
|             orderDetailVo.setExpressCom(expressInfo.getExpressCom()); | 
|         } | 
|   | 
|         if (orderInfo.getStatus() == OrderStatusEnum.REFUNDING.getValue() || orderInfo.getStatus() == OrderStatusEnum.REFUNDED.getValue()) { | 
|             MallOrderRefund orderRefund = mallOrderRefundMapper.selectOrderRefundByOrderId(orderInfo.getId()); | 
|             OrderRefundVo orderRefundVo = MallOrderRefundConversion.INSTANCE.entityToVo(orderRefund); | 
|             orderDetailVo.setOrderRefund(orderRefundVo); | 
|         } | 
|   | 
|         if (OrderStatusEnum.WAIT_PAY.getValue() == orderInfo.getStatus()) { | 
|             Date endTime = DateUtil.offsetMinute(orderInfo.getOrderTime(), 15); | 
|   | 
|             long remainTime = DateUtil.between(new Date(), endTime, DateUnit.SECOND, false); | 
|             orderDetailVo.setRemainTime(remainTime); | 
|         } | 
|         return orderDetailVo; | 
|     } | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public void confirmOrder(Long id) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         MallOrderInfo orderInfo = this.baseMapper.selectOrderByMemberIdAndId(member.getId(), id); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         if (orderInfo.getStatus() != OrderStatusEnum.WAIT_FINISH.getValue()) { | 
|             throw new FebsException("该状态不能确认收货"); | 
|         } | 
|   | 
|         orderInfo.setStatus(OrderStatusEnum.FINISH.getValue()); | 
|         orderInfo.setReceivingTime(new Date()); | 
|         this.baseMapper.updateById(orderInfo); | 
|     } | 
|   | 
|     @Override | 
|     public void delOrder(Long id) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         MallOrderInfo orderInfo = this.baseMapper.selectOrderByMemberIdAndId(member.getId(), id); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         orderInfo.setDelFlag(AppContants.DEL_FLAG_Y); | 
|         this.baseMapper.updateById(orderInfo); | 
|     } | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public void applyRefund(AddRefundDto addRefundDto) { | 
|         MallOrderInfo orderInfo = this.baseMapper.selectById(addRefundDto.getId()); | 
|         if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { | 
|             throw new FebsException("订单不存在"); | 
|         } | 
|   | 
|         if (orderInfo.getStatus() == OrderStatusEnum.REFUNDING.getValue()) { | 
|             throw new FebsException("已提交退款, 请勿重复提交"); | 
|         } | 
|   | 
|         if (orderInfo.getStatus() != OrderStatusEnum.WAIT_SHIPPING.getValue() && orderInfo.getStatus() != OrderStatusEnum.WAIT_FINISH.getValue()) { | 
|             throw new FebsException("该订单不能退款"); | 
|         } | 
|   | 
|         Integer beforeStatus = orderInfo.getStatus(); | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|         orderInfo.setStatus(OrderStatusEnum.REFUNDING.getValue()); | 
|         this.baseMapper.updateById(orderInfo); | 
|   | 
|         MallOrderRefund orderRefund = mallOrderRefundMapper.selectOrderRefundByOrderId(orderInfo.getId()); | 
|         if (orderRefund == null) { | 
|             orderRefund = new MallOrderRefund(); | 
|             orderRefund.setOrderId(orderInfo.getId()); | 
|             orderRefund.setMemberId(member.getId()); | 
|             orderRefund.setDesp(addRefundDto.getDesp()); | 
|             orderRefund.setReason(addRefundDto.getReason()); | 
|             orderRefund.setType(addRefundDto.getType()); | 
|             orderRefund.setRefundTime(new Date()); | 
|             orderRefund.setBeforeStatus(beforeStatus); | 
|             orderRefund.setStatus(OrderRefundStatusEnum.REFUND_APPLY.getValue()); | 
|             mallOrderRefundMapper.insert(orderRefund); | 
|         } else { | 
|             orderRefund.setDesp(addRefundDto.getDesp()); | 
|             orderRefund.setReason(addRefundDto.getReason()); | 
|             orderRefund.setType(addRefundDto.getType()); | 
|             orderRefund.setRefundTime(new Date()); | 
|             orderRefund.setBeforeStatus(beforeStatus); | 
|             orderRefund.setStatus(OrderRefundStatusEnum.REFUND_APPLY.getValue()); | 
|             mallOrderRefundMapper.updateById(orderRefund); | 
|         } | 
|   | 
|   | 
|         MallOrderRefundOperation operation = new MallOrderRefundOperation(); | 
|         operation.setOrderId(orderInfo.getId()); | 
|         operation.setRefundId(orderRefund.getId()); | 
|         operation.setContent(StrUtil.format("用户:{}提交退款申请", member.getName())); | 
|         mallOrderRefundOperationMapper.insert(operation); | 
|     } | 
|   | 
|     @Override | 
|     public void refundExpress(RefundExpressDto refundExpressDto) { | 
|         MallMember member = LoginUserUtil.getLoginUser(); | 
|   | 
|         MallOrderRefund orderRefund = mallOrderRefundMapper.selectOrderRefundByOrderId(refundExpressDto.getId()); | 
|         if (!OrderRefundStatusEnum.AGREE.getValue().equals(orderRefund.getStatus())) { | 
|             throw new FebsException("暂不能提交物流信息"); | 
|         } | 
|   | 
|         orderRefund.setExpressNo(refundExpressDto.getExpressNo()); | 
|         orderRefund.setExpressCom(refundExpressDto.getExpressCom()); | 
|         orderRefund.setStatus(OrderRefundStatusEnum.EXPRESS_SUBMIT.getValue()); | 
|         mallOrderRefundMapper.updateById(orderRefund); | 
|   | 
|         MallOrderRefundOperation operation = new MallOrderRefundOperation(); | 
|         operation.setOrderId(refundExpressDto.getId()); | 
|         operation.setRefundId(orderRefund.getId()); | 
|         operation.setContent(StrUtil.format("用户:{}提交物流信息,快递公司:{},单号:{}", member.getName(), refundExpressDto.getExpressCom(), refundExpressDto.getExpressNo())); | 
|         mallOrderRefundOperationMapper.insert(operation); | 
|     } | 
|   | 
|     @Override | 
|     public void autoCancelOrder(Long id) { | 
|         MallOrderInfo orderInfo = this.baseMapper.selectById(id); | 
|         if (orderInfo == null) { | 
|             log.error("自动取消订单参数错误:{}", id); | 
|             return; | 
|         } | 
|         if (orderInfo.getStatus() == OrderStatusEnum.WAIT_PAY.getValue()) { | 
|             log.info("自动取消订单:{},{}", orderInfo.getMemberId(), id); | 
|             orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); | 
|             orderInfo.setCancelType(MallOrderInfo.CANCEL_OVERTIME_NO_PAY); | 
|             this.baseMapper.updateById(orderInfo); | 
|         } | 
|     } | 
| } |