/**
 * 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.*;
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.log.LogTreadLocal;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.OrderRefundConstant;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.MCCafeDeliveryBaseResponse;
import cn.freemud.entities.dto.PayAccessResponse;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.QueryOrdersResponseDto.DataBean.OrderBean;
import cn.freemud.entities.dto.activity.PayGiftCheckAndJoinResponseDto;
import cn.freemud.entities.dto.activity.PayGitCheckAndJoinRequestDto;
import cn.freemud.entities.dto.delivery.OrderRemindRequestDto;
import cn.freemud.entities.dto.delivery.QueryDeliveryAmountResponseDto;
import cn.freemud.entities.dto.delivery.QueryLocusRiderTrackDto;
import cn.freemud.entities.dto.delivery.ResRiderTrackDto;
import cn.freemud.entities.dto.delivery.*;
import cn.freemud.entities.dto.ecology.SendMessageRequest;
import cn.freemud.entities.dto.ecology.SendMessageResponse;
import cn.freemud.entities.dto.ecology.SubscribeMessageRequest;
import cn.freemud.entities.dto.order.CreateOrderOperateDto;
import cn.freemud.entities.dto.order.CreatePrepayRequestDto;
import cn.freemud.entities.dto.order.FacePayRequestDto;
import cn.freemud.entities.dto.order.FacePayResponseDto;
import cn.freemud.entities.dto.pay.CombPayResponse;
import cn.freemud.entities.dto.promotion.*;
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.CollageOrderDto;
import cn.freemud.entities.dto.shoppingCart.NewShoppingCartClearDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.enums.AfterSalesOrderCreateEventEnum;
import cn.freemud.enums.OrderChannelType;
import cn.freemud.enums.PayRefundStatus;
import cn.freemud.enums.PayStatus;
import cn.freemud.enums.QueryOrderStatus;
import cn.freemud.enums.RefundStatus;
import cn.freemud.enums.ResponseResult;
import cn.freemud.enums.OrderType;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.management.entities.dto.request.BatchOrderRefundV2Request;
import cn.freemud.management.entities.dto.response.activity.GroupWorkRefundResponse;
import cn.freemud.management.entities.dto.response.pay.PayBatchRefundResponse;
import cn.freemud.management.service.handle.ActivityHandle;
import cn.freemud.management.thirdparty.MulitiPaymentClient;
import cn.freemud.manager.BuyProductOnceManager;
import cn.freemud.manager.OrderTackCodeManager;
import cn.freemud.manager.SpellGroupOrderDataManager;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.BuriedPointService;
import cn.freemud.service.CouponActivityService;
import cn.freemud.service.OrderAdapterService;
import cn.freemud.service.Orderservice;
import cn.freemud.service.business.OrderBusinessService;
import cn.freemud.service.order.OrderRelationFactory;
import cn.freemud.service.order.OrderRelationService;
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.alibaba.fastjson.TypeReference;
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.cache.CacheOpenPlatformPartnerWxappConfigManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.api.assortment.datamanager.meal.MealCacheManager;
import com.freemud.application.sdk.api.constant.ResponseConstant;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.couponcenter.offline.service.OfflineCouponSdkService;
//import com.freemud.application.sdk.api.deliverycenter.service.DeliveryService;
//import com.freemud.application.sdk.api.deliverycenter.response.DeliveryInfoDto;
//import com.freemud.application.sdk.api.deliverycenter.response.DeliveryResponseDto;
//import com.freemud.application.sdk.api.deliverycenter.service.DeliveryService;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.entities.PayItem;
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.PayChannelType;
import com.freemud.application.sdk.api.ordercenter.enums.ProductTypeEnum;
import com.freemud.application.sdk.api.ordercenter.enums.*;
import com.freemud.application.sdk.api.ordercenter.request.OrderConditionsReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtendedReq;
import com.freemud.application.sdk.api.ordercenter.request.SdkUpdateAbnormalState;
import com.freemud.application.sdk.api.ordercenter.request.*;
import com.freemud.application.sdk.api.ordercenter.request.carpark.ParkingOrderCreateReq;
import com.freemud.application.sdk.api.ordercenter.response.BaseDownLoadResponse;
import com.freemud.application.sdk.api.ordercenter.response.OrderCountResp;
import com.freemud.application.sdk.api.ordercenter.response.OrderStateInfoResp;
import com.freemud.application.sdk.api.ordercenter.response.carpark.OrderResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderInfoReqs;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
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.PaymentCloseUnifiedOrderRequest;
import com.freemud.application.sdk.api.paymentcenter.client.request.PaymentQueryRequest;
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.PaymentCloseUnifiedOrderResponse;
import com.freemud.application.sdk.api.paymentcenter.client.response.PaymentQueryResponse;
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.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.structure.request.PushMessageNoticeDto;
import com.freemud.application.sdk.api.structure.service.MessageCenterClient;
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.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.enums.AutoOrderConfigTime;
import com.freemud.sdk.api.assortment.order.enums.NewOrderType;
import com.freemud.sdk.api.assortment.order.enums.OldOrderStatus;
import com.freemud.sdk.api.assortment.order.enums.QueryDeliveryType;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.request.payment.CombPayRequest;
import com.freemud.sdk.api.assortment.order.response.order.*;
import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.freemud.sdk.api.assortment.order.vo.ProductGroupVo;
import com.freemud.sdk.api.assortment.orderdistributor.entity.dto.PaymentMqMessageDto;
import com.freemud.sdk.api.assortment.orderdistributor.service.PaymentQueueService;
import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest;
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.StandardPaymentService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.commons.lang.builder.ToStringBuilder;
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.stereotype.Service;
import tk.mybatis.mapper.util.StringUtil;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.freemud.constant.OrderRefundConstant.ALLOW_REFUND;
@Slf4j
@Service
public class OrderServiceImpl implements Orderservice {

    private final Integer RESPONSE_SUCCESS_CODE = 100;

    private static Gson gson = new Gson();

    @Value("${saas.reverseNotifyiDcUrl}")
    private String reverseNotifyiDcUrl;
    @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("${collage.pre_order_pay.goods_tag}")
    private String collageGoodsTag;
    @Value("${collage.pre_order_pay.goods_tag_list}")
    private String collageGoodsTagList;
    /**
     * coco商户
     */
    @Value("#{'${coco.partnerId}'.split(',')}")
    private List<String> cocoPartnerId;
    @Value("#{'${hls.partnerId}'.split(',')}")
    private List<String> hlsPartnerId;
    @Value("#{'${order.not.automatic.twist.partnerId}'.split(',')}")
    private List<String> notAutomaticTwistPartnerId;
    @Value("${order.not.automatic.twist.time}")
    private Integer notAutomaticTwistTime;

    @Value("${query.order.es:true}")
    private Boolean queryOrderEs;

    @Autowired
    private AssortmentCloudPrinterManager cloudPrinterManager;
    //    @Autowired
//    private OrderCommonService orderCommonService;
    @Autowired
    private FMAssistantCloudPrintClient fmAssistantCloudPrintClient;
    @Autowired
    private MessageCenterClient messageNoticeClient;
    @Autowired
    private PromotionActivityClient promotionActivityClient;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private ItemServiceImpl itemService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private CouponActivityService couponActivityService;
    @Autowired
    private MessageNoticeAdapter messageNoticeAdapter;
    @Autowired
    private OrderAdapter orderAdapter;
    @Autowired
    private ActivityAdapter activityAdapter;
    @Autowired
    private CouponAdapter couponAdapter;
    //    @Autowired
//    private ActivitySdkAdapter activitySdkAdapter;
    @Autowired
    private MealCacheManager mealCacheManager;
    //聚合订单服务
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
    private StandardPaymentService standardPaymentService;
    //门店SDK
    @Autowired
    private StoreCenterService storeCenterService;
//    @Autowired
//    private DeliveryService deliveryService;
    @Autowired
    private MQService mqService;
    @Autowired
    @Qualifier("messageTemplatePushOrderService")
    private IMessageTemplatePushService<MessagePushOrderTemplateRequest> messageTemplatePushService;
    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private CheckOrder checkOrder;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private PaymentQueueService paymentQueueService;
    @Autowired
    private PaymentNewService paymentNewService;
    @Autowired
    private ActivityApplicationClient activityApplicationClient;
    @Autowired
    private AssortmentOpenPlatformWxappAuthorizerManager wxappAuthorizerManager;
    @Autowired
    private PaymentNewClient paymentNewClient;
    //    @Autowired
