package com.bonus.canteen.core.order.mobile.business.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.common.constant.OrderConstant;
import com.bonus.canteen.core.common.redis.RedisUtil;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.order.common.constants.*;
import com.bonus.canteen.core.order.common.service.OrderAmountChangeService;
import com.bonus.canteen.core.order.common.service.OrderDeliveryService;
import com.bonus.canteen.core.order.common.service.OrderDetailService;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.common.houqin.constant.RetCodeEnum;
import com.bonus.canteen.core.account.v3.api.AccPayBusinessApi;
import com.bonus.canteen.core.allocation.api.AllocCanteenApi;
import com.bonus.canteen.core.allocation.api.AllocHolidayApi;
import com.bonus.canteen.core.allocation.api.AllocStallApi;
import com.bonus.canteen.core.allocation.canteen.dto.AllocCanteenOrderDTO;
import com.bonus.canteen.core.common.enums.DeliveryTypeEnum;
import com.bonus.canteen.core.common.enums.MetadataModelTypeEnum;
import com.bonus.canteen.core.common.enums.SourceTypeEnum;
import com.bonus.canteen.core.common.utils.AesEncryptUtil;
import com.bonus.canteen.core.common.utils.JavaxValidateUtils;
import com.bonus.canteen.core.common.utils.LogUtil;
import com.bonus.canteen.core.customer.vo.CustPayVO;
import com.bonus.canteen.core.device.api.DeviceApi;
import com.bonus.canteen.core.menu.model.AllocMealtimeModel;
import com.bonus.canteen.core.order.client.OrderModuleClient;
import com.bonus.canteen.core.order.client.po.CustPayInfoQueryParam;
import com.bonus.canteen.core.order.client.po.MetaDataValueParam;
import com.bonus.canteen.core.order.client.po.OrderConfigQueryParam;
import com.bonus.canteen.core.order.common.business.OrderPlaceBusiness;
import com.bonus.canteen.core.order.common.business.OrderResultBusiness;
import com.bonus.canteen.core.order.common.dto.OrderDetailPayDTO;
import com.bonus.canteen.core.order.common.dto.RequestHeaderDTO;
import com.bonus.canteen.core.order.common.model.OrderAmountChange;
import com.bonus.canteen.core.order.common.model.OrderDelivery;
import com.bonus.canteen.core.order.common.model.OrderDetail;
import com.bonus.canteen.core.order.common.model.OrderInfo;
import com.bonus.canteen.core.order.common.service.OrderInfoService;
import com.bonus.canteen.core.order.common.vo.OrderDeliveryResultVO;
import com.bonus.canteen.core.order.custom.OrderCustomBusiness;
import com.bonus.canteen.core.order.custom.po.OrderCustomMobileCheckRepeatPO;
import com.bonus.canteen.core.order.custom.po.OrderCustomMobileCustInfoPO;
import com.bonus.canteen.core.order.mobile.business.OrderPlaceMobileBusiness;
import com.bonus.canteen.core.order.mobile.dto.*;
import com.bonus.canteen.core.order.mobile.service.ShoppingCartBusiness;
import com.bonus.canteen.core.order.mobile.vo.OrderAmountChangeVO;
import com.bonus.canteen.core.order.mobile.vo.OrderListPayMobileVO;
import com.bonus.canteen.core.order.mobile.vo.OrderPayMobileVO;
import com.bonus.canteen.core.order.mq.OrderMessageSend;
import com.bonus.canteen.core.order.mq.constants.OrderMQConstants;
import com.bonus.canteen.core.order.mq.po.OrderSavePO;
import com.bonus.canteen.core.order.utils.LeNumUtil;
import com.bonus.canteen.core.pay.api.PayApi;
import com.bonus.canteen.core.pay.api.TradeRecordApi;
import com.bonus.canteen.core.pay.api.dto.UnifyPayDTO;
import com.bonus.canteen.core.pay.api.vo.UnifyPayVO;
import com.bonus.canteen.core.pay.common.constants.PayChannelSelectEnum;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;
import com.bonus.canteen.core.pay.common.constants.TradeTypeEnum;
import com.bonus.canteen.core.pay.common.po.PayResultPO;
import com.bonus.canteen.core.pay.common.vo.PayChannelSelectDTO;
import com.bonus.canteen.core.pay.common.vo.PayChannelSelectResultVO;
import com.bonus.canteen.core.supermarket.api.SupermarketApi;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.id.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderPlaceMobileBusinessImplV3 implements OrderPlaceMobileBusiness {
   private static final Logger log = LoggerFactory.getLogger(OrderPlaceMobileBusinessImplV3.class);
   @Autowired
   @Lazy
   protected OrderCustomBusiness orderCustomBusiness;
   @Autowired
   @Lazy
   protected OrderPlaceBusiness orderPlaceBusiness;
   @Autowired
   @Lazy
   protected OrderResultBusiness orderResultBusiness;
   @Autowired
   @Lazy
   protected OrderInfoService orderInfoService;
   @Autowired
   @Lazy
   protected OrderDetailService orderDetailService;
   @Autowired
   @Lazy
   protected OrderAmountChangeService orderAmountChangeService;
   @Autowired
   @Lazy
   protected OrderDeliveryService orderDeliveryService;
   //   @Autowired
//   @Lazy
//   protected OrderPreBookService orderPreBookService;
   @Autowired
   @Lazy
   protected ShoppingCartBusiness shoppingCartBusiness;
   @Autowired
   @Lazy
   protected OrderModuleClient orderModuleClient;
   @Autowired
   @Lazy
   protected AllocCanteenApi allocCanteenApi;
   @Autowired
   @Lazy
   protected AllocStallApi allocStallApi;
   @Autowired
   @Lazy
   protected DeviceApi deviceApi;
   @Autowired
   @Lazy
   protected PayApi payApi;
   @Autowired
   @Lazy
   protected TradeRecordApi tradeRecordApi;
   @Autowired
   @Lazy
   protected SupermarketApi supermarketApi;
   @Autowired
   @Lazy
   protected AesEncryptUtil aesEncryptUtil;
   @Autowired
   @Lazy
   protected AccPayBusinessApi accPayBusinessApi;
   @Lazy
   @Autowired
   private AllocHolidayApi allocHolidayApi;
   @Autowired
   private ConnectionFactory connectionFactory;

//   public OrderPayMobileVO addCurrentMealOrder(RequestHeaderDTO headerDTO, OrderCurrMealTotalDTO currMealTotalDTO) {
//      LogUtil.info("当餐点餐|入参", currMealTotalDTO);
//      JavaxValidateUtils.validate(currMealTotalDTO);
//      CustPayVO custInfo = this.getCustInfo(currMealTotalDTO.getCustId(), headerDTO.getSourceType());
//      if (!LeConstants.COMMON_YES.equals(currMealTotalDTO.getIfTrial())) {
//         this.checkOrderRepeated(headerDTO.getOpenid(), custInfo.getCustId());
//      }
//
//      UnifyPayDTO payDTO = this.createPay(currMealTotalDTO.getPayType(), currMealTotalDTO.getCouponId(), headerDTO.getSourceType(), (Long)LeNumUtil.reduceField(currMealTotalDTO.getCurrMealList(), OrderCurrMealDTO::getCanteenId, (Object)null), (Long)LeNumUtil.reduceField(currMealTotalDTO.getCurrMealList(), OrderCurrMealDTO::getStallId, (Object)null), headerDTO.getOpenid(), custInfo, currMealTotalDTO);
//      OrderSavePO orderSavePO = this.packageOrderInfo(currMealTotalDTO, currMealTotalDTO.getCurrMealList(), payDTO);
//      this.currentMealOrderPlaceCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (LeConstants.COMMON_NO.equals(currMealTotalDTO.getIfTrial())) {
//         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
//      }
//
//      this.orderPlaceBusiness.checkWaitPlaceOrder(orderSavePO.getOrderInfoList());
//      this.orderPlaceBusiness.checkOrderPermission(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      this.orderPlaceBusiness.fillOrderDetailPrice(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      OrderDeliveryResultVO orderDeliveryResultVO = this.orderPlaceBusiness.fillOrderDeliveryAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (!LeConstants.COMMON_YES.equals(currMealTotalDTO.getIfTrial()) && !orderDeliveryResultVO.ifSuccess()) {
//         throw new LeException(orderDeliveryResultVO.getCode(), orderDeliveryResultVO.getMsg());
//      } else {
//         List<OrderAmountChange> amountChangeList = this.orderPlaceBusiness.calcNeedPayAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//         orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
//         List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(currMealTotalDTO.getIfTrial()));
//         amountChangeList.addAll(amountChangeListRole);
//         this.orderPlaceBusiness.checkCoupon(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList());
//         orderSavePO.setAmountChangeList(amountChangeList);
//         return LeConstants.COMMON_YES.equals(currMealTotalDTO.getIfTrial()) ? this.trialPay(orderSavePO, orderDeliveryResultVO) : this.saveAndPay(orderSavePO, true, false);
//      }
//   }

   public boolean isRabbitMqAvailable() {
      String mqResultKey = "yst:" + TenantContextHolder.getTenantId() + ":order:reserve:checkMQResult";
      String redisValue = RedisUtil.getString(mqResultKey);
      LogUtil.info("MQ检测结果，redis值 : ", redisValue);
      if (redisValue != null) {
         return "1".equals(redisValue);
      }
      String lockKey = "yst:" + TenantContextHolder.getTenantId() + ":order:reserve:checkMQ";
      long timeOut = 5 * 60;
      Connection connection = null;
      try {
         if (!RedisUtil.tryLock(lockKey, 10, 15)) {
            throw new ServiceException("系统异常，请联系管理员");
         }
         redisValue = RedisUtil.getString(mqResultKey);
         LogUtil.info("MQ二次检测结果，redis值 : ", redisValue);
         if (redisValue != null) {
            return "1".equals(redisValue);
         }
         connection = connectionFactory.createConnection();
         boolean isConnected = connection.isOpen();
         RedisUtil.setString(mqResultKey, isConnected ? "1" : "0", timeOut);
         LogUtil.info("MQ连接检测结果 : ", isConnected ?  "正常" : "异常");
         return isConnected;
      } catch (Exception e) {
         LogUtil.info("RabbitMQ 连接检测异常：" + e);
         RedisUtil.setString(mqResultKey, "0", timeOut);
         return false;
      }finally {
         RedisUtil.safeUnLock(lockKey);
         if(Objects.nonNull(connection)) {
            try {
               connection.close();
            } catch (Exception ex) {
               LogUtil.info("关闭 RabbitMQ 连接异常", ex);
            }
         }
      }
   }

   public OrderPayMobileVO addReserveMealOrder(RequestHeaderDTO headerDTO, OrderReserveMealTotalDTO reserveMealDTO) {
      LogUtil.info("预定餐点餐|入参", reserveMealDTO);
      if(!isRabbitMqAvailable()) {
         throw new ServiceException("系统异常，请联系管理员");
      }
      JavaxValidateUtils.validate(reserveMealDTO);
      CustPayVO custInfo = this.getCustInfo(reserveMealDTO.getCustId(), headerDTO.getSourceType());
      if (!LeConstants.COMMON_YES.equals(reserveMealDTO.getIfTrial())) {
         this.checkOrderRepeated(headerDTO.getOpenid(), custInfo.getCustId());
      }

      UnifyPayDTO payDTO = this.createPay(reserveMealDTO.getPayType(), reserveMealDTO.getCouponId(), headerDTO.getSourceType()
              , (Long) LeNumUtil.reduceField(reserveMealDTO.getReserveMealList(), OrderReserveMealDTO::getCanteenId
                      , (Object)null), (Long)LeNumUtil.reduceField(reserveMealDTO.getReserveMealList()
                      , OrderReserveMealDTO::getStallId, (Object)null), headerDTO.getOpenid(), custInfo, reserveMealDTO);

      OrderSavePO orderSavePO = this.packageOrderInfo(reserveMealDTO, reserveMealDTO.getReserveMealList(), payDTO);
      this.reserveMealOrderPlaceCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList()
              , orderSavePO.getOrderDeliveryList());

      if (LeConstants.COMMON_NO.equals(reserveMealDTO.getIfTrial())) {
         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
      }

      this.orderPlaceBusiness.checkWaitPlaceOrder(orderSavePO.getOrderInfoList());
      this.orderPlaceBusiness.checkOrderPermission(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
      this.orderPlaceBusiness.fillOrderDetailPrice(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
      OrderDeliveryResultVO orderDeliveryResultVO = this.orderPlaceBusiness.fillOrderDeliveryAmount(orderSavePO.getOrderInfoList()
              , orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
      if (!LeConstants.COMMON_YES.equals(reserveMealDTO.getIfTrial()) && !orderDeliveryResultVO.ifSuccess()) {
         throw new ServiceException(orderDeliveryResultVO.getMsg(), orderDeliveryResultVO.getCode());
      } else {
         List<OrderAmountChange> amountChangeList = this.orderPlaceBusiness.calcNeedPayAmount(orderSavePO.getOrderInfoList()
                 , orderSavePO.getOrderDetailList());
         orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount)
                 .reduce(BigDecimal.ZERO, BigDecimal::add));
         List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO()
                 , orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(reserveMealDTO.getIfTrial()));
         amountChangeList.addAll(amountChangeListRole);
         this.orderPlaceBusiness.checkCoupon(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList());
         orderSavePO.setAmountChangeList(amountChangeList);
         return LeConstants.COMMON_YES.equals(reserveMealDTO.getIfTrial()) ? this.trialPay(orderSavePO, orderDeliveryResultVO)
                 : this.saveAndPay(orderSavePO, true, false);
      }
   }

