package com.zm.order.tool.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.github.dozermapper.core.Mapper;
import com.google.common.collect.Lists;
import com.zm.order.tool.server.component.ShardingKeyGenerator;
import com.zm.order.tool.server.cy.WmKoubeiOrdersDao;
import com.zm.order.tool.server.cy.WmOrderAttachGoodsDao;
import com.zm.order.tool.server.cy.WmOrderGiveGoodsDao;
import com.zm.order.tool.server.dao.*;
import com.zm.order.tool.server.dto.OrderAddrDTO;
import com.zm.order.tool.server.dto.QueryPerformanceDTO;
import com.zm.order.tool.server.manager.AsyncMessageManager;
import com.zm.order.tool.server.manager.CommonManager;
import com.zm.order.tool.server.manager.RedisManager;
import com.zm.order.tool.server.manager.SearchManager;
import com.zm.order.tool.server.message.BatchSyncEsMessage;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.query.*;
import com.zm.order.tool.server.request.OrderDataReviseRequest;
import com.zm.order.tool.server.service.ExceptionConstants;
import com.zm.order.tool.server.service.RetailService;
import com.zm.order.tool.server.tempdb.*;
import com.zm.order.tool.server.utils.ConvertUtils;
import com.zm.util.dto.Result;
import org.apache.lucene.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author nianchang
 * @ClassName CyServiceImpl
 * @date 2021/08/30 3:22 下午
 */
@Service
@SuppressWarnings("all")
public class RetailServiceImpl implements RetailService, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(RetailServiceImpl.class);

    private BlockingQueue workQueue;
    private ExecutorService executorService;
    @Autowired
    private RedisManager redisManager;
    @Autowired
    private CommonManager commonManager;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private ShardingKeyGenerator shardingKeyGenerator;
    @Autowired
    private Mapper mapper;
    @Autowired
    private OrderAddrDao orderAddrDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderIndexDao orderIndexDao;
    @Autowired
    private OrderDiscountDao orderDiscountDao;
    @Autowired
    private OrderPayDetailsDao payDetailsDao;
    @Autowired
    private WmOrderAttachGoodsDao orderAttachGoodsDao;
    @Autowired
    private WmOrderGiveGoodsDao orderGiveGoodsDao;
    @Autowired
    private OrderItemBatchingDao itemBatchingDao;
    @Autowired
    private WmKoubeiOrdersDao wmKoubeiOrdersDao;
    @Autowired
    private AsyncMessageManager messageManager;
    @Autowired
    private OrderUserRelationDao ourDao;
    @Autowired
    private RefundDao refundDao;
    @Autowired
    private RefundItemDao refundItemDao;
    @Autowired
    private PerformanceSelfTakeDao performanceSelfTakeDao;
