/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: OrderServiceImpl
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: liming.guo
 * @date: 2018/5/17 20:55
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
package cn.freemud.service.impl;

import cn.freemud.adapter.DeliveryAdapter;
import cn.freemud.adapter.LightApplicationConvertToAssortmentSdkAdapter;
import cn.freemud.adapter.MessageNoticeAdapter;
import cn.freemud.adapter.OrderAdapter;
import cn.freemud.amp.body.MessagePushNewMqBody;
import cn.freemud.amqp.Header;
import cn.freemud.amqp.MQAction;
import cn.freemud.amqp.MQMessage;
import cn.freemud.amqp.MQService;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.db.PushMccafeOrder;
import cn.freemud.entities.dto.order.McCafePushOrderDto;
import cn.freemud.entities.dto.MCCafeDeliveryBaseResponse;
import cn.freemud.entities.dto.PayAccessResponse;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.delivery.*;
import cn.freemud.entities.dto.order.CreateOrderOperateDto;
import cn.freemud.entities.dto.order.CreatePrepayRequestDto;
import cn.freemud.entities.dto.pay.OrderPayResponse;
import cn.freemud.entities.dto.pay.PaymentMqMessageDto;
import cn.freemud.entities.dto.product.AttributeValue;
import cn.freemud.entities.dto.product.GroupDetail;
import cn.freemud.entities.dto.product.ProductAttributeGroup;
import cn.freemud.entities.dto.product.ProductGroup;
import cn.freemud.entities.dto.shoppingCart.ActivityDiscountsDto;
import cn.freemud.entities.dto.shoppingCart.NewShoppingCartClearDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.user.OrderInfoRequest;
import cn.freemud.entities.dto.user.SendCouponForqujiaDtoResponseDto;
import cn.freemud.entities.dto.user.SendCouponForqujiaRequestDto;
import cn.freemud.entities.vo.CreateDeliveryVo;
import cn.freemud.entities.vo.*;
import cn.freemud.entities.vo.mccafe.RecentGoodsInfoVo;
import cn.freemud.enums.*;
import cn.freemud.enums.OrderType;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.management.entities.dto.request.order.MCCafeCouponRequest;
import cn.freemud.management.entities.dto.request.order.MCCafeCouponVo;
import cn.freemud.management.entities.dto.response.coupon.McdNetBatchQueryResponse;
import cn.freemud.management.enums.OrderSource;
import cn.freemud.management.service.OrderBaseService;
import cn.freemud.manager.PushMccafeOrderManager;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.BuriedPointService;
import cn.freemud.service.MCCafeOrderService;
import cn.freemud.service.mccafe.CouponClientService;
import cn.freemud.service.mccafe.MCCafeOrderCenterSdkService;
import cn.freemud.service.mccafe.thirdparty.DeliveryFeiginMCCafeClient;
import cn.freemud.service.thirdparty.*;
import cn.freemud.utils.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.*;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.enums.IappIdType;
import com.freemud.api.assortment.datamanager.manager.*;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.constant.ResponseConstant;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.couponcenter.offline.response.CouponBaseResponse;
import com.freemud.application.sdk.api.couponcenter.offline.response.CouponRedeemResponse;
import com.freemud.application.sdk.api.deliverycenter.response.CreateDeliveryOrderResponseDto;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.v1.ProductBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.v1.RefundBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.ordercenter.enums.ProductTypeEnum;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.ordercenter.enums.*;
import com.freemud.application.sdk.api.ordercenter.request.*;
import com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
import com.freemud.application.sdk.api.ordercenter.response.BaseDownLoadResponse;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.*;
import com.freemud.application.sdk.api.ordercenter.service.OrderDownLoadSdkService;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.paymentcenter.client.request.CodePayRequest;
import com.freemud.application.sdk.api.paymentcenter.client.request.SVCCardAmountRequest;
import com.freemud.application.sdk.api.paymentcenter.client.response.CodePayResponse;
import com.freemud.application.sdk.api.paymentcenter.client.response.SVCCardAmountResponse;
import com.freemud.application.sdk.api.paymentcenter.client.service.PaymentNewService;
import com.freemud.application.sdk.api.service.EmailAlertService;
import com.freemud.application.sdk.api.storecenter.request.GetListByCodesRequest;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.response.GetListByCodesResponse;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.application.sdk.api.util.Md5Util;
import com.freemud.sdk.api.assortment.message.config.MessageOfficialRefundPushMqConfig;
import com.freemud.sdk.api.assortment.message.entity.MpTemplateMsg;
import com.freemud.sdk.api.assortment.message.entity.MpTemplateMsgDataValue;
import com.freemud.sdk.api.assortment.message.enums.MessageEventType;
import com.freemud.sdk.api.assortment.message.request.MessagePushOrderTemplateRequest;
import com.freemud.sdk.api.assortment.message.request.MessageTemplateRequest;
import com.freemud.sdk.api.assortment.message.service.IMessageTemplatePushService;
import com.freemud.sdk.api.assortment.order.enums.NewOrderType;
import com.freemud.sdk.api.assortment.order.enums.OldOrderAccountType;
import com.freemud.sdk.api.assortment.order.enums.OldOrderStatus;
import com.freemud.sdk.api.assortment.order.enums.OldOrderType;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.*;
//import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse;
import cn.freemud.service.mccafe.CouponClientService;
import cn.freemud.service.mccafe.MCCafeOrderCenterSdkService;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.freemud.sdk.api.assortment.order.util.LockUtils;
import com.freemud.sdk.api.assortment.order.vo.ProductGroupVo;
import com.freemud.sdk.api.assortment.payment.request.OrderRefundQueryRequest;
import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest;
import com.freemud.sdk.api.assortment.payment.response.OrderRefundQueryResponse;
import com.freemud.sdk.api.assortment.payment.response.OrderRefundResponse;
import com.freemud.sdk.api.assortment.payment.response.UnifiedOrderResponse;
import com.freemud.sdk.api.assortment.payment.service.PaymentCenterService;
import com.freemud.sdk.api.assortment.payment.service.StandardPaymentService;
import com.freemud.sdk.api.assortment.payment.service.process.NewPaymentCenterServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.HttpClient;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class MCCafeOrderServiceImpl implements MCCafeOrderService {

    private final Integer RESPONSE_SUCCESS_CODE = 100;

    private static Gson gson = new Gson();

    @Value("${mcCafe.reverseNotifyiDcUrl}")
    private String reverseNotifyiDcUrl;
    @Value("${mcCafe.refund.interval}")
    private String mccafeRefundInterval;
    @Value("${program.backorders_change_order_status_consumer_queue}")
    private String backOrdersChangeOrderStatusConsumerQueue;
    @Value("${program.backorders_notify_activity_exchange}")
    private String backOrdersNotifyActivityExchange;
    @Value("${mq.queue.cloud_print_queue}")
    private String cloudPrintQueue;
    @Value("${mq.cloud_print_exchange}")
    private String cloud_print_exchange;
    @Value("${saas.order.delivery.mcCafe.callBackUrl}")
    private String deliveryCallBackUrl;
    @Value("${mcCafe.quickOrder.interval}")
    private String quickOrderInterval;
    @Value("${mccafe.partner.id}")
    private String mcCafePartnerId;
    @Value("${mccafe.push.order.url}")
    private String mccafePushOrderUrl;
    @Value("${mccafe.push.order.gateway.url}")
    private String mccafePushOrderGatewayUrl;
    @Value("${mccafe.pushorder.MerchantId}")
    private String mccafePushOrderMerchantId;
    @Value("${mccafe.pushorder.AppId}")
    private String mccafePushOrderAppId;
    @Value("${mccafe.pushorder.Key}")
    private String mccafePushOrderKey;
    /**
     * 创单锁定的key
     */
    @Value("${create.order.key.expire:5}")
    private String createOrderKeyExpire;


    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;
    @Autowired
    private DeliveryAdapter deliveryAdapter;
    @Autowired
    private AssortmentCloudPrinterManager cloudPrinterManager;
    @Autowired
    private FMAssistantCloudPrintClient fmAssistantCloudPrintClient;
    @Autowired
    private OrderServiceImpl orderService;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private ItemServiceImpl itemService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private MessageNoticeAdapter messageNoticeAdapter;
    @Autowired
    private OrderAdapter orderAdapter;
    //聚合订单服务
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
    private MCCafeOrderCenterSdkService mcCafeOrderCenterSdkService;
    @Autowired
    private PayServiceImpl payService;
    //门店SDK
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private MQService mqService;
    @Autowired
    @Qualifier("messageTemplatePushOrderService")
    private IMessageTemplatePushService<MessagePushOrderTemplateRequest> messageTemplatePushService;
    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private CheckMCCafeOrder checkMCCafeOrder;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private PaymentQueueService paymentQueueService;
    @Autowired
    private PaymentNewService paymentNewService;
    @Autowired
    private AssortmentOpenPlatformWxappAuthorizerManager wxappAuthorizerManager;
    @Autowired
    private OrderAdapterServiceImpl orderAdapterService;
    @Autowired
    private AssortmentOpenPlatformPartnerManager assortmentOpenPlatformPartnerManager;
    @Autowired
    private CouponClientService couponClientService;
    @Autowired
    private DeliveryFeiginMCCafeClient deliveryFeiginMCCafeClient;
    @Autowired
    private OrderSdkService orderSdkService;
    @Autowired
    private EmailAlertService emailAlertService;
    @Autowired
    private OrderBaseService orderBaseService;
    @Autowired
    private CustomerExtendClient customerExtendClient;
    @Autowired
    private AssortmentOpenPlatformPartnerConfigManager openPlatformPartnerConfigManager;
    @Resource(name = "mcCafePushOrderExecutor")
    private ThreadPoolTaskExecutor executor;
    @Resource(name = "mcCafePushOrderSubExecutor")
    private ThreadPoolTaskExecutor subExecutor;
    @Autowired
    private OrderDownLoadSdkService orderDownLoadSdkService;
    @Autowired
    private CustomerClient customerClient;
    @Autowired
    private MemberCenterService memberCenterService;
    @Autowired
    private McCafePushOrderClient mcCafePushOrderClient;
    @Autowired
    private PushMccafeOrderManager pushMccafeOrderManager;
    @Autowired
    private NewPaymentCenterServiceImpl paymentCenterService;

    @Autowired
    private AssortmentCustomerInfoManager assortmentCustomerInfoManager;

    private static MapperFacade mapper = new DefaultMapperFactory.Builder().build().getMapperFacade();
    /**
     * 下单检查key，防止重复下单
     */
    private final String CREATE_ORDER_KEY = "create_order_key:";
    private final String PAY_SUCCESS_KEY = "pay_success_key:";

    @Override
    public BaseResponse createMCCafeOrder(CreateOrderVo createOrderVo) {
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = assortmentCustomerInfoManager.getCustomerInfoByObject(createOrderVo.getSessionId());
        if (assortmentCustomerInfoVo == null || StringUtils.isEmpty(assortmentCustomerInfoVo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        if (!mcCafePartnerId.equals(assortmentCustomerInfoVo.getPartnerId())) {
            return ResponseUtil.error(ResponseResult.LOGIN_STORE_ERROR);
        }
        // 扩展字段中存储 sessionKey
        createOrderVo.setSessionKey(assortmentCustomerInfoVo.getSessionKey());

        // 添加分布式锁，如果没有取得锁直接返回失败；整个方法执行完毕后会删掉该锁
        // 锁定秒数从apollo获取，如果apollo没有设置，默认5秒
        String createOrderKey = CREATE_ORDER_KEY + assortmentCustomerInfoVo.getMemberId();
        try {
            Long expire = Long.valueOf(createOrderKeyExpire);
            if (!LockUtils.lock(redisCache.getRedisTemplate(), createOrderKey, expire)) {
                return ResponseUtil.error(ResponseResult.ORDER_NOT_CREATE_ERROR);
            }
        } catch (Exception e) {
            throw e;
        } finally {
            //LockUtils.unlock(redisCache.getRedisTemplate(),createOrderKey);
        }
        //原标准点餐程序逻辑处理
        BaseResponse baseResponse = this.checkStandardParamInfo(createOrderVo);
        if (ObjectUtils.notEqual(baseResponse.getCode(), ResponseResult.SUCCESS.getCode())) {
            return baseResponse;
        }
        String trackingNo = LogThreadLocal.getTrackingNo();
        // 查询用户信息,余额购物车校验
        AssortmentCustomerInfoVo userLoginInfoDto = checkMCCafeOrder.checkOrderByMember(createOrderVo, trackingNo);
        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数
        ShoppingCartGoodsDto shoppingCartGoodsDto = checkMCCafeOrder.getMCCafeShoppingCartGoodsDto(createOrderVo, userLoginInfoDto);
        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内
        StoreResponse.BizVO storeResponseDto = checkMCCafeOrder.checkOrderByStore(createOrderVo, trackingNo);
        // 查询小程序自提外卖配置信息 校验当前订单类型的下单参数 校验外卖是否满足起送条件
        Integer pushOrderTime = checkMCCafeOrder.checkOrderByOrderType(createOrderVo, userLoginInfoDto, storeResponseDto, shoppingCartGoodsDto, trackingNo);
        OrderExtInfoDto extInfo = getExtInfo(userLoginInfoDto, storeResponseDto, pushOrderTime, createOrderVo);
        //1.9.2套餐需求同步优化创建订单代码
        BaseResponse createOrderOperateDtoResponse = this.sdkCreateOrder(createOrderVo, storeResponseDto, shoppingCartGoodsDto, userLoginInfoDto);
        if(createOrderOperateDtoResponse == null || !ResponseResult.SUCCESS.getCode().equals(createOrderOperateDtoResponse.getCode()) || createOrderOperateDtoResponse.getResult() == null ) {
            return createOrderOperateDtoResponse;
        }
        CreateOrderOperateDto createOrderOperateDto = (CreateOrderOperateDto)createOrderOperateDtoResponse.getResult();
        //创建支付
        CreatePrepayRequestDto createPrepayRequestDto = orderAdapter.convertToCreatePrepayRequestDto(createOrderVo.getPartnerId(), userLoginInfoDto.getWxAppId(), userLoginInfoDto.getOpenId(),
                createOrderVo.getFaceCode(), createOrderVo.getCardCode(), null,
                createOrderOperateDto.getFatherOrderBean(), createOrderOperateDto.getProductOrderBean(),
                createOrderOperateDto.getTotalAmount() == null ? 0 : createOrderOperateDto.getTotalAmount(),
                createOrderOperateDto.getCardAmount() == null ? 0 : createOrderOperateDto.getCardAmount(), extInfo,
                createOrderOperateDto.getFatherOrderBean().getOid(), null);
        if(createOrderVo.getOrderType().equals(CreateOrderType.COLLECT_GOODS.getCode())) {
            createPrepayRequestDto.setNeedInvoice(createOrderVo.getNeedInvoice());
        } else {
            createPrepayRequestDto.setNeedInvoice(0);
        }
        return this.createPrepayOrder(createPrepayRequestDto);
    }


    /**
     * 获取预支付成功，将信息放入死心队列，当支付成功没有回掉的时候处理
     *
     * @param partnerId
     * @param storeId
     * @param fmId
     * @param orderId
     */
    public void putDelMq(String partnerId, String storeId, String fmId, String orderId) {
        PaymentMqMessageDto dto = new PaymentMqMessageDto();
        try {
            dto.setFmId(fmId);
            dto.setOrderId(orderId);
            dto.setPartnerId(partnerId);
            dto.setStoreId(storeId);
            dto.setTrackingNo(LogThreadLocal.getTrackingNo());
            paymentQueueService.paymentCallback(dto);
        } catch (Exception e) {
            AppLogUtil.errorLog("paymentQueueService.paymentCallback" , JSON.toJSONString(dto),null ,e);
        }

    }

    @Override
    public String mcCafePaySuccessCallback(NewPaysuccessNoticeMessage newMessage) {
        PaysuccessNoticeMessage message = new PaysuccessNoticeMessage();
        message.setResult_code(StringUtils.isBlank(newMessage.getResultCode()) ? 0 : Integer.valueOf(newMessage.getResultCode()));
        message.setOut_trade_no(StringUtils.isBlank(newMessage.getTransactionCode()) ? "" : newMessage.getTransactionCode());
        message.setTrans_id(StringUtils.isBlank(newMessage.getTransId()) ? "" : newMessage.getTransId());
        message.setTotal_fee(newMessage.getTotalAmount() == null ? 0 : newMessage.getTotalAmount());
        message.setOpenid(StringUtils.isBlank(newMessage.getOpenId()) ? "" : newMessage.getOpenId());
        message.setPlatform_coupon(newMessage.getPlatformCoupon() == null ? 0 : newMessage.getPlatformCoupon());
        message.setMerchant_coupon(newMessage.getPlatformCoupon() == null ? 0 : newMessage.getPlatformCoupon());
        message.setPaid_no(newMessage.getThirdPartTradeNo());
        message.setEndTransId(newMessage.getEndTransId());
        message.setPlatformMchId(newMessage.getPlatformMchId());
        message.setTerminalId(newMessage.getAppId());
        message.setRuleId(newMessage.getRuleId());
        String res = this.mcCafePaySuccessCallback(message);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if (jsonObject.containsKey("code")) {
            Integer code = (Integer) jsonObject.get("code");
            if (Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS_0, code) || Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS, code)) {
                //  新版支付成功的情况下code为100
                return newSendPaySuccessNoticeMessage();
            } else {
                return res;
            }
        }
        return newSendPayFaileMessage();
    }


    //    @Override
    public String mcCafePaySuccessCallback(PaysuccessNoticeMessage message) {
        //添加分布式锁，如果没有取得锁直接返回失败；整个方法执行完毕后会删掉该锁
        String paySuccessKey = PAY_SUCCESS_KEY + message.getTrans_id();
        if (!LockUtils.lockAfter(redisCache.getRedisTemplate(), paySuccessKey)) {
            return orderAdapter.paySuccessLockedMessage();
        }
        try {
            ConfirmOrderDto confirmOrderDto = orderAdapter.convent2ConfirmOrderDto(message);
            // 通过交易号从缓存中拿订单号，如果有数据则实际订单号为其value值
            String orderId = redisCache.getValue(RedisUtil.getPaymentTransIdOrderKey(confirmOrderDto.getOrderId()));
            if (StringUtils.isNotBlank(orderId)) {
                confirmOrderDto.setOrderId(orderId);
            }
            Map<String, OrderBeanV1> orderBeans = orderService.getOrderBeanByOrderId(confirmOrderDto.getOrderId());
            if (MapUtils.isEmpty(orderBeans)) {
                return gson.toJson(message);
            }
            OrderBeanV1 orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());
            if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus())) {
                return orderAdapter.sendPaySuccessNoticeMessage();
            }
            /**
             * 默认点餐处理
             */
            return this.paySuccessCallback(message, confirmOrderDto, orderBeans);
        } catch (Exception e) {
            throw e;
        } finally {
            //删除分布式锁
            redisCache.delete("saas:lockAfter:" + paySuccessKey);
        }
    }

    public QueryRelationOrderByIdResponseDto getQueryRelationOrderByIdResponseDto(String oid) {
        QueryRelatedOrderByCodeRequest baseQueryOrderRequest = new QueryRelatedOrderByCodeRequest();
        baseQueryOrderRequest.setOrderCode(oid);
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryRelatedOrderByCodeResp queryOrderByIdResponse;
        queryOrderByIdResponse = orderCenterSdkService.queryRelatedOrderByCode(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = jsonObject.toJavaObject(QueryRelationOrderByIdResponseDto.class);
        String orderString = JSONObject.toJSONString(queryOrderByIdResponse.getOrderBeanList());
        queryOrderByIdResponseDto.setData(JSONArray.parseArray(orderString, OrderBeanV1.class));
        return queryOrderByIdResponseDto;
    }

    public void backOrdersStatusChange(String oid, Integer orderStatus) {
        if (StringUtils.isEmpty(oid)) {
            return;
        }
//        AppLogUtil.debugLotsParams("backOrdersStatusChange oid:{} orderStatus:{}", oid, String.valueOf(orderStatus));
        OrderStatusChangeRequestDto requestDto = new OrderStatusChangeRequestDto();
        requestDto.setOid(oid);
        requestDto.setOrderStatus(orderStatus);

        try {
            Header header = new Header(MQAction.INSERT.getAction(), "backOrdersStatusChange", oid, backOrdersChangeOrderStatusConsumerQueue);
            MQMessage<OrderStatusChangeRequestDto> message = new MQMessage<>(header, requestDto);
            mqService.convertAndSend(backOrdersNotifyActivityExchange, backOrdersChangeOrderStatusConsumerQueue, message);
        } catch (Exception e) {
            AppLogUtil.errorLog("ActivityReverse", JSON.toJSONString(requestDto), "", e);
        }
    }

    private QueryOrderByIdResponseDto getQueryOrderByIdResponseDto(String oid) {
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(oid);
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        return jsonObject.toJavaObject(QueryOrderByIdResponseDto.class);
    }

    /**
     * 支付后通知确认返回信息
     */
    public String newSendPaySuccessNoticeMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 100);
        map.put("message", "success");
        return gson.toJson(map);
    }

    /**
     * 支付后通知失败返回信息
     */
    public String newSendPayFaileMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 102);
        map.put("message", "failed");
        return gson.toJson(map);
    }


    /**
     * 发送模板消息
     *
     * @param orderBean
     * @param messageEventType
     */
    private void sendMessage(OrderBeanV1 orderBean, MessageEventType messageEventType) {
        MessageTemplateRequest<MessagePushOrderTemplateRequest> messageTemplateRequest = null;
        try {
            messageTemplateRequest = messageNoticeAdapter.convent2MessageTemplateRequest(orderBean);
            messageTemplateRequest.setMessageEventType(messageEventType);
            this.messageTemplatePushService.sendTemplateMsg(messageTemplateRequest);
        } catch (Exception e) {
            AppLogUtil.errorLog("sendTemplateMsg_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(messageTemplateRequest), e);
        }
    }

    /**
     * 获取商品第三方商品编号
     *
     * @param createOrderDto
     * @return
     */
    private BaseCreateOrderRequest getProductCustomerCode(BaseCreateOrderRequest createOrderDto) {
        List<String> spuIds = new ArrayList<>();
        for (CreateOrderProductRequest productDto : createOrderDto.getProducts()) {
            spuIds.add(productDto.getProductId());
        }
        Map<String, GetProductsVo> products = itemService.getSpuProducts(spuIds, createOrderDto.getCompanyId(), createOrderDto.getShopId(),createOrderDto.getMenuType());
        if (products.isEmpty()) {
            return createOrderDto;
        }
        for (CreateOrderProductRequest productDto : createOrderDto.getProducts()) {
            String skuId = productDto.getSpecification();
            if (products.get(skuId) != null) {
                productDto.setThirdProductSpecId(products.get(productDto.getSpecification()).getThirdProductSpecId());
                productDto.setThirdProductPropertyId(getThirdPropertyId(products.get(productDto.getSpecification()).getProductAttributeGroupList(),productDto.getAddInfo()));

                // todo 商品组信息
                setProductGroupInfo(products.get(skuId).getProductGroupList(), productDto);
            } else {
                AppLogUtil.errorLog("getProducts_exception", JSONObject.toJSONString(skuId), JSONObject.toJSONString(products), null);
            }
            //套餐子商品
            if(CollectionUtils.isNotEmpty(productDto.getComboProduct())){
                for (CreateOrderProductRequest comboProduct : productDto.getComboProduct()){
                    String comboSkuId = comboProduct.getSpecification();
                    if (products.get(comboSkuId) != null) {
                        comboProduct.setThirdProductSpecId(products.get(comboSkuId).getThirdProductSpecId());
                        comboProduct.setThirdProductPropertyId(getThirdPropertyId(products.get(comboSkuId).getProductAttributeGroupList(),comboProduct.getAddInfo()));
                        comboProduct.setStapleFood(products.get(comboSkuId).getStapleFood());
                        // todo 套餐商品的商品组信息
                        setProductGroupInfo(products.get(comboSkuId).getProductGroupList(), comboProduct);
                    } else {
                        AppLogUtil.errorLog("getProducts_exception", JSONObject.toJSONString(skuId), JSONObject.toJSONString(products), null);
                    }
                }
            }
        }
        return createOrderDto;
    }

    /**
     * 设置商品组信息
     * @param productGroupList
     * @param product
     */
    private void setProductGroupInfo(List<ProductGroup> productGroupList, CreateOrderProductRequest product) {
        if (CollectionUtils.isEmpty(productGroupList)) return;

        List<ProductGroupVo> targetGroupList = Lists.newArrayList();
        for (ProductGroup productGroup : productGroupList) {
            for (GroupDetail groupDetail : productGroup.getGroupDetail()) {
                ProductGroupVo productGroupVo = ProductGroupVo.builder()
                        .groupId(groupDetail.getGroupId()).groupName(productGroup.getName())
                        .thirdGroupId(productGroup.getGroupCode()).build();
                if (!targetGroupList.contains(productGroupVo)) {
                    targetGroupList.add(productGroupVo);
                }
            }
        }
        product.setProductGroupList(targetGroupList);
    }

    private String getThirdPropertyId(List<ProductAttributeGroup> productAttributeGroups, String addInfo) {
        String thirdProductPropertyId = "";
        if(StringUtils.isBlank(addInfo) || CollectionUtils.isEmpty(productAttributeGroups) ){
            return thirdProductPropertyId;
        }
        JSONObject jsonObject = JSONObject.parseObject(addInfo);
        String attributeNames = (String)jsonObject.get("attributeNames");
        List<String> list = new ArrayList<>();
        String[] split = attributeNames.split("/");

        List<AttributeValue> attributeValues = new ArrayList<>();
        for (ProductAttributeGroup attributeGroup : productAttributeGroups){
            attributeValues.addAll(attributeGroup.getAttributeValues());
        }

        for (int i= 0;i<split.length;i++){
            for (AttributeValue attributeValue : attributeValues){
                if(attributeValue.getAttributeValue().equals(split[i])){
                    list.add(attributeValue.getCustomerCode());
                    break;
                }
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            thirdProductPropertyId = StringUtils.join(list, ",");
        }
        return thirdProductPropertyId;
    }

    /**
     * 创建订单调用集成，不区分订单类型
     *
     * @return
     */
    public BaseResponse sdkCreateOrder(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto,
                                                              AssortmentCustomerInfoVo userLoginInfoDto) {
        CreateOrderOperateDto response = new CreateOrderOperateDto();
        OrderExtendedReq orderExtendedReq = orderAdapter.saveStoreInfo(storeResponseDto);
        OrderClientType orderClient = OrderClientType.SAAS;
        String appId = userLoginInfoDto.getWxAppId();
        if(UserLoginChannelEnum.ALIPAY.getCode().equals(userLoginInfoDto.getChannel()) ){
            orderClient = OrderClientType.ALIPAY;
        } else if(UserLoginChannelEnum.APP.getCode().equals(userLoginInfoDto.getChannel())) {
            orderClient = OrderClientType.APP;
        }

        //麦咖啡只有普通订单
        CreateOrderResponse createOrderFlowResponse = createOrder(createOrderVo, storeResponseDto, shoppingCartGoodsDto, orderExtendedReq, orderClient,appId);
        if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createOrderFlowResponse.getErrcode())) {
            return ResponseUtil.error(createOrderFlowResponse.getErrcode().toString(), createOrderFlowResponse.getErrmsg());
        }
        OrderBeanV1 fatherBeanListOne = createOrderFlowResponse.getData();
        OrderBeanV1 productBeanListOne = createOrderFlowResponse.getData();
        long totalAmount = createOrderFlowResponse.getData().getAmount();

        response.setTotalAmount(totalAmount);
        response.setCardAmount(0);
        response.setFatherOrderBean(fatherBeanListOne);
        response.setProductOrderBean(productBeanListOne);
        return ResponseUtil.success(response);
    }

    /**
     * 创建预支付订单
     */
    public BaseResponse createPrepayOrder(CreatePrepayRequestDto createPrepayRequestDto) {

        CreateOrderResponseVo createOrderResponse;
        OrderPayResponse orderPayResponse = null;
        PaymentRequest paymentRequest = orderBodyConvertToPaymentBody(createPrepayRequestDto.getOpenId(), createPrepayRequestDto.getPartnerId(), createPrepayRequestDto.getWxAppId(), createPrepayRequestDto.getPayCode());
        long totalAmount = createPrepayRequestDto.getTotalAmount();
        String cardCode = createPrepayRequestDto.getCardCode();
        String transId = createPrepayRequestDto.getTransId();
        //麦咖啡不支持svc卡
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else if (totalAmount > 0) {
            orderPayResponse = getPreOrderPay(createPrepayRequestDto.getFatherOrderBean(), paymentRequest, LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getCardAmount(), transId, createPrepayRequestDto.getNeedInvoice());
        } else {
            // 0元订单如果不需要支付，自定义支付单号
            orderPayResponse = getOrderPayResponse(paymentRequest, createPrepayRequestDto.getFatherOrderBean());
        }
        if (orderPayResponse == null) {
            return failPreOrderPay(LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getProductOrderBean(), cardCode, createPrepayRequestDto.getOrderClient());
        }
        createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, createPrepayRequestDto.getProductOrderBean());
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, createPrepayRequestDto.getOrderExtInfoDTO(), createPrepayRequestDto.getProductOrderBean(), LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        if (totalAmount > 0 && StringUtils.isBlank(cardCode)) {
            createOrderResponse.setPaySuccess(false);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        // 推荐优惠插件用户下单数据上报
        //wechatPushProcessor.statusOrderCreate(userLoginInfoDto, createOrderResponse.getOid(), createOrderVo.getPartnerId());
        if (!createOrderResponse.getPaySuccess()) {
            return ResponseUtil.success(createOrderResponse);
        } else {
            //如果是商品券支付0元，调用回调接口
            PaysuccessNoticeMessage message = new PaysuccessNoticeMessage();
            message.setResult_code(100);
            message.setOut_trade_no(createOrderResponse.getFmId());
            message.setTrans_id(createOrderResponse.getOid());
            message.setTotal_fee(0);
            message.setOpenid(createPrepayRequestDto.getOpenId());
            message.setPlatform_coupon(0);
            message.setMerchant_coupon(0);
            //修改为麦咖啡支付成功回调
            this.mcCafePaySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }

    /**
     * 创建普通订单
     */
    public CreateOrderResponse createOrder(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto,
                                           OrderExtendedReq orderExtendedReq, OrderClientType orderClient,String appId) {
//        processRepeatGoodsWithSeedCoupon(shoppingCartGoodsDto);
        BaseCreateOrderRequest baseCreateOrderRequest = orderAdapter.convent2CreateOrderDto(createOrderVo, shoppingCartGoodsDto, storeResponseDto);
        //查询第三方商品编号
        baseCreateOrderRequest = getProductCustomerCode(baseCreateOrderRequest);
        //保存门店渠道信息
        baseCreateOrderRequest.setOrderExtended(orderExtendedReq);
        baseCreateOrderRequest.setOrderClient(orderClient);
        baseCreateOrderRequest.setAppId(appId);
        CreateOrderRequest createOrderRequest = new CreateOrderRequest();
        baseCreateOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        createOrderRequest.setBaseCreateOrderRequest(baseCreateOrderRequest);
        MqMessageRequest mqMessageRequest = new MqMessageRequest();
        mqMessageRequest.setBackOrdersNotifyActivityExchange(backOrdersNotifyActivityExchange);
        mqMessageRequest.setBackOrdersNotifyActivityQueue(backOrdersChangeOrderStatusConsumerQueue);
        createOrderRequest.setMqMessageRequest(mqMessageRequest);
        createOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        return mcCafeOrderCenterSdkService.createMCCafeOrderFlow(createOrderRequest);
    }

    private void processRepeatGoodsWithSeedCoupon(ShoppingCartGoodsDto shoppingCartGoodsDto) {
        List<String> cardCodeList = shoppingCartGoodsDto.getProducts().stream().filter(o -> ProductTypeEnum.VIRTUAL_PRODUCT.getCode().equals(o.getProductType()))
                .map(o -> o.getMonthCardInfo().getCardCode()).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(cardCodeList)) {
            return;
        }

        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos();
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> products = new ArrayList<>();
        shoppingCartGoodsDto.getProducts().stream().forEach(o -> {
            boolean flag = false;
            if(o.getQty() > 1 && CollectionUtils.isNotEmpty(o.getActivityDiscountsDtos())) {
                for(ActivityDiscountsDto activityDiscountsDto : o.getActivityDiscountsDtos()) {
                    if(cardCodeList.contains(activityDiscountsDto.getActivityCode())) {
                        flag = true;
                        int qty = o.getQty();
                        Integer totalDiscountAmount = o.getTotalDiscountAmount()/qty;
                        Integer discountAmount = activityDiscountsDto.getDiscountAmount()/qty;
                        String cartGoodsUid = o.getCartGoodsUid();
                        for(int i=qty;i>=1;i--) {
                            ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = mapper.map(o, ShoppingCartGoodsDto.CartGoodsDetailDto.class);
                            cartGoodsDetailDto.setQty(1);
                            cartGoodsDetailDto.setTotalDiscountAmount(totalDiscountAmount);
                            cartGoodsDetailDto.getActivityDiscountsDtos().get(0).setDiscountAmount(discountAmount);
                            cartGoodsDetailDto.setSplitIndex(cartGoodsUid);
                            products.add(cartGoodsDetailDto);
                        }
                        for(int j=0;j<activityDiscountsDtos.size();j++) {
                            if(cartGoodsUid.equals(activityDiscountsDtos.get(j).getCartGoodsUid())) {
                                ActivityDiscountsDto orderActivityDiscountsDto = activityDiscountsDtos.get(j);
                                orderActivityDiscountsDto.setDiscountAmount(orderActivityDiscountsDto.getDiscountAmount()/qty);
                                activityDiscountsDtos.remove(j);
                                for(int k=0;k<qty;k++) {
                                    activityDiscountsDtos.add(j, mapper.map(orderActivityDiscountsDto, ActivityDiscountsDto.class));
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            if(!flag) {
                products.add(o);
            }
        });
        shoppingCartGoodsDto.setProducts(products);
    }

    private OrderPayResponse getOrderPayResponse(PaymentRequest paymentRequest, OrderBeanV1 orderBean) {
        OrderPayResponse orderPayResponse;
        String fmId = "SPAY" + ValidationCode.getRandomUuid();
        orderPayResponse = orderAdapter.getOrderPayResponse(orderBean.getCompanyId(), paymentRequest,
                orderBean.getOid(), fmId);
        return orderPayResponse;
    }

    private BaseResponse failPreOrderPay(String trackingNo, OrderBeanV1 orderBean, String cardCode, OrderClientType orderClient) {
        List<OrderClientType> notCancelOrderClientList = Lists.newArrayList(OrderClientType.APP);
        if(!notCancelOrderClientList.contains(orderClient)) {
            //失败冲正库存，冲正活动库存，取消订单
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, "获取预支付失败", trackingNo, null);
            orderCenterSdkService.orderCancel(cancelOrderRequest);
            // TODO: 2019/9/10 hubowen mq推送变更
            backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
        }
        //svc 卡支付失败
        if (StringUtils.isNotBlank(cardCode)) {
            return ResponseUtil.error(ResponseResultEnum.PAY_BACKEND_CONFIG_ERROR.getCode(), ResponseResultEnum.PAY_BACKEND_CONFIG_ERROR.getMessage(), null);
        }
        return ResponseUtil.error(ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getCode(), ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getMessage(), null);
    }

    public OrderPayResponse getPreOrderPay(OrderBeanV1 orderBean, PaymentRequest paymentRequest, String trackingNo, Integer cardAmount, String transId, int needInvoice) {
        try {
            UnifiedOrderRequest request = orderAdapter.convent2MCCafeUnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, transId, null);
            request.setInvoiceFlag(needInvoice);
            Map<String, String> extendParams = new HashMap<>();
            if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType())) {
                extendParams.put("mealType", "delivery");
            } else {
                extendParams.put("mealType", "pickup");
            }
            request.setExtendParams(extendParams);
            com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> responseBase = payService.unifiedOrder(request);
            if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode())) {
                return null;
            }
            putDelMq(request.getPartnerId(), request.getStoreId(), responseBase.getData().getFmId(), orderBean.getOid());
            OrderPayResponse orderPayResponse = orderAdapter.convent2OrderPayResponse(responseBase.getData());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            return orderPayResponse;
        } catch (Exception e) {
            AppLogUtil.errorLog("getPreOrderPay_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(paymentRequest),e);
            //TODO 邮件告警
            return null;
        }
    }

//    public OrderPayResponse svcPay(String cardCode, OrderBeanV1 orderBean, PaymentRequest paymentRequest, String transId, String trackingNo) {
//        CodePayRequest request = new CodePayRequest();
//        String partnerId = orderBean.getCompanyId();
//        request.setBody(orderBean.getShopName());
//        request.setBusinessDate(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
//        request.setCode(cardCode);
//        request.setPartnerId(partnerId);
//        request.setStoreId(orderBean.getShopId());
//        request.setAmount(orderBean.getAmount());
//        request.setTransId(transId);
//        request.setStationId("1");
//        request.setOperatorId("1");
//        request.setVer("2");
//        SVCCardAmountRequest svcRequest = new SVCCardAmountRequest();
//        svcRequest.setPartnerId(partnerId);
//        svcRequest.setCardCodes(Arrays.asList(cardCode));
//        //查询svc卡余额
//        com.freemud.application.sdk.api.base.BaseResponse<SVCCardAmountResponse> svcCardAmountResponseBaseResponse = paymentNewService.querySVCCardAmount(svcRequest, trackingNo);
//        if (svcCardAmountResponseBaseResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(svcCardAmountResponseBaseResponse.getCode())
//                || svcCardAmountResponseBaseResponse.getData().getData() == null || CollectionUtils.isEmpty(svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos())) {
//            return null;
//        }
//        Integer amount = svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos().get(0).getAmount();
//        Integer vamount = svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos().get(0).getVamount();
//        if (amount + vamount < orderBean.getAmount()) {
//            return null;
//        }
//        //svc卡支付
//        com.freemud.application.sdk.api.base.BaseResponse<CodePayResponse> responseBase = paymentNewService.codePay(request, trackingNo);
//        if (responseBase == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode()) || responseBase.getData().getData() == null) {
//            return null;
//        }
//        OrderPayResponse orderPayResponse = new OrderPayResponse();
//        CodePayResponse.CodePayDate codePayResponse = responseBase.getData().getData();
//        orderPayResponse.setFmId(codePayResponse.getFmId());
//        orderPayResponse.setPayTransId(codePayResponse.getPayTransId());
//        orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
//        orderPayResponse.setOpenId(paymentRequest.getOpenId());
//        orderPayResponse.setPartnerId(orderBean.getCompanyId());
//        orderPayResponse.setOrderId(orderBean.getOid());
//        return orderPayResponse;
//    }

    private PaymentRequest orderBodyConvertToPaymentBody(String openId, String partnerId, String appId, String payCode) {
        //设置支付信息
        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setOpenId(openId);
        paymentRequest.setWxAppId(appId);
        AssortmentOpenPlatformWxapp wxApp = openPlatformWxappManager.findByPartnerIdAndWxappId(partnerId, appId);
        AssortmentOpenPlatformPartner platformPartner = null;
        if (wxApp == null) {
            platformPartner = assortmentOpenPlatformPartnerManager.selectOpenPlatformPartner(partnerId);
        }
        paymentRequest.setPrincipalName(wxApp != null ? wxApp.getPrincipalName() : platformPartner != null ? platformPartner.getCompanyName() : "上海非码网络科技有限公司");
        paymentRequest.setReverseNotifyiDcUrl(reverseNotifyiDcUrl);
        paymentRequest.setPayCode(payCode);
        return paymentRequest;
    }

    private OrderExtInfoDto getExtInfo(AssortmentCustomerInfoVo userLoginInfoDto, StoreResponse.BizVO storeResponseDto,
                                      Integer pushOrderTime, CreateOrderVo createOrderVo) {

        Integer serviceTime = storeResponseDto.getServiceTime();
        String sessionId = createOrderVo.getSessionId();
        String version = createOrderVo.getVersion();
        CreateOrderVo.BuyMemberCard memberCard = createOrderVo.getBuyMemberCard();

        String deliveryHoursDayStart = "";
        String deliveryHoursDayEnd = "";
        if (StringUtils.isNotBlank(storeResponseDto.getDeliveryHoursDay())) {
            String[] days = storeResponseDto.getDeliveryHoursDay().split("-");
            if (days.length == 2) {
                deliveryHoursDayStart = DateUtil.convert2String(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " " + days[0] + ":00";
//                deliveryHoursDayEnd = DateUtil.convert2String(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " " + days[1] + ":00";
            }
        }

        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        orderExtInfoDto.setDeliveryHoursDayStart(deliveryHoursDayStart);
        orderExtInfoDto.setDeliveryHoursDayEnd(deliveryHoursDayEnd);
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(sessionId);
        if (Objects.equals(serviceTime, null)) {
            serviceTime = 50;
        }
        orderExtInfoDto.setServiceTime(serviceTime);
        orderExtInfoDto.setPushOrderTime(pushOrderTime);
        orderExtInfoDto.setVersion(version);
        if (memberCard != null && memberCard.getRuleId() != null) {
            orderExtInfoDto.setRuleId(memberCard.getRuleId());
        }
        // 扩展字段中存储 sessionKey
        orderExtInfoDto.setSessionKey(createOrderVo.getSessionKey());
        orderExtInfoDto.setFormId(createOrderVo.getFormId());
        orderExtInfoDto.setFromAppId(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setNeedInvoice(createOrderVo.getNeedInvoice());
        orderExtInfoDto.setInvoiceTitle(createOrderVo.getInvoiceTitle());
        orderExtInfoDto.setNeedTableware(createOrderVo.getNeedTableware());
        orderExtInfoDto.setThirdPartyMemberId(userLoginInfoDto.getThirdPartyMemberID());
        if (StringUtils.isNotBlank(createOrderVo.getScene())) {
            orderExtInfoDto.setScene(createOrderVo.getScene());
        }
        return orderExtInfoDto;
    }

    /**
     * 编辑订单，保持预支付信息
     */
    public BaseResponse updateOrderInfo(OrderPayResponse orderPayResponse, OrderExtInfoDto orderExtInfo
            , OrderBeanV1 orderBean, String trackingNo) {
        orderExtInfo.setOpenid(orderPayResponse.getOpenId());
        orderExtInfo.setFmId(orderPayResponse.getFmId());
        orderExtInfo.setAppid(orderPayResponse.getWxAppid());
        String prepayId = "";
        OrderPayResponse.PayOrderBean payOrder = orderPayResponse.getPayOrder();
        // StringUtils 依赖修改
        if (payOrder != null && !StringUtils.isEmpty(payOrder.getPackageX())) {
            String[] prepayIds = payOrder.getPackageX().split("=");
            prepayId = prepayIds.length > 1 ? prepayIds[1] : "";
        }
        //支付宝保存交易流水号发送支付宝模板消息
        if (payOrder != null && !StringUtils.isEmpty(payOrder.getAliPayOrder())) {
            prepayId = payOrder.getAliPayOrder();
        }
        orderExtInfo.setPrepayId(prepayId);

        OrderEditRequest orderEditRequest = new OrderEditRequest(orderPayResponse.getPayTransId(),
                JSONObject.toJSONString(orderExtInfo));
        orderEditRequest.setOrderId(orderBean.getOid());
        orderEditRequest.setTrackingNo(trackingNo);
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderEdit(orderEditRequest);
        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS, baseOrderResponse.getErrcode())) {
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, "编辑订单支付信息失败", trackingNo, null);
            orderCenterSdkService.orderCancel(cancelOrderRequest);
            //如果编辑订单支付信息失败，冲正
            backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
            return ResponseUtil.error(baseOrderResponse.getErrcode().toString(), baseOrderResponse.getErrmsg());

        }

        return null;
    }


    @Override
    public String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, OrderBeanV1> orderBeans) {
        OrderBeanV1 orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());
        String oid = StringUtils.isNotEmpty(orderBean.getParentCode()) && !"0".equals(orderBean.getParentCode()) ? orderBean.getParentCode() : orderBean.getOid();
        String partnerId = orderBean.getCompanyId();
        String userId = orderBean.getUserId();
        String storeId = orderBean.getShopId();
        orderBean.setPayVoucher(message.getOut_trade_no());
        //编辑订单信息，获取openid，用于退款
        String extInfo = orderBean.getExtInfo();
        OrderExtInfoDto orderExtInfoDto = null;
        String wxappid = "";
        String sessionId = "";