//    private MallOrderServiceImpl mallOrderService;
    @Autowired
    private CacheOpenPlatformPartnerWxappConfigManager cacheOpenPlatformPartnerWxappConfigManager;
    @Autowired
    private OrderAdapterService orderAdapterService;
    @Autowired
    private AssortmentOpenPlatformPartnerManager assortmentOpenPlatformPartnerManager;
    @Autowired
    private OrderSdkService orderSdkService;
    @Autowired
    private OrderDownLoadSdkService orderDownLoadSdkService;
    @Autowired
    private OrderSdkAdapter orderSdkAdapter;
    @Autowired
    private OfflineCouponSdkService offlineCouponSdkService;
    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;
    @Autowired
    private MulitiPaymentClient mulitiPaymentClient;

    @Autowired
    private CustomerExtendClient extendClient;

    @Autowired
    private ComPayClient comPayClient;
    @Autowired
    private AssortmentOpenPlatformIappWxappStoreManager assortmentOpenPlatformIappWxappStoreManager;
    @Autowired
    private EcologyAdminApplicationClient ecologyAdminApplicationClient;

    @Autowired
    private SvcComPayClient svcComPayClient;

    @Autowired
    private AssortmentOpenPlatformPartnerConfigManager openPlatformPartnerConfigManager;

    @Autowired
    private OrderRelationFactory orderRelationFactory;

    @Autowired
    private SpellGroupOrderDataManager spellGroupOrderDataManager;

    @Autowired
    private SpellGroupOrderAdapter spellGroupOrderAdapter;

    @Autowired
    private ActivityHandle activityHandle;

    @Autowired
    private OrderTackCodeManager orderTackCodeManager;

    @Autowired
    private OrderBusinessService orderBusinessService;

    @Autowired
    private BuyProductOnceManager buyProductOnceManager;

    @Override
    public BaseResponse checkBeforeCreateOrder(CheckBeforeCreateOrderRequestVo requestVo) {
        String trackingNo = LogTreadLocal.getTrackingNo();
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(requestVo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        StoreResponse storeResponse = checkOrder.getStoreInfo(requestVo.getPartnerId(), requestVo.getShopId(), trackingNo);
        if (storeResponse == null || storeResponse.getBizVO() == null) {
            return ResponseUtil.error(ResponseResult.STORE_NOT_FOUND);
        }
        StoreResponse.BizVO storeInfo = storeResponse.getBizVO();
        CheckBeforeCreateOrderResponseVo responseVo = new CheckBeforeCreateOrderResponseVo();
        Integer maxOrderQuantity = storeInfo.getMaxOrderQuantity();
        if (maxOrderQuantity == null) {
            maxOrderQuantity = 100;
        }
        // 调用文顺接口获取队列长度
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setPartnerId(requestVo.getPartnerId());
        baseQueryOrderRequest.setShopId(requestVo.getShopId());
        baseQueryOrderRequest.setTrackingNo(trackingNo);
        BaseOrderResponse queryStoreOrderQuantity = orderCenterSdkService.queryStoreOrderQuantity(baseQueryOrderRequest);
        QueryStoreOrderQuantityResponseDto responseDto = new QueryStoreOrderQuantityResponseDto();
        BeanUtil.convertBean(queryStoreOrderQuantity, responseDto);

        if (!RESPONSE_SUCCESS_CODE.equals(responseDto.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERY_QUANTITYR_ERROR);
        }
        Integer lineNumber = Integer.parseInt(responseDto.getData());
        // 判断最大接单量和队列长度的关系
        if (maxOrderQuantity > lineNumber) {
            responseVo.setWhetherMaxOrderQuantity(false);
            responseVo.setBeforeNumber(lineNumber);
            responseVo.setWarningInfo("");
        } else {
            responseVo.setWhetherMaxOrderQuantity(true);
            String beforeMessage = "您前面排队超过";
            String afterMessage = "单，出餐时间稍长，是否继续提交？";
            responseVo.setBeforeNumber(lineNumber);
            responseVo.setWarningInfo(beforeMessage + lineNumber + afterMessage);
        }
        return ResponseUtil.success(responseVo);
    }

    // 原来saas
    @Override
    public BaseResponse createOrderNew(CreateOrderVo createOrderVo) {
        String trackingNo = LogThreadLocal.getTrackingNo();
        // 查询用户信息、校验svc卡,余额购物车校验
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.checkOrderByMember(createOrderVo, trackingNo);
        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内 点餐桌号
        StoreResponse.BizVO storeResponseDto = checkOrder.checkOrderByStore(createOrderVo, trackingNo);
        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数
        ShoppingCartGoodsDto shoppingCartGoodsDto = checkOrder.getShoppingCartGoodsDto(createOrderVo);
        // 查询小程序自提外卖配置信息 校验当前订单类型的下单参数 校验外卖是否满足起送条件
        Integer pushOrderTime = checkOrder.checkOrderByOrderType(createOrderVo, userLoginInfoDto, storeResponseDto, shoppingCartGoodsDto, trackingNo);
        OrderExtInfoDto extInfo = getExtInfo(userLoginInfoDto, storeResponseDto, pushOrderTime, createOrderVo, shoppingCartGoodsDto);
        //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(userLoginInfoDto, createOrderVo, createOrderOperateDto, extInfo);
        return this.createPrepayOrder(createPrepayRequestDto);
    }




    public CreateOrderResponse getCreateOrderResponse(String code, String message, QueryOrdersResponse.DataBean.OrderBean data) {
        CreateOrderResponse baseOrderResponse = new CreateOrderResponse();
        baseOrderResponse.setErrcode(Integer.valueOf(code));
        baseOrderResponse.setErrmsg(message);
        baseOrderResponse.setData(data);
        return baseOrderResponse;
    }
    /**
     * 扫脸支付下单
     */
    @Override
    public BaseResponse scanFaceCreateOrder(CreateOrderVo createOrderVo) {
        String trackingNo = LogThreadLocal.getTrackingNo();
        // 查询用户信息、校验svc卡,余额购物车校验
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.checkOrderByMember(createOrderVo, trackingNo);
        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内 点餐桌号
        StoreResponse.BizVO storeResponseDto = checkOrder.checkOrderByStore(createOrderVo, trackingNo);
        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数
        ShoppingCartGoodsDto shoppingCartGoodsDto = checkOrder.getShoppingCartGoodsDto(createOrderVo);
        // 查询小程序自提外卖配置信息 校验当前订单类型的下单参数 校验外卖是否满足起送条件
        Integer pushOrderTime = checkOrder.checkOrderByOrderType(createOrderVo, userLoginInfoDto, storeResponseDto, shoppingCartGoodsDto, trackingNo);
        //1.5.4版本，商品库存校验与扣库存
        //List<String> stockProductIds = checkOrder.getStockProductIdList(createOrderVo, shoppingCartGoodsDto);
        OrderExtInfoDto extInfo = getExtInfo(userLoginInfoDto, storeResponseDto, pushOrderTime, createOrderVo, shoppingCartGoodsDto);
        //下单并支付
        return this.createOrderAndPay(createOrderVo, storeResponseDto, shoppingCartGoodsDto, userLoginInfoDto, extInfo);
    }

    /**
     * 获取预支付成功，将信息放入死心队列，当支付成功没有回掉的时候处理
     *
     * @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) {
            LogUtil.error("paymentQueueService.paymentCallback", "", orderId, e);
        }
    }

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



    @Override
    public String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, QueryOrdersResponseDto.DataBean.OrderBean> orderBeans) {
        OrderBean 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();
        }
        //若该订单使用了优惠券，则移除卡包,移除失败也不退款，现在支付成功个调用核销，无需调用此功能
//        couponActivityService.callbackNotify(orderBean);
        // 订单失败后 发消息重试 待实现
        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());
        var1.setMealCodeRule(getMealCodeRule(wxappid));
        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));
        }
        //合阔pos 商户不接单自动退款时间
        if (CollectionUtils.isNotEmpty(notAutomaticTwistPartnerId) && notAutomaticTwistPartnerId.contains(partnerId)) {
            var1.setNotAutomaticTwistTime(notAutomaticTwistTime);
        }
        String pickUpGoodsNo = orderTackCodeManager.generateTackCode(orderBean.getType(),partnerId,storeId,var1,OrderTackCodeFactory.getByOrderClient(orderBean.getOrderClient()).getGenerateTackCodeFunc());
        var1.setPickUpGoodsNo(pickUpGoodsNo);
        // 订单支付成功
        com.freemud.sdk.api.assortment.order.response.order.PayAccessResponse payAccessRes = orderBusinessService.payAccess(var1);
        String string2 = JSONObject.toJSONString(payAccessRes);
        JSONObject jsonObject2 = JSONObject.parseObject(string2);
        payAccessResponse = jsonObject2.toJavaObject(PayAccessResponse.class);
        // 添加幂等处理，若订单是已支付成功状态，直接返回成功
        if (!RESPONSE_SUCCESS_CODE.equals(payAccessResponse.getErrcode())) {
            OrderBean 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();
            }
            LogUtil.error("paySuccessCallback_payAccess_faild", gson.toJson(confirmOrderDto), gson.toJson(payAccessResponse));
            //orderRefund(orderBean, "订单异常退款", openid, oid);
            return gson.toJson(message);
        }
        // TODO 订单序号替换取餐码显示
        takeCode = payAccessResponse.getData().getTakeCode();
        daySeq = payAccessResponse.getData().getDaySeq();

        if (null != orderBean.getMarketingType() && OrderMarketType.COLLAGE.getIndex() == orderBean.getMarketingType()) {
            // 更新拼单购物车状态
            CollageOrderDto collageOrderDto = new CollageOrderDto();
            collageOrderDto.setSessionId(StringUtils.isBlank(sessionId) ? oid : sessionId);
            collageOrderDto.setPartnerId(partnerId);
            collageOrderDto.setShopId(storeId);
            collageOrderDto.setCreateCollageUserId(userId);
            collageOrderDto.setOrderCode(oid);
            collageOrderDto.setStatus(1);
            shoppingCartClient.updateCollageOrder(collageOrderDto);
        } else {
            //TODO 清空购物车
            NewShoppingCartClearDto newShoppingCartClearDto = new NewShoppingCartClearDto();
            newShoppingCartClearDto.setPartnerId(partnerId);
            newShoppingCartClearDto.setShopId(storeId);
            newShoppingCartClearDto.setUserId(userId);
            newShoppingCartClearDto.setAppId(wxappid);
            newShoppingCartClearDto.setSessionId(sessionId);
            newShoppingCartClearDto.setOperationType(1);
            shoppingCartClient.clearShoppingCart(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) {
            LogUtil.error("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 (StringUtils.isNotBlank(ruleId)) {
            this.activateMemberCard(partnerId, ruleId, oid, userId, storeId, orderBean.getShopName());
        }
        //支付回掉成功标记
        redisCache.save(RedisKeyConstant.KGD_PAYMENT_CALLBACK_FMID + message.getOut_trade_no(), message.getOut_trade_no(), 10L, TimeUnit.MINUTES);
        if (message.getSource() != null && message.getSource().equals(PaySuccessSource.OUTSIDE.getSource())) {
            ApiLog.debug("调用券码核销==" + message.getTrans_id());
            verificationCoupon(message.getTrans_id());
            ApiLog.debug("调用券码结束==" + message.getTrans_id());
        }
        //支付成功后
//        buriedPointService.paySuccessBuridPoint(partnerId, storeId, orderBean);
        return sendPaySuccessNoticeMessage();
    }

    public Map<String, OrderBean> getOrderBeanByOrderId(String orderId) {
        // 订单查询：若结果集只有一个orderBean，则为普通订单，否则为会员卡订单（父子订单）
        Map<String, OrderBean> 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<OrderBean> saasOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            List<OrderBean> memberOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(3) && !order.isParent()).collect(Collectors.toList());
            List<OrderBean> fatherOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(2) && order.isParent()).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 partnerId 商户号
     * @param ruleId    会员规则ID
     * @param oid       订单号
     * @param userId    用户ID
     * @param storeId   门店id
     * @param shopName  门店名称
     */
    private void activateMemberCard(String partnerId, String ruleId, String oid, String userId, String storeId, String shopName) {
        PurchasePaidRequestDto purchasePaidRequestDto = new PurchasePaidRequestDto();
        purchasePaidRequestDto.setPartnerId(partnerId);
        purchasePaidRequestDto.setOperatorType(0);
        purchasePaidRequestDto.setRuleId(ruleId);
        purchasePaidRequestDto.setOrderId(oid);
        purchasePaidRequestDto.setMemberId(userId);
        purchasePaidRequestDto.setPromoteStoreId(storeId);
        purchasePaidRequestDto.setPromoteStoreName(shopName);
        // 尝试三次开通会员卡，中途成功则跳出
        int count = 3;
        for (int i = 1; i <= count; i++) {
            BaseResponse baseResponse = customerApplicationClient.purchasePaid(purchasePaidRequestDto);
            // 不以响应码为判断是否开通会员卡成功的标准
            if (baseResponse != null && "SUCCESS".equals(baseResponse.getResult())) {
                break;
            }
            // 尝试开通会员卡失败三次
            if (i >= count) {
                LogUtil.error("尝试开通会员卡失败" + count + "次", JSON.toJSONString(purchasePaidRequestDto), JSON.toJSONString(baseResponse));
            }
        }
    }

    @Override
    public String newPaySuccessCallback(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.getMerchantCoupon() == null ? 0 : newMessage.getMerchantCoupon());
        message.setPaid_no(newMessage.getThirdPartTradeNo());
        message.setEndTransId(newMessage.getEndTransId());
        message.setPlatformMchId(newMessage.getPlatformMchId());
        message.setTerminalId(newMessage.getAppId());
        message.setRuleId(newMessage.getRuleId());
        message.setSource(PaySuccessSource.OUTSIDE.getSource());
        String res = orderAdapterService.paySuccessCallback(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)) {
                return newSendPaySuccessNoticeMessage();
            } else {
                return newSendPayFaileMessage();
            }
        }
        return newSendPayFaileMessage();
    }

    private String verificationCoupon(String transId) {
        String orderId = redisCache.getValue(RedisUtil.getPaymentTransIdOrderKey(transId));
        if (StringUtils.isNotBlank(orderId)) {
            ApiLog.debug("从缓存中获取的订单数据,trackingNo:{},transId:{},orderId:{}", LogTreadLocal.getTrackingNo(), transId, orderId);
            transId = orderId;
        }
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = getQueryRelationOrderByIdResponseDto(transId);
        if (queryOrderByIdResponseDto.getData() == null || !Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS, queryOrderByIdResponseDto.getErrcode())) {
            return refundFaileMessage("order query fail" + queryOrderByIdResponseDto);
        }
        OrderBean orderBean = new OrderBean();
        if (1 == queryOrderByIdResponseDto.getData().size()) {
            orderBean = queryOrderByIdResponseDto.getData().get(0);
        } else {
            List<OrderBean> orderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(orderBeans)) {
                orderBean = orderBeans.get(0);
            }
        }
        //核销券
        BaseResponse baseResponse = couponActivityService.verificationCoupon(orderBean, CouponReqType.WRITEOFF);
        return "核销券码返回结果" + baseResponse.getCode() + "," + baseResponse.getMessage();
    }

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

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

        //订单状态
        Integer status = orderBean.getRefundList().get(0).getStatus();
        if (!Objects.equals(RefundStatus.ALREADY_REFUND.getCode(), status)) {
            //不是退款中处理不处理
            return refundFaileMessage("order status is not 3,status=" + status);
        }
        String afterSalesCode = orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getRid();
        //退款流水号
        BaseQueryOrderRequest request = new BaseQueryOrderRequest();
        request.setPartnerId(requestVo.getPartnerId());
        request.setOrderId(requestVo.getTransId());
        request.setAfterSalesCode(afterSalesCode);
        request.setRefundSerialNo(requestVo.getRefundId());
        request.setOperator("admin");
        request.setTrackingNo(trackingNo);
        BaseOrderResponse response = orderCenterSdkService.orderRefundComplete(request);
        if (response == null || !Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS, response.getErrcode())) {
            return refundFaileMessage("orderRefundComplete fail" + response);
        }
        return newSendPaySuccessNoticeMessage();
    }

    public QueryRelationOrderByIdResponseDto getQueryRelationOrderByIdResponseDto(String oid) {
        QueryRelatedOrderByCodeRequest baseQueryOrderRequest = new QueryRelatedOrderByCodeRequest();
        baseQueryOrderRequest.setOrderCode(oid);
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.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, OrderBean.class));
        return queryOrderByIdResponseDto;
    }

    @Override
    public BaseResponse queryOrders(QueryOrderVo 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())) {
            if (isQueryEs(queryOrderVo.getQueryOrderStatus()) && queryOrderEs) {
                queryOrderVo.setStartDate(DateUtil.convert2String(DateUtil.addMonths(new Date(), -3), "yyyy-MM-dd"));
            } else {
                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 (queryOrderVo.getQueryOrderStatus() == null) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "查询订单状态不能为空");
        }
        if (queryOrderVo.getQueryOrderType() != null) {
            if (OrderType.getByCode(queryOrderVo.getQueryOrderType()) == null) {
                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 (isQueryEs(queryOrderVo.getQueryOrderStatus()) && queryOrderEs) {
            Date startDateEs = DateUtil.convert2Date(startDateStr, "yyyy-MM-dd");
            Date endDateEs = DateUtil.convert2Date(new Date(), "yyyy-MM-dd");
            if (startDateEs.getTime() < DateUtil.addMonths(endDateEs, -3).getTime()) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "只能查询3个月内的订单信息");
            }
        } else {
            if (startDate.getTime() < DateUtil.addMonths(new Date(), -3).getTime()) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "只能查询3个月内的订单信息");
            }
        }

        String userId = userLoginInfoDto.getMemberId();
        QueryOrderDto queryOrderDto = BeanUtil.convertBean(queryOrderVo, QueryOrderDto::new);
        queryOrderDto.setPartnerId(queryOrderVo.getPartnerId());
        queryOrderDto.setStartDate(startDateStr);
        queryOrderDto.setEndDate(endDateStr);
        String channelType = this.getQueryOrderChannelType(queryOrderVo, userLoginInfoDto);
        QueryOrdersDto queryOrdersDto = orderAdapter.convent2QueryOrdersDto(queryOrderDto, userId, channelType);
        QueryOrdersResponse queryOrderResponse;
        try {
            QueryOrdersRequest queryOrdersRequest2 = new QueryOrdersRequest();
            BeanUtil.convertBean(queryOrdersDto, queryOrdersRequest2);
            queryOrdersRequest2.setTrackingNo(LogTreadLocal.getTrackingNo());
            // 订单要查3个月的，如果查询的订单状态是待取餐、未支付，则查实时，否则，查es
            if (isQueryEs(queryOrderVo.getQueryOrderStatus()) && queryOrderEs) {
                OrderConditionsReq es = new OrderConditionsReq();
                es.setPartnerId(queryOrderVo.getPartnerId());
                es.setUserId(userId);
                es.setStartTimestamp(DateTimeUtil.parseDate(startDateStr, DateTimeUtil.YYYY_MM_DD_HH_MM_SS).getTime() / 1000);
                es.setEndTimestamp(DateTimeUtil.parseDate(endDateStr, DateTimeUtil.YYYY_MM_DD_HH_MM_SS).getTime() / 1000);
                es.setPageNum(queryOrderVo.getPageNumber());
                es.setPageSize(queryOrderVo.getPageSize());
                es.setMarketingType(queryOrderVo.getMarketingType());
                OrderConditionsReq queryEs = orderAdapter.convent2QueryOrdersDtoES(es, userId, channelType, queryOrderVo.getQueryOrderStatus(), queryOrderVo.getQueryOrderType(), queryOrderVo.getQueryPayStatus());

                BaseDownLoadResponse<List<OrderInfoReqs>> response = orderDownLoadSdkService.queryOrderByConditions(queryEs, LogThreadLocal.getTrackingNo());

                queryOrderResponse = orderAdapter.conventEs2queryOrderResponse(response);
            } else {
                queryOrderResponse = orderCenterSdkService.queryOrders(queryOrdersRequest2);
            }

        } catch (Exception e) {
            LogUtil.error("queryOrders_error", gson.toJson(queryOrdersDto), 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<QueryOrdersResponse.DataBean.OrderBean> ordersOld = queryOrderResponse.getData().getOrders();
        List<QueryOrdersResponse.DataBean.OrderBean> orders = new ArrayList<>();
        Set<String> shopIds = new HashSet<>();
        // 过滤待支付订单
        if (CollectionUtils.isNotEmpty(ordersOld)) {
            for (QueryOrdersResponse.DataBean.OrderBean orderBean : ordersOld) {
                if (!(OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus()) || PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()))) {
                    shopIds.add(orderBean.getShopId());
                }
                //围餐过滤掉未唤起支付的订单
                if (OrderChannelType.IWC.getCode().equals(channelType) && OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus()) && PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus())) {
                    // 如果已经唤起了支付则不再进行促销计算
                    boolean prePayLock = mealCacheManager.getOrderCreatePreParmentLock(userLoginInfoDto.getPartnerId(), userLoginInfoDto.getStoreId(), userLoginInfoDto.getTableNumber());
                    if (prePayLock) {
                        //已唤起支付
                        orders.add(orderBean);
                    }
                } else {
                    orders.add(orderBean);
                }
            }
        }
        String storeCodes = "";
        for (String shopId : shopIds) {
            storeCodes = shopId + "," + storeCodes;
        }
        GetListByCodesRequest request = new GetListByCodesRequest();
        request.setPartnerId(partnerId);
        request.setStoreCodes(storeCodes);
        // 查询多个门店信息
        GetListByCodesResponse storeInfoResponse = storeCenterService.getListByCodes(request, LogTreadLocal.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((StringUtils.isNotBlank(storeResponseDto.getLatitude()) ? Double.valueOf(storeResponseDto.getLatitude()) : 0d));
                    orderBean.setLongitude((StringUtils.isNotBlank(storeResponseDto.getLongitude()) ? Double.valueOf(storeResponseDto.getLongitude()) : 0d));
                }
                // 获取订单运单号，如果有运单则是第三方外卖单
                if (orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getDeliveryId())) {
                    hasThirdDelivery(orderBean);
                }
                orderBean.setQueueIndex("");
                // 查询待取餐订单才需要查询排队人数和订单状态扭转记录
                if (QueryOrderStatus.TAKE_MEAL.getCode().equals(queryOrderDto.getQueryOrderStatus())) {
                    String returnWords = "";
                    Integer productSum = 0; //件数
                    Long pickUpTime = 0L; //预计
                    Integer totalSumTime = 0;
                    String progress = "0"; //进度
                    Integer orderProgressBarStatus = 2;
                    try {
                        if (null != storeResponseDto) {
                            String configurationStr = storeResponseDto.getConfiguration();
                            if (StringUtils.isNotEmpty(configurationStr)) {
                                StoreResponse.Configuration configuration = JSONObject.parseObject(configurationStr).toJavaObject(StoreResponse.Configuration.class);
                                if (null != configuration) {
                                    orderProgressBarStatus = configuration.getOrderProgressBarStatus();
                                    ; //默认关闭
                                    //订单状态为已接单并且无售后单展示进度条
                                    if (OrderStatus.RECEIPT.getCode() == orderBean.getStatus() && null == orderBean.getAfterSalesOrderResp() && null != orderProgressBarStatus && null != configuration.getTurnOnTimeOfMaking()) {
                                        // 查询订单的排队人数
                                        QueryLineUpOrderReq queryLineUpOrderReq = new QueryLineUpOrderReq();
                                        queryLineUpOrderReq.setPartnerId(orderBean.getCompanyId());
                                        queryLineUpOrderReq.setStoreId(orderBean.getShopId());
                                        queryLineUpOrderReq.setStartTime(DateUtil.addHours(new Date(orderBean.getGmtCreate()), -24).getTime());
                                        queryLineUpOrderReq.setEndTime(orderBean.getGmtCreate());
                                        // 取餐排队人数查询代码去除
                                        QueryLineUpResponse response = orderCenterSdkService.queryLineUpOrder(queryLineUpOrderReq);
                                        if (RESPONSE_SUCCESS_CODE.equals(response.getErrcode())) {
                                            if (null == response.getOrderCodes()) {
                                                progress = "100";
                                                returnWords = "";
                                            } else {
                                                List<String> orderCodeList = response.getOrderCodes();
                                                if (null != orderCodeList && orderCodeList.size() > 0) {
                                                    returnWords += "前方还有 " + orderCodeList.size() + " 单";
                                                    //开启制作时间 1 ：是 ， 2 ：否"
                                                    if (1 != configuration.getTurnOnTimeOfMaking()) {
                                                        totalSumTime = orderCodeList.size() * AutoOrderConfigTime.getTime(configuration.getAutoSelfmentionTakeOrderWorkflowFinishTime()); //分钟
                                                    } else {
                                                        Integer goodsAvgTimeOfMaking = (null == configuration.getGoodsAvgTimeOfMaking() || 0 == configuration.getGoodsAvgTimeOfMaking()) ? 5 : configuration.getGoodsAvgTimeOfMaking();
                                                        productSum = orderCodeList.stream().mapToInt(product -> Integer.parseInt(product.split("-")[1])).sum();
                                                        totalSumTime = productSum * goodsAvgTimeOfMaking;
                                                        returnWords += " / " + productSum + " 件";
                                                    }
                                                    pickUpTime = DateUtil.addMinutes(new Date(orderBean.getGmtAccept()), totalSumTime).getTime();
                                                    Date date = new Date(pickUpTime);
                                                    returnWords += "，预计 " + (String.valueOf(date.getHours()).length() == 1 ? "0" + (String.valueOf(date.getHours())) : date.getHours()) + ":" + (String.valueOf(date.getMinutes()).length() == 1 ? "0" + (String.valueOf(date.getMinutes())) : date.getMinutes()) + " 可取餐";
                                                    //制餐进度（当前时间-接单时间）/总时长（制餐时长）x100%
                                                    BigDecimal progressB = new BigDecimal(DateUtil.diffMinute(new Date(orderBean.getGmtAccept()), new Date())).divide(new BigDecimal(totalSumTime), 2, BigDecimal.ROUND_HALF_UP);
                                                    progress = progressB.compareTo(new BigDecimal(1)) == 1 ? "100" : progressB.multiply(new BigDecimal(100)).toString();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        LogUtil.error("get returnWords", "",JSONObject.toJSONString(storeResponseDto),e);
                    }
                    orderBean.setProgress(String.valueOf(progress));
                    orderBean.setReturnWords(returnWords);
                    orderBean.setOrderProgressBarStatus(orderProgressBarStatus);
                    //以下代码为老代码，不确定还在不在用，就留着了
                    // 查询订单的排队人数
                    BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
                    var1.setOrderId(orderBean.getOid());
                    var1.setTrackingNo(LogTreadLocal.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(LogTreadLocal.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);
                    }
                }

            });
        }

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

        if (QueryOrderStatus.TAKE_MEAL.getCode().intValue() == queryOrderVo.getQueryOrderStatus()) {
            queryOrderResponseVos.forEach(queryOrderResponseVo -> {
                try {
                    // 判断是否有裂变活动 订单扩展信息判断必须有wxappid
                    // 查询门店下有没有 裂变活动
                    Long orderTime = DateUtil.convert2Date(queryOrderResponseVo.getOrderCreateTime(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS).getTime();
                    StoreResponse.BizVO bizVO = storeMap.get(queryOrderResponseVo.getShopId());
                    String activityId = isShareActivity(queryOrderVo.getPartnerId(), queryOrderResponseVo.getShopId()
                            , queryOrderResponseVo.getWxappid()
                            , orderTime == null ? 0 : orderTime
                            , queryOrderResponseVo.getOid()
                            , userId
                            , queryOrderVo.getSessionId()
                            , bizVO.getParentCode());
                    // 取红包图片
                    queryOrderResponseVo.setRedpacketsPicture(getRedpacketsPicture(activityId));
                    queryOrderResponseVo.setActivityId(activityId);

                    // coco订单不考略是否查询待取餐的订单，直接调用支付有礼活动
                    // 所以在这个地方排除掉coco，在下边单独实现
                    //参与支付有礼活动
                    if (!cocoPartnerId.contains(queryOrderVo.getPartnerId())) {
                        joinPayGift(queryOrderVo.getSessionId(), queryOrderResponseVo, partnerId, queryOrderVo.getPayGiftVer());
                    }

                } catch (Exception e) {
                    LogUtil.error("queryOrders_activity_error", gson.toJson(queryOrdersDto), gson.toJson(queryOrderResponseVo), e);
                }
            });
        }

        // coco订单参与支付有礼活动
        if (cocoPartnerId.contains(queryOrderVo.getPartnerId())) {
            queryOrderResponseVos.forEach(queryOrderResponseVo -> {
                try {
                    joinPayGift(queryOrderVo.getSessionId(), queryOrderResponseVo, partnerId, null);

                } catch (Exception e) {
                    LogUtil.error("coco_queryOrders_activity_error", gson.toJson(queryOrdersDto), gson.toJson(queryOrderResponseVo), e);
                }
            });
        }

        for(QueryOrderResponseVo orderResponseVo : queryOrderResponseVos){
            if (OrderMarketType.GROUPB.getIndex() == orderResponseVo.getMarketingType() && StringUtils.isNotEmpty(orderResponseVo.getSpellGroupCode())
                    && orders.get(0).getApportionDetails() != null) {
                QueryHistoryGroupVO querySpellGroupVo = spellGroupOrderDataManager.queryHistoryByGroupId(orderResponseVo.getSpellGroupCode(),
                         partnerId,userId);
                orderResponseVo.setSpellGroup(querySpellGroupVo);
            }
        }


        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);
    }

    @Override
    public BaseResponse queryCollageOrderById(Integer operation, String sessionId, String oid, String partnerId, String channel) {

        BaseResponse orderInfoRes = this.queryOrderById(operation, sessionId, oid, partnerId, channel);

        if (null == orderInfoRes.getResult() || !String.valueOf(RESPONSE_SUCCESS_CODE).equals(orderInfoRes.getCode())) {
            return orderInfoRes;
        }

        // 根据用户聚合商品信息
        QueryCollageOrderResponseVo queryCollageOrderResponseVo = new QueryCollageOrderResponseVo();
        QueryOrderResponseVo queryOrderResponseVo = (QueryOrderResponseVo) orderInfoRes.getResult();
        List<ProductVo> productVo = queryOrderResponseVo.getProducts();
        // 根据用户id分类商品
        Map<String, List<ProductVo>> orderItemMap = productVo.stream().collect(Collectors.groupingBy(ProductVo::getUserId));
        List<UserProductVo> userProducts = new ArrayList<>();
        for (Map.Entry<String, List<ProductVo>> m : orderItemMap.entrySet()) {
            List<ProductVo> products = m.getValue();

            UserProductVo userProductVo = new UserProductVo();
            userProductVo.setUserId(products.get(0).getUserId());
            userProductVo.setOpenId(products.get(0).getOpenId());
            userProductVo.setNickName(products.get(0).getNickName());
            userProductVo.setPhotoUrl(products.get(0).getPhotoUrl());
            userProductVo.setProducts(products);
            userProducts.add(userProductVo);
        }

        queryCollageOrderResponseVo = JSONObject.parseObject(JSONObject.toJSONString(queryOrderResponseVo), QueryCollageOrderResponseVo.class);
        queryCollageOrderResponseVo.setUserProducts(userProducts);

        return ResponseUtil.success(queryCollageOrderResponseVo);

    }

    @Override
    public BaseResponse queryOrderRider(OrderRiderRequestVo requestVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(requestVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(requestVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        baseQueryOrderRequest.setWithOperationHistory(1);
        QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        QueryOrdersResponse.DataBean.OrderBean orderBean = response.getData();
        if (orderBean == null || orderBean.getAddInfo() == null || StringUtils.isEmpty(orderBean.getAddInfo().getDeliveryId()) || "0".equals(orderBean.getAddInfo().getDeliveryId())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_NOT_EXIST);
        }
        QueryDeliveryBaseRequest queryDeliveryBaseRequest = new QueryDeliveryBaseRequest();
        queryDeliveryBaseRequest.setDeliveryId(orderBean.getAddInfo().getDeliveryId());
        queryDeliveryBaseRequest.setOpenDistance(1);
        DeliveryBaseResponse<DeliveryStatusAndRiderPositionDto> deliveryBaseResponse = deliveryFeiginClient.getDeliveryStatusAndRiderPosition(queryDeliveryBaseRequest);
        if (RESPONSE_SUCCESS_CODE != deliveryBaseResponse.getCode() || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.DELIVERY_QUERY_RIDER_ERROR);
        }
        OrderRiderResponseVo responseVo = new OrderRiderResponseVo();
        List<OrderRiderResponseVo.Operation> operationList = new ArrayList<>();
        orderBean.getOrderOperationHistoryList().stream().forEach(operationHistory -> {
            OrderRiderResponseVo.Operation operation = new OrderRiderResponseVo.Operation();
            operation.setCreateTime(DateTimeUtil.timeStampToTime(operationHistory.getCreateTime()));
            operation.setOperationDesc(operationHistory.getOperationDesc());
            operation.setOperationMethod(operationHistory.getOperationMethod());
            operation.setOperator(operationHistory.getOperator());
            operationList.add(operation);
        });
        responseVo.setOperationList(operationList);
        responseVo.setOrderId(orderBean.getOid());
        responseVo.setOrderStatus(orderBean.getStatus());
        responseVo.setStorePhone(deliveryBaseResponse.getData().getStorePhone());
        responseVo.setRiderName(deliveryBaseResponse.getData().getRiderName());
        responseVo.setRiderPhone(deliveryBaseResponse.getData().getRiderPhone());
//        responseVo.setExpressType(orderBean.getExpressType());

        if (orderBean.getAddInfo() != null && orderBean.getAddInfo().getDeliveryType() != null && QueryDeliveryType.THIRD.getCode().equals(orderBean.getAddInfo().getDeliveryType())
                && (DeliveryStatus.DELIVERYERROR.getCode() == orderBean.getAddInfo().getDeliverStatus() || DeliveryStatus.DELIVERYCANCEL.getCode() == orderBean.getAddInfo().getDeliverStatus())
        ) {
            responseVo.setDeliveryType(QueryDeliveryType.SELF.getCode());
        } else {
            responseVo.setDeliveryType(orderBean.getAddInfo() == null ? "" : orderBean.getAddInfo().getDeliveryType());
        }


        if (deliveryBaseResponse.getData().getCurrentPoint() != null) {
            String[] currentPoint = deliveryBaseResponse.getData().getCurrentPoint().split(",");
            responseVo.setRiderLongitude(currentPoint[0]);
            responseVo.setRiderLatitude(currentPoint[1]);
        }
        if (deliveryBaseResponse.getData().getStorePoint() != null) {
            String[] storePoint = deliveryBaseResponse.getData().getStorePoint().split(",");
            responseVo.setShopLongitude(storePoint[0]);
            responseVo.setShopLatitude(storePoint[1]);
        }
        //用户经纬度,改为从配送返回信息获取
        if (deliveryBaseResponse.getData().getDestPoint() != null) {
            String[] destPoint = deliveryBaseResponse.getData().getDestPoint().split(",");
            responseVo.setDestLongitude(destPoint[0]);
            responseVo.setDestLatitude(destPoint[1]);
        }
        responseVo.setDistance(deliveryBaseResponse.getData().getDistance());
        responseVo.setDuration(deliveryBaseResponse.getData().getDuration());
        responseVo.setStoreDistance(deliveryBaseResponse.getData().getStoreDistance());
        responseVo.setStoreDuration(deliveryBaseResponse.getData().getStoreDuration());

        responseVo.setDeliveryId(deliveryBaseResponse.getData().getDeliveryId());
        responseVo.setDevlieryStatus(deliveryBaseResponse.getData().getDevlieryStatus());
        return ResponseUtil.success(responseVo);
    }

    @Override
    public BaseResponse timeOutOrderRefund(TimeOutOrderVo timeOutOrderVo) {
        Map<String, QueryOrdersResponseDto.DataBean.OrderBean> orderBeans = this.getOrderBeanByOrderId(timeOutOrderVo.getOid());
        if (MapUtils.isEmpty(orderBeans)) {
            ResponseUtil.error("404", "订单不存在");
        }
        QueryOrdersResponseDto.DataBean.OrderBean orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());

        if (OrderStatus.CALCEL.getCode().equals(orderBean.getStatus())) {
            this.timeOutRefund(orderBean);
        }
        return ResponseUtil.success();
    }

    private String getRedpacketsPicture(String activityId) {
        if (StringUtils.isNotBlank(activityId)) {
            try {
                ActivityGetByIdResponseDto activityGetByIdResponseDto = promotionActivityClient.getById(Long.valueOf(activityId));
                if (Objects.equals(activityGetByIdResponseDto.getCode(), ResponseResult.SUCCESS.getCode())
                        && activityGetByIdResponseDto.getResult() != null) {
                    return activityGetByIdResponseDto.getResult().getShareConfig().getRedpacketsPicture();
                }
            } catch (Exception e) {
                ErrorLog.errorConvertJson(OrderServiceImpl.class, "getRedpacketsPicture", e);
            }
        }
        return null;
    }

    //参与支付有礼活动
    private void joinPayGift(String sessionId, QueryOrderResponseVo queryOrderResponseVo, String partnerId, Integer payGiftVer) {
        PayGitCheckAndJoinRequestDto payGitRequestDto = new PayGitCheckAndJoinRequestDto();
        payGitRequestDto.setStoreId(queryOrderResponseVo.getShopId());
        payGitRequestDto.setSessionId(sessionId);
        payGitRequestDto.setOid(queryOrderResponseVo.getOid());
        payGitRequestDto.setPayAmount(queryOrderResponseVo.getAmount());

        // 通知支付有礼发放奖励：区分是否是储值卡支付
        if (OrderAdapter.isPayOfSVC(queryOrderResponseVo.getPayChannel())) {
            payGitRequestDto.setPayType(2);
        } else {
            payGitRequestDto.setPayType(1);//1-微信,2-储值卡
        }
        if (CollectionUtils.isNotEmpty(queryOrderResponseVo.getProducts())) {
            // add by miaohui for 20210325_华莱士紧急上线需求支付有礼须支持套餐内固定可选商品_miaohui start
            List<String> skuIds = queryOrderResponseVo.getProducts().stream().map(p -> p.getPid()).collect(Collectors.toList());
            if (hlsPartnerId != null && hlsPartnerId.contains(partnerId)) {
                // 华莱士获取支付有理促销数据时须将套餐商品内固定搭配、可选搭配商品的skuId一同传入
                queryOrderResponseVo.getProducts().forEach(productVo -> {
                    if (CollectionUtils.isNotEmpty(productVo.getSetMealProducts())) {
                        productVo.getSetMealProducts().forEach(setMealProduct -> {
                            skuIds.add(setMealProduct.getPid());
                        });
                    }
                });

            }
            payGitRequestDto.setSkuIds(skuIds);
            // add by miaohui for 20210325_华莱士紧急上线需求支付有礼须支持套餐内固定可选商品_miaohui end
        }
        if (OrderType.COLLECT_GOODS.getCode().intValue() == queryOrderResponseVo.getOrderType() || OrderType.EAT_IN.getCode().intValue() == queryOrderResponseVo.getOrderType()) {
            payGitRequestDto.setOrderWay(1);
        } else {
            payGitRequestDto.setOrderWay(2);
        }

        payGitRequestDto.setVer(payGiftVer);
        //coco业务默认传值1
        if (cocoPartnerId.contains(partnerId)) {
            payGitRequestDto.setVer(1);
        }

        BaseResponse<PayGiftCheckAndJoinResponseDto> payGiftBaseResponse = activityApplicationClient.payGiftCheckAndJoin(payGitRequestDto);
        if (String.valueOf(RESPONSE_SUCCESS_CODE).equals(payGiftBaseResponse.getCode()) && payGiftBaseResponse.getResult() != null) {
            PayGiftCheckAndJoinResponseDto payGiftResponse = payGiftBaseResponse.getResult();
            //版本前 原参数保留，暂不变更
            //防止牵扯其他服务返回参数结构引起异常
            queryOrderResponseVo.setActivityName(payGiftResponse.getActivityName());
            queryOrderResponseVo.setCoupons(payGiftResponse.getCoupons());
            queryOrderResponseVo.setWechatCouponInfo(payGiftResponse.getWechatCouponInfo());

            //20201223本次变更-》去掉set，直接以对象进行返参
            queryOrderResponseVo.setPayGiftReps(payGiftResponse);
//            queryOrderResponseVo.setActivityNo(payGiftResponse.getActivityNo());
//            queryOrderResponseVo.setSyncWechat(payGiftResponse.getSyncWechat());
//            queryOrderResponseVo.setActivityPicture(payGiftResponse.getActivityPicture());
//            queryOrderResponseVo.setRedirectType(payGiftResponse.getRedirectType());
//            queryOrderResponseVo.setGoodsConfig(payGiftResponse.getGoodsConfig());
//            queryOrderResponseVo.setMicroProgramConfig(payGiftResponse.getMicroProgramConfig());
//            queryOrderResponseVo.setRedirectPage(payGiftResponse.getRedirectPage());
//            queryOrderResponseVo.setActivitySendType(payGiftResponse.getSendType());
        }
    }

    private void orderStatusTracking(QueryOrdersResponse.DataBean.OrderBean 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;
                }
            }
        }
    }

    @Override
    public BaseResponse queryOrderById(Integer operation, String sessionId, String oid, String partnerId, String channel) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String userId = userInfo.getMemberId();
        partnerId = userInfo.getPartnerId();
        if (StringUtils.isBlank(oid)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(oid);
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        // 订单详情要查询3个月前的订单
        // 先实时查询如果没有查询es
        QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);

        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode())) {
            ApiLog.info("订单详情实时查询错误，baseQueryOrderRequest，", baseQueryOrderRequest, "");
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }

        if (response.getData() == null && queryOrderEs) {
            // 查询es
            response = orderCenterSdkService.queryOrderByCodeES(partnerId, oid, LogThreadLocal.getTrackingNo());
            ApiLog.info("订单详情实时查询没有数据,es查询，partnerId，oid", partnerId, oid);
        }

        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        QueryOrdersResponse.DataBean.OrderBean orderBean = response.getData();
        String storeId = orderBean.getShopId();
        StoreInfoRequest request = new StoreInfoRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeId);
        StoreResponse storeInfo = storeCenterService.getStoreInfo(request, LogTreadLocal.getTrackingNo());
        String organizationId = "";
        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()));
            organizationId = storeResponseDto.getParentCode();
        }
        //TODO 查询订单的排队人数
        orderBean.setQueueIndex("");

        BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
        var1.setOrderId(orderBean.getOid());
        var1.setTrackingNo(LogTreadLocal.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);
        //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小时内未成功退款，请联系商家人工处理");
            }
        }

        /*if (IappIdType.WC_XCX.getCode().equals(userInfo.getIappId())) {
            if(CollectionUtils.isNotEmpty(queryOrderResponseVo.getProducts()) ) {
                queryOrderResponseVo.getProducts().stream().forEach(each -> {
                    orderBean.getProductList().forEach(var -> {
                        if (var.getId() == each.getId()) {
                            each.setSaleTotalAmount(var.getSettlementPrice());
                            each.setOriginalTotalAmount(var.getSettlementPrice());
                        }
                    });

                });
            }
        }*/

        // 判断是否有裂变活动 订单扩展信息判断必须有wxappid
        String extInfo = response.getData().getExtInfo();
        if (StringUtils.isNotBlank(extInfo)) {
            OrderExtInfoDto orderExtInfoDto = gson.fromJson(extInfo, OrderExtInfoDto.class);
            String wxappid = orderExtInfoDto.getAppid();
            // 查询门店下有没有 裂变活动
            String activityId = isShareActivity(partnerId, storeId, wxappid, response.getData().getGmtCreate(), oid, userId, sessionId, organizationId);
            queryOrderResponseVo.setActivityId(activityId);
            // 取红包图片
            queryOrderResponseVo.setRedpacketsPicture(getRedpacketsPicture(activityId));
        }


        // 支付有礼
        // 目前只有coco在订单详情参加支付有礼，且不检查订单的状态
        if (cocoPartnerId.contains(partnerId)) {
            joinPayGift(sessionId, queryOrderResponseVo, partnerId, null);
        }

        //拼团订单
        if(OrderMarketType.GROUPB.getIndex() == queryOrderResponseVo.getMarketingType() && StringUtils.isNotEmpty(queryOrderResponseVo.getSpellGroupCode())
        && orderBean.getApportionDetails()!=null){
            QueryHistoryGroupVO querySpellGroupVo = spellGroupOrderDataManager.queryHistoryByGroupId(queryOrderResponseVo.getSpellGroupCode(),partnerId,orderBean.getUserId());
            queryOrderResponseVo.setSpellGroup(querySpellGroupVo);
        }
        buildQueryOrderResponseVo(queryOrderResponseVo, response, partnerId);

        return ResponseUtil.success(queryOrderResponseVo);
    }

    /**
     * 如果有第三方配送，返回值添加第三方配送信息
     */