//    @Autowired
//    private RetaOrderExpressesDao retaOrderExpressesDao;
//    @Autowired
//    private RetaAreaDao retaAreaDao;
    @Autowired
    private TmpOrderDao tmpOrderDao;
    @Autowired
    private TmpOrderDiscountDao tmpOrderDiscountDao;
    @Autowired
    private TmpOrderItemDao tmpOrderItemDao;
    @Autowired
    private TmpRefundDao tmpRefundDao;
    @Autowired
    private TmpOrderAddrDao tmpOrderAddrDao;
    @Autowired
    private IdMapDao idMapDao;
    @Autowired
    private TmpRefundItemDao tmpRefundItemDao;
    @Autowired
    private TmpPerformanceSelfTakeDao tmpPerformanceSelfTakeDao;
    @Autowired
    private SearchManager searchManager;
    @Autowired
    private ShardingKeyGenerator keyGenerator;

    /**
     * 零售迁移的订单类型
     **/
    private static List<Integer> orderTypeList = new ArrayList<>();
    private static Map<Long, Long> storeIdMap = new HashMap<>();

    //巴莉甜甜零售线上：29171
    //巴莉甜甜烘焙线上：208331
    private static Long newSellerId = 208331L;//pro
    private static Long oldSellerId = 29171L;//pro
    private static Integer reta = 2;
    private static Integer baking = 4;

    static {
        orderTypeList.add(1);
        orderTypeList.add(2);
        orderTypeList.add(3);
        orderTypeList.add(5);
        orderTypeList.add(6);
    }

    static {
        storeIdMap.put(4079L,96622L);
        storeIdMap.put(4081L,96623L);
        storeIdMap.put(4082L,96624L);
        storeIdMap.put(4083L,96625L);
        storeIdMap.put(4084L,96626L);
        storeIdMap.put(4085L,96627L);
        storeIdMap.put(4086L,96601L);
        storeIdMap.put(4087L,96628L);
        storeIdMap.put(4088L,96629L);
        storeIdMap.put(4089L,96630L);
        storeIdMap.put(4090L,96631L);
        storeIdMap.put(4091L,96632L);
        storeIdMap.put(4092L,96633L);
        storeIdMap.put(4093L,96634L);
        storeIdMap.put(4094L,96602L);
        storeIdMap.put(4095L,96635L);
        storeIdMap.put(4096L,96636L);
        storeIdMap.put(4097L,96637L);
        storeIdMap.put(4098L,96638L);
        storeIdMap.put(4099L,96639L);
        storeIdMap.put(4100L,96603L);
        storeIdMap.put(4101L,96640L);
        storeIdMap.put(4578L,96641L);
        storeIdMap.put(4579L,96604L);
        storeIdMap.put(4639L,96642L);
        storeIdMap.put(4643L,96643L);
        storeIdMap.put(4644L,96644L);
        storeIdMap.put(5010L,96645L);
        storeIdMap.put(5192L,96646L);
        storeIdMap.put(6036L,96647L);
        storeIdMap.put(9001L,96648L);
        storeIdMap.put(9002L,96649L);
        storeIdMap.put(12087L,96650L);
        storeIdMap.put(12370L,96651L);
        storeIdMap.put(12846L,96652L);
        storeIdMap.put(12847L,96653L);
        storeIdMap.put(103267L,96654L);
        storeIdMap.put(103268L,96605L);
        storeIdMap.put(103521L,96655L);
        storeIdMap.put(103985L,96656L);
        storeIdMap.put(104159L,96657L);
        storeIdMap.put(105015L,96658L);
        storeIdMap.put(105016L,96659L);
        storeIdMap.put(104979L,96660L);
        storeIdMap.put(104980L,96661L);
        storeIdMap.put(104981L,96662L);
        storeIdMap.put(105483L,96663L);
        storeIdMap.put(105855L,96606L);
        storeIdMap.put(105485L,96607L);
        storeIdMap.put(105486L,96664L);
        storeIdMap.put(105601L,96665L);
        storeIdMap.put(105602L,96666L);
        storeIdMap.put(105603L,96667L);
        storeIdMap.put(105856L,96668L);
        storeIdMap.put(105857L,96669L);
        storeIdMap.put(105858L,96670L);
        storeIdMap.put(105859L,96671L);
        storeIdMap.put(106114L,96672L);
        storeIdMap.put(106115L,96608L);
        storeIdMap.put(106455L,96673L);
        storeIdMap.put(107088L,96609L);
        storeIdMap.put(107089L,96610L);
        storeIdMap.put(107090L,96611L);
        storeIdMap.put(107091L,96674L);
        storeIdMap.put(107092L,96675L);
        storeIdMap.put(107093L,96612L);
        storeIdMap.put(107120L,96676L);
        storeIdMap.put(107586L,96677L);
        storeIdMap.put(107587L,96678L);
        storeIdMap.put(107778L,96679L);
        storeIdMap.put(107779L,96680L);
        storeIdMap.put(107780L,96681L);
        storeIdMap.put(107781L,96682L);
        storeIdMap.put(107949L,96683L);
        storeIdMap.put(107950L,96684L);
        storeIdMap.put(107980L,96685L);
        storeIdMap.put(107981L,96868L);
        storeIdMap.put(108371L,96686L);
        storeIdMap.put(108199L,96613L);
        storeIdMap.put(108200L,96614L);
        storeIdMap.put(108115L,96687L);
        storeIdMap.put(108143L,96688L);
        storeIdMap.put(108274L,96689L);
        storeIdMap.put(108268L,96690L);
        storeIdMap.put(108443L,96691L);
        storeIdMap.put(108345L,96615L);
        storeIdMap.put(108437L,96692L);
        storeIdMap.put(108438L,96693L);
        storeIdMap.put(108616L,96694L);
        storeIdMap.put(108788L,100505L);
        storeIdMap.put(108806L,100504L);
        storeIdMap.put(108961L,122592L);
        storeIdMap.put(108962L,122593L);
        storeIdMap.put(108963L,122594L);
        storeIdMap.put(108964L,122595L);
        storeIdMap.put(108965L,122596L);
        storeIdMap.put(108966L,122597L);
        storeIdMap.put(108967L,122598L);
        storeIdMap.put(108968L,122599L);
        storeIdMap.put(108969L,122600L);
        storeIdMap.put(109000L,122601L);
        storeIdMap.put(4102L,96695L);
        storeIdMap.put(4103L,96696L);
        storeIdMap.put(4104L,96697L);
        storeIdMap.put(4105L,96698L);
        storeIdMap.put(4106L,96699L);
        storeIdMap.put(4107L,96700L);
        storeIdMap.put(4108L,96701L);
        storeIdMap.put(4109L,96702L);
        storeIdMap.put(4110L,96703L);
        storeIdMap.put(4111L,96704L);
        storeIdMap.put(4112L,96705L);
        storeIdMap.put(4113L,96706L);
        storeIdMap.put(8518L,96707L);
        storeIdMap.put(8562L,96708L);
        storeIdMap.put(8563L,96709L);
        storeIdMap.put(8564L,96710L);
        storeIdMap.put(8565L,96711L);
        storeIdMap.put(9003L,96616L);
        storeIdMap.put(4115L,96712L);
        storeIdMap.put(4117L,96713L);
        storeIdMap.put(4118L,96714L);
        storeIdMap.put(4119L,96715L);
        storeIdMap.put(4121L,96716L);
        storeIdMap.put(4122L,96717L);
        storeIdMap.put(4123L,96718L);
        storeIdMap.put(4128L,96719L);
        storeIdMap.put(4129L,96720L);
        storeIdMap.put(108144L,96721L);
        storeIdMap.put(4133L,96722L);
        storeIdMap.put(4134L,96723L);
        storeIdMap.put(4135L,96724L);
        storeIdMap.put(4136L,96725L);
        storeIdMap.put(4137L,96726L);
        storeIdMap.put(4138L,96727L);
        storeIdMap.put(4139L,96728L);
        storeIdMap.put(4140L,96729L);
        storeIdMap.put(4143L,96730L);
        storeIdMap.put(4144L,96731L);
        storeIdMap.put(4145L,96732L);
        storeIdMap.put(4148L,96733L);
        storeIdMap.put(4150L,96734L);
        storeIdMap.put(108145L,96735L);
        storeIdMap.put(4152L,96736L);
        storeIdMap.put(4153L,96737L);
        storeIdMap.put(4154L,96738L);
        storeIdMap.put(4157L,96739L);
        storeIdMap.put(4158L,96740L);
        storeIdMap.put(4159L,96741L);
        storeIdMap.put(4161L,96742L);
        storeIdMap.put(4162L,96743L);
        storeIdMap.put(4163L,96744L);
        storeIdMap.put(4165L,96745L);
        storeIdMap.put(4166L,96746L);
        storeIdMap.put(4168L,96747L);
        storeIdMap.put(4169L,96748L);
        storeIdMap.put(4170L,96749L);
        storeIdMap.put(4171L,96750L);
        storeIdMap.put(4172L,96751L);
        storeIdMap.put(4173L,96752L);
        storeIdMap.put(4174L,96753L);
        storeIdMap.put(4175L,96617L);
        storeIdMap.put(4176L,96618L);
        storeIdMap.put(4178L,96754L);
        storeIdMap.put(4179L,96755L);
        storeIdMap.put(4180L,96756L);
        storeIdMap.put(4181L,96757L);
        storeIdMap.put(4182L,96758L);
        storeIdMap.put(4184L,96759L);
        storeIdMap.put(107983L,96760L);
        storeIdMap.put(4186L,96761L);
        storeIdMap.put(4529L,96619L);
        storeIdMap.put(4187L,96762L);
        storeIdMap.put(4188L,96763L);
        storeIdMap.put(4190L,96764L);
        storeIdMap.put(4191L,96765L);
        storeIdMap.put(4531L,96766L);
        storeIdMap.put(4192L,96767L);
        storeIdMap.put(4193L,96620L);
        storeIdMap.put(4194L,96768L);
        storeIdMap.put(4195L,96769L);
        storeIdMap.put(4196L,96770L);
        storeIdMap.put(4197L,96771L);
        storeIdMap.put(4199L,96772L);
        storeIdMap.put(4201L,96773L);
        storeIdMap.put(4202L,96621L);
        storeIdMap.put(4204L,96774L);
        storeIdMap.put(4205L,96775L);
        storeIdMap.put(4206L,96776L);
        storeIdMap.put(4207L,96777L);
        storeIdMap.put(4208L,96778L);
        storeIdMap.put(4209L,96779L);
        storeIdMap.put(4210L,96780L);
        storeIdMap.put(4211L,96781L);
        storeIdMap.put(4213L,96782L);
        storeIdMap.put(4214L,96783L);
        storeIdMap.put(4216L,96784L);
        storeIdMap.put(4218L,96785L);
        storeIdMap.put(4219L,96786L);
        storeIdMap.put(4220L,96787L);
        storeIdMap.put(4221L,96788L);
        storeIdMap.put(4222L,96789L);
        storeIdMap.put(4223L,96790L);
        storeIdMap.put(4224L,96791L);
        storeIdMap.put(4225L,96792L);
        storeIdMap.put(4226L,96793L);
        storeIdMap.put(4227L,96794L);
        storeIdMap.put(4228L,96795L);
        storeIdMap.put(4229L,96796L);
        storeIdMap.put(4230L,96797L);
        storeIdMap.put(4231L,96798L);
        storeIdMap.put(4232L,96799L);
        storeIdMap.put(4233L,96800L);
        storeIdMap.put(4235L,96801L);
        storeIdMap.put(4236L,96802L);
        storeIdMap.put(4237L,96803L);
        storeIdMap.put(4238L,96804L);
        storeIdMap.put(4239L,96805L);
        storeIdMap.put(4240L,96806L);
        storeIdMap.put(4241L,96807L);
        storeIdMap.put(4242L,96808L);
        storeIdMap.put(4243L,96809L);
        storeIdMap.put(4244L,96810L);
        storeIdMap.put(4245L,96811L);
        storeIdMap.put(4246L,96812L);
        storeIdMap.put(4247L,96813L);
        storeIdMap.put(4249L,96814L);
        storeIdMap.put(4250L,96815L);
        storeIdMap.put(4251L,96816L);
        storeIdMap.put(4252L,96817L);
        storeIdMap.put(4253L,96818L);
        storeIdMap.put(4254L,96819L);
        storeIdMap.put(4255L,96820L);
        storeIdMap.put(4256L,96821L);
        storeIdMap.put(4257L,96822L);
        storeIdMap.put(4258L,96823L);
        storeIdMap.put(4260L,96824L);
        storeIdMap.put(4261L,96825L);
        storeIdMap.put(4262L,96826L);
        storeIdMap.put(4263L,96827L);
        storeIdMap.put(4264L,96828L);
        storeIdMap.put(4265L,96829L);
        storeIdMap.put(4266L,96830L);
        storeIdMap.put(4267L,96831L);
        storeIdMap.put(4268L,96832L);
        storeIdMap.put(4270L,96833L);
        storeIdMap.put(4271L,96834L);
        storeIdMap.put(4272L,96835L);
        storeIdMap.put(4273L,96836L);
        storeIdMap.put(4274L,96837L);
        storeIdMap.put(4275L,96838L);
        storeIdMap.put(4276L,96839L);
        storeIdMap.put(4278L,96840L);
        storeIdMap.put(4280L,96841L);
        storeIdMap.put(4283L,96842L);
        storeIdMap.put(4284L,96843L);
        storeIdMap.put(4288L,96844L);
        storeIdMap.put(4289L,96845L);
        storeIdMap.put(4290L,96846L);
        storeIdMap.put(4292L,96847L);
        storeIdMap.put(4293L,96848L);
        storeIdMap.put(4294L,96849L);
        storeIdMap.put(108146L,96850L);
        storeIdMap.put(4296L,96851L);
        storeIdMap.put(4298L,96852L);
        storeIdMap.put(4299L,96853L);
        storeIdMap.put(4300L,96854L);
        storeIdMap.put(4301L,96855L);
        storeIdMap.put(4302L,96856L);
        storeIdMap.put(4303L,96857L);
        storeIdMap.put(4304L,96858L);
        storeIdMap.put(4305L,96859L);
        storeIdMap.put(4306L,96860L);
        storeIdMap.put(4307L,96861L);
        storeIdMap.put(4308L,96862L);
        storeIdMap.put(4309L,96863L);
        storeIdMap.put(4311L,96869L);
        storeIdMap.put(4312L,96865L);
        storeIdMap.put(12371L,96866L);
        storeIdMap.put(4313L,96867L);
        storeIdMap.put(108273L,96864L);
    }

    @Override
    public Result retailTransfer1(OrderDataReviseRequest request) {
        int count = 0;
        Long sellerId = oldSellerId;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSellerId(sellerId);
        orderQuery.setSize(100);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        long startAt = System.currentTimeMillis();
                        List<Long> orderIdList = commonManager.scanOrderId(orderQuery, i, j);
                        logger.info("retailTransfer1_orderList_lastId:{},i:{},j:{},orderQuery:{},orderIdList:{}", lastId, i, j, orderQuery, orderIdList);
                        if (CollectionUtils.isEmpty(orderIdList)) {
                            break;
                        }
                        List<Order> orderList = commonManager.listOrderById(orderIdList, i, j);
                        logger.info("retailTransfer1_query_time1:{}ms", System.currentTimeMillis() - startAt);
                        orderList = orderList.stream()
                                .filter((Order s) -> orderTypeList.contains(s.getOrderType()))
                                .collect(Collectors.toList());
                        executeTransfer(orderList, i, j);
                        count += orderIdList.size();
                        logger.info("retailTransfer1:{}条", count);
                        if (orderIdList.size() < 100) {
                            break;
                        }
                        lastId = orderIdList.get(orderIdList.size() - 1);
                        logger.info("retailTransfer1:lastId:{},i:{},j:{}", lastId, i, j);
                        Result<String> redisData = redisManager.get("retail_Transfer1");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            return Result.successNullData();
                        }
                    }
                }
            }
            logger.info("retailTransfer1:end");
        } catch (Exception e) {
            logger.error("[retailTransfer1]failed!cause by:{}", e);
            return Result.failureData(ExceptionConstants.SYSTEM_ERROR);
        }
        return Result.successNullData();
    }

    private void executeTransfer(List<Order> orderList, int i, int j) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                if (CollectionUtils.isEmpty(orderList)) {
                    return;
                }
                
                List<BatchSyncEsMessage> messageList = new ArrayList<>(500);

                long deletePayAt = System.currentTimeMillis();
                List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
                long startAt = System.currentTimeMillis();
                // 批量查询订单下的所有商品 商品只需修改bizType,sellerId
                List<OrderItem> itemList = queryOrderItemList(orderList);
                // 商品ID列表
                List<Long> itemIdList = itemList.stream().map(OrderItem::getId).collect(Collectors.toList());
                // 按照订单号分组
                Map<String, List<OrderItem>> itemMap = itemList.stream().collect(Collectors.groupingBy(OrderItem::getOrderNo));

                //批量查询订单下优惠
                List<OrderDiscount> orderDiscountList = queryOrderDiscountList(orderList);

                //批量查询退款单