//        String openid = "";
//        String ruleId = "";
        String payCode = "";
        if (StringUtils.isNotBlank(extInfo)) {
            orderExtInfoDto = gson.fromJson(extInfo, OrderExtInfoDto.class);
            if (orderExtInfoDto != null && StringUtils.isNotBlank(orderExtInfoDto.getOpenid())) {
//                openid = orderExtInfoDto.getOpenid();
                wxappid = orderExtInfoDto.getAppid();
                sessionId = orderExtInfoDto.getSessionId();
//                ruleId = orderExtInfoDto.getRuleId();
            }
            if (orderExtInfoDto != null && StringUtils.isNotBlank(orderExtInfoDto.getPayCode())
                    && Arrays.asList(PayChannel.ALIPAY.getCode(), PayChannel.WXPAY.getCode()).contains(orderExtInfoDto.getPayCode())) {
                payCode = orderExtInfoDto.getPayCode();
            }
        }
        // 如果订单状态不是未支付，返回信息
//        if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()) || !OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
//            return sendPaySuccessNoticeMessage();
//        }

        //麦咖啡随单购咖啡月卡
        if(withOrderBuyCoupon3(orderBean, orderExtInfoDto.getThirdPartyMemberId())) {
            orderBean = getOrderBean(confirmOrderDto);
        }

        // 如果是到店，则冻结优惠券
        // 如果是外卖，则核销优惠券
        // 失败重试三次
        if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            List<CouponRedeemResponse> couponRedeemResponseList = couponClientService.redeemBatch(orderBean);

            if (CollectionUtils.isNotEmpty(couponRedeemResponseList)){
                // TODO 记录一下核销失败的券
            }

        } else if(OldOrderType.COLLECT_GOODS.getCode().equals(orderBean.getType()) || OldOrderType.EAT_IN.getCode().equals(orderBean.getType())) {
            List<CouponBaseResponse> couponBaseResponseList = couponClientService.lockBatch(orderBean);

            if (CollectionUtils.isNotEmpty(couponBaseResponseList)){
                // TODO 记录一下冻结失败的券
            }
        }

        //调用基础服务生成第三方订单号
        String downstreamThirdOrderCode = "";
        if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            //调用基础订单接口更新信息
            UpdateDownstreamOrderCodeReq updateDownstreamOrderCodeReq = new UpdateDownstreamOrderCodeReq();
            updateDownstreamOrderCodeReq.setOrderCode(orderBean.getOid());
            OrderBaseResp baseResponse = orderSdkService.updateDownstreamThirdOrderCode(updateDownstreamOrderCodeReq, LogThreadLocal.getTrackingNo());

            LinkedHashMap<String, String> linkedHashMap = (LinkedHashMap) baseResponse.getResult();
            downstreamThirdOrderCode = linkedHashMap.get("downstreamThirdOrderCode");
        }

        // 订单失败后 发消息重试 待实现
        String takeCode;
        String daySeq;
        PayAccessResponse payAccessResponse;
        ConfirmOrderRequest var1 = LightApplicationConvertToAssortmentSdkAdapter.confirmOrderDtoConvertToConfirmOrderRequest(confirmOrderDto, orderBeans.get(OrderBeanType.MERMBERORDER.getCode()));
        var1.setPartnerId(partnerId);
        var1.setStoreId(storeId);
        var1.setOrderType(orderBean.getType());
        var1.setProductOrderCode(orderBean.getOid());
        var1.setPayDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
        var1.setPayTransId(message.getOut_trade_no());
        var1.setOperator(orderBean.getUserName());
        var1.setEndTransId(message.getEndTransId());
        if (StringUtils.isNotBlank(payCode)) {
            var1.setPayChannel(payCode);
            var1.setPayChannelName(PayChannel.getByCode(payCode).getDesc());
        }
        if (orderBean.getGmtExpect() != null && orderBean.getGmtExpect() != 0) {
            var1.setExpectTime(DateUtil.convert2String(new Date(orderBean.getGmtExpect()), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
            if(OldOrderType.COLLECT_GOODS.getCode().equals(orderBean.getType()) || OldOrderType.EAT_IN.getCode().equals(orderBean.getType())) {
                var1.setTimeout(-5);
            }
        }
        // 订单支付成功
        com.freemud.sdk.api.assortment.order.response.order.PayAccessResponse payAccessRes = orderCenterSdkService.payAccessMCCafe(var1);

        String string2 = JSONObject.toJSONString(payAccessRes);
        JSONObject jsonObject2 = JSONObject.parseObject(string2);
        payAccessResponse = jsonObject2.toJavaObject(PayAccessResponse.class);
        // 添加幂等处理，若订单是已支付成功状态，直接返回成功
        if (!RESPONSE_SUCCESS_CODE.equals(payAccessResponse.getErrcode())) {
            OrderBeanV1 saasOrder = getOrderBeanByOrderId(confirmOrderDto.getOrderId()).get(OrderBeanType.SAASORDER.getCode());
            if (saasOrder != null && (!PayStatus.NOT_PAY.getCode().equals(saasOrder.getPayStatus()) || !OrderStatus.WAIT_PAY.getCode().equals(saasOrder.getStatus()))) {
                return sendPaySuccessNoticeMessage();
            }
//            AppLogUtil.errorLog("paySuccessCallback_payAccess_faild", gson.toJson(confirmOrderDto), gson.toJson(payAccessResponse));
            //orderRefund(orderBean, "订单异常退款", openid, oid);
            return gson.toJson(message);
        }

        //麦咖啡支付成功接单
        if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            BaseQueryOrderRequest var2 = new BaseQueryOrderRequest();
            var2.setOrderId(confirmOrderDto.getOrderId());
            var2.setPartnerId(partnerId);
            BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderConfirmTakeMCCafe(var2);
            AppLogUtil.infoLog("paySuccessCallback_orderConfirmTake", gson.toJson(var2), gson.toJson(baseOrderResponse));
        }

        // TODO 订单序号替换取餐码显示
        takeCode = payAccessResponse.getData().getTakeCode();
        daySeq = payAccessResponse.getData().getDaySeq();


        //TODO 清空购物车
        NewShoppingCartClearDto newShoppingCartClearDto = new NewShoppingCartClearDto();
        newShoppingCartClearDto.setPartnerId(partnerId);
        newShoppingCartClearDto.setShopId(storeId);
        newShoppingCartClearDto.setUserId(userId);
        newShoppingCartClearDto.setAppId(wxappid);
        newShoppingCartClearDto.setSessionId(sessionId);
        newShoppingCartClearDto.setOperationType(1);
        shoppingCartClient.clearMCCafeShoppingCart(newShoppingCartClearDto);
        if (StringUtils.isNotBlank(daySeq) && orderExtInfoDto != null && !OrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            String storeAddress = StringUtils.isNotBlank(orderBean.getAddress()) ? orderBean.getAddress() : "";
            orderBean.setAddress(storeAddress);
            orderBean.setOtherCode(takeCode);
            //发送支付成功模板消息
            this.sendPaySuccessMessage(orderBean);
        }
        // 有云打印机 打印小票，杯贴
        try {
            List<AssortmentCloudPrinter> storePrinters = cloudPrinterManager.getStorePrinters(partnerId, storeId);
            if (null != storePrinters && storePrinters.size() > 0) {
                boolean printerStatus = false;
                for (AssortmentCloudPrinter cloudPrinter : storePrinters) {
                    if (null != cloudPrinter.getStatus() && cloudPrinter.getStatus() == 1) {
                        printerStatus = true;
                    }
                }
                //在线打印
                if (printerStatus) {
                    OrderPrintDto orderPrintDto = orderAdapter.convert2OrderPrintDto(orderBean);
                    orderPrintDto.setDaySeq(daySeq);
                    orderPrintDto.setOtherCode(takeCode);
                    asynchronousPrint(orderPrintDto);
                }
            }
        } catch (Exception e) {
            AppLogUtil.errorLog("cloudPrint_error", null, null, e);
        }
        //TODO 埋点支付行为
        BuriedPointPaymentRequestDto requestDto = new BuriedPointPaymentRequestDto();
        requestDto.setStoreId(storeId);
        requestDto.setPartnerId(partnerId);
        requestDto.setWxAppId(wxappid);
        requestDto.setSessionId(sessionId);
        requestDto.setOpenId(orderExtInfoDto != null ? orderExtInfoDto.getOpenid() : "");
        buriedPointService.BuriedPointPayment(requestDto, orderBean);

        if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            //获取门店信息
            StoreResponse storeInfo = storeCenterService.getStoreInfo(new StoreInfoRequest(orderBean.getCompanyId(), orderBean.getShopId()), "");
            if (storeInfo == null || ObjectUtils.notEqual(cn.freemud.management.enums.ResponseResult.SUCCESS.getCode(), storeInfo.getStatusCode().toString()) || storeInfo.getBizVO() == null) {
                return sendPaySuccessNoticeMessage();
            }
            CreateDeliveryVo createDeliveryVo = deliveryAdapter.buildDeliveryOrderRequestDto(orderBean, storeInfo, deliveryCallBackUrl, downstreamThirdOrderCode);
            //创建配送单
            CreateDeliveryOrderResponseDto deliveryResponse = deliveryFeiginClient.deliveryOrderAdd(createDeliveryVo);
            //创建配送单失败，更新订单为异常单
            if (deliveryResponse == null || RESPONSE_SUCCESS_CODE != deliveryResponse.getCode() || deliveryResponse.getData() == null) {
                String deliveryId = deliveryResponse != null && deliveryResponse.getData() != null ? deliveryResponse.getData().getDeliveryId() : "";
                String operator =  "系统" ;
                String abnormalDesc = "配送异常";
                if(null != deliveryResponse && StringUtils.isNotBlank(deliveryResponse.getMsg())) {
                    abnormalDesc = deliveryResponse.getMsg();
                }
                updateDeliveryAbnormal(orderBean.getCompanyId(), orderBean.getOid(), deliveryId, operator, abnormalDesc);
                emailAlertService.sendEmailAlert("创建配送单失败", String.format("request:%s \r\nresponse:%s", JSONObject.toJSONString(createDeliveryVo), JSONObject.toJSONString(deliveryResponse)));
                return sendPaySuccessNoticeMessage();
            } else {
                orderBaseService.updateDeliverySuccess(orderBean.getOid(), deliveryResponse.getData().getDeliveryId(), "系统");
            }
        }

        Header header = new Header(MQAction.INSERT.getAction(), "order-application-service-api",
                "inviter-activity-queue-routing-key", "inviter-activity-queue");
        OrderInfoRequest body = new OrderInfoRequest();
        body.setBizType(orderBean.getBizType());
        body.setExtInfo(orderBean.getExtInfo());
        body.setOrderClient(orderAdapter.getNewOrderClient(orderBean.getSource()));
        body.setOrderCode(orderBean.getOid());
        body.setPartnerId(orderBean.getCompanyId());
        body.setStoreId(orderBean.getShopId());
        body.setUserId(orderBean.getUserId());
        BigDecimal settlementAmount = new BigDecimal(0);
        for(OrderSettlementResp orderSettlementResp : orderBean.getOrderSettlementDetailList()) {
            if(orderSettlementResp.getSettlementType() != null && orderSettlementResp.getSettlementType() != 0 && "0".equals(orderSettlementResp.getProductId())) {
                settlementAmount.add(orderSettlementResp.getSettlementAmount());
            }
        }
        body.setSettlementAmount(settlementAmount);
        MQMessage<OrderInfoRequest> mqMessage = new MQMessage<>(header, body);
        AppLogUtil.infoLog("邀请有礼发消息：",JSON.toJSONString(mqMessage),null);
        mqService.convertAndSend("topic-Exchange", "inviter-activity-queue-routing-key", mqMessage);

        //支付回掉成功标记
        redisCache.save(RedisKeyConstant.KGD_PAYMENT_CALLBACK_FMID + message.getOut_trade_no(), message.getOut_trade_no(), 10L, TimeUnit.MINUTES);
        return sendPaySuccessNoticeMessage();
    }

    private OrderBeanV1 getOrderBean(ConfirmOrderDto confirmOrderDto) {
        Map<String, OrderBeanV1> orderBeans = orderService.getOrderBeanByOrderId(confirmOrderDto.getOrderId());
//        AppLogUtil.debugLotsParams("从缓存重新获取数据,orderId:{},orderBeans:{}", confirmOrderDto.getOrderId(), orderBeans);
        return orderBeans.get(OrderBeanType.SAASORDER.getCode());
    }

    /**
     * 创建配送单一车 -> 更新订单为异常单
     *
     * @param partnerId
     * @param orderCode
     * @param deliveryId
     */
    public void updateDeliveryAbnormal(String partnerId, String orderCode, String deliveryId, String operator, String abnormalDesc) {
        AssortmentUpdateDeliveryAbnormalRequest request = AssortmentUpdateDeliveryAbnormalRequest.builder()
                .abnormalDesc(abnormalDesc)
                .deliveryId(deliveryId)
                .orderCode(orderCode)
                .partnerId(partnerId)
                .operator(StringUtils.isNotBlank(operator) ? operator : "sys")
                .build();
        orderCenterSdkService.updateDeliveryAbnormal(request);
    }


    @Override
    public BaseResponse orderRefund(OrderRefundVo orderRefundVo) {
        if (StringUtils.isEmpty(orderRefundVo.getReason())) {
            orderRefundVo.setReason("用户申请退款");
        }
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(orderRefundVo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String memberId = userInfo.getMemberId();
        String partnerId = userInfo.getPartnerId();

        if (StringUtils.isBlank(orderRefundVo.getOid())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }

        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(orderRefundVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryOrderByIdResponseDto orderByIdResponseDto = jsonObject.toJavaObject(QueryOrderByIdResponseDto.class);
        boolean isSon = StringUtils.isEmpty(orderByIdResponseDto.getData().getParentCode()) || "0".equals(orderByIdResponseDto.getData().getParentCode());
        String orderId = isSon ? orderByIdResponseDto.getData().getOid() : orderByIdResponseDto.getData().getParentCode();
        if (!RESPONSE_SUCCESS_CODE.equals(orderByIdResponseDto.getErrcode()) || orderByIdResponseDto.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "订单信息不存在");
        }
        if (!memberId.equals(orderByIdResponseDto.getData().getUserId())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "不能操作非本人的订单");
        }
        OrderBeanV1 orderBean = orderByIdResponseDto.getData();
        if (PayStatus.NOT_PAY.getCode().equals(orderByIdResponseDto.getData().getPayStatus())
                || OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单未支付，无法退款");
        }
        if (OrderStatus.CALCEL.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单已取消，无法退款");
        }
        if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单已完成，无法退款");
        }
        if(OldOrderType.COLLECT_GOODS.getCode().equals(orderBean.getOrderType()) || OldOrderType.EAT_IN.getCode().equals(orderBean.getOrderType())) {
            if(null == orderBean.getGmtExpect() || orderBean.getGmtExpect().equals(0l)) {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "实时到店订单无法退款");
            } else {
                Date expectTime = new Date(orderBean.getGmtExpect());
                if(expectTime.before(new Date())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "预约到店订单超过预约时间后无法退款");
                }
            }
        }
        List<String> couponCodeList = orderBean.getProductList().stream().filter(o -> ProductTypeEnum.getVirtualProductType().contains(o.getProductType()))
                .map(o -> Arrays.stream(o.getNote().split("/")).collect(Collectors.toList()))
                .reduce(new ArrayList<String>(), (o1, o2) -> {o1.addAll(o2); return o1;});
        if(CollectionUtils.isNotEmpty(couponCodeList)) {
            QueryUseCouponOrderReq queryUseCouponOrderReq = new QueryUseCouponOrderReq();
            queryUseCouponOrderReq.setOrderCode(orderBean.getOid());
            queryUseCouponOrderReq.setPartnerId(orderBean.getCompanyId());
            queryUseCouponOrderReq.setCouponCodeList(couponCodeList);
            OrderBaseResp<Integer> response =  orderSdkService.queryUseCouponOrder(queryUseCouponOrderReq, LogThreadLocal.getTrackingNo());
            if(null != response && ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(response.getCode()) && response.getResult() != 0) {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "优惠券已经在其他订单使用过了，无法退款");
            }
        }

        /**
         * 已接单，制作完成，配送中,未接单，用户可申请退款
         *
         * v1.9.3.1 支持已完成订单可申请退款(通过b端后台控制)
         */
        List<Integer> enableRefundCodes = Lists.newArrayList(Arrays.asList(
                OrderStatus.TAKE_ORDER.getCode(),
                OrderStatus.RECEIPT.getCode(),
                OrderStatus.COMPLETE_MAKE.getCode(),
                OrderStatus.DISTRIBUTION.getCode()
//                ,OrderStatus.COMPLETE.getCode()
        ));

        if (enableRefundCodes.contains(orderBean.getStatus()) && PayStatus.HAVE_PAID.getCode().equals(orderBean.getPayStatus())) {
            if (CollectionUtils.isNotEmpty(orderBean.getRefundList())) {

                for(int i=0;i<orderBean.getRefundList().size();i++) {
                    RefundBeanV1 refundBean = orderBean.getRefundList().get(i);
                    if (RefundStatus.COMPLETE_REFUND.getCode().equals(refundBean.getStatus())) {
                        return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单已退款完成，无法再次退款");
                    }
                    if (RefundStatus.APPLY_REFUND.getCode().equals(refundBean.getStatus())) {
                        return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "商家正在处理中，请稍后……");
                    }
                    if(new Date().getTime() - Long.valueOf(refundBean.getCreateTime()) < Long.valueOf(mccafeRefundInterval)) {
                        return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "退款请求太频繁，请稍后再试");
                    }
                }
