package cn.freemud.service.impl;

import cn.freemud.adapter.DeliveryAdapter;
import cn.freemud.adapter.LightApplicationConvertToAssortmentSdkAdapter;
import cn.freemud.adapter.OrderAdapter;
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.base.util.JsonUtil;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.PayAccessResponse;
import cn.freemud.entities.dto.ecology.VirtualBindStoreResponse;
import cn.freemud.entities.dto.ecology.VirtualStoreRequest;
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.promotion.GroupWorkJoinResponse;
import cn.freemud.entities.dto.shoppingCart.NewShoppingCartClearDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.wechat.GetAuthorizerRequestDto;
import cn.freemud.entities.dto.wechat.GetTokenResponseDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.manager.SpellGroupOrderDataManager;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.BuriedPointService;
import cn.freemud.service.CouponActivityService;
import cn.freemud.service.MallOrderService;
import cn.freemud.service.business.OrderBusinessService;
import cn.freemud.service.thirdparty.EcologyAdminApplicationClient;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import cn.freemud.utils.LogUtil;
import cn.freemud.utils.RedisUtil;
import cn.freemud.utils.ResponseUtil;
import cn.freemud.utils.ValidationCode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformWxapp;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformWxappManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.constant.ResponseConstant;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.deliverycenter.dto.ArriveDeliveryRequestDto;
import com.freemud.application.sdk.api.deliverycenter.dto.CreateDeliveryOrderRequestDto;
import com.freemud.application.sdk.api.deliverycenter.response.CreateDeliveryOrderResponseDto;
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.LogThreadLocal;
import com.freemud.application.sdk.api.log.ThirdPartyLog;
import com.freemud.application.sdk.api.ordercenter.enums.*;
import com.freemud.application.sdk.api.ordercenter.request.OrderChangeStateReq;
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.POSOrderOperationBaseReq;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.AfterSalesOrderResp;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.*;
import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse;
import 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.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MallOrderServiceImpl implements MallOrderService {

    private final Integer RESPONSE_SUCCESS_CODE = 100;

    private static Gson gson = new Gson();

    @Value("${saas.reverseNotifyiDcUrl}")
    private String reverseNotifyiDcUrl;

    @Value("${saas.delivery.mall.callback.notifyUrl}")
    private String deliveryNotifyUrl;

    @Autowired
    private CheckMallOrder checkMallOrder;
    @Autowired
    private CheckOrder checkOrder;
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private OrderAdapter orderAdapter;
    @Autowired
    private ItemServiceImpl itemService;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private StandardPaymentService standardPaymentService;
    @Autowired
    private DeliveryAdapter deliveryAdapter;
    @Autowired
    private DeliveryService deliveryService;
    @Autowired
    private OrderSdkService orderSdkService;
    @Autowired
    private EcologyAdminApplicationClient ecologyAdminApplicationClient;
    @Autowired
    private OrderSdkAdapter orderSdkAdapter;

    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;

    @Value("${program.backorders_change_order_status_consumer_queue}")
    private String backOrdersChangeOrderStatusConsumerQueue;
    @Value("${program.backorders_notify_activity_exchange}")
    private String backOrdersNotifyActivityExchange;
    @Autowired
    private CouponActivityService couponActivityService;

    @Autowired
    private AssortmentCustomerInfoManager assortmentCustomerInfoManager;
    @Autowired
    private PaymentQueueService paymentQueueService;
    @Autowired
    private OrderBusinessService orderBusinessService;
    /**
     * 创建订单
     */
    @Override
    public BaseResponse createOrder(CreateOrderVo createOrderVo) {
        BaseResponse baseResponse = this.checkParamInfo(createOrderVo);
        if(ObjectUtils.notEqual(baseResponse.getCode(),ResponseResult.SUCCESS.getCode())){
            return baseResponse;
        }

        String trackingNo = LogThreadLocal.getTrackingNo();
        // 查询用户信息、校验svc卡,余额购物车校验
        AssortmentCustomerInfoVo userLoginInfoDto = checkMallOrder.checkOrderByMember(createOrderVo);
        // 设置门店id为商城的虚拟门店id
        this.change2BindMallShopId(createOrderVo, userLoginInfoDto.getWxAppId());
        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内 点餐桌号
        StoreResponse.BizVO storeResponseDto = checkMallOrder.checkOrderByStore(createOrderVo, trackingNo);
        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数
        ShoppingCartGoodsDto shoppingCartGoodsDto = checkMallOrder.getShoppingCartGoodsDto(createOrderVo);
        // 查询商城的配送模板信息，校验订单是否满足配送条件
        checkMallOrder.checkOrderByDelivery(createOrderVo, userLoginInfoDto, storeResponseDto, shoppingCartGoodsDto.getTotalAmount(), trackingNo);
        OrderExtInfoDto extInfo = this.getExtInfo(userLoginInfoDto, storeResponseDto, createOrderVo);
        return this.sdkCreateOrder(createOrderVo, storeResponseDto, shoppingCartGoodsDto, userLoginInfoDto, extInfo);
    }

    /**
     * 订单确认完成
     */
    @Override
    public BaseResponse orderAffirm(OrderAffirmRequestVO requestVO) {
        String trackingNo = LogTreadLocal.getTrackingNo();

        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(requestVO.getOid());
        baseQueryOrderRequest.setTrackingNo(trackingNo);
        QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        // 判断订单信息是否存在
        BaseResponse baseResponse = this.checkOrder(response, requestVO.getPartnerId());
        if (baseResponse != null) {
            return baseResponse;
        }
        QueryOrdersResponse.DataBean.OrderBean orderBean = response.getData();
        //判断订单是否已经完成
        if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_REPEAT_DO_COMPLETE);
        }
        //已取消的订单不能操作
        if (OrderStatus.CALCEL.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED);
        }
        //非商城订单不允许操作
        if(!OrderSourceType.SAASMALL.getCode().equals(orderBean.getSource())) {
            return ResponseUtil.error(ResponseResult.ORDER_MALL_NOT_MATCH);
        }

        /**
         * 修改配送状态
         */
        if(orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getDeliveryId())) {
            UpdateDeliveryInfoByIdRequest updateDeliveryInfoByIdRequest = new UpdateDeliveryInfoByIdRequest();
            updateDeliveryInfoByIdRequest.setOrderId(orderBean.getOid());
            updateDeliveryInfoByIdRequest.setOrderSubState(DeliveryStatus.DELIVERYARRIVED.getCode());
            orderCenterSdkService.updateDeliveryInfoById(updateDeliveryInfoByIdRequest);
        }

        /**
         * 配送完成
         */
        POSOrderOperationBaseReq prepareCompleteDeliveryReq = new POSOrderOperationBaseReq();
        prepareCompleteDeliveryReq.setOrderCode(orderBean.getOid());
        orderSdkService.prepareCompleteDelivery(prepareCompleteDeliveryReq, trackingNo);

        /**
         * 调用物流运单完成
         */
        if(orderBean.getAddInfo() != null && StringUtils.isNotEmpty(orderBean.getAddInfo().getDeliveryId())) {
            ArriveDeliveryRequestDto arriveDeliveryRequestDto = new ArriveDeliveryRequestDto();
            arriveDeliveryRequestDto.setDeliveryId(orderBean.getAddInfo().getDeliveryId());
            deliveryService.deliveryFinish(arriveDeliveryRequestDto, trackingNo);
        }

        return ResponseUtil.success();
    }

    private BaseResponse checkParamInfo(CreateOrderVo createOrderVo){
        if(StringUtils.isEmpty(createOrderVo.getSessionId())){
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_SESSION_ERROR);
        }
        return ResponseUtil.success();
    }

    private void change2BindMallShopId(CreateOrderVo createOrderVo, String wxAppId) {
        VirtualStoreRequest virtualStoreRequest = new VirtualStoreRequest();
        virtualStoreRequest.setPlatformAppId(wxAppId);
        virtualStoreRequest.setType("microMall");
        BaseResponse<VirtualBindStoreResponse> virtualBindStoreResponse = ecologyAdminApplicationClient.getBuyBindVirtualStore(virtualStoreRequest);
        if(virtualBindStoreResponse == null || virtualBindStoreResponse.getResult() == null || StringUtils.isBlank(virtualBindStoreResponse.getResult().getStoreId())) {
            throw new ServiceException(ResponseResult.STORE_BIND_MALL_NOT_FOUND);
        }
        createOrderVo.setShopId(virtualBindStoreResponse.getResult().getStoreId());
    }

    private OrderExtInfoDto getExtInfo(AssortmentCustomerInfoVo userLoginInfoDto, StoreResponse.BizVO storeResponseDto, CreateOrderVo createOrderVo) {
        String sessionId = createOrderVo.getSessionId();
        String version = createOrderVo.getVersion();

        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(sessionId);
        orderExtInfoDto.setVersion(version);
        orderExtInfoDto.setProvince(createOrderVo.getProvince());
        return orderExtInfoDto;
    }

    private BaseResponse sdkCreateOrder(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto, AssortmentCustomerInfoVo userLoginInfoDto, OrderExtInfoDto orderExtInfoDTO) {
        OrderExtendedReq orderExtendedReq = orderAdapter.saveStoreInfo(storeResponseDto);
        //创建普通订单
        Function<Object, CreateOrderResponse> createOrder = (var -> {
            BaseCreateOrderRequest baseCreateOrderRequest = orderAdapter.convent2CreateOrderDto(createOrderVo, shoppingCartGoodsDto,storeResponseDto);
            //查询第三方商品编号
            baseCreateOrderRequest = getProductCustomerCode(baseCreateOrderRequest);
            //保存门店渠道信息
            baseCreateOrderRequest.setOrderExtended(orderExtendedReq);
            baseCreateOrderRequest.setOrderClient(OrderClientType.SAASMALL);
            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.getBaseCreateOrderRequest().setUserName(userLoginInfoDto.getNickName());
            createOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
            return orderCenterSdkService.createOrderFlow(createOrderRequest);
        });

        //普通订单
        CreateOrderResponse createOrderFlowResponse = createOrder.apply(null);
        if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createOrderFlowResponse.getErrcode())) {
            return ResponseUtil.error(createOrderFlowResponse.getErrcode().toString(), createOrderFlowResponse.getErrmsg());
        }
        QueryOrdersResponse.DataBean.OrderBean orderBean = createOrderFlowResponse.getData();
        long totalAmount = orderBean.getAmount();

        //<!---创建订单公共方法执行逻辑--->
        OrderPayResponse orderPayResponse = null;
        PaymentRequest paymentRequest = orderBodyConvertToPaymentBody(userLoginInfoDto, createOrderVo.getPartnerId());
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else if(totalAmount > 0) {
            orderPayResponse = getPreOrderPay(orderBean, paymentRequest, LogThreadLocal.getTrackingNo(), 0);
        } else {
            // 0元订单如果不需要支付，自定义支付单号
            orderPayResponse = getOrderPayResponse(paymentRequest, orderBean);
        }
        if (orderPayResponse == null) {
            return failPreOrderPay(LogThreadLocal.getTrackingNo(), orderBean, createOrderVo.getCardCode());
        }
        CreateOrderResponseVo createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, orderBean);
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, orderExtInfoDTO, orderBean, LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        if (totalAmount > 0 && StringUtils.isBlank(createOrderVo.getCardCode())) {
            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);
            message.setSource(PaySuccessSource.OUTSIDE.getSource());
            this.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }

    }

    private PaymentRequest orderBodyConvertToPaymentBody(AssortmentCustomerInfoVo userLoginInfoDto, String partnerId) {
        String wxAppId = userLoginInfoDto.getWxAppId();
        //设置支付信息
        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setOpenId(userLoginInfoDto.getOpenId());
        paymentRequest.setWxAppId(wxAppId);
        AssortmentOpenPlatformWxapp wxApp = openPlatformWxappManager.findByPartnerIdAndWxappId(partnerId, wxAppId);
        paymentRequest.setPrincipalName(StringUtils.defaultString(wxApp.getPrincipalName(), "上海非码网络科技有限公司"));
        paymentRequest.setReverseNotifyiDcUrl(reverseNotifyiDcUrl);
        return paymentRequest;
    }

    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) {
        //失败冲正库存，冲正活动库存，取消订单
        CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                AfterSalesType.SYSTEM_CANCEL, "获取预支付失败", trackingNo, null);
        orderCenterSdkService.orderCancel(cancelOrderRequest);
        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) {
        try {
            OrderPayResponse orderPayResponse;
            UnifiedOrderRequest request = orderAdapter.convent2UnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, orderBean.getOid());
            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());
                return orderPayResponse;
            }
            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());
            }
            putDelMq(request.getPartnerId(), request.getStoreId(), responseBase.getData().getFmId(), orderBean.getOid());
            return orderPayResponse;
        } catch (Exception e) {
            LogUtil.error("getPreOrderPay_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(paymentRequest));
            //TODO 邮件告警
            return null;
        }
    }

    /**
     * 编辑订单，保持预支付信息
     */
    public BaseResponse updateOrderInfo(OrderPayResponse orderPayResponse, OrderExtInfoDto orderExtInfo
            , QueryOrdersResponse.DataBean.OrderBean orderBean, String trackingNo) {
//        orderExtInfo = orderAdapter.getOrderExtInfo(orderPayResponse, orderExtInfo);
        orderExtInfo.setOpenid(orderPayResponse.getOpenId());
        String prepayId = "";
        // StringUtils 依赖修改
        if (orderPayResponse.getPayOrder() != null && !StringUtils.isEmpty(orderPayResponse.getPayOrder().getPackageX())) {
            String[] prepayIds = orderPayResponse.getPayOrder().getPackageX().split("=");
            prepayId = prepayIds.length > 1 ? prepayIds[1] : "";
        }
        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());
        }
        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);
            return ResponseUtil.error(baseOrderResponse.getErrcode().toString(), baseOrderResponse.getErrmsg());
        }

        return null;
    }

    public String paySuccessCallback(PaysuccessNoticeMessage message) {
        ConfirmOrderDto confirmOrderDto = orderAdapter.convent2ConfirmOrderDto(message);
        Map<String, QueryOrdersResponseDto.DataBean.OrderBean> orderBeans = getOrderBeanByOrderId(confirmOrderDto.getOrderId());
        return this.paySuccessCallback(message, confirmOrderDto, orderBeans);
    }

    @Autowired
    private MQService mqService;

    @Autowired
    private SpellGroupOrderDataManager spellGroupOrderDataManager;

    @Override
    public String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, QueryOrdersResponseDto.DataBean.OrderBean> orderBeans) {
        QueryOrdersResponseDto.DataBean.OrderBean orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());

        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 = "";
        if (StringUtils.isNotBlank(extInfo)) {
            orderExtInfoDto = gson.fromJson(extInfo, OrderExtInfoDto.class);
            if (orderExtInfoDto != null) {
                wxappid = orderExtInfoDto.getAppid();
                sessionId = orderExtInfoDto.getSessionId();
            }
        }
        // 如果订单状态不是未支付，返回信息
        if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()) || !OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
            return sendPaySuccessNoticeMessage();
        }

        // 订单失败后 发消息重试 待实现
        PayAccessResponse payAccessResponse;
        ConfirmOrderRequest confirmOrderRequest = LightApplicationConvertToAssortmentSdkAdapter.confirmOrderDtoConvertToConfirmOrderRequest(confirmOrderDto, null);
        confirmOrderRequest.setPartnerId(partnerId);
        confirmOrderRequest.setStoreId(storeId);
        confirmOrderRequest.setOrderId(orderBean.getOid());
        confirmOrderRequest.setOrderType(orderBean.getType());
        confirmOrderRequest.setProductOrderCode(orderBean.getOid());

        List<String> orderIds = new ArrayList<>();
        //拼单调促销开团
        if(OrderMarketType.GROUPB.getIndex() == orderBean.getMarketingType()){
            AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(sessionId);
            GroupWorkJoinResponse groupWorkJoinResponse = spellGroupOrderDataManager.groupWorkJoin(orderBean,userLoginInfoDto,wxappid);
            if(!ResponseResult.SUCCESS.getCode().equals(groupWorkJoinResponse.getStatusCode()) || groupWorkJoinResponse.getResult() == null){
                orderRefund(orderBean, groupWorkJoinResponse.getMsg());
                backOrdersNotifyActivity(orderBean, backOrdersChangeOrderStatusConsumerQueue, backOrdersNotifyActivityExchange);
                return gson.toJson(message);
            }

            if("2".equals(groupWorkJoinResponse.getResult().getGroupStatus())){
                orderRefund(orderBean, "成团失败,退款流程");
                backOrdersNotifyActivity(orderBean, backOrdersChangeOrderStatusConsumerQueue, backOrdersNotifyActivityExchange);
                return gson.toJson(message);
            }
            if(StringUtils.isEmpty(orderBean.getSpellGroupCode())){
                confirmOrderRequest.setSpellGroupCode(groupWorkJoinResponse.getResult().getGroupId());
            }
            //表示已成团，团下面订单全部接单
            if("1".equals(groupWorkJoinResponse.getResult().getGroupStatus())){
                orderIds = groupWorkJoinResponse.getResult().getOrderIds();
            }

        }
        // 订单支付成功
        com.freemud.sdk.api.assortment.order.response.order.PayAccessResponse payAccessRes = orderBusinessService.payAccess(confirmOrderRequest);
        String string2 = JSONObject.toJSONString(payAccessRes);
        JSONObject jsonObject2 = JSONObject.parseObject(string2);
        payAccessResponse = jsonObject2.toJavaObject(PayAccessResponse.class);
        // 添加幂等处理，若订单是已支付成功状态，直接返回成功
        if (!RESPONSE_SUCCESS_CODE.equals(payAccessResponse.getErrcode())) {
            QueryOrdersResponseDto.DataBean.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));
            return gson.toJson(message);
        }

        // 订单扩展信息
        if (orderExtInfoDto != null) {
            orderExtInfoDto.setPayDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
            orderExtInfoDto.setPayTransId(message.getOut_trade_no());
            OrderEditDto orderEditDto = new OrderEditDto(orderBean.getOid(), gson.toJson(orderExtInfoDto));
            OrderEditRequest orderEditRequest = new OrderEditRequest(orderEditDto.getOrderId(), orderEditDto.getExtInfo());
            orderEditRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
            orderCenterSdkService.orderEdit(orderEditRequest);
        }

        // 清空购物车
        NewShoppingCartClearDto newShoppingCartClearDto = new NewShoppingCartClearDto();
        newShoppingCartClearDto.setPartnerId(partnerId);
        newShoppingCartClearDto.setShopId(storeId);
        newShoppingCartClearDto.setUserId(userId);
        newShoppingCartClearDto.setAppId(wxappid);
        newShoppingCartClearDto.setSessionId(sessionId);
        newShoppingCartClearDto.setOperationType(1);
        newShoppingCartClearDto.setChannelType(OrderChannelType.SAASMALL.getCode());
        shoppingCartClient.clearShoppingCart(newShoppingCartClearDto);

        // 埋点支付行为
        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);

        //支付回掉成功标记
        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())) {
            log.info("微商城调用券码核销==" + message.getTrans_id());
            verificationCoupon(message.getTrans_id());
            log.info("微商城调用券码结束==" + message.getTrans_id());
        }

        orderIds.add(orderBean.getOid());
        orderIds = orderIds.stream().distinct().collect(Collectors.toList());
        //接单

        if(orderIds.size() > 1 || orderBean.getMarketingType() != OrderMarketType.GROUPB.getIndex()){
            POSOrderOperationBaseReq acceptOrderReq = new POSOrderOperationBaseReq();
            for(String orderId : orderIds){
                acceptOrderReq.setOrderCode(orderId);
                try {
                    com.freemud.application.sdk.api.ordercenter.response.BaseResponse baseResponse = orderSdkService.acceptOrder(acceptOrderReq, LogTreadLocal.getTrackingNo());
                    if(baseResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(baseResponse.getCode())) {
                        LogUtil.error("paySuccessCallback_acceptOrder_faild", gson.toJson(confirmOrderDto), gson.toJson(payAccessResponse));
                    }
                }catch (Exception e){
                    LogUtil.error("paySuccessCallback_acceptOrder_error",orderId,e);
                }
            }
        }
        return sendPaySuccessNoticeMessage();
    }

    private Map<String, QueryOrdersResponseDto.DataBean.OrderBean> getOrderBeanByOrderId(String orderId) {
        // 订单查询：若结果集只有一个orderBean，则为普通订单，否则为会员卡订单（父子订单）
        Map<String, QueryOrdersResponseDto.DataBean.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<QueryOrdersResponseDto.DataBean.OrderBean> saasOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            List<QueryOrdersResponseDto.DataBean.OrderBean> memberOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(3) && !order.isParent()).collect(Collectors.toList());
            List<QueryOrdersResponseDto.DataBean.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 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;
    }

    private 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, QueryOrdersResponseDto.DataBean.OrderBean.class));
        return queryOrderByIdResponseDto;
    }

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

    /**
     * 异常状态退款流程
     */
    public void orderRefund(QueryOrdersResponseDto.DataBean.OrderBean orderBean, String refundReason) {
        OrderRefundVo orderRefundVo = new OrderRefundVo();
        orderRefundVo.setOid(orderBean.getOid());
        orderRefundVo.setPartnerId(orderBean.getCompanyId());
        orderRefundVo.setReason(refundReason);
        partnerNoTakeOrder(orderRefundVo, orderBean, orderBean.getOid());
    }


    private void backOrdersNotifyActivity(QueryOrdersResponseDto.DataBean.OrderBean orderBean, String backOrdersChangeOrderStatusConsumerQueue, String backOrdersNotifyActivityExchange) {
        if (null == orderBean || backOrdersChangeOrderStatusConsumerQueue == null || backOrdersNotifyActivityExchange == null) {
            return;
        }
        String oid = orderBean.getOid();
        Integer status = orderBean.getStatus();
        if (StringUtils.isEmpty(oid)) {
            return;
        }
        ApiLog.info("backOrdersStatusChange", oid, String.valueOf(status));
        OrderStatusChangeRequestDto requestDto = new OrderStatusChangeRequestDto();
        requestDto.setOid(oid);
        requestDto.setOrderStatus(status);
        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) {
            //TODO 邮件告警
            ThirdPartyLog.infoConvertJson(System.currentTimeMillis(), System.currentTimeMillis(),
                    "backOrdersStatusChangeNotify_error", backOrdersNotifyActivityExchange, backOrdersChangeOrderStatusConsumerQueue);
        }
    }

    /**
     * 商家未接单,取消订单逻辑处理    1.调用支付退款 2.根据支付退款返回状态组装订单取消参数,调用订单取消接口
     *
     * @param orderRefundVo
     * @param orderBean
     */
    private BaseResponse partnerNoTakeOrder(OrderRefundVo orderRefundVo, QueryOrdersResponseDto.DataBean.OrderBean orderBean, String fatherOrderId) {
        com.freemud.application.sdk.api.base.BaseResponse<OrderRefundResponse> response = null;
        Long refundId = System.currentTimeMillis();
        String partnerId = orderBean.getCompanyId();
        int state = PayRefundStatus.SUCCESS.getCode();
        if (orderBean.getAmount() != 0) {
            //调用支付退款
            com.freemud.sdk.api.assortment.payment.request.OrderRefundRequest orderPayRefundRequest = orderAdapter.getOrderPayRefundRequest(orderBean, refundId, fatherOrderId);
            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.USER_CANCEL, orderRefundVo.getReason(), LogTreadLocal.getTrackingNo(), refundId.toString());
        cancelOrderRequest.setPartnerId(orderBean.getCompanyId());
        if (PayRefundStatus.RUNNING.getCode().intValue() == state) {
            // 退款中
            cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.RETURN_COMPLETE.getCreateEvent());
        } else if (PayRefundStatus.SUCCESS.getCode().intValue() == state) {
            //退款成功
            cancelOrderRequest.setCreateEvent(AfterSalesOrderCreateEventEnum.REFUND_COMPLETE.getCreateEvent());
        }
        cancelOrderRequest.setReqRemark(orderRefundVo.getRemarks());
        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;
    }


    /**
     * 创建配送
     */
    private boolean createDelivery(QueryOrdersResponseDto.DataBean.OrderBean orderBean, String trackingNo){
        try {
            // 获取门店信息
            StoreResponse storeResponse = checkOrder.getStoreInfo(orderBean.getCompanyId(), orderBean.getShopId(), trackingNo);
            if (storeResponse == null || storeResponse.getBizVO() == null) {
                LogUtil.info(trackingNo, "createDelivery getStoreInfo fail", orderBean.getShopId(), gson.toJson(storeResponse));
                return false;
            }
            OrderExtInfoDto orderExtInfoDto = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class) == null ? new OrderExtInfoDto() : JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);

            GetAuthorizerRequestDto getAuthorizerRequestDto = new GetAuthorizerRequestDto();
            getAuthorizerRequestDto.setPartnerId(orderBean.getCompanyId());
            getAuthorizerRequestDto.setAuthorizerAppid(orderExtInfoDto.getAppid());
            GetTokenResponseDto getTokenResponseDto = ecologyAdminApplicationClient.getAuthorizerAccessToken(getAuthorizerRequestDto);
            if(getTokenResponseDto == null || getTokenResponseDto.getResult() == null || StringUtils.isBlank(getTokenResponseDto.getResult().getAccessToken())) {
                LogUtil.info(trackingNo, "createDelivery getToken fail", gson.toJson(getAuthorizerRequestDto), gson.toJson(getTokenResponseDto));
                return false;
            }
            String accessToken = getTokenResponseDto.getResult().getAccessToken();
            CreateDeliveryOrderRequestDto createDeliveryOrderRequestDto = deliveryAdapter.convertToWeixinDeliveryOrderRequestDto(orderBean, storeResponse, accessToken, deliveryNotifyUrl);
            CreateDeliveryOrderResponseDto createDeliveryOrderResponseDto = deliveryService.deliveryOrderAdd(createDeliveryOrderRequestDto, trackingNo);
            /**
             * 创建配送单失败
             */
            if (createDeliveryOrderResponseDto == null || ResponseCodeConstant.RESPONSE_SUCCESS != createDeliveryOrderResponseDto.getCode() || createDeliveryOrderResponseDto.getData() == null) {
                LogUtil.info(trackingNo, "createDelivery deliveryOrderAdd fail", gson.toJson(createDeliveryOrderRequestDto), gson.toJson(createDeliveryOrderResponseDto));
                return false;
            }
            String deliveryId = createDeliveryOrderResponseDto.getData().getDeliveryId();
            DeliveryResponseDto<DeliveryInfoDto> dtoDeliveryResponse = deliveryService.deliveryOrderOne(deliveryId, trackingNo);
            /**
             * 运单查询失败
             */
            if (dtoDeliveryResponse == null || ResponseCodeConstant.RESPONSE_SUCCESS != dtoDeliveryResponse.getCode() || dtoDeliveryResponse.getData() == null) {
                LogUtil.info(trackingNo, "createDelivery deliveryOrderOne fail", deliveryId, gson.toJson(dtoDeliveryResponse));
                return false;
            }
            DeliveryInfoDto deliveryInfoDto = dtoDeliveryResponse.getData();
            /**
             * 更新配送信息
             */
            UpdateDeliveryInfoByIdRequest updateDeliveryInfoByIdRequest = new UpdateDeliveryInfoByIdRequest();
            updateDeliveryInfoByIdRequest.setDeliveryId(deliveryInfoDto.getDeliveryId());
            updateDeliveryInfoByIdRequest.setOrderId(orderBean.getOid());
            updateDeliveryInfoByIdRequest.setExpressChannelCode(deliveryInfoDto.getCompanyId());
            updateDeliveryInfoByIdRequest.setExpressChannelName(deliveryInfoDto.getRemark());
            updateDeliveryInfoByIdRequest.setExpress(deliveryInfoDto.getCompanyId());
            updateDeliveryInfoByIdRequest.setExpressNo(deliveryInfoDto.getChannelDeliveryId());
            updateDeliveryInfoByIdRequest.setOrderSubState(DeliveryStatus.RIDERSTARTDELIVERY.getCode());
            orderCenterSdkService.updateDeliveryInfoById(updateDeliveryInfoByIdRequest);

            /**
             * 更新订单状态配送中
             */
            POSOrderOperationBaseReq directDeliveryReq = new POSOrderOperationBaseReq();
            directDeliveryReq.setOrderCode(orderBean.getOid());
            orderSdkService.directDelivery(directDeliveryReq, trackingNo);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.info(trackingNo, "createDelivery exception", gson.toJson(orderBean), Throwables.getStackTraceAsString(e));
            return false;
        }
    }

    private BaseResponse checkOrder(QueryOrderByIdResponse response, String partnerId) {
        if (!RESPONSE_SUCCESS_CODE.equals(response.getErrcode()) || response.getData() == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR);
        }
        if (partnerId != null && !partnerId.equals(response.getData().getCompanyId())) {
            return ResponseUtil.error(ResponseResult.ORDER_PARTNER_ID_NOT_MATCTH);
        }
        return null;
    }

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

        List<com.freemud.sdk.api.assortment.order.vo.ProductGroupVo> targetGroupList = Lists.newArrayList();
        for (ProductGroup productGroup : productGroupList) {
            for (GroupDetail groupDetail : productGroup.getGroupDetail()) {
                com.freemud.sdk.api.assortment.order.vo.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;
    }

    @Override
    public BaseResponse saveAfterSalesExpress(EditAfterSalesExpressVo editAfterSalesExpressVo) {
        AssortmentCustomerInfoVo userInfo = customerInfoManager.getCustomerInfoByObject(editAfterSalesExpressVo.getSessionId());
        if (userInfo == null || StringUtils.isEmpty(userInfo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }

        BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
        baseQueryOrderRequest.setOrderId(editAfterSalesExpressVo.getOid());
        baseQueryOrderRequest.setTrackingNo(LogTreadLocal.getTrackingNo());
        QueryOrderByIdResponse queryOrderByIdResponse = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
        QueryOrdersResponse.DataBean.OrderBean orderBean;
        if (queryOrderByIdResponse == null || !RESPONSE_SUCCESS_CODE.equals(queryOrderByIdResponse.getErrcode()) || (orderBean = queryOrderByIdResponse.getData()) == null) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "订单信息不存在");
        }
        // 检查参数
        BaseResponse response = checkAfterSalesExpress(orderBean, userInfo.getMemberId());
        if (!Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, response.getCode())) {
            return response;
        }

        // 配送中,完成状态的，用户可填写
        List<Integer> enableRefundExpressCodes = Arrays.asList(OrderStatus.DISTRIBUTION.getCode(), OrderStatus.COMPLETE.getCode());
        if (enableRefundExpressCodes.contains(orderBean.getStatus()) && PayStatus.HAVE_PAID.getCode().equals(orderBean.getPayStatus())) {
            EditAfterSalesExpressRequest editAfterSalesExpressRequest = new EditAfterSalesExpressRequest();
            editAfterSalesExpressRequest.setPartnerId(orderBean.getCompanyId());
            editAfterSalesExpressRequest.setStoreId(orderBean.getShopId());
            editAfterSalesExpressRequest.setOrderId(orderBean.getOid());
            editAfterSalesExpressRequest.setOrderClient(orderAdapter.getNewOrderClient(orderBean.getSource()));
            editAfterSalesExpressRequest.setExpressNo(editAfterSalesExpressVo.getExpressNo());
            editAfterSalesExpressRequest.setExpressChannelName(editAfterSalesExpressVo.getExpressChannelName());
            editAfterSalesExpressRequest.setAfterSalesCode(orderBean.getAfterSalesOrderResp().getAfterSalesCode());
            editAfterSalesExpressRequest.setOperator(userInfo.getNickName());
            BaseOrderResponse baseResponseDto = orderCenterSdkService.editAfterSalesExpress(editAfterSalesExpressRequest);

            if (!RESPONSE_SUCCESS_CODE.equals(baseResponseDto.getErrcode())) {
                return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR);
            }
        }
        return ResponseUtil.success();
    }

    private BaseResponse checkAfterSalesExpress(QueryOrdersResponse.DataBean.OrderBean orderBean, String userId) {

        if (!Objects.equals(userId, orderBean.getUserId())) {
            return ResponseUtil.error(ResponseResult.ORDER_QUERYORDER_ERROR.getCode(), "不能操作非本人的订单");
        }

        // 必须微商城订单
        if (!OrderSourceType.SAASMALL.getCode().equalsIgnoreCase(orderBean.getSource())) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR.getCode(), "非商城订单不可填写");
        }
        // 检查售后单的状态
        AfterSalesOrderResp afterSalesOrderResp = orderBean.getAfterSalesOrderResp();
        if (afterSalesOrderResp == null) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR.getCode(), "售后单不存在");
        }
        if (Objects.equals(AfterSalesStatus.PENDING.getIndex(), afterSalesOrderResp.getAfterSalesStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR.getCode(), "商家正在处理中，请稍后……");
        }
        if (!Objects.equals(AfterSalesStatus.RETURNING.getIndex(), afterSalesOrderResp.getAfterSalesStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR.getCode(), "未找到有效的售后单");
        }

        // 是否为 退款退货方式
        CancelOrderRequest.AfterSalesOrderExtInfoReq afterSalesOrderExtInfoVo = getAfterSalesOrderExtInfoVo(afterSalesOrderResp);
        log.debug("售后单信息方式为:{}", afterSalesOrderResp);
        if (Objects.isNull(afterSalesOrderExtInfoVo) || !Objects.equals(RefundModeEnum.REFUND_ALL.getIndex(), afterSalesOrderExtInfoVo.getRefundMode())) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_EXPRESS_ERROR.getCode(), "当前退款方式无需填写");
        }

        return ResponseUtil.success();
    }



    private  CancelOrderRequest.AfterSalesOrderExtInfoReq getAfterSalesOrderExtInfoVo(AfterSalesOrderResp afterSalesOrderResp) {
        if (afterSalesOrderResp == null) {
            return null;
        }
        CancelOrderRequest.AfterSalesOrderExtInfoReq afterSalesOrderExtInfoVo = null;
        try {
            afterSalesOrderExtInfoVo = JSON.parseObject(afterSalesOrderResp.getExtInfo(), new com.alibaba.fastjson.TypeReference< CancelOrderRequest.AfterSalesOrderExtInfoReq>() {
            }.getType());
        } catch (Exception e) {
            log.error("解析售后单 extInfo 失败");
        }
        return afterSalesOrderExtInfoVo;
    }

    private String verificationCoupon(String transId) {
        String orderId = redisCache.getValue(RedisUtil.getPaymentTransIdOrderKey(transId));
        log.info("mallOrderService verificationCoupon,trackingNo:{},transId:{},orderId:{}", LogTreadLocal.getTrackingNo(), transId, orderId);
        if (StringUtils.isNotBlank(orderId)) {
            log.info("mallOrderService从缓存中获取的订单数据,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("mallOrderService order query fail" + queryOrderByIdResponseDto);
        }
        QueryOrdersResponseDto.DataBean.OrderBean orderBean = new QueryOrdersResponseDto.DataBean.OrderBean();
        if (1 == queryOrderByIdResponseDto.getData().size()) {
            orderBean = queryOrderByIdResponseDto.getData().get(0);
        } else {
            List<QueryOrdersResponseDto.DataBean.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();
    }

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

    /**
     * 订单确认收货
     */
    @Override
    public BaseResponse orderReceive(OrderReceiveRequestVO requestVO) {
        BaseResponse result = new BaseResponse();
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = assortmentCustomerInfoManager.getCustomerInfoByObject(requestVO.getSessionId());
        if (assortmentCustomerInfoVo == null || StringUtils.isEmpty(assortmentCustomerInfoVo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }

        try {
            String trackingNo = LogTreadLocal.getTrackingNo();

            BaseQueryOrderRequest baseQueryOrderRequest = new BaseQueryOrderRequest();
            baseQueryOrderRequest.setOrderId(requestVO.getOid());
            baseQueryOrderRequest.setTrackingNo(trackingNo);
            QueryOrderByIdResponse response = orderCenterSdkService.queryOrderById(baseQueryOrderRequest);
            // 判断订单信息是否存在
            BaseResponse baseResponse = this.checkOrder(response, requestVO.getPartnerId());
            if (baseResponse != null) {
                return baseResponse;
            }
            QueryOrdersResponse.DataBean.OrderBean orderBean = response.getData();
            //判断订单是否已经完成
            if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
                return ResponseUtil.error(ResponseResult.ORDER_REPEAT_DO_COMPLETE);
            }
            //已取消的订单不能操作
            if (OrderStatus.CALCEL.getCode().equals(orderBean.getStatus())) {
                return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED);
            }
            //非商城订单不允许操作
            if (!OrderSourceType.SAASMALL.getCode().equals(orderBean.getSource())) {
                return ResponseUtil.error(ResponseResult.ORDER_MALL_NOT_MATCH);
            }

            /**
             * 修改配送状态
             */
            OrderChangeStateReq request = new OrderChangeStateReq();
            request.setOrderCode(baseQueryOrderRequest.getOrderId());
            request.setOrderState(NewOrderStatus.COMPLETE.getIndex());
            request.setOperator(assortmentCustomerInfoVo.getNickName());
            request.setTaskType(Arrays.asList((byte) 5));
            request.setRemark("已完成");
            orderSdkService.updateOrderState(request, baseQueryOrderRequest.getTrackingNo());
            orderSdkService.completeBookingTask(request, baseQueryOrderRequest.getTrackingNo());
            return ResponseUtil.success();
        }catch (Exception e){
            result.setCode(ResponseResult.ORDER_RECEIVE_ERR.getCode());
            result.setMessage(ResponseResult.ORDER_RECEIVE_ERR.getMessage());
        }
        return result;
    }
    /**
     * 获取预支付成功，将信息放入死心队列，当支付成功没有回掉的时候处理
     *
     * @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);
        }
    }
}