//    private void hasThirdDelivery(QueryOrdersResponse.DataBean.OrderBean orderBean) {
//        String deliveryId = orderBean.getAddInfo().getDeliveryId();
//        if ("0".equals(deliveryId)) {
//            return;
//        }
//        String trackingNo = LogTreadLocal.getTrackingNo();
//        DeliveryResponseDto<DeliveryInfoDto> delivery = deliveryService.deliveryOrderOne(deliveryId, trackingNo);
//        if (RESPONSE_SUCCESS_CODE == delivery.getCode() && delivery.getData() != null) {
//            DeliveryInfoDto result = delivery.getData();
//            orderBean.setDeliverStatus(result.getDeliveryStatus());
//            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());
//        }
//        if (orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getRiderPhone())) {
//            orderBean.setRiderPhone(orderBean.getAddInfo().getRiderPhone());
//        }
//    }

    /**
     * 如果有第三方配送，返回值添加第三方配送信息
     */
    private void hasThirdDelivery(QueryOrdersResponse.DataBean.OrderBean orderBean) {
        String deliveryId = orderBean.getAddInfo().getDeliveryId();
        if ("0".equals(deliveryId)) {
            return;
        }
//        String trackingNo = LogTreadLocal.getTrackingNo();
        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]);
                }
            }
        }

    }

    /**
     * 查询门店下有没有 裂变活动
     *
     * @param partnerId
     * @param storeId
     * @param wxappid
     * @param orderTime
     * @return
     */
    private String isShareActivity(String partnerId, String storeId, String wxappid, Long orderTime, String bizId, String userId, String sessionId, String organizationId) {

        QueryValidShareActivityReq activityReq = new QueryValidShareActivityReq();
        activityReq.setAppId(wxappid);
        activityReq.setPartnerId(partnerId);
        activityReq.setStoreId(storeId);
        activityReq.setOrderId(bizId);
        if (StringUtils.isNotBlank(organizationId)) {
            activityReq.setOrgIds(Arrays.asList(organizationId));
        }
        String activityId = Optional.ofNullable(promotionActivityClient.queryValidShareActivity(activityReq)).map(BaseResponse::getResult).map(Object::toString).orElse("");

        String nickName = Optional.ofNullable(customerInfoManager.getCustomerInfoByObject(sessionId)).map(AssortmentCustomerInfoVo::getNickName).orElse("");
        if (StringUtils.isNotBlank(activityId)) {
            // 添加分享记录 每笔订单只能添加一笔分享记录
            ShareAcitivityRequestDto shareAcitivityRequestDto = couponAdapter.convert2ShareAcitivityRequestDto(activityId, bizId, partnerId, userId, nickName);
            BaseResponse shareResponse = promotionActivityClient.shareRecord(shareAcitivityRequestDto);
            if (Objects.equals(shareResponse.getCode(), ResponseResult.SUCCESS.getCode())) {
                return activityId;
            }
        }
        return null;
    }



    @Override
    public BaseResponse deleteOrder(DeleteOrderVo deleteOrderVo) {
        if (StringUtils.isBlank(deleteOrderVo.getOid())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(deleteOrderVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryOrderByIdResponseDto responseDto = jsonObject.toJavaObject(QueryOrderByIdResponseDto.class);
        if (!RESPONSE_SUCCESS_CODE.equals(responseDto.getErrcode()) || responseDto.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBean orderBean = responseDto.getData();
        if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许删除");
        }
        if (!OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许删除");
        }
//        DeleteOrderDto deleteOrderDto = orderAdapter.convent2DeleteOrderDto(deleteOrderVo.getOid());
//
//        DeleteOrderRequest var1 = new DeleteOrderRequest();
//        var1.setOrderId(deleteOrderDto.getOrderId());
//        var1.setOrderSdkType(getDefaultOrderSdkType(deleteOrderVo.getPartnerId()));
//        var1.setTrackingNo(LogTreadLocal.getTrackingNo());
//        BaseOrderResponse baseOrderResponse = orderCenterSdkService.deleteOrder(var1);
//
//        if (!RESPONSE_SUCCESS_CODE.equals(baseOrderResponse.getErrcode())) {
////            log.error("deleteOrder is error , deleteOrderDto :{}", deleteOrderDto);
//            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR);
//        }
        // TODO: 2019/9/10 删除订单通知
        backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
        //取消支付时，清理key.此处不做校验是否限制次数的单子，卖券订单直接清理
        if(Objects.equals(BizTypeEnum.APP_COUPON.getBizType(),orderBean.getBizType())){
            buyProductOnceManager.removeCheckBuyProductOnceKey(orderBean.getCompanyId(),orderBean.getUserId(),orderBean.getProductList().get(0).getProductId());
        }
        return ResponseUtil.success();
    }

    @Override
    public BaseResponse cancelPayOrder(DeleteOrderVo deleteOrderVo) {
        if (StringUtils.isBlank(deleteOrderVo.getOid())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(deleteOrderVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryOrderByIdResponseDto responseDto = jsonObject.toJavaObject(QueryOrderByIdResponseDto.class);
        if (!RESPONSE_SUCCESS_CODE.equals(responseDto.getErrcode()) || responseDto.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBean orderBean = responseDto.getData();
        if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许取消");
        }
        if (!OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许取消");
        }
        this.closeHistoryPrePay(orderBean);
        CancelOrderRequest var1 = new CancelOrderRequest();
        var1.setOrderId(deleteOrderVo.getOid());
        var1.setPartnerId(deleteOrderVo.getPartnerId());
        var1.setAfterSalesType(AfterSalesType.SYSTEM_CANCEL);
        var1.setReason(null);
        var1.setTrackingNo(LogTreadLocal.getTrackingNo());
        var1.setRefundSerialNo(null);
        var1.setReqRemark("未支付取消");
        var1.setOperator("admin");
        //若为4，默认做【创建】+【同意并退款完成】，售后单状态为【完成】
        var1.setCreateEvent(4);
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderCancel(var1);
        if (!RESPONSE_SUCCESS_CODE.equals(baseOrderResponse.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER_CANCEL_ERROR.getCode(), baseOrderResponse.getErrmsg());
        }
        // TODO: 2019/9/10 删除订单通知
        backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
        //取消支付时，清理key.此处不做校验是否限制次数的单子，卖券订单直接清理
        if(Objects.equals(BizTypeEnum.APP_COUPON.getBizType(),orderBean.getBizType())){
            buyProductOnceManager.removeCheckBuyProductOnceKey(orderBean.getCompanyId(),orderBean.getUserId(),orderBean.getProductList().get(0).getProductId());
        }
        return ResponseUtil.success();
    }

    @Override
    public BaseResponse deleteOrderById(DeleteOrderVo deleteOrderVo) {
        if (StringUtils.isBlank(deleteOrderVo.getOid())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "oid不能为空");
        }
        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(deleteOrderVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryOrderByIdResponseDto responseDto = jsonObject.toJavaObject(QueryOrderByIdResponseDto.class);
        if (!RESPONSE_SUCCESS_CODE.equals(responseDto.getErrcode()) || responseDto.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBean orderBean = responseDto.getData();
        if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许删除");
        }
        if (!OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR.getCode(), "订单状态不允许删除");
        }
        DeleteOrderDto deleteOrderDto = orderAdapter.convent2DeleteOrderDto(deleteOrderVo.getOid());
        //
        DeleteOrderRequest var1 = new DeleteOrderRequest();
        var1.setOrderId(deleteOrderDto.getOrderId());
        var1.setTrackingNo(LogTreadLocal.getTrackingNo());
        var1.setOperator("未支付取消");
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.deleteOrder(var1);

        if (!RESPONSE_SUCCESS_CODE.equals(baseOrderResponse.getErrcode())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELETE_ERROR);
        }
        // TODO: 2019/9/10 删除订单通知
        backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
        return ResponseUtil.success();
    }

    @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(LogTreadLocal.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(), "不能操作非本人的订单");
        }
        OrderBean 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 (com.freemud.sdk.api.assortment.order.enums.OrderSourceType.SAASMALL.getCode().equalsIgnoreCase(orderBean.getSource())){
            // 微商城因为没有退款原因选项 所以将用户退款说明用户作为退款原因
            orderRefundVo.setReason(orderRefundVo.getRemarks());
            // 必须选择退款方式
            if(Objects.isNull(orderRefundVo.getRefundMode()) || RefundModeEnum.getByIndex(orderRefundVo.getRefundMode()) == null){
                return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "请选择退款方式");
            }
            // 完成/配送中 可以选择退货退款
            List<Integer> refundGoodsCodes = Arrays.asList(
                    OrderStatus.DISTRIBUTION.getCode(), OrderStatus.COMPLETE.getCode());
            if(!refundGoodsCodes.contains(orderBean.getStatus())&& !Objects.equals(RefundModeEnum.UN_REFUND_GOODS.getIndex(), orderRefundVo.getRefundMode())){
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "还未发货，请选择只退款不退货");
            }
            // 拼团类型
            if (Objects.equals(OrderMarketType.GROUPB.getIndex(), orderBean.getMarketingType())
                    && (StringUtils.isBlank(orderBean.getSpellGroupCode()) || StringUtils.isBlank(orderBean.getSpellGroupActivityCode()))) {
                return ResponseUtil.error(ResponseResult.SPELL_GROUP_QUERY_GROUP_WORK_ERROR);
            }
        }
        // todo 这里直接拒绝?
        else if (OrderStatus.DISTRIBUTION.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "订单配送中，退款请联系售后！");
        }

        // todo coco 商户校验
        if (cocoPartnerId.contains(orderByIdResponseDto.getData().getCompanyId())) {
            // COCO 即时单不可取消
            if (NewOrderType.GENERAL_SELF_PICKUP.getCode().equals(queryOrderByIdResponse.getData().getNewOrderType())) {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND);
            }
            // 4,6 预约单
            List<Integer> expectOrderType = Lists.newArrayList(
                    NewOrderType.RESERVED_EXPRESS.getCode(),
                    NewOrderType.RESERVED_SELF_PICKUP.getCode());
            long time = DateUtil.addMinutes(new Date(), 15).getTime();

            // 外卖单
            List<Integer> takeOrderType = Lists.newArrayList(
                    NewOrderType.RESERVED_EXPRESS.getCode(),
                    NewOrderType.GENERAL_EXPRESS.getCode());
            long taskCancelOrderTime = DateUtil.addMinutes(new Date(), 30).getTime();
            if (takeOrderType.contains(queryOrderByIdResponse.getData().getNewOrderType())
                    && Objects.nonNull(queryOrderByIdResponse.getData().getEstimateDeliveryCompleteTime())
                    && taskCancelOrderTime > queryOrderByIdResponse.getData().getEstimateDeliveryCompleteTime()) {
                return ResponseUtil.error(ResponseResult.ORDER_CANCEL_ERROR_ESTIMATE_TIME);
            }
            if (expectOrderType.contains(queryOrderByIdResponse.getData().getNewOrderType())) {
                if (Objects.nonNull(orderBean.getGmtExpect())
                        && time > orderBean.getGmtExpect()) {
                    return ResponseUtil.error(ResponseResult.ORDER_CANCEL_ERROR_EXPECT_TIME);
                }
                // todo coco 预约单直接退款
                BaseResponse baseResponse = partnerNoTakeOrder(orderRefundVo, orderBean, orderId, AfterSalesType.USER_CANCEL, true);
                if (baseResponse != null) {
                    return baseResponse;
                }
                // 删除订单 通知活动添加商品库存
                backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus(), orderBean.getPayStatus());
                return ResponseUtil.success();
            }

        }
        /**
         * 已接单，制作完成，配送中,未接单，用户可申请退款
         *
         * v1.9.3.1 支持已完成订单可申请退款(通过b端后台控制)
         */
        List<Integer> enableRefundCodes = Lists.newArrayList(Arrays.asList(
                OrderStatus.RECEIPT.getCode(), OrderStatus.COMPLETE_MAKE.getCode(), OrderStatus.DISTRIBUTION.getCode(), OrderStatus.TAKE_ORDER.getCode(), OrderStatus.COMPLETE.getCode()
        ));
        if (enableRefundCodes.contains(orderBean.getStatus()) && PayStatus.HAVE_PAID.getCode().equals(orderBean.getPayStatus())) {
            if (CollectionUtils.isNotEmpty(orderBean.getRefundList())) {
                OrderBean.RefundBean refundBean = orderBean.getRefundList().get(0);
                if (RefundStatus.APPLY_REFUND.getCode().equals(refundBean.getStatus())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "商家正在处理中，请稍后……");
                }
                //商城订单可二次发起退款
                if (!com.freemud.sdk.api.assortment.order.enums.OrderSourceType.SAASMALL.getCode().equalsIgnoreCase(orderBean.getSource())  && RefundStatus.REFUSE_REFUND.getCode().equals(refundBean.getStatus())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "您的申请已被商家拒绝，请联系门店沟通。");
                }
            }
            // 【优化】【小程序】顾客申请退款提交时，判断当前的订单状态，是否允许申请退款
            //if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
            boolean refundButton = orderAdapter.checkRefundButton(queryOrderByIdResponse.getData(), userInfo.getWxAppId());
            if (!refundButton) {
                return ResponseUtil.error(ResponseResult.ORDER_NOT_ALLOW_REFUND.getCode(), ResponseResult.ORDER_NOT_ALLOW_REFUND.getMessage());
            }

            //}
            List<AssortmentOpenPlatformPartnerWxappConfig> partnerWxappConfigs = cacheOpenPlatformPartnerWxappConfigManager.cacheSelectDefaultPage(userInfo.getWxAppId(), "2");

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

            boolean isRefundDeliveryFee = true;
            //商城查询配送费
            if (com.freemud.sdk.api.assortment.order.enums.OrderSourceType.SAASMALL.getCode().equalsIgnoreCase(orderBean.getSource()) && StringUtils.isNotEmpty(orderBean.getExtInfo())){
                JSONObject extInfoJsonObject = JSONObject.parseObject(orderBean.getExtInfo());
                OrderExtInfoDto orderExtInfoDto = extInfoJsonObject.toJavaObject(OrderExtInfoDto.class);
                if(null != orderExtInfoDto && null !=  orderExtInfoDto.getProvince()){
                    String province = orderExtInfoDto.getProvince();
                    QueryFreightRefundSupportedVo queryFreightRefundSupportedVo = new QueryFreightRefundSupportedVo();
                    queryFreightRefundSupportedVo.setPartnerId(orderBean.getCompanyId());
                    queryFreightRefundSupportedVo.setProvince(province);
                    //整合商城订单状态，订单状态 1 2 3不需校验直接退运费 20210513
                    List<Integer> isRefundDeliveryFeeCodes = Arrays.asList(
                            OrderStatus.TAKE_ORDER.getCode(), OrderStatus.WAIT_PAY.getCode(), OrderStatus.RECEIPT.getCode());
                    if(isRefundDeliveryFeeCodes.contains(orderBean.getStatus())){
                        isRefundDeliveryFee = true;
                    }else{
                        QueryFreightRefundSupportedResponse queryFreightRefundSupportedResponse = deliveryFeiginClient.isFreightRefundSupported(queryFreightRefundSupportedVo);
                        LogUtil.info("queryFreightRefundSupportedResponse of oid:{}, {}, {}", orderBean.getOid(), orderBean.getStatus(), (null != queryFreightRefundSupportedResponse ? ToStringBuilder.reflectionToString(queryFreightRefundSupportedResponse) : null));
                        if(null != queryFreightRefundSupportedResponse &&  RESPONSE_SUCCESS_CODE == queryFreightRefundSupportedResponse.getCode()){
                            Boolean freightRefundSupported = queryFreightRefundSupportedResponse.getData();
                            isRefundDeliveryFee = freightRefundSupported;
                        }
                    }
                }
            }else {
                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(), OrderStatus.COMPLETE.getCode()).contains(orderBean.getStatus())
                        && !ALLOW_REFUND.equals(refundDeliveryFeeConfig.getAppValue())) {
                    isRefundDeliveryFee = false;
                }
            }

            // 未接单
            if (OrderStatus.TAKE_ORDER.getCode().equals(orderBean.getStatus())) {
                // 拼团订单主动退款触发通知促销
                if (Objects.equals(com.freemud.sdk.api.assortment.order.enums.OrderSourceType.SAASMALL.getCode(), orderBean.getSource())
                        && Objects.equals(OrderMarketType.GROUPB.getIndex(), orderBean.getMarketingType())) {
                    GroupWorkRefundResponse refundResponse = activityHandle.groupWorkRefund(queryOrderByIdResponse.getData());
                    if (Objects.isNull(refundResponse) || !Objects.equals(ResponseConstant.SUCCESS_RESPONSE_CODE, refundResponse.getStatusCode())) {
                        return ResponseUtil.error(ResponseResult.SPELL_GROUP_REFUND_ERROR);
                    }
                }
                //商家未接单逻辑处理    1.调用支付退款 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
                BaseResponse baseResponse = partnerNoTakeOrder(orderRefundVo, orderBean, orderId, AfterSalesType.USER_CANCEL, isRefundDeliveryFee);
                if (baseResponse != null) {
                    return baseResponse;
                }
                // 删除订单 通知活动添加商品库存
                backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus(), orderBean.getPayStatus());
            } else {
                CancelOrderRequest cancelOrderRequest = new CancelOrderRequest();
                cancelOrderRequest.setPartnerId(orderBean.getCompanyId());
                cancelOrderRequest.setStoreId(orderBean.getShopId());
                cancelOrderRequest.setOrderId(orderBean.getOid());
                cancelOrderRequest.setOrderClient(orderAdapter.getNewOrderClient(orderBean.getSource()));

                //传入的售后单类型为：2：售中用户取消 8：售后申请
                cancelOrderRequest.setAfterSalesType(AfterSalesType.USER_CANCEL);
                if (OldOrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
                    cancelOrderRequest.setAfterSalesType(AfterSalesType.USER_SALE_RETURN);
                }
                cancelOrderRequest.setReason(orderRefundVo.getReason());
                cancelOrderRequest.setReqRemark(orderRefundVo.getRemarks());
                // 商城订单 增加拓展信息
                CancelOrderRequest.AfterSalesOrderExtInfoReq salesOrderExtInfoReq = new CancelOrderRequest.AfterSalesOrderExtInfoReq();
                salesOrderExtInfoReq.setRefundMode(orderRefundVo.getRefundMode());
                cancelOrderRequest.setExtInfoReq(salesOrderExtInfoReq);

                cancelOrderRequest.setOperator(orderBean.getUserName());
                cancelOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
                cancelOrderRequest.setRefundDeliveryAmount(isRefundDeliveryFee);
                BaseOrderResponse baseResponseDto = orderCenterSdkService.orderCancel(cancelOrderRequest);

                if (!RESPONSE_SUCCESS_CODE.equals(baseResponseDto.getErrcode())) {
                    return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), baseResponseDto.getErrmsg());
                }
                if (orderBean.getAmount() > 0) {
                    sendPosMessage(partnerId, orderBean.getShopId());
                }
                //通知小助手发送申请退款公众号订阅消息
                sendApplyRefundSubscriptionNotice(orderBean, orderRefundVo);
                //已接单可发起退款申请，查询门店有无云打印机，有则打印退款申请小票
                printApplyRefundSmallTicket(orderBean, orderRefundVo);
            }
        }
        return ResponseUtil.success();
    }


    /**
     * 商家未接单,取消订单逻辑处理    1.调用支付退款 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
     *
     * @param orderRefundVo
     * @param orderBean
     */
    @SneakyThrows
    private BaseResponse partnerNoTakeOrder(OrderRefundVo orderRefundVo, OrderBean 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) {
            if (null != orderBean.getOrderPayItem() && orderBean.getOrderPayItem().size() > 0) {
                //调用支付退款
                MultiOrderRefundRequest multiOrderRefundRequest = orderAdapter.getMultiOrderPayRefundRequest(orderBean, refundId);
                MultiOrderRefundResponse multiOrderRefundResponse = mulitiPaymentClient.paymentApplicationRefund(multiOrderRefundRequest, orderBean.getCompanyId());
                if (multiOrderRefundResponse == null || multiOrderRefundResponse.getData() == null || !com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant.ORDER_PAY_RESPONSE_SUCCESS.equals(multiOrderRefundResponse.getCode())) {
                    return ResponseUtil.error(ResponseResult.MULTIORDER__ERRORREFUND.getCode(), "multiOrderRefund_failed");
                }
                List<MultiOrderRefundResponse.RefundPlatformResponse> refundPlatformResponseList = multiOrderRefundResponse.getData().refundPlatformResponseList;
                if (null != refundPlatformResponseList && refundPlatformResponseList.size() > 0) {
                    redisCache.save(RedisUtil.getPaymentTransIdSequenceKey(refundPlatformResponseList.get(0).getTransId()), orderBean.getOid(), 1L, TimeUnit.DAYS);
                }
                //获取支付返回退款状态
                state = PayRefundStatus.SUCCESS.getCode();
            } else {
                //调用支付退款
                com.freemud.sdk.api.assortment.payment.request.OrderRefundRequest orderPayRefundRequest = orderAdapter.getOrderPayRefundRequest(orderBean, refundId, fatherOrderId);
                response = standardPaymentService.orderRefund(orderPayRefundRequest, LogTreadLocal.getTrackingNo());
                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(), LogTreadLocal.getTrackingNo(), refundId.toString());
        cancelOrderRequest.setOperator(orderBean.getUserName());
        cancelOrderRequest.setPartnerId(orderBean.getCompanyId());
        if (Objects.equals(PayRefundStatus.RUNNING.getCode(), state)) {
            // 退款中
            cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.RETURN_COMPLETE.getCreateEvent());
        } else if (Objects.equals(PayRefundStatus.SUCCESS.getCode(), state)) {
            //退款成功
            cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.REFUND_COMPLETE.getCreateEvent());
        }
        cancelOrderRequest.setReqRemark(orderRefundVo.getRemarks());
        cancelOrderRequest.setRefundDeliveryAmount(isRefundDeliveryFee);
        // 商城订单 增加拓展信息
        CancelOrderRequest.AfterSalesOrderExtInfoReq salesOrderExtInfoReq = new CancelOrderRequest.AfterSalesOrderExtInfoReq();
        salesOrderExtInfoReq.setRefundMode(orderRefundVo.getRefundMode());
        cancelOrderRequest.setExtInfoReq(salesOrderExtInfoReq);

        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;
    }