//                if (RefundStatus.REFUSE_REFUND.getCode().equals(refundBean.getStatus())) {
//                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "您的申请已被商家拒绝，请联系门店沟通。");
//                }
            }
//            List<AssortmentOpenPlatformPartnerWxappConfig> partnerWxappConfigs = cacheOpenPlatformPartnerWxappConfigManager.cacheSelectDefaultPage(userInfo.getWxAppId(), "2");

//            Map<String, AssortmentOpenPlatformPartnerWxappConfig> configMap = partnerWxappConfigs.stream().collect(Collectors.toMap(AssortmentOpenPlatformPartnerWxappConfig::getAppKey, Function.identity()));

            //是否退配送费  麦咖啡必退配送费
            boolean isRefundDeliveryFee = true;
//            AssortmentOpenPlatformPartnerWxappConfig refundDeliveryFeeConfig = configMap.get(OrderRefundEnum.REFUND_DELIVERY_FEE_ENABLE.getKeyValue());
//            LogUtil.info("orderRefund of oid:{}, {}, {}", orderBean.getOid(),orderBean.getStatus(), (null != refundDeliveryFeeConfig ? ToStringBuilder.reflectionToString(refundDeliveryFeeConfig) : null));
//            // 0、null表示 关闭 ; 1 表示开启
//            if (null != refundDeliveryFeeConfig
//                    && Arrays.asList(OrderStatus.DISTRIBUTION.getCode()).contains(orderBean.getStatus())
//                    && !ALLOW_REFUND.equals(refundDeliveryFeeConfig.getAppValue())) {
//                isRefundDeliveryFee = false;
//            }

            //申请取消配送单/取消配送单
            BaseResponseDto deliveryBaseResponse = new BaseResponseDto();
            if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType())) {
                deliveryBaseResponse = cancelDelivery(orderBean);
                if(!ResponseConstant.SUCCESS_RESPONSE_CODE.equals(deliveryBaseResponse.getErrcode())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "取消配送单失败，退款失败");
                }
            }

            //
            if ((OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType()) && CancelDeliveryResponseDto.notCollectMsg.equals(deliveryBaseResponse.getErrmsg()))
                    || OldOrderType.COLLECT_GOODS.getCode().equals(orderBean.getOrderType())
                    || OldOrderType.EAT_IN.getCode().equals(orderBean.getOrderType())) {
                //商家未接单逻辑处理    1.调用支付退款 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
                BaseResponse baseResponse = partnerNoTakeOrder(orderRefundVo, orderBean, orderId,AfterSalesType.USER_CANCEL,isRefundDeliveryFee);
                if (baseResponse != null) {
                    return baseResponse;
                }
                // 删除订单 通知活动添加商品库存
                backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
            } else if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType()) && CancelDeliveryResponseDto.hasCollectMsg.equals(deliveryBaseResponse.getErrmsg())) {

                OrderRefundRequest orderRefundRequest = new OrderRefundRequest();
                orderRefundRequest.setPartnerId(orderBean.getCompanyId());
                orderRefundRequest.setStoreId(orderBean.getShopId());
                orderRefundRequest.setOrderId(orderBean.getOid());
                orderRefundRequest.setOrderClient(OrderClientType.SAAS.getIndex());

                orderRefundRequest.setAfterSalesType(AfterSalesType.USER_CANCEL);
                orderRefundRequest.setReason(orderRefundVo.getReason());
                orderRefundRequest.setRemark(orderRefundVo.getRemarks());
                orderRefundRequest.setOperator(orderBean.getUserName());
                orderRefundRequest.setOrderStatus(orderBean.getStatus());
                orderRefundRequest.setActualAmount(orderBean.getAmount());
                orderRefundRequest.setReqAmount(orderBean.getAmount());

                BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderRefund(orderRefundRequest);
                if (baseOrderResponse == null || baseOrderResponse.getData() == null || !ObjectUtils.equals(ResponseConstant.SUCCESS_RESPONSE_CODE, baseOrderResponse.getErrcode())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "创建售后单失败");
                }