//   public OrderPayMobileVO addBookMealOrder(RequestHeaderDTO headerDTO, OrderBookMealTotalDTO bookMealDTO) {
//      LogUtil.info("报餐点餐|入参", bookMealDTO);
//      JavaxValidateUtils.validate(bookMealDTO);
//      CustPayVO custInfo = this.getCustInfo(bookMealDTO.getCustId(), headerDTO.getSourceType());
//      if (!LeConstants.COMMON_YES.equals(bookMealDTO.getIfTrial())) {
//         this.checkOrderRepeated(headerDTO.getOpenid(), custInfo.getCustId());
//      }
//
//      UnifyPayDTO payDTO = this.createPay(bookMealDTO.getPayType(), bookMealDTO.getCouponId(), headerDTO.getSourceType(), (Long)LeNumUtil.reduceField(bookMealDTO.getBookMealList(), OrderBookMealDTO::getCanteenId, (Object)null), (Long)LeNumUtil.reduceField(bookMealDTO.getBookMealList(), OrderBookMealDTO::getStallId, (Object)null), headerDTO.getOpenid(), custInfo, bookMealDTO);
//      OrderSavePO orderSavePO = this.packageOrderInfo(bookMealDTO, bookMealDTO.getBookMealList(), payDTO);
//      this.bookMealOrderPlaceCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (LeConstants.COMMON_NO.equals(bookMealDTO.getIfTrial())) {
//         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
//      }
//
//      this.orderPlaceBusiness.checkWaitPlaceOrder(orderSavePO.getOrderInfoList());
//      this.orderPlaceBusiness.checkOrderPermission(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      this.orderPlaceBusiness.fillOrderDetailPrice(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      List<OrderAmountChange> amountChangeList = this.orderPlaceBusiness.calcNeedPayAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
//      List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(bookMealDTO.getIfTrial()));
//      amountChangeList.addAll(amountChangeListRole);
//      this.orderPlaceBusiness.checkCoupon(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList());
//      orderSavePO.setAmountChangeList(amountChangeList);
//      return LeConstants.COMMON_YES.equals(bookMealDTO.getIfTrial()) ? this.trialPay(orderSavePO, (OrderDeliveryResultVO)null) : this.saveAndPay(orderSavePO, false, false);
//   }
//
//   public OrderPayMobileVO addShopMealOrder(RequestHeaderDTO headerDTO, OrderShopDTO orderShopDTO) {
//      LogUtil.info("超市下单|入参", orderShopDTO);
//      JavaxValidateUtils.validate(orderShopDTO);
//      CustPayVO custInfo = this.getCustInfo(orderShopDTO.getCustId(), headerDTO.getSourceType());
//      if (!LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial())) {
//         this.checkOrderRepeated(headerDTO.getOpenid(), custInfo.getCustId());
//      }
//
//      UnifyPayDTO payDTO = this.createPay(orderShopDTO.getPayType(), orderShopDTO.getCouponId(), headerDTO.getSourceType(), orderShopDTO.getCanteenId(), (Long)null, headerDTO.getOpenid(), custInfo, orderShopDTO);
//      OrderSavePO orderSavePO = this.packageOrderInfo(orderShopDTO, CollUtil.toList(new OrderShopDTO[]{orderShopDTO}), payDTO);
//      this.shopOrderPlaceCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (LeConstants.COMMON_NO.equals(orderShopDTO.getIfTrial())) {
//         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
//      }
//
//      this.orderPlaceBusiness.checkWaitPlaceOrder(orderSavePO.getOrderInfoList());
//      this.orderPlaceBusiness.checkOrderPermission(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      this.orderPlaceBusiness.fillOrderDetailPrice(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      OrderDeliveryResultVO orderDeliveryResultVO = this.orderPlaceBusiness.fillOrderDeliveryAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (!LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial()) && !orderDeliveryResultVO.ifSuccess()) {
//         throw new LeException(orderDeliveryResultVO.getCode(), orderDeliveryResultVO.getMsg());
//      } else {
//         List<OrderAmountChange> amountChangeList = this.orderPlaceBusiness.calcNeedPayAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//         orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
//         List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial()));
//         amountChangeList.addAll(amountChangeListRole);
//         orderSavePO.setAmountChangeList(amountChangeList);
//         return LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial()) ? this.trialPay(orderSavePO, orderDeliveryResultVO) : this.saveAndPay(orderSavePO, true, false);
//      }
//   }
//
//   public OrderPayMobileVO addSacnOrder(RequestHeaderDTO headerDTO, OrderMobileScanDTO orderShopDTO) {
//      LogUtil.info("到店扫码下单|入参", orderShopDTO);
//      JavaxValidateUtils.validate(orderShopDTO);
//      CustPayVO custInfo = this.getCustInfo(orderShopDTO.getCustId(), headerDTO.getSourceType());
//      if (!LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial())) {
//         this.checkOrderRepeated(headerDTO.getOpenid(), custInfo.getCustId());
//      }
//
//      UnifyPayDTO payDTO = this.createPay(orderShopDTO.getPayType(), orderShopDTO.getCouponId(), headerDTO.getSourceType(), orderShopDTO.getCanteenId(), (Long)null, headerDTO.getOpenid(), custInfo, orderShopDTO);
//      OrderSavePO orderSavePO = this.packageOrderInfo(orderShopDTO, CollUtil.toList(new OrderMobileScanDTO[]{orderShopDTO}), payDTO);
//      this.scanOrderPlaceCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//      if (LeConstants.COMMON_NO.equals(orderShopDTO.getIfTrial())) {
//         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
//      }
//
//      this.orderPlaceBusiness.checkOrderPermission(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      this.orderPlaceBusiness.fillOrderDetailPrice(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      List<OrderAmountChange> amountChangeList = this.orderPlaceBusiness.calcNeedPayAmount(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
//      orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
//      List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial()));
//      amountChangeList.addAll(amountChangeListRole);
//      orderSavePO.setAmountChangeList(amountChangeList);
//      return LeConstants.COMMON_YES.equals(orderShopDTO.getIfTrial()) ? this.trialPay(orderSavePO, (OrderDeliveryResultVO)null) : this.saveAndPay(orderSavePO, true, false);
//   }

   public OrderPayMobileVO orderPayByOrderId(RequestHeaderDTO headerDTO, OrderPayMobileDTO orderPayDTO) {
      LogUtil.info("订单支付|入参", orderPayDTO);
      JavaxValidateUtils.validate(orderPayDTO);
      if (!LeConstants.COMMON_YES.equals(orderPayDTO.getIfTrial())) {
         this.checkOrderRepeated(headerDTO.getOpenid(), (Long)null);
      }

      OrderInfo orderInfo = this.orderInfoService.checkAndGetOrderInfo(orderPayDTO.getOrderId());
      OrderSavePO orderSavePO = OrderSavePO.byOrderInfo(CollUtil.toList(orderInfo),
              this.orderDetailService.getOrderDetailList(orderInfo.getOrderId(), orderInfo.getOrderDate()),
              this.orderDeliveryService.listOrderDeliveryByOrderIds(CollUtil.toList(orderInfo.getOrderId()), CollUtil.toList(orderInfo.getOrderDate())));
      CustPayVO custInfo = this.getCustInfo(orderInfo.getCustId(), headerDTO.getSourceType());
      this.orderPayForIdCheck(CollUtil.toList(new OrderInfo[]{orderInfo}), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
      if (LeConstants.COMMON_NO.equals(orderPayDTO.getIfTrial())) {
         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
      }

      orderSavePO.setPayDTO(this.createPay(orderPayDTO.getPayType(), orderPayDTO.getCouponId(), headerDTO.getSourceType(), orderInfo.getCanteenId(), orderInfo.getStallId(), headerDTO.getOpenid(), custInfo, orderPayDTO));
      this.updateOrderField(CollUtil.toList(orderInfo), orderSavePO.getPayDTO());
      orderSavePO.getPayDTO().setAmount(orderInfo.calcNeedPayAmount());
      List<OrderAmountChange> amountChangeList = this.orderAmountChangeService.listByOrderIds(CollUtil.toList(new Long[]{orderInfo.getOrderId()}), CollUtil.toList(new LocalDate[]{orderInfo.getOrderDate()})).stream().filter((s) -> {
         return !ChangeDetailTypeEnum.ifFromRule(s.getChangeDetailType());
      }).collect(Collectors.toList());
      orderInfo.setDiscountsAmount(LeNumUtil.sumField(amountChangeList, OrderAmountChange::getChangeAmount));
      List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), LeConstants.COMMON_YES.equals(orderPayDTO.getIfTrial()));
      amountChangeList.addAll(amountChangeListRole);
      if (OrderTypeEnum.isCanteenCategory(orderInfo.getOrderType())) {
         this.orderPlaceBusiness.checkCoupon(orderSavePO.getPayDTO(), CollUtil.toList(new OrderInfo[]{orderInfo}));
      }

      orderSavePO.setAmountChangeList(amountChangeList);
      return LeConstants.COMMON_YES.equals(orderPayDTO.getIfTrial()) ? this.trialPay(orderSavePO, (OrderDeliveryResultVO)null) : this.saveAndPay(orderSavePO, false, true);
   }

   @Override
   public UnifyPayVO stageOrderPay(RequestHeaderDTO headerDTO, StagePayMobileDTO stagePayDTO) {
      CustPayVO custInfo = this.getCustInfo(stagePayDTO.getCustId(), stagePayDTO.getSourceType());
      UnifyPayDTO unifyPayDTO = this.createPay(stagePayDTO.getPayType(),
              stagePayDTO.getCouponId(),
              stagePayDTO.getSourceType(),
              null,
              null,
              stagePayDTO.getOpenid(),
              custInfo,
              stagePayDTO);
      unifyPayDTO.setAmount(stagePayDTO.getAmount());
      unifyPayDTO.setRemark(stagePayDTO.getRemark()+"支付");
      //处理设备sn码问题
      unifyPayDTO.setMachineSn( stagePayDTO.getMerchant());
      return payApi.pay(unifyPayDTO);
   }