//    public void backOrdersNotifyActivity(OrderBean orderBean, List<Integer> transType) {
//        LogUtil.info("backOrdersNotifyActivity", gson.toJson(orderBean), gson.toJson(transType));
//        if (orderBean == null) {
//            return;
//        }
//        // 删除订单 通知活动添加商品库存
//        ActivityCancelStockRequestDto activityCancelStockRequestDto = activityAdapter.convert2ActivityCancelStockRequestDto(
//                orderBean, transType);
//        try {
//            Header header = new Header(MQAction.INSERT.getAction(), "backOrdersNotifyActivity", orderBean.getOid(), backOrdersChangeOrderStatusConsumerQueue);
//            MQMessage<ActivityCancelStockRequestDto> message = new MQMessage<>(header, activityCancelStockRequestDto);
//            mqService.convertAndSend(backOrdersNotifyActivityExchange, backOrdersChangeOrderStatusConsumerQueue, message);
//        } catch (Exception e) {
//            LogUtil.error("ActivityReverse", JSON.toJSONString(activityCancelStockRequestDto), "", e);
//        }
//    }


    public void backOrdersStatusChange(String oid, Integer orderStatus) {
        if (StringUtils.isEmpty(oid)) {
            return;
        }
        ApiLog.info("backOrdersStatusChange", 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) {
            LogUtil.error("ActivityReverse", JSON.toJSONString(requestDto), "", e);
        }
    }

    public void backOrdersStatusChange(String oid, Integer orderStatus, Integer payStatus) {
        if (StringUtils.isEmpty(oid)) {
            return;
        }
        ApiLog.info("backOrdersStatusChange", oid, String.valueOf(orderStatus));
        OrderStatusChangeRequestDto requestDto = new OrderStatusChangeRequestDto();
        requestDto.setOid(oid);
        requestDto.setPayStatus(payStatus);
        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) {
            LogUtil.error("ActivityReverse", JSON.toJSONString(requestDto), "", e);
        }
    }

    /**
     * 发MQ去打印
     *
     * @param request
     */
    public void asynchronousPrint(OrderPrintDto request) {
        LogUtil.debug("OrderPrintDto", JSONObject.toJSONString(request), null);
        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);
    }

    @Override
    public BaseResponse queryOrderQueueIndex(QueryOrderQueueIndexVo queryOrderQueueIndexVo) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(queryOrderQueueIndexVo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        try {
            BaseQueryOrderRequest var1 = new BaseQueryOrderRequest();
            var1.setOrderId(queryOrderQueueIndexVo.getOid());
            var1.setTrackingNo(LogTreadLocal.getTrackingNo());
            BaseOrderResponse response = orderCenterSdkService.queryOrderQueueIndex(var1);

            if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode())) {
                return ResponseUtil.error(ResponseResult.NOT_LOGIN);
            }
            Map<String, String> queueIndexMap = Maps.newTreeMap();
            queueIndexMap.put("oid", queryOrderQueueIndexVo.getOid());
            queueIndexMap.put("queueIndex", response.getData() == null ? "" : response.getData().toString());
            return ResponseUtil.success(queueIndexMap);
        } catch (Exception e) {
            return ResponseUtil.error(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
    }

    @Override
    public BaseResponse getRefundReason(GetRefundReasonVo getRefundReasonVo) {
        AssortmentCustomerInfoVo customerInfoByObject = customerInfoManager.getCustomerInfoByObject(getRefundReasonVo.getSessionId());
        if (customerInfoByObject != null && customerInfoByObject.getMemberId() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        List<RefundReasonResponseVo> refundReasonResponseVos = getRefundReasonResponseVos(getRefundReasonVo);
        return ResponseUtil.success(refundReasonResponseVos);
    }

    @Override
    public BaseResponse getNewRefundReason(GetRefundReasonVo getRefundReasonVo) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(getRefundReasonVo.getSessionId());
        if (userInfo != null && userInfo.getMemberId() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        String oid = getRefundReasonVo.getOid();
        if (StringUtils.isEmpty(oid)) {
            throw new ServiceException(ResponseResult.ORDER_CODE_EMPTY);
        }
        GetRefundResonResponseVo result = new GetRefundResonResponseVo();
        List<RefundReasonResponseVo> refundReasonResponseVos = getRefundReasonResponseVos(getRefundReasonVo);
        result.setRefundReasons(refundReasonResponseVos);
        assert userInfo != null;
        String refundDocument = buildRefundDocument(oid);
        result.setRefundDocument(refundDocument);
        return ResponseUtil.success(result);
    }

    @Override
    public BaseResponse createIntegralOrder(IntegralOrderVo vo) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(vo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        ParkingOrderCreateReq req = new ParkingOrderCreateReq();
        req.setBizType(vo.getBizType());
        req.setUserId(userInfo.getMemberId());
        req.setUserName(userInfo.getNickName());
        req.setPartnerId(vo.getPartnerId());
        req.setImgUlr(vo.getImgUrl());
        req.setMobile(userInfo.getMobile());
        req.setOperator(userInfo.getNickName());
        //积分订单为4
        req.setOrderType((byte) 4);
        com.freemud.application.sdk.api.ordercenter.response.BaseResponse<OrderResp> result = orderSdkService.parking_v2_create(req, LogThreadLocal.getTrackingNo());
        if (Objects.isNull(result)) {
            return new BaseResponse(ResponseResultEnum.SYSTEM_ERROR.getCode(), ResponseResultEnum.SYSTEM_ERROR.getMessage(), "", null);
        }
        if (!ResponseResultEnum.SUCCESS.getCode().equalsIgnoreCase(result.getCode()) || Objects.isNull(result.getResult())) {
            return new BaseResponse(result.getCode(), result.getMessage(), "", null);
        }
        return ResponseUtil.success();
    }

    private String buildRefundDocument(String oid) {
        QueryOrderByIdResponseDto response = getQueryOrderByIdResponseDto(oid);
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            throw new ServiceException(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderBean orderBean = response.getData();
        // TODO: 2019/9/9 再次校验是否可以退款 是否需要
        String document = OrderRefundConstant.COMMON_DOCUMENT;
        if (OrderType.COLLECT_GOODS.getCode().equals(orderBean.getType())) {
            return document;
        }
        if (OrderType.TAKE_OUT.getCode().equals(orderBean.getType())) {
            if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
                document = OrderRefundConstant.TAKE_OUT_COMPLETE_DOCUMENT;
                return document;
            } else {
                document = OrderRefundConstant.TAKE_OUT_NOT_COMPLETE_DOCUMENT;
                return document;
            }
        }
        return document;
    }

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

    /**
     * 构建订单退款原因
     *
     * @param getRefundReasonVo 请求参数
     * @return
     */
    private List<RefundReasonResponseVo> getRefundReasonResponseVos(GetRefundReasonVo getRefundReasonVo) {
        List<RefundReasonResponseVo> refundReasonResponseVos = Lists.newArrayList();
        if (CreateOrderType.TAKE_OUT.getCode().equals(getRefundReasonVo.getOrderType())) {
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Delivery_Time_too_long));
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Misdelivery_Leakage_of_Goods));
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Riders_confirm_service_ahead_of_schedule));
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Other));
        } else {
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Wrong_order));
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Goods_not_match_expectations));
            refundReasonResponseVos.add(getRefundReasonResponseVo(RefundReasonEnum.Other));
        }
        return refundReasonResponseVos;
    }

    /**
     * 发送pos端消息
     */
    public void sendPosMessage(String partnerId, String storeId) {
        PushMessageNoticeDto pushMessageNoticeDto = messageNoticeAdapter.convent2PushMessageNoticeDto(2, partnerId, storeId,
                null, null, null, null);
        messageNoticeClient.createMessage(pushMessageNoticeDto, LogThreadLocal.getTrackingNo());
    }

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

    /**
     * 支付后通知确认返回信息
     */
    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", 500);
        map.put("message", "failed");
        return gson.toJson(map);
    }

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

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

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


    /**
     * 异常状态退款流程
     */