//                if (orderBean.getAmount() > 0) {
//                    sendPosMessage(partnerId, orderBean.getShopId());
//                }
                //通知小助手发送申请退款公众号订阅消息
                sendApplyRefundSubscriptionNotice(orderBean, orderRefundVo);
                //已接单可发起退款申请，查询门店有无云打印机，有则打印退款申请小票
                printApplyRefundSmallTicket(orderBean, orderRefundVo);
            } else {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单状态异常，退款失败");
            }
        }
        return ResponseUtil.success();
    }

    /**
     * 商家未接单,取消订单逻辑处理    1.调用支付退款 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
     *
     * @param orderRefundVo
     * @param orderBean
     */
    private BaseResponse partnerNoTakeOrder(OrderRefundVo orderRefundVo, OrderBeanV1 orderBean, String fatherOrderId,AfterSalesType afterSalesType,Boolean isRefundDeliveryFee) {
        com.freemud.application.sdk.api.base.BaseResponse<OrderRefundResponse> response = null;
        Long refundId = System.currentTimeMillis();
        String partnerId = orderBean.getCompanyId();
        int state = PayRefundStatus.SUCCESS.getCode();

        if (orderBean.getAmount() != 0) {
            //调用支付退款
            com.freemud.sdk.api.assortment.payment.request.OrderRefundRequest orderPayRefundRequest = orderAdapter.getOrderPayRefundRequest(orderBean, refundId, fatherOrderId);
            Map<String, String> extendParams = new HashMap<>();
            if(OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType())) {
                extendParams.put("mealType", "delivery");
            } else {
                extendParams.put("mealType", "pickup");
            }
            orderPayRefundRequest.setExtendParams(extendParams);
            response = payService.orderRefund(orderPayRefundRequest);
            if (response == null || response.getData() == null || !com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(response.getCode())) {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "orderRefund_failed");
            }
            //获取支付返回退款状态
            state = response.getData().getRefundStatus() == null ? PayRefundStatus.SUCCESS.getCode() : response.getData().getRefundStatus();
        }
        CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(),
                partnerId, afterSalesType, orderRefundVo.getReason(), LogThreadLocal.getTrackingNo(), refundId.toString());
        cancelOrderRequest.setOperator(orderBean.getUserName());
        cancelOrderRequest.setPartnerId(orderBean.getCompanyId());
        if (PayRefundStatus.SUCCESS.getCode().intValue() == state) {
            //退款成功
            cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.REFUND_COMPLETE.getCreateEvent());
        }
        cancelOrderRequest.setReqRemark(orderRefundVo.getRemarks());
        cancelOrderRequest.setRefundDeliveryAmount(isRefundDeliveryFee);
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderCancel(cancelOrderRequest);
        if (baseOrderResponse == null || baseOrderResponse.getData() == null || !ObjectUtils.equals(ResponseConstant.SUCCESS_RESPONSE_CODE, baseOrderResponse.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "orderRefund_failed");
        }
        return null;
    }

    @Override
    public String mcCafeRefundNotifyCallback(RefundNotifyCallbackRequestVo requestVo) {
        if (StringUtils.isEmpty(requestVo.getTransId())) {
            //订单号不能为空
            return refundFailedMessage("transId is can not empty");
        }
        //混合支付需要从缓存中获取订单号码，正常支付TransId = orderId
        String orderId = redisCache.getValue(RedisUtil.getPaymentTransIdOrderKey(requestVo.getTransId()));
        if(StringUtils.isNotEmpty(orderId)){
            requestVo.setTransId(orderId);
        }
        String trackingNo = LogThreadLocal.getTrackingNo();
        if (!Objects.equals(requestVo.getRefundStatus(), RefundStatus.COMPLETE_REFUND.getCode())) {
            //只有退款成功更新状态.其他情况不处理
            return refundFailedMessage("pay refundStatus is not 4,refundStatus=" + requestVo.getRefundStatus());
        }
        // 如果transId为空,返回失败
        if (StringUtils.isBlank(requestVo.getTransId())) {
            return refundFailedMessage("transId is empty " + requestVo);
        }
        //查询订单详情
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = getQueryRelationOrderByIdResponseDto(requestVo.getTransId());
        if (queryOrderByIdResponseDto.getData() == null || !Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS, queryOrderByIdResponseDto.getErrcode())) {
            return refundFailedMessage("order query fail " + queryOrderByIdResponseDto);
        }

        OrderBeanV1 orderBean = new OrderBeanV1();
        if (1 == queryOrderByIdResponseDto.getData().size()) {
            orderBean = queryOrderByIdResponseDto.getData().get(0);
        } else {
            List<OrderBeanV1> orderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(orderBeans)) {
                orderBean = orderBeans.get(0);
            }
        }