//
//   public OrderPayMobileVO orderMixPayByTradeId(RequestHeaderDTO headerDTO, OrderMixPayMobileDTO orderMixPayMobileDTO) {
//      LogUtil.info("订单混合支付|入参", orderMixPayMobileDTO);
//      JavaxValidateUtils.validate(orderMixPayMobileDTO);
//      this.orderPlaceBusiness.checkOrderSubmitted(orderMixPayMobileDTO.getTradeId().toString());
//      List<OrderInfo> orderInfoList = this.orderInfoService.getOrderInfoListByTradeId(orderMixPayMobileDTO.getTradeId());
//      if (CollUtil.isEmpty(orderInfoList)) {
//         throw new LeException(OrderTips.noOrder());
//      } else {
//         List<Long> orderIds = (List)orderInfoList.stream().map(OrderInfo::getOrderId).collect(Collectors.toList());
//         List<LocalDate> orderDates = (List)orderInfoList.stream().map(OrderInfo::getOrderDate).collect(Collectors.toList());
//         OrderSavePO orderSavePO = OrderSavePO.byOrderInfo(orderInfoList, this.orderDetailService.getOrderDetailList((List)orderIds, (Collection)orderDates), this.orderDeliveryService.listOrderDeliveryByOrderIds(orderIds, orderDates));
//         CustPayVO custInfo = this.getCustInfo(orderMixPayMobileDTO.getCustId(), headerDTO.getSourceType());
//         this.orderPayForIdCheck(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getOrderDeliveryList());
//         this.orderPlaceBusiness.orderHandlerLock(orderSavePO.getMacOrderId(), OrderCacheConstants.MOBILE_PAY_INTERVAL);
//         orderSavePO.setPayDTO(this.createPay(orderMixPayMobileDTO.getPayType(), (String)orderSavePO.getOrderInfoList().stream().map(OrderInfo::getCouponId).filter(CharSequenceUtil::isNotBlank).findFirst().orElse((Object)null), headerDTO.getSourceType(), (Long)LeNumUtil.reduceField(orderSavePO.getOrderInfoList(), OrderInfo::getCanteenId, (Object)null), (Long)LeNumUtil.reduceField(orderSavePO.getOrderInfoList(), OrderInfo::getStallId, (Object)null), headerDTO.getOpenid(), custInfo, orderMixPayMobileDTO));
//         this.updateOrderField(orderSavePO.getOrderInfoList(), orderSavePO.getPayDTO());
//         orderSavePO.getPayDTO().setAmount((BigDecimal)orderSavePO.getOrderInfoList().stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
//         List<OrderAmountChange> amountChangeList = (List)this.orderAmountChangeService.listByOrderIds((List)orderSavePO.getOrderInfoList().stream().map(OrderInfo::getOrderId).collect(Collectors.toList()), (Collection)orderSavePO.getOrderInfoList().stream().map(OrderInfo::getOrderDate).collect(Collectors.toList())).stream().filter((s) -> {
//            return !ChangeDetailTypeEnum.ifFromRule(s.getChangeDetailType());
//         }).collect(Collectors.toList());
//         orderSavePO.getOrderInfoList().forEach((orderInfo) -> {
//            List<OrderAmountChange> currentOrderAmountList = (List)amountChangeList.stream().filter((s) -> {
//               return s.getOrderId().equals(orderInfo.getOrderId());
//            }).collect(Collectors.toList());
//            orderInfo.setDiscountsAmount(LeNumUtil.sumField(currentOrderAmountList, OrderAmountChange::getChangeAmount));
//         });
//         List<OrderAmountChange> amountChangeListRole = this.orderPlaceBusiness.calcRuleAmount(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), false);
//         amountChangeList.addAll(amountChangeListRole);
//         if (OrderTypeEnum.isCanteenCategory(((OrderInfo)orderSavePO.getOrderInfoList().get(0)).getOrderType())) {
//            this.orderPlaceBusiness.checkCoupon(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList());
//         }
//
//         orderSavePO.setAmountChangeList(amountChangeList);
//         return this.saveAndPay(orderSavePO, false, true);
//      }
//   }
//
//   public void orderPreBookAdd(RequestHeaderDTO headerDTO, OrderPreBookAddDTO addDTO) {
//      CustPayVO custInfo = this.getCustInfo(addDTO.getCustId(), headerDTO.getSourceType());
//      addDTO.setCustId(custInfo.getCustId());
//      if (this.orderPreBookService.existsByCustAndDate(custInfo.getCustId(), addDTO.getOrderDate(), addDTO.getOrderType())) {
//         throw new LeException(I18n.getMessage("order.mobile.pre-book-exists", new Object[0]));
//      } else {
//         this.orderPreBookService.insert(addDTO);
//      }
//   }

   protected OrderPayMobileVO saveAndPay(OrderSavePO orderSavePO, boolean needInventory, boolean secondaryPay) {
      boolean orderSaved = secondaryPay;

      UnifyPayVO unifyPayVO;
      try {
         if (needInventory) {
            this.orderPlaceBusiness.inventoryDeduct(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
         }

         if (!secondaryPay) {
            Integer delay = OrderMQConstants.delaySecondByOrderType(((OrderInfo)orderSavePO.getOrderInfoList().get(0)).getOrderType());
            LocalDateTime expireTime = OrderMessageSend.orderV3AsyncTimeoutByMacOrderId(orderSavePO.getMacOrderId(), delay);
            orderSavePO.getOrderInfoList().forEach((s) -> {
               s.setExpireTime(expireTime);
            });
         }

         this.orderPlaceBusiness.save(orderSavePO, false, secondaryPay);
         orderSaved = true;
         OrderPayMobileVO customVO = this.orderCustomBusiness.mobile().willMobileOrderPay(orderSavePO, secondaryPay);
         if (customVO != null) {
            return customVO;
         }

         unifyPayVO = this.orderPlaceBusiness.pay(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList());
         orderSavePO.setPayVO(unifyPayVO);
      } catch (Exception var7) {
         log.error("[移动端点餐] 保存支付错误 ", var7);
         unifyPayVO = orderSavePO.getPayVO();
         if (unifyPayVO == null) {
            unifyPayVO = new UnifyPayVO();
            unifyPayVO.setTradeId(orderSavePO.getPayDTO().getTradeId());
            unifyPayVO.setAmount(orderSavePO.getPayDTO().getAmount());
            unifyPayVO.setCode(var7 instanceof ServiceException ? ((ServiceException)var7).getCode() : PayStateEnum.PAY_FAIL.getKey());
            unifyPayVO.setMsg(var7.getMessage());
            orderSavePO.setPayVO(unifyPayVO);
         }
      }

      return this.payResultHandler(orderSavePO, orderSaved);
   }

   protected CustPayVO getCustInfo(Long custId, Integer sourceType) {
      CustPayVO custInfo = null;
      if (ObjectUtil.isNotNull(custId)) {
         custInfo = this.orderModuleClient.custPayInfoQuery(CustPayInfoQueryParam.ofCustId(custId));
      }

      custInfo = this.orderCustomBusiness.mobile().didGetCustInfoV2(custInfo, OrderCustomMobileCustInfoPO.of((String)null, custId, sourceType));
      if (ObjectUtil.isNull(custInfo)) {
         custInfo = new CustPayVO();
      }

      return custInfo;
   }

   protected void mealsCounterCheck(OrderInfo orderInfo, OrderDelivery orderDelivery, List<OrderDetail> orderDetailList) {
      if (DeliveryTypeEnum.DINING_CABINET.getKey().equals(orderDelivery.getDeliveryType())) {
         Integer maxOrdNum = this.deviceApi.getMaxOrdNum(orderDelivery.getDeliveryRelatedId(), SourceTypeEnum.MEAL_LOCKER.getKey());
         if (ObjectUtil.isNotNull(maxOrdNum) && maxOrdNum > 0) {
            int sumOrdDetail = orderDetailList.stream().mapToInt(OrderDetail::getQuantity).sum();
            if (maxOrdNum < sumOrdDetail) {
               throw new ServiceException(I18n.getMessage("order.mobile.locker-num-limit", new Object[]{maxOrdNum}));
            }
         }

         Integer orderCounterNum = this.orderInfoService.getOrderCounterNum(orderInfo.getOrderDate(), orderInfo.getMealtimeType(), orderDelivery.getDeliveryRelatedId());
         if (orderCounterNum > 0) {
            Long mealsCounterNum = this.deviceApi.getActiveLockerCount(orderDelivery.getDeliveryRelatedId());
            if ((long)orderCounterNum >= mealsCounterNum) {
               throw new ServiceException(I18n.getMessage("order.mobile.locker-full", new Object[0]));
            }
         }

      }
   }

   protected void currentMealOrderPlaceCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      if (this.orderCustomBusiness.mobile().willOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList)) {
         Iterator var4 = orderInfoList.iterator();

         while(var4.hasNext()) {
            OrderInfo orderInfo = (OrderInfo)var4.next();
            LocalTime nowTime = LocalTime.now();
            if (LeNumUtil.isValidId(orderInfo.getStallId())) {
               this.allocStallApi.checkStallBusinessState(orderInfo.getStallId(), nowTime);
            }

            if (orderInfo.getDeliveryType() == null) {
               throw new ServiceException(OrderTips.mobileNoDelivery());
            }

            AllocMealtimeModel mealtime = this.orderPlaceBusiness.checkMealtime(orderInfo.getMealtimeType(), orderInfo.getCanteenId(), orderInfo.getStallId());
            if (mealtime.getCurrStartTime() != null && nowTime.compareTo(mealtime.getCurrStartTime()) < 0 || mealtime.getCurrEndTime() != null && nowTime.compareTo(mealtime.getCurrEndTime()) > 0) {
               throw new ServiceException(I18n.getMessage("order.mobile.out-of-curr-time", new Object[0]));
            }

            orderInfo.setMealtimeType(mealtime.getMealtimeType());
            orderInfo.setMealtimeName(mealtime.getMealtimeName());
         }

      }
   }

   protected void reserveMealOrderPlaceCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      if (this.orderCustomBusiness.mobile().willOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList)) {
         LocalDate nowDate = LocalDate.now();
         LocalTime nowTime = LocalTime.now();
         String repeatReserveCheck = this.orderModuleClient.metadataGetValue(MetaDataValueParam.ofMerchant(MetadataModelTypeEnum.MOBILE, "repeatReserveCheck"));
         boolean repeatReserveFlag = "1".equals(repeatReserveCheck);
         Map<String, OrderInfo> goodsDateIntervalMap = new HashMap();
         if (repeatReserveFlag) {
            goodsDateIntervalMap = this.getOrderMapByCustId(((OrderInfo)orderInfoList.get(0)).getCustId(), nowDate);
         }

         Iterator var9 = orderInfoList.iterator();

         while(var9.hasNext()) {
            OrderInfo orderInfo = (OrderInfo)var9.next();
            if (LeNumUtil.isValidId(orderInfo.getStallId())) {
               this.allocStallApi.checkStallBusinessState(orderInfo.getStallId(), (LocalTime)null);
            }

            if (orderInfo.getDeliveryType() == null) {
               throw new ServiceException(OrderTips.mobileNoDelivery());
            }

            this.mealsCounterCheck(orderInfo, orderDeliveryList.stream().filter((s) -> {
               return s.getOrderId().equals(orderInfo.getOrderId());
            }).findFirst().orElse(new OrderDelivery()), orderDetailList.stream().filter((s) -> {
               return s.getOrderId().equals(orderInfo.getOrderId());
            }).collect(Collectors.toList()));
            AllocMealtimeModel mealtime = this.orderPlaceBusiness.checkMealtime(orderInfo.getMealtimeType(), orderInfo.getCanteenId(), orderInfo.getStallId());
            AllocCanteenOrderDTO canteenOrderDTO = this.orderModuleClient.metadataQueryOrderConfig(OrderConfigQueryParam.of(orderInfo.getCanteenId(), orderInfo.getStallId()));
            if (nowDate.isAfter(orderInfo.getOrderDate())) {
               throw new ServiceException(I18n.getMessage("order.mobile.out-of-reverse-date", new Object[0]));
            }

            if (nowDate.equals(orderInfo.getOrderDate())) {
               if (!"1".equals(canteenOrderDTO.getIfAllowReserveToday())) {
                  throw new ServiceException(I18n.getMessage("order.mobile.not-allow-reverse-today", new Object[0]));
               }

               LocalTime startTime = mealtime.getStartTime();
               String var10002;
               if (nowTime.isAfter(startTime)) {
                  var10002 = mealtime.getMealtimeName();
                  throw new ServiceException(var10002 + I18n.getMessage("order.mobile.not-allow-mealtime-start", new Object[0]));
               }

               LocalTime reserveStartTime = mealtime.getReserveStartTime();
               LocalTime endTime = mealtime.getReserveEndTime();
               if (ObjectUtil.isNotNull(reserveStartTime) && nowTime.isBefore(reserveStartTime)) {
                  var10002 = mealtime.getMealtimeName();
                  throw new ServiceException(var10002 + I18n.getMessage("order.mobile.not-allow-reverse", new Object[0]));
               }

               if (ObjectUtil.isNotNull(endTime) && nowTime.isAfter(endTime)) {
                  var10002 = mealtime.getMealtimeName();
                  throw new ServiceException(var10002 + I18n.getMessage("order.mobile.not-allow-reverse", new Object[0]));
               }
            } else {
               LocalDate tomorrow = this.allocHolidayApi.getWeekdayDeadLine(nowDate, 1, "1".equals(canteenOrderDTO.getIfReserveSkipHoliday()));
               LocalDate reserveLimitDate;
               if (tomorrow.equals(orderInfo.getOrderDate())) {
                  String reserveEndTime = canteenOrderDTO.getReserveEndTime();
                  reserveLimitDate = this.allocHolidayApi.getWeekdayDeadLine(tomorrow, -1, "1".equals(canteenOrderDTO.getIfReserveSkipHoliday()));
                  if (nowDate.isAfter(reserveLimitDate) || CharSequenceUtil.isNotBlank(reserveEndTime) && nowTime.isAfter(LocalTime.parse(reserveEndTime))) {
                     throw new ServiceException(I18n.getMessage("order.mobile.not-allow-reverse-tomorrow", new Object[0]));
                  }
               }

               int reserveLimitDay = ObjectUtil.isNull(canteenOrderDTO.getReserveLimitDay()) ? 7 : Integer.parseInt(canteenOrderDTO.getReserveLimitDay());
               reserveLimitDate = this.allocHolidayApi.getWeekdayDeadLine(nowDate, reserveLimitDay, "1".equals(canteenOrderDTO.getIfReserveSkipHoliday()));
               if (orderInfo.getOrderDate().isAfter(reserveLimitDate)) {
                  throw new ServiceException(I18n.getMessage("order.mobile.out-of-reverse-date", new Object[0]));
               }
            }

            String dishesNumberLimit;
            if (repeatReserveFlag) {
               String var10000 = orderInfo.getOrderDate().toString();
               dishesNumberLimit = var10000 + orderInfo.getCanteenId() + orderInfo.getStallId() + orderInfo.getMealtimeType();
               OrderInfo targetOrderInfo = (OrderInfo)((Map)goodsDateIntervalMap).get(dishesNumberLimit);
               this.reserveOrBookCheck(targetOrderInfo);
            }

            dishesNumberLimit = this.orderModuleClient.metadataGetValue(MetaDataValueParam.ofMerchant(MetadataModelTypeEnum.MOBILE, "dishesNumberLimit"));
            if (ObjectUtil.isNotEmpty(dishesNumberLimit)) {
               long size = orderDetailList.stream().filter((s) -> {
                  return s.getOrderId().equals(orderInfo.getOrderId());
               }).count();
               if (size > (long)Integer.parseInt(dishesNumberLimit)) {
                  throw new ServiceException(I18n.getMessage("order.mobile.reverse-num-limit", new Object[]{dishesNumberLimit}));
               }
            }
         }

      }
   }

   protected void bookMealOrderPlaceCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      if (this.orderCustomBusiness.mobile().willOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList)) {
         LocalDate nowDate = LocalDate.now();
         LocalTime nowTime = LocalTime.now();
         LocalDate tomorrow = nowDate.plusDays(1L);
         String repeatReserveCheck = this.orderModuleClient.metadataGetValue(MetaDataValueParam.ofMerchant(MetadataModelTypeEnum.MOBILE, "repeatReserveCheck"));
         boolean repeatReserveFlag = "1".equals(repeatReserveCheck);
         Map<String, OrderInfo> goodsDateIntervalMap = new HashMap();
         if (repeatReserveFlag) {
            goodsDateIntervalMap = this.getOrderMapByCustId(((OrderInfo)orderInfoList.get(0)).getCustId(), nowDate);
         }

         Map<String, AllocMealtimeModel> mealtimeMap = MapUtil.newHashMap();
         Map<String, AllocCanteenOrderDTO> orderDTOMap = MapUtil.newHashMap();
         Iterator var12 = orderInfoList.iterator();

         while(var12.hasNext()) {
            OrderInfo orderInfo = (OrderInfo)var12.next();
            if (LeNumUtil.isValidId(orderInfo.getStallId())) {
               this.allocStallApi.checkStallBusinessState(orderInfo.getStallId(), (LocalTime)null);
            }

            String mealtimeKey = CharSequenceUtil.join("_", new Object[]{orderInfo.getCanteenId(), orderInfo.getStallId(), orderInfo.getMealtimeType()});
            String orderDTOKey = CharSequenceUtil.join("_", new Object[]{orderInfo.getCanteenId(), orderInfo.getStallId()});
            AllocMealtimeModel mealtime = mealtimeMap.get(mealtimeKey) != null ? (AllocMealtimeModel)mealtimeMap.get(mealtimeKey) : this.orderPlaceBusiness.checkMealtime(orderInfo.getMealtimeType(), orderInfo.getCanteenId(), orderInfo.getStallId());
            mealtimeMap.put(mealtimeKey, mealtime);
            AllocCanteenOrderDTO canteenOrderDTO = orderDTOMap.get(orderDTOKey) != null ? (AllocCanteenOrderDTO)orderDTOMap.get(orderDTOKey) : this.orderModuleClient.metadataQueryOrderConfig(OrderConfigQueryParam.of(orderInfo.getCanteenId(), orderInfo.getStallId()));
            orderDTOMap.put(orderDTOKey, canteenOrderDTO);
            if (nowDate.isAfter(orderInfo.getOrderDate())) {
               throw new ServiceException(I18n.getMessage("order.mobile.out-of-reverse-time", new Object[0]));
            }

            if (nowDate.equals(orderInfo.getOrderDate())) {
               if (ObjectUtil.isNotNull(mealtime.getBookCurrDeadline()) && LocalTime.now().isAfter(mealtime.getBookCurrDeadline())) {
                  String var10002 = I18n.getMessage("order.mobile.book-time-limit", new Object[0]);
                  throw new ServiceException(var10002 + mealtime.getBookCurrDeadline().toString());
               }
            } else {
               boolean ifBookTomorrow = true;
               String bookEndTime = canteenOrderDTO.getBookEndTime();
               if (CharSequenceUtil.isNotBlank(bookEndTime) && nowTime.isAfter(LocalTime.parse(bookEndTime))) {
                  ifBookTomorrow = false;
               }

               if (tomorrow.equals(orderInfo.getOrderDate()) && !ifBookTomorrow) {
                  throw new ServiceException(I18n.getMessage("order.mobile.not-allow-reverse-tomorrow", new Object[0]));
               }

               String limitDay = canteenOrderDTO.getReportMealLimitDay();
               int dayNum = CharSequenceUtil.isBlank(limitDay) ? OrderConstant.DEFAULT_APPLET_BOOK_DAY_LIMIT : Integer.parseInt(limitDay);
               LocalDate limitDate = nowDate.plusDays((long)dayNum);
               if (orderInfo.getOrderDate().isAfter(limitDate)) {
                  throw new ServiceException(I18n.getMessage("order.mobile.book-day-limit", dayNum));
               }
            }

            String var10000 = orderInfo.getOrderDate().toString();
            String orderKey = var10000 + orderInfo.getCanteenId() + orderInfo.getStallId() + orderInfo.getMealtimeType();
            OrderInfo targetOrderInfo = (OrderInfo)((Map)goodsDateIntervalMap).get(orderKey);
            this.reserveOrBookCheck(targetOrderInfo);
         }

      }
   }

   protected void shopOrderPlaceCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      if (this.orderCustomBusiness.mobile().willOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList)) {
         Iterator var4 = orderInfoList.iterator();

         OrderInfo orderInfo;
         do {
            if (!var4.hasNext()) {
               return;
            }

            orderInfo = (OrderInfo)var4.next();
            if (orderInfo.getDeliveryType() == null) {
               throw new ServiceException(OrderTips.mobileNoDelivery());
            }
         } while(this.supermarketApi.ifBusiness(orderInfo.getCanteenId()));

         throw new ServiceException(I18n.getMessage("order.mobile.shop-not-in-time", new Object[0]));
      }
   }

   public void scanOrderPlaceCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      if (this.orderCustomBusiness.mobile().willOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList)) {
         Iterator var4 = orderInfoList.iterator();

         while(var4.hasNext()) {
            OrderInfo orderInfo = (OrderInfo)var4.next();
            LocalTime nowTime = LocalTime.now();
            if (OrderTypeEnum.isMobileScanType(orderInfo.getOrderType())) {
               if (LeNumUtil.isValidId(orderInfo.getCanteenId())) {
                  this.allocCanteenApi.checkCanteenBusinessState(orderInfo.getCanteenId(), nowTime);
               }

               if (LeNumUtil.isValidId(orderInfo.getStallId())) {
                  this.allocStallApi.checkStallBusinessState(orderInfo.getStallId(), nowTime);
               }

               AllocMealtimeModel mealtimeModel = this.orderPlaceBusiness.checkMealtime((Integer)null, orderInfo.getCanteenId(), orderInfo.getStallId());
               orderInfo.setMealtimeType(mealtimeModel.getMealtimeType());
               orderInfo.setMealtimeName(mealtimeModel.getMealtimeName());
            } else if (OrderTypeEnum.isMobileScanShopType(orderInfo.getOrderType()) && !this.supermarketApi.ifBusiness(orderInfo.getCanteenId())) {
               throw new ServiceException(I18n.getMessage("order.mobile.shop-not-in-time", new Object[0]));
            }
         }

      }
   }

   protected void orderPayForIdCheck(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderDelivery> orderDeliveryList) {
      Iterator var4 = orderInfoList.iterator();

      OrderInfo orderInfo;
      do {
         if (!var4.hasNext()) {
            if (OrderTypeEnum.isCurrMealType(((OrderInfo)orderInfoList.get(0)).getOrderType())) {
               this.currentMealOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList);
            } else if (OrderTypeEnum.isReserveMealType(((OrderInfo)orderInfoList.get(0)).getOrderType())) {
               this.reserveMealOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList);
            } else if (OrderTypeEnum.isBookMealCategory(((OrderInfo)orderInfoList.get(0)).getOrderType())) {
               this.bookMealOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList);
            } else if (OrderTypeEnum.isShopCategory(((OrderInfo)orderInfoList.get(0)).getOrderType())) {
               this.shopOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList);
            } else if (OrderTypeEnum.isMobileScanCategory(((OrderInfo)orderInfoList.get(0)).getOrderType())) {
               this.scanOrderPlaceCheck(orderInfoList, orderDetailList, orderDeliveryList);
            }

            this.orderPlaceBusiness.checkOrderPermission(orderInfoList, orderDetailList);
            return;
         }

         orderInfo = (OrderInfo)var4.next();
      } while(PayStateEnum.isUnPayState(orderInfo.getPayState()) && !OrderStateEnum.isCancelState(orderInfo.getOrderState()));

      log.info("[根据订单id支付]订单{}状态为{}", orderInfo.getOrderId(), orderInfo.getPayState());
      throw new ServiceException(I18n.getMessage("order.mobile.not-allow-pay", new Object[0]));
   }

   protected void checkOrderRepeated(String openid, Long custId) {
      if (this.orderCustomBusiness.mobile().willCheckOrderRepeated(OrderCustomMobileCheckRepeatPO.of(openid, custId))) {
         if (ObjectUtil.isNotNull(custId)) {
            this.orderPlaceBusiness.checkOrderSubmitted(custId.toString());
         } else if (CharSequenceUtil.isNotBlank(openid)) {
            this.orderPlaceBusiness.checkOrderSubmitted(openid);
         }

      }
   }

   protected void reserveOrBookCheck(OrderInfo orderInfo) {
      if (ObjectUtil.isNotNull(orderInfo)) {
         String space = " ";
         String msg = orderInfo.getOrderDate().toString() + space + orderInfo.getCanteenName() + space + orderInfo.getStallName() + space + orderInfo.getMealtimeName() + " 已存在订单";
         throw new ServiceException(msg);
      }
   }

   protected Map<String, OrderInfo> getOrderMapByCustId(Long custId, LocalDate nowDate) {
      Map<String, OrderInfo> orderMap = new HashMap();
      List<OrderInfo> ordAppInfoList = this.orderInfoService.getPlacedOrderInfoList(custId, nowDate);
      if (CollUtil.isNotEmpty(ordAppInfoList)) {
         ordAppInfoList.forEach((orderInfo) -> {
            String var10000 = orderInfo.getOrderDate().toString();
            String intervalKey = var10000 + orderInfo.getCanteenId() + orderInfo.getStallId() + orderInfo.getMealtimeType();
            orderMap.put(intervalKey, orderInfo);
         });
      }

      return orderMap;
   }

   protected void updateOrderField(List<OrderInfo> orderInfoList, UnifyPayDTO unifyPayDTO) {
      Iterator var3 = orderInfoList.iterator();

      while(var3.hasNext()) {
         OrderInfo orderInfo = (OrderInfo)var3.next();
         orderInfo.setSourceType(unifyPayDTO.getSourceType());
         orderInfo.setPayType(unifyPayDTO.getPayType());
         orderInfo.fillCustInfo(unifyPayDTO);
         if (unifyPayDTO.getCouponId() != null) {
            orderInfo.setCouponId(unifyPayDTO.getCouponId().toString());
         } else {
            orderInfo.setCouponId("");
         }
      }

   }

   protected UnifyPayDTO createPay(Integer payType, String couponId, Integer sourceType, Long canteenId, Long stallId, String openid, CustPayVO custInfo, OrderMobilePayParam requestParam) {
      PayChannelSelectDTO payChannelSelectDTO = new PayChannelSelectDTO();
      payChannelSelectDTO.setPayType(payType);
      payChannelSelectDTO.setCouponNum(couponId);
      payChannelSelectDTO.setOpenId(openid);
      payChannelSelectDTO.setCustId(custInfo.getCustId());
      payChannelSelectDTO.setCanteenId(canteenId);
      payChannelSelectDTO.setStallId(stallId);
      payChannelSelectDTO.setOnlineState(LeConstants.COMMON_YES);
      payChannelSelectDTO.setSourceType(sourceType);
      PayChannelSelectEnum scenario = PayChannelSelectEnum.MOBILE_CONSUME;
      PayChannelSelectResultVO payChannelSelectResultVO = this.payApi.payChannelSelect(scenario, payChannelSelectDTO);
      UnifyPayDTO unifyPayDTO = UnifyPayDTO.of(payChannelSelectResultVO);
      unifyPayDTO.setTradeId(Id.next());
      unifyPayDTO.setScenario(scenario.getKey());
      unifyPayDTO.setTradeType(TradeTypeEnum.CONSUME.getKey());
      unifyPayDTO.setSourceType(sourceType);
      unifyPayDTO.setOrderTime(LocalDateTime.now());
      unifyPayDTO.setOpenid(openid);
      unifyPayDTO.setPayPassword(requestParam.getPayPassword());
      if (payChannelSelectResultVO.getCustPayVO() == null) {
         unifyPayDTO.fillCustInfo(custInfo);
      }

      this.orderCustomBusiness.mobile().didCreatePay(unifyPayDTO, requestParam);
      return unifyPayDTO;
   }

   protected OrderPayMobileVO payResultHandler(OrderSavePO orderSavePO, boolean orderSaved) {
      OrderPayMobileVO orderPayMobileVO = new OrderPayMobileVO();
      UnifyPayVO payVO = orderSavePO.getPayVO();
      if (orderSaved) {
         if (!payVO.isAsyncPay()) {
            PayResultPO payResultPO = PayResultPO.of(payVO);
            OrderMessageSend.orderV3AsyncPayResult(payResultPO);
         }

         if (CollUtil.isNotEmpty(orderSavePO.getShoppingCartIdMapByDetailId())) {
            this.shoppingCartBusiness.clearAfterPlaced(CollUtil.newArrayList(orderSavePO.getShoppingCartIdMapByDetailId().values()));
         }

         orderPayMobileVO.setOrderList(OrderListPayMobileVO.listOf(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getShoppingCartIdMapByDetailId()));
         orderPayMobileVO.setOrderAmountChangeList(orderSavePO.getAmountChangeList().stream().filter((s) -> {
            return ChangeDetailTypeEnum.DISHES_DISCOUNTS.getKey().equals(s.getChangeDetailType()) || ChangeDetailTypeEnum.RULE_DISCOUNT.getKey().equals(s.getChangeDetailType());
         }).map(OrderAmountChangeVO::of).collect(Collectors.toList()));
      } else {
         orderSavePO.getOrderInfoList().forEach((s) -> {
            s.setIfQuickFail(LeConstants.COMMON_YES);
         });
         this.orderResultBusiness.orderDidFailedHandler(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), payVO.getCode(), false);
      }

      orderPayMobileVO.fillPayVO(payVO);
      orderPayMobileVO = this.orderCustomBusiness.mobile().didPayResultHandler(orderSavePO, orderPayMobileVO);
      return orderPayMobileVO;
   }

   protected OrderPayMobileVO trialPay(OrderSavePO orderSavePO, OrderDeliveryResultVO orderDeliveryResultVO) {
      OrderPayMobileVO orderPayMobileVO = new OrderPayMobileVO();
      orderPayMobileVO.setCode(RetCodeEnum.SUCC.getKey());
      orderPayMobileVO.setMsg(RetCodeEnum.SUCC.getDesc());
      orderPayMobileVO.setPayAmount(orderSavePO.getPayDTO().getAmount() != null ? orderSavePO.getPayDTO().getAmount().intValue() : 0);
      orderSavePO.getPayDTO().setIfTrail(LeConstants.COMMON_YES);
      orderSavePO.setPayVO(this.orderPlaceBusiness.pay(orderSavePO.getPayDTO(), orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList()));
      orderPayMobileVO.fillPayVO(orderSavePO.getPayVO());
      orderPayMobileVO.setOrderList(OrderListPayMobileVO.listOf(orderSavePO.getOrderInfoList(), orderSavePO.getOrderDetailList(), orderSavePO.getShoppingCartIdMapByDetailId()));
      if (orderDeliveryResultVO != null) {
         orderPayMobileVO.setLessAmountForDelivery(orderDeliveryResultVO.getLessAmountForDelivery());
         if (CollUtil.isNotEmpty(orderDeliveryResultVO.getLessAmountInfoList())) {
            Map<Long, BigDecimal> orderLessAmountDeliveryMap = orderDeliveryResultVO.getLessAmountInfoList().stream().collect(Collectors.toMap(OrderDeliveryResultVO.LessAmountInfo::getOrderId, OrderDeliveryResultVO.LessAmountInfo::getLessAmountForDelivery));
            orderPayMobileVO.getOrderList().forEach((s) -> {
               s.setLessAmountForDelivery((BigDecimal)orderLessAmountDeliveryMap.getOrDefault(s.getOrderId(), BigDecimal.ZERO));
            });
         }
      }

      orderPayMobileVO.setOrderAmountChangeList(orderSavePO.getAmountChangeList().stream().filter((s) -> {
         return ChangeDetailTypeEnum.DISHES_DISCOUNTS.getKey().equals(s.getChangeDetailType()) || ChangeDetailTypeEnum.RULE_DISCOUNT.getKey().equals(s.getChangeDetailType());
      }).map(OrderAmountChangeVO::of).collect(Collectors.toList()));
      orderPayMobileVO = this.orderCustomBusiness.mobile().didTrialResultHandler(orderSavePO, orderPayMobileVO);
      return orderPayMobileVO;
   }

   protected <T extends OrderMobileParam> OrderSavePO packageOrderInfo(OrderMobilePayParam summitParam, List<T> orderMobileParamList
           , UnifyPayDTO unifyPayDTO) {
      OrderSavePO orderSavePO = OrderSavePO.byLockKey(Id.nextString());
      orderSavePO.setPayDTO(unifyPayDTO);
      Iterator var5 = orderMobileParamList.iterator();

      while(var5.hasNext()) {
         OrderMobileParam orderMobileParam = (OrderMobileParam)var5.next();
         OrderInfo orderInfo = orderMobileParam.convertToOrderInfo();
         orderInfo.setOrderId(Id.next());
         orderInfo.setMacOrderId(orderSavePO.getMacOrderId());
         orderInfo.setIfOnline(LeConstants.COMMON_YES);
         orderInfo.setSourceType(unifyPayDTO.getSourceType());
         orderInfo.setPayType(unifyPayDTO.getPayType());
         orderInfo.setPayChannel(unifyPayDTO.getPayChannel());
         orderInfo.fillCustInfo(unifyPayDTO);
         orderSavePO.getOrderInfoList().add(orderInfo);
         OrderDelivery orderDelivery = orderMobileParam.convertToOrderDelivery();
         orderDelivery.setDeliveryId(Id.next());
         orderDelivery.setOrderId(orderInfo.getOrderId());
         orderDelivery.setOrderDate(orderInfo.getOrderDate());
         if (CharSequenceUtil.isBlank(orderDelivery.getConsigneeName())) {
            orderDelivery.setConsigneeName(unifyPayDTO.getCustName());
         }

         if (CharSequenceUtil.isBlank(orderDelivery.getConsigneeMobile())) {
            orderDelivery.setConsigneeMobile(unifyPayDTO.getMobile());
         } else {
            orderDelivery.setConsigneeMobile(this.aesEncryptUtil.aesDecode(orderDelivery.getConsigneeMobile()));
         }

         orderSavePO.getOrderDeliveryList().add(orderDelivery);
         List<OrderDetailPayDTO> detailPayDTOList = orderMobileParam.convertToOrderDetailList();
         if (LeConstants.COMMON_YES.equals(summitParam.getIfTrial())) {
            detailPayDTOList = this.shoppingCartBusiness.filterInvalidByCartIds(orderInfo.getOrderType(), orderInfo.getCustId(), detailPayDTOList);
         }

         Iterator var10 = detailPayDTOList.iterator();

         while(var10.hasNext()) {
            OrderDetailPayDTO orderDetailPayDTO = (OrderDetailPayDTO)var10.next();
            OrderDetail orderDetail = orderDetailPayDTO.convertToOrderDetail();
            orderDetail.setDetailId(Id.next());
            orderDetail.setOrderId(orderInfo.getOrderId());
            orderDetail.setOrderDate(orderInfo.getOrderDate());
            orderSavePO.getOrderDetailList().add(orderDetail);
            if (LeNumUtil.isValidId(orderDetailPayDTO.getShoppingCartId())) {
               orderSavePO.getShoppingCartIdMapByDetailId().put(orderDetail.getDetailId(), orderDetailPayDTO.getShoppingCartId());
            }
         }
      }

      this.orderCustomBusiness.mobile().didPackageOrderInfo(summitParam, orderMobileParamList, orderSavePO);
      return orderSavePO;
   }
}