//                RefundQuery refundQuery = new RefundQuery();
//                refundQuery.setOrderNoList(orderNoList);
//                List<Refund> refundList = refundDao.selectList(refundQuery);
//
//                //批量查询退款商品
//                List<String> refundNoList = refundList.stream().map(Refund::getRefundNo).collect(Collectors.toList());
//                RefundItemQuery refundItemQuery = new RefundItemQuery();
//                refundItemQuery.setRefundNoList(refundNoList);
//                List<RefundItem> refundItemList = refundItemDao.selectList(refundItemQuery);
//                //按退款单号分组
//                Map<String, List<RefundItem>> refundItemMap = refundItemList.stream().collect(Collectors.groupingBy(RefundItem::getRefundNo));

                List<OrderAddr> orderAddrList = new ArrayList<>(300);
                List<OrderItem> newOrderItemList = new ArrayList<>(itemIdList.size());
                logger.info("startAt_indexOrder_time:{}ms", System.currentTimeMillis() - startAt);

                long startAt1 = System.currentTimeMillis();
                for (Order order : orderList) {
                    buildOrderParam(order);
                    buildOrderAddress(order, orderAddrList);
                    buildOrderItem(order, itemMap, newOrderItemList);
                    messageList.add(buildMessage(order));
                }
                logger.info("startAt1_indexOrder_time:{}ms", System.currentTimeMillis() - startAt1);

                if (!CollectionUtils.isEmpty(orderDiscountList)) {
                    for (OrderDiscount orderDiscount : orderDiscountList) {
                        buildDiscountExtra(orderDiscount);
                        buildDiscountType(orderDiscount);
                    }
                }

//                List<RefundItem> newRefundItemList = new ArrayList<>(refundItemList.size());
//                if (!CollectionUtils.isEmpty(refundList)) {
//                    for (Refund refund : refundList) {
//                        buildRefundExtra(refund);
//                        convertOrderType(refund);
//                        buildRefundStatus(refund);
//                        buildRefundParams(refund, refundItemMap, newRefundItemList);
//                        buildRefundWay(refund);
//                        refund.setBizType(baking);
//                        refund.setSellerId(newSellerId);
//                        refund.setStoreId(converStoreId(refund.getStoreId()));
//                    }
//                }
                // 批量查询订单自提表
                List<PerformanceSelfTake> orderSelfTakeList = queryOrderSelfTakeList(orderList);
                if (!CollectionUtils.isEmpty(orderSelfTakeList)) {
                    for (PerformanceSelfTake performanceSelfTake : orderSelfTakeList) {
                        performanceSelfTake.setStoreId(converStoreId(performanceSelfTake.getStoreId()));
                    }
                }

                // 执行变更
                long startAt2 = System.currentTimeMillis();
                commonManager.updateBatchOrderInfo(orderList, i, j, newSellerId);
                logger.info("startAt2_indexOrder_time:{}ms", System.currentTimeMillis() - startAt2);

                long startAt3 = System.currentTimeMillis();
                List<OrderItem> newItemList = null;

                //批量修改订单优惠
                if (!CollectionUtils.isEmpty(orderDiscountList)) {
                    commonManager.updateDiscountBatch(orderDiscountList, i, j);
                }
                //批量添加地址
                if (!CollectionUtils.isEmpty(orderAddrList)) {
                    orderAddrDao.inserts(orderAddrList);
                }
                //批量修改商品
                if (!CollectionUtils.isEmpty(newOrderItemList)) {
                    commonManager.updateItemBizTypeSellerId(newOrderItemList, baking, newSellerId, i, j);
                }
                //批量修改退款表