//        PlatformBaseRequest platformBaseRequest = getRequest(orderBean);

        OrderRefundRequest orderRefundRequest = new OrderRefundRequest();
        orderRefundRequest.setPartnerId(orderBean.getCompanyId());
        orderRefundRequest.setStoreId(orderBean.getShopId());
        orderRefundRequest.setOrderId(orderBean.getOid());
        orderRefundRequest.setOrderClient(OrderClientType.SAAS.getIndex());

        orderRefundRequest.setAfterSalesType(AfterSalesType.USER_CANCEL);
        orderRefundRequest.setReason("门店线下退款");
        orderRefundRequest.setOperator("门店营业人员");
        orderRefundRequest.setOrderStatus(orderBean.getStatus());
        orderRefundRequest.setActualAmount(orderBean.getAmount());
        orderRefundRequest.setReqAmount(orderBean.getAmount());
        orderRefundRequest.setTrackingNo(trackingNo);
        orderRefundRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.REFUND_COMPLETE.getCreateEvent());

        BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderRefund(orderRefundRequest);

        if (baseOrderResponse == null || baseOrderResponse.getData() == null || !ObjectUtils.equals(ResponseConstant.SUCCESS_RESPONSE_CODE, baseOrderResponse.getErrcode())) {
            AppLogUtil.infoLog("mcCafeRefundNotifyCallback", orderRefundRequest, baseOrderResponse);
            return refundFailedMessage("create after sale order failed");
        }
        return newSendPaySuccessNoticeMessage();
    }


    /**
     * 麦咖啡查询订单详情
     *
     * @param queryOrderVo
     * @return
     */
    @Override
    public BaseResponse mcCafeQueryOrderById(MaCafeQueryOrderVo queryOrderVo) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(queryOrderVo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String oid = queryOrderVo.getOid();
        if (StringUtils.isBlank(oid)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(oid);
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryOrderByIdResponse response = orderCenterSdkService.queryMCCafeOrderById(baseQueryOrderRequest);
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBeanV1 orderBean = response.getData();
        String storeId = orderBean.getShopId();
        StoreInfoRequest request = new StoreInfoRequest();
        request.setPartnerId(queryOrderVo.getPartnerId());
        request.setStoreCode(storeId);
        StoreResponse storeInfo = storeCenterService.getStoreInfo(request, LogThreadLocal.getTrackingNo());
        if (storeInfo != null && storeInfo.getBizVO() != null) {
            StoreResponse.BizVO storeResponseDto = storeInfo.getBizVO();
            orderBean.setShopAddress(storeResponseDto.getAddress());
            orderBean.setShopPhone(storeResponseDto.getPhone());
            orderBean.setShopImageUrl(storeResponseDto.getLogoUrl());
            //默认骑手头像显示为门店首页图片
            orderBean.setRiderPhoto(storeResponseDto.getLogoUrl());
            orderBean.setShopPhone(storeResponseDto.getPhone());
            orderBean.setLatitude(Double.valueOf(storeResponseDto.getLatitude()));
            orderBean.setLongitude(Double.valueOf(storeResponseDto.getLongitude()));
        }

        BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
        var1.setOrderId(orderBean.getOid());
        var1.setTrackingNo(LogThreadLocal.getTrackingNo());
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.queryOrderQueueIndex(var1);
        QueryOrderQueueIndexResponse response1 = new QueryOrderQueueIndexResponse();
        response1.setErrcode(baseOrderResponse.getErrcode());
        response1.setErrmsg(baseOrderResponse.getErrmsg());
        if (RESPONSE_SUCCESS_CODE.equals(response1.getErrcode())) {
            String queueIndex = response1.getData() == null ? "" : response1.getData().toString();
            orderBean.setQueueIndex(queueIndex);
        }
        //  获取订单运单号，如果有运单则是第三方外卖单
        if (orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getDeliveryId())) {
            hasThirdDelivery(orderBean);
        }
        // 查询订单的操作状态
        OrderStatusTrackingInfoResponse statusTrackingInfoByOid = orderCenterSdkService.getOrderStatusTrackingInfoByOid(var1);
        String string2 = JSONObject.toJSONString(statusTrackingInfoByOid);
        JSONObject jsonObject2 = JSONObject.parseObject(string2);
        OrderStatusTrackingInfoDto orderStatusTrackingInfoByOid = jsonObject2.toJavaObject(OrderStatusTrackingInfoDto.class);

        if (RESPONSE_SUCCESS_CODE.equals(orderStatusTrackingInfoByOid.getErrcode())) {
            orderStatusTracking(orderBean, orderStatusTrackingInfoByOid);
        }

        List<QueryOrderResponseVo> queryOrderResponseVos = orderAdapter.convent2QueryOrderResponseVos(Collections.singletonList(orderBean), userInfo.getWxAppId(), userInfo.getIappId());
        if (CollectionUtils.isEmpty(queryOrderResponseVos)) {
            throw new ServiceException(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        QueryOrderResponseVo queryOrderResponseVo = queryOrderResponseVos.get(0);

        Optional<ProductVo> productVoOptional = queryOrderResponseVo.getProducts().stream()
                .filter(o -> StringUtils.isNotBlank(o.getSplitIndex()))
                .findFirst();
        Map<String, Integer> existMap = new HashMap<>();

        if (productVoOptional.isPresent()) {
            int size = queryOrderResponseVo.getProducts().size();
            List<ProductVo> productVoList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                ProductVo productVo = queryOrderResponseVo.getProducts().get(i);
                if (StringUtils.isBlank(productVo.getSplitIndex())) {
                    productVoList.add(productVo);
                } else {
                    if (existMap.get(productVo.getSplitIndex()) == null) {
                        existMap.put(productVo.getSplitIndex(), productVoList.size());
                        productVoList.add(productVo);
                    } else {
                        ProductVo productVoExists = productVoList.get(existMap.get(productVo.getSplitIndex()));
                        productVoExists.setOriginalTotalAmount(productVoExists.getOriginalTotalAmount() + productVo.getOriginalTotalAmount());
                        productVoExists.setSaleTotalAmount(productVoExists.getSaleTotalAmount() + productVo.getSaleTotalAmount());
                        productVoExists.setQty(productVoExists.getQty() + productVo.getQty());
                    }
                }
            }
            queryOrderResponseVo.setProducts(productVoList);
        }

        //麦咖啡 预约外卖单重新封装取餐时间
        if (OrderType.TAKE_OUT.getCode().equals(queryOrderResponseVo.getOrderType()) && StringUtils.isNotEmpty(queryOrderResponseVo.getReserveDeliveryTime())) {
            Date reserveDeliveryTime = DateUtil.convert2Date(queryOrderResponseVo.getReserveDeliveryTime(), "yyyy-MM-dd HH:mm:ss");
            queryOrderResponseVo.setReserveDeliveryTime(formatSpecialDate(reserveDeliveryTime));
        }

        if (OrderStatus.TAKE_ORDER.getCode().equals(queryOrderResponseVo.getOrderStatus())
                || OrderStatus.WAIT_PAY.getCode().equals(queryOrderResponseVo.getOrderStatus())) {
            queryOrderResponseVo.setTakeCode("");
        }

        queryOrderResponseVo.setOrderTypeDesc(Optional.ofNullable(McCafeOrderTypeGather.getByCode(queryOrderResponseVo.getOrderType()))
                .map(McCafeOrderTypeGather::getDesc).orElse(""));

        queryOrderResponseVo.setIsCouponOrder(queryOrderResponseVo.getProducts().stream()
                .filter(o -> !ProductTypeEnum.getVirtualProductType().contains(o.getProductType())).findAny().isPresent() ? 0 : 1);

        //48小时自动退款描述
        if (storeInfo != null && storeInfo.getBizVO() != null && storeInfo.getBizVO().getStoreConfig() != null
                && queryOrderResponseVo.getRefundStatus() != null && queryOrderResponseVo.getRefundStatus() == 1) {
            Integer automaticRefund = storeInfo.getBizVO().getStoreConfig().getAutomaticRefund();
            if (automaticRefund != null && automaticRefund == 1) {
                queryOrderResponseVo.setRefundTips("若48小时内未成功退款，请联系商家人工处理");
            } else {
                queryOrderResponseVo.setRefundTips("若48小时内未成功退款，请联系商家人工处理");
            }
        }

        return ResponseUtil.success(queryOrderResponseVo);
    }


    @Override
    public BaseResponse mcCafeQueryOrders(McCafeQueryOrderVo queryOrderVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        if (StringUtils.isBlank(queryOrderVo.getStartDate())) {
            queryOrderVo.setStartDate(DateUtil.convert2String(DateUtil.addMonths(new Date(), -1), "yyyy-MM-dd"));
        }
        if (StringUtils.isBlank(queryOrderVo.getEndDate())) {
            queryOrderVo.setEndDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd"));
        }
        if (CollectionUtils.isEmpty(queryOrderVo.getQueryOrderStatus())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "查询订单状态不能为空");
        }
        if (CollectionUtils.isNotEmpty(queryOrderVo.getQueryOrderType())) {
            if (CollectionUtils.isEmpty(OrderType.getByCode(queryOrderVo.getQueryOrderType()))) {
                return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "查询订单类型不存在");
            }
        }
        String partnerId = queryOrderVo.getPartnerId();
        String startDateStr = queryOrderVo.getStartDate() + " 00:00:00";
        String endDateStr = queryOrderVo.getEndDate() + " 23:59:59";
        Date startDate = DateUtil.convert2Date(startDateStr, "yyyy-MM-dd HH:mm:ss");
        if (startDate == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单开始时间格式不正确");
        }
        Date endDate = DateUtil.convert2Date(endDateStr, "yyyy-MM-dd HH:mm:ss");
        if (endDate == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单结束时间格式不正确");
        }
        if (startDate.getTime() < DateUtil.addMonths(new Date(), -3).getTime()) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "只能查询3个月内的订单信息");
        }
        String userId = userLoginInfoDto.getMemberId();
        queryOrderVo.setStartDate(startDateStr);
        queryOrderVo.setEndDate(endDateStr);
        QueryOrderVo vo = new QueryOrderVo();
        BeanUtils.copyProperties(queryOrderVo, vo);
        String channelType = this.getQueryOrderChannelType(vo, userLoginInfoDto);
        QueryOrdersDto queryOrdersDto = orderAdapter.convent2QueryOrdersDtoMcCafe(queryOrderVo, userId, channelType);
        QueryOrdersResponse queryOrderResponse;
        try {
            QueryOrdersRequest queryOrdersRequest2 = new QueryOrdersRequest();
            BeanUtil.convertBean(queryOrdersDto, queryOrdersRequest2);
            queryOrdersRequest2.setTrackingNo(LogThreadLocal.getTrackingNo());
            queryOrderResponse = orderCenterSdkService.queryMCCafeOrders(queryOrdersRequest2);
        } catch (Exception e) {
            AppLogUtil.errorLog("queryOrders_error", gson.toJson(queryOrdersDto), null,e);
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        if (queryOrderResponse == null || !RESPONSE_SUCCESS_CODE.equals(queryOrderResponse.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode());
        }
        Map<String, Object> responseMap = Maps.newTreeMap();
        //用户无订单数据
        if (queryOrderResponse.getData() == null || queryOrderResponse.getData().getCount() == 0) {
            responseMap.put("count", 0);
            responseMap.put("list", new ArrayList<QueryOrderResponseVo>());
            return ResponseUtil.success(responseMap);
        }
        List<OrderBeanV1> orders = queryOrderResponse.getData().getOrders();
        Set<String> shopIds = new HashSet<>();
        // 过滤待支付订单
        if (CollectionUtils.isNotEmpty(orders)) {
            for (OrderBeanV1 orderBean : orders) {
                if (!(OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus()) || PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()))) {
                    shopIds.add(orderBean.getShopId());
                }
            }
        }
        String storeCodes = "";
        for (String shopId : shopIds) {
            storeCodes = shopId + "," + storeCodes;
        }
        GetListByCodesRequest request = new GetListByCodesRequest();
        request.setPartnerId(partnerId);
        request.setStoreCodes(storeCodes);
        // 查询多个门店信息
        GetListByCodesResponse storeInfoResponse = storeCenterService.getListByCodes(request, LogThreadLocal.getTrackingNo());
        Map<String, StoreResponse.BizVO> storeMap = new HashMap<>();
        if (storeInfoResponse != null && storeInfoResponse.getBizVO() != null && storeInfoResponse.getBizVO().getList() != null) {
            for (StoreResponse.BizVO bizVO : storeInfoResponse.getBizVO().getList()) {
                storeMap.put(bizVO.getStoreCode(), bizVO);
            }
        }
        if (CollectionUtils.isNotEmpty(orders)) {
            orders.forEach(orderBean -> {
                StoreResponse.BizVO storeResponseDto = storeMap.get(orderBean.getShopId());
                if (storeResponseDto != null) {
                    orderBean.setShopAddress(storeResponseDto.getAddress());
                    orderBean.setShopPhone(storeResponseDto.getPhone());
                    orderBean.setShopImageUrl(storeResponseDto.getLogoUrl());
                    //默认骑手头像显示为门店首页图片
                    orderBean.setRiderPhoto(storeResponseDto.getLogoUrl());
                    orderBean.setLatitude(Double.valueOf(storeResponseDto.getLatitude()));
                    orderBean.setLongitude(Double.valueOf(storeResponseDto.getLongitude()));
                }
                // 获取订单运单号，如果有运单则是第三方外卖单
                if (orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getDeliveryId())) {
                    hasThirdDelivery(orderBean);
                }
                orderBean.setQueueIndex("");
                // 查询待取餐订单才需要查询排队人数和订单状态扭转记录
                if (QueryOrderStatus.TAKE_MEAL.getCode().equals(orderBean.getOrderType())) {
                    // 查询订单的排队人数
                    BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
                    var1.setOrderId(orderBean.getOid());
                    var1.setTrackingNo(LogThreadLocal.getTrackingNo());
                    BaseOrderResponse baseOrderResponse = orderCenterSdkService.queryOrderQueueIndex(var1);
                    QueryOrderQueueIndexResponse response = new QueryOrderQueueIndexResponse();
                    response.setErrcode(baseOrderResponse.getErrcode());
                    response.setErrmsg(baseOrderResponse.getErrmsg());
                    response.setData(baseOrderResponse.getData() == null ? 0 : Integer.parseInt(baseOrderResponse.getData()));
                    if (RESPONSE_SUCCESS_CODE.equals(response.getErrcode())) {
                        String queueIndex = response.getData() == null ? "" : response.getData().toString();
                        orderBean.setQueueIndex(queueIndex);
                    }
                    // 查询订单的操作状态
                    BaseQueryOrderRequest var2 = new BaseQueryOrderRequest();
                    var2.setOrderId(orderBean.getOid());
                    var2.setTrackingNo(LogThreadLocal.getTrackingNo());
                    OrderStatusTrackingInfoResponse orderStatusTrackingInfoResponse = orderCenterSdkService.getOrderStatusTrackingInfoByOid(var2);

                    String string = JSONObject.toJSONString(orderStatusTrackingInfoResponse);
                    JSONObject jsonObject = JSONObject.parseObject(string);
                    OrderStatusTrackingInfoDto orderStatusTrackingInfoByOid = jsonObject.toJavaObject(OrderStatusTrackingInfoDto.class);
                    if (RESPONSE_SUCCESS_CODE.equals(orderStatusTrackingInfoByOid.getErrcode())) {
                        orderStatusTracking(orderBean, orderStatusTrackingInfoByOid);
                    }
                }
                if (OrderStatus.TAKE_ORDER.getCode().equals(orderBean.getStatus())
                        || OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
                    orderBean.setOtherCode("");
                }
            });
        }

        List<QueryOrderResponseVo> queryOrderResponseVos = orderAdapter.convent2QueryOrderResponseVos(orders, userLoginInfoDto.getWxAppId(), userLoginInfoDto.getIappId());

        responseMap.put("count", queryOrderResponse.getData() == null ? 0 : queryOrderResponse.getData().getCount());
        responseMap.put("list", queryOrderResponseVos);
        //只有有订单时才显示用户自定义取餐信息
        if (CollectionUtils.isNotEmpty(queryOrderResponseVos)) {
            responseMap.put("definitionMsg", getDefinitionMsg(queryOrderVo.getPartnerId()));
        }
        return ResponseUtil.success(responseMap);
    }

    /**
     * 获取商户自定义提示信息配置
     *
     * @param partnerId
     * @return
     */
    public String getDefinitionMsg(String partnerId) {
        String definitionMsgKey = "partner_definition_msg";
        AssortmentOpenPlatformPartnerConfig partnerConfig = openPlatformPartnerConfigManager.selectPartnerConfigByPartnerKey(partnerId, definitionMsgKey, 1);
        if (partnerConfig == null) {
            return null;
        }
        return partnerConfig.getPartnerValue();
    }

    /**
     * 如果有第三方配送，返回值添加第三方配送信息
     */
    private void hasThirdDelivery(OrderBeanV1 orderBean) {
        String deliveryId = orderBean.getAddInfo().getDeliveryId();
        if ("0".equals(deliveryId)) {
            return;
        }
        QueryDeliveryBaseRequest queryDeliveryBaseRequest = new QueryDeliveryBaseRequest();
        queryDeliveryBaseRequest.setDeliveryId(deliveryId);
        queryDeliveryBaseRequest.setOpenDistance(1);
        //变更查询配送信息换新接口 wanghanghang  20210129
        //【ID1021981】C端小程序配送显示骑手、商家坐标地图、配送距离以及骑手姓名电话，支持直接拨打
        DeliveryBaseResponse<DeliveryStatusAndRiderPositionDto> deliveryBaseResponse = deliveryFeiginClient.getDeliveryStatusAndRiderPosition(queryDeliveryBaseRequest);
//        DeliveryResponseDto<DeliveryInfoDto> delivery = deliveryService.deliveryOrderOne(deliveryId, trackingNo);
        if (RESPONSE_SUCCESS_CODE.equals(deliveryBaseResponse.getCode()) && deliveryBaseResponse.getData() != null) {
            DeliveryStatusAndRiderPositionDto result = deliveryBaseResponse.getData();
            orderBean.setDeliverStatus(result.getDevlieryStatus());
            orderBean.setRiderName(result.getRiderName());
            orderBean.setRiderPhone(result.getRiderPhone());
            orderBean.setReceiveTime(result.getReceiveTime());
            orderBean.setDepatchTime(result.getDepatchTime());
            orderBean.setArriveShopTime(result.getArriveShopTime());
            orderBean.setSendTime(result.getSendTime());
            orderBean.setCompleteTime(result.getCompleteTime());

            /** 只有配送状态是2 3 4 5时，返回三方坐标信息
             * 此处如果是外卖单，则需要返回门店经纬度/用户经纬度/骑手经纬度
             * 门店经纬度 = 配送返回信息为准，外卖单独新增门店经纬度字段，和配送信息接口统一 /queryOrderRider
             * wanghanghang 20210129
             */
            if (result.getDevlieryStatus().equals(DeliveryStatus.ALLOTRIDER.getCode()) ||
                    result.getDevlieryStatus().equals(DeliveryStatus.RIDERARRIVESTORE.getCode()) ||
                    result.getDevlieryStatus().equals(DeliveryStatus.RIDERGETMEAL.getCode()) ||
                    result.getDevlieryStatus().equals(DeliveryStatus.RIDERSTARTDELIVERY.getCode())
            ) {
                orderBean.getAddInfo().setDeliverStatus(result.getDevlieryStatus());
                orderBean.getAddInfo().setDistance(deliveryBaseResponse.getData().getDistance());
                orderBean.getAddInfo().setDuration(deliveryBaseResponse.getData().getDuration());
                orderBean.getAddInfo().setStoreDistance(deliveryBaseResponse.getData().getStoreDistance());
                orderBean.getAddInfo().setStoreDuration(deliveryBaseResponse.getData().getStoreDuration());
                orderBean.getAddInfo().setRiderName(result.getRiderName());
                orderBean.getAddInfo().setRiderPhone(result.getRiderPhone());
                orderBean.getAddInfo().setOrderId(orderBean.getOid());
                orderBean.getAddInfo().setStorePhone(result.getStorePhone());
                //门店经纬度
                if (deliveryBaseResponse.getData().getStorePoint() != null) {
                    String[] storePoint = deliveryBaseResponse.getData().getStorePoint().split(",");
                    orderBean.getAddInfo().setShopLongitude(storePoint[0]);
                    orderBean.getAddInfo().setShopLatitude(storePoint[1]);
                }
                //骑手经纬度
                if (deliveryBaseResponse.getData().getCurrentPoint() != null) {
                    String[] currentPoint = deliveryBaseResponse.getData().getCurrentPoint().split(",");
                    orderBean.getAddInfo().setRiderLongitude(currentPoint[0]);
                    orderBean.getAddInfo().setRiderLatitude(currentPoint[1]);
                }
                //用户经纬度
                if (deliveryBaseResponse.getData().getDestPoint() != null) {
                    String[] destPoint = deliveryBaseResponse.getData().getDestPoint().split(",");
                    orderBean.getAddInfo().setDestLongitude(destPoint[0]);
                    orderBean.getAddInfo().setDestLatitude(destPoint[1]);
                }
            }
        }

    }

    private void orderStatusTracking(OrderBeanV1 orderBean, OrderStatusTrackingInfoDto orderStatusTrackingInfoByOid) {
        List<OrderStatusTrackingInfoDto.OrderStatusTrackingInfo> data = orderStatusTrackingInfoByOid.getData();
        if (CollectionUtils.isNotEmpty(data)) {
            for (OrderStatusTrackingInfoDto.OrderStatusTrackingInfo orderStatusTrackingInfo : data) {
                Integer status = orderStatusTrackingInfo.getStatus();
                String statusTime = orderStatusTrackingInfo.getStatusTime();
                switch (status) {
                    case 1:
                        orderBean.setOperateTakeOrderTime(statusTime);
                        break;
                    case 2:
                        orderBean.setOperateWaitPayTime(statusTime);
                        break;
                    case 3:
                        orderBean.setOperateReceiptTime(statusTime);
                        break;
                    case 4:
                        orderBean.setOperateDistributionTime(statusTime);
                        break;
                    case 5:
                        orderBean.setOperateCompleteTime(statusTime);
                        break;
                    case 6:
                        orderBean.setOperateCalcelTime(statusTime);
                        break;
                    case 7:
                        orderBean.setOperatePefuseTime(statusTime);
                        break;
                    case 31:
                        orderBean.setOperateCompleteMakeTime(statusTime);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public static String formatSpecialDate(Date date) {
        if (date == null) {
            return null;
        }
        DateTime now = new DateTime();
        DateTime today_start = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), 0, 0, 0);
        DateTime today_end = today_start.plusDays(1);
        DateTime tomorrow_start = today_start.plusDays(2);

        if (date.after(today_start.toDate()) && date.before(today_end.toDate())) {
            return String.format("%s", new DateTime(date).toString("HH:mm"));
        } else if (date.after(today_end.toDate()) && date.before(tomorrow_start.toDate())) {
            return String.format("明天%s%s", DateUtils.getDayWeek(date), new DateTime(date).toString("HH:mm"));
        }
        return new DateTime(date).toString("yyyy-MM-dd") + DateUtils.getDayWeek(date) + new DateTime(date).toString("HH:mm");
    }

    /**
     * 取消配送
     *
     * @param orderBean
     * @return
     */
    public BaseResponseDto cancelDelivery(OrderBeanV1 orderBean) {
        BaseResponseDto baseResponseDto = new BaseResponseDto();
        baseResponseDto.setErrcode(100);
        if (orderBean.getType() == 1 && orderBean.getAddInfo() != null) {
            Integer deliverStatus = orderBean.getDeliverStatus();
            if (ObjectUtils.equals(cn.freemud.management.enums.DeliveryStatus.DELIVERYERROR.getCode(), deliverStatus)) {
                baseResponseDto.setErrmsg(CancelDeliveryResponseDto.notCollectMsg);
                return baseResponseDto;
            }
            if (ObjectUtils.equals(cn.freemud.management.enums.DeliveryStatus.DELIVERYCANCEL.getCode(), deliverStatus)
                    || ObjectUtils.equals(cn.freemud.management.enums.DeliveryStatus.DELIVERYARRIVED.getCode(), deliverStatus)) {
                return baseResponseDto;
            }

            CancelDeliveryRequest cancelDeliveryRequest = CancelDeliveryRequest.builder()
                    .displayOrderId(orderBean.getDownstreamThirdOrderCode())
                    .orderId(orderBean.getOid())
                    .orderCancelCode("4")
                    .orderCancelDescription("用户申请退款")
                    .storeId(orderBean.getShopId())
                    .deliveryId(orderBean.getAddInfo().getDeliveryId())
                    .reviewId(orderBean.getOid().substring(0, 20))
                    .build();
            CancelDeliveryResponseDto deliveryBaseResponse = deliveryFeiginMCCafeClient.cancelRequest(cancelDeliveryRequest);
            baseResponseDto.setErrcode(deliveryBaseResponse.getCode());
            baseResponseDto.setErrmsg(deliveryBaseResponse.getMsg());

            if (deliveryBaseResponse == null || !ResponseConstant.SUCCESS_RESPONSE_CODE.equals(deliveryBaseResponse.getCode())) {
                AppLogUtil.infoLog("申请取消配送单失败", cancelDeliveryRequest, deliveryBaseResponse);
                return baseResponseDto;
            }
        }
        return baseResponseDto;
    }

    /**
     * 退款中回调失败返回信息
     */
    public String refundFailedMessage(String errorMes) {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 102);
        map.put("message", "failed:" + errorMes);
        return gson.toJson(map);
    }

    /**
     * 通知小助手发送申请退款公众号订阅消息
     * @param orderBean
     */
    public void sendApplyRefundSubscriptionNotice(OrderBeanV1 orderBean,OrderRefundVo request) {
        String partnerId = orderBean.getCompanyId();
        String shopId = orderBean.getShopId();
        if(orderBean.getExtInfo() == null){
            return;
        }
        OrderExtInfoDto extInfo = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
        if(extInfo == null || extInfo.getAppid() == null){
            return;
        }
        AssortmentOpenPlatformWxappAuthorizer authorizerAppid = wxappAuthorizerManager.findAuthorizerByWxAppId(extInfo.getAppid());
        if(authorizerAppid == null){
            return;
        }
        String accessToken = authorizerAppid.getAuthorizerAccessToken();
        String orderId = orderBean.getOid();
        MpTemplateMsg template = new MpTemplateMsg();
        MpTemplateMsg.TemplateMsgData data = new MpTemplateMsg.TemplateMsgData();
        MpTemplateMsgDataValue first = new MpTemplateMsgDataValue();
        first.setValue("用户申请退款");
        MpTemplateMsgDataValue keyword1 = new MpTemplateMsgDataValue();
        keyword1.setValue(orderId);
        MpTemplateMsgDataValue keyword2 = new MpTemplateMsgDataValue();
        Double amount = orderBean.getAmount() / 100.0D;
        keyword2.setValue(amount.toString()+ " 元");
        MpTemplateMsgDataValue keyword3 = new MpTemplateMsgDataValue();
        keyword3.setValue(orderBean.getGmtPay() == null ? "" : DateUtil.convert2String(new Date(orderBean.getGmtPay()), "yyyy-MM-dd HH:mm:ss"));
        MpTemplateMsgDataValue keyword4 = new MpTemplateMsgDataValue();
        keyword4.setValue(orderBean.getUserName());
        MpTemplateMsgDataValue keyword5 = new MpTemplateMsgDataValue();
        keyword5.setValue(orderBean.getPhone());
        MpTemplateMsgDataValue remark = new MpTemplateMsgDataValue();
        remark.setValue(request.getReason()+","+request.getRemarks());
        data.setFirst(first);
        data.setKeyword1(keyword1);
        data.setKeyword2(keyword2);
        data.setKeyword3(keyword3);
        data.setKeyword4(keyword4);
        data.setKeyword5(keyword5);
        data.setRemark(remark);
        template.setData(data);
        MessagePushNewMqBody messagePushMqBody = new MessagePushNewMqBody();
        messagePushMqBody.setPartnerId(partnerId);
        messagePushMqBody.setAccessToken(accessToken);
        messagePushMqBody.setTemplate(template);
        messagePushMqBody.setStoreId(shopId);
        messagePushMqBody.setOrderId(orderId);
        messagePushMqBody.setWxappid(extInfo.getAppid());
        Header header = new Header(MQAction.INSERT.getAction(), "order-application-service-api", orderId, MessageOfficialRefundPushMqConfig.MESSAGE_PUSH_ORDER_REFUND_QUEUE);
        MQMessage<MessagePushNewMqBody> message = new MQMessage<>(header, messagePushMqBody);
        mqService.convertAndSend(MessageOfficialRefundPushMqConfig.MESSAGE_PUSH_EXCHANGE_TOPIC, MessageOfficialRefundPushMqConfig.MESSAGE_PUSH_ORDER_REFUND_QUEUE_EKY, message);
    }

    /**
     * 申请退款小票打印
     *
     * @param orderBean
     * @param orderRefundVo
     */
    private void printApplyRefundSmallTicket(OrderBeanV1 orderBean, OrderRefundVo orderRefundVo) {
        // 有云打印机 打印小票，杯贴
        try {
            List<AssortmentCloudPrinter> storePrinters = cloudPrinterManager.getStorePrinters(orderBean.getCompanyId(), orderBean.getShopId());
            if (null != storePrinters && storePrinters.size() > 0) {
                boolean printerStatus = false;
                for (AssortmentCloudPrinter cloudPrinter : storePrinters) {
                    if (null != cloudPrinter.getStatus() && cloudPrinter.getStatus() == 1) {
                        printerStatus = true;
                    }
                }
                //在线打印
                if (printerStatus) {
                    OrderPrintDto orderPrintDto = orderAdapter.convert2OrderPrintDto(orderBean);
                    String reason = orderRefundVo.getReason();
                    if (StringUtils.isNotBlank(orderRefundVo.getRemarks())) {
                        reason = reason + "," + orderRefundVo.getRemarks();
                    }
                    orderPrintDto.setRemark(reason);
                    fmAssistantCloudPrintClient.applyRefundPrint(orderPrintDto);
                }
            }
        } catch (Exception e) {
            AppLogUtil.errorLog("applyRefundPrint_error", null, null, e);
        }
    }

    /**
     * 支付后通知确认返回信息
     */
    public String sendPaySuccessNoticeMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 0);
        map.put("message", "success");
        return gson.toJson(map);
    }


    public Map<String, OrderBeanV1> getOrderBeanByOrderId(String orderId) {
        // 订单查询：若结果集只有一个orderBean，则为普通订单，否则为会员卡订单（父子订单）
        Map<String, OrderBeanV1> result = new HashMap<>();
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = getQueryRelationOrderByIdResponseDto(orderId);
        if (CollectionUtils.isEmpty(queryOrderByIdResponseDto.getData())) {
            return result;
        }
        if (1 == queryOrderByIdResponseDto.getData().size()) {
            result.put(OrderBeanType.SAASORDER.getCode(), queryOrderByIdResponseDto.getData().get(0));
        } else {
            List<OrderBeanV1> saasOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            List<OrderBeanV1> memberOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(3) && !order.getIsParent()).collect(Collectors.toList());
            List<OrderBeanV1> fatherOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(2) && order.getIsParent()).collect(Collectors.toList());
            result.put(OrderBeanType.SAASORDER.getCode(), CollectionUtils.isNotEmpty(saasOrderBeans) ? saasOrderBeans.get(0) : null);
            result.put(OrderBeanType.MERMBERORDER.getCode(), CollectionUtils.isNotEmpty(memberOrderBeans) ? memberOrderBeans.get(0) : null);
            result.put(OrderBeanType.FATHERORDER.getCode(), CollectionUtils.isNotEmpty(fatherOrderBeans) ? fatherOrderBeans.get(0) : null);
        }
        return result;
    }


    /**
     * 发送支付成功模板消息
     *
     * @param orderBean
     */
    private void sendPaySuccessMessage(OrderBeanV1 orderBean) {
        Long gmtExpect = orderBean.getGmtExpect();
        if (gmtExpect != null) {
            // 预约下单
            this.sendMessage(orderBean, MessageEventType.PAYORDEREXPECT);
        } else {
            // 非预约下单
            this.sendMessage(orderBean, MessageEventType.PAYORDER);
        }
    }


    /**
     * 发MQ去打印
     *
     * @param request
     */
    public void asynchronousPrint(OrderPrintDto request) {
        Header header = new Header(MQAction.INSERT.getAction(), "asynchronous-print-api", request.getOid() + "", cloudPrintQueue);
        MQMessage<OrderPrintDto> message = new MQMessage<>(header, request);
        mqService.convertAndSend(cloud_print_exchange, cloudPrintQueue, message);
    }

    /**
     * 月享卡2.0发券
     * @param orderBean
     */
    public boolean withOrderBuyCoupon2(OrderBeanV1 orderBean, String thirdPartyMemberId){
        AppLogUtil.infoLog("发券入参：", thirdPartyMemberId, JSON.toJSONString(orderBean));
        try{
            List<String> cardIds = new ArrayList<>();
            List<String> defaultCardCodes = new ArrayList<>();
            for (ProductBeanV1 productBean : orderBean.getProductList()){
                if(ProductTypeEnum.getVirtualProductType().contains(productBean.getProductType())) {
                    OrderProductAddInfoDto extInfo = JSON.parseObject(productBean.getExtInfo(), OrderProductAddInfoDto.class);
                    for(int i=0;i<productBean.getNumber();i++) {
                        cardIds.add(extInfo.getCardId());
                    }
                    defaultCardCodes.add(extInfo.getCardCode());
                }
            }

            if(CollectionUtils.isEmpty(cardIds)){
                return false;
            }

            SendCouponForqujiaRequestDto request = new SendCouponForqujiaRequestDto();
            request.setReceivedId(orderBean.getOid());
            request.setCardIds(cardIds);
            request.setThirdPartyMemberId(thirdPartyMemberId);
            SendCouponForqujiaDtoResponseDto responseDto = customerExtendClient.sendCouponForqujia(request);
            if(!Objects.equals(responseDto.getCode(), ResponseResult.SUCCESS.getCode())){
                AppLogUtil.infoLog("sendCouponForqujia", JSON.toJSONString(request), JSON.toJSONString(responseDto));
                return false;
            }

            if(responseDto.getData() == null || CollectionUtils.isEmpty(responseDto.getData().getCard_list())){
                return false;
            }

            List<SendCouponForqujiaDtoResponseDto.Card> cardList = responseDto.getData().getCard_list();

            MCCafeCouponRequest mcCafeCouponRequest = MCCafeCouponRequest.builder()
                    .ver(88)
                    .reqtype(CouponReqTypeEnum.BATCH_QUERY.getCode())
                    .partnerId(Integer.parseInt(orderBean.getCompanyId()))
                    .store_id(orderBean.getShopId())
                    .station_id("1")
                    .operator_id(orderBean.getUserId())
                    .channel(OrderSource.ALIPAY.getSource().equals(orderBean.getSource())?MCCafeChannelEnum.MOCOFFEE_ZFB.getName():MCCafeChannelEnum.MOCOFFEE_WX.getName())
                    .couponlist(cardList.stream().map(o -> new MCCafeCouponVo(o.getCard_code())).collect(Collectors.toList()))
                    .sign("skip")
                    .build();
            McdNetBatchQueryResponse mcdNetBatchQueryResponse = couponClientService.batchQuery(mcCafeCouponRequest);
            if (mcdNetBatchQueryResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS.equals(mcdNetBatchQueryResponse.getStatusCode())
                    || CollectionUtils.isEmpty(mcdNetBatchQueryResponse.getCouponlist())) {
                AppLogUtil.infoLog("获取优惠券详情失败，发券失败", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                return false;
            }
            Map<String, Integer> cardStatusMap = mcdNetBatchQueryResponse.getCouponlist().stream()
                    .collect(Collectors.toMap(McdNetBatchQueryResponse.Coupon::getCode, McdNetBatchQueryResponse.Coupon::getStatusCode, (k1, k2) -> k1));

            Map<String, String> cardMap = new HashMap<>();

            UpdateCouponCodeReq req = new UpdateCouponCodeReq();
            req.setOrderCode(orderBean.getOid());
            req.setPartnerId(orderBean.getCompanyId());
            req.setCouponReceiveInfoList(new ArrayList<>());
            req.setCouponUpdateInfoList(new ArrayList<>());
            AppLogUtil.infoLog("准备开始生成参数：", orderBean, null);
            for (ProductBeanV1 productBean : orderBean.getProductList()) {
                if(ProductTypeEnum.getVirtualProductType().contains(productBean.getProductType())) {
                    UpdateCouponCodeReq.CouponReceiveInfo couponReceiveInfo = new UpdateCouponCodeReq.CouponReceiveInfo();
                    couponReceiveInfo.setGoodsId(productBean.getSpecification());
                    couponReceiveInfo.setProductSeq(productBean.getSequence());
                    OrderProductAddInfoDto extInfo = JSON.parseObject(productBean.getExtInfo(), OrderProductAddInfoDto.class);
                    String cardCodeStr = "";
                    numberFor:
                    for(int j=0;j<productBean.getNumber();j++) {
                        cardFor:
                        for(int i=0;i<cardList.size();i++) {
                            if(cardList.get(i).getCard_id().equals(extInfo.getCardId())) {
                                String couponCode = cardList.get(i).getCard_code();
                                cardCodeStr += couponCode+"/";
                                if(ResponseCodeConstant.RESPONSE_SUCCESS.equals(cardStatusMap.get(couponCode))) {
                                    if(cardMap.get(extInfo.getCardCode()) == null) {
                                        UpdateCouponCodeReq.CouponUpdateInfo couponUpdateInfo = new UpdateCouponCodeReq.CouponUpdateInfo();
                                        couponUpdateInfo.setOldCouponCode(extInfo.getCardCode());
                                        couponUpdateInfo.setCouponCode(couponCode);
                                        req.getCouponUpdateInfoList().add(couponUpdateInfo);
                                        cardMap.put(extInfo.getCardCode(), couponCode);
                                    }
                                }
                                cardList.remove(i);
                                break cardFor;
                            }
                        }
                    }
                    couponReceiveInfo.setCouponCode(cardCodeStr.substring(0, cardCodeStr.length()-1));
                    req.getCouponReceiveInfoList().add(couponReceiveInfo);
                }
            }

//            AppLogUtil.infoLog("生成参数完成：", req, null);

            orderSdkService.updateCostCouponCodeNew(req, LogThreadLocal.getTrackingNo());

            return true;
        } catch (Exception e){
            AppLogUtil.errorLog("发券异常", null, null, e);
        }
        return true;
    }

    /**
     * 月享卡2.0发券
     * @param orderBean
     */
    public boolean withOrderBuyCoupon3(OrderBeanV1 orderBean, String thirdPartyMemberId){
//        AppLogUtil.infoLog("发券入参：", thirdPartyMemberId, JSON.toJSONString(orderBean));
        try{

            UpdateCouponCodeReq req = new UpdateCouponCodeReq();
            req.setOrderCode(orderBean.getOid());
            req.setPartnerId(orderBean.getCompanyId());
            req.setCouponReceiveInfoList(new ArrayList<>());
            req.setCouponUpdateInfoList(new ArrayList<>());

            for (ProductBeanV1 productBean : orderBean.getProductList()) {
                if(ProductTypeEnum.getVirtualProductType().contains(productBean.getProductType())) {
                    List<String> cardIds = new ArrayList<>();
                    OrderProductAddInfoDto extInfo = JSON.parseObject(productBean.getExtInfo(), OrderProductAddInfoDto.class);
                    for(int i=0;i<productBean.getNumber();i++) {
                        cardIds.add(extInfo.getCardId());
                    }

                    if(CollectionUtils.isEmpty(cardIds)){
                        continue;
                    }

                    SendCouponForqujiaRequestDto request = new SendCouponForqujiaRequestDto();
                    request.setReceivedId(orderBean.getOid());
                    request.setCardIds(cardIds);
                    request.setThirdPartyMemberId(thirdPartyMemberId);
                    SendCouponForqujiaDtoResponseDto responseDto = customerExtendClient.sendCouponForqujia(request);
                    if(!Objects.equals(responseDto.getCode(), ResponseResult.SUCCESS.getCode())
                            || responseDto.getData() == null || CollectionUtils.isEmpty(responseDto.getData().getCard_list())){
                        AppLogUtil.infoLog("发券异常",JSON.toJSONString(request) ,JSON.toJSONString(responseDto));
                        continue;
                    }

                    List<SendCouponForqujiaDtoResponseDto.Card> cardList = responseDto.getData().getCard_list();

                    MCCafeCouponRequest mcCafeCouponRequest = MCCafeCouponRequest.builder()
                            .ver(88)
                            .reqtype(CouponReqTypeEnum.BATCH_QUERY.getCode())
                            .partnerId(Integer.parseInt(orderBean.getCompanyId()))
                            .store_id(orderBean.getShopId())
                            .station_id("1")
                            .operator_id(orderBean.getUserId())
                            .channel(OrderSource.ALIPAY.getSource().equals(orderBean.getSource())?MCCafeChannelEnum.MOCOFFEE_ZFB.getName():MCCafeChannelEnum.MOCOFFEE_WX.getName())
                            .couponlist(cardList.stream().map(o -> new MCCafeCouponVo(o.getCard_code())).collect(Collectors.toList()))
                            .sign("skip")
                            .build();
                    McdNetBatchQueryResponse mcdNetBatchQueryResponse = couponClientService.batchQuery(mcCafeCouponRequest);
                    if (mcdNetBatchQueryResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS.equals(mcdNetBatchQueryResponse.getStatusCode())
                            || CollectionUtils.isEmpty(mcdNetBatchQueryResponse.getCouponlist())) {
                        AppLogUtil.infoLog("获取优惠券详情失败，发券失败" , JSON.toJSONString(mcCafeCouponRequest) , JSON.toJSONString(mcdNetBatchQueryResponse));
                        return false;
                    }

                    UpdateCouponCodeReq.CouponReceiveInfo couponReceiveInfo = new UpdateCouponCodeReq.CouponReceiveInfo();
                    couponReceiveInfo.setGoodsId(productBean.getSpecification());
                    couponReceiveInfo.setProductSeq(productBean.getSequence());
                    couponReceiveInfo.setCouponCode(mcdNetBatchQueryResponse.getCouponlist().stream()
                            .map(o -> o.getCode()).collect(Collectors.joining("/")));
                    req.getCouponReceiveInfoList().add(couponReceiveInfo);

                    String couponCode = "";
                    if(extInfo.getIsMonthCard() != null && extInfo.getIsMonthCard() == 1) {
                        Optional<McdNetBatchQueryResponse.Coupon> couponOptional = mcdNetBatchQueryResponse.getCouponlist().stream()
                                .filter(o -> ResponseCodeConstant.RESPONSE_SUCCESS.equals(o.getStatusCode())).findFirst();
                        if(!couponOptional.isPresent()) {
                            AppLogUtil.infoLog("没有有效的优惠券，更新失败" , JSON.toJSONString(mcCafeCouponRequest) , JSON.toJSONString(mcdNetBatchQueryResponse));
                            continue;
                        } else {
                            couponCode = couponOptional.get().getCode();
                        }
                    } else if(extInfo.getIsB3S1Coupon() != null && extInfo.getIsB3S1Coupon() == 1) {

                        Optional<McdNetBatchQueryResponse.Coupon> couponOptional = mcdNetBatchQueryResponse.getCouponlist().stream()
                                .filter(o -> ResponseCodeConstant.RESPONSE_SUCCESS.equals(o.getStatusCode())).findFirst();
                        if(!couponOptional.isPresent()) {
                            AppLogUtil.infoLog("没有有效的优惠券，更新失败" , JSON.toJSONString(mcCafeCouponRequest) , JSON.toJSONString(mcdNetBatchQueryResponse));
                            continue;
                        } else {
                            couponCode = couponOptional.get().getCode();
                        }
                    }
                    if(StringUtils.isBlank(couponCode)) {
                        AppLogUtil.infoLog("没有匹配的优惠券，更新失败" , JSON.toJSONString(mcCafeCouponRequest) , JSON.toJSONString(mcdNetBatchQueryResponse));
                        continue;
                    }
                    UpdateCouponCodeReq.CouponUpdateInfo couponUpdateInfo = new UpdateCouponCodeReq.CouponUpdateInfo();
                    couponUpdateInfo.setOldCouponCode(extInfo.getCardCode());
                    couponUpdateInfo.setCouponCode(couponCode);
                    req.getCouponUpdateInfoList().add(couponUpdateInfo);

                }

            }

            orderSdkService.updateCostCouponCodeNew(req, LogThreadLocal.getTrackingNo());

            return true;
        } catch (Exception e){
            AppLogUtil.errorLog("发券异常", null, null, e);
        }
        return true;
    }

    @Override
    public BaseResponse mcCafePollingPickUpCode(MaCafeQueryOrderVo queryOrderVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String oid = queryOrderVo.getOid();
        if (StringUtils.isBlank(oid)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(oid);
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBeanV1 orderBean = response.getData();
        OrderViewStatusDto orderViewStatusDesc = orderAdapter.getOrderViewStatusDesc(orderBean, userLoginInfoDto.getWxAppId());
        Map<String, Object> responseMap = Maps.newTreeMap();
        responseMap.put("orderStatus", orderViewStatusDesc.getOrderStatus());
        responseMap.put("takeCode", "");
        responseMap.put("queueIndex", "");
        String extInfo = orderBean.getExtInfo();
        OrderExtInfoDto orderExtInfoDto = null;
        if (StringUtils.isNotBlank(extInfo)) {
            orderExtInfoDto = gson.fromJson(extInfo, OrderExtInfoDto.class);
        }
        responseMap.put("payVoucher", orderExtInfoDto != null ? orderExtInfoDto.getPayTransId() : "");
        //非外卖单才获取取餐码和排队人数
        if (!OrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            if (!(OrderStatus.TAKE_ORDER.getCode().equals(orderBean.getStatus())
                    || OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus()))) {
                responseMap.put("takeCode", orderBean.getOtherCode());
            }
            BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
            var1.setOrderId(orderBean.getOid());
            var1.setTrackingNo(LogThreadLocal.getTrackingNo());
            BaseOrderResponse baseOrderResponse = orderCenterSdkService.queryOrderQueueIndex(var1);
            QueryOrderQueueIndexResponse response1 = new QueryOrderQueueIndexResponse();
            response1.setErrcode(baseOrderResponse.getErrcode());
            response1.setErrmsg(baseOrderResponse.getErrmsg());
            if (RESPONSE_SUCCESS_CODE.equals(response1.getErrcode())) {
                String queueIndex = response1.getData() == null ? "" : response1.getData().toString();
                responseMap.put("queueIndex", queueIndex);
            }
        }
        return ResponseUtil.success(responseMap);
    }

    /**
     * 催单
     *
     * @param reminderVo
     * @return
     */
    @Override
    public BaseResponse reminder(ReminderVo reminderVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(reminderVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(reminderVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBeanV1 orderBean = response.getData();
        //判断订单状态
        if (!cn.freemud.management.enums.OrderStatus.DISTRIBUTION.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_REMINDER_ORDER_ERROR);
        }

        //调用配送服务进行催单
        OrderRemindRequestDto dto = new OrderRemindRequestDto();
        dto.setOrderKey(reminderVo.getOid());
        dto.setStoreId(orderBean.getShopId());
        dto.setDeliveryChannel("CanDao");
        dto.setDisplayOrderId(orderBean.getDownstreamThirdOrderCode());
        if (orderBean.getAddInfo() != null) {
            dto.setDeliveryId(orderBean.getAddInfo().getDeliveryId());
        }
        QueryDeliveryAmountResponseDto responseDto = deliveryFeiginClient.orderRemind(dto);
        if (null != responseDto && 120 == responseDto.getCode()) {
            return ResponseUtil.error("120", responseDto.getMsg());
        }
        if (responseDto == null || RESPONSE_SUCCESS_CODE != responseDto.getCode()) {
            return ResponseUtil.error(ResponseResult.DELIVERY_REMINDER_ERROR);
        }
        return ResponseUtil.success();
    }

    /**
     * 查询骑手位置
     *
     * @param vo
     * @return
     */
    @Override
    public BaseResponse listFreeRider(FreeRiderPositionVo vo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(vo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        QueryLocusRiderTrackDto dto = new QueryLocusRiderTrackDto();
        dto.setDeliveryChannel("CanDao");
        dto.setOrderId(vo.getOid());
        MCCafeDeliveryBaseResponse<ResRiderTrackDto> responses = deliveryFeiginClient.listFreeRider(dto);
        if (responses == null || RESPONSE_SUCCESS_CODE != Integer.valueOf(responses.getCode()) || responses.getData() == null) {
            return ResponseUtil.error(ResponseResult.DELIVERY_QUERY_RIDER_ERROR);
        }
        return ResponseUtil.success(responses.getData());
    }


    @Override
    public BaseResponse mcCafeQueryRecentOrder(McCafeQueryOrderVo queryOrderVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }

        List<RecentGoodsInfoVo> recentGoodsInfoVoList = new ArrayList<>();


        if(null == quickOrderInterval || "0".equals(quickOrderInterval)) {
            return ResponseUtil.success(recentGoodsInfoVoList);
        }

        queryOrderVo.setStartDate(DateUtil.convert2String(DateUtil.addDays(new Date(), -Integer.valueOf(quickOrderInterval)), "yyyy-MM-dd"));
        queryOrderVo.setEndDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd"));
        queryOrderVo.setQueryOrderStatus(Arrays.asList(OldOrderStatus.COMPLETE.getCode()));
        queryOrderVo.setQueryOrderType(Arrays.asList(OldOrderType.TAKE_OUT.getCode(), OldOrderType.COLLECT_GOODS.getCode(), OldOrderType.EAT_IN.getCode()));
        queryOrderVo.setPartnerId(queryOrderVo.getPartnerId());

        String startDateStr = queryOrderVo.getStartDate() + " 00:00:00";
        String endDateStr = queryOrderVo.getEndDate() + " 23:59:59";
        Date startDate = DateUtil.convert2Date(startDateStr, "yyyy-MM-dd HH:mm:ss");
        if (startDate == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单开始时间格式不正确");
        }
        Date endDate = DateUtil.convert2Date(endDateStr, "yyyy-MM-dd HH:mm:ss");
        if (endDate == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单结束时间格式不正确");
        }
        QueryOrdersRequest queryOrdersRequest = new QueryOrdersRequest();
        queryOrdersRequest.setUserId(userLoginInfoDto.getMemberId());
        queryOrdersRequest.setCompanyId(queryOrderVo.getPartnerId());
        queryOrdersRequest.setPageSize(1);
        queryOrdersRequest.setPageNumber(1);
        queryOrdersRequest.setStartDate(startDateStr);
        queryOrdersRequest.setEndDate(endDateStr);

        queryOrdersRequest.setSource(new String[]{OrderChannelType.SAAS.getCode()});

        queryOrdersRequest.setPayStatus(new Integer[]{PayStatus.HAVE_PAID.getCode(), PayStatus.HAVE_REFUND.getCode(), PayStatus.COMPLETE.getCode()});

        queryOrdersRequest.setStatus(new Integer[]{OrderStatus.COMPLETE.getCode()});

        queryOrdersRequest.setType(new Integer[]{OrderType.COLLECT_GOODS.getCode(), OrderType.EAT_IN.getCode(), OrderType.TAKE_OUT.getCode()});

        //商品订单和卖券订单
        queryOrdersRequest.setBizTypes(Arrays.asList(1,6));

        queryOrdersRequest.setTrackingNo(LogThreadLocal.getTrackingNo());


        QueryOrdersResponse queryOrderResponse = null;
        try {
            queryOrderResponse = orderCenterSdkService.queryMCCafeOrders(queryOrdersRequest);
        } catch (Exception e) {
            AppLogUtil.errorLog("queryRecentOrders_error",JSON.toJSONString(queryOrdersRequest),null, e);
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单异常");
        }
        if (queryOrderResponse == null || !RESPONSE_SUCCESS_CODE.equals(queryOrderResponse.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单失败");
        }
        //用户无订单数据
        if (queryOrderResponse.getData() == null || queryOrderResponse.getData().getCount() == 0) {
            return ResponseUtil.error(ResponseResult.SUCCESS.getCode(), "查询订单数量为0");
        }

        for (ProductBeanV1 o : queryOrderResponse.getData().getOrders().get(0).getProductList()) {
            if(ProductTypeEnum.getVirtualProductType().contains(o.getProductType())) {
                continue;
            }
            if(CollectionUtils.isNotEmpty(o.getDiscountList()) && o.getDiscountList().stream()
                    .filter(p -> OldOrderAccountType.PRODUCT_COUPON.getCode().equals(p.getDiscountType())
                            || OldOrderAccountType.EVM_PRODUCT_COUPON.getCode().equals(p.getDiscountType())).findAny().isPresent()) {
                continue;
            }
            RecentGoodsInfoVo recentGoodsInfoVo = new RecentGoodsInfoVo();
            recentGoodsInfoVo.setSpuId(o.getProductId());
            recentGoodsInfoVo.setSpuName(o.getProductName());
            recentGoodsInfoVo.setSkuId(o.getSpecification());
            recentGoodsInfoVo.setSkuName(o.getSpecificationName());
            recentGoodsInfoVo.setQty(o.getNumber());
            if(StringUtils.isNotBlank(o.getExtInfo())) {
                OrderProductAddInfoDto orderProductAddInfoDto = JSON.parseObject(o.getExtInfo(), OrderProductAddInfoDto.class);
                if(null != orderProductAddInfoDto) {
                    recentGoodsInfoVo.setSpecialExtra(JSON.parseArray(JSON.toJSONString(orderProductAddInfoDto.getSpecialAttrs()), RecentGoodsInfoVo.SpecialExtra.class));
                }
            }
            if(CollectionUtils.isNotEmpty(o.getComboProduct())) {
                recentGoodsInfoVo.setProductComboList(new ArrayList<RecentGoodsInfoVo.ComboGoodsVo>());
                recentGoodsInfoVo.setProductGroupList(new ArrayList<RecentGoodsInfoVo.ComboGoodsVo>());
                o.getComboProduct().forEach(p -> {
                    RecentGoodsInfoVo.ComboGoodsVo comboGoodsVo = new RecentGoodsInfoVo.ComboGoodsVo();
                    comboGoodsVo.setSpuId(p.getProductId());
                    comboGoodsVo.setSpuName(p.getProductName());
                    comboGoodsVo.setSkuId(p.getSpecification());
                    comboGoodsVo.setSkuName(p.getSpecificationName());
                    if(StringUtils.isNotBlank(p.getExtInfo())) {
                        OrderProductAddInfoDto extInfo = JSON.parseObject(p.getExtInfo(), OrderProductAddInfoDto.class);
                        comboGoodsVo.setProductGroupId(extInfo.getProductGroupId()+"");
                    }
                    comboGoodsVo.setQty(p.getNumber());
                    OrderProductAddInfoDto orderProductAddInfoDto = JSON.parseObject(p.getExtInfo(), OrderProductAddInfoDto.class);
                    if(null != orderProductAddInfoDto) {
                        comboGoodsVo.setSpecialExtra(JSON.parseArray(JSON.toJSONString(orderProductAddInfoDto.getSpecialAttrs()), RecentGoodsInfoVo.SpecialExtra.class));
                    }
                    if(CollectionUtils.isNotEmpty(p.getMaterialProduct())) {
                        comboGoodsVo.setProductMaterialList(new ArrayList<RecentGoodsInfoVo.MaterialGoodsVo>());
                        p.getMaterialProduct().forEach(q -> {
                            RecentGoodsInfoVo.MaterialGoodsVo materialGoodsVo = new RecentGoodsInfoVo.MaterialGoodsVo();
                            materialGoodsVo.setSpuId(q.getProductId());
                            materialGoodsVo.setSpuName(q.getProductName());
                            materialGoodsVo.setQty(q.getNumber());
                            materialGoodsVo.setCustomerCode(q.getProductCode());
                            comboGoodsVo.getProductMaterialList().add(materialGoodsVo);
                        });
                    }
                    if(orderProductAddInfoDto.getIsFixedProduct()) {
                        recentGoodsInfoVo.getProductComboList().add(comboGoodsVo);
                    } else {
                        recentGoodsInfoVo.getProductGroupList().add(comboGoodsVo);
                    }
                });
            }
            if(CollectionUtils.isNotEmpty(o.getMaterialProduct())) {
                recentGoodsInfoVo.setProductMaterialList(new ArrayList<RecentGoodsInfoVo.MaterialGoodsVo>());
                o.getMaterialProduct().forEach(p -> {
                    RecentGoodsInfoVo.MaterialGoodsVo materialGoodsVo = new RecentGoodsInfoVo.MaterialGoodsVo();
                    materialGoodsVo.setSpuId(p.getProductId());
                    materialGoodsVo.setSpuName(p.getProductName());
                    materialGoodsVo.setQty(p.getNumber());
                    materialGoodsVo.setCustomerCode(p.getProductCode());
                    recentGoodsInfoVo.getProductMaterialList().add(materialGoodsVo);
                });
            }

            recentGoodsInfoVoList.add(recentGoodsInfoVo);
        }

        return ResponseUtil.success(recentGoodsInfoVoList);
    }


    /**
     * 历史判断围餐是从userLoginInfoDto判断iappid的。
     * 商城订单从前端传channelType区分，
     * 默认点餐
     */
    private String getQueryOrderChannelType(QueryOrderVo queryOrderVo, AssortmentCustomerInfoVo userLoginInfoDto) {
        String channelType = OrderChannelType.SAAS.getCode();
        if (IappIdType.WC_XCX.getCode().equals(userLoginInfoDto.getIappId())) {
            channelType = OrderChannelType.IWC.getCode();
        } else if (OrderChannelType.SAASMALL.getCode().equals(queryOrderVo.getChannelType())) {
            channelType = OrderChannelType.SAASMALL.getCode();
        } else if (UserLoginChannelEnum.APP.getCode().equals(userLoginInfoDto.getChannel())) {
            channelType = OrderChannelType.APP.getCode();
        } else if (OrderChannelType.BEAUTIFUL.getCode().equals(queryOrderVo.getChannelType())) {
            channelType = OrderChannelType.BEAUTIFUL.getCode();
        }
        return channelType;
    }

    public BaseResponse mcCafePushOrder(McCafeQueryOrderVo queryOrderVo) {

        executor.submit(() -> {
            Long lastCreateTime = DateUtil.convert2Date(queryOrderVo.getStartDate(), "yyyy-MM-dd HH:mm:ss").getTime();
            for(int i=1;;i++) {
                OrderConditionsReq orderConditionsReq = new OrderConditionsReq();
                orderConditionsReq.setPartnerId(mcCafePartnerId);
                orderConditionsReq.setOrderStatuses(Arrays.asList(6,7));
                orderConditionsReq.setPayStatuses(Arrays.asList(2,3,5));
                orderConditionsReq.setOrderTypes(Arrays.asList(1,2,3,4,5,6));
                orderConditionsReq.setStartTimestamp(DateUtil.convert2Date(queryOrderVo.getStartDate(), "yyyy-MM-dd HH:mm:ss").getTime()/1000);
                orderConditionsReq.setEndTimestamp(DateUtil.convert2Date(queryOrderVo.getEndDate(), "yyyy-MM-dd HH:mm:ss").getTime()/1000);
                orderConditionsReq.setPageNum(i);
                orderConditionsReq.setPageSize(500);
                orderConditionsReq.setSortRule(1);
                if(StringUtils.isNotBlank(queryOrderVo.getUserId())) {
                    orderConditionsReq.setUserId(queryOrderVo.getUserId());
                }
                BaseDownLoadResponse<List<OrderInfoReqs>> response = orderDownLoadSdkService.queryOrderByConditions(orderConditionsReq, LogThreadLocal.getTrackingNo());
                AppLogUtil.infoLog("queryOrderByConditions："+ JSON.toJSONString(response),null,null);
                if("50002".equals(response.getCode())) {
                    AppLogUtil.infoLog("麦咖啡重置退单查询:  重置前：  "+i+"   "+JSON.toJSONString(queryOrderVo),null,null);
                    i=1;
                    queryOrderVo.setStartDate(DateUtil.convert2String(new Date(lastCreateTime), "yyyy-MM-dd HH:mm:ss"));
                    AppLogUtil.infoLog("麦咖啡重置退单查询:  重置后：  "+i+"   "+JSON.toJSONString(queryOrderVo),null,null);
                    continue;
                } else if(!ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(response.getCode())) {
                    AppLogUtil.infoLog("麦咖啡历史订单查询异常: "+JSON.toJSONString(queryOrderVo),null,null);
                    break;
                }
                if(ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(response.getCode()) && CollectionUtils.isEmpty(response.getResult())) {
                    AppLogUtil.infoLog("麦咖啡历史订单查询结束: "+JSON.toJSONString(queryOrderVo),null,null);
                    break;
                }
                RestTemplate client = new RestTemplate();
                for(OrderInfoReqs orderInfoReqs : response.getResult()) {
                    try {
                        if(Long.valueOf(orderInfoReqs.getCreateTime()) > lastCreateTime) {
                            lastCreateTime = Long.valueOf(orderInfoReqs.getCreateTime());
                        }
                        McCafePushOrderDto mcCafePushOrderDto = convert2McCafePushOrderInfo(orderInfoReqs);
                        AppLogUtil.infoLog("订单推送入参: "+JSON.toJSONString(mcCafePushOrderDto),null,null);

                        String timestamp = System.currentTimeMillis()+"";
                        String sign = getMcdOpenApiSign(mccafePushOrderAppId,JSON.toJSONString(mcCafePushOrderDto),mccafePushOrderMerchantId,timestamp,mccafePushOrderKey);

                        HttpHeaders headers = new HttpHeaders();
                        headers.setContentType(MediaType.APPLICATION_JSON);
                        headers.set("Provider", "WX");
                        headers.set("Version", "1.0");
                        headers.set("AppId", mccafePushOrderAppId);
                        headers.set("MerchantId", mccafePushOrderMerchantId);
                        headers.set("Timestamp", timestamp);
                        headers.set("Sign", sign);
                        headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
                        AppLogUtil.infoLog("订单推送header: "+JSON.toJSONString(headers),null,null);
                        String json = JSON.toJSONString(mcCafePushOrderDto);
                        HttpEntity<String> requestEntity = new HttpEntity<>(json, headers);
                        ResponseEntity<String> responseEntity = client.exchange(mccafePushOrderGatewayUrl+"/mp/order", HttpMethod.POST, requestEntity, String.class);

                        McCafePushOrderResponseDto responseDto = JSON.parseObject(responseEntity.getBody(), McCafePushOrderResponseDto.class);

//                        McCafePushOrderResponseDto responseDto = mcCafePushOrderClient.mcCafePushOrder(mcCafePushOrderDto);
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        if(!"SUCCESS".equals(responseDto.getCode())) {
                            pushMccafeOrder.setStatus(0);
                            pushMccafeOrder.setFailReason(subLongString(JSON.toJSONString(responseDto)));
                        } else {
                            pushMccafeOrder.setStatus(1);
                        }
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);


                    } catch (ServiceException e) {
                        AppLogUtil.errorLog("麦咖啡历史订单推送失败: "+JSON.toJSONString(orderInfoReqs)
                                +" 异常信息: "+e.getMessage(),null,null, null);
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        pushMccafeOrder.setStatus(0);
                        pushMccafeOrder.setFailReason(e.getMessage());
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);
                    } catch (Exception e) {
                        AppLogUtil.errorLog("麦咖啡历史订单推送失败: "+JSON.toJSONString(orderInfoReqs)
                                +" 异常信息: "+ExceptionUtils.getExceptionInfo(e),null,null, null);
                        e.printStackTrace();
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        pushMccafeOrder.setStatus(0);
                        pushMccafeOrder.setFailReason(subLongString(ExceptionUtils.getExceptionInfo(e)));
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);
                    }

                }
            }

            AppLogUtil.infoLog("麦咖啡历史订单推送完成: "+JSON.toJSONString(queryOrderVo),null,null);

        });

        BaseResponse baseResponse = new BaseResponse();
        baseResponse.setCode("100");
        baseResponse.setMessage("success");
        return baseResponse;
    }

    public String subLongString(String s) {
        if(StringUtils.isNotBlank(s)) {
            if(s.length() > 15000) {
                return s.substring(0,15000);
            } else {
                return s;
            }
        } else {
            return "";
        }
    }

    public BaseResponse mcCafePushOrderMakeUp(McCafeQueryOrderVo queryOrderVo) {

        executor.submit(() -> {

            int id = 0;
            while (true) {
                List<PushMccafeOrder> pushMccafeOrderList = pushMccafeOrderManager.selectOrderByStatus(id);
                if(CollectionUtils.isEmpty(pushMccafeOrderList)) {
                    break;
                }

                List<String> orderCodes = pushMccafeOrderList.stream().map(o -> o.getOrderCode()).collect(Collectors.toList());
                OrderConditionsReq orderConditionsReq = new OrderConditionsReq();
                orderConditionsReq.setOrderCodes(orderCodes);
                orderConditionsReq.setPageNum(1);
                orderConditionsReq.setPageSize(500);
                orderConditionsReq.setSortRule(1);
                BaseDownLoadResponse<List<OrderInfoReqs>> response = orderDownLoadSdkService.queryOrderByConditions(orderConditionsReq, LogThreadLocal.getTrackingNo());
                AppLogUtil.infoLog("queryOrderByConditions："+ JSON.toJSONString(response),null,null);
                if(CollectionUtils.isEmpty(response.getResult())) {
                    break;
                }
                RestTemplate client = new RestTemplate();
                for(OrderInfoReqs orderInfoReqs : response.getResult()) {
                    try {
                        McCafePushOrderDto mcCafePushOrderDto = convert2McCafePushOrderInfo(orderInfoReqs);
                        AppLogUtil.infoLog("订单推送入参: "+JSON.toJSONString(mcCafePushOrderDto),null,null);

                        String timestamp = System.currentTimeMillis()+"";
                        String sign = getMcdOpenApiSign(mccafePushOrderAppId,JSON.toJSONString(mcCafePushOrderDto),mccafePushOrderMerchantId,timestamp,mccafePushOrderKey);

                        HttpHeaders headers = new HttpHeaders();
                        headers.setContentType(MediaType.APPLICATION_JSON);
                        headers.set("Provider", "WX");
                        headers.set("Version", "1.0");
                        headers.set("AppId", mccafePushOrderAppId);
                        headers.set("MerchantId", mccafePushOrderMerchantId);
                        headers.set("Timestamp", timestamp);
                        headers.set("Sign", sign);
                        headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
                        Gson gson = new Gson();
                        String json = gson.toJson(mcCafePushOrderDto);
                        HttpEntity<String> requestEntity = new HttpEntity<>(json, headers);
                        ResponseEntity<String> responseEntity = client.exchange(mccafePushOrderGatewayUrl+"/mp/order", HttpMethod.POST, requestEntity, String.class);

                        McCafePushOrderResponseDto responseDto = JSON.parseObject(responseEntity.getBody(), McCafePushOrderResponseDto.class);

//                        McCafePushOrderResponseDto responseDto = mcCafePushOrderClient.mcCafePushOrder(mcCafePushOrderDto);
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        if(!"SUCCESS".equals(responseDto.getCode())) {
                            pushMccafeOrder.setStatus(0);
                            pushMccafeOrder.setFailReason(JSON.toJSONString(responseDto));
                        } else {
                            pushMccafeOrder.setStatus(1);
                        }
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);


                    } catch (ServiceException e) {
                        AppLogUtil.errorLog("麦咖啡历史订单推送失败: "+JSON.toJSONString(orderInfoReqs)
                                +" 异常信息: "+e.getMessage(),null,null, null);
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        pushMccafeOrder.setStatus(0);
                        pushMccafeOrder.setFailReason(e.getMessage());
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);
                    } catch (Exception e) {
                        AppLogUtil.errorLog("麦咖啡历史订单推送失败: "+JSON.toJSONString(orderInfoReqs)
                                +" 异常信息: "+ExceptionUtils.getExceptionInfo(e),null,null, null);
                        e.printStackTrace();
                        PushMccafeOrder pushMccafeOrder = new PushMccafeOrder();
                        pushMccafeOrder.setOrderCode(orderInfoReqs.getOrderCode());
                        pushMccafeOrder.setPartnerId(orderInfoReqs.getPartnerId());
                        pushMccafeOrder.setStoreId(orderInfoReqs.getStoreId());
                        pushMccafeOrder.setStatus(0);
                        pushMccafeOrder.setFailReason(ExceptionUtils.getExceptionInfo(e));
                        pushMccafeOrderManager.insertOrder(pushMccafeOrder);
                    }

                }

            }

        });


        BaseResponse baseResponse = new BaseResponse();
        baseResponse.setCode("100");
        baseResponse.setMessage("success");
        return baseResponse;
    }

    private McCafePushOrderDto convert2McCafePushOrderInfo(OrderInfoReqs orderInfoReqs) {
        if(StringUtils.isBlank(orderInfoReqs.getReceiveTime())) {
            orderInfoReqs.setReceiveTime(DateUtil.addHours(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), 1).getTime()+"");
        }
        if(StringUtils.isBlank(orderInfoReqs.getAcceptTime())) {
            orderInfoReqs.setAcceptTime(orderInfoReqs.getCreateTime());
        }
        OrderExtInfoDto orderExtInfoDto = JSON.parseObject(orderInfoReqs.getExtInfo(), OrderExtInfoDto.class);
        McCafePushOrderDto mcCafePushOrderDto = new McCafePushOrderDto();
        mcCafePushOrderDto.setMpOrderId(orderInfoReqs.getOrderCode());
        mcCafePushOrderDto.setDisplayOrderId(orderInfoReqs.getDownstreamThirdOrderCode());
        mcCafePushOrderDto.setType(orderInfoReqs.getOrderType()==3||orderInfoReqs.getOrderType()==4?"2":"1");
        mcCafePushOrderDto.setSaleType(orderInfoReqs.getOrderType()==1||orderInfoReqs.getOrderType()==3||orderInfoReqs.getOrderType()==5?"1":"2");
        mcCafePushOrderDto.setEatType(orderInfoReqs.getOrderType()==3||orderInfoReqs.getOrderType()==4?"2":"1");
        mcCafePushOrderDto.setDeliveryType("1");
        mcCafePushOrderDto.setSourceType(orderInfoReqs.getOrderClient().equals(OrderClientType.ALIPAY.getIndex())?"ALIMP":"WXMP");
        mcCafePushOrderDto.setBeType("3");
        mcCafePushOrderDto.setDayPart("2");
        mcCafePushOrderDto.setChannel(orderInfoReqs.getOrderClient().equals(OrderClientType.ALIPAY.getIndex())?"43":"10");

        mcCafePushOrderDto.setStatus(NewOrderStatus.COMPLETE.getIndex().equals(orderInfoReqs.getOrderState())?"40":"80");
        mcCafePushOrderDto.setInvoiceNeeded(orderExtInfoDto.getNeedInvoice());
        mcCafePushOrderDto.setInvoiced(orderExtInfoDto.getNeedInvoice());
        mcCafePushOrderDto.setCustomer_id(orderExtInfoDto.getThirdPartyMemberId());
        mcCafePushOrderDto.setStoreCode(orderInfoReqs.getStoreId());
        mcCafePushOrderDto.setStoreName(orderInfoReqs.getStoreName());
        mcCafePushOrderDto.setBusinessDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), "yyyy-MM-dd"));
        mcCafePushOrderDto.setTablewareInfo(Integer.valueOf(1).equals(orderExtInfoDto.getNeedTableware())?"01":"02");
        if(orderInfoReqs.getOriginalAmount().intValue() >= orderInfoReqs.getActualPayAmount().intValue()) {
            mcCafePushOrderDto.setTotalAmount(orderInfoReqs.getOriginalAmount().intValue());
            mcCafePushOrderDto.setDiscountTotalAmount(orderInfoReqs.getOriginalAmount().subtract(orderInfoReqs.getActualPayAmount()).intValue());
            mcCafePushOrderDto.setRealTotalAmount(orderInfoReqs.getActualPayAmount().intValue());
        } else {
            mcCafePushOrderDto.setTotalAmount(orderInfoReqs.getActualPayAmount().intValue());
            mcCafePushOrderDto.setDiscountTotalAmount(0);
            mcCafePushOrderDto.setRealTotalAmount(orderInfoReqs.getActualPayAmount().intValue());
        }
        Optional<OrderCostResp> optionalOrderCostResp = orderInfoReqs.getOrderCostDetailList().stream().filter(
                o -> CostTypeEnum.DELIVERY_AMOUNT.getCode().equals(o.getCostType())).findFirst();
        if(optionalOrderCostResp.isPresent()) {
            mcCafePushOrderDto.setDeliveryPrice(optionalOrderCostResp.get().getCostAmount().intValue());
            mcCafePushOrderDto.setRealDeliveryPrice(optionalOrderCostResp.get().getActualCostAmount().intValue());
        } else {
            mcCafePushOrderDto.setDeliveryPrice(0);
            mcCafePushOrderDto.setRealDeliveryPrice(0);
        }
        mcCafePushOrderDto.setRemark(orderInfoReqs.getNote());
        mcCafePushOrderDto.setSaleTime(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getPayTime())), "yyyy-MM-dd HH:mm:ss"));
        mcCafePushOrderDto.setCompletionTime(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getReceiveTime())), "yyyy-MM-dd HH:mm:ss"));

        Optional<AfterSalesOrderResp> afterSalesOrderRespOptional = Optional.empty();
        if(NewOrderStatus.CLOSED.getIndex().equals(orderInfoReqs.getOrderState()) && CollectionUtils.isNotEmpty(orderInfoReqs.getAfterSalesOrderList())) {
            mcCafePushOrderDto.setCancellationReasonCode("-1");
            afterSalesOrderRespOptional = orderInfoReqs.getAfterSalesOrderList().stream().filter(
                    o -> AfterSalesStatus.COMPLETE.getIndex().equals(o.getAfterSalesStatus())).findFirst();
            if(afterSalesOrderRespOptional.isPresent()) {
                mcCafePushOrderDto.setCancellationRemark(afterSalesOrderRespOptional.get().getReqRemark());
            }
        }
        mcCafePushOrderDto.setAcceptTime(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getAcceptTime())), "yyyy-MM-dd HH:mm:ss.SSS"));
        mcCafePushOrderDto.setPickupCode(orderInfoReqs.getPickUpGoodsNo());
        mcCafePushOrderDto.setOpenId(orderExtInfoDto.getOpenid());
        GetMemberInfoByIdRequestDto getMemberInfoByIdRequestDto = new GetMemberInfoByIdRequestDto();
        getMemberInfoByIdRequestDto.setPartnerId(mcCafePartnerId);
        getMemberInfoByIdRequestDto.setMemberId(orderInfoReqs.getUserId());
        GetMemberInfoByIdResponseDto getMemberInfoByIdResponseDto = customerClient.getMemberInfoById(getMemberInfoByIdRequestDto);
        if(!ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(getMemberInfoByIdResponseDto.getCode())) {
            throw new ServiceException(ResponseResult.USER_GETPHONE_ERROR, "获取用户信息异常");
        }
        if(CollectionUtils.isNotEmpty(getMemberInfoByIdResponseDto.getData().getMemberChannels())) {
            Optional<GetMemberInfoByChannelResponseDto.ResultBean.ChannelListBean> channelListBeanOptional = getMemberInfoByIdResponseDto.getData().getMemberChannels().stream().filter(o -> mcCafePartnerId.equals(o.getPartnerId())).findFirst();
            if(channelListBeanOptional.isPresent()) {
                mcCafePushOrderDto.setUnionId(channelListBeanOptional.get().getUnionId());
            }
        }
        mcCafePushOrderDto.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), "yyyy-MM-dd HH:mm:ss"));


        List<McCafePushOrderDto.OrderItem> orderItemList = new ArrayList<>();
        List<OrderItemResp> materialList = orderInfoReqs.getOrderItemList().stream()
                .filter(item -> ProductTypeEnum.LITTLE_MATERIAL_PRODUCT.getCode().equals(item.getProductType()))
                .collect(Collectors.toList());

        Integer taxTotalAmount = 0;
        for (OrderItemResp orderItemResp : orderInfoReqs.getOrderItemList()) {
            if(ProductTypeEnum.LITTLE_MATERIAL_PRODUCT.getCode().equals(orderItemResp.getProductType())) {
                continue;
            }
            McCafePushOrderDto.OrderItem orderItem = new McCafePushOrderDto.OrderItem();
            orderItem.setMpItemId(orderItemResp.getProductId());
            orderItem.setSequenceId(orderItemResp.getProductSeq().toString());
            orderItem.setRound(orderItemResp.getProductSeq().toString());
            if(!"0".equals(orderItemResp.getParentProductId())) {
                orderItem.setMpParentItemId(orderItemResp.getParentProductId().split("_")[0]);
                orderItem.setProductType("1");
            } else {
                orderItem.setProductType(parse2McdProductType(orderItemResp.getProductType()));
            }
            orderItem.setProductCode(StringUtils.isNotBlank(orderItemResp.getProductCode())?orderItemResp.getProductCode():orderItemResp.getThirdProductId());
            OrderProductAddInfoDto orderProductAddInfoDto = JSON.parseObject(orderItemResp.getExtInfo(), OrderProductAddInfoDto.class);
            orderItem.setProductAttribute(new ArrayList<>());
            if(CollectionUtils.isNotEmpty(orderProductAddInfoDto.getSpecialAttrs())) {
                for(OrderSpecialExtraAttrRequest orderSpecialExtraAttrRequest : orderProductAddInfoDto.getSpecialAttrs()) {
                    if(StringUtils.isNotBlank(orderSpecialExtraAttrRequest.getSpecialCode())) {
                        String[] codes = orderSpecialExtraAttrRequest.getSpecialCode().split("_");
                        if(codes.length > 2) {
                            McCafePushOrderDto.productAttribute productAttribute = new McCafePushOrderDto.productAttribute();
                            productAttribute.setGrillCode(codes[0]);
                            McCafePushOrderDto.GrillItem grillItem = new McCafePushOrderDto.GrillItem();
                            grillItem.setGrillItemCode(codes[1]);
                            grillItem.setGrillItemNameCn(orderSpecialExtraAttrRequest.getAttributeName());
                            grillItem.setGrillItemNameEn(orderSpecialExtraAttrRequest.getAttributeForeignName());
                            grillItem.setQuantity(codes[2]);
                            if (codes.length == 4){
                                grillItem.setIsModify(codes[3]);
                            }
                            productAttribute.setGrillItemList(Arrays.asList(grillItem));
                            orderItem.getProductAttribute().add(productAttribute);
                        }
                    }
                }
            }
            Integer materialPrice = 0;
            if(CollectionUtils.isNotEmpty(materialList)) {
                String parentProductId = orderItemResp.getProductId() + "_" + orderItemResp.getProductSeq();
                List<OrderItemResp> productMaterialList = materialList.stream().filter(o -> parentProductId.equals(o.getParentProductId())).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(productMaterialList)) {
                    for(OrderItemResp material : productMaterialList) {
                        if(material.getSalePrice().intValue() != 0) {
                            materialPrice += material.getSalePrice().intValue();
                        }
                        String[] codes = material.getThirdProductId().split("_");
                        if(codes.length > 1) {
                            McCafePushOrderDto.productAttribute productAttribute = new McCafePushOrderDto.productAttribute();
                            productAttribute.setGrillCode(codes[0]);
                            McCafePushOrderDto.GrillItem grillItem = new McCafePushOrderDto.GrillItem();
                            grillItem.setGrillItemCode(codes[1]);
                            grillItem.setGrillItemNameCn(material.getProductName());
                            grillItem.setGrillItemNameCn(material.getProductForeignName());
                            grillItem.setQuantity(material.getProductQuantity().toString());
                            if (codes.length == 3){
                                grillItem.setIsModify(codes[2]);
                            }
                            productAttribute.setGrillItemList(Arrays.asList(grillItem));
                            orderItem.getProductAttribute().add(productAttribute);
                        }
                    }
                }
            }
            orderItem.setProductName(orderItemResp.getProductName());
            orderItem.setProductLongName(orderItemResp.getProductName());
            orderItem.setProductNameEn(orderItemResp.getProductForeignName());
            orderItem.setProductLongNameEn(orderItemResp.getProductForeignName());
            orderItem.setQuantity(orderItemResp.getProductQuantity().toString());
            orderItem.setReal_quantity(orderItemResp.getProductQuantity().toString());
            orderItem.setOriginal_price(String.valueOf(orderItemResp.getSalePrice().intValue()));
            orderItem.setPrice(String.valueOf(orderItemResp.getSalePrice().intValue()+materialPrice));
            orderItem.setSubtotal(new BigDecimal(orderItem.getPrice()).multiply(new BigDecimal(orderItemResp.getProductQuantity())).intValue()+"");
            orderItem.setDiscountAmount(0+"");
            orderItem.setRealAmount(new BigDecimal(orderItem.getPrice()).multiply(new BigDecimal(orderItemResp.getProductQuantity())).intValue()+"");
            String taxId = "10";
            orderItem.setTaxId(taxId);
            Integer taxRate = 6;
            orderItem.setTaxRate(String.valueOf(taxRate));
            orderItem.setTaxAmount(String.valueOf(new BigDecimal(taxRate).multiply(new BigDecimal(orderItem.getPrice()))
                    .multiply(new BigDecimal(orderItemResp.getProductQuantity())).intValue()/100));
            taxTotalAmount += Integer.parseInt(orderItem.getTaxAmount());
            McCafePushOrderDto.TaxAmountDetail taxAmountDetail = new McCafePushOrderDto.TaxAmountDetail();
            taxAmountDetail.setUniqueCode(orderItemResp.getProductCode());
            McCafePushOrderDto.TaxItem taxItem = new McCafePushOrderDto.TaxItem();
            taxItem.setRealAmount(new BigDecimal(orderItem.getPrice()).multiply(new BigDecimal(orderItemResp.getProductQuantity())).intValue());
            taxItem.setTaxAmount(new BigDecimal(taxRate).multiply(new BigDecimal(orderItem.getPrice()))
                    .multiply(new BigDecimal(orderItemResp.getProductQuantity())).intValue()/100);
            taxItem.setTaxId(taxId);
            taxItem.setTaxRate(taxRate+"");
            taxAmountDetail.setTaxItems(Arrays.asList(taxItem));
            orderItem.setTaxAmountDetail(Arrays.asList(taxAmountDetail));
            if(StringUtils.isBlank(orderItemResp.getParentProductId()) && "0".equals(orderItemResp.getParentProductId())) {
                orderItem.setCostInclusive(null);
            } else {
                orderItem.setCostInclusive("1");
            }
            orderItem.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), "yyyy-MM-dd HH:mm:ss"));

            orderItemList.add(orderItem);
        }
        mcCafePushOrderDto.setOrderItem(orderItemList);
        mcCafePushOrderDto.setTaxTotalAmount(taxTotalAmount);

        List<McCafePushOrderDto.OrderPayment> orderPaymentList = new ArrayList<>();
        McCafePushOrderDto.OrderPayment orderPayment = new McCafePushOrderDto.OrderPayment();
        orderPayment.setChannelPayTransactionId(orderExtInfoDto.getPayTransId());
        orderPayment.setPayStatus("PAID");
        orderPayment.setPaySource(orderInfoReqs.getOrderClient().equals(OrderClientType.ALIPAY.getIndex())?"43":"10");
        orderPayment.setPayChannel(orderInfoReqs.getOrderClient().equals(OrderClientType.ALIPAY.getIndex())?"ALI":"WX");
        orderPayment.setPayAmount(orderInfoReqs.getActualPayAmount().intValue());
        if(NewOrderStatus.CLOSED.getIndex().equals(orderInfoReqs.getOrderState()) && CollectionUtils.isNotEmpty(orderInfoReqs.getAfterSalesOrderList())) {
            orderPayment.setRefundType(String.valueOf(1));
            orderPayment.setRefundAmount(orderInfoReqs.getActualPayAmount().intValue());
            if(afterSalesOrderRespOptional.isPresent()) {
                orderPayment.setRefundTime(DateUtil.convert2String(new Date(Long.valueOf(afterSalesOrderRespOptional.get().getCreateTime())), "yyyy-MM-dd HH:mm:ss"));
                orderPayment.setRefundReason(afterSalesOrderRespOptional.get().getAfterSalesReason());
            }
            orderPayment.setRefundStatus("REFUNDED");
            OrderRefundQueryRequest orderRefundQueryRequest = new OrderRefundQueryRequest();
            orderRefundQueryRequest.setPartnerId(mcCafePartnerId);
            orderRefundQueryRequest.setStoreId(orderInfoReqs.getStoreId());
            orderRefundQueryRequest.setOrgTransId(orderInfoReqs.getOrderCode());
            orderRefundQueryRequest.setOrgPayFmId(orderExtInfoDto.getFmId());
            com.freemud.application.sdk.api.base.BaseResponse<OrderRefundQueryResponse> refundQueryResponseBaseResponse =
                    paymentCenterService.orderRefundQuery(orderRefundQueryRequest, LogThreadLocal.getTrackingNo());
            if(ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(refundQueryResponseBaseResponse.getCode())
                    && null != refundQueryResponseBaseResponse.getData()
                    && ResponseConstant.SUCCESS_RESPONSE_CODE.equals(refundQueryResponseBaseResponse.getData().getStatusCode())) {
                orderPayment.setChannelRefundTransactionId(refundQueryResponseBaseResponse.getData().getRefundDetail().get(0).getEndTransId());
            } else {
                AppLogUtil.errorLog("获取退款三方流水号失败 request: "+ JSON.toJSONString(orderRefundQueryRequest) + "  response: "+JSON.toJSONString(refundQueryResponseBaseResponse), null, null, null);
                throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR, "获取退款三方流水号失败");
            }


        }
        orderPayment.setSignType("0");
        orderPayment.setPayPurpose("02");
        orderPayment.setConsumeType(NewOrderType.GENERAL_EXPRESS.getCode().equals(orderInfoReqs.getOrderType())?"02":"01");
        if(OrderClientType.ALIPAY.getIndex().equals(orderInfoReqs.getOrderClient())) {
            if(NewOrderType.GENERAL_EXPRESS.getCode().equals(orderInfoReqs.getOrderType())) {
                orderPayment.setTenderCode("152");
            } else {
                orderPayment.setTenderCode("151");
            }
        } else {
            if(NewOrderType.GENERAL_EXPRESS.getCode().equals(orderInfoReqs.getOrderType())) {
                orderPayment.setTenderCode("26");
            } else {
                orderPayment.setTenderCode("150");
            }
        }
        orderPayment.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getPayTime())), "yyyy-MM-dd HH:mm:ss"));
        orderPaymentList.add(orderPayment);
        mcCafePushOrderDto.setOrderPayment(orderPaymentList);

        if(NewOrderType.GENERAL_EXPRESS.getCode().equals(orderInfoReqs.getOrderType())) {
            McCafePushOrderDto.OrderDelivery orderDelivery = new McCafePushOrderDto.OrderDelivery();
            McCafePushOrderDto.OrderAddress orderAddress = new McCafePushOrderDto.OrderAddress();

            orderDelivery.setStatus("completed");
            if(CollectionUtils.isNotEmpty(orderInfoReqs.getDeliveryContactInfoList())) {
                for (DeliveryContactInfoResp deliveryContactInfoResp : orderInfoReqs.getDeliveryContactInfoList()) {
                    //地址类型 1:订单地址 2:售后单地址 3:配送员信息
                    if (deliveryContactInfoResp.getRelateObjectType() == 3) {
                        orderDelivery.setRiderNickName(deliveryContactInfoResp.getContactsName());
                        orderDelivery.setRiderMobileNo(deliveryContactInfoResp.getMobile());
                    }
                    if (deliveryContactInfoResp.getRelateObjectType() == 1) {
                        QueryReceiveAddressRequest request = new QueryReceiveAddressRequest(JSON.parseObject(deliveryContactInfoResp.getExtInfo()).getString("receiveId"), mcCafePartnerId);
                        com.freemud.application.sdk.api.base.BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(request, LogThreadLocal.getTrackingNo());
                        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
                            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR, "查询收货地址异常");
                        }
                        orderAddress.setGender(queryReceiveAddressResponse.getData().getSex().toString());
                        orderAddress.setPhone_no(queryReceiveAddressResponse.getData().getReceiveMobile());
                        if(StringUtils.isNotBlank(queryReceiveAddressResponse.getData().getReceiveAddress())) {
                            JSONObject jsonObject = JSON.parseObject(queryReceiveAddressResponse.getData().getReceiveAddress());
                            orderAddress.setAddress(jsonObject.getString("officeName"));
                            orderAddress.setDetail(jsonObject.getString("address"));
                        }
                        orderAddress.setLongitude(queryReceiveAddressResponse.getData().getLongitude());
                        orderAddress.setLatitude(queryReceiveAddressResponse.getData().getLatitude());
                        orderAddress.setCreatedDate(queryReceiveAddressResponse.getData().getCreateTime());
                    }
                }
            }
            orderDelivery.setCompletedTime(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getReceiveTime())), "yyyy-MM-dd HH:mm:ss"));
            orderDelivery.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), "yyyy-MM-dd HH:mm:ss"));

            orderAddress.setChannel(orderInfoReqs.getOrderClient().equals(OrderClientType.ALIPAY.getIndex())?"43":"10");
            orderAddress.setCustomerId(orderExtInfoDto.getThirdPartyMemberId());
            orderAddress.setCustomerNickName(orderInfoReqs.getUserName());

            mcCafePushOrderDto.setOrderDelivery(orderDelivery);
            mcCafePushOrderDto.setOrderAddress(orderAddress);
        }

        List<McCafePushOrderDto.OrderFoe> orderFoeList = new ArrayList<>();
        McCafePushOrderDto.OrderFoe orderFoe = new McCafePushOrderDto.OrderFoe();
        orderFoe.setFoeOrderKey(orderInfoReqs.getThirdOrderCode());
        orderFoe.setStoreCode(orderInfoReqs.getStoreId());
        orderFoe.setOrderType(orderInfoReqs.getOrderType()==3?"2":"1");
        orderFoe.setPickupCode(orderInfoReqs.getPickUpGoodsNo());
        orderFoe.setStatus("20");
        orderFoe.setFoeType("1");
        orderFoe.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(orderInfoReqs.getCreateTime())), "yyyy-MM-dd HH:mm:ss"));
        orderFoeList.add(orderFoe);
        if(NewOrderStatus.CLOSED.getIndex().equals(orderInfoReqs.getOrderState()) && CollectionUtils.isNotEmpty(orderInfoReqs.getAfterSalesOrderList())) {
            McCafePushOrderDto.OrderFoe afterSaleOrderFoe = new McCafePushOrderDto.OrderFoe();
            afterSaleOrderFoe.setFoeOrderKey("R".concat(orderInfoReqs.getThirdOrderCode()).concat(orderInfoReqs.getCreateTime()));
            afterSaleOrderFoe.setStoreCode(orderInfoReqs.getStoreId());
            afterSaleOrderFoe.setOrderType(orderInfoReqs.getOrderType()==3?"2":"1");
            afterSaleOrderFoe.setPickupCode(orderInfoReqs.getPickUpGoodsNo());
            afterSaleOrderFoe.setStatus("20");
            afterSaleOrderFoe.setFoeType("2");
            if(afterSalesOrderRespOptional.isPresent()) {
                afterSaleOrderFoe.setCreatedDate(DateUtil.convert2String(new Date(Long.valueOf(afterSalesOrderRespOptional.get().getCreateTime())), "yyyy-MM-dd HH:mm:ss"));
            }
            orderFoeList.add(afterSaleOrderFoe);
        }

        mcCafePushOrderDto.setOrderFoe(orderFoeList);

        return mcCafePushOrderDto;
    }

    private String parse2McdProductType(Integer productType) {
        switch (productType) {
            case 1:return "1";
            case 88:return "1";
            case 6:return "2";
            case 3:return "3";
            case 12:return "99";
            default:return "1";
        }
    }

    public static String getMcdOpenApiSign(String appId, String body, String merchantId, String timestamp, String key) {
        String signStr = String.format("AppId=%s&Body=%s&MerchantId=%s&Timestamp=%s&key=%s", appId, body, merchantId, timestamp, key);
        String sign = MD5Util.MD5Encode(signStr,"utf-8").toUpperCase();
        return sign;
    }

    public static void main(String[] args) {
        String t = String.valueOf(System.currentTimeMillis());
        System.out.println(t);
        System.out.println(getMcdOpenApiSign("132150066","{\"mpOrderId\":\"22210922765267866600006\",\"displayOrderId\":\"0\",\"type\":\"1\",\"saleType\":\"2\",\"eatType\":\"1\",\"deliveryType\":\"1\",\"sourceType\":\"WXMP\",\"beType\":\"3\",\"dayPart\":\"2\",\"channel\":\"10\",\"status\":\"80\",\"invoiceNeeded\":1,\"Invoiced\":1,\"customer_id\":\"MEDDY991578176625117171\",\"storeCode\":\"1450167\",\"storeName\":\"麦当劳麦咖啡（桂平路-漕河泾店）\",\"businessDate\":\"2021-09-17\",\"tablewareInfo\":\"02\",\"totalAmount\":2500,\"taxTotalAmount\":150,\"discountTotalAmount\":0,\"realTotalAmount\":2500,\"deliveryPrice\":0,\"realDeliveryPrice\":0,\"remark\":\"\",\"saleTime\":\"2021-09-17 14:51:28\",\"completionTime\":\"2021-09-17 15:51:05\",\"cancellationReasonCode\":\"-1\",\"cancellationRemark\":\"\",\"acceptTime\":\"2021-09-17 14:51:05.000\",\"pickupCode\":\"0\",\"openId\":\"oDF-Z5V60m2rgKYaHkf4ImhqR_XQ\",\"unionId\":\"oJeaRwyFU420hv0V3tddABipaH2I\",\"createdDate\":\"2021-09-17 14:51:05\",\"orderItem\":[{\"mpItemId\":\"190081895830260510\",\"sequenceId\":\"1\",\"round\":\"1\",\"productType\":\"1\",\"productCode\":\"507332\",\"productAttribute\":[{\"grillCode\":\"8008\",\"grillItemList\":[{\"grillItemCode\":\"1\",\"grillItemNameCn\":\"\",\"quantity\":\"1\"}]},{\"grillCode\":\"120146\",\"grillItemList\":[{\"grillItemCode\":\"0\",\"grillItemNameCn\":\"\",\"quantity\":\"1\"}]}],\"productName\":\"摩卡\",\"productLongName\":\"摩卡\",\"productNameEn\":\"\",\"productLongNameEn\":\"\",\"quantity\":\"1\",\"real_quantity\":\"1\",\"original_price\":\"2100\",\"price\":\"2500\",\"subtotal\":\"2500\",\"discountAmount\":\"0\",\"realAmount\":\"2500\",\"taxAmount\":\"150\",\"taxAmountDetail\":[{\"uniqueCode\":\"507332\",\"taxItems\":[{\"realAmount\":2500,\"taxAmount\":150,\"taxId\":\"10\",\"taxRate\":\"6\"}]}],\"taxId\":\"10\",\"taxRate\":\"6\",\"costInclusive\":\"1\",\"createdDate\":\"2021-09-17 14:51:05\"}],\"orderPayment\":[{\"channelPayTransactionId\":\"TSXA1205O347754218314084352\",\"payStatus\":\"PAID\",\"paySource\":\"10\",\"payChannel\":\"WX\",\"payAmount\":2500,\"refundType\":\"1\",\"refundAmount\":2500,\"refundTime\":\"2021-09-17 14:52:59\",\"refundReason\":\"用户申请退款\",\"signType\":\"0\",\"payPurpose\":\"02\",\"consumeType\":\"01\",\"tenderCode\":\"150\",\"refundStatus\":\"REFUNDED\",\"channelRefundTransactionId\":\"4200001214202109173002127737\",\"createdDate\":\"2021-09-17 14:51:28\"}],\"orderFoe\":[{\"foeOrderKey\":\"22210922765267866600006\",\"storeCode\":\"1450167\",\"orderType\":\"1\",\"pickupCode\":\"0\",\"status\":\"20\",\"foeType\":\"1\",\"createdDate\":\"2021-09-17 14:51:05\"},{\"foeOrderKey\":\"22210922765267866600006\",\"storeCode\":\"1450167\",\"orderType\":\"1\",\"pickupCode\":\"0\",\"status\":\"20\",\"foeType\":\"1\",\"createdDate\":\"2021-09-17 14:51:05\"}]}",
                "M32118436",t, "78c915bb-a3a3-4957-b177-27667adb8df1"));
    }
    /**
     * 标准点餐参数校验
     *
     * @param createOrderVo
     * @return
     */
    private BaseResponse checkStandardParamInfo(CreateOrderVo createOrderVo) {
        if (StringUtils.isEmpty(createOrderVo.getSessionId())) {
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_SESSION_ERROR);
        }
        if (StringUtils.isEmpty(createOrderVo.getShopId())) {
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_STORE_ERROR);
        }
        if (createOrderVo.getOrderType() == null) {
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_ORDERTYPE_ERROR);
        }
        return ResponseUtil.success();
    }

}
