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

import cn.qmai.data.encrypt.service.DataEncryptService;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zm.order.tool.server.cipher.OrderEncryptionHandler;
import com.zm.order.tool.server.component.ShardingKeyGenerator;
import com.zm.order.tool.server.constants.CommonConstants;
import com.zm.order.tool.server.constants.ListSellerConst;
import com.zm.order.tool.server.dao.*;
import com.zm.order.tool.server.enums.BizTypeEnum;
import com.zm.order.tool.server.helper.OrderDataHandleHelper;
import com.zm.order.tool.server.helper.SplitResult;
import com.zm.order.tool.server.history.*;
import com.zm.order.tool.server.manager.*;
import com.zm.order.tool.server.message.BatchSyncEsMessage;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.newdatasource.*;
import com.zm.order.tool.server.query.OrderCommentQuery;
import com.zm.order.tool.server.query.OrderPayDetailsQuery;
import com.zm.order.tool.server.query.OrderQuery;
import com.zm.order.tool.server.query.RefundQuery;
import com.zm.order.tool.server.request.ListOrderRequest;
import com.zm.order.tool.server.service.OrderRoutingService;
import com.zm.order.tool.server.stream.convert.OrderStreamConverter;
import com.zm.order.tool.server.stream.convert.PayDetailStreamConverter;
import com.zm.order.tool.server.stream.convert.RefundDetailsStreamConverter;
import com.zm.order.tool.server.stream.convert.RefundStreamConverter;
import com.zm.order.tool.server.stream.factory.MapperFactory;
import com.zm.order.tool.server.tempdb.*;
import com.zm.order.tool.server.utils.CommonUtils;
import com.zm.order.tool.server.utils.DateUtils;
import com.zm.util.dto.Result;
import org.apache.commons.lang3.StringUtils;
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.Assert;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author nianchang
 * @date 2022/01/25 3:57 下午
 */
@Service
@SuppressWarnings("all")
public class OrderRoutingServiceImpl implements OrderRoutingService, InitializingBean {

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

    private BlockingQueue workQueue;

    private ExecutorService executorService;

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

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

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

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

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private OrderDataHandleHelper orderDataHandleHelper;

    @Autowired
    private NewHintManager hintManager;

    @Autowired
    private CommonManager commonManager;

    @Autowired
    private SearchRefundManager refundManager;

    @Autowired
    private OrderNoUserDao noUserDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderItemDao itemDao;
    @Autowired
    private OrderDiscountDao discountDao;
    @Autowired
    private OrderPayDetailsDao payDetailsDao;
    @Autowired
    private OrderAddrDao addrDao;
    @Autowired
    private OrderItemBatchingDao batchingDao;
    @Autowired
    private PerformanceSelfTakeDao selfTakeDao;
    @Autowired
    private OrderExtendsDao extendsDao;
    @Autowired
    private OrderStreamConverter orderStreamConverter;

    @Autowired
    private PayDetailStreamConverter payStreamConverter;

    @Autowired
    private RefundStreamConverter refundStreamConverter;

    @Autowired
    private RefundDetailsStreamConverter detailsStreamConverter;

    @Autowired
    private NewDataSourceOrderDao newOrderDao;

    @Autowired
    private NewDataSourceOrderPayDetailsDao newPayDao;

    @Autowired
    private NewDataSourceRefundDao newRefundDao;

    @Autowired
    private NewDataSourceOrderRefundDetailsDao newRefundDetailDao;

    @Autowired
    private NewDataSourceOrderCommentDao newCommentDao;

    @Autowired
    private NewDataSourceOrderItemCommentDao newItemCommentDao;

    @Autowired
    private SearchManager searchManager;