//    public void orderRefund(OrderBean orderBean, String refundReason, String openid, String oid) {
//        String storeId = orderBean.getShopId();
//        String partnerId = orderBean.getCompanyId();
//        OrderRefundVo orderRefundVo = new OrderRefundVo();
//        orderRefundVo.setOid(orderBean.getOid());
//        orderRefundVo.setPartnerId(orderBean.getCompanyId());
//        orderRefundVo.setReason(refundReason);
//        //系统异常取消订单
//        partnerNoTakeOrder(orderRefundVo, orderBean, oid,AfterSalesType.SYSTEM_CANCEL,true);
//        // 发送消息到消息中心推送给pos前端
//        PushMessageNoticeDto pushMessageNoticeDto = messageNoticeAdapter.convent2PushMessageNoticeDto(2, partnerId, storeId,
//                null, null, null, null);
//        String messageNoticeResponse = messageNoticeClient.createMessage(pushMessageNoticeDto, LogThreadLocal.getTrackingNo());
//        // 退单冲正商品库存，冲正商品券，冲正活动库存
//        //backOrdersNotifyActivity(orderBean, Arrays.asList(TransTypeEnum.ACTIVITY.getCode(), TransTypeEnum.COUPON.getCode(), TransTypeEnum.PRODUCT.getCode()));
//        backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
//
//    }

    /**
     * 获取父子订单商品第三方商品编号
     *
     * @param
     * @return
     */
    private CreateFatherSonOrderRequest getProductCustomerCodeNew(CreateFatherSonOrderRequest fatherSonOrderRequest) {
        List<String> pids = new ArrayList<>();
        List<CreateFatherSonOrderRequest.OrderInfo> productOrderInfoList = fatherSonOrderRequest.getOrderInfoList().stream().filter(orderInfo -> orderInfo.getProducts() != null).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(productOrderInfoList)) {
            return fatherSonOrderRequest;
        }
        for (CreateOrderProductRequest productDto : productOrderInfoList.get(0).getProducts()) {
            pids.add(productDto.getProductId());
        }
        Map<String, GetProductsVo> products = itemService.getSpuProducts(pids, fatherSonOrderRequest.getPartnerId(), productOrderInfoList.get(0).getShopId(), fatherSonOrderRequest.getMenuType());
        if (products.isEmpty()) {
            return fatherSonOrderRequest;
        }
        for (CreateOrderProductRequest productDto : productOrderInfoList.get(0).getProducts()) {
            if (StringUtils.isNotEmpty(productDto.getSpecification()) && products.get(productDto.getSpecification()) != null) {
                productDto.setCustomerCode(products.get(productDto.getSpecification()).getCustomerCode());
                productDto.setProductCode(products.get(productDto.getSpecification()).getProductCode());
                productDto.setThirdProductSpecId(products.get(productDto.getSpecification()).getThirdProductSpecId());
                productDto.setThirdProductPropertyId(getThirdPropertyId(products.get(productDto.getSpecification()).getProductAttributeGroupList(), productDto.getAddInfo()));
            } else {
                productDto.setCustomerCode("");
                productDto.setProductCode("");
                LogUtil.error("getProducts_exception", JSONObject.toJSONString(pids), JSONObject.toJSONString(products));
            }
            //套餐子商品
            if (CollectionUtils.isNotEmpty(productDto.getComboProduct())) {
                for (CreateOrderProductRequest comboProduct : productDto.getComboProduct()) {
                    String comboSkuId = comboProduct.getSpecification();
                    if (products.get(comboSkuId) != null) {
                        comboProduct.setCustomerCode(products.get(comboSkuId).getCustomerCode());
                        comboProduct.setProductCode(products.get(comboSkuId).getProductCode());
                        comboProduct.setThirdProductSpecId(products.get(comboSkuId).getThirdProductSpecId());
                        comboProduct.setThirdProductPropertyId(getThirdPropertyId(products.get(comboSkuId).getProductAttributeGroupList(), comboProduct.getAddInfo()));
                    } else {
                        comboProduct.setCustomerCode("");
                        comboProduct.setProductCode("");
                        LogUtil.error("getProducts_exception", JSONObject.toJSONString(comboSkuId), JSONObject.toJSONString(products), null);
                    }
                }
            }
        }
        return fatherSonOrderRequest;
    }

    /**
     * 获取商品第三方商品编号
     *
     * @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.setCustomerCode(products.get(skuId).getCustomerCode());
                productDto.setProductCode(products.get(skuId).getProductCode());
                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 {
                productDto.setCustomerCode("");
                productDto.setProductCode("");
                LogUtil.error("getProducts_exception", JSONObject.toJSONString(skuId), JSONObject.toJSONString(products), null);
            }
            //套餐子商品
            if (CollectionUtils.isNotEmpty(productDto.getComboProduct())) {
                for (CreateOrderProductRequest comboProduct : productDto.getComboProduct()) {
                    String comboSkuId = comboProduct.getSpecification();
                    System.out.println(comboSkuId);
                    if (products.get(comboSkuId) != null) {
                        comboProduct.setCustomerCode(products.get(comboSkuId).getCustomerCode());
                        comboProduct.setProductCode(products.get(comboSkuId).getProductCode());
                        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 {
                        comboProduct.setCustomerCode("");
                        comboProduct.setProductCode("");
                        LogUtil.error("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 ("2".equals(userLoginInfoDto.getChannel())) {
            orderClient = OrderClientType.ALIPAY;
        } else if (UserLoginChannelEnum.APP.getCode().equals(userLoginInfoDto.getChannel())) {
            orderClient = OrderClientType.APP;
        }
        //抖音小程序
        if ("5".equalsIgnoreCase(createOrderVo.getChannel())) {
            createOrderVo.setPayChannelType(PayChannelType.TIKTOKPAY.getIndex());
            orderClient = OrderClientType.TIKTOKPAY;
        }

        // 美业
        if (OrderChannelType.BEAUTIFUL.getCode().equals(createOrderVo.getChannelType())) {
            orderClient = OrderClientType.BEAUTIFUL;
        }

        long totalAmount = 0;
        int cardAmount = 0;
        QueryOrdersResponse.DataBean.OrderBean fatherBeanListOne = new QueryOrdersResponse.DataBean.OrderBean();
        QueryOrdersResponse.DataBean.OrderBean productBeanListOne = new QueryOrdersResponse.DataBean.OrderBean();
        if (createOrderVo.getBuyMemberCard() != null && StringUtils.isNotEmpty(createOrderVo.getBuyMemberCard().getRuleId()) && StringUtils.isNotEmpty(createOrderVo.getBuyMemberCard().getPaidId())) {
            //父子订单
            int cardOriginalAmount = shoppingCartGoodsDto.getCardOriginalAmount() == null ? 0 : shoppingCartGoodsDto.getCardOriginalAmount();
            int cardDiscountAmount = shoppingCartGoodsDto.getCardDiscountAmount() == null ? 0 : shoppingCartGoodsDto.getCardDiscountAmount();
            cardAmount = cardOriginalAmount - cardDiscountAmount;
            CreateFatherSonOrderResponse createFatherSonOrderResponse = createFatherSonOrder(createOrderVo, storeResponseDto, shoppingCartGoodsDto, orderExtendedReq, appId,userLoginInfoDto.getOpenId());
            if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createFatherSonOrderResponse.getErrcode())) {
                return ResponseUtil.error(createFatherSonOrderResponse.getErrcode().toString(), createFatherSonOrderResponse.getErrmsg());
            }
            List<QueryOrdersResponse.DataBean.OrderBean> orderBeanList = createFatherSonOrderResponse.getOrderBeanList();
            List<QueryOrdersResponse.DataBean.OrderBean> fatherBeanList = orderBeanList.stream().filter(orderBeanTemp -> orderBeanTemp.getIsParent()).collect(Collectors.toList());
            List<QueryOrdersResponse.DataBean.OrderBean> productBeanList = orderBeanList.stream().filter(orderBeanTemp -> 1 == orderBeanTemp.getBizType()).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(fatherBeanList)) fatherBeanListOne = fatherBeanList.get(0);
            if (CollectionUtils.isNotEmpty(productBeanList)) productBeanListOne = productBeanList.get(0);
            //订单总金额 商品+会员卡
            totalAmount = orderBeanList.stream().mapToLong(QueryOrdersResponse.DataBean.OrderBean::getAmount).count();
            fatherBeanList.get(0).setShopId(storeResponseDto.getStoreCode());
            fatherBeanList.get(0).setCompanyId(createOrderVo.getPartnerId());
        } else {
            //普通订单
            CreateOrderResponse createOrderFlowResponse = createOrder(createOrderVo, storeResponseDto, shoppingCartGoodsDto, orderExtendedReq, orderClient, appId,userLoginInfoDto.getOpenId());
            if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createOrderFlowResponse.getErrcode())) {
                return ResponseUtil.error(createOrderFlowResponse.getErrcode().toString(), createOrderFlowResponse.getErrmsg());
            }
            fatherBeanListOne = createOrderFlowResponse.getData();
            productBeanListOne = createOrderFlowResponse.getData();
            totalAmount = createOrderFlowResponse.getData().getAmount();
        }
        response.setTotalAmount(totalAmount);
        response.setCardAmount(cardAmount);
        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();
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else if (totalAmount > 0 && Objects.nonNull(createPrepayRequestDto.getUnionPayCard())) {
            // 电子风味卡支付
            orderPayResponse = uSvcPay(createPrepayRequestDto.getFatherOrderBean(), paymentRequest, transId, LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getUnionPayCard());
        } else if (totalAmount > 0 && StringUtils.isBlank(cardCode)) {
            String partnerPayOvertime = this.getPartnerPayOvertime(createPrepayRequestDto.getPartnerId());
            orderPayResponse = getPreOrderPay(createPrepayRequestDto.getFatherOrderBean(), paymentRequest, LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getCardAmount(), transId, partnerPayOvertime, createPrepayRequestDto.getOrderExtInfoDTO());
        }
        //混合支付+svc卡
        else if (totalAmount > 0 && StringUtils.isNotBlank(cardCode)) {
            orderPayResponse = switchSvcOrComb(totalAmount, cardCode, createPrepayRequestDto.getFatherOrderBean(), paymentRequest, transId, createPrepayRequestDto.getChannel(), createPrepayRequestDto.getStoreId(), LogThreadLocal.getTrackingNo());
        } else {
            // 0元订单如果不需要支付，自定义支付单号
            orderPayResponse = getOrderPayResponse(paymentRequest, createPrepayRequestDto.getFatherOrderBean());
        }
        if (orderPayResponse == null || Objects.isNull(orderPayResponse.getFmId())) {
            BaseResponse baseResponse = failPreOrderPay(LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getProductOrderBean(), cardCode, createPrepayRequestDto.getOrderClient(),
                    Objects.isNull(orderPayResponse) ? null : orderPayResponse.getMsg());
            // 电子风味卡需要给用户特殊的返回
            if (totalAmount > 0 && Objects.nonNull(createPrepayRequestDto.getUnionPayCard())) {
                baseResponse.setMessage(Objects.nonNull(orderPayResponse) &&
                        (ResponseCodeConstant.PASSWORD_WRONG.equals(orderPayResponse.getPayTransId())
                                || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(orderPayResponse.getPayTransId())) ?
                        orderPayResponse.getMsg() : "支付失败");
            }
            return baseResponse;
        }
        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) && Objects.isNull(createPrepayRequestDto.getUnionPayCard())) {
            createOrderResponse.setPaySuccess(false);
        } else if (StringUtils.isNotBlank(orderPayResponse.getPayMode()) && PayChannelType.COMB.getEbcode().equals(orderPayResponse.getPayMode())) {
            createOrderResponse.setPaySuccess(false);
        } else if (StringUtils.isNotBlank(orderPayResponse.getPayMode()) && PayChannelType.SVC.getEbcode().equals(orderPayResponse.getPayMode())) {
            createOrderResponse.setPaySuccess(true);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        // 推荐优惠插件用户下单数据上报
        //wechatPushProcessor.statusOrderCreate(userLoginInfoDto, createOrderResponse.getOid(), createOrderVo.getPartnerId());
        if (!createOrderResponse.getPaySuccess()) {
            return ResponseUtil.success(createOrderResponse);
        } else {
            //如果是商品券支付0元，调用回调接口
            /**
             *  - 老的svc卡或是0元订单下单成功直接核销 这里不处理
             *  - 混合支付纯svc支付 需要直接内部核销 其他支付方式需依靠外部回调
             *  -
             */
            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);
            message.setSource(PaySuccessSource.OUTSIDE.getSource());
            /*
            if (StringUtils.isNotBlank(orderPayResponse.getPayMode()) && PayChannelType.SVC.getEbcode().equals(orderPayResponse.getPayMode())) {
                message.setSource(PaySuccessSource.OUTSIDE.getSource());
            }
             */
            orderAdapterService.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }

    private OrderPayResponse switchSvcOrComb(Long totalAmount
            , String cardCode
            , QueryOrdersResponse.DataBean.OrderBean orderBean
            , PaymentRequest paymentRequest
            , String transId
            , String channel
            , String storeId
            , String trackingNo) {

        OrderPayResponse orderPayResponse = new OrderPayResponse();
        boolean check = this.checkSvcComPay(orderBean.getCompanyId(), orderBean.getShopId());
        //混合支付
        if (check && StringUtils.isNotBlank(channel)) {
            ApiLog.debug("混合支付:");
            String partnerPayOvertime = this.getPartnerPayOvertime(orderBean.getCompanyId());
            orderPayResponse = comPayOrder(cardCode, orderBean, paymentRequest, partnerPayOvertime, totalAmount.intValue(), channel, storeId, LogThreadLocal.getTrackingNo());
        }
        //svc 支付
        else {
            ApiLog.debug("svc卡支付");
            orderPayResponse = svcPay(cardCode, orderBean, paymentRequest, transId, trackingNo);
        }
        return orderPayResponse;
    }

    /**
     * unionPay card pay
     *
     * @param orderBean
     * @param paymentRequest
     * @param transId
     * @param trackingNo
     * @param unionPayCard
     * @return
     */
    private OrderPayResponse uSvcPay(QueryOrdersResponse.DataBean.OrderBean orderBean, PaymentRequest paymentRequest, String transId, String trackingNo, CreateOrderVo.UnionPayCard unionPayCard) {
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        if (Objects.isNull(unionPayCard) || StringUtils.isBlank(unionPayCard.getCode()) || StringUtils.isBlank(unionPayCard.getPassword())) {
            orderPayResponse.setMsg("电子风味卡信息缺失");
            return orderPayResponse;
        }
        CodePayRequest request = new CodePayRequest();
        String partnerId = orderBean.getCompanyId();
        request.setBody(orderBean.getShopName());
        request.setBusinessDate(DateTimeFormatter.ofPattern(DateUtil.FORMAT_YYYY_MM_DD_HHMMSS).format(LocalDateTime.now()));
        // paymentRequest 的 payCode可能为null,不保险
        request.setPayCode(PayChannel.USVCP.getCode());
        // 电子风味卡信息
        request.setCode(unionPayCard.getCode());
        request.setCardPassword(unionPayCard.getPassword());
        request.setPartnerId(partnerId);
        request.setStoreId(orderBean.getShopId());
        request.setAmount(orderBean.getAmount());
        request.setTransId(transId);
        request.setStationId("2");
        request.setOperatorId("2");
        request.setVer("2");
        request.setMerchantDiscount(orderBean.getOriginalAmount().longValue()-orderBean.getAmount());
        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) {
            // 需要把2种特殊情况抛给用户
            if (Objects.nonNull(responseBase) && (ResponseCodeConstant.PASSWORD_WRONG.equals(responseBase.getCode()) || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(responseBase.getCode()))) {
                orderPayResponse.setPayTransId(responseBase.getCode());
            }
            orderPayResponse.setMsg(Objects.isNull(responseBase) ? "电子风味卡支付异常" : responseBase.getMessage());
        } else {
            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());
            orderPayResponse.setPayMode(PayChannelType.USVCP.getEbcode());
        }
        return orderPayResponse;
    }

    /**
     * 创建普通订单  saas会走  app会走
     */
    public CreateOrderResponse createOrder(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto,
                                           OrderExtendedReq orderExtendedReq, OrderClientType orderClient, String appId,String openId) {
        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);
        createOrderRequest.setOpenId(openId);
        MqMessageRequest mqMessageRequest = new MqMessageRequest();
        mqMessageRequest.setBackOrdersNotifyActivityExchange(backOrdersNotifyActivityExchange);
        mqMessageRequest.setBackOrdersNotifyActivityQueue(backOrdersChangeOrderStatusConsumerQueue);
        createOrderRequest.setMqMessageRequest(mqMessageRequest);
        createOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        ApiLog.debug("createOrder  sessionId:{},createOrderVo:{}", createOrderVo.getSessionId(), JSON.toJSONString(createOrderRequest));
        return orderCenterSdkService.createOrderFlow(createOrderRequest);
    }

    /**
     * 创建父子订单
     */
    public CreateFatherSonOrderResponse createFatherSonOrder(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto,
                                                             ShoppingCartGoodsDto shoppingCartGoodsDto, OrderExtendedReq orderExtendedReq,
                                                             String appId,String openId) {
        CreateFatherSonOrderRequest createFatherSonOrderRequest = orderAdapter.convertFatherSonOrderRequest(createOrderVo, shoppingCartGoodsDto, orderExtendedReq, storeResponseDto, appId);
        //查询第三方商品编号
        createFatherSonOrderRequest = getProductCustomerCodeNew(createFatherSonOrderRequest);
        MqMessageRequest mqMessageRequest = new MqMessageRequest();
        mqMessageRequest.setBackOrdersNotifyActivityExchange(backOrdersNotifyActivityExchange);
        mqMessageRequest.setBackOrdersNotifyActivityQueue(backOrdersChangeOrderStatusConsumerQueue);
        createFatherSonOrderRequest.setOpenId(openId);
        createFatherSonOrderRequest.setMqMessageRequest(mqMessageRequest);
        return orderCenterSdkService.createFatherSonOrder(createFatherSonOrderRequest);
    }

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

    private BaseResponse failPreOrderPay(String trackingNo, QueryOrdersResponse.DataBean.OrderBean orderBean, String cardCode, OrderClientType orderClient, String msg) {
        List<OrderClientType> notCancelOrderClientList = Lists.newArrayList(OrderClientType.APP);
        if (!notCancelOrderClientList.contains(orderClient)) {
            //失败冲正库存，冲正活动库存，取消订单
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, StringUtils.join(new String[]{"获取预支付失败", msg}, '-'), 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(), StringUtils.isNotBlank(msg) ? msg : 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(QueryOrdersResponse.DataBean.OrderBean orderBean, PaymentRequest paymentRequest, String trackingNo, Integer cardAmount, String transId, String partnerPayOvertime, OrderExtInfoDto orderExtInfoDto) {
        OrderPayResponse orderPayResponse;
        try {
            UnifiedOrderRequest request = orderAdapter.convent2UnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, transId, partnerPayOvertime);
            // add by miaohui for 拼单群收款判断拼单人数大于1时参与微信平台补贴活动，创建预支付时上送goodsTag，后续抽成促销服务活动时删除此逻辑 start
            if (null != orderBean.getMarketingType() && OrderMarketType.COLLAGE.getIndex() == orderBean.getMarketingType()) {
                // 拼单人数大于1人时参加拼单补贴
                if (null != orderBean.getProductList() && orderBean.getProductList().stream().map(QueryOrdersResponse.DataBean.OrderBean.ProductBean::getUserId).distinct().collect(Collectors.toList()).size() > 1) {
                    Map<String, String> goodsTagMap = this.goodsTagMap();
                    String goodsTag = goodsTagMap.get(orderBean.getCompanyId());
                    request.setGoodsTag(StringUtils.isBlank(goodsTag) ? collageGoodsTag : goodsTag);
                }
            }
            // add by miaohui for 拼单群收款判断拼单人数大于1时参与微信平台补贴活动，创建预支付时上送goodsTag，后续抽成促销服务活动时删除此逻辑 end
            if (orderExtInfoDto != null && StringUtils.isNotBlank(orderExtInfoDto.getStationId())) {
                request.setStationId(orderExtInfoDto.getStationId());
            }
            com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> responseBase = standardPaymentService.unifiedOrder(request, trackingNo);
            if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode())) {
                ApiLog.info("支付SDK返回信息错误,trackingNo:{} request:{} response:{}", trackingNo, JSONObject.toJSONString(request), JSONObject.toJSONString(responseBase));
                // 1.9.34 预支付失败需要把原因进行记录
                orderPayResponse = new OrderPayResponse();
                orderPayResponse.setMsg(responseBase.getMessage());
            } else {
                putDelMq(request.getPartnerId(), request.getStoreId(), responseBase.getData().getFmId(), orderBean.getOid());
                orderPayResponse = orderAdapter.convent2OrderPayResponse(responseBase.getData());
                orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
                orderPayResponse.setOpenId(paymentRequest.getOpenId());
                orderPayResponse.setPartnerId(orderBean.getCompanyId());
                orderPayResponse.setOrderId(orderBean.getOid());
                orderPayResponse.setPayMode(PayChannelType.WECHAT.getEbcode());
                if (orderPayResponse.getPayOrder() != null && StringUtils.isNotBlank(orderPayResponse.getPayOrder().getAliPayOrder())) {
                    orderPayResponse.setPayMode(PayChannelType.ALIPAY.getEbcode());
                }
                //抖音支付
                if (PayChannelType.TIKTOKPAY.getIndex().toString().equalsIgnoreCase(orderBean.getPayChannelType())) {
                    orderPayResponse.setPayMode(PayChannelType.TIKTOKPAY.getEbcode());
                }

            }
        } catch (Exception e) {
            LogUtil.error("getPreOrderPay_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(paymentRequest));
            //TODO 邮件告警
            orderPayResponse = new OrderPayResponse();
            orderPayResponse.setMsg("getPreOrderPay_error");
        }
        return orderPayResponse;
    }

    public OrderPayResponse svcPay(String cardCode, QueryOrdersResponse.DataBean.OrderBean orderBean, PaymentRequest paymentRequest, String transId, String trackingNo) {
        CodePayRequest request = new CodePayRequest();
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        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");
        request.setMerchantDiscount(orderBean.getOriginalAmount().longValue()-orderBean.getAmount());
        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())) {
            orderPayResponse.setMsg(Objects.isNull(svcCardAmountResponseBaseResponse) ? "获取svc卡余额异常" : svcCardAmountResponseBaseResponse.getMessage());
            return orderPayResponse;
        }
        Integer amount = svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos().get(0).getAmount();
        Integer vamount = svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos().get(0).getVamount();
        if (amount + vamount < orderBean.getAmount()) {
            orderPayResponse.setMsg("svc卡余额不足");
            return orderPayResponse;
        }
        //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) {
            // 1.9.34 预支付失败需要把原因进行记录
            orderPayResponse.setMsg(Objects.isNull(responseBase) ? "svc卡支付异常" : responseBase.getMessage());
        } else {
            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());
            orderPayResponse.setPayMode(PayChannelType.SVC.getEbcode());
        }
        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;
    }

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

        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());
        if (StringUtils.isNotBlank(createOrderVo.getScene())) {
            orderExtInfoDto.setScene(createOrderVo.getScene());
        }
        if (null != shoppingCartGoodsDto && null != shoppingCartGoodsDto.getSendPoint()) {
            ShoppingCartGoodsDto.SendPoint sendPoint = shoppingCartGoodsDto.getSendPoint();
            orderExtInfoDto.setSendPointValidityDateDays(sendPoint.getValidityDateDays());
            orderExtInfoDto.setSendPointMaxNum(sendPoint.getMaxNum());
            orderExtInfoDto.setSendPointActivityCode(sendPoint.getActivityCode());
            orderExtInfoDto.setSendPointEndTime(sendPoint.getEndTime().getTime() + "");
            orderExtInfoDto.setSendPointSendPoint(sendPoint.getSendPoint());
            orderExtInfoDto.setSendPointStoreLevel(sendPoint.getStoreLevel());
        }
        return orderExtInfoDto;
    }


    /**
     * 获取商户自定义提示信息配置
     *
     * @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();
    }

    /**
     * 冲正商品库存，活动库存,商品库存，订单取消，退款
     *
     * @param orderBean 订单信息
     * @param transType TransTypeEnum 冲正类型
     */