//                if (!CollectionUtils.isEmpty(refundList)) {
//                    refundDao.updateBatch(refundList, baking, newSellerId);
//                }
//                //批量修改退款商品表itemType 和 isDeleted
//                if (!CollectionUtils.isEmpty(newRefundItemList)) {
//                    refundItemDao.updateBatch(newRefundItemList, newSellerId);
//                }
                //批量修改自提表
                if (!CollectionUtils.isEmpty(orderSelfTakeList)) {
                    performanceSelfTakeDao.updateBatch(orderSelfTakeList, baking, newSellerId);
                }

                logger.info("startAt3_indexOrder_time:{}ms", System.currentTimeMillis() - startAt3);
                long startAt4 = System.currentTimeMillis();
                List<BatchSyncEsMessage> pushList = new ArrayList<>(500);
                buildPushMessage(messageList, pushList);
                messageManager.sendBatchSyncMessage(pushList);
                logger.info("startAt4_indexOrder_time:{}ms", System.currentTimeMillis() - startAt4);
            } catch (Exception e) {
                logger.error("[executeTransfer]failed！cause by:{}", e);
            }
        });
    }

    private BatchSyncEsMessage buildMessage(Order order) {
        BatchSyncEsMessage message = new BatchSyncEsMessage();
        message.setUserId(order.getUserId());
        message.setId(order.getId());
        message.setOrderNo(order.getOrderNo());
        message.setOrderSubType(order.getOrderSubType());
        return message;
    }

    private List<OrderItem> queryOrderItemList(List<Order> orderList) {
        List<OrderItem> itemList = new ArrayList<>();
        List<List<Order>> partition = Lists.partition(orderList, 50);
        for (List<Order> orders : partition) {
            List<Long> userIdList = orders.stream().map(Order::getUserId).collect(Collectors.toList());
            List<String> orderNoList = orders.stream().map(Order::getOrderNo).collect(Collectors.toList());
            OrderItemQuery orderItemQuery = new OrderItemQuery();
            orderItemQuery.setUserIdList(userIdList);
            orderItemQuery.setOrderNoList(orderNoList);
            itemList.addAll(orderItemDao.selectList(orderItemQuery));
        }
        return itemList;
    }

    private List<OrderItem> queryOrderItemListTmp(List<Order> orderList) {
        List<Long> userIdList = orderList.stream().map(Order::getUserId).collect(Collectors.toList());
        List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
        OrderItemQuery orderItemQuery = new OrderItemQuery();
        orderItemQuery.setUserIdList(userIdList);
        orderItemQuery.setOrderNoList(orderNoList);
        return tmpOrderItemDao.selectList(orderItemQuery);
    }

    private List<PerformanceSelfTake> queryOrderSelfTakeList(List<Order> orderList) {
        List<Long> userIdList = orderList.stream().map(Order::getUserId).collect(Collectors.toList());
        List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
        QueryPerformanceDTO queryPerformanceDTO = new QueryPerformanceDTO();
        queryPerformanceDTO.setUserIdList(userIdList);
        queryPerformanceDTO.setOrderNoList(orderNoList);
        return performanceSelfTakeDao.selectListByUserIdOrderNo(queryPerformanceDTO);
    }

    private List<PerformanceSelfTake> queryOrderSelfTakeListTmp(List<Order> orderList) {
        List<Long> userIdList = orderList.stream().map(Order::getUserId).collect(Collectors.toList());
        List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
        QueryPerformanceDTO queryPerformanceDTO = new QueryPerformanceDTO();
        queryPerformanceDTO.setUserIdList(userIdList);
        queryPerformanceDTO.setOrderNoList(orderNoList);
        return tmpPerformanceSelfTakeDao.selectListByUserIdOrderNo(queryPerformanceDTO);
    }

    private List<OrderDiscount> queryOrderDiscountList(List<Order> orderList) {
        List<OrderDiscount> discountList = new ArrayList<>();
        List<List<Order>> partition = Lists.partition(orderList, 50);
        for (List<Order> orders : partition) {
            List<Long> userIdList = orders.stream().map(Order::getUserId).collect(Collectors.toList());
            List<String> orderNoList = orders.stream().map(Order::getOrderNo).collect(Collectors.toList());
            OrderDiscountQuery orderDiscountQuery = new OrderDiscountQuery();
            orderDiscountQuery.setUserIdList(userIdList);
            orderDiscountQuery.setOrderNoList(orderNoList);
            discountList.addAll(orderDiscountDao.selectListByUserIds(orderDiscountQuery));
        }
        return discountList;
    }

    private List<OrderDiscount> queryOrderDiscountListTmp(List<Order> orderList) {
        List<Long> userIdList = orderList.stream().map(Order::getUserId).collect(Collectors.toList());
        List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
        OrderDiscountQuery orderDiscountQuery = new OrderDiscountQuery();
        orderDiscountQuery.setUserIdList(userIdList);
        orderDiscountQuery.setOrderNoList(orderNoList);
        return tmpOrderDiscountDao.selectListByUserIds(orderDiscountQuery);
    }

    private Map<String, List<OrderAddrDTO>> queryOrderAddressList(List<Order> orderList) {
        List<Long> userIdList = orderList.stream().map(Order::getUserId).collect(Collectors.toList());
        List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
        OrderAddressQuery query = new OrderAddressQuery();
        query.setUserIdList(userIdList);
        query.setOrderNoList(orderNoList);
        List<OrderAddrDTO> addrDTOList = ConvertUtils.convertList(orderAddrDao.selectList(query), OrderAddrDTO.class);
        if (CollectionUtils.isEmpty(addrDTOList)) {
            return Collections.EMPTY_MAP;
        }
        return addrDTOList.stream().collect(Collectors.groupingBy(OrderAddrDTO::getOrderNo));
    }

    private void buildOrderItem(Order order, Map<String, List<OrderItem>> itemMap, List<OrderItem> newOrderItemList) {
        if (Objects.isNull(itemMap.get(order.getOrderNo()))) {
            return;
        }
        List<OrderItem> itemList = itemMap.get(order.getOrderNo());
        for (OrderItem orderItem : itemList) {
            Map<String, Object> itemExtra = orderItem.getExtraMap();
            if (CollectionUtils.isEmpty(itemExtra)) {
                itemExtra = new HashMap<>(10);
            }
            itemExtra.put("isHistoryOrder", 1);
            itemExtra.put("historyItemSpec", orderItem.getItemSpec());
            orderItem.setExtraMap(itemExtra);

            //处理商品的商品规格 start
            if (Objects.equals("\"\"", orderItem.getItemSpec())) {
                orderItem.setItemSpec(null);
            } else if (!StringUtils.isEmpty(orderItem.getItemSpec())) {
                try {
                    Map<String, Object> itemSpecMap = JSON.parseObject(orderItem.getItemSpec(), Map.class);
                    List<Map<String, Object>> specList = new ArrayList<>(itemSpecMap.size());
                    for (Map.Entry<String, Object> entry : itemSpecMap.entrySet()) {
                        Map<String, Object> specItemMap = new HashMap<>(4);
                        specItemMap.put("specId", 0L);
                        specItemMap.put("specName", entry.getKey());
                        specItemMap.put("specValueId", 0L);
                        specItemMap.put("specValue", entry.getValue());
                        specList.add(specItemMap);
                    }
                    orderItem.setItemSpec(JSON.toJSONString(specList));
                } catch (Throwable e) {
                    orderItem.setItemSpec(null);
                }
            } else {
                orderItem.setItemSpec(null);
            }
            newOrderItemList.add(orderItem);
        }
        String itemInfo = order.getItemInfo();
        if (!Objects.equals("TL", itemInfo)) {
            List<InnerOrderItem> innerOrderItemList = ConvertUtils.convertList(itemList, InnerOrderItem.class);
            if (!CollectionUtils.isEmpty(innerOrderItemList)) {
                order.setItemInfo(JSON.toJSONString(innerOrderItemList));
            }
        }

    }


    private void buildOrderAddress(Order order, List<OrderAddr> orderAddrList) {
        String areaCacheKey = "order_transf_temp_area:";
        OrderAddr orderAddr = new OrderAddr();
        String performanceInfo = order.getPerformanceInfo();
        if (!StringUtils.isEmpty(performanceInfo)) {
            Map<String, Object> performanceInfoMap = JSON.parseObject(performanceInfo, Map.class);
            if (Objects.nonNull(performanceInfoMap.get("orderAddress"))) {
                Map<String, Object> addressMap = JSON.parseObject(performanceInfoMap.get("orderAddress").toString(), Map.class);
                orderAddr.setAcceptName(addressMap.getOrDefault("accept_name", "").toString());
                if (Objects.nonNull(addressMap.get("province"))) {
                    Integer province = Integer.valueOf(addressMap.get("province").toString());
                    orderAddr.setProvince(province);
                    //获取省名称
                    String provinceName = "";
                    Result<String> provinceCache = redisManager.get(areaCacheKey + province);
                    if (provinceCache.isStatus() && Objects.nonNull(provinceCache.getData())) {
                        provinceName = provinceCache.getData();
                    } else {
//                        RetaArea area = retaAreaDao.selectOne(province);
//                        if (Objects.nonNull(area)) {
//                            provinceName = area.getName();
//                            redisManager.set(areaCacheKey + province, area.getName());
//                        }
                    }
                    orderAddr.setProvinceName(provinceName);
                }
                if (Objects.nonNull(addressMap.get("city"))) {
                    Integer city = Integer.valueOf(addressMap.get("city").toString());
                    orderAddr.setCity(city);
                    //获取市名称
                    String cityName = "";
                    Result<String> provinceCache = redisManager.get(areaCacheKey + city);
                    if (provinceCache.isStatus() && Objects.nonNull(provinceCache.getData())) {
                        cityName = provinceCache.getData();
                    } else {
//                        RetaArea area = retaAreaDao.selectOne(city);
//                        if (Objects.nonNull(area)) {
//                            cityName = area.getName();
//                            redisManager.set(areaCacheKey + city, area.getName());
//                        }
                    }
                    orderAddr.setCityName(cityName);
                }
                if (Objects.nonNull(addressMap.get("area"))) {
                    Integer areaId = Integer.valueOf(addressMap.get("area").toString());
                    orderAddr.setArea(areaId);
                    //获取区名称
                    String areaName = "";
                    Result<String> provinceCache = redisManager.get(areaCacheKey + areaId);
                    if (provinceCache.isStatus() && Objects.nonNull(provinceCache.getData())) {
                        areaName = provinceCache.getData();
                    } else {
//                        RetaArea area = retaAreaDao.selectOne(areaId);
//                        if (Objects.nonNull(area)) {
//                            areaName = area.getName();
//                            redisManager.set(areaCacheKey + areaId, area.getName());
//                        }
                    }
                    orderAddr.setAreaName(areaName);
                }
                orderAddr.setMobile(addressMap.getOrDefault("mobile", "").toString());
                orderAddr.setLat(addressMap.getOrDefault("lat", "").toString());
                orderAddr.setLng(addressMap.getOrDefault("lng", "").toString());
                orderAddr.setStreet(addressMap.getOrDefault("street", "").toString());
                orderAddr.setOrderNo(order.getOrderNo());
                orderAddr.setUserId(order.getUserId());
                orderAddr.setSex(0);
                orderAddr.setLabel(0);
                orderAddr.setZip("");
                orderAddr.setSellerId(newSellerId);
                orderAddr.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                orderAddrList.add(orderAddr);
                order.setAddrInfo(JSON.toJSONString(orderAddr));
            }
        }
    }

    private void buildDiscountType(OrderDiscount orderDiscount) {
        orderDiscount.setBizType(baking);
        orderDiscount.setSellerId(newSellerId);
        if (Objects.equals("coupon", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(2);
            orderDiscount.setDiscountName("优惠券");
        }
        if (Objects.equals("card", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(1);
            orderDiscount.setDiscountName("会员价");
        }
        if (Objects.equals("paid_card", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(1);
            orderDiscount.setDiscountName("会员价");
        }
        if (Objects.equals("reward", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(8);
            orderDiscount.setDiscountName("满减");
        }
        if (Objects.equals("gift", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(31);
            orderDiscount.setDiscountName("满赠");
        }
        if (Objects.equals("gift_card", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(18);
            orderDiscount.setDiscountName("礼品卡优惠");
        }
        if (Objects.equals("redpack", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(32);
            orderDiscount.setDiscountName("红包");
        }
        if (Objects.equals("limit_discount", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(22);
            orderDiscount.setDiscountName("限时折扣");
        }
        if (Objects.equals("point_deduction", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(19);
            orderDiscount.setDiscountName("积分抵扣");
        }
        if (Objects.equals("offline_minus", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(33);
            orderDiscount.setDiscountName("线下");
        }
        if (Objects.equals("change_price", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(34);
            orderDiscount.setDiscountName("订单改价");
        }
        if (Objects.equals("enterprise_card", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(35);
            orderDiscount.setDiscountName("企业会员");
        }
        if (Objects.equals("pre_sale_order_minus", orderDiscount.getDiscountName())) {
            orderDiscount.setDiscountType(36);
            orderDiscount.setDiscountName("定金膨胀");
        }
    }

    private void buildOrderParam(Order order) {
        convertExtraMap(order);
        convertOrderType(order);
        convertSource(order);
        if (Objects.equals(1, order.getPayStatus())) {
            convertPayType(order);
        }
        convertInvoiceType(order);
        convertStatus(order);
        convertPerformanceStatus(order);
        convertPackAmount(order);
        convertBuyerRemarks(order);
        convertPerformanceType(order);
        order.setStoreId(converStoreId(order.getStoreId()));
    }

    private Long converStoreId(Long oldStoreId) {
        if (storeIdMap.containsKey(oldStoreId)) {
            return storeIdMap.get(oldStoreId);
        }
        return oldStoreId;
    }

    private void convertStatus(Order order) {
        if (Objects.equals(3, order.getStatus())
                || Objects.equals(4, order.getStatus())
                || Objects.equals(6, order.getStatus())) {
            order.setStatus(8);
            return;
        }
        if (Objects.equals(5, order.getStatus())) {
            order.setStatus(4);
            return;
        }
    }

    private void convertPerformanceStatus(Order order) {
        if (Objects.equals(2, order.getPerformanceStatus())) {
            order.setPerformanceStatus(1);
            return;
        }
    }

    private void convertPayType(Order order) {
        if (Objects.equals(4, order.getPayType())) {
            order.setPayType(266);
            return;
        }
        if (Objects.equals(5, order.getPayType())) {
            order.setPayType(267);
            return;
        }
        if (Objects.equals(6, order.getPayType())) {
            order.setPayType(268);
            return;
        }
        if (Objects.equals(7, order.getPayType())) {
            order.setPayType(265);
            return;
        }
        if (Objects.equals(9, order.getPayType())) {
            order.setPayType(1);
            return;
        }
        if (Objects.equals(10, order.getPayType())) {
            order.setPayType(264);
            return;
        }
        //微信支付存在混合支付的情况
        String payInfo = order.getPayInfo();
        if (!StringUtils.isEmpty(payInfo)) {
            Map<String, Object> payInfoMap = JSON.parseObject(payInfo, Map.class);
            //use_wallet == 1 有混合支付 余额支付的情况
            if (Objects.nonNull(payInfoMap.get("use_wallet"))) {
                if (Objects.equals(1, Integer.valueOf(payInfoMap.get("use_wallet").toString()))) {
                    //use_wallet == 1 && pay_type == 0 余额支付
                    if (Objects.equals(0, order.getPayType())) {
                        //余额支付
                        order.setPayType(4);
                        return;
                    }

                    //use_wallet == 1 && PayAmount > 0 混合支付
                    if (order.getPayAmount() > 0) {
                        order.setPayType(8);
                        //补充扩展字段 微信支付金额 分，余额支付金额 元；
                        Map<String, Object> extraMap = order.getExtraMap();
                        extraMap.put("wechatAmount", order.getPayAmount());
                        if (Objects.nonNull(payInfoMap.get("wallet_amount"))) {
                            Map<String, Object> walletInfoMap = new HashMap<>(1);
                            walletInfoMap.put("walletAmount", Double.valueOf(payInfoMap.get("wallet_amount").toString()) / 100);
                            extraMap.put("walletInfo", JSON.toJSONString(walletInfoMap));
                        }
                        order.setExtraMap(extraMap);
                        return;
                    }
                }
                //免支付
                if (Objects.equals(0, Integer.valueOf(payInfoMap.get("use_wallet").toString()))) {
                    if (Objects.equals(0, order.getPayType()) && Objects.equals(0, order.getPayAmount())) {
                        order.setPayType(16);
                        return;
                    }
                }

            }
        }

    }

    private void convertInvoiceType(Order order) {
        if (Objects.equals(0, order.getInvoiceType())) {
            order.setInvoiceType(1);
            return;
        }
        if (Objects.equals(1, order.getInvoiceType())) {
            order.setInvoiceType(2);
            return;
        }
    }

    private void convertOrderType(Order order) {
        //订单子类型默认0
        order.setOrderSubType(0);
        //礼品卡订单零售6；烘焙4
        if (Objects.equals(6, order.getOrderType())) {
            order.setOrderType(4);
        }
        //零售拼团5
        if (Objects.equals(5, order.getOrderType())) {
            order.setOrderType(1);
            order.setOrderSubType(1);
        }
    }

    private void convertOrderType(Refund order) {
        //订单子类型默认0
        order.setOrderSubType(0);
        //礼品卡订单零售6；烘焙4
        if (Objects.equals(6, order.getOrderType())) {
            order.setOrderType(4);
        }
        //零售拼团5
        if (Objects.equals(5, order.getOrderType())) {
            order.setOrderType(1);
            order.setOrderSubType(1);
        }

        //退款单source
        if (Objects.equals(1, order.getSource()) || Objects.equals(2, order.getSource())) {
            order.setSource(1);
        }
        if (Objects.equals(3, order.getSource()) || Objects.equals(5, order.getSource())) {
            order.setSource(8);
        }
        if (Objects.equals(4, order.getSource()) || Objects.equals(7, order.getSource())) {
            order.setSource(18);
        }
        if (Objects.equals(6, order.getSource())) {
            order.setSource(14);
        }
        if (Objects.equals(8, order.getSource())) {
            order.setSource(4);
        }
        if (Objects.equals(9, order.getSource())) {
            order.setSource(5);
        }
    }

    private void convertSource(Order order) {
        if (Objects.equals(1, order.getSource()) || Objects.equals(2, order.getSource())) {
            order.setSource(1);
        }
        if (Objects.equals(3, order.getSource()) || Objects.equals(5, order.getSource())) {
            order.setSource(8);
        }
        if (Objects.equals(4, order.getSource()) || Objects.equals(7, order.getSource())) {
            order.setSource(18);
        }
        if (Objects.equals(6, order.getSource())) {
            order.setSource(14);
        }
        if (Objects.equals(8, order.getSource())) {
            order.setSource(4);
        }
        if (Objects.equals(9, order.getSource())) {
            order.setSource(5);
        }
    }

    private void convertExtraMap(Order order) {
        Map<String, Object> extraMap = order.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            extraMap = new HashMap<>(20);
        }
        extraMap.put("sellerName", "巴莉甜甜智慧经营");
        extraMap.put("isHistoryOrder", 1);
        extraMap.put("historyOrderType", order.getOrderType());
        extraMap.put("historyOrderSubType", order.getOrderSubType());
        extraMap.put("historySource", order.getSource());
        extraMap.put("historyPayType", order.getPayType());
        extraMap.put("historyStatus", order.getStatus());
        extraMap.put("historyPayAmount", order.getPayAmount());
        extraMap.put("historyBizType", order.getBizType());
        extraMap.put("historySellerId", order.getSellerId());
        extraMap.put("historyStoreId", order.getStoreId());
        extraMap.put("historyBuyerRemarks", order.getBuyerRemarks());
        extraMap.put("historyInvoiceType", order.getInvoiceType());
        extraMap.put("historyPerformanceType", order.getPerformanceType());
        extraMap.put("historyPerformanceStatus", order.getPerformanceStatus());

        if (Objects.equals(1, order.getOrderType()) || Objects.equals(5, order.getOrderType())) {
            if (order.getStoreId() > 0L) {
                extraMap.put("from", 0);
            } else {
                extraMap.put("from", 1);
            }
        }
        //查询快递信息
//        if (Objects.equals(1, order.getPerformanceType())) {
//            RetaOrderExpress retaOrderExpress = retaOrderExpressesDao.selectOne(order.getOrderNo());
//            if (Objects.nonNull(retaOrderExpress)) {
//                Map<String, String> map = new HashMap<>(3);
//                map.put("expressNumber", retaOrderExpress.getExpressNo());
//                map.put("name", retaOrderExpress.getExpressName());
//                map.put("id", retaOrderExpress.getExpressId());
//                extraMap.put("expressInfo", JSON.toJSONString(map));
//            }
//        }
        order.setExtraMap(extraMap);
    }

    private void convertPackAmount(Order order) {
        Map<String, Object> extraMap = order.getExtraMap();
        if (!CollectionUtils.isEmpty(extraMap)) {
            if (Objects.nonNull(extraMap.get("orderSubinfo"))) {
                String orderSubinfo = extraMap.get("orderSubinfo").toString();
                Map<String, Object> orderSubinfoMap = JSON.parseObject(orderSubinfo, Map.class);
                if (Objects.nonNull(orderSubinfoMap.get("pack_cost")) && !StringUtils.isEmpty(orderSubinfoMap.get("pack_cost").toString())) {
                    Double packCost = Double.valueOf(orderSubinfoMap.get("pack_cost").toString()) * 100;
                    Integer packAmount = packCost.intValue();
                    order.setPackAmount(packAmount);
                }

                if (Objects.nonNull(orderSubinfoMap.get("sort_num")) && !StringUtils.isEmpty(orderSubinfoMap.get("sort_num").toString())) {
                    order.setStoreOrderNo(orderSubinfoMap.get("sort_num").toString());
                }
            }
        }
    }

    private void convertPerformanceType(Order order) {
        //零售三方上送订单默认自提
        if (Objects.equals(1, order.getOrderType()) && Objects.equals(0, order.getPerformanceType())) {
            order.setPerformanceType(3);
        }
    }

    private void convertBuyerRemarks(Order order) {
        if (!StringUtils.isEmpty(order.getBuyerRemarks())) {
            try {
                String remarks = decodeUnicode(order.getBuyerRemarks());
                order.setBuyerRemarks(remarks);
            } catch (Throwable e) {
            }
        }
    }

    //Unicode转中文
    public static String decodeUnicode(String unicode) {
        List<String> list = new ArrayList<String>();
        String reg = "\\\\u[0-9,a-f,A-F]{4}";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(unicode);
        while (m.find()) {
            list.add(m.group());
        }
        for (int i = 0, j = 2; i < list.size(); i++) {
            String code = list.get(i).substring(j, j + 4);
            char ch = (char) Integer.parseInt(code, 16);
            unicode = unicode.replace(list.get(i), String.valueOf(ch));
        }
        return unicode;
    }

    private void buildDiscountExtra(OrderDiscount orderDiscount) {
        Map<String, Object> extraMap = orderDiscount.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            extraMap = new HashMap<>(10);
        }
        extraMap.put("isHistoryOrder", 1);
        extraMap.put("historyDiscountName", orderDiscount.getDiscountName());
        extraMap.put("historyBizType", orderDiscount.getBizType());
        extraMap.put("historySellerId", orderDiscount.getSellerId());
        orderDiscount.setExtraMap(extraMap);
    }

    private void buildRefundExtra(Refund refund) {
        Map<String, Object> extraMap = refund.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            extraMap = new HashMap<>(10);
        }
        extraMap.put("isHistoryOrder", 1);
        extraMap.put("historyStatus", refund.getStatus());
        extraMap.put("historyBizType", refund.getBizType());
        extraMap.put("historySellerId", refund.getSellerId());
        extraMap.put("historyStoreId", refund.getStoreId());
        extraMap.put("historyOrderType", refund.getOrderType());
        extraMap.put("historySource", refund.getSource());
        extraMap.put("historyOrderSubType", refund.getOrderSubType());
        refund.setExtraMap(extraMap);
    }

    private void buildRefundStatus(Refund refund) {
        if (Objects.equals(1, refund.getStatus())) {
            refund.setStatus(0);
        }
        if (Objects.equals(2, refund.getStatus())) {
            refund.setStatus(1);
        }
        if (Objects.equals(4, refund.getStatus())) {
            refund.setStatus(2);
        }
    }

    private void buildRefundWay(Refund refund) {
        if (Objects.equals(3, refund.getRefundType())) {
            refund.setRefundWay(1);
        }
        if (Objects.equals(1, refund.getRefundType())) {
            refund.setRefundWay(2);
        }
        if (Objects.equals(2, refund.getRefundType())) {
            refund.setRefundWay(3);
        }
    }

    private void buildRefundParams(Refund refund, Map<String, List<RefundItem>> refundItemMap, List<RefundItem> newRefundItemList) {
        Map<String, Object> extraMap = refund.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            extraMap = new HashMap<>(10);
        }
        List<RefundItem> refundItemList = refundItemMap.get(refund.getRefundNo());
        if (!CollectionUtils.isEmpty(refundItemList)) {

            for (RefundItem refundItem : refundItemList) {
                //退款商品的扩展字段
                Map<String, Object> refundItemExtra = refundItem.getExtraMap();
                if (CollectionUtils.isEmpty(refundItemExtra)) {
                    refundItemExtra = new HashMap<>(10);
                }
                refundItemExtra.put("isHistoryOrder", 1);
                refundItemExtra.put("historyItemSpec", refundItem.getItemSpec());
                refundItemExtra.put("historyItemType", refundItem.getItemType());
                refundItem.setExtraMap(refundItemExtra);

                //退款商品的itemType
                //零售的运费
                if (Objects.equals(0, refundItem.getItemType())) {
                    refundItem.setIsDeleted(-1);
                    extraMap.put("freightFee", refundItem.getRefundAmount() / 100);
                }
                //零售的包装费
                if (Objects.equals(1, refundItem.getItemType())) {
                    refundItem.setIsDeleted(-1);
                    extraMap.put("packCost", refundItem.getRefundAmount() / 100);
                }
                if (Objects.equals(2, refundItem.getItemType())) {
                    refundItem.setItemType(0);
                }

                //处理退款商品的商品规格 start
                if (Objects.equals("\"\"", refundItem.getItemSpec())) {
                    refundItem.setItemSpec(null);
                } else if (!StringUtils.isEmpty(refundItem.getItemSpec())) {
                    try {
                        Map<String, Object> itemSpecMap = JSON.parseObject(refundItem.getItemSpec(), Map.class);
                        List<Map<String, Object>> specList = new ArrayList<>(itemSpecMap.size());
                        for (Map.Entry<String, Object> entry : itemSpecMap.entrySet()) {
                            Map<String, Object> specItemMap = new HashMap<>(4);
                            specItemMap.put("specId", 0L);
                            specItemMap.put("specName", entry.getKey());
                            specItemMap.put("specValueId", 0L);
                            specItemMap.put("specValue", entry.getValue());
                            specList.add(specItemMap);
                        }
                        refundItem.setItemSpec(JSON.toJSONString(specList));
                    } catch (Throwable e) {
                        refundItem.setItemSpec(null);
                    }
                } else {
                    refundItem.setItemSpec(null);
                }
                //处理退款商品的商品规格 end
                newRefundItemList.add(refundItem);
            }
        }
        refund.setExtraMap(extraMap);
    }

    private void buildPushMessage(List<BatchSyncEsMessage> messageList, List<BatchSyncEsMessage> pushList) {
        if (!CollectionUtils.isEmpty(messageList)) {
            for (BatchSyncEsMessage message : messageList) {
                pushList.add(message);
            }
        }
    }

    @Value("${sharding.db.size}")
    private int dbSize;

    @Value("${sharding.tb.size}")
    private int tbSize;

    @Override
    public void afterPropertiesSet() throws Exception {
        int coreSize = Runtime.getRuntime().availableProcessors();
        workQueue = new ArrayBlockingQueue(256);
        executorService = new ThreadPoolExecutor(12, 20, 1, TimeUnit.MINUTES, workQueue, new NamedThreadFactory("order-data-sync"),
                new ThreadPoolExecutor.AbortPolicy());
    }

    @Override
    public Result retailTransfer1Temp(OrderDataReviseRequest request) {
        int count = 0;
        Long sellerId = oldSellerId;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSellerId(sellerId);
        orderQuery.setSize(300);
        try {
            Long lastId = null;
            for (; ; ) {
                orderQuery.setLastId(lastId);
                long startAt = System.currentTimeMillis();
                List<Long> orderIdList = tmpOrderDao.scanId(orderQuery);
                if (CollectionUtils.isEmpty(orderIdList)) {
                    break;
                }
                List<Order> orderList = tmpOrderDao.selectListById(orderIdList);
                logger.info("query_time1:{}ms", System.currentTimeMillis() - startAt);
                orderList = orderList.stream()
                        .filter((Order s) -> orderTypeList.contains(s.getOrderType()))
                        .collect(Collectors.toList());
                executeTransferTemp(orderList);
                count += orderIdList.size();
                logger.info("retailTransfer1:{}条", count);
                if (orderIdList.size() < 300) {
                    break;
                }
                lastId = orderIdList.get(orderIdList.size() - 1);
                logger.info("retaTransfer1_lastId:{}", lastId);
                Result<String> redisData = redisManager.get("retaTransfer1");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    return Result.successNullData();
                }
            }
            logger.info("retaTransfer1test_end");

        } catch (Exception e) {
            logger.error("[retaTransfer1]failed!cause by:{}", e);
            return Result.failureData(ExceptionConstants.SYSTEM_ERROR);
        }
        return Result.successNullData();
    }


    private void executeTransferTemp(List<Order> orderList) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                if (CollectionUtils.isEmpty(orderList)) {
                    return;
                }
                List<BatchSyncEsMessage> messageList = new ArrayList<>(500);
                long deletePayAt = System.currentTimeMillis();
                List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());
                long startAt = System.currentTimeMillis();
                // 批量查询订单下的所有商品 商品只需修改bizType,sellerId
                List<OrderItem> itemList = queryOrderItemListTmp(orderList);
                // 商品ID列表
                List<Long> itemIdList = itemList.stream().map(OrderItem::getId).collect(Collectors.toList());
                // 按照订单号分组
                Map<String, List<OrderItem>> itemMap = itemList.stream().collect(Collectors.groupingBy(OrderItem::getOrderNo));

                //批量查询订单下优惠
                List<OrderDiscount> orderDiscountList = queryOrderDiscountListTmp(orderList);

                //批量查询退款单
                RefundQuery refundQuery = new RefundQuery();
                refundQuery.setOrderNoList(orderNoList);
                List<Refund> refundList = tmpRefundDao.selectList(refundQuery);

                //批量查询退款商品
                Map<String, List<RefundItem>> refundItemMap = new HashMap<String, List<RefundItem>>();
                if (!CollectionUtils.isEmpty(refundList)) {
                    List<String> refundNoList = refundList.stream().map(Refund::getRefundNo).collect(Collectors.toList());
                    RefundItemQuery refundItemQuery = new RefundItemQuery();
                    refundItemQuery.setRefundNoList(refundNoList);
                    List<RefundItem> refundItemList = tmpRefundItemDao.selectList(refundItemQuery);
                    //按退款单号分组
                    refundItemMap = refundItemList.stream().collect(Collectors.groupingBy(RefundItem::getRefundNo));
                }

                List<OrderAddr> orderAddrList = new ArrayList<>(300);
                List<OrderItem> newOrderItemList = new ArrayList<>(itemIdList.size());
                logger.info("startAt_indexOrder_time:{}ms", System.currentTimeMillis() - startAt);

                long startAt1 = System.currentTimeMillis();
                for (Order order : orderList) {
                    buildOrderParam(order);
                    buildOrderAddress(order, orderAddrList);
                    buildOrderItem(order, itemMap, newOrderItemList);
                    messageList.add(buildMessage(order));
                }
                logger.info("startAt1_indexOrder_time:{}ms", System.currentTimeMillis() - startAt1);

                if (!CollectionUtils.isEmpty(orderDiscountList)) {
                    for (OrderDiscount orderDiscount : orderDiscountList) {
                        buildDiscountExtra(orderDiscount);
                        buildDiscountType(orderDiscount);
                    }
                }

                List<RefundItem> newRefundItemList = new ArrayList<>(1000);
                if (!CollectionUtils.isEmpty(refundList)) {
                    for (Refund refund : refundList) {
                        buildRefundExtra(refund);
                        convertOrderType(refund);
                        buildRefundStatus(refund);
                        buildRefundParams(refund, refundItemMap, newRefundItemList);
                        buildRefundWay(refund);
                        refund.setBizType(baking);
                        refund.setSellerId(newSellerId);
                        refund.setStoreId(converStoreId(refund.getStoreId()));
                    }
                }
                // 批量查询订单自提表
                List<PerformanceSelfTake> orderSelfTakeList = queryOrderSelfTakeListTmp(orderList);
                if (!CollectionUtils.isEmpty(orderSelfTakeList)) {
                    for (PerformanceSelfTake performanceSelfTake : orderSelfTakeList) {
                        performanceSelfTake.setStoreId(converStoreId(performanceSelfTake.getStoreId()));
                    }
                }

                // 执行变更
                long startAt2 = System.currentTimeMillis();
                tmpOrderDao.updateBatchOrderInfo(orderList, newSellerId);
                logger.info("startAt2_indexOrder_time:{}ms", System.currentTimeMillis() - startAt2);

                long startAt3 = System.currentTimeMillis();
                List<OrderItem> newItemList = null;

                //批量修改订单优惠
                if (!CollectionUtils.isEmpty(orderDiscountList)) {
                    tmpOrderDiscountDao.updateBatch(orderDiscountList);
                }
                //批量添加地址
                if (!CollectionUtils.isEmpty(orderAddrList)) {
                    tmpOrderAddrDao.inserts(orderAddrList);
                }
                //批量修改商品
                if (!CollectionUtils.isEmpty(itemIdList)) {
                    tmpOrderItemDao.updateBizTypeSellerId(newOrderItemList, baking, newSellerId);
                }
                //批量修改退款表
                if (!CollectionUtils.isEmpty(refundList)) {
                    tmpRefundDao.updateBatch(refundList, baking, newSellerId);
                }
                //批量修改退款商品表itemType 和 isDeleted
                if (!CollectionUtils.isEmpty(newRefundItemList)) {
                    tmpRefundItemDao.updateBatch(newRefundItemList, newSellerId);
                }
                //批量修改自提表
                if (!CollectionUtils.isEmpty(orderSelfTakeList)) {
                    tmpPerformanceSelfTakeDao.updateBatch(orderSelfTakeList, baking, newSellerId);
                }

                logger.info("startAt3_indexOrder_time:{}ms", System.currentTimeMillis() - startAt3);
                long startAt4 = System.currentTimeMillis();
                List<BatchSyncEsMessage> pushList = new ArrayList<>(500);
                buildPushMessage(messageList, pushList);
//                messageManager.sendBatchSyncMessage(pushList);
                logger.info("startAt4_indexOrder_time:{}ms", System.currentTimeMillis() - startAt4);
            } catch (Exception e) {
                logger.error("[executeTransfer]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void retailTransfer1Beta(OrderDataReviseRequest request) {
        //select min(id) from orders where seller_id=29171 and created_at > "2021-11-01" ;
        // 661721368844312577
        Long userId = 9941319L;
        Long sellerId = 11245L;
        Long storeId = 1039198L;
//        Long lastId = 661721368844312577L;
//        Long lastId = 661840128313921537L;
        Long lastId = 663425440135798784L;
        OrderQuery query = new OrderQuery();
        query.setSize(300);
        int count = 0;
        for (; ; ) {
            List<String> orderNoList0 = new ArrayList<>();
            orderNoList0.add("A61CAADA2B13F72790");
            orderNoList0.add("A61CAAD23E76F81543");
            orderNoList0.add("A61CA832B8035C4316");
            orderNoList0.add("BT6005312112120009");
            orderNoList0.add("A616FD3192B01A4069");
            orderNoList0.add("BT6005312110070021");
            orderNoList0.add("BT6005312109130046");
            orderNoList0.add("A608830F8021967636");
            orderNoList0.add("A608830BFF3EC49780");
            orderNoList0.add("A601C166467A2B1474");
            orderNoList0.add("A5F4A5DF403D894919");
            orderNoList0.add("A5F106347A776D2599");
            orderNoList0.add("A5EE5D0B34A80A2492");
            orderNoList0.add("A5EE5D082B59B27638");
            orderNoList0.add("A5EBFD8736AEE17531");
            orderNoList0.add("A5E17DB14023791482");
            orderNoList0.add("A5E0563189EF018971");
            orderNoList0.add("A5DFC662B423388911");
            orderNoList0.add("A5DF917AF0860E9635");
            orderNoList0.add("A5DC63D0802DE28950");
            orderNoList0.add("A5DC62A69122E97708");
            orderNoList0.add("A5DC4D50AAC5B48020");
            orderNoList0.add("A5D848CC7DF5D06843");
            List<Order> orderList = tmpOrderDao.selectByOrderNo(orderNoList0);
            if (CollectionUtils.isEmpty(orderList)) {
                return;
            }
            logger.info("retailTransfer1Beta:start:size:{};lastId:{}", orderList.size(), lastId);

            List<OrderIndex> orderIndexList = new ArrayList<>(orderList.size());
            List<String> orderNoList = orderList.stream().map(Order::getOrderNo).collect(Collectors.toList());

            // 批量查询订单下的所有商品 商品只需修改bizType,sellerId
            List<OrderItem> itemList = queryOrderItemListTmp(orderList);
            //批量查询订单下优惠
            List<OrderDiscount> orderDiscountList = queryOrderDiscountListTmp(orderList);
            //批量查询地址
            OrderAddressQuery orderAddressQuery = new OrderAddressQuery();
            orderAddressQuery.setOrderNoList(orderNoList);
            List<OrderAddr> orderAddrList = tmpOrderAddrDao.selectList(orderAddressQuery);
            //批量查询自提单
            QueryPerformanceDTO queryPerformanceDTO = new QueryPerformanceDTO();
            queryPerformanceDTO.setOrderNoList(orderNoList);
            List<PerformanceSelfTake> takeList = tmpPerformanceSelfTakeDao.selectList(queryPerformanceDTO);

            //批量查询退款单
            RefundQuery refundQuery = new RefundQuery();
            refundQuery.setOrderNoList(orderNoList);
            List<Refund> refundList = tmpRefundDao.selectList(refundQuery);
            List<RefundItem> refundItemList = new ArrayList<>();
            //批量查询退款商品
            if (!CollectionUtils.isEmpty(refundList)) {
                List<String> refundNoList = refundList.stream().map(Refund::getRefundNo).collect(Collectors.toList());
                RefundItemQuery refundItemQuery = new RefundItemQuery();
                refundItemQuery.setRefundNoList(refundNoList);
                refundItemList = tmpRefundItemDao.selectList(refundItemQuery);
            }

            //订单
            for (Order order : orderList) {
                order.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                order.setSellerId(sellerId);
                order.setStoreId(storeId);
                order.setUserId(userId);
                OrderIndex orderIndex = new OrderIndex();
                orderIndex.setOrderId(order.getId());
                orderIndex.setOrderNo(order.getOrderNo());
                orderIndex.setBizType(4);
                orderIndex.setUserId(order.getUserId());
                orderIndex.setCreatedAt(order.getCreatedAt());
                orderIndex.setIsDeleted(order.getIsDeleted());
                orderIndexList.add(orderIndex);
            }
            OrderQuery orderQuery = new OrderQuery();
            orderQuery.setOrderNoList(orderNoList);
            orderQuery.setUserId(userId);
            List<Order> orderList1 = orderDao.selectList(orderQuery);
            if (!CollectionUtils.isEmpty(orderList1)) {
                orderDao.deleteTemp(orderNoList, userId);
            }
            orderDao.insertList(orderList);

            List<OrderIndex> orderIndexList1 = orderIndexDao.selectList(orderNoList);
            if (!CollectionUtils.isEmpty(orderIndexList1)) {
                for (OrderIndex orderIndex: orderIndexList1) {
                    orderIndexDao.delete(orderIndex.getOrderNo(), orderIndex.getId());
                }
            }
            orderIndexDao.insertList(orderIndexList);

            searchManager.indexOrder(orderList);
            //商品
            for (OrderItem orderItem : itemList) {
                orderItem.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                orderItem.setSellerId(sellerId);
                orderItem.setUserId(userId);
                orderItemDao.deleteTemp(orderItem.getOrderNo(), userId);
            }
            if (!CollectionUtils.isEmpty(itemList)) {
                orderItemDao.inserts(itemList);
            }

            //优惠
            for (OrderDiscount orderDiscount : orderDiscountList) {
                orderDiscount.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                orderDiscount.setSellerId(sellerId);
                orderDiscount.setUserId(userId);
                orderDiscountDao.deleteTemp(orderDiscount.getOrderNo(), userId);
            }
            if (!CollectionUtils.isEmpty(orderDiscountList)) {
                orderDiscountDao.inserts(orderDiscountList);
            }

            //地址
            for (OrderAddr addr : orderAddrList) {
                addr.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                addr.setSellerId(sellerId);
                addr.setUserId(userId);
                orderAddrDao.deleteTemp(addr.getOrderNo(), userId);
            }
            if (!CollectionUtils.isEmpty(orderAddrList)) {
                orderAddrDao.inserts(orderAddrList);
            }

            //自提
            for (PerformanceSelfTake take : takeList) {
                take.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                take.setStoreId(storeId);
                take.setSellerId(sellerId);
                take.setUserId(userId);
                performanceSelfTakeDao.deleteTemp(take.getOrderNo(), userId);
                performanceSelfTakeDao.insert(take);
            }

            //退款单
            for (Refund refund : refundList) {
                refund.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                refund.setSellerId(sellerId);
                refund.setUserId(userId);
                refund.setStoreId(storeId);
                if (Objects.isNull(refund.getPerformanceType())) {
                    refund.setPerformanceType(0);
                }
                refundDao.deleteTemp(refund.getOrderNo(), userId);
                refundDao.insert(refund);
            }
            //退款商品
            for (RefundItem refundItem : refundItemList) {
                refundItem.setId(shardingKeyGenerator.generateSnowflakeNumKey());
                refundItem.setSellerId(sellerId);
                refundItem.setUserId(userId);
                refundItemDao.deleteTemp(refundItem.getOrderNo(), userId);
            }
            if (!CollectionUtils.isEmpty(refundItemList)) {
                refundItemDao.inserts(refundItemList);
            }

            lastId = orderList.get(orderList.size() - 1).getId();
            count += orderList.size();
            logger.info("retailTransfer1Beta:count:{};lastId:{}", count, lastId);
            if (orderList.size() < 300) {
                break;
            }
            break;
        }
    }

    @Override
    public Result retailTransferRefund(OrderDataReviseRequest request) {
        Long lastId = 424237644686348440L;
        RefundQuery query = new RefundQuery();
        query.setSellerId(oldSellerId);
        query.setSize(200);
        int count = 0;
        try {
            for (;;) {
                query.setLastId(lastId);
                List<Refund> refundList = refundDao.selectList(query);
                if (CollectionUtils.isEmpty(refundList)) {
                    break;
                }
                lastId = refundList.get(refundList.size() - 1).getId();
                count += refundList.size();
                logger.info("retailTransferRefund_count:{};lastId:{}", count, lastId);

                //批量查询退款商品
                List<String> refundNoList = refundList.stream().map(Refund::getRefundNo).collect(Collectors.toList());
                RefundItemQuery refundItemQuery = new RefundItemQuery();
                refundItemQuery.setRefundNoList(refundNoList);
                List<RefundItem> refundItemList = refundItemDao.selectList(refundItemQuery);
                //按退款单号分组
                Map<String, List<RefundItem>> refundItemMap = refundItemList.stream().collect(Collectors.groupingBy(RefundItem::getRefundNo));

                List<RefundItem> newRefundItemList = new ArrayList<>(refundItemList.size());
                if (!CollectionUtils.isEmpty(refundList)) {
                    for (Refund refund : refundList) {
                        buildRefundExtra(refund);
                        convertOrderType(refund);
                        buildRefundStatus(refund);
                        buildRefundParams(refund, refundItemMap, newRefundItemList);
                        buildRefundWay(refund);
                        refund.setBizType(baking);
                        refund.setSellerId(newSellerId);
                        refund.setStoreId(converStoreId(refund.getStoreId()));
                    }
                }
                logger.info("retailTransferRefund_refundItemListCount:{};lastId:{}", refundItemList.size(), lastId);

                //批量修改退款表
                if (!CollectionUtils.isEmpty(refundList)) {
                    refundDao.updateBatch(refundList, baking, newSellerId);
                }
                //批量修改退款商品表itemType 和 isDeleted
                if (!CollectionUtils.isEmpty(newRefundItemList)) {
                    refundItemDao.updateBatch(newRefundItemList, newSellerId);
                }

                if (refundList.size() < 200) {
                    break;
                }
            }
            logger.info("retailTransferRefund_end:{};lastId:{}", count, lastId);
            return Result.successNullData();
        } catch (Throwable e) {
            logger.error("retailTransferRefund_error[rerouting] failed!, cause by:{}", e);
            return Result.failureData(e);
        }
    }
}