    @Override
    public void routing() {
        int count = 0;
        OrderQuery orderQuery = new OrderQuery();
//        orderQuery.setMaxId(713015960788865025L);
//        orderQuery.setExcludeSellerId(40927L);
//        orderQuery.setUpdatedAtEnd(new Date(1645977600000L));
        orderQuery.setSize(200);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    int loop = 0;
                    Long lastId = null;
                    Map<String, List<Order>> orderMap = new HashMap<>(262144);
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        long startAt = System.currentTimeMillis();
                        List<Order> orderList = commonManager.scanOrder(orderQuery, i, j);
                        long endAt = System.currentTimeMillis() - startAt;
                        if (endAt >= 500) {
                            logger.info("routing_query_time:{}ms", endAt);
                        }
                        if (CollectionUtils.isEmpty(orderList)) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute(k, v));
                            }
                            break;
                        }
                        for (Order order : orderList) {
                            groupOrder(order, orderMap);
                        }
                        if (++loop >= 100) {
                            orderMap.forEach((k, v) -> execute(k, v));
                            orderMap.clear();
                            loop = 0;
                        }
                        count += orderList.size();
                        logger.info("routing_count:{}条", count);
                        if (orderList.size() < 200) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute(k, v));
                            }
                            break;
                        }
                        lastId = orderList.get(orderList.size() - 1).getId();
                        logger.info("routing_last_id:{},i:{},j:{}", lastId, i, j);

                        Result<String> redisData = redisManager.get("routing_order_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[routing]shut down！");
                            return;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[RoutingServiceImpl]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void execute(String shardKey, List<Order> orderList) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 1) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                String[] split = shardKey.split("-");
                for (List<Order> orders : Lists.partition(orderList, 50)) {
                    hintManager.replaceOrder(orders, Integer.valueOf(split[0]), Integer.valueOf(split[1]));
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private void groupOrder(Order order, Map<String, List<Order>> orderMap) {
        // 计算在新数据库中的路由
        final Long userId = order.getUserId();
        int dbIndex = RoutingAlgorithm.routeDB(userId, dbSize);
        int tbIndex = RoutingAlgorithm.routeTB(userId, dbSize, tbSize);
        // 按照路由结果进行分组，用于批量查询
        String key = dbIndex + "-" + tbIndex;
        List<Order> orderList = null;
        if (!orderMap.containsKey(key)) {
            orderList = new ArrayList<>();
        } else {
            orderList = orderMap.get(key);
        }
        orderList.add(order);
        orderMap.put(key, orderList);
    }

    @Override
    public void check() {
        int count = 0;
        AtomicInteger diffCount = new AtomicInteger();
        AtomicInteger sameCount = new AtomicInteger();
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setMaxId(715586871182270464L);
//        orderQuery.setExcludeSellerId(40927L);
        orderQuery.setSize(1000);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    int loop = 0;
                    Long lastId = 714628532138975232L;
                    Map<String, List<Order>> orderMap = new HashMap<>(262144);
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        List<Order> orderList = commonManager.scanOrder(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(orderList)) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            }
                            break;
                        }
                        for (Order order : orderList) {
                            groupOrder(order, orderMap);
                        }
                        if (++loop >= 100) {
                            orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            orderMap.clear();
                            loop = 0;
                        }
                        count += orderList.size();
                        logger.info("CHECK_COUNT:{}条", count);

                        if (orderList.size() < 1000) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            }
                            break;
                        }
                        lastId = orderList.get(orderList.size() - 1).getId();
                        logger.info("check_last_id:{},i:{},j:{}", lastId, i, j);

                        Result<String> redisData = redisManager.get("check_order_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[check]shut down！");
                            return;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[RoutingServiceImpl]check failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void execute0(String k, List<Order> orderList, AtomicInteger diffCount, AtomicInteger sameCount) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                String[] split = k.split("-");
                List<Long> idList = orderList.stream().map(Order::getId).collect(Collectors.toList());
                List<Order> newOrderList = hintManager.selectOrderById(idList, Integer.valueOf(split[0]), Integer.valueOf(split[1]));
                if (newOrderList.size() != orderList.size()) {
                    logger.info("FIND_COUNT_DIFF,newOrderList:{}条,orderList:{}条", newOrderList.size(), orderList.size());
                }
                this.compare11(orderList, newOrderList, diffCount, sameCount);
                logger.info("COMPARE_ORDER_COUNT,diffCount:{}条,sameCount:{}条", diffCount, sameCount);
            } catch (Exception e) {
                logger.error("[execute0]failed！cause by:{}", e);
            }
        });
    }

    private void compare(List<Order> oldList, List<Order> newList, AtomicInteger diffCount, AtomicInteger sameCount) {
        Map<String, List<Order>> oldMap = oldList.stream().collect(Collectors.groupingBy(order -> {
            return order.getOrderNo() + "-" + order.getUserId();
        }));
        for (Order newOrder : newList) {
            String s = newOrder.getOrderNo() + "-" + newOrder.getUserId();
            List<Order> oldOrders = oldMap.get(s);
            if (CollectionUtils.isEmpty(oldOrders)) {
                Order oldData = oldOrders.get(0);
                orderDao.updateUpdated(oldData.getId(), oldData.getUserId());
                logger.info("ORDER_EMPTY, key:{}", s);
                continue;
            }
            logger.info("COMPARE_ORDER! orderNo:{}", oldOrders.get(0).getOrderNo());
            String newData = JSON.toJSONString(newOrder);
            String oldData = JSON.toJSONString(oldOrders.get(0));
            if (!Objects.equals(newData, oldData)) {
                OrderNoUser noUser = buildParam(newOrder);
                noUserDao.insert(noUser);
                diffCount.incrementAndGet();
                logger.info("FIND_DIFF_ORDER,orderNo:{}, old:{}, new:{}", newOrder.getOrderNo(), oldData, newOrder);
            } else {
                sameCount.incrementAndGet();
            }
        }
    }

    @Autowired
    private OrderStreamConverter streamConverter;


    private void compare11(List<Order> oldList, List<Order> newList, AtomicInteger diffCount, AtomicInteger sameCount) {
        Map<String, List<Order>> newMap = newList.stream().collect(Collectors.groupingBy(order -> {
            return order.getOrderNo() + "-" + order.getUserId();
        }));
        for (Order oldOrder : oldList) {
            String s = oldOrder.getOrderNo() + "-" + oldOrder.getUserId();
            List<Order> newOrders = newMap.get(s);
            if (CollectionUtils.isEmpty(newOrders)) {
                orderDao.updateUpdated(oldOrder.getId(), oldOrder.getUserId());
                logger.info("ORDER_EMPTY, orderNo:{}, userId:{}", oldOrder.getOrderNo(), oldOrder.getUserId());
                continue;
            }

            logger.info("COMPARE_ORDER! orderNo:{}, userId:{}", oldOrder.getOrderNo(), oldOrder.getUserId());
            Order converted = (Order) streamConverter.streamIn(oldOrder);
            String oldData = JSON.toJSONString(converted);
            String newData = JSON.toJSONString(newOrders.get(0));
            if (!Objects.equals(newData, oldData)) {
                OrderNoUser noUser = buildParam(oldOrder);
                noUserDao.insert(noUser);
                diffCount.incrementAndGet();
                logger.info("FIND_DIFF_ORDER! orderNo:{}, old:{}, new:{}", oldOrder.getOrderNo(), oldData, newData);
            } else {
                sameCount.incrementAndGet();
            }
        }
    }

    private OrderNoUser buildParam(Order order) {
        OrderNoUser noUser = new OrderNoUser();
        noUser.setOrderNo(order.getOrderNo());
        noUser.setUserId(order.getUserId());
        noUser.setOrderId(order.getId());
        noUser.setType(1);
        return noUser;
    }


    @Override
    public void updateData() {
        int count = 0;
        Date now = new Date();
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setExcludeSellerId(40927L);
        orderQuery.setUpdatedAtStart(DateUtils.before(now, Calendar.DAY_OF_YEAR, 30));
        orderQuery.setUpdatedAtEnd(now);
        orderQuery.setSize(1000);
        try {
            for (int i = 0; i < oldDbSize; i++) {
                for (int j = 0; j < oldTbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        List<Long> orderIdList = commonManager.scanOrderId(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(orderIdList)) {
                            break;
                        }
                        execute1(orderIdList, i, j);
                        count += orderIdList.size();
                        logger.info("order_update_data_count:{}条", count);
                        if (orderIdList.size() < 1000) {
                            break;
                        }
                        lastId = orderIdList.get(orderIdList.size() - 1);
                        logger.info("order_update_data_last_id:{},i:{},j:{}", lastId, i, j);
                        Result<String> redisData = redisManager.get("update_data_order_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[ORDER_UPDATE_DATA]shut down！");
                            return;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[OrderRoutingServiceImpl]update data failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void execute1(List<Long> idList, int i, int j) {
        while (workQueue.remainingCapacity() < 10) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                commonManager.batchUpdateDate(idList, i, j);
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private BlockingQueue workQueue0;

    private ExecutorService executorService0;

    @Override
    public void checkTask() {
        OrderQuery orderQuery = buildQuery();
        AtomicInteger diff = new AtomicInteger();
        AtomicInteger same = new AtomicInteger();
        try {
            for (int i = 0; i < oldDbSize; i++) {
                for (int j = 0; j < oldTbSize; j++) {
                    List<Order> orders = commonManager.scanOrder(orderQuery, i, j);
                    if (CollectionUtils.isEmpty(orders)) {
                        break;
                    }
                    orders.forEach(o -> execute2(o, diff, same));
                }
            }
            logger.info("COMPARE0_ORDER_COUNT, diffCount:{}条, sameCount:{}条", diff, same);
        } catch (Exception e) {
            logger.error("[CHECK_TASK]failed! cause by:{0}", e);
        }
    }

    private void execute2(Order oldData, AtomicInteger diff, AtomicInteger same) {
        while (workQueue0.remainingCapacity() < 100) {
            logger.info("workQueue2 size:{}", workQueue.size());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService0.submit(() -> {
            try {
                compare0(oldData, diff, same);
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private OrderQuery buildQuery() {
        Date nowDate = new Date();
        Date beforeDate0 = DateUtils.before(nowDate, Calendar.MINUTE, 3);
        Date beforeDate1 = DateUtils.before(nowDate, Calendar.MINUTE, 5);
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setUpdatedAtEnd(beforeDate0);
        orderQuery.setUpdatedAtStart(beforeDate1);
        orderQuery.setSize(1000);
        return orderQuery;
    }

    private void compare0(Order oldOrder, AtomicInteger diff, AtomicInteger same) {
        List<Order> newOrders = this.getNewOrders(oldOrder);
        if (CollectionUtils.isEmpty(newOrders)) {
            return;
        }
        String oldData = JSON.toJSONString(oldOrder);
        String newData = JSON.toJSONString(newOrders.get(0));
        if (!Objects.equals(newData, oldData)) {
            OrderNoUser noUser = buildParam(oldOrder);
            noUserDao.insert(noUser);
            diff.incrementAndGet();
            logger.info("FIND_DIFF_ORDER0,old:{}, new:{}", oldData, newData);
        } else {
            same.incrementAndGet();
        }
    }

    private List<Order> getNewOrders(Order oldOrder) {
        final Long userId = oldOrder.getUserId();
        int dbIndex = RoutingAlgorithm.routeDB(userId, dbSize);
        int tbIndex = RoutingAlgorithm.routeTB(userId, dbSize, tbSize);
        return hintManager.selectOrderById(Lists.newArrayList(oldOrder.getId()), dbIndex, tbIndex);
    }

    @Override
    public void count(ListOrderRequest request) {
        int count = 0;
        Long lastId = request.getLastId();
        OrderQuery query = new OrderQuery();
        query.setMaxId(request.getMaxId());
//        query.setMaxId(713015960788865025L);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    query.setLastId(lastId);
                    count += hintManager.orderCount(query, i, j);
                }
            }
            logger.info("order_count:{}条", count);
        } catch (Exception e) {
            logger.error("[OrderRoutingServiceImpl]count data failed! cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Override
//    @Scheduled(cron = "0 0 1 * * ?")
    public void checkByOne() {
        int count = 0;
        Date date = new Date();
        AtomicInteger diffCount = new AtomicInteger();
        AtomicInteger sameCount = new AtomicInteger();
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSortFlag(1);
//        orderQuery.setUpdatedAtEnd(new Date(1652112000000L));
//        orderQuery.setUpdatedAtStart(new Date(1652104800000L));
//        orderQuery.setUpdatedAtEnd(new Date(1652117400000L));
//        orderQuery.setUpdatedAtStart(new Date(1652112000000L));

        orderQuery.setUpdatedAtEnd(new Date(1652119200000L));
        orderQuery.setUpdatedAtStart(new Date(1652117400000L));
        orderQuery.setPageSize(1000);
        try {
            for (int i = 0; i < oldDbSize; i++) {
                for (int j = 0; j < oldTbSize; j++) {
                    int loop = 0;
                    int page = 1;
                    Map<String, List<Order>> orderMap = new HashMap<>(262144);
                    for (; ; ) {
                        orderQuery.setPageNo(page);
                        List<Order> orderList = commonManager.scanOrder(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(orderList)) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            }
                            break;
                        }
                        for (Order order : orderList) {
                            groupOrder(order, orderMap);
                        }
                        if (++loop >= 100) {
                            orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            orderMap.clear();
                            loop = 0;
                        }
                        page++;
                        count += orderList.size();
                        logger.info("CHECK_BY_ONE_COUNT:{}条", count);
                        if (orderList.size() < 1000) {
                            if (!CollectionUtils.isEmpty(orderMap)) {
                                orderMap.forEach((k, v) -> execute0(k, v, diffCount, sameCount));
                            }
                            break;
                        }

                        Result<String> redisData = redisManager.get("check_order_by_one_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[check]shut down！");
                            return;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[RoutingServiceImpl]checkByOne failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private static List<String> orderNoList = new ArrayList<>();

    static {
        // 餐饮堂食
        orderNoList.add("D32167988851530121223");
        // 餐饮外带
        orderNoList.add("D69167988856339316339");
        // 餐饮外卖
        orderNoList.add("D12167988719170656895");
        // 餐饮到店自取
        orderNoList.add("D40167980901829064892");
        // 餐饮商城
        orderNoList.add("D52167948419301057274");
        // 餐饮多人点餐
        orderNoList.add("D37167931085335790752");

        // 烘焙商城
        orderNoList.add("44167924230986211949");
        // 烘焙多人点餐
        orderNoList.add("33167973040804920387");
        // 烘焙 status = 4
        orderNoList.add("44167926929165223004");
        // 烘焙 source = 2
        orderNoList.add("00167938324311473602");
        // 烘焙 payType = 266
        orderNoList.add("88167971915724366315");

    }

    @Override
    public void orderConvert() {
        int count = 0;
        int size = 500;
        Date endAt = CommonUtils.getEndAt();
        logger.info("orderConvert, The end time get success. endAt:{}", endAt.getTime());
        if (endAt == null) {
            return;
        }

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSize(size);
        try {
            for (Long sellerId : ListSellerConst.list) {
                orderQuery.setSellerId(sellerId);
                for (int i = 0; i < dbSize; i++) {
                    for (int j = 0; j < tbSize; j++) {
                        Long lastId = null;
                        for (; ; ) {
                            orderQuery.setLastId(lastId);
                            List<Long> idList = commonManager.scanOrderId(orderQuery, i, j);
                            if (CollectionUtils.isEmpty(idList)) {
                                break;
                            }
                            List<Order> orderList = commonManager.listOrderById(idList, i, j);

                            execute0(orderList, i, j);

                            count += orderList.size();
                            lastId = orderList.get(orderList.size() - 1).getId();
                            logger.info("orderConvert,convert_order_last_id_1:{}, count:{}, i:{}, j:{}, sellerId:{}",
                                    lastId, count, i, j, sellerId);

                            Result<String> redisData = redisManager.get("convert_order_shut_down_key_44");
                            if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                                logger.info("[orderConvert]shut down！");
                                return;
                            }
                            if (new Date().after(endAt)) {
                                logger.info("orderConvert,[time_end]shut down！sellerId:{},lastId:{}", sellerId, lastId);
                                return;
                            }
                            if (idList.size() < size) {
                                break;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[orderConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }


    /**
     *
     * 新库订单数据是老的枚举修复
     * 从新库读，改新库 自动同步老库
     */
    @Override
    public void orderConvertFixNew() {
        int count = 0;
        int size = 500;

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSize(size);
        try {
            Long lastId = 0L;
            for (; ; ) {
                orderQuery.setLastId(lastId);
                List<IdOrderNoFix> idOrderNoFixes = fixDao.selectListByIdSize(lastId, size);
                if (CollectionUtils.isEmpty(idOrderNoFixes)) {
                    break;
                }
                List<Long> idList = idOrderNoFixes.stream().map(IdOrderNoFix::getOrderId).collect(Collectors.toList());
                for (IdOrderNoFix idOrderNoFix : idOrderNoFixes) {
                    int i = getDb(idOrderNoFix.getUserId());
                    int j = getTb(idOrderNoFix.getUserId());
                    Order order = newOrderDao.selectByOrderNo(idOrderNoFix.getOrderNo(), idOrderNoFix.getUserId());
                    if(order == null){
                        continue;
                    }
                    List<Order> orderList = Arrays.asList(order);
                    executeFromNew(orderList, i, j);
                }

                count += idOrderNoFixes.size();
                lastId = idOrderNoFixes.get(idOrderNoFixes.size() - 1).getId();

                logger.info("orderConvertFixNew,convert_order_last_id_1:{}, count:{}",
                        lastId, count);

                Result<String> redisData = redisManager.get("convert_order_shut_down_key_3");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    logger.info("[orderConvertFixNew]shut down！");
                    return;
                }
                if (idList.size() < size) {
                    break;
                }
            }
            logger.info("[orderConvertFixNew][end]");

        } catch (Exception e) {
            logger.error("[orderConvertFix]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }



    @Override
    public void orderConvertFixType(Order order) {
        Assert.notNull(order.getOrderNo(), "订单号为空");
        OrderIndex orderIndex = indexDao.selectOne(order.getOrderNo());
        if (Objects.isNull(orderIndex)) {
            throw new RuntimeException("订单索引不存在");
        }
        Order o = newOrderDao.selectByOrderNo(order.getOrderNo(), orderIndex.getUserId());
        if (Objects.isNull(o)) {
            throw new RuntimeException("订单不存在");
        }
        // 枚举值
        Order newOrder = (Order) orderStreamConverter.streamIn(o);
        newOrderDao.replaceList(Lists.newArrayList(newOrder));
        try {
            searchManager.indexOrder(newOrder, CommonConstants.ES_NEW_INDEX_TOPIC);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        handleEachPay(newPayDao.selectByOrderNo(newOrder.getOrderNo(), newOrder.getUserId()));

    }

    private void handleEachPay(List<OrderPayDetails> payDetailsList) {
        for (OrderPayDetails orderPayDetails : payDetailsList) {
            OrderPayDetails p = (OrderPayDetails) orderStreamConverter.streamIn(orderPayDetails);
            Order order = newOrderDao.selectByOrderNo(orderPayDetails.getOrderNo(), orderPayDetails.getUserId());
            if (order != null) {
                p.setBizType(order.getBizType());
                p.setOrderType(order.getOrderType());
                p.setOrderSubType(order.getOrderSubType());
                p.setPerformanceType(order.getPerformanceType());
            }
            payDetailsDao.replace(p);
        }
    }


    @Autowired
    private IdOrderNoFixDao fixDao;

    public static void main(String[] args) {
        Long userId = 1021454700439907968L;
        int hashCode = userId.toString().hashCode();
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        long db = hashCode % 32;
        long tb = hashCode / 32 % 32;
        System.out.println(db);
        System.out.println(tb);
    }

    private int getDb(Long userId) {
        int hashCode = userId.toString().hashCode();
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        return hashCode % dbSize;
    }

    private int getTb(Long userId) {
        int hashCode = userId.toString().hashCode();
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        return hashCode / 32 % tbSize;
    }


    @Override
    public void orderConvertFix() {
        int count = 0;
        int size = 500;

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSize(size);
        try {
            Long lastId = 0L;
            for (; ; ) {
                orderQuery.setLastId(lastId);
                List<IdOrderNoFix> idOrderNoFixes = fixDao.selectListByIdSize(lastId, size);
                if (CollectionUtils.isEmpty(idOrderNoFixes)) {
                    break;
                }
                List<Long> idList = idOrderNoFixes.stream().map(IdOrderNoFix::getOrderId).collect(Collectors.toList());
                for (IdOrderNoFix idOrderNoFix : idOrderNoFixes) {
                    int i = getDb(idOrderNoFix.getUserId());
                    int j = getTb(idOrderNoFix.getUserId());
                    List<Order> orderList = commonManager.listOrderById(idList, i, j);
                    execute0(orderList, i, j);
                }

                count += idOrderNoFixes.size();
                lastId = idOrderNoFixes.get(idOrderNoFixes.size() - 1).getId();

                logger.info("orderConvertFix,convert_order_last_id_1:{}, count:{}",
                        lastId, count);

                Result<String> redisData = redisManager.get("convert_order_shut_down_key_3");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    logger.info("[orderConvertFix]shut down！");
                    return;
                }
                if (idList.size() < size) {
                    break;
                }
            }
            logger.info("[orderConvertFix][end]");

        } catch (Exception e) {
            logger.error("[orderConvertFix]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private static int count = 0;

    public void doTable(OrderQuery orderQuery, int i, int j, Long sellerId, int sellerTotalCount) {
        try {
            logger.info("orderConvert[tableStart],i:{}, j:{}, sellerId:{}", i, j, sellerId);
            Long lastId = null;
            int tableCount = 0;
            for (; ; ) {
                orderQuery.setLastId(lastId);

                List<Long> idList = commonManager.scanOrderId(orderQuery, i, j);
                if (CollectionUtils.isEmpty(idList)) {
                    break;
                }

                List<Order> orderList = commonManager.listOrderById(idList, i, j);

                executeWithOutThread(orderList, i, j);

                int orderListSize = orderList.size();
                sellerTotalCount += orderListSize;
                count += orderListSize;
                tableCount += orderListSize;

                lastId = orderList.get(orderListSize - 1).getId();
                logger.info("orderConvert,convert_order_last_id_1:{}, count:{}, i:{}, j:{}, sellerId:{}",
                        lastId, count, i, j, sellerId);
                Result<String> redisData = redisManager.get("convert_order_shut_down_key_3");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    logger.info("[orderConvert]shut down！");
                    return;
                }
                if (CommonUtils.getHour() == CommonUtils.stopHour) {
                    logger.info("orderConvert,[time_end]shut down！sellerId:{},lastId:{}", sellerId, lastId);
                    return;
                }
                if (idList.size() < CommonUtils.size) {
                    break;
                }
            }
            logger.info("orderConvert[tableEnd],lastId:{}, count:{}, i:{}, j:{}, sellerId:{}, sellerCount:{}",
                    lastId, count, i, j, sellerId, sellerTotalCount);
        } catch (Throwable e) {
            logger.error("orderConvert[doTable] failed!, cause by:{}", e);
        }
    }

    private void executeWithOutThread(List<Order> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        try {
            long s = System.currentTimeMillis();
            List<Order> converted = new ArrayList<>(orderList.size());
            orderList.forEach(each -> {
                // 枚举值
                Order newOrder = (Order) orderStreamConverter.streamIn(each);
                converted.add(newOrder);
            });
            if (!CollectionUtils.isEmpty(converted)) {
                newOrderDao.replaceList(converted);
                List<Order> orderList1 = hintManager.selectOrderById(converted.stream().map(Order::getId).collect(Collectors.toList()), i, j);
                searchManager.indexOrder(filter(orderList1), CommonConstants.ES_NEW_INDEX_TOPIC);
            }
            logger.info("orderConvert[running]: time:{}, threadName:{}", System.currentTimeMillis() - s,
                    Thread.currentThread().getName());
            long s1 = System.currentTimeMillis();
            syncHandlePay(i, j, converted);
            logger.info("Pay details handle time:{}", System.currentTimeMillis() - s1);
        } catch (Exception e) {
            logger.error("[order_execute]failed！cause by:{}", e);
        }

    }


    @Autowired
    private TempOrderDao tempOrderDao;

    @Override
    public void repairOrder() {
        Date endAt = getEndAt();
        OrderQuery query = new OrderQuery();
        int count = 0;
        for (int i = 0; i < dbSize; i++) {
            for (int j = 0; j < tbSize; j++) {
                Long lastId = null;
                query.setSize(500);
                for (; ; ) {
                    query.setDbIndex(i + 1);
                    query.setTbIndex(j);
                    query.setLastId(lastId);
                    List<TempOrder> tempOrderList = tempOrderDao.selectList(query);
                    if (CollectionUtils.isEmpty(tempOrderList)) {
                        break;
                    }

                    tempOrderList.forEach(e -> {
                        OrderIndex orderIndex = indexDao.selectOne(e.getOrderNo());
                        if (orderIndex != null) {
//                            Order order = orderDao.selectByOrderNo(orderIndex.getOrderNo(), orderIndex.getUserId());
//                            if (order != null) {
//                                executeRepairOrder(order);
//                            }
                            executeRepairOrderTemp(orderIndex);
                        }
                    });

                    count += tempOrderList.size();
                    logger.info("convert order repair, count:{}", count);
                    if (tempOrderList.size() < 500) {
                        break;
                    }
                    lastId = tempOrderList.get(tempOrderList.size() - 1).getId();
                }
            }
        }
    }

    private void executeRepairOrder(Order order) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                long s = System.currentTimeMillis();

                // 枚举值
                Order newOrder = (Order) orderStreamConverter.streamIn(order);
                newOrderDao.replaceList(Lists.newArrayList(newOrder));

                Order newOrder1 = newOrderDao.selectByOrderNo(newOrder.getOrderNo(), newOrder.getUserId());
                searchManager.indexOrder(filter(Lists.newArrayList(newOrder1)), CommonConstants.ES_NEW_INDEX_TOPIC);
                logger.info("Order handle time:{}", System.currentTimeMillis() - s);

                long s1 = System.currentTimeMillis();
                eachOrderSyncHandlePay(Lists.newArrayList(newOrder1));
                logger.info("Pay details handle time:{}", System.currentTimeMillis() - s1);
            } catch (Exception e) {
                logger.error("[order_execute]failed！cause by:{}", e);
            }
        });
    }

    private void executeRepairOrderTemp(OrderIndex orderIndex) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                Order order = orderDao.selectByOrderNo(orderIndex.getOrderNo(), orderIndex.getUserId());
                if (order == null) {
                    order = newOrderDao.selectByOrderNo(orderIndex.getOrderNo(), orderIndex.getUserId());
                }

                if (order != null) {
                    if (Objects.equals(0, order.getMasterDataSource())) {
                        searchManager.indexOrder(order);
                    } else {
                        searchManager.indexOrder(order, CommonConstants.ES_NEW_INDEX_TOPIC);
                    }
                }
            } catch (Exception e) {
                logger.error("[order_execute]failed！cause by:{}", e);
            }
        });
    }

    private void eachOrderSyncHandlePay(List<Order> converted) {
        if (converted != null) {
            OrderPayDetailsQuery query = new OrderPayDetailsQuery();
            query.setPageNo(1);
            query.setPageSize(500);
            query.setOrderNoList(converted.stream().map(Order::getOrderNo).collect(Collectors.toList()));
            List<OrderPayDetails> payDetailsList = payDetailsDao.selectList(query);

            Map<String, List<Order>> orderMap = converted.stream().collect(Collectors.groupingBy(Order::getOrderNo));
            List<OrderPayDetails> payConverted = new ArrayList<>(converted.size());
            payDetailsList.forEach(each -> {
                rebuild(orderMap, payConverted, each);
            });
            if (!CollectionUtils.isEmpty(converted)) {
                List<List<OrderPayDetails>> partition = Lists.partition(payConverted, 200);
                for (List<OrderPayDetails> group : partition) {
                    newPayDao.replaceList(group);
                }
            }
        }
    }

    private Date getEndAt() {
        Calendar calendar = Calendar.getInstance();
        if (LocalTime.now().isAfter(LocalTime.parse("21:00"))) {
            Date d = DateUtils.getStartDate(DateUtils.next(new Date(), Calendar.DAY_OF_YEAR, 1));
            calendar.setTime(d);
            calendar.add(Calendar.HOUR_OF_DAY, 9);
            return calendar.getTime();
        }
        if (LocalTime.now().isBefore(LocalTime.parse("09:00"))) {
            Date d = DateUtils.getStartDate(new Date());
            calendar.setTime(d);
            calendar.add(Calendar.HOUR_OF_DAY, 9);
            return calendar.getTime();
        }
        return null;
    }


    @Autowired
    private OrderEncryptionHandler orderEncryption;

    @Autowired
    private DataEncryptService dataEncryptService;

    @Autowired
    private NewHintManager newHintManager;

    public void filterHave(List<Order> orderList, int i, int j) {
        OrderQuery query = new OrderQuery();
        query.setIdList(orderList.stream().map(Order::getId).collect(Collectors.toList()));
        List<Long> ids = newHintManager.scanRespId(query, i, j);
        // 如果新库找到了id，把orderList中的id对应的对象删除
        if (!CollectionUtils.isEmpty(ids)) {
            orderList.removeIf(order -> ids.contains(order.getId()));
        }
    }

    /**
     * <p>
     * 清洗枚举值
     * 加密扩展字段脱敏信息
     * 写入数据库
     * 写入ES
     * </p>
     *
     * @param orderList
     * @param i
     * @param j
     * @return
     */
    private void execute0(List<Order> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                long s = System.currentTimeMillis();
                List<Order> converted = new ArrayList<>(orderList.size());

                List<Order> orders1 = filterAt(orderList);
                if (CollectionUtils.isEmpty(orders1)) {
                    return;
                }
                orders1.forEach(each -> {
                    // 枚举值
                    Order newOrder = (Order) orderStreamConverter.streamIn(each);
                    converted.add(newOrder);
                });
                if (!CollectionUtils.isEmpty(converted)) {
                    long replaceListTime = System.currentTimeMillis();
                    List<List<Order>> partition = Lists.partition(converted, 100);
                    for (List<Order> orders : partition) {
                        newOrderDao.replaceList(orders);
                    }
                    logger.info("orderConvert[replaceListTime]: replaceListTime:{}, threadName:{}",
                            System.currentTimeMillis() - replaceListTime,
                            Thread.currentThread().getName());

                    long hintManagers = System.currentTimeMillis();

                    List<Order> orderList1 = hintManager.selectOrderById(converted.stream().map(Order::getId).collect(Collectors.toList()), i, j);
                    logger.info("orderConvert[hintManagerTime]: hintManagerTime:{}, threadName:{}",
                            System.currentTimeMillis() - hintManagers,
                            Thread.currentThread().getName());

                    long indexOrderTime = System.currentTimeMillis();
//                    List<Order> esList = orderDataHandleHelper.filterUpdateAt365(filter(orderList1));
                    fixEsMsg(filter(orderList1));
                    logger.info("orderConvert[indexOrderTime]: indexOrderTime:{}, threadName:{}",
                            System.currentTimeMillis() - indexOrderTime,
                            Thread.currentThread().getName());
                }
                logger.info("orderConvert[running]: time:{}, threadName:{}", System.currentTimeMillis() - s,
                        Thread.currentThread().getName());
                long s1 = System.currentTimeMillis();
                syncHandlePay(i, j, converted);
                logger.info("Pay details handle time:{}", System.currentTimeMillis() - s1);
            } catch (Exception e) {
                logger.error("[order_execute]failed！cause by:{}", e);
            }
        });
    }

    private List<Order> filterAt(List<Order> orderList) {
        List<Order> result = new ArrayList<>();
        for (Order order : orderList) {
            if (order.getOrderAt().getTime() > new Date(1717171200000L).getTime()) {
                result.add(order);
            }
        }
        return  result;
    }


    /**
     * <p>
     * 清洗枚举值
     * 加密扩展字段脱敏信息
     * 写入数据库
     * 写入ES
     * </p>
     *
     * @param orderList
     * @param i
     * @param j
     * @return
     */
    private void executeFromNew(List<Order> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
            try {
                long s = System.currentTimeMillis();
                List<Order> converted = new ArrayList<>(orderList.size());

                orderList.forEach(each -> {
                    // 枚举值
                    Order newOrder = (Order) orderStreamConverter.streamIn(each);
                    converted.add(newOrder);
                });
                if (!CollectionUtils.isEmpty(converted)) {
                    long replaceListTime = System.currentTimeMillis();
                    List<List<Order>> partition = Lists.partition(converted, 100);
                    newOrderDao.replaceList(converted);
                    logger.info("orderConvert[replaceListTime]: replaceListTime:{}, threadName:{}",
                            System.currentTimeMillis() - replaceListTime,
                            Thread.currentThread().getName());

                    long hintManagers = System.currentTimeMillis();

                    List<Order> orderList1 = hintManager.selectOrderById(converted.stream().map(Order::getId).collect(Collectors.toList()), i, j);
                    logger.info("orderConvert[hintManagerTime]: hintManagerTime:{}, threadName:{}",
                            System.currentTimeMillis() - hintManagers,
                            Thread.currentThread().getName());

                    long indexOrderTime = System.currentTimeMillis();
//                    List<Order> esList = orderDataHandleHelper.filterUpdateAt365(filter(orderList1));
                    fixEsMsg(filter(orderList1));
                    logger.info("orderConvert[indexOrderTime]: indexOrderTime:{}, threadName:{}",
                            System.currentTimeMillis() - indexOrderTime,
                            Thread.currentThread().getName());
                }
                logger.info("orderConvert[running]: time:{}, threadName:{}", System.currentTimeMillis() - s,
                        Thread.currentThread().getName());
                long s1 = System.currentTimeMillis();
                syncHandlePay(i, j, converted);
                logger.info("Pay details handle time:{}", System.currentTimeMillis() - s1);
            } catch (Exception e) {
                logger.error("[order_execute]failed！cause by:{}", e);
            }

    }

    @Autowired
    private AsyncMessageManager messageManager;

    private void fixEsMsg(List<Order> esList) {
        try {
            long millis = 10;
            Result<String> stringResult = redisManager.get("order-convert-es-msg-sleep-time");
            if (stringResult.isStatus() && Objects.nonNull(stringResult.getData())) {
                millis = Long.parseLong(stringResult.getData());
            }

            List<BatchSyncEsMessage> messageList = new ArrayList<>(500);
            for (Order order : esList) {
                messageList.add(buildMessage(order));
            }
            List<List<BatchSyncEsMessage>> partition = Lists.partition(messageList, 50);
            for (List<BatchSyncEsMessage> batchSyncEsMessages : partition) {
                messageManager.sendBatchSyncMessageNewOrder(batchSyncEsMessages);
                Thread.sleep(millis);
            }
        } catch (Throwable e) {
            logger.error("fixEsMsg[execute] 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 void executeSW10(List<Order> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 10) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                long s = System.currentTimeMillis();
                List<Order> converted = new ArrayList<>(orderList.size());
                filterHave(orderList, i, j);

                orderList.forEach(each -> {
                    // 枚举值
                    Order newOrder = (Order) orderStreamConverter.streamIn(each);
                    converted.add(newOrder);
                });
                if (!CollectionUtils.isEmpty(converted)) {
                    if (converted.size() > 100) {
                        SplitResult splitResult = OrderDataHandleHelper.splitList(converted);
                        List<Order> firstAndLastTen = splitResult.getFirstAndLastTen();
                        List<Order> remaining = splitResult.getRemaining();
                        newOrderDao.replaceList(remaining);
                        newOrderDao.replaceList(firstAndLastTen);
                    } else {
                        newOrderDao.replaceList(converted);
                    }
                    List<Order> orderList1 = hintManager.selectOrderById(converted.stream().map(Order::getId).collect(Collectors.toList()), i, j);
                    searchManager.indexOrder(filter(orderList1), CommonConstants.ES_NEW_INDEX_TOPIC);
                }
                logger.info("orderConvert[running]: time:{}, threadName:{}", System.currentTimeMillis() - s,
                        Thread.currentThread().getName());
                long s1 = System.currentTimeMillis();
                syncHandlePay(i, j, converted);
                logger.info("Pay details handle time:{}", System.currentTimeMillis() - s1);
            } catch (Exception e) {
                logger.error("[order_execute]failed！cause by:{}", e);
            } finally {
            }

        });
    }


    private void syncHandlePay(int i, int j, List<Order> converted) {
        if (converted != null) {
            OrderPayDetailsQuery query = new OrderPayDetailsQuery();
            query.setSize(2000);
            query.setOrderNoList(converted.stream().map(Order::getOrderNo).collect(Collectors.toList()));
            List<OrderPayDetails> payDetailsList = commonManager.scanPayDetailsList(query, i, j);

            Map<String, List<Order>> orderMap = converted.stream().collect(Collectors.groupingBy(Order::getOrderNo));
            List<OrderPayDetails> payConverted = new ArrayList<>(converted.size());
            payDetailsList.forEach(each -> {
                rebuild(orderMap, payConverted, each);
            });
            if (!CollectionUtils.isEmpty(converted)) {
                List<List<OrderPayDetails>> partition = Lists.partition(payConverted, 200);
                for (List<OrderPayDetails> group : partition) {
                    newPayDao.replaceList(group);
                }
            }
        }
    }

    @Override
    public void syncPayFromOldByOrderNo(String orderNo) {
        try {
            Assert.notNull(orderNo, "orderNo is null!");
            OrderIndex orderIndex = indexDao.selectOne(orderNo);
            Order order = orderDao.selectByOrderNo(orderNo, orderIndex.getUserId());
            List<Order> converted = Arrays.asList(order);
            orderIndex.getUserId();
            if (Objects.nonNull(order)) {
                List<OrderPayDetails> payDetailsList = payDetailsDao.selectByOrderNo(orderNo, orderIndex.getUserId());
                Map<String, List<Order>> orderMap = converted.stream().collect(Collectors.groupingBy(Order::getOrderNo));
                List<OrderPayDetails> payConverted = new ArrayList<>(converted.size());
                payDetailsList.forEach(each -> {
                    rebuild(orderMap, payConverted, each);
                });
                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<OrderPayDetails>> partition = Lists.partition(payConverted, 200);
                    for (List<OrderPayDetails> group : partition) {
                        newPayDao.replaceList(group);
                    }
                }
            }
        } catch (Throwable e) {
            logger.error("DelEsExpireDataTask[execute] failed!, cause by:{}", e);
        }

    }

    @Override
    public void orderMergeFix(String orderNo) {
        try {
            Assert.notNull(orderNo, "orderNo is null!");
            OrderIndex orderIndex = indexDao.selectOne(orderNo);
            Order order = orderDao.selectByOrderNo(orderNo, orderIndex.getUserId());
            orderIndex.getUserId();
            //改老库  master_data_source = 0, updated_at = now ()
            if (Objects.nonNull(order)) {
                // 改新库 master_data_source = 1,
                //  updated_at = now ()
                orderDao.updateMasterDataSource(0, order.getId(), order.getUserId());
                newOrderDao.updateMasterDataSource(1, order.getId(), order.getUserId());
                Order newOrder = newOrderDao.selectById(order.getId(), order.getUserId());
                searchManager.indexOrder(newOrder, CommonConstants.ES_NEW_INDEX_TOPIC);
            }
        } catch (Throwable e) {
            logger.error("orderMergeFix[orderMergeFix] failed!, cause by:{}", e);
        }
    }

    @Autowired
    private OrderUserRelationDao relationDao;

    private List<Order> filter(List<Order> converted) {
        List<Order> newList = new ArrayList<>(converted.size());
        for (Order order : converted) {
            Integer bizType = order.getBizType();
            if (bizType == 1 && order.getOrderSubType() == 1) {
                OrderUserRelation relation = relationDao.selectRoot(order.getOrderNo());
                if (relation == null) {
                    newList.add(order);
                    continue;
                }
                if (Objects.equals(order.getUserId(), relation.getUserId())) {
                    newList.add(order);
                }
                continue;
            }
            if ((bizType == 4 || bizType == 5 || bizType == 6 || bizType == 7)
                    && (order.getOrderSubType() == 1 || order.getOrderSubType() == 2)) {
                OrderUserRelation relation = relationDao.selectRoot(order.getOrderNo());
                if (relation == null) {
                    newList.add(order);
                    continue;
                }
                if (Objects.equals(order.getUserId(), relation.getUserId())) {
                    newList.add(order);
                }
                continue;
            }
            newList.add(order);
        }
        return newList;
    }

    @Override
    public void payConvert() {
        int count = 0;
        int size = 1000;
        Date endAt = getEndAt();
        logger.info("It's not time to start. endAt:{}", endAt);
        if (endAt == null) {
            return;
        }

        OrderPayDetailsQuery query = new OrderPayDetailsQuery();
        query.setSize(size);
//        query.setUpdatedAtStart(new Date(1648742400000L));
//        query.setUpdatedAtEnd(new Date(1681999200000L));
        try {
            for (Long sellerId : ListSellerConst.list) {
                query.setSellerId(sellerId);

                for (int i = 0; i < dbSize; i++) {
                    for (int j = 0; j < tbSize; j++) {
                        Long lastId = null;
                        for (; ; ) {
                            query.setLastId(lastId);

                            List<OrderPayDetails> idList = commonManager.scanPayDetailsId(query, i, j);
                            if (CollectionUtils.isEmpty(idList)) {
                                break;
                            }

                            List<OrderPayDetails> list = commonManager.queryPayDetailsListById(
                                    idList.stream().map(OrderPayDetails::getId).collect(Collectors.toList()), i, j);
                            if (CollectionUtils.isEmpty(list)) {
                                break;
                            }

                            executePay(list, i, j);

                            count += list.size();
                            lastId = list.get(list.size() - 1).getId();
                            logger.info("convert_pay_last_id:{}, count:{}, i:{},j:{}", lastId, count, i, j);

                            Result<String> redisData = redisManager.get("convert_pay_shut_down_key_12");
                            if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                                logger.info("[pay_convert_order]shut down！");
                                return;
                            }
                            if (new Date().after(endAt)) {
                                logger.info("[pay_time_end]shut down！sellerId:{},lastId:{}", sellerId, lastId);
                                return;
                            }
                            if (list.size() < size) {
                                break;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[orderConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void executePay(List<OrderPayDetails> list, int i, int j) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<String> orderNoList = list.stream().map(OrderPayDetails::getOrderNo).collect(Collectors.toList());
                HashSet<String> set = Sets.newHashSet(orderNoList);
                List<List<String>> lists = Lists.partition(Lists.newArrayList(set), 200);

                List<Order> orderList = new ArrayList<>();
                for (List<String> strings : lists) {
                    orderList.addAll(newHintManager.scanOrderByOrderNo(strings, i, j));
                }

                if (orderList != null) {
                    Map<String, List<Order>> collect = orderList.stream().collect(Collectors.groupingBy(Order::getOrderNo));
                    List<OrderPayDetails> converted = new ArrayList<>(list.size());

                    list.forEach(each -> {
                        rebuild(collect, converted, each);
                    });

                    if (!CollectionUtils.isEmpty(converted)) {
                        List<List<OrderPayDetails>> partition = Lists.partition(converted, 200);
                        for (List<OrderPayDetails> group : partition) {
                            newPayDao.replaceList(group);
                            Thread.sleep(10);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    public static final List<Integer> FILTER = Lists.newArrayList(4, 5, 6);

    private void rebuild(Map<String, List<Order>> collect, List<OrderPayDetails> converted, OrderPayDetails each) {
        List<Order> l1 = collect.get(each.getOrderNo());
        if (!CollectionUtils.isEmpty(l1)) {
            Order order = l1.get(0);
            Integer bizType = order.getBizType();

            // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
            each.setBizType(bizType);
            each.setSource(order.getSource());
            each.setOrderType(order.getOrderType());
            each.setOrderSubType(order.getOrderSubType());
            each.setPerformanceType(order.getPerformanceType());
            each.setPayType(MapperFactory.payTypeMap(bizType, each.getPayType()));
            converted.add(each);
        }
    }

    @Autowired
    private RefundDao refundDao;

    @Autowired
    private OrderRefundDetailsDao refundDetailsDao;

    @Autowired
    private NewDataSourceOrderRefundDetailsDao newRefundDetailsDao;

    @Override
    public void refundConvert() {
        int count = 0;
        int size = 500;
        RefundQuery query = new RefundQuery();
        query.setSize(size);

        for (Long sellerId : ListSellerConst.list) {
            Date s = null;
            Date e = null;
            String start = "2019-01-01";
            int sellerCount = 0;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            query.setSellerId(sellerId);

            for (; ; ) {
                Calendar c = getCalendar(start);
                start = sdf.format(c.getTime());
                s = DateUtils.getStartDate(c.getTime());

                logger.info("[refundConvert]start:{}, sellerId:{}", start, sellerId);

                if (new Date().before(s)) {
                    break;
                }

                e = DateUtils.getEndDate(c.getTime());

                query.setSortFlag(1);
                query.setUpdatedAtEnd(e);
                query.setUpdatedAtStart(s);
                Long lastId = null;
                for (; ; ) {
                    query.setLastId(lastId);
                    List<Long> idList = refundDao.selectIdList(query);
                    if (CollectionUtils.isEmpty(idList)) {
                        break;
                    }

                    List<Refund> list = refundDao.selectByIdList(idList);

                    executeRefund(list);

                    count += list.size();
                    sellerCount = sellerCount + list.size();
                    lastId = list.get(list.size() - 1).getId();
                    logger.info("[refundConvert]sellerRunning sellerId:{}, sellerCount:{}, lastId:{}, start:{}", sellerId, sellerCount, lastId, start);
                    Result<String> redisData = redisManager.get("convert_refund_shut_down_key_2");
                    if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                        logger.info("[convert_refund]shut down！");
                        return;
                    }
                    if (list.size() < size) {
                        break;
                    }
                }
            }
            logger.info("[refundConvert]sellerEnd sellerId:{}, sellerCount:{}", sellerId, sellerCount);
        }
    }

    private Calendar getCalendar(String start) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = sf.parse(start);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(parse);
        c.add(Calendar.DAY_OF_MONTH, 1);
        return c;
    }

    private void executeRefund(List<Refund> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<Refund> converted = new ArrayList<>(list.size());
                long s = System.currentTimeMillis();
                list.forEach(each -> converted.add((Refund) refundStreamConverter.streamIn(each)));
                logger.info("time1:{}", System.currentTimeMillis() - s);

                long s1 = System.currentTimeMillis();
                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<Refund>> partition = Lists.partition(converted, 50);
                    partition.forEach(i -> newRefundDao.replaceList(i));
                }
                logger.info("time2:{}", System.currentTimeMillis() - s1);

                Map<String, List<Refund>> collect = converted.stream().collect(Collectors.groupingBy(Refund::getRefundNo));

                long s2 = System.currentTimeMillis();
                List<String> refundNoList = list.stream().map(Refund::getRefundNo).collect(Collectors.toList());
                List<List<String>> partition = Lists.partition(refundNoList, 200);
                for (List<String> part : partition) {
                    List<OrderRefundDetails> detailList = refundDetailsDao.selectByRefundNoList(part);
                    if (!CollectionUtils.isEmpty(detailList)) {
                        detailList.forEach(each -> {
                            List<Refund> refundList = collect.get(each.getRefundNo());
                            if (!CollectionUtils.isEmpty(refundList)) {
                                each.setBizType(refundList.get(0).getBizType());
                                each.setPerformanceType(refundList.get(0).getPerformanceType());
                            }
                            each.setPayType(MapperFactory.payTypeMap(each.getBizType(), each.getPayType()));
                        });

                        newRefundDetailsDao.replaceList(detailList);
                    }
                }
                logger.info("time32:{}", System.currentTimeMillis() - s2);
            } catch (Exception e) {
                logger.error("[refund_execute_failed]failed！cause by:{}", e);
            }
        });
    }

    private void rebuild0(Map<String, List<Order>> collect, List<Refund> converted, Refund each) {
        List<Order> l1 = collect.get(each.getOrderNo());
        if (!CollectionUtils.isEmpty(l1)) {
            Order order = l1.get(0);
            Integer bizType = order.getBizType();

            if (FILTER.contains(bizType)) {
                // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
                each.setBizType(bizType);
                each.setSource(order.getSource());
                each.setOrderType(order.getOrderType());
                each.setOrderSubType(order.getOrderSubType());
                each.setPayType(order.getPayType());
                each.setPerformanceType(order.getPerformanceType());
                each.setStatus(MapperFactory.refundStatusMap(bizType, each.getStatus()));
                rebuildRefundDetail(each);
            }
            converted.add(each);
        }
    }

    private void rebuildRefundDetail(Refund refund) {
        String refundDetail = refund.getRefundDetailInfo();
        if (StringUtils.isNotBlank(refundDetail)) {
            List<InnerRefundDetail> list = JSON.parseArray(refundDetail, InnerRefundDetail.class);
            if (!CollectionUtils.isEmpty(list)) {
                for (InnerRefundDetail each : list) {
                    each.setPayType(MapperFactory.payTypeMap(refund.getBizType(), each.getPayType()));
                }
                refund.setRefundDetailInfo(JSON.toJSONString(list));
            }
        }
    }

    @Override
    public void commentConvert() {
        int count = 0;
        OrderCommentQuery query = new OrderCommentQuery();
        query.setSize(1000);
//        query.setSortFlag(1);
//        query.setUpdatedAtStart(new Date(1681999200000L));
//        query.setUpdatedAtEnd(new Date(1681999200000L));
        try {
            for (Long sellerId : ListSellerConst.list) {
                query.setSellerId(sellerId);

                for (int i = 0; i < dbSize; i++) {
                    for (int j = 0; j < 8; j++) {
                        Long lastId = null;
                        for (; ; ) {
                            query.setLastId(lastId);
                            List<OrderComment> list = commonManager.scanComment(query, i, j);
                            if (CollectionUtils.isEmpty(list)) {
                                break;
                            }

                            executeComment(list, i, j);

                            count += list.size();
                            lastId = list.get(list.size() - 1).getId();
                            logger.info("convert_comment_last_id:{},count:{}, i:{},j:{}", lastId, count, i, j);

                            Result<String> redisData = redisManager.get("convert_comment_shut_down_key_0");
                            if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                                logger.info("[convert_comment]shut down！");
                                return;
                            }
                            if (list.size() < 1000) {
                                break;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[commentConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Autowired
    private SearchCommentManager searchCommentManager;

    private void executeComment(List<OrderComment> list, int i, int j) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {

                List<OrderComment> converted = new ArrayList<>(list.size());
                list.forEach(each -> {
                    Order order = newOrderDao.selectByOrderNo(each.getOrderNo(), each.getUserId());
                    if (order != null) {
                        Integer bizType = order.getBizType();

                        // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
                        each.setBizType(bizType);
                        each.setOrderType(order.getOrderType());
                        each.setOrderSubType(order.getOrderSubType());
                        each.setPerformanceType(order.getPerformanceType());
                    }
                    converted.add(each);
                });

                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<OrderComment>> partition = Lists.partition(converted, 200);
                    for (List<OrderComment> group : partition) {
                        newCommentDao.replaceList(group);
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private void rebuild1(Map<String, List<Order>> collect, List<OrderComment> converted, OrderComment each) {
        List<Order> l1 = collect.get(each.getOrderNo());
        if (!CollectionUtils.isEmpty(l1)) {
            Order order = l1.get(0);
            Integer bizType = order.getBizType();

            // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
            each.setBizType(bizType);
            each.setOrderType(order.getOrderType());
            each.setPerformanceType(order.getPerformanceType());
            converted.add(each);
        }
    }

    @Override
    public void itemCommentConvert() {
        int count = 0;
        OrderItemCommentQuery query = new OrderItemCommentQuery();
        query.setSize(1000);
//        query.setSortFlag(1);
//        query.setUpdatedAtStart(new Date(1646064000000L));
//        query.setUpdatedAtEnd(new Date(1681999200000L));
        try {
            for (Long sellerId : ListSellerConst.list) {
                query.setSellerId(sellerId);

                for (int i = 0; i < dbSize; i++) {
                    for (int j = 0; j < 8; j++) {
                        Long lastId = null;
                        for (; ; ) {
                            query.setLastId(lastId);
                            List<OrderItemComment> list = commonManager.scanItemComment(query, i, j);
                            if (CollectionUtils.isEmpty(list)) {
                                break;
                            }

                            executeItemComment(list, i, j);

                            count += list.size();
                            lastId = list.get(list.size() - 1).getId();
                            logger.info("convert_item_comment_last_id:{}, count:{}, i:{}, j:{}", lastId, count, i, j);

                            Result<String> redisData = redisManager.get("convert_item_comment_shut_down_key");
                            if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                                logger.info("[convert_item_comment]shut down！");
                                return;
                            }
                            if (list.size() < 1000) {
                                break;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[orderConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Override
    public void checkOrderConvert() {
        int count = 0;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setBizType(5);
        orderQuery.setOrderTypeList(Lists.newArrayList(2, 3));
        orderQuery.setOrderAtStart(new Date(1674316799000L));
        orderQuery.setOrderAtEnd(new Date(1674662399000L));
        orderQuery.setSize(200);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = 0L;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        List<Long> idList = hintManager.scanRespId(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(idList)) {
                            logger.info("check_convert_order_last_id1:{}, idList:{}, i:{}, j:{}", lastId, idList, i, j);
                            break;
                        }
                        logger.info("check_convert_order_last_id:{}, idList:{}, i:{}, j:{}", lastId, idList, i, j);
                        return;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[orderConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Override
    public void orderRepair() {
        int count = 0;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setOrderAtEnd(new Date());
        orderQuery.setOrderAtStart(new Date(1751558400000L));
        orderQuery.setSize(1000);
        try {
            for (Long sellerId : ListSellerConst.list) {
                orderQuery.setSellerId(sellerId);
                for (int i = 0; i < dbSize; i++) {
                    for (int j = 0; j < tbSize; j++) {
                        Long lastId = null;
                        for (; ; ) {
                            orderQuery.setLastId(lastId);

                            List<Long> idList = commonManager.scanOrderId(orderQuery, i, j);
                            if (CollectionUtils.isEmpty(idList)) {
                                break;
                            }
                            List<Order> orderList = commonManager.listOrderById(idList, i, j);

                            execute0(orderList, i, j);

                            count += idList.size();
                            lastId = idList.get(idList.size() - 1);
                            logger.info("repair_order_last_id_1:{}, count:{}, i:{}, j:{}", lastId, count, i, j);

                            Result<String> redisData = redisManager.get("repair_order_shut_down_key_1");
                            if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                                logger.info("[orderRepair]shut down！");
                                return;
                            }
                            if (idList.size() < 1000) {
                                break;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[orderConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void execute1123(List<Long> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                OrderQuery query = new OrderQuery();
                query.setIdList(orderList);

                List<Long> newList = hintManager.scanRespId(query, i, j);
                for (Long newId : newList) {
                    if (!orderList.contains(newId)) {
                        Order oldOrder = commonManager.listOrderById(Lists.newArrayList(newId), i, j).get(0);
                        logger.info("[FIND_REPAIR_ORDER] order:{}", oldOrder);

                        newOrderDao.replaceList(Lists.newArrayList(oldOrder));
                    }
                }
            } catch (Exception e) {
                logger.error("[execute1123]failed！cause by:{}", e);
            }
        });
    }

    private void executeItemComment(List<OrderItemComment> list, int i, int j) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<OrderItemComment> converted = new ArrayList<>(list.size());

                list.forEach(each -> {
                    Order order = newOrderDao.selectByOrderNo(each.getOrderNo(), each.getUserId());
                    if (order != null) {
                        each.setBizType(each.getBizType());
                        each.setOrderType(order.getOrderType());
                        each.setOrderSubType(order.getOrderSubType());
                        each.setPerformanceType(order.getPerformanceType());
                    }
                    converted.add(each);
                });

                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<OrderItemComment>> partition = Lists.partition(converted, 200);
                    for (List<OrderItemComment> group : partition) {
                        newItemCommentDao.replaceList(group);
                        searchCommentManager.batchIndex(group, CommonConstants.ES_ORDER_COMMENTS_INDEX);
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private void rebuild2(Map<String, List<Order>> collect, List<OrderItemComment> converted, OrderItemComment each) {
        List<Order> l1 = collect.get(each.getOrderNo());
        if (!CollectionUtils.isEmpty(l1)) {
            Order order = l1.get(0);
            Integer bizType = order.getBizType();

            // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
            each.setBizType(bizType);
            each.setOrderType(order.getOrderType());
            each.setPerformanceType(order.getPerformanceType());
            converted.add(each);
        }
    }

    @Override
    public void syncEs() {
        int count = 0;
        String start = "2020-01-01";
        Date s = null;
        Date dTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setIsDeleted(-3);
        orderQuery.setSize(1000);
        try {
            for (; ; ) {
                Calendar c = getCalendar(start);
                s = DateUtils.getStartDate(c.getTime());
                dTime = DateUtils.getEndDate(c.getTime());

                start = sdf.format(c.getTime());

                if (new Date().before(s)) {
                    return;
                }

                orderQuery.setOrderAtStart(s);
                orderQuery.setOrderAtEnd(dTime);

                Long lastId = null;
                for (; ; ) {
//                    orderQuery.setLastId(lastId);
                    List<Long> idList = commonManager.scanOrderId(orderQuery, 20, 18);
                    if (CollectionUtils.isEmpty(idList)) {
                        break;
                    }

                    List<Order> orderList = commonManager.listOrderById(idList, 20, 18);

                    execute123455(orderList, 20, 18);

                    count += orderList.size();
                    lastId = orderList.get(orderList.size() - 1).getId();
                    logger.info("sync_es_order_last_id:{}, count:{}, i:{}, j:{}, start:{}", lastId, count, 20, 18, start);

                    Result<String> redisData = redisManager.get("sync_es_order_shut_down_key");
                    if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                        logger.info("[sync_es_order]shut down！");
                        return;
                    }
                    if (idList.size() < 1000) {
                        break;
                    }

                }
            }
//            for (int i = 0; i < dbSize; i++) {
//                for (int j = 0; j < tbSize; j++) {

            //            if (idList.size() < 1000) {
//                            break;
//                        }
//                }
//            }
        } catch (Exception e) {
            logger.error("[syncEs]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Autowired
    private HistoryDataOrderDao historyDataOrderDao;

    @Autowired
    private MergeOrderDao mergeOrderDao;

    @Override
    public void historyOrder() {
        int count = 0;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setUpdatedAtEnd(new Date(1648742400000L));
        orderQuery.setSize(400);
        try {
            for (int i = 11; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    if (i == 11 && j < 29) {
                        continue;
                    }
                    Long lastId = null;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);

                        List<Long> idList = commonManager.scanOrderId(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(idList)) {
                            break;
                        }

                        List<Order> orderList = commonManager.listOrderById(idList, i, j);

                        execute999(orderList, i, j);

                        count += orderList.size();
                        lastId = orderList.get(orderList.size() - 1).getId();
                        logger.info("his_convert_order_last_id:{}, count:{}, i:{}, j:{}", lastId, count, i, j);

                        Result<String> redisData = redisManager.get("his_convert_order_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[his_convert_order]shut down！");
                            return;
                        }
                        if (idList.size() < 400) {
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[historyOrder]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

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

                if (!CollectionUtils.isEmpty(converted)) {
                    historyDataOrderDao.replaceList(converted);
                }
            } catch (Exception e) {
                logger.error("[execute999]failed！cause by:{}", e);
            }
        });
    }

    private void execute123455(List<Order> orderList, int i, int j) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
//                List<Order> filter = filter(orderList);
//
//                searchManager.indexOrder(filter);
                List<MergeOrder> list = new ArrayList<>();
                for (Order order : orderList) {
                    MergeOrder data = new MergeOrder();
                    data.setOrderId(order.getId());
                    data.setOrderNo(order.getOrderNo());
                    data.setUserId(order.getUserId());
                    data.setSellerId(order.getSellerId());
                    data.setStoreId(order.getStoreId());
                    list.add(data);
                }
                mergeOrderDao.insertList(list);
            } catch (Exception e) {
                logger.error("[ORDER_SYNC_ES_EXECUTE]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void historyPay() {
        int count = 0;
        OrderPayDetailsQuery query = new OrderPayDetailsQuery();
//        query.setUpdatedAtStart(new Date(1648742400000L));
        query.setUpdatedAtEnd(new Date(1648742400000L));
        query.setSize(1000);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);

                        List<OrderPayDetails> idList = commonManager.scanPayDetailsId(query, i, j);
                        if (CollectionUtils.isEmpty(idList)) {
                            break;
                        }

                        List<OrderPayDetails> list = commonManager.queryPayDetailsListById(
                                idList.stream().map(OrderPayDetails::getId).collect(Collectors.toList()), i, j);
                        if (CollectionUtils.isEmpty(list)) {
                            break;
                        }

                        executePay111(list, i, j);

                        count += list.size();
                        lastId = list.get(list.size() - 1).getId();
                        logger.info("history_pay_last_id:{}, count:{}, i:{},j:{}", lastId, count, i, j);

                        Result<String> redisData = redisManager.get("history_pay_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[pay_history_order]shut down！");
                            return;
                        }
                        if (list.size() < 1000) {
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[historyPay]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Autowired
    private OBHistoryHintManager historyHintManager;

    @Autowired
    private HistoryDataPayDetailsDao historyDataPayDetailsDao;

    private void executePay111(List<OrderPayDetails> list, int i, int j) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<String> orderNoList = list.stream().map(OrderPayDetails::getOrderNo).collect(Collectors.toList());
                HashSet<String> set = Sets.newHashSet(orderNoList);
                List<List<String>> lists = Lists.partition(Lists.newArrayList(set), 200);

                List<Order> orderList = new ArrayList<>();
                for (List<String> strings : lists) {
                    orderList.addAll(historyHintManager.scanOrderByOrderNo(strings, i, j));
                }

                if (orderList != null) {
                    Map<String, List<Order>> collect = orderList.stream().collect(Collectors.groupingBy(Order::getOrderNo));
                    List<OrderPayDetails> converted = new ArrayList<>(list.size());

                    list.forEach(each -> {
                        rebuild(collect, converted, each);
                    });

                    if (!CollectionUtils.isEmpty(converted)) {
                        List<List<OrderPayDetails>> partition = Lists.partition(converted, 200);
                        for (List<OrderPayDetails> group : partition) {
                            historyDataPayDetailsDao.replaceList(group);
                            Thread.sleep(10);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void historyRefund() {
        int count = 0;
        RefundQuery query = new RefundQuery();
        query.setSize(200);

        Date s = null;
        Date e = null;
        String start = "2022-04-01";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        for (; ; ) {
            Calendar c = getCalendar0(start);
            start = sdf.format(c.getTime());
            s = DateUtils.getStartDate(c.getTime());

            logger.info("[refund_history_date]start:{}", start);

            if (s.before(new Date(1520152280000L))) {
                return;
            }

            e = DateUtils.getEndDate(c.getTime());

            query.setUpdatedAtEnd(e);
            query.setUpdatedAtStart(s);
            Long lastId = null;
            for (; ; ) {
                query.setLastId(lastId);
                List<Long> idList = refundDao.selectIdList(query);
                if (CollectionUtils.isEmpty(idList)) {
                    break;
                }

                List<Refund> list = refundDao.selectByIdList(idList);

                executeRefund90(list);

                count += list.size();
                lastId = list.get(list.size() - 1).getId();
                logger.info("history_refund_last_id:{}, start:{}, count:{}", lastId, start, count);

                Result<String> redisData = redisManager.get("history_refund_shut_down_key");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    logger.info("[history_refund]shut down！");
                    return;
                }
                if (list.size() < 200) {
                    break;
                }
            }
        }
    }

    @Autowired
    private HistoryDataRefundDao historyDataRefundDao;

    @Autowired
    private HistoryDataRefundDetailsDao historyDataRefundDetailsDao;

    private void executeRefund90(List<Refund> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<Refund> converted = new ArrayList<>(list.size());
                list.forEach(each -> converted.add((Refund) refundStreamConverter.streamIn(each)));
                if (!CollectionUtils.isEmpty(converted)) {
                    historyDataRefundDao.replaceList(converted);
                }

                List<String> refundNoList = list.stream().map(Refund::getRefundNo).collect(Collectors.toList());
                List<List<String>> partition = Lists.partition(refundNoList, 200);
                for (List<String> part : partition) {
                    List<OrderRefundDetails> detailList = refundDetailsDao.selectByRefundNoList(part);
                    if (!CollectionUtils.isEmpty(detailList)) {
                        detailList.forEach(each -> {
                            each.setPayType(MapperFactory.payTypeMap(each.getBizType(), each.getPayType()));
                        });
                        historyDataRefundDetailsDao.replaceList(detailList);
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    private Calendar getCalendar0(String start) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = sf.parse(start);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(parse);
        c.add(Calendar.DAY_OF_MONTH, -1);
        return c;
    }

    @Override
    public void historyComment() {
        int count = 0;
        OrderCommentQuery query = new OrderCommentQuery();
        query.setSortFlag(1);
        query.setSize(1000);
//        query.setUpdatedAtStart(new Date(1681999200000L));
        query.setUpdatedAtEnd(new Date(1648742400000L));
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < 8; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);
                        List<OrderComment> list = commonManager.scanComment(query, i, j);
                        if (CollectionUtils.isEmpty(list)) {
                            break;
                        }

                        executeComment11(list, i, j);

                        count += list.size();
                        lastId = list.get(list.size() - 1).getId();
                        logger.info("history_comment_last_id:{},count:{}, i:{},j:{}", lastId, count, i, j);

                        Result<String> redisData = redisManager.get("history_comment_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[history_comment]shut down！");
                            return;
                        }
                        if (list.size() < 1000) {
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[commentConvert]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Autowired
    private HistoryDataCommentDao historyDataCommentDao;

    private void executeComment11(List<OrderComment> list, int i, int j) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {

                List<OrderComment> converted = new ArrayList<>(list.size());
                list.forEach(each -> {
                    Order order = historyDataOrderDao.selectByOrderNo(each.getOrderNo(), each.getUserId());
                    if (order != null) {
                        Integer bizType = order.getBizType();

                        // 从订单中获取枚举值，先决条件：订单数据必须先处理完成
                        each.setBizType(bizType);
                        each.setOrderType(order.getOrderType());
                        each.setPerformanceType(order.getPerformanceType());
                    }
                    converted.add(each);
                });

                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<OrderComment>> partition = Lists.partition(converted, 200);
                    for (List<OrderComment> group : partition) {
                        historyDataCommentDao.replaceList(group);
                        logger.info("[comment_replace]group:{}", group.stream().map(OrderComment::getOrderNo).collect(Collectors.toList()));
                    }
                }
            } catch (Exception e) {
                logger.error("[execute]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void historyItemComment() {
        int count = 0;
        OrderItemCommentQuery query = new OrderItemCommentQuery();
        query.setSortFlag(1);
        query.setSize(1000);
//        query.setUpdatedAtStart(new Date(1681999200000L));
        query.setUpdatedAtEnd(new Date(1648742400000L));
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < 8; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);
                        List<OrderItemComment> list = commonManager.scanItemComment(query, i, j);
                        if (CollectionUtils.isEmpty(list)) {
                            break;
                        }

                        executeItemComment1123(list, i, j);

                        count += list.size();
                        lastId = list.get(list.size() - 1).getId();
                        logger.info("history_item_comment_last_id:{}, count:{}, i:{}, j:{}", lastId, count, i, j);

                        Result<String> redisData = redisManager.get("history_item_comment_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[history_item_comment]shut down！");
                            return;
                        }
                        if (list.size() < 1000) {
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("[historyItemComment]failed!cause by:{0}", e);
            throw new RuntimeException("系统异常");
        }
    }

    @Override
    public void mergeRepair() {
        int count = 0;
        Long lastId = null;
        for (; ; ) {
            List<MergeOrder> list = mergeOrderDao.selectListByIdSize(lastId, 1000);
            if (CollectionUtils.isEmpty(list)) {
                return;
            }

            mergeOrder(list);

            count += list.size();
            lastId = list.get(list.size() - 1).getId();
            logger.info("mergeRepairOrder, count:{}, lastId", count, lastId);

            if (list.size() < 1000) {
                return;
            }
        }
    }

    @Autowired
    private OrderIndexDao indexDao;

    private void mergeOrder(List<MergeOrder> list) {
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                for (MergeOrder each : list) {
                    Order order = orderDao.selectByOrderNo(each.getOrderNo(), each.getUserId());
                    if (order != null) {
                        Order converted0 = (Order) orderStreamConverter.streamIn(order);
                        if (new Date(1646064000000L).before(order.getOrderAt())) {
                            newOrderDao.replace(converted0);
                        } else {
                            historyDataOrderDao.replaceList(Lists.newArrayList(converted0));
                        }

                        OrderIndex index = indexDao.selectOne(order.getOrderNo());
                        if (index != null) {
                            Order order1 = orderDao.selectByOrderNo(index.getOrderNo(), index.getUserId());
                            if (order1 != null) {
                                Order converted = (Order) orderStreamConverter.streamIn(order1);
                                if (new Date(1646064000000L).before(order1.getOrderAt())) {
                                    newOrderDao.replace(converted);
                                    searchManager.indexOrder(converted, null);
                                } else {
                                    historyDataOrderDao.replaceList(Lists.newArrayList(converted));
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("[mergeOrder]failed！cause by:{}", e);
            }
        });
    }

    @Autowired
    private HistoryDataItemCommentDao historyDataItemCommentDao;

    private void executeItemComment1123(List<OrderItemComment> list, 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 {
                List<OrderItemComment> converted = new ArrayList<>(list.size());

                list.forEach(each -> {
                    Order order = historyDataOrderDao.selectByOrderNo(each.getOrderNo(), each.getUserId());
                    if (order != null) {
                        each.setBizType(each.getBizType());
                        each.setOrderType(order.getOrderType());
                        each.setPerformanceType(order.getPerformanceType());
                    }
                    converted.add(each);
                });

                if (!CollectionUtils.isEmpty(converted)) {
                    List<List<OrderItemComment>> partition = Lists.partition(converted, 200);
                    for (List<OrderItemComment> group : partition) {
                        historyDataItemCommentDao.replaceList(group);
                    }
                }
            } catch (Exception e) {
                logger.error("[executeItemComment1123]failed！cause by:{}", e);
            }
        });
    }

    private Map<String, Object> extMap = new ConcurrentHashMap<>();

    @Override
    public void orderLoss(Order order) {
        int count = 0;
        String start = "2022-12-01";
        Date sTime = null;
        Date dTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        AtomicInteger diff = new AtomicInteger();

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSize(200);

        // 每一天
        for (; ; ) {
            Calendar c = getCalendar(start);
            sTime = DateUtils.getStartDate(c.getTime());
            dTime = DateUtils.getEndDate(c.getTime());

            start = sdf.format(c.getTime());

            if (new Date().after(new Date(1691020800000L))) {
                logger.info("order_loss_last_id_stop, now time:{}", start);
                return;
            }

            orderQuery.setOrderAtStart(sTime);
            orderQuery.setOrderAtEnd(dTime);


            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        List<Long> orderList = commonManager.scanOrderId(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(orderList)) {
                            break;
                        }
                        List<Order> orders = commonManager.scanOrderRespExt(orderList, i, j);

                        execute1111(orders, i, j, diff);

                        count += orderList.size();
                        lastId = orderList.get(orderList.size() - 1);
                        logger.info("order_loss_last_id:{}, count:{}, i:{}, j:{}, start:{}", lastId, count, i, j,
                                start);

                        Result<String> redisData = redisManager.get("order_loss_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[order_loss_order]shut down！");
                            return;
                        }
                        if (orderList.size() < 200) {
                            break;
                        }
                    }
                }
            }
        }
    }

    private void execute14(List<Order> orderList, int i, int j, AtomicInteger diff) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                searchManager.indexOrder(filter(orderList));
            } catch (Exception e) {
                logger.error("[execute14]failed！cause by:{}", e);
            }
        });
    }

    @Autowired
    private OrderExtDao extDao;

    @Autowired
    private ShardingKeyGenerator generator;

    private void execute1111(List<Order> orderList, int i, int j, AtomicInteger diff) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                Set<String> keys = new HashSet<>();
                List<Map<String, Object>> collects = orderList.stream().map(Order::getExtraMap).collect(Collectors.toList());
                for (Map<String, Object> features : collects) {
                    extMap.putAll(features);
                }
                if (!CollectionUtils.isEmpty(keys)) {
                    List<OrderExt> extList = extDao.selectAll();
                    List<String> keyList = extList.stream().map(OrderExt::getExtKey).collect(Collectors.toList());
                    for (String key : keys) {
                        if (!keyList.contains(key)) {
                            try {
                                extDao.insertList(Lists.newArrayList(
                                        new OrderExt(generator.generateSnowflakeKey().hashCode(), key)));
                            } catch (Exception ignore) {
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("[execute1111]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void payLoss() {
        int count = 0;
        String start = "2020-01-01";
//        String start = "2022-03-01";
        Date sTime = null;
        Date dTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        AtomicInteger diff = new AtomicInteger();

        OrderPayDetailsQuery query = new OrderPayDetailsQuery();
        query.setSize(1000);

        // 每一天
        for (; ; ) {
            Calendar c = getCalendar(start);
            sTime = DateUtils.getStartDate(c.getTime());
            dTime = DateUtils.getEndDate(c.getTime());

            start = sdf.format(c.getTime());

            logger.info("pay_loss_start:{}", start);

            if (new Date(1646150400000L).before(dTime)) {
                return;
            }

            query.setUpdatedAtStart(sTime);
            query.setUpdatedAtEnd(dTime);


            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);
                        List<Long> list = commonManager.scanPayDetailsIdList(query, i, j);
                        if (CollectionUtils.isEmpty(list)) {
                            break;
                        }
                        execute15(list, i, j, diff);

                        count += list.size();
                        lastId = list.get(list.size() - 1);
                        logger.info("pay_loss_last_id:{}, count:{}, i:{}, j:{}, start:{}",
                                lastId, count, i, j, start);

                        Result<String> redisData = redisManager.get("pay_loss_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[pay_loss_order]shut down！");
                            return;
                        }
                        if (list.size() < 1000) {
                            break;
                        }
                    }
                }
            }
        }
    }

    private void execute15(List<Long> orderList, int i, int j, AtomicInteger diff) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<OrderPayDetails> historyOrder = historyHintManager.scanPayById(orderList, i, j);

                if (CollectionUtils.isEmpty(historyOrder)) {
                    List<OrderPayDetails> olds = commonManager.queryPayDetailsListById(orderList, i, j);

                    if (!CollectionUtils.isEmpty(olds)) {
                        List<OrderPayDetails> converted = new ArrayList<>();
                        olds.forEach(each -> converted.add((OrderPayDetails) payStreamConverter.streamIn(each)));

                        historyDataPayDetailsDao.replaceList(converted);
                        logger.info("[FIND_LOSS_PAYS] idList:{}", orderList);
                    }
                } else {
                    List<Long> hisId = historyOrder.stream().map(OrderPayDetails::getId).collect(Collectors.toList());
                    for (Long id : orderList) {
                        if (!hisId.contains(id)) {
                            List<OrderPayDetails> olds = commonManager.queryPayDetailsListById(Lists.newArrayList(id), i, j);
                            List<OrderPayDetails> converted = new ArrayList<>();
                            olds.forEach(each -> converted.add((OrderPayDetails) payStreamConverter.streamIn(each)));

                            historyDataPayDetailsDao.replaceList(olds);

                            logger.info("[FIND_LOSS_PAY] orderNo:{}", olds.get(0).getOrderNo());
                            diff.incrementAndGet();
                        }
                    }
                    logger.info("[FIND_LOSS_PAY_DIFF]diff:{}", diff);
                }
            } catch (Exception e) {
                logger.error("[execute14]failed！cause by:{}", e);
            }
        });
    }

    private void execute16(List<Long> orderList, int i, int j, AtomicInteger diff) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
                List<OrderPayDetails> pays = newHintManager.selectRespById(orderList, i, j);

                if (CollectionUtils.isEmpty(pays)) {
                    List<OrderPayDetails> olds = commonManager.queryPayDetailsListById(orderList, i, j);

                    if (!CollectionUtils.isEmpty(olds)) {
                        List<OrderPayDetails> converted = new ArrayList<>();
                        olds.forEach(each -> converted.add((OrderPayDetails) payStreamConverter.streamIn(each)));

                        newPayDao.replaceList(converted);
                        logger.info("[FIND_LOSS_PAYS] idList:{}", orderList);
                    }
                } else {
                    List<Long> hisId = pays.stream().map(OrderPayDetails::getId).collect(Collectors.toList());
                    for (Long id : orderList) {
                        if (!hisId.contains(id)) {
                            List<OrderPayDetails> olds = commonManager.queryPayDetailsListById(Lists.newArrayList(id), i, j);
                            List<OrderPayDetails> converted = new ArrayList<>();
                            olds.forEach(each -> converted.add((OrderPayDetails) payStreamConverter.streamIn(each)));

                            newPayDao.replaceList(olds);

                            logger.info("[FIND_LOSS_PAY] orderNo:{}", olds.get(0).getOrderNo());
                            diff.incrementAndGet();
                        }
                    }
                    logger.info("[FIND_LOSS_PAY_DIFF]diff:{}", diff);
                }
            } catch (Exception e) {
                logger.error("[execute14]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void refundLoss() {
        int count = 0;
//        String start = "2022-03-01";
        String start = "2020-01-01";
        Date sTime = null;
        Date dTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        AtomicInteger diff = new AtomicInteger();

        RefundQuery query = new RefundQuery();
        query.setSize(1000);
        for (; ; ) {
            Calendar c = getCalendar(start);
            sTime = DateUtils.getStartDate(c.getTime());
            dTime = DateUtils.getEndDate(c.getTime());

            start = sdf.format(c.getTime());

            if (new Date(1646150400000L).before(dTime)) {
                return;
            }

            query.setUpdatedAtStart(sTime);
            query.setUpdatedAtEnd(dTime);

            Long lastId = null;
            for (; ; ) {
                query.setLastId(lastId);
                List<Long> list = refundDao.selectIdList(query);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }

                execute17(list, diff);

                count += list.size();
                lastId = list.get(list.size() - 1);
                logger.info("loss_refund_last_id:{}, start:{}, count:{}", lastId, start, count);

                Result<String> redisData = redisManager.get("loss_refund_shut_down_key");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    logger.info("[history_refund]shut down！");
                    return;
                }
                if (list.size() < 1000) {
                    break;
                }
            }
        }
    }

    private void execute17(List<Long> orderList, AtomicInteger diff) {
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        while (workQueue.remainingCapacity() < 20) {
            logger.info("workQueue size:{}", workQueue.size());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.submit(() -> {
            try {
//                List<Refund> historyOrder = newRefundDao.selectRespId(orderList);
                List<Refund> historyOrder = historyDataRefundDao.selectRespId(orderList);

                if (CollectionUtils.isEmpty(historyOrder)) {
                    List<Refund> olds = refundDao.selectByIdList(orderList);

                    if (!CollectionUtils.isEmpty(olds)) {
                        List<Refund> converted = new ArrayList<>();
                        olds.forEach(each -> converted.add((Refund) refundStreamConverter.streamIn(each)));

//                        newRefundDao.replaceList(converted);
                        historyDataRefundDao.replaceList(converted);
                        logger.info("[FIND_LOSS_REFUNDS] idList:{}", orderList);
                    }
                } else {
                    List<Long> hisId = historyOrder.stream().map(Refund::getId).collect(Collectors.toList());
                    for (Long id : orderList) {
                        if (!hisId.contains(id)) {
                            Refund refund = refundDao.selectById(id);
                            Refund newRefund = (Refund) refundStreamConverter.streamIn(refund);

//                            newRefundDao.replace(newRefund);
                            historyDataRefundDao.replaceList(Lists.newArrayList(newRefund));

                            logger.info("[FIND_LOSS_REFUND] orderNo:{}", newRefund.getOrderNo());
                            diff.incrementAndGet();
                        }
                    }
                    logger.info("[FIND_LOSS_REFUND_DIFF]diff:{}", diff);
                }
            } catch (Exception e) {
                logger.error("[execute14]failed！cause by:{}", e);
            }
        });
    }

    @Override
    public void orderCheck() {
        int count = 0;
        String start = "2022-02-28";
        Date sTime = null;
        Date dTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        AtomicInteger diff = new AtomicInteger();

        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setSize(1000);

        // 每一天
        for (; ; ) {
            Calendar c = getCalendar(start);
            sTime = DateUtils.getStartDate(c.getTime());
            dTime = DateUtils.getEndDate(c.getTime());

            start = sdf.format(c.getTime());

            if (new Date().before(dTime)) {
                return;
            }

            orderQuery.setOrderAtStart(sTime);
            orderQuery.setOrderAtEnd(dTime);


            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        orderQuery.setLastId(lastId);
                        List<Long> orderList = newHintManager.scanRespId(orderQuery, i, j);
                        if (CollectionUtils.isEmpty(orderList)) {
                            break;
                        }
                        execute18(orderList, i, j);

                        count += orderList.size();
                        lastId = orderList.get(orderList.size() - 1);
                        logger.info("order_check_last_id:{}, count:{}, i:{}, j:{}, start:{}", lastId, count, i, j,
                                start);

                        Result<String> redisData = redisManager.get("order_check_shut_down_key");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[order_check_order]shut down！");
                            return;
                        }
                        if (orderList.size() < 1000) {
                            break;
                        }
                    }
                }
            }
        }
    }

    List<Integer> bizList = Lists.newArrayList(5, 6, 7);
    List<Integer> bakStatusList = Lists.newArrayList(1, 2, 4, 8);
    List<Integer> bakPayList = Lists.newArrayList(267, 268, 132, 264, 266, 265);
    List<Integer> catOrderList = Lists.newArrayList(2, 3);
    List<Integer> catPerList = Lists.newArrayList(1, 2, 3, 4, 5);

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

                List<Order> list = newHintManager.selectOrderByIdTemp(orderList, i, j);
                for (Order order : list) {
                    BizTypeEnum value = BizTypeEnum.getValue(order.getBizType());
                    switch (value) {
                        case BAKING:
                            Integer status = order.getStatus();
                            if (bakStatusList.contains(status)) {
                                errList.add(order);
                                logger.error("[BAKING_ERROR_ORDER]status orderNo:{}", order.getOrderNo());
                            }
                            if (bakPayList.contains(order.getPayType())) {
                                errList.add(order);
                                logger.error("[BAKING_ERROR_ORDER]pat_type orderNo:{}", order.getOrderNo());
                            }
                            break;
                        case CATERING:
                        case ASSISTANT:
                        case MEAL_MATE:
                            if (catOrderList.contains(order.getOrderType())) {
                                errList.add(order);
                                logger.error("[CATERING_ERROR_ORDER]orderType orderNo:{}", order.getOrderNo());
                            }
                            if (order.getOrderType() == 1 && !catPerList.contains(order.getPerformanceType())) {
                                errList.add(order);
                                logger.error("[CATERING_ERROR_ORDER]per orderNo:{}", order.getOrderNo());
                            }
                            break;
                    }
                }

                if (!CollectionUtils.isEmpty(errList)) {
                    List<Long> collect = errList.stream().map(Order::getId).collect(Collectors.toList());
                    List<Order> orders = commonManager.scanOrderByIdList(collect, i, j);

                    List<Order> converted = new ArrayList<>();
                    orders.forEach(each -> converted.add((Order) orderStreamConverter.streamIn(each)));

                    newOrderDao.replaceList(converted);
                    searchManager.indexOrder(filter(converted));
                }
            } catch (Exception e) {
                logger.error("[execute18]failed！cause by:{}", e);
            }
        });
    }

    private MergeOrder convert(Order order) {
        MergeOrder data = new MergeOrder();
        data.setOrderId(order.getId());
        data.setOrderNo(order.getOrderNo());
        data.setUserId(order.getUserId());
        data.setSellerId(order.getSellerId());
        data.setStoreId(order.getStoreId());
        return data;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        int coreSize = Runtime.getRuntime().availableProcessors();
        workQueue = new ArrayBlockingQueue(40);

        executorService = new ThreadPoolExecutor(24, 24, 1, TimeUnit.MINUTES,
                workQueue, new NamedThreadFactory("order-routing"),
                new ThreadPoolExecutor.AbortPolicy());

//        workQueue0 = new ArrayBlockingQueue(1024);
//        executorService0 = new ThreadPoolExecutor(4, 4, 1, TimeUnit.MINUTES,
//                workQueue0, new NamedThreadFactory("order-routing-1"),
//                new ThreadPoolExecutor.AbortPolicy());
    }
}