//    public void backOrdersNotifyActivity(QueryOrdersResponse.DataBean.OrderBean orderBean, List<Integer> transType, String backOrdersNotifyActivityQueue,
//                                         String backOrdersNotifyActivityExchange) {
//        LogUtil.info("backOrdersNotifyActivity", JSONObject.toJSONString(transType), null);
//        if (orderBean == null) {
//            return;
//        }
//        // 删除订单 通知活动添加商品库存
//        ActivityCancelStockRequest activityCancelStockRequestDto = activitySdkAdapter.convert2ActivityCancelStockRequestDto(
//                orderBean, transType);
//        try {
//            Header header = new Header(MQAction.INSERT.getAction(), "backOrdersNotifyActivity", orderBean.getOid(), backOrdersNotifyActivityQueue);
//            MQMessage<ActivityCancelStockRequest> message = new MQMessage<>(header, activityCancelStockRequestDto);
//            mqService.convertAndSend(backOrdersNotifyActivityExchange, backOrdersNotifyActivityQueue, message);
//        } catch (Exception e) {
//            //TODO 邮件告警
//            LogUtil.error("backOrdersNotifyActivity_error", backOrdersNotifyActivityExchange, backOrdersNotifyActivityQueue, e);
//        }
//    }

    /**
     * 编辑订单，保持预支付信息
     */
    public BaseResponse updateOrderInfo(OrderPayResponse orderPayResponse, OrderExtInfoDto orderExtInfo
            , QueryOrdersResponse.DataBean.OrderBean 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);
        if (orderPayResponse.getPayMode() != null) {
            orderEditRequest.setPayChannel(PayChannelType.getByEbcode(orderPayResponse.getPayMode()).getEbcode());
            orderEditRequest.setPayChannelName(PayChannelType.getByEbcode(orderPayResponse.getPayMode()).getName());
            orderEditRequest.setPayChannelType(PayChannelType.getByEbcode(orderPayResponse.getPayMode()).getIndex());
        }
        //混合支付项
        if (CollectionUtils.isNotEmpty(orderPayResponse.getPayItem())) {
            orderEditRequest.setOrderPayItem(orderPayResponse.getPayItem());
            if (orderPayResponse.getPayItem().size() == 2) {
                orderEditRequest.setPayChannel(PayChannelType.COMB.getEbcode());
                orderEditRequest.setPayChannelName(PayChannelType.COMB.getName());
                orderEditRequest.setPayChannelType(PayChannelType.COMB.getIndex());
            }
        }
        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;
    }

    public RefundReasonResponseVo getRefundReasonResponseVo(RefundReasonEnum refundReasonEnum) {
        RefundReasonResponseVo refundReasonResponseVo = new RefundReasonResponseVo();
        refundReasonResponseVo.setCode(refundReasonEnum.getCode());
        refundReasonResponseVo.setDesc(refundReasonEnum.getDesc());
        return refundReasonResponseVo;
    }

    /**
     * 通知小助手发送申请退款公众号订阅消息
     *
     * @param orderBean
     */
    public void sendApplyRefundSubscriptionNotice(OrderBean orderBean, OrderRefundVo request) {
        LogUtil.debug("sendApplyRefundSubscriptionNotice", JSONObject.toJSONString(request), null);
//        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);
        try {
            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 orderId = orderBean.getOid();
            Double amount = orderBean.getAmount() / 100.0D;
            SendMessageRequest sendMessageRequest = new SendMessageRequest();
            sendMessageRequest.setMessageType("REFUND_ORDER");
            sendMessageRequest.setOrderId(orderId);
            sendMessageRequest.setPartnerId(orderBean.getCompanyId());
            sendMessageRequest.setRemark(request.getReason() + "," + request.getRemarks());
            sendMessageRequest.setStoreId(orderBean.getShopId());
            sendMessageRequest.setAmount(amount.toString());
            sendMessageRequest.setRemindMessage("用户申请退款");
            sendMessageRequest.setOrderTime(orderBean.getGmtPay() == null ? "" : DateUtil.convert2String(new Date(orderBean.getGmtPay()), "yyyy-MM-dd HH:mm:ss"));
            sendMessageRequest.setUserName(orderBean.getUserName());
            sendMessageRequest.setPhone(orderBean.getPhone());
            ecologyAdminApplicationClient.sendTemplateMessage(sendMessageRequest);
        } catch (Exception e) {
            LogUtil.error("sendApplyRefundSubscriptionNotice_error", null, null, e);
        }
    }

    /**
     * 申请退款小票打印
     *
     * @param orderBean
     * @param orderRefundVo
     */
    private void printApplyRefundSmallTicket(OrderBean 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) {
            LogUtil.error("applyRefundPrint_error", null, null, e);
        }
    }

    /**
     * 下单支付
     */
    private BaseResponse createOrderAndPay(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto,
                                           AssortmentCustomerInfoVo userLoginInfoDto, OrderExtInfoDto orderExtInfoDTO) {
        //创建订单--包括下单购买会员卡创建父子订单
        CreateOrderOperateDto operateDto = createOrderForFace(createOrderVo, storeResponseDto, shoppingCartGoodsDto, userLoginInfoDto.getWxAppId(),userLoginInfoDto.getOpenId());
        long totalAmount = operateDto.getTotalAmount();
        int cardAmount = operateDto.getCardAmount();
        QueryOrdersResponse.DataBean.OrderBean fatherOrderBean = operateDto.getFatherOrderBean();
        QueryOrdersResponse.DataBean.OrderBean productOrderBean = operateDto.getProductOrderBean();
        //支付-- 包含商品券无需支付、唤起微信支付、储值卡支付直接支付、扫脸支付
        OrderPayResponse orderPayResponse = pay(userLoginInfoDto, createOrderVo, totalAmount, cardAmount, fatherOrderBean);
        // 默认支付成功必有非码订单号
        if (orderPayResponse == null || Objects.isNull(orderPayResponse.getFmId())) {
            if (createOrderVo.getFaceCode() != null) {
                createOrderVo.setCardCode(createOrderVo.getFaceCode());
            }
            BaseResponse baseResponse = failPreOrderPay(LogThreadLocal.getTrackingNo(), productOrderBean, createOrderVo.getCardCode(), null,
                    Objects.isNull(orderPayResponse) ? null : orderPayResponse.getMsg());
            // 电子风味卡需要给用户特殊的返回
            if (totalAmount > 0 && Objects.nonNull(createOrderVo.getUnionPayCard())) {
                baseResponse.setMessage(Objects.nonNull(orderPayResponse) &&
                        (ResponseCodeConstant.PASSWORD_WRONG.equals(orderPayResponse.getPayTransId())
                                || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(orderPayResponse.getPayTransId())) ?
                        orderPayResponse.getMsg() : "支付失败");
            }
            return baseResponse;
        }
        //更新订单extinfo信息
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, orderExtInfoDTO, productOrderBean, LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        CreateOrderResponseVo createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, productOrderBean);
        // 推荐优惠插件用户下单数据上报
        //wechatPushProcessor.statusOrderCreate(userLoginInfoDto, createOrderResponse.getOid(), createOrderVo.getPartnerId());
        //设置是否唤起微信支付
        if (totalAmount > 0 && StringUtils.isBlank(createOrderVo.getCardCode()) && StringUtils.isBlank(createOrderVo.getFaceCode())) {
            createOrderResponse.setPaySuccess(false);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        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(userLoginInfoDto.getOpenId());
            message.setPlatform_coupon(0);
            message.setMerchant_coupon(0);
            //0元订单内部调支付成功
            orderAdapterService.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }

    /**
     * 创建订单
     */
    private CreateOrderOperateDto createOrderForFace(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto,
                                                     ShoppingCartGoodsDto shoppingCartGoodsDto, String appId,String openId) {
        CreateOrderOperateDto response = new CreateOrderOperateDto();
        OrderExtendedReq orderExtendedReq = orderAdapter.saveStoreInfo(storeResponseDto);
        //创建普通订单
        Function<Object, CreateOrderResponse> createOrder = (var -> {
            BaseCreateOrderRequest baseCreateOrderRequest = orderAdapter.convent2CreateOrderDto(createOrderVo, shoppingCartGoodsDto, storeResponseDto);
            //查询第三方商品编号
            baseCreateOrderRequest = getProductCustomerCode(baseCreateOrderRequest);
            //保存门店渠道信息
            baseCreateOrderRequest.setOrderExtended(orderExtendedReq);
            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.setOpenId(openId);
            createOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
            return orderCenterSdkService.createOrderFlow(createOrderRequest);
        });
        //创建父子订单
        Function<Object, CreateFatherSonOrderResponse> createFatherSonOrder = (var -> {
            CreateFatherSonOrderRequest createFatherSonOrderRequest = orderAdapter.convertFatherSonOrderRequest(createOrderVo, shoppingCartGoodsDto, orderExtendedReq, storeResponseDto, appId);
            //查询第三方商品编号
            createFatherSonOrderRequest = getProductCustomerCodeNew(createFatherSonOrderRequest);
            MqMessageRequest mqMessageRequest = new MqMessageRequest();
            mqMessageRequest.setBackOrdersNotifyActivityExchange(backOrdersNotifyActivityExchange);
            mqMessageRequest.setBackOrdersNotifyActivityQueue(backOrdersChangeOrderStatusConsumerQueue);
            createFatherSonOrderRequest.setOpenId(openId);
            createFatherSonOrderRequest.setMqMessageRequest(mqMessageRequest);
            return orderCenterSdkService.createFatherSonOrder(createFatherSonOrderRequest);
        });

        long totalAmount = 0;
        int cardAmount = 0;
        QueryOrdersResponse.DataBean.OrderBean fatherBeanListOne = new QueryOrdersResponse.DataBean.OrderBean();
        QueryOrdersResponse.DataBean.OrderBean productBeanListOne = new QueryOrdersResponse.DataBean.OrderBean();
        if (createOrderVo.getBuyMemberCard() != null && StringUtils.isNotEmpty(createOrderVo.getBuyMemberCard().getRuleId()) && StringUtils.isNotEmpty(createOrderVo.getBuyMemberCard().getPaidId())) {
            //父子订单
            int cardOriginalAmount = shoppingCartGoodsDto.getCardOriginalAmount() == null ? 0 : shoppingCartGoodsDto.getCardOriginalAmount();
            int cardDiscountAmount = shoppingCartGoodsDto.getCardDiscountAmount() == null ? 0 : shoppingCartGoodsDto.getCardDiscountAmount();
            cardAmount = cardOriginalAmount - cardDiscountAmount;
            //创建父子订单
            CreateFatherSonOrderResponse createFatherSonOrderResponse = createFatherSonOrder.apply(null);
            if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createFatherSonOrderResponse.getErrcode())) {
                throw new ServiceException(ResponseResult.ORDER_CREATE_ERROR);
            }
            List<QueryOrdersResponse.DataBean.OrderBean> orderBeanList = createFatherSonOrderResponse.getOrderBeanList();
            List<QueryOrdersResponse.DataBean.OrderBean> fatherBeanList = orderBeanList.stream().filter(orderBeanTemp -> orderBeanTemp.getIsParent()).collect(Collectors.toList());
            List<QueryOrdersResponse.DataBean.OrderBean> productBeanList = orderBeanList.stream().filter(orderBeanTemp -> 1 == orderBeanTemp.getBizType()).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(fatherBeanList)) fatherBeanListOne = fatherBeanList.get(0);
            if (CollectionUtils.isNotEmpty(productBeanList)) productBeanListOne = productBeanList.get(0);
            //订单总金额 商品+会员卡
            totalAmount = orderBeanList.stream().mapToLong(QueryOrdersResponse.DataBean.OrderBean::getAmount).count();
        } else {
            //创建普通订单
            CreateOrderResponse createOrderFlowResponse = createOrder.apply(null);
            if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createOrderFlowResponse.getErrcode())) {
                throw new ServiceException(ResponseResult.ORDER_CREATE_ERROR);
            }
            fatherBeanListOne = createOrderFlowResponse.getData();
            productBeanListOne = createOrderFlowResponse.getData();
            totalAmount = productBeanListOne.getAmount();
        }
        response.setTotalAmount(totalAmount);
        response.setCardAmount(cardAmount);
        response.setFatherOrderBean(fatherBeanListOne);
        response.setProductOrderBean(productBeanListOne);
        return response;
    }

    /**
     * 支付
     * 包含唤起微信支付、储值卡支付直接支付、扫脸支付、商品券无需支付
     */
    private OrderPayResponse pay(AssortmentCustomerInfoVo userLoginInfoDto, CreateOrderVo createOrderVo, long totalAmount, int cardAmount,
                                 QueryOrdersResponse.DataBean.OrderBean fatherBeanListOne) {
        //<!---创建订单公共方法执行逻辑--->
        OrderPayResponse orderPayResponse = null;
        String appId = userLoginInfoDto.getWxAppId();
        PaymentRequest paymentRequest = orderBodyConvertToPaymentBody(userLoginInfoDto.getOpenId(), createOrderVo.getPartnerId(), appId, null);
        //支付金额异常
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        }
        //电子风味卡支付
        if (totalAmount > 0 && Objects.nonNull(createOrderVo.getUnionPayCard())) {
            return uSvcPay(fatherBeanListOne, paymentRequest, fatherBeanListOne.getOid(), LogThreadLocal.getTrackingNo(), createOrderVo.getUnionPayCard());
        }
        //唤起微信支付
        if (totalAmount > 0 && StringUtils.isBlank(createOrderVo.getCardCode()) && StringUtils.isBlank(createOrderVo.getFaceCode())) {
            String partnerPayOvertime = this.getPartnerPayOvertime(createOrderVo.getPartnerId());
            orderPayResponse = getPreOrderPay(fatherBeanListOne, paymentRequest, LogThreadLocal.getTrackingNo(), cardAmount, fatherBeanListOne.getOid(), partnerPayOvertime, null);
            return orderPayResponse;
        }
        //储值卡支付
        if (totalAmount > 0 && StringUtils.isNotBlank(createOrderVo.getCardCode())) {
            //svc卡支付
            orderPayResponse = svcPay(createOrderVo.getCardCode(), fatherBeanListOne, paymentRequest, fatherBeanListOne.getOid(), LogThreadLocal.getTrackingNo());
            return orderPayResponse;
        }
        //扫脸支付
        if (totalAmount > 0 && StringUtils.isNotBlank(createOrderVo.getFaceCode())) {
            //svc卡支付
            orderPayResponse = facePay(createOrderVo.getFaceCode(), fatherBeanListOne, paymentRequest, LogThreadLocal.getTrackingNo());
            return orderPayResponse;
        }
        //0元订单，商品券订单等等
        if (totalAmount == 0) {
            // 0元订单如果不需要支付，自定义支付单号
            String fmId = "SPAY" + ValidationCode.getRandomUuid();
            orderPayResponse = orderAdapter.getOrderPayResponse(fatherBeanListOne.getCompanyId(), paymentRequest, fatherBeanListOne.getOid(), fmId);
            return orderPayResponse;
        }
        return orderPayResponse;
    }

    /**
     * 扫脸支付
     */
    public OrderPayResponse facePay(String cardCode, QueryOrdersResponse.DataBean.OrderBean orderBean, PaymentRequest paymentRequest, String trackingNo) {
        FacePayRequestDto request = new FacePayRequestDto();
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        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(orderBean.getOid());
        request.setStationId("1");
        request.setOperatorId("1");
        request.setVer("2");
        //支付服务扫脸付接口
        LogUtil.info("facePay_request", JSONObject.toJSON(request), null);
        com.freemud.application.sdk.api.base.BaseResponse<FacePayResponseDto> responseDto = null;
        try {
            responseDto = paymentNewClient.facePay(request);
            LogUtil.info("facePay_response", null, JSONObject.toJSON(responseDto));
        } catch (Exception e) {
            LogUtil.error("facePay_error", null, null, e);
        }
        if (responseDto == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseDto.getCode()) || responseDto.getData() == null) {
            // 1.9.34 预支付失败需要把原因进行记录
            orderPayResponse.setMsg(Objects.isNull(responseDto) ? "扫脸支付异常" : responseDto.getMessage());
        } else {
            FacePayResponseDto response = responseDto.getData();
            orderPayResponse.setFmId(response.getFmId());
            orderPayResponse.setPayTransId(response.getPayTransId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
        }
        return orderPayResponse;
    }


    /**
     * 历史判断围餐是从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 queryOrderByConditions(QueryOrderByConditionsRequestVo queryOrderByConditionsRequestVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderByConditionsRequestVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String userId = userLoginInfoDto.getMemberId();
        List<QueryOrderByConditionsResponseVo> responseVos = null;
        try {
            OrderConditionsReq orderConditionsReq = new OrderConditionsReq();
            BeanUtil.convertBean(queryOrderByConditionsRequestVo, orderConditionsReq);
            orderConditionsReq.setUserId(userId);
            Date startDate = DateUtil.convert2Date("2020-08-01 00:00:00", DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
            orderConditionsReq.setStartTimestamp(startDate.getTime() / 1000);
            orderConditionsReq.setEndTimestamp(new Date().getTime() / 1000);
            BaseDownLoadResponse<List<OrderInfoReqs>> orderInfoReqs = orderDownLoadSdkService.queryOrderByConditions(orderConditionsReq, LogTreadLocal.getTrackingNo());
            if (!String.valueOf(RESPONSE_SUCCESS_CODE).equals(orderInfoReqs.getCode())) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode());
            }
            Map<String, Object> responseMap = Maps.newTreeMap();
            //用户无订单数据
            if (orderInfoReqs.getResult() == null || orderInfoReqs.getTotalNum() == 0) {
                return ResponseUtil.success();
            }
            responseVos = orderInfoReqs.getResult().stream().map(
                    orderBean -> {
                        QueryOrderByConditionsResponseVo queryOrderByConditionsResponseVo = new QueryOrderByConditionsResponseVo();
                        BeanUtil.convertBean(orderBean, queryOrderByConditionsResponseVo);
                        BeanUtil.convertBean(orderBean, queryOrderByConditionsResponseVo);
                        List<String> imgUrl = new ArrayList<>();
                        String extInfo = orderBean.getExtInfo();
                        if (!StringUtil.isEmpty(extInfo)) {
                            JSONObject jsonObject = JSONObject.parseObject(extInfo);
                            JSONArray jsonArray = (JSONArray) JSONArray.parse(jsonObject.getString("imgUlr"));
                            for (int i = 0; i < jsonArray.size(); i++) {
                                imgUrl.add(String.valueOf(jsonArray.get(i)));
                            }
                        }
                        if (null != orderBean.getOrderSettlementDetailList() && orderBean.getOrderSettlementDetailList().size() > 0) {
                            queryOrderByConditionsResponseVo.setSettlementAmount(orderBean.getOrderSettlementDetailList().stream().map(OrderSettlementResp::getSettlementAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
                        } else {
                            queryOrderByConditionsResponseVo.setSettlementAmount(BigDecimal.ZERO);
                        }
                        queryOrderByConditionsResponseVo.setImgUrl(imgUrl);
                        queryOrderByConditionsResponseVo.setOrderStateValue(orderSdkAdapter.getOrderStatusValue(orderBean.getOrderState()));
                        SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String sd = sdff.format(new Date(Long.valueOf(orderBean.getCreateTime())));
                        queryOrderByConditionsResponseVo.setCreateTime(sd);
                        return queryOrderByConditionsResponseVo;
                    }
            ).collect(Collectors.toList());
        } catch (Exception e) {
            LogUtil.error("queryOrders_error", gson.toJson(queryOrderByConditionsRequestVo), e);
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        return ResponseUtil.success(responseVos);
    }

    /**
     * 获取商户支付超时时间
     *
     * @param partnerId 商户Id
     * @return 超时时间
     */
    private String getPartnerPayOvertime(String partnerId) {
        return Optional.ofNullable(openPlatformPartnerConfigManager.selectPartnerConfigByPartnerKey(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME))
                .orElseGet(() -> {
                    AssortmentOpenPlatformPartnerConfig config = new AssortmentOpenPlatformPartnerConfig();
                    config.setPartnerValue("30");
                    openPlatformPartnerConfigManager.addPartnerConfig(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME, config);
                    return config;
                }).getPartnerValue();
    }

    public void buildQueryOrderResponseVo(QueryOrderResponseVo queryOrderResponseVo, QueryOrderByIdResponse response, String partnerId) {

        if (null == response || response.getData() == null || !ObjectUtils.equals(response.getErrcode(), RESPONSE_SUCCESS_CODE)) {
            ApiLog.info("订单详情查询，返回值错误，QueryOrderByIdResponse", response);
            return;
        }

        OrderRelationService orderRelationService = orderRelationFactory.getQueryOrdrBuildService(partnerId);
        orderRelationService.queryOrdrBuild(queryOrderResponseVo, response);

    }

    public String getMealCodeRule(String appId) {
        String mealCodeRule = "";
        List<AssortmentOpenPlatformPartnerWxappConfig> partnerWxappConfigs = orderAdapter.cacheSelectDefaultPage(appId, "2");
        Map<String, AssortmentOpenPlatformPartnerWxappConfig> configMap = partnerWxappConfigs.stream().collect(Collectors.toMap(AssortmentOpenPlatformPartnerWxappConfig::getAppKey, Function.identity()));
        AssortmentOpenPlatformPartnerWxappConfig refundDeliveryFeeConfig = configMap.get("mealCodeRule");
        if (null != refundDeliveryFeeConfig) {
            mealCodeRule = refundDeliveryFeeConfig.getAppValue();
        }
        return mealCodeRule;
    }

    /**
     * 创建混合支付
     *
     * @param orderBean
     * @param paymentRequest
     * @param partnerPayOvertime
     * @param totalAmount
     * @param channel
     * @param storeId
     * @param trackingNo
     * @return
     */
    public OrderPayResponse comPayOrder(String cardNo
            , QueryOrdersResponse.DataBean.OrderBean orderBean
            , PaymentRequest paymentRequest
            , String partnerPayOvertime
            , Integer totalAmount
            , String channel
            , String storeId
            , String trackingNo) {

        String ebCode = this.getPayCodeByChanel(paymentRequest.getWxAppId(), channel, storeId);
        OrderPayResponse orderPayResponse = new OrderPayResponse();

        if (StringUtils.isBlank(ebCode)) {
            orderPayResponse.setMsg("请先联系相关人员配置商户对应的支付渠道");
            return orderPayResponse;
        }

        CombPayRequest combPayRequest = orderAdapter.convent2CombPayOrderRequest(cardNo, orderBean, paymentRequest, partnerPayOvertime, ebCode, channel, totalAmount);
        //todo :xxxooooo xxxoooxox
        CombPayResponse combPayResponse = null;
        int i = 1;
        do {
            try {
                combPayResponse = comPayClient.combPay(combPayRequest, combPayRequest.getPartner_id());
                if (combPayResponse != null) {
                    break;
                }
            } catch (Exception exception) {
            }
            i++;
        } while (i < 4);

        if (combPayResponse == null || !ResponseCodeConstant.PAYMENT_RESPONSE_SUCCESS.equals(combPayResponse.getCode())) {
            ApiLog.debug("混合支付返回信息错误,trackingNo:{} request:{} response:{}", trackingNo, JSONObject.toJSONString(combPayRequest), JSONObject.toJSONString(combPayResponse));
            orderPayResponse.setMsg(combPayResponse != null ? "支付：" + combPayResponse.getMsg() : "混合支付忙不过来啦，请稍后再试");
            return orderPayResponse;
        }
        Integer svcAmount = 0;
        Integer svcVAmount = 0;
        List<CombPayResponse.PayPlatform> payPlatforms = combPayResponse.getData().getPayPlatformResponseList();
        if (payPlatforms.size() == 0) {
            orderPayResponse.setMsg("混合支付:生成预支付失败");
            return orderPayResponse;
        }
        //生成预支付参数
        CombPayResponse.PayPlatform cashPay = payPlatforms
                .stream()
                .filter(f -> !PayChannelType.SVC.getEbcode().equals(f.getEbCode())).findFirst()
                .orElse(null);

        //现金+svc   现金
        if (payPlatforms.size() == 2 || (payPlatforms.size() == 1 && cashPay != null)) {
            orderPayResponse = orderAdapter.convent2OrderCombPayResponse(combPayResponse.getData().getPayPlatformResponseList(), orderBean.getCompanyId(), storeId);
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            orderPayResponse.setPayMode(orderPayResponse.getPayMode());
            //隐射关系
            redisCache.save(RedisUtil.getPaymentTransIdOrderKey(cashPay.getTransId()), orderBean.getOid(), 1L, TimeUnit.DAYS);
            //加入轮训队列
            putDelMq(orderBean.getCompanyId(), storeId, orderPayResponse.getFmId(), orderBean.getOid(), PayChannelType.getByEbcode(cashPay.getEbCode()).getIndex().intValue());
            return orderPayResponse;
        }
        //单svc
        else {
            CombPayResponse.PayPlatform svcPay = payPlatforms
                    .stream()
                    .filter(f -> PayChannelType.SVC.getEbcode().equals(f.getEbCode())).findFirst()
                    .orElse(null);
            orderPayResponse.setFmId(svcPay.getTransId());
            orderPayResponse.setPayTransId(svcPay.getTransId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            orderPayResponse.setPayMode(PayChannelType.SVC.getEbcode());
            for (CombPayResponse.PayPlatform pt : payPlatforms) {
                PayItem payItem = new PayItem();
                payItem.setFmTradeNo(pt.getFmTradeNo());
                payItem.setStoreId(storeId);
                payItem.setPayChannelType(PayChannelType.getByEbcode(pt.getEbCode()).getIndex().intValue());
                payItem.setPayChannelName(PayChannelType.getByEbcode(pt.getEbCode()).getName());
                payItem.setTransId(pt.getTransId());
                payItem.setPartnerId(combPayRequest.getPartner_id());
                payItem.setPayAmount(new BigDecimal(pt.getPayAmount()));
                orderPayResponse.getPayItem().add(payItem);
            }
        }

        return orderPayResponse;


    }

    /**
     * 通过payCode ->clientCode
     *
     * @param wxAppid
     * @param channel
     * @param storeId
     * @return
     */
    private String getPayCodeByChanel(String wxAppid, String channel, String storeId) {
        if (StringUtils.isBlank(channel)) return "";

        PayChannelType byIndex = PayChannelType.getByIndex(Byte.parseByte(channel));
        if (byIndex.getEbcode() == null) return "";
        AssortmentOpenPlatformIappWxappStore wxAppStore = assortmentOpenPlatformIappWxappStoreManager.selectWxappStoreByWxAppIdAndStoreId(wxAppid
                , storeId
                , byIndex.getEbcode());
        if (wxAppStore != null && StringUtils.isNotBlank(wxAppStore.getClientCode())) {
            return wxAppStore.getClientCode();
        }
        return "";
    }

    public String cannelComPayOrder(ConfirmOrderDto confirmOrderDto, QueryOrdersResponseDto.DataBean.OrderBean orderBean) {
        //失败冲正库存，冲正活动库存，取消订单
        CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(confirmOrderDto.getOrderId(), orderBean.getCompanyId(),
                AfterSalesType.SYSTEM_CANCEL, "混合支付SVC卡支付失败", LogTreadLocal.getTrackingNo(), null);
        //BaseOrderResponse request = orderCenterSdkService.orderCancel(cancelOrderRequest);
        BaseOrderResponse request = null;
        int i = 1;
        do {
            try {
                request = orderCenterSdkService.orderCancel(cancelOrderRequest);
                if (request != request) {
                    break;
                }
            } catch (Exception e) {
            }
            i++;
        } while (i < 4);

        backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
        if (ResponseCodeConstant.RESPONSE_SUCCESS.equals(request.getErrcode())) {
            backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus());
            return this.newSendPaySuccessNoticeMessage();
        } else {
            return this.newSendPayFaileMessage();
        }
    }

    /**
     * 获取混合支付是否开启
     *
     * @param partnerId
     * @return
     */
    private boolean checkSvcComPay(String partnerId, String storeId) {
        SvcComPayRequestDto requestDto = new SvcComPayRequestDto();
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        SvcComPayResponseDto query = null;
        for (int i = 0; i < 3; i++) {
            query = svcComPayClient.query(requestDto);
            if (query != null) break;
        }
        ApiLog.debug("order checkSvcComPay:{}", JSON.toJSONString(query));
        if (query == null || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
            return false;
        }
        if (query.getResult() != null && query.getResult().getValue()) {
            return true;
        } else {
            return false;
        }
    }

    private Map<String, String> goodsTagMap() {
        Map<String, String> map = new HashMap<>();
        try {
            for (String pg : collageGoodsTagList.split(",")) {
                map.put(pg.split(":")[0], pg.split(":")[1]);
            }
        } catch (Exception e) {
            LogUtil.error("goodsTag解析失败：" ,"","",e);
        }
        return map;
    }

    /**
     * 超时回调直接退款
     *
     * @param orderBean
     */
    public void timeOutRefund(QueryOrdersResponseDto.DataBean.OrderBean orderBean) {
        //调用支付退款
        ApiLog.debug("payment timeout callback for refund orderDto={}", JSON.toJSONString(orderBean));
        Integer abState = 4;
        String noPay = "8200404";
        //4 表示订单已经退款了
        if (abState.equals(orderBean.getAbnormalState())) {
            ApiLog.debug("payment timeout callback for refund is exist");
            return;
        }
        com.freemud.application.sdk.api.base.BaseResponse<OrderRefundResponse> response = null;
        Long refundId = System.currentTimeMillis();
        OrderExtInfoDto orderExtInfoDTO = gson.fromJson(orderBean.getExtInfo(), OrderExtInfoDto.class);
        if (orderExtInfoDTO == null || StringUtils.isBlank(orderExtInfoDTO.getFmId())) {
            ApiLog.debug("payment timeout callback for refund not create pre order");
            return;
        }
        Integer state = PayRefundStatus.SUCCESS.getCode();
        orderBean.setPayVoucher(orderExtInfoDTO.getFmId());
        SdkUpdateAbnormalState sdkUpdateAbnormalState = new SdkUpdateAbnormalState();
        String desc = "支付未及时回调";

        com.freemud.sdk.api.assortment.payment.request.OrderRefundRequest orderPayRefundRequest = orderAdapter.getOrderPayRefundRequest(orderBean, refundId, orderBean.getOid());
        response = standardPaymentService.orderRefund(orderPayRefundRequest, LogTreadLocal.getTrackingNo());
        ApiLog.debug("payment timeout callback for refund  orderId={},request={},resp={}", orderBean.getOid(), JSON.toJSONString(orderPayRefundRequest), JSON.toJSONString(response));
        if (response != null && noPay.equals(response.getCode())) {
            return;
        }
        if (response != null || state.equals(response.getData().getRefundStatus())) {
            sdkUpdateAbnormalState.setAbnormalDesc(desc + ",退款成功");
        } else {
            sdkUpdateAbnormalState.setAbnormalDesc(desc + ",退款失败");
        }
        sdkUpdateAbnormalState.setPartnerId(orderBean.getCompanyId());
        sdkUpdateAbnormalState.setAbnormalState(4);
        sdkUpdateAbnormalState.setOrderCode(orderBean.getOid());
        orderSdkService.updateAbnormalState(sdkUpdateAbnormalState);
    }

    private void closeHistoryPrePay(OrderBean orderBean) {

        OrderExtInfoDto extInfo = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
        //判断当前订单是否存在预支付订单
        if (extInfo != null && StringUtils.isNotEmpty(extInfo.getFmId())) {
            //订单状态未支付且存在预支付订单：
            // 1.查询预支付订单支付状态
            PaymentQueryRequest paymentQueryRequest = new PaymentQueryRequest();
            paymentQueryRequest.setPartnerId(orderBean.getCompanyId());
            paymentQueryRequest.setStoreId(orderBean.getShopId());
            paymentQueryRequest.setFmId(extInfo.getFmId());
            paymentQueryRequest.setVer("2");
            com.freemud.application.sdk.api.base.BaseResponse<PaymentQueryResponse> queryResponseBaseResponse = paymentNewService.query(paymentQueryRequest, LogThreadLocal.getTrackingNo());
            //判断预支付订单状态
            if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), queryResponseBaseResponse.getCode())) {
                throw new ServiceException(ResponseResult.ORDER_PAY_GETPRE_MESSAGE_ERROR);
            }
            //判断当前预支付订单是否已经支付成功
            if (ObjectUtils.equals(TradeState.SUCCESS.getCode(), queryResponseBaseResponse.getData().getTradeState())) {
                throw new ServiceException(ResponseResult.ORDER_HAS_PAID);
            }
            // 3.取消前一个预支付订单  调用支付取消预支付订单,如果预支付订单已经取消了再调用取消预支付订单接口会报错的
            if (ObjectUtils.equals(TradeState.NOTPAY.getCode(), queryResponseBaseResponse.getData().getTradeState())) {
                PaymentCloseUnifiedOrderRequest closeUnifiedOrderRequest = new PaymentCloseUnifiedOrderRequest();
                closeUnifiedOrderRequest.setFmId(extInfo.getFmId());
                closeUnifiedOrderRequest.setVer("2");
                closeUnifiedOrderRequest.setPartnerId(orderBean.getCompanyId());
                closeUnifiedOrderRequest.setStoreId(orderBean.getShopId());
                com.freemud.application.sdk.api.base.BaseResponse<PaymentCloseUnifiedOrderResponse> cancelNewUnifiedOrder = paymentNewService.cancelNewUnifiedOrder(closeUnifiedOrderRequest, LogThreadLocal.getTrackingNo());
                if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), cancelNewUnifiedOrder.getCode())) {
                    throw new ServiceException(ResponseResult.ORDER_PRE_PAYMENT_CLOSE_FAILED);
                }
            }
        }
    }

    private Boolean isQueryEs(Integer queryOrderStatus) {

        if (ObjectUtils.equals(QueryOrderStatus.TAKE_MEAL.getCode(), queryOrderStatus) || ObjectUtils.equals(QueryOrderStatus.NO_PAY.getCode(), queryOrderStatus)) {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    public BaseResponse queryTodayOrders(QueryOrderByConditionsRequestVo queryOrderByConditionsRequestVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderByConditionsRequestVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        String userId = userLoginInfoDto.getMemberId();
        Map<String, Object> result = new HashMap<>(0);
        Integer totalOrders = 0;
        try {
            OrderConditionsReq orderConditionsReq = new OrderConditionsReq();
            BeanUtil.convertBean(queryOrderByConditionsRequestVo, orderConditionsReq);
            orderConditionsReq.setUserId(userId);
            Date startDate = DateUtil.convert2Date(DateUtil.convert2String(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " 00:00:00", DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
            orderConditionsReq.setStartTimestamp(startDate.getTime() / 1000);
            orderConditionsReq.setEndTimestamp(new Date().getTime() / 1000);
            BaseDownLoadResponse<List<OrderInfoReqs>> orderInfoReqs = orderDownLoadSdkService.queryOrderByConditions(orderConditionsReq, LogTreadLocal.getTrackingNo());
            if (!String.valueOf(RESPONSE_SUCCESS_CODE).equals(orderInfoReqs.getCode())) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode());
            }
            totalOrders = null == orderInfoReqs.getTotalNum() ? 0 : orderInfoReqs.getTotalNum();
            result.put("totalOrders", totalOrders);
        } catch (Exception e) {
            LogUtil.error("queryTodayOrders", gson.toJson(queryOrderByConditionsRequestVo), e);
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        return ResponseUtil.success(result);
    }

    @Override
    public BaseResponse spellGroupOrderFailRefund(SpellGroupFailRefundVo refundVo) {
        List<String> orderCodeList = refundVo.getOrderCodeList();
        if (CollectionUtils.isEmpty(orderCodeList) || orderCodeList.stream().anyMatch(StringUtils::isBlank)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING.getCode(), "订单号不能为空");
        }
        // 进行一次去重
        orderCodeList = orderCodeList.stream().distinct().collect(Collectors.toList());

        // 查询订单列表
        QueryOrdersResponse orderListResp = getOrderList(orderCodeList);
        if (!RESPONSE_SUCCESS_CODE.equals(orderListResp.getErrcode()) || orderListResp.getData() == null || CollectionUtils.isEmpty(orderListResp.getData().getOrders())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "订单信息不存在");
        }

        String string = JSONArray.toJSONString(orderListResp.getData().getOrders());
        JSONArray jsonArray = JSONArray.parseArray(string);
        List<OrderBean> orderBeanList = jsonArray.toJavaList(OrderBean.class);
        // 前置检查
        BaseResponse checkResponse = batchRefundBeforeCheck(orderCodeList, orderBeanList);
        if (!RESPONSE_SUCCESS_CODE.equals(orderListResp.getErrcode())) {
            return ResponseUtil.error(checkResponse.getCode(), checkResponse.getMessage());
        }

        // 过滤订单
        // todo 此时存在处理中的售后怎么办?
        orderBeanList = filterOrder(orderBeanList);
        if (orderBeanList.isEmpty()){
            log.warn("拼团失败取消订单 -> 需要取消的订单未空  团号:{}",refundVo.getSpellGroupCode());
            return  ResponseUtil.success();
        }

        // 批量退款
        log.info("拼团失败取消订单 -> 开始处理， 团号:{}, 订单号:{}", refundVo.getSpellGroupCode(), orderBeanList);

        SpellGroupBatchOrderRefundVo orderRefundVo = new SpellGroupBatchOrderRefundVo();
        orderRefundVo.setPartnerId(orderBeanList.get(0).getCompanyId());
        orderRefundVo.setStoreId(orderBeanList.get(0).getShopId());
        orderRefundVo.setReason(Optional.ofNullable(RefundReasonEnum.getSpellGroupReasonByIndex(refundVo.getReason())).orElse(RefundReasonEnum.Other).getDesc());
        orderRefundVo.setRemarks(orderRefundVo.getReason());
        // 拼团失败取消 默认为只退款不退货
        orderRefundVo.setRefundMode(RefundModeEnum.UN_REFUND_GOODS.getIndex());

        // 拼团失败逻辑处理
        BaseResponse baseResponse = batchRefundOrderNoTake(orderRefundVo, orderBeanList, AfterSalesType.SYSTEM_CANCEL, true);
        if (baseResponse != null) {
            return baseResponse;
        }
        return ResponseUtil.success();
    }

    private QueryOrdersResponse getOrderList(List<String> orderCodeList) {
        BatchQueryByCodesRequest baseQueryOrderRequest = new BatchQueryByCodesRequest();
        baseQueryOrderRequest.setOrderCodes(orderCodeList);
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        return orderCenterSdkService.batchQueryByCodes(baseQueryOrderRequest);
    }

    private List<OrderBean> filterOrder(List<OrderBean> orderBeans) {
        List<OrderBean> list = new ArrayList<>(orderBeans.size());
        for (OrderBean orderBean : orderBeans) {
            if (Objects.equals(PayStatus.NOT_PAY.getCode(), orderBean.getPayStatus())
                    || Objects.equals(OrderStatus.WAIT_PAY.getCode(), orderBean.getStatus())) {
                log.info("拼团批量取消订单 -> 订单未支付，无需退款 订单号:{} ", orderBean.getOid());
                continue;
            }
            if (OrderStatus.CALCEL.getCode().equals(orderBean.getStatus())) {
                log.info("拼团批量取消订单 -> 订单已取消，无需退款  订单号:{} ", orderBean.getOid());
                continue;
            }
            list.add(orderBean);
        }
        return list;
    }

    private BaseResponse batchRefundBeforeCheck(List<String> orderCodeList, List<OrderBean> orderBeans) {
        List<String> notFoundCodeList = new ArrayList<>(orderCodeList);
        List<String> notSupportOrderCodeList = new ArrayList<>(orderCodeList.size());
        for (OrderBean orderBean : orderBeans) {
            notFoundCodeList.remove(orderBean.getOid());
            // 是否是微商城拼团订单
            if (!Objects.equals(com.freemud.sdk.api.assortment.order.enums.OrderSourceType.SAASMALL.getCode(), orderBean.getSource()) || !Objects.equals(OrderMarketType.GROUPB.getIndex(),orderBean.getMarketingType())) {
                notSupportOrderCodeList.add(orderBean.getOid());
            }
        }
        StringBuilder builder = new StringBuilder();
        if (!notFoundCodeList.isEmpty()) {
            builder.append(String.format("部分订单信息不存在:%s ,", JSON.toJSONString(notFoundCodeList)));
        }
        if (!notSupportOrderCodeList.isEmpty()) {
            builder.append(String.format("不是微商城拼团订单:%s", JSON.toJSONString(notSupportOrderCodeList)));
        }
        if (builder.length() != 0) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), builder.toString());
        }
        return ResponseUtil.success();
    }


    /**
     * 拼团失败逻辑处理
     * <p>应当只用于售前</p>
     *
     * 1.调用支付退款
     * 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
     *
     * @param orderRefundVo
     * @param orderBeans
     * @param afterSalesType
     * @param isRefundDeliveryFee
     * @return
     */
    private BaseResponse batchRefundOrderNoTake(SpellGroupBatchOrderRefundVo orderRefundVo, List<OrderBean> orderBeans, AfterSalesType afterSalesType, Boolean isRefundDeliveryFee) {
        if (CollectionUtils.isEmpty(orderBeans)) {
            return null;
        }
        long refundId = System.currentTimeMillis();
        String partnerId = orderRefundVo.getPartnerId();
        String storeId = orderRefundVo.getStoreId();
        // 退款批次号
        Long batchId = 0L;

        List<OrderBean> payRefundOrderCodes = new ArrayList<>(orderBeans.size());
        Set<String> unPayRefund = new HashSet<>(orderBeans.size());
        orderBeans.forEach(orderBean -> {
            // 金额为0不需要退款
            if (orderBean.getAmount() > 0) {
                payRefundOrderCodes.add(orderBean);
            } else {
                unPayRefund.add(orderBean.getOid());
            }
        });

        // 1 进行批量退款
        if (!payRefundOrderCodes.isEmpty()) {
            PayBatchRefundResponse response = null;
            try {
                // 1.1 组装批量退款参数
                BatchOrderRefundV2Request batchOrderRefundV2Request = orderAdapter.getBatchOrderRefundV2Request(payRefundOrderCodes, partnerId, storeId);
                // 1.2 调用支付服务退款
                response = mulitiPaymentClient.batchRefund(batchOrderRefundV2Request);
            } catch (Exception e) {
                log.error("拼团批量退款失败!!", e);
            }
            PayBatchRefundResponse.BatchRefundBatchIdData batchIdData;
            // 注意响应值是200
            if (Objects.isNull(response) || !Objects.equals(ResponseCodeConstant.PAYMENT_RESPONSE_SUCCESS, response.getCode())
                    || Objects.isNull(batchIdData = response.getData()) || Objects.isNull(batchIdData.getBatchId())) {
                return ResponseUtil.error(ResponseResult.ORDER__ERRORREFUND.getCode(), "批量退款失败");
            }
            // 获取退款批次号
            batchId = batchIdData.getBatchId();
        }

        // 2 循环退单
        List<OrderBean> failOrderBean = new ArrayList<>();
        String trackingNo = LogTreadLocal.getTrackingNo();
        for (OrderBean orderBean : orderBeans) {
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(),
                    partnerId, afterSalesType, orderRefundVo.getReason(), trackingNo, Long.toString(refundId));

            cancelOrderRequest.setOperator(Optional.ofNullable(cancelOrderRequest.getOperator()).orElse(orderBean.getUserName()));
            cancelOrderRequest.setPartnerId(orderBean.getCompanyId());
            // 增加拓展信息
            CancelOrderRequest.AfterSalesOrderExtInfoReq salesOrderExtInfoReq = new CancelOrderRequest.AfterSalesOrderExtInfoReq();
            salesOrderExtInfoReq.setRefundMode(orderRefundVo.getRefundMode());
            cancelOrderRequest.setExtInfoReq(salesOrderExtInfoReq);

            if (unPayRefund.contains(orderBean.getOid())) {
                // 无需退款
                cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.REFUND_COMPLETE.getCreateEvent());
            } else {
                // 记录退款批次
                cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.RETURN_COMPLETE.getCreateEvent());
                salesOrderExtInfoReq.setBatchRefundId(batchId);
                // todo 发生延时mq用于检查
            }
            cancelOrderRequest.setReqRemark(orderRefundVo.getRemarks());
            cancelOrderRequest.setRefundDeliveryAmount(isRefundDeliveryFee);
            boolean fail = true;
            try {
                BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderCancel(cancelOrderRequest);
                if (baseOrderResponse == null || baseOrderResponse.getData() == null || !ObjectUtils.equals(ResponseConstant.SUCCESS_RESPONSE_CODE, baseOrderResponse.getErrcode())) {
                    log.error("批量取消订单失败  订单号:{}",orderBean.getOid());
                }else {
                    fail = false;
                    // 删除订单 通知活动添加商品库存
                    backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus(), orderBean.getPayStatus());
                }
            }catch(Exception e){
                log.error("批量取消订单异常  订单号:{}",orderBean.getOid(),e);
            }
            // 记录失败
            if (fail){
                failOrderBean.add(orderBean);
            }
        }
        // todo 失败入库


        return ResponseUtil.success();
    }


    @Override
    public BaseResponse scoreRecord(QueryOrderVo queryOrderVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(queryOrderVo.getSessionId());
        if (userLoginInfoDto == null || StringUtils.isBlank(userLoginInfoDto.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        Date startDate;
        Date endDate;
        if (StringUtils.isBlank(queryOrderVo.getStartDate()) || StringUtils.isBlank(queryOrderVo.getEndDate())) {
            Date now = new Date();
            startDate = DateUtil.addMonths(now, -6);
            endDate = DateUtil.addDays(now, 1);
        } else {
            String startDateStr = queryOrderVo.getStartDate() + " 00:00:00";
            String endDateStr = queryOrderVo.getEndDate() + " 23:59:59";
            startDate = DateUtil.convert2Date(startDateStr, "yyyy-MM-dd HH:mm:ss");
            if (startDate == null) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单开始时间格式不正确");
            }
            endDate = DateUtil.convert2Date(endDateStr, "yyyy-MM-dd HH:mm:ss");
            if (endDate == null) {
                return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "查询订单结束时间格式不正确");
            }
        }

        OrderConditionsReq queryOrdersDto = new OrderConditionsReq();
        queryOrdersDto.setUserId(userLoginInfoDto.getMemberId());
        queryOrdersDto.setPartnerId(userLoginInfoDto.getPartnerId());
        queryOrdersDto.setPageSize(queryOrderVo.getPageSize() != null ? queryOrderVo.getPageSize() : 500);
        queryOrdersDto.setPageNum(queryOrderVo.getPageNumber() != null ? queryOrderVo.getPageNumber() : 1);
        queryOrdersDto.setStartTimestamp(startDate.getTime() / 1000);
        queryOrdersDto.setEndTimestamp(endDate.getTime() / 1000);
        queryOrdersDto.setOrderClients(Arrays.asList(OrderClientType.I_MEMBER.getIndex()));
        queryOrdersDto.setBizType(4);
        queryOrdersDto.setOrderStatus(OrderStatus.CALCEL.getCode());
//        queryOrdersDto.setPayStatuses(Arrays.asList(PayStatus.HAVE_PAID.getCode()));
        BaseDownLoadResponse<List<OrderInfoReqs>> response = orderDownLoadSdkService.queryOrderByConditions(queryOrdersDto, LogThreadLocal.getTrackingNo());

        List<ScoreRecordVo> result = new ArrayList<>();
        if (null == response || null == response.getResult()) {
            return ResponseUtil.success(result);
        }
        List<OrderInfoReqs> list = response.getResult();
        list.forEach(order -> {
            ScoreRecordVo responseVo = new ScoreRecordVo();
            responseVo.setOrderCode(order.getOrderCode());
            if (order.getCreateTime() != null) {
                responseVo.setCreateTime(Long.parseLong(order.getCreateTime()));
            }
            if (CollectionUtils.isNotEmpty(order.getOrderItemList())) {
                responseVo.setProductName(order.getOrderItemList().get(0).getProductName());
                responseVo.setProductQuantity(order.getOrderItemList().get(0).getProductQuantity());
            }
            result.add(responseVo);
        });
        return ResponseUtil.success(result);
    }


    @Override
    public BaseResponse<List<OrderCountResp>> selectCountOrdersByPartnerIds(OrderCountRequestVo orderCountRequestVo, String trackingNo) {
        OrderCountReqs orderCountReqs = new OrderCountReqs();
        BeanUtil.convertBean(orderCountRequestVo, orderCountReqs);

        com.freemud.application.sdk.api.ordercenter.response.BaseResponse<List<OrderCountResp>> result = orderSdkService.countOrdersByPartnerIds(orderCountReqs, trackingNo);
        LogUtil.info("remote /order/v2/orderCount  resp :",orderCountReqs, result);
        if (Objects.isNull(result)) {
            return new BaseResponse(ResponseResultEnum.SYSTEM_ERROR.getCode(), ResponseResultEnum.SYSTEM_ERROR.getMessage(), "", null);
        }
        if (!ResponseResultEnum.SUCCESS.getCode().equalsIgnoreCase(result.getCode()) || Objects.isNull(result.getResult())) {
            return new BaseResponse(result.getCode(), result.getMessage(), "", null);
        }
        return ResponseUtil.success(result.getResult());
    }

    @Override
    public BaseResponse<OrderStateMonitorInfoVo> queryOrderStateMonitorInfo(String orderCode, String partnerId, Byte orderClient) {
        BaseQueryOrderRequest request = new BaseQueryOrderRequest();
        request.setOrderId(orderCode);
        request.setPartnerId(partnerId);
        if (Objects.nonNull(orderClient) && !Objects.equals(orderClient, 0)) {
            request.setOrderClient(orderClient.toString());
        }
        // 实时查询，暂时不查询es
        OrderStateInfoResp response = orderCenterSdkService.queryOrderStateInfo(orderCode, partnerId, orderClient, LogThreadLocal.getTrackingNo());
        if (Objects.isNull(response) || !Objects.equals(RESPONSE_SUCCESS_CODE, response.getErrcode()) || response.getData() == null) {
            LogUtil.info("订单详情实时查询错误，queryOrderStateInfoResp，", response, "");
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        OrderStateMonitorInfoVo infoVo = new OrderStateMonitorInfoVo();
        infoVo.setOrderCode(response.getData().getOrderCode());
        infoVo.setOrderState(response.getData().getOrderState());
        infoVo.setStateTimeout(response.getData().getStateTimeout());
        infoVo.setNeedMonitor(Objects.equals(response.getData().getStateTimeout(), 0L));
        infoVo.setUpdateTimestamp(response.getData().getStateUpdateTimestamp());


        return ResponseUtil.success(infoVo);
    }


}
