package com.liquidnet.service.kylin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.cache.redisson.util.RedisLockUtil;
import com.liquidnet.common.mq.constant.MQConst;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.dto.vo.AdamAddressesVo;
import com.liquidnet.service.adam.dto.vo.AdamEntersVo;
import com.liquidnet.service.base.*;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dao.OrderScriptDto;
import com.liquidnet.service.kylin.dto.param.PayAgainParam;
import com.liquidnet.service.kylin.dto.param.PayOrderParam;
import com.liquidnet.service.kylin.dto.param.SyncOrderParam;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.dto.vo.middle.message.MessageConfigVo;
import com.liquidnet.service.kylin.dto.vo.middle.message.MessageDataVo;
import com.liquidnet.service.kylin.dto.vo.mongo.*;
import com.liquidnet.service.kylin.dto.vo.returns.*;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketRelationsMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketStatusMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import com.liquidnet.service.kylin.service.IKylinOrderTicketsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.service.kylin.utils.*;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.result.UpdateResult;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaDamaiMevOpenBatchpushticketRequest;
import com.taobao.api.response.AlibabaDamaiMevOpenBatchpushticketResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.bson.Document;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-05-20
 */
@Service
@Slf4j
public class KylinOrderTicketsServiceImpl extends ServiceImpl<KylinOrderTicketsMapper, KylinOrderTickets> implements IKylinOrderTicketsService {

    @Value("${liquidnet.url-pay.pay}")
    private String payUrl;
    @Value("${liquidnet.url-pay.check}")
    private String checkUrl;
    @Value("${liquidnet.url-pay.localUrl}")
    private String synUrl;

    @Autowired
    private Environment environment;
    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private OtherUtils otherUtils;
    @Autowired
    private RedisLockUtil redisLockUtil;
    @Autowired
    private MongoVoUtils mongoVoUtils;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private TaobaoTicketUtils taobaoTicketUtils;
    @Autowired
    private KylinOrderTicketsMapper orderTicketsMapper;
    @Autowired
    private KylinOrderTicketStatusMapper orderTicketStatusMapper;
    @Autowired
    private KylinOrderTicketRelationsMapper orderTicketRelationsMapper;
    @Autowired
    private OrderRefundsCallbackServiceImpl orderRefundsCallbackService;
    @Autowired
    private KylinRefundsStatusServiceImpl refundsStatusService;


    ArrayList<Integer> canBuyStatus = new ArrayList() {{
        add(6);
        add(8);
        add(9);
        add(10);
    }};


    @Override
    public ResponseDto<PayResultVo> checkCanOrder(PayOrderParam payOrderParam) {
        Long currentTime;
        boolean isDownGeneral = false;
        String uid = CurrentUtil.getCurrentUid();
        String lock = "userId:" + uid;
        if (!redisLockUtil.tryLock(lock, 1, 5)) {
            return ResponseDto.failure("请求频繁");//参数错误
        }
        try {
            currentTime = System.currentTimeMillis();
            KylinPerformanceVo performanceData = dataUtils.getPerformanceVo(payOrderParam.getPerformanceId());
            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("redis 获取演出详情 -> time:" + currentTime + "毫秒");
            KylinTicketTimesVo ticketTimesData = null;
            KylinTicketVo ticketData = null;
            for (int x = 0; x < performanceData.getTicketTimeList().size(); x++) {
                KylinTicketTimesVo timeItem = performanceData.getTicketTimeList().get(x);
                if (timeItem.getTimeId().equals(payOrderParam.getTimeId())) {
                    ticketTimesData = timeItem;
                    for (int y = 0; y < ticketTimesData.getTicketList().size(); y++) {
                        KylinTicketVo ticketItem = ticketTimesData.getTicketList().get(y);
                        if (ticketItem.getTicketsId().equals(payOrderParam.getTicketId())) {
                            ticketData = ticketItem;
                            break;
                        }
                    }
                    break;
                }
            }

            if (performanceData == null || ticketTimesData == null || ticketData == null) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20004"));//参数错误
            }
            if (!ticketData.getTimeId().equals(payOrderParam.getTimeId()) || !ticketTimesData.getPerformanceId().equals(payOrderParam.getPerformanceId())) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20004"));//参数错误
            }
            if (payOrderParam.getNumber() % ticketData.getCounts() != 0) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20007"));//数量错误
            }
            //判断代理
            if (!checkAgent(payOrderParam.getAgentId(), ticketData)) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20008"));//无权购买
            }

            Integer isStudent = ticketData.getIsStudent();
            //会员时间获取
            String memberTimeStart = ticketData.getMemberTimeStart(); // 会员开售时间
            String timeStart = ticketData.getTimeStart(); // 普通开售时间
            String timeEnd = ticketData.getTimeEnd(); // 购票停售时间
            String timeExpressEnd = ticketData.getTimeEndExpress(); // 快递停售时间
            currentTime = System.currentTimeMillis();
            boolean isMember = orderUtils.isMember(uid);//feignAdamBaseClient.isMember(uid).getData();//获取是否是会员
            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("fegin 会员 -> time:" + (currentTime) + "毫秒");
            int memberType; //会员状态 不需要判断会员 1判断会员逻辑 2会员专属
            if (ticketData.getIsExclusive() == 1) {
                memberType = 2;
                if (!isMember) {
                    redisLockUtil.unlock(lock);
                    return ResponseDto.failure(ErrorMapping.get("20009"));//没有会员权限
                }
            } else {
                if (DateUtil.compareStrDay(DateUtil.getNowTime(), memberTimeStart) == 1 && DateUtil.compareStrDay(DateUtil.getNowTime(), timeStart) == -1 && ticketData.getIsMember() == 1) {
                    // 会员购买逻辑
                    memberType = 1;
                    if (!isMember) {
                        redisLockUtil.unlock(lock);
                        return ResponseDto.failure(ErrorMapping.get("20009"));//没有会员权限
                    }
                } else {
                    // 普通用户购买逻辑
                    memberType = 0;
                }
            }

            // 获取限购 实名
            int ticketLimit = ticketData.getLimitCount();//普通票种限购
            int ticketMemberLimit = ticketData.getLimitCountMember();//会员票种限购
            int performanceLimit = performanceData.getLimitCount();//普通演出限购
            int performanceMemberLimit = performanceData.getLimitCountMember();//会员演出限购
            int isTrueName = ticketData.getIsTrueName();//是否演出实名

            if (!canBuyStatus.contains(performanceData.getAppStatus())) {
                return ResponseDto.failure(ErrorMapping.get("20010"));//当前不可购买
            }

            if (!canBuyStatus.contains(performanceData.getAppStatus())) {
                return ResponseDto.failure(ErrorMapping.get("20010"));//当前不可购买
            }

            //通用判断时间
            if (isMember) {
                if (DateUtil.compareStrDay(DateUtil.getNowTime(), memberTimeStart) == -1) {
                    redisLockUtil.unlock(lock);
                    return ResponseDto.failure(ErrorMapping.get("20011"));//未开始
                }
            } else {
                if (DateUtil.compareStrDay(DateUtil.getNowTime(), timeStart) == -1) {
                    redisLockUtil.unlock(lock);
                    return ResponseDto.failure(ErrorMapping.get("20011"));//未开始
                }
            }
            if (DateUtil.compareStrDay(DateUtil.getNowTime(), timeEnd) == 1) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20012"));//已结束
            }

            //快递票判断
            if (payOrderParam.getIsExpress() != null) {
                if (payOrderParam.getIsExpress() == 1 && DateUtil.compareStrDay(DateUtil.getNowTime(), timeExpressEnd) == 1) {
                    redisLockUtil.unlock(lock);
                    return ResponseDto.failure(ErrorMapping.get("20013"));//快递票不卖
                }
                if (payOrderParam.getIsExpress() == 1 && payOrderParam.getAddressId().isEmpty()) {
                    redisLockUtil.unlock(lock);
                    return ResponseDto.failure(ErrorMapping.get("20014"));//快递票未填写收货地址
                }
            }
            //实名判断
            if (isTrueName == 1 && payOrderParam.getEnterIdList().size() <= 0) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20015"));//需要实名 未实名
            }
            if (isTrueName == 1 && payOrderParam.getEnterIdList().size() != payOrderParam.getNumber()) {
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20015"));//入场人数量错误
            }

            // 判断库存

            currentTime = System.currentTimeMillis();
            int surplusGeneral = dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), -payOrderParam.getNumber());
            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("redis 获取库存 -> time:" + (currentTime) + "毫秒");

            if (surplusGeneral < 0) {//库存回滚
                currentTime = System.currentTimeMillis();
                dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), payOrderParam.getNumber());
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("redis 修改库存 售罄 -> time:" + (currentTime) + "毫秒");
                redisLockUtil.unlock(lock);
                return ResponseDto.failure(ErrorMapping.get("20016"));//没抢到
            } else {
                isDownGeneral = true;

                //学生票 判断
                List<AdamEntersVo> entersVoList = new ArrayList<>();
                if (isTrueName == 1) {
                    currentTime = System.currentTimeMillis();
                    for (String enterId : payOrderParam.getEnterIdList()) {
                        AdamEntersVo adamEnters = orderUtils.getEnters(uid, enterId);//feignAdamBaseClient.queryEnters(enterId, uid).getData();
                        entersVoList.add(adamEnters);
                        if (isStudent == 1) {
                            int age = IDCard.getAgeByIdCard(adamEnters.getIdCard());
                            if (age > 25) {
                                redisLockUtil.unlock(lock);
                                dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), payOrderParam.getNumber());
                                return ResponseDto.failure(ErrorMapping.get("20017"));//年龄超了
                            }
                        }
                    }
                    currentTime = System.currentTimeMillis() - currentTime;
                    log.debug("获取 feign 入场人 -> time:" + (currentTime) + "毫秒");
                }

                //限购判断 如果实名 则身份证维度限购 如果不实名则数量限购
                if (entersVoList.size() > 0) {
                    currentTime = System.currentTimeMillis();
                    for (int i = 0; i < entersVoList.size(); i++) {
                        String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, entersVoList.get(i).getIdCard(), payOrderParam.getPerformanceId(), payOrderParam.getTicketId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, 1, 1, memberType, isTrueName);
                        log.debug("redis 判断库存 -> time:" + (currentTime) + "毫秒");
                        if (!res1.equals("")) {
                            redisLockUtil.unlock(lock);
                            dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), payOrderParam.getNumber());
                            return ResponseDto.failure(res1);//乱七八糟异常
                        }
                    }
                    currentTime = System.currentTimeMillis() - currentTime;

                } else {
                    log.debug("redis 判断库存 -> time:" + (currentTime) + "毫秒");
                    currentTime = System.currentTimeMillis();
                    String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, "", payOrderParam.getPerformanceId(), payOrderParam.getTicketId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, payOrderParam.getNumber(), payOrderParam.getNumber(), memberType, isTrueName);
                    currentTime = System.currentTimeMillis() - currentTime;
                    if (!res1.equals("")) {
                        redisLockUtil.unlock(lock);
                        dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), payOrderParam.getNumber());
                        return ResponseDto.failure(res1);//乱七八糟异常
                    }
                    currentTime = System.currentTimeMillis() - currentTime;

                }

                ResponseDto<PayResultVo> resultData = order(payOrderParam, uid, isMember, isTrueName, performanceData, ticketData, entersVoList, isStudent, ticketTimesData, currentTime);
                redisLockUtil.unlock(lock);
                return resultData;
            }
        } catch (Exception e) {
            if (isDownGeneral) {
                currentTime = System.currentTimeMillis();
                dataUtils.changeSurplusGeneral(payOrderParam.getTicketId(), payOrderParam.getNumber());
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("redis 修改库存 异常 -> time:" + (currentTime) + "毫秒");
            }
            e.printStackTrace();
            log.error("Kylin Order Pay Error = " + e.getMessage());
            redisLockUtil.unlock(lock);
            return ResponseDto.failure(ErrorMapping.get("20018"));//乱七八糟异常
        }
    }

    private ResponseDto<PayResultVo> order(PayOrderParam payOrderParam, String uid, boolean isMember, int isTrueName, KylinPerformanceVo performanceData, KylinTicketVo ticketData, List<AdamEntersVo> entersVoList, Integer isStudent, KylinTicketTimesVo ticketTimesData, Long currentTime) {
        LinkedList<String> sqls = new LinkedList<>();
        String source = CurrentUtil.getCliSource() == null ? "" : CurrentUtil.getCliSource();
        String version = CurrentUtil.getCliVersion() == null ? "" : CurrentUtil.getCliVersion();
        LocalDateTime now = LocalDateTime.now();
        //生成订单 order_ticket
        KylinOrderTickets orderTickets = new KylinOrderTickets();
        String orderTicketId = IDGenerator.nextSnowId().toString();
        log.debug("\n ORDER_TICKET_ID = " + orderTicketId + " \n TIME = " + System.currentTimeMillis());
        orderTickets.setOrderTicketsId(orderTicketId);
        orderTickets.setUserId(uid);
        Map token = CurrentUtil.getTokenClaims();
        orderTickets.setUserName(StringUtils.defaultString(((String) token.get("nickname")), ""));
        orderTickets.setUserMobile(StringUtils.defaultString(((String) token.get("mobile")), ""));
        orderTickets.setPerformanceTitle(performanceData.getTitle());
        orderTickets.setOrderCode(IDGenerator.ticketOrderCode(orderTicketId));
        orderTickets.setPayCode("");
        orderTickets.setQrCode("");
        orderTickets.setOrderType(source);
        orderTickets.setOrderVersion(version);
        orderTickets.setNumber(payOrderParam.getNumber());
        orderTickets.setPrice(ticketData.getPrice());
        orderTickets.setPriceMember(ticketData.getMemberPrice());
        if (isMember) {
            orderTickets.setPriceTotal(ticketData.getMemberPrice().multiply(new BigDecimal(payOrderParam.getNumber())).add(payOrderParam.getIsExpress() == 1 ? ticketData.getPriceExpress() : new BigDecimal("0")));
        } else {
            orderTickets.setPriceTotal(ticketData.getPrice().multiply(new BigDecimal(payOrderParam.getNumber())).add(payOrderParam.getIsExpress() == 1 ? ticketData.getPriceExpress() : new BigDecimal("0")));
        }

        /*if (Arrays.asList("dev", "test").contains(environment.getProperty("spring.profiles.active"))) {
            orderTickets.setPriceActual(new BigDecimal("0.01"));
        } else {*/
        orderTickets.setPriceActual(orderTickets.getPriceTotal());
        /*}*/

        orderTickets.setPriceVoucher(new BigDecimal("0.0"));
        orderTickets.setPriceExpress(ticketData.getPriceExpress());
        orderTickets.setPriceRefund(new BigDecimal(0.0));
        orderTickets.setRefundNumber(0);
        orderTickets.setPayType(payOrderParam.getPayType());
        orderTickets.setPaymentType(null);
        orderTickets.setTimePay(null);
        if (payOrderParam.getIsExpress() == 1) {
            currentTime = System.currentTimeMillis();
            AdamAddressesVo addressesVo = orderUtils.getAddress(uid, payOrderParam.getAddressId());//feignAdamBaseClient.queryAddresses(payOrderParam.getAddressId(), uid).getData();
            orderTickets.setExpressContacts(addressesVo.getName());
            orderTickets.setExpressAddress(addressesVo.getProvince() + addressesVo.getCity() + addressesVo.getCounty() + addressesVo.getAddress());
            orderTickets.setExpressPhone(addressesVo.getPhone());
            orderTickets.setGetTicketType("express");
            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("feign 获取入场人 -> time:" + (currentTime) + "毫秒");
        } else {
            orderTickets.setExpressContacts("");
            orderTickets.setExpressAddress("");
            orderTickets.setExpressPhone("");
            orderTickets.setGetTicketType("electronic");
        }
        orderTickets.setCouponType("no");
        orderTickets.setGetTicketDescribe("");
        orderTickets.setPayCountdownMinute(performanceData.getPayCountdownMinute());
        orderTickets.setCreatedAt(now);
        orderTickets.setUpdatedAt(null);


        //生成订单 order_ticket_status
        KylinOrderTicketStatus orderTicketStatus = new KylinOrderTicketStatus();
        String orderTicketStatusId = IDGenerator.nextSnowId().toString();
        orderTicketStatus.setOrderTicketStatusId(orderTicketStatusId);
        orderTicketStatus.setOrderId(orderTicketId);
        orderTicketStatus.setExpressType(payOrderParam.getExpressType());
        orderTicketStatus.setTransferStatus(KylinTableStatusConst.ORDER_TRANSFER_STATUS0);
        orderTicketStatus.setStatus(KylinTableStatusConst.ORDER_STATUS0);
        orderTicketStatus.setIsStudent(isStudent);
        orderTicketStatus.setPayStatus(KylinTableStatusConst.ORDER_PAY_STATUS0);
        orderTicketStatus.setCreatedAt(now);
        orderTicketStatus.setUpdatedAt(null);
        sqls.add(SqlMapping.get("kylin_order_ticket_status.add"));
        LinkedList<Object[]> sqlsDataB = new LinkedList<Object[]>();
        sqlsDataB.add(orderTicketStatus.getAddObject());

        //生成订单 order_ticket_relation
        KylinOrderTicketRelations orderTicketRelations = new KylinOrderTicketRelations();
        String orderTicketRelationId = IDGenerator.nextSnowId();
        orderTicketRelations.setOrderTicketRelationsId(orderTicketRelationId);
        orderTicketRelations.setOrderId(orderTicketId);
        orderTicketRelations.setTransferId("");
        orderTicketRelations.setLiveId("");
        orderTicketRelations.setAgentId(payOrderParam.getAgentId());
        orderTicketRelations.setIsMember(isMember ? 1 : 0);
        orderTicketRelations.setPerformanceId(payOrderParam.getPerformanceId());
        orderTicketRelations.setTimeId(payOrderParam.getTimeId());
        orderTicketRelations.setTicketId(payOrderParam.getTicketId());
        orderTicketRelations.setCreatedAt(now);
        orderTicketRelations.setUpdatedAt(null);
        sqls.add(SqlMapping.get("kylin_order_ticket_relation.add"));
        LinkedList<Object[]> sqlsDataC = new LinkedList<Object[]>();
        sqlsDataC.add(orderTicketRelations.getAddObject());


        //生成票
        KylinOrderTicketEntities orderTicketEntities = new KylinOrderTicketEntities();
        LinkedList<Object[]> sqlsDataD = null;
        sqlsDataD = new LinkedList<Object[]>();
        sqls.add(SqlMapping.get("kylin_order_ticket_entities.add"));
        if (isTrueName == 1) {
            for (AdamEntersVo enters : entersVoList) {
                String orderTicketEntitiesId = IDGenerator.nextSnowId().toString();
                orderTicketEntities.setOrderTicketEntitiesId(orderTicketEntitiesId);
                orderTicketEntities.setOrderId(orderTicketId);
                orderTicketEntities.setTicketId(payOrderParam.getTicketId());
                orderTicketEntities.setUserId(uid);
                orderTicketEntities.setPerformanceId(payOrderParam.getPerformanceId());
                orderTicketEntities.setTimeId(payOrderParam.getTimeId());
                orderTicketEntities.setEnterType(enters.getType());
                orderTicketEntities.setEnterName(enters.getName());
                orderTicketEntities.setEnterMobile(enters.getMobile());
                orderTicketEntities.setEnterIdCode(enters.getIdCard());
                orderTicketEntities.setStatus(KylinTableStatusConst.ENTITIES_STATUS0);
                orderTicketEntities.setSysDamai(ticketData.getSysDamai());
                orderTicketEntities.setCheckClient("");
                orderTicketEntities.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT0);
                orderTicketEntities.setRefundPrice(BigDecimal.valueOf(0.0));
                orderTicketEntities.setComment("");
                orderTicketEntities.setCreatedAt(now);
                orderTicketEntities.setUpdatedAt(null);
                sqlsDataD.add(orderTicketEntities.getAddObject());
                // 生成vo
                KylinOrderTicketEntitiesVo orderTicketEntitiesVo = new KylinOrderTicketEntitiesVo();
                BeanUtils.copyProperties(orderTicketEntities, orderTicketEntitiesVo);
                orderTicketEntitiesVo.setPerformanceTitle(performanceData.getTitle());
                orderTicketEntitiesVo.setTicketTitle(ticketData.getTitle());
                orderTicketEntitiesVo.setUseStart(ticketData.getUseStart());
                orderTicketEntitiesVo.setUseEnd(ticketData.getUseEnd());
                orderTicketEntitiesVo.setTicketsmId(ticketData.getMid());
                orderTicketEntitiesVo.setTimemId(ticketTimesData.getMid());
                orderTicketEntitiesVo.setCreatedAt(orderTicketEntities.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orderTicketEntitiesVo.setUpdatedAt(null);
                orderTicketEntitiesVo.setChangeDate(orderTicketEntities.getCreatedAt());
                currentTime = System.currentTimeMillis();
                mongoTemplate.insert(orderTicketEntitiesVo, KylinOrderTicketEntitiesVo.class.getSimpleName());
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("mongo 添加入场人 -> time:" + (currentTime) + "毫秒");
                currentTime = System.currentTimeMillis();
                dataUtils.changeBuyInfo(orderTicketEntitiesVo.getUserId(), orderTicketEntitiesVo.getEnterIdCode(), orderTicketEntitiesVo.getPerformanceId(), orderTicketEntitiesVo.getTicketId(), 1);
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("redis 修改 限购 -> time:" + (currentTime) + "毫秒");
            }
        } else {
            for (int i = 0; i < payOrderParam.getNumber(); i++) {
                String orderTicketEntitiesId = IDGenerator.nextSnowId().toString();
                orderTicketEntities.setOrderTicketEntitiesId(orderTicketEntitiesId);
                orderTicketEntities.setOrderId(orderTicketId);
                orderTicketEntities.setTicketId(payOrderParam.getTicketId());
                orderTicketEntities.setUserId(uid);
                orderTicketEntities.setPerformanceId(payOrderParam.getPerformanceId());
                orderTicketEntities.setTimeId(payOrderParam.getTimeId());
                orderTicketEntities.setEnterType(0);
                orderTicketEntities.setEnterName("");
                orderTicketEntities.setEnterMobile("");
                orderTicketEntities.setEnterIdCode("");
                orderTicketEntities.setStatus(KylinTableStatusConst.ENTITIES_STATUS0);
                orderTicketEntities.setSysDamai(ticketData.getSysDamai());
                orderTicketEntities.setCheckClient("");
                orderTicketEntities.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT0);
                orderTicketEntities.setComment("");
                orderTicketEntities.setCreatedAt(now);
                orderTicketEntities.setUpdatedAt(null);
                sqlsDataD.add(orderTicketEntities.getAddObject());
                // 生成vo
                KylinOrderTicketEntitiesVo orderTicketEntitiesVo = new KylinOrderTicketEntitiesVo();
                BeanUtils.copyProperties(orderTicketEntities, orderTicketEntitiesVo);
                orderTicketEntitiesVo.setPerformanceTitle(performanceData.getTitle());
                orderTicketEntitiesVo.setTicketTitle(ticketData.getTitle());
                orderTicketEntitiesVo.setUseStart(ticketData.getUseStart());
                orderTicketEntitiesVo.setUseEnd(ticketData.getUseEnd());
                orderTicketEntitiesVo.setTicketsmId(ticketData.getMid());
                orderTicketEntitiesVo.setTimemId(ticketTimesData.getMid());
                orderTicketEntitiesVo.setCreatedAt(orderTicketEntities.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orderTicketEntitiesVo.setUpdatedAt(null);
                orderTicketEntitiesVo.setChangeDate(orderTicketEntities.getCreatedAt());
                currentTime = System.currentTimeMillis();
                mongoTemplate.insert(orderTicketEntitiesVo, KylinOrderTicketEntitiesVo.class.getSimpleName());
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("mongo 添加入场人 -> time:" + (currentTime) + "毫秒");
                currentTime = System.currentTimeMillis();
                dataUtils.changeBuyInfo(orderTicketEntitiesVo.getUserId(), orderTicketEntitiesVo.getEnterIdCode(), orderTicketEntitiesVo.getPerformanceId(), orderTicketEntitiesVo.getTicketId(), 1);
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("redis 修改限购 -> time:" + (currentTime) + "毫秒");
            }
        }
        // 调用支付
        String time1 = DateUtil.format(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketData.getUseStart()), DateUtil.Formatter.MM_dd_zh);
        String time2 = DateUtil.format(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketData.getUseEnd()), DateUtil.Formatter.MM_dd_zh);
        String useTime = ticketData.getType() == 2 ? time1 + "~" + time2 : time2;


        LinkedMultiValueMap<String, String> httpData = new LinkedMultiValueMap<String, String>();
        httpData.add("type", "TICKET");
        /*if (Arrays.asList("dev", "test").contains(environment.getProperty("spring.profiles.active"))) {
            httpData.add("price", "0.01");
        } else {*/
        httpData.add("price", orderTickets.getPriceActual().toString());
//        }
        httpData.add("name", useTime + ticketData.getTitle() + "-" + performanceData.getTitle());
        httpData.add("detail", performanceData.getTitle() + "-" + ticketData.getTitle() + "-" + useTime);
        httpData.add("order_code", orderTickets.getOrderCode());
        httpData.add("client_ip", CurrentUtil.getCliIpAddr());
        httpData.add("notify_url", synUrl);
        httpData.add("create_date", orderTickets.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        httpData.add("expire_time", (orderTickets.getPayCountdownMinute()) + "");

        if (payOrderParam.getDeviceFrom().equals("js") || payOrderParam.getDeviceFrom().equals("applet")) {
            httpData.add("open_id", payOrderParam.getOpenId());
        }
        if (payOrderParam.getPayType().equals("alipay") && payOrderParam.getDeviceFrom().equals("wap")) {
            httpData.add("show_url", payOrderParam.getShowUrl() + orderTicketId);
            httpData.add("return_url", payOrderParam.getReturnUrl() + orderTicketId);
        }

        currentTime = System.currentTimeMillis();
        String returnData = HttpUtil.post(payUrl + payOrderParam.getDeviceFrom() + "/" + payOrderParam.getPayType(), httpData);
        currentTime = System.currentTimeMillis() - currentTime;
        log.debug("调用 PHP 支付 -> time:" + (currentTime) + "毫秒");
        PayResultVo payResultVo = JsonUtils.fromJson(returnData, PayResultVo.class);
//        PayResultVo payResultVo = null;
//        try {
//            payResultVo = JsonUtils.fromJson("{\n" +
//                    "    \"code\": \"20210618130049218267704668657P\",\n" +
//                    "    \"order_code\": \"T7774750254320448484\",\n" +
//                    "    \"status\": null,\n" +
//                    "    \"order_id\": \"77747502543208448\",\n" +
//                    "    \"showUrl\": \"http://devm.zhengzai.tv/#/ticket/purchase/detail?id=5936241&amp;type=purchase&amp;performance_id=5936241&amp;ticket_id=10981&amp;amount=1&amp;products_array=&amp;amount_array=&amp;express=077747502543208448\",\n" +
//                    "    \"returnUrl\": \"http://devm.zhengzai.tv/#/order/status?order_type=ticket&amp;order_id=77747502543208448\",\n" +
//                    "    \"price\": 0.01,\n" +
//                    "    \"pay_data\": {\n" +
//                    "      \"packages\": null,\n" +
//                    "      \"partnerid\": null,\n" +
//                    "      \"prepayid\": null,\n" +
//                    "      \"sign\": null,\n" +
//                    "      \"mweb_url\": null,\n" +
//                    "      \"paySign\": null,\n" +
//                    "      \"signType\": null,\n" +
//                    "      \"redirect_url\": \"https://openapi.alipay.com/gateway.do?alipay_sdk=lokielse%2Fomnipay-alipay&app_id=2019082866535131&biz_content=%7B%22product_code%22%3A%22QUICK_WAP_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%2206%5Cu670830%5Cu65e5%5Cu5355%5Cu65e5%5Cu7968%5Cu80e1%5Cu5927%5Cu7f8e%5Cu5e76%5Cu53d1%5Cu4e0b%5Cu5355%22%2C%22body%22%3A%22%5Cu80e1%5Cu5927%5Cu7f8e%5Cu5e76%5Cu53d1%5Cu4e0b%5Cu5355%5Cu5355%5Cu65e5%5Cu796806%5Cu670830%5Cu65e5%22%2C%22out_trade_no%22%3A%2220210618130049218267704668657P%22%2C%22time_expire%22%3A%222021-06-18+13%3A06%22%2C%22quit_url%22%3A%22http%3A%5C%2F%5C%2Fdevm.zhengzai.tv%5C%2F%23%5C%2Fticket%5C%2Fpurchase%5C%2Fdetail%3Fid%3D5936241%26amp%3Btype%3Dpurchase%26amp%3Bperformance_id%3D5936241%26amp%3Bticket_id%3D10981%26amp%3Bamount%3D1%26amp%3Bproducts_array%3D%26amp%3Bamount_array%3D%26amp%3Bexpress%3D077747502543208448%22%7D&charset=utf-8&format=JSON&method=alipay.trade.wap.pay&notify_url=http%3A%2F%2Ftestpay.zhengzai.tv%2Fnotify%2Fwap%2Falipay%2F1&return_url=http%3A%2F%2Fdevm.zhengzai.tv%2F%23%2Forder%2Fstatus%3Forder_type%3Dticket%26amp%3Border_id%3D77747502543208448&sign_type=RSA2&timestamp=2021-06-18+13%3A00%3A49&version=1.0&sign=UaHmNdI1cXjjSkR4gwrnELSWXqb1Icg1uCOe0vEo5yHCqWOy4JZCZbjCR1xOHQKowSMBAr6U2XLtMAaNXr6mX%2B%2F5IiaChsD4IPoODNT7F4GckVcqP3GkdLZTro%2FGmBau6VoYw1uVpyutQTJsjEU1fQ%2F5KDAKLvg0XG%2F1D%2BXb%2Bv6LdLDvehCEPzy4W%2BCT0qPANU4ysgZkt9hP1ljH61%2FBWiDnfz%2BOdust4KBoJYQzNWO3XSwvc17OxdGHn8EBmYRJz6sr1nt0i2h4BGQtjrOHRB3dToVkxrlsHtbrOmiCdRFH6utSVA8UjeKtlEB%2FH%2BkQfVxPkpOicTjkokhDNK6svg%3D%3D\",\n" +
//                    "      \"order_str\": null,\n" +
//                    "      \"appId\": null,\n" +
//                    "      \"appid\": null,\n" +
//                    "      \"nonceStr\": null,\n" +
//                    "      \"noncestr\": null,\n" +
//                    "      \"timeStamp\": null,\n" +
//                    "      \"timestamp\": null,\n" +
//                    "      \"package\": null\n" +
//                    "    }\n" +
//                    "  }", PayResultVo.class);
//        } catch (Exception e) {
//            payResultVo = new PayResultVo();
//        }
        payResultVo.setOrder_id(orderTicketId);
        payResultVo.setPrice(orderTickets.getPriceActual());
        orderTickets.setPayCode(payResultVo.getCode());
        sqls.add(SqlMapping.get("kylin_order_ticket.add"));
        LinkedList<Object[]> sqlsDataA = new LinkedList<>();
        sqlsDataA.add(orderTickets.getAddObject());

        if (payOrderParam.getPayType().equals("alipay") && payOrderParam.getDeviceFrom().equals("wap")) {
            payResultVo.setShowUrl(payOrderParam.getShowUrl() + orderTicketId);
            payResultVo.setReturnUrl(payOrderParam.getReturnUrl() + orderTicketId);
        }
        // 生成vo
        KylinOrderTicketVo orderTicketVo = new KylinOrderTicketVo();
        orderTicketVo.setOrderTicket(orderTickets);
        orderTicketVo.setOrderTicketStatus(orderTicketStatus);
        orderTicketVo.setOrderTicketRelation(orderTicketRelations);
        orderTicketVo.setPerformanceImg(performanceData.getImgPoster());
        orderTicketVo.setTicketTitle(ticketData.getTitle());
        orderTicketVo.setUseStart(ticketData.getUseStart());
        orderTicketVo.setTimeStart(performanceData.getTimeStart());
        orderTicketVo.setOverdueAt(orderTickets.getCreatedAt().plusMinutes(performanceData.getPayCountdownMinute()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderTicketVo.setCreatedAt(orderTickets.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderTicketVo.setChangeDate(orderTickets.getCreatedAt());
        currentTime = System.currentTimeMillis();
        mongoTemplate.insert(orderTicketVo, KylinOrderTicketVo.class.getSimpleName());
        currentTime = System.currentTimeMillis() - currentTime;
        log.debug("mongo  添加 订单 -> time:" + (currentTime) + "毫秒");

        currentTime = System.currentTimeMillis();
        mongoVoUtils.resetOrderListVo(uid, 1, orderTicketVo.getOrderTicketsId(), orderTicketVo);
        currentTime = System.currentTimeMillis() - currentTime;
        log.debug("redis 修改订单列表 -> time:" + (currentTime) + "毫秒");

        // 执行sql
        String sqlData = SqlMapping.gets(sqls, sqlsDataB, sqlsDataC, sqlsDataD, sqlsDataA);
        currentTime = System.currentTimeMillis();
        rabbitTemplate.convertAndSend(MQConst.EXCHANGES_LIQUIDNET_SQL_ORDER_CREADE, MQConst.ROUTING_KEY_SQL_ORDER_CREATE,
                sqlData);
        currentTime = System.currentTimeMillis() - currentTime;
        log.debug("MQ 发送 -> time:" + (currentTime) + "毫秒");
        log.info(UserPathDto.setData("下单(唤起支付)", payOrderParam, payResultVo));
        return ResponseDto.success(payResultVo);
    }

    @Override
    public ResponseDto<PayResultVo> payAgain(PayAgainParam payAgainParam) {
        try {
            String uid = CurrentUtil.getCurrentUid();
//            checkOrderTime(uid);
            //检查订单时间 是否关闭
            KylinOrderTicketVo orderTicketData = dataUtils.getOrderTicketVo(payAgainParam.getOrderId());
            if (!orderTicketData.getUserId().equals(uid)) {
                return null;
            }
            if (orderTicketData == null) {
                return ResponseDto.failure("订单不存在");
            }

            if (orderTicketData.getStatus() == KylinTableStatusConst.ORDER_STATUS1) {
                return ResponseDto.failure("订单已支付");
            } else {
                if (orderTicketData.getStatus() != KylinTableStatusConst.ORDER_STATUS0) {
                    return ResponseDto.failure("订单已关闭");
                }
            }
            String returnCheckData = HttpUtil.get(checkUrl + "?code=" + orderTicketData.getPayCode(), null);
            PayResultVo checkVo = JsonUtils.fromJson(returnCheckData, PayResultVo.class);
            if (checkVo.getStatus() == 1) {
                return ResponseDto.failure("'您已支付请刷新再试'");
            }
            if (!orderTicketData.getPayType().equals("no")) {

                if (orderTicketData.getEntitiesVoList().size() == 0) {
                    return ResponseDto.failure("参数错误");
                }
                KylinOrderTicketEntitiesVo entitiesData = orderTicketData.getEntitiesVoList().get(0);

                LinkedMultiValueMap<String, String> httpData = new LinkedMultiValueMap<String, String>();
                httpData.add("type", "TICKET");
                if (Arrays.asList("dev", "test").contains(environment.getProperty("spring.profiles.active"))) {
                    httpData.add("price", orderTicketData.getPriceActual().toString());
                } else {
                    httpData.add("price", "0.01");
                }
                httpData.add("name", entitiesData.getUseStart() + "" + entitiesData.getPerformanceTitle());
                httpData.add("detail", entitiesData.getPerformanceTitle() + "-" + entitiesData.getTicketTitle() + "-" + entitiesData.getUseStart());
                httpData.add("order_code", orderTicketData.getOrderCode());
                httpData.add("client_ip", CurrentUtil.getCliIpAddr());
                httpData.add("notify_url", synUrl);
                httpData.add("create_date", orderTicketData.getCreatedAt());
                httpData.add("expire_time", orderTicketData.getPayCountdownMinute().toString());

                httpData.add("open_id", payAgainParam.getOpenId());

                if (payAgainParam.getPayType().equals("alipay") && payAgainParam.getDeviceFrom().equals("wap")) {
                    httpData.add("show_url", payAgainParam.getShowUrl() + payAgainParam.getOrderId());
                    httpData.add("return_url", payAgainParam.getReturnUrl() + payAgainParam.getOrderId());
                }

                String returnData = HttpUtil.post(payUrl + payAgainParam.getDeviceFrom() + "/" + payAgainParam.getPayType(), httpData);
                PayResultVo payResultVo = JsonUtils.fromJson(returnData, PayResultVo.class);
                payResultVo.setOrder_id(orderTicketData.getOrderTicketsId());
                payResultVo.setPrice(orderTicketData.getPriceActual());
                if (payAgainParam.getPayType().equals("alipay") && payAgainParam.getDeviceFrom().equals("wap")) {
                    payResultVo.setShowUrl(payAgainParam.getShowUrl());
                    payResultVo.setReturnUrl(payAgainParam.getReturnUrl());
                }

                KylinOrderTickets orderTickets = new KylinOrderTickets();
                orderTickets.setOrderTicketsId(payAgainParam.getOrderId());
                orderTickets.setUpdatedAt(LocalDateTime.now());
                orderTickets.setPayCode(payResultVo.getCode());
                orderTickets.setPayType(payAgainParam.getPayType());

                //改vo
                HashMap<String, Object> map = new HashMap<>();
                map.put("payType", payAgainParam.getPayType());
                map.put("payCode", payResultVo.getCode());
                map.put("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(orderTickets.getUpdatedAt()));
                map.put("changeDate", orderTickets.getUpdatedAt());
                mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                        Query.query(Criteria.where("orderTicketsId").is(payAgainParam.getOrderId())).getQueryObject(),
                        new BasicDBObject("$set", mongoConverter.convertToMongoType(map))
                );

                LocalDateTime strTime = orderTicketData.getChangeDate();
                dataUtils.delOrderTicketRedis(orderTickets.getOrderTicketsId());

                LinkedList<String> sqls = new LinkedList<>();
                sqls.add(SqlMapping.get("kylin_order_ticket.payAgain"));
                LinkedList<Object[]> sqlsDataA = new LinkedList<>();
                sqlsDataA.add(orderTickets.getPayAgainObject(strTime, strTime));
                sqls.add(SqlMapping.get("kylin_order_ticket_status.payAgain"));
                LinkedList<Object[]> sqlsDataB = new LinkedList<>();
                sqlsDataB.add(new Object[]{orderTickets.getUpdatedAt(), orderTickets.getOrderTicketsId(), strTime, strTime});
                sqls.add(SqlMapping.get("kylin_order_ticket_relation.payAgain"));
                LinkedList<Object[]> sqlsDataC = new LinkedList<>();
                sqlsDataC.add(new Object[]{orderTickets.getUpdatedAt(), orderTickets.getOrderTicketsId(), strTime, strTime});
                sqls.add(SqlMapping.get("kylin_order_ticket_entities.payAgain"));
                LinkedList<Object[]> sqlsDataD = new LinkedList<>();
                sqlsDataD.add(new Object[]{orderTickets.getUpdatedAt(), orderTickets.getOrderTicketsId(), strTime, strTime});

                String sqlData = SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC, sqlsDataD);
                rabbitTemplate.convertAndSend(MQConst.EXCHANGES_LIQUIDNET_SQL_ORDER_AGAIN, MQConst.ROUTING_KEY_SQL_ORDER_AGAIN, sqlData);
                log.info(UserPathDto.setData("再次支付", payAgainParam, payResultVo));
                return ResponseDto.success(payResultVo);
            }
            return ResponseDto.failure("未选择支付方式");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDto.failure("订单已失效");
        }

    }

    @Override
    public String syncOrder(SyncOrderParam syncOrderParam) {
        //支付时间
        LocalDateTime now = LocalDateTime.now();
        String lock = "order_lock:" + syncOrderParam.getOrder_code();
        if (!redisLockUtil.tryLock(lock, 1, 5)) {
            return "fail";//参数错误
        }

        String timePay = DateUtil.Formatter.yyyyMMddHHmmss.format(now);
        KylinOrderTicketVo orderTicketData = mongoTemplate.findOne(Query.query(Criteria.where("orderCode").is(syncOrderParam.getOrder_code())), KylinOrderTicketVo.class, KylinOrderTicketVo.class.getSimpleName());
        if (orderTicketData == null) {
            redisLockUtil.unlock(lock);
            return "fail";//订单不存在
        }

        if (orderTicketData.getStatus() != KylinTableStatusConst.ORDER_STATUS0) {
            if (orderTicketData.getPayCode().equals(syncOrderParam.getCode()) && orderTicketData.getStatus() == KylinTableStatusConst.ORDER_STATUS1) {
                redisLockUtil.unlock(lock);
                return "success";//已经支付
            }

            if (!orderTicketData.getPayCode().equals(syncOrderParam.getCode())) {
                redisLockUtil.unlock(lock);
                return "fail";//重复支付
            }
        }

        if (orderTicketData.getPriceActual().compareTo(syncOrderParam.getPrice()) != 0) {
            redisLockUtil.unlock(lock);
            return "fail";//价格不符
        }

        LinkedList<String> sqls = new LinkedList<>();
        LinkedList<Object[]> sqlsDataA = new LinkedList<>();
        LinkedList<Object[]> sqlsDataB = new LinkedList<>();
        LinkedList<Object[]> sqlsDataC = new LinkedList<>();
        LinkedList<Object[]> sqlsDataD = new LinkedList<>();

        LocalDateTime strTime = orderTicketData.getChangeDate();

        KylinOrderTickets orderTickets = new KylinOrderTickets();
        KylinOrderTicketStatus orderTicketStatus = new KylinOrderTicketStatus();
        KylinOrderTicketEntities orderTicketEntities = new KylinOrderTicketEntities();

        if (orderTicketData.getStatus() == 2) {
            mongoVoUtils.resetOrderListVo(orderTicketData.getUserId(), 2, orderTicketData.getOrderTicketsId(), null);
            log.error("订单号位 {} 的订单超时支付", syncOrderParam.getOrder_code());
            orderRefundsCallbackService.refundApply(orderTicketData.getOrderTicketsId());
        } else if (orderTicketData.getStatus() == 3 || orderTicketData.getStatus() == 4) {
            log.error("订单号位 {} 的订单正在退款 或者已退款", syncOrderParam.getOrder_code());
        } else {
            orderTickets.setOrderTicketsId(orderTicketData.getOrderTicketsId());
            orderTickets.setPaymentType(syncOrderParam.getPayment_type());
            orderTickets.setPayCode(syncOrderParam.getCode());
            orderTickets.setTimePay(timePay);
            orderTickets.setQrCode(IDGenerator.ticketQrCode(orderTicketData.getOrderTicketsId()));
            orderTickets.setUpdatedAt(now);
            sqls.add(SqlMapping.get("kylin_order_ticket.synPay"));
            sqlsDataA.add(orderTickets.getSynOrderObject(strTime, strTime));

            orderTicketStatus.setOrderId(orderTicketData.getOrderTicketsId());
            orderTicketStatus.setStatus(KylinTableStatusConst.ORDER_STATUS1);
            orderTicketStatus.setPayStatus(syncOrderParam.getStatus());
            orderTicketStatus.setUpdatedAt(orderTickets.getUpdatedAt());
            sqls.add(SqlMapping.get("kylin_order_ticket_status.synPay"));
            sqlsDataB.add(orderTicketStatus.getSynOrderObject(strTime, strTime));

            sqls.add(SqlMapping.get("kylin_order_ticket_relation.synPay"));
            sqlsDataC.add(new Object[]{orderTickets.getUpdatedAt(), orderTickets.getOrderTicketsId(), strTime, strTime});

            orderTicketEntities.setOrderId(orderTicketData.getOrderTicketsId());
            orderTicketEntities.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT1);
            orderTicketEntities.setUpdatedAt(orderTickets.getUpdatedAt());
            sqls.add(SqlMapping.get("kylin_order_ticket_entities.synPay"));
            sqlsDataD.add(orderTicketEntities.getSynOrderObject(strTime, strTime));

            //vo
            HashMap<String, Object> orderTicketVo = new HashMap<>();
            orderTicketVo.put("paymentType", orderTickets.getPaymentType());
            orderTicketVo.put("payCode", orderTickets.getPayCode());
            orderTicketVo.put("timePay", orderTickets.getTimePay());
            orderTicketVo.put("qrCode", orderTickets.getQrCode());
            orderTicketVo.put("status", KylinTableStatusConst.ORDER_STATUS1);
            orderTicketVo.put("payStatus", orderTicketStatus.getStatus());
            orderTicketVo.put("updatedAt", timePay);
            orderTicketVo.put("changeDate", now);
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderTickets.getOrderTicketsId())).getQueryObject(),
                    new BasicDBObject("$set", mongoConverter.convertToMongoType(orderTicketVo))
            );


            HashMap<String, Object> orderTicketEntitiesVo = new HashMap<>();
            orderTicketEntitiesVo.put("isPayment", KylinTableStatusConst.ENTITIES_IS_PAYMENT1);
            orderTicketEntitiesVo.put("updatedAt", timePay);
            orderTicketEntitiesVo.put("changeDate", now);
            mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).updateMany(
                    Query.query(Criteria.where("orderId").is(orderTicketData.getOrderTicketsId())).getQueryObject(),
                    new BasicDBObject("$set", mongoConverter.convertToMongoType(orderTicketEntitiesVo))
            );

            rabbitTemplate.convertAndSend(MQConst.EXCHANGES_LIQUIDNET_SQL_ORDER_PAY, MQConst.ROUTING_KEY_SQL_ORDER_PAY,
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC, sqlsDataD));

            //生成vo redis
            dataUtils.delOrderTicketRedis(orderTickets.getOrderTicketsId());
            mongoVoUtils.resetOrderListVo(orderTicketData.getUserId(), 2, orderTicketData.getOrderTicketsId(), null);

            // 发短信
            KylinPerformanceVo performanceData = dataUtils.getPerformanceVo(orderTicketData.getPerformanceId());
            KylinTicketTimesVo ticketTimesData = null;
            KylinTicketVo ticketData = null;
            for (int x = 0; x < performanceData.getTicketTimeList().size(); x++) {
                KylinTicketTimesVo timeItem = performanceData.getTicketTimeList().get(x);
                if (timeItem.getTimeId().equals(orderTicketData.getTimeId())) {
                    ticketTimesData = timeItem;
                    for (int y = 0; y < ticketTimesData.getTicketList().size(); y++) {
                        KylinTicketVo ticketItem = ticketTimesData.getTicketList().get(y);
                        if (ticketItem.getTicketsId().equals(orderTicketData.getTicketId())) {
                            ticketData = ticketItem;
                            break;
                        }
                    }
                    break;
                }
            }

            MessageDataVo dataVo = new MessageDataVo();
            dataVo.setName(orderTicketData.getPerformanceTitle());
            String time1 = DateUtil.format(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketData.getUseStart()), DateUtil.Formatter.yyyy_MM_dd);
            String time2 = DateUtil.format(DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceData.getTimeStart()), DateUtil.Formatter.HHmm);
            dataVo.setTime(time1 + " " + time2);

            MessageConfigVo configVo = new MessageConfigVo();
            configVo.setStatus(true);
            if (orderTicketData.getGetTicketType().equals("express")) {
                configVo.setId("SMS_181490473");
            } else if (orderTicketData.getGetTicketType().equals("electronic")) {
                configVo.setId(ticketData.getIsShowCode() == 1 ? "SMS_171358560" : "SMS_181500419");
            }
//            otherUtils.sendMessage(orderTicketData.getUserMobile(), dataVo, configVo, 1);

            // 大麦回调
            sycDamaiOrder(orderTickets.getOrderTicketsId());
        }
        redisLockUtil.unlock(lock);
        log.info(UserPathDto.setData("订单支付成功回调", syncOrderParam, ""));
        return "success";
    }

    @Override
    public PageInfo<List<KylinOrderListVo>> orderList() {
        //TODO 缺快递
        PageInfo<List<KylinOrderListVo>> mPageInfo = null;
        String uid = CurrentUtil.getCurrentUid();
//        checkOrderTime(uid);
        try {
            List<KylinOrderListVo> voList = dataUtils.getOrderList(uid);
            for (int i = 0; i < voList.size(); i++) {
                KylinOrderListVo item = voList.get(i);
                //TODO 顺丰快递
                Object expresses = null;
                if (null != expresses) {
                    item.setExpress_number("");//expresses.getNumber()
                    item.setExpress_company("");//expresses.getName()
                    item.setKuaidi_status(-2);//expresses.getStatus()
                } else {
                    item.setExpress_number("");
                    item.setExpress_company("");
                    item.setKuaidi_status(-2);
                }

                if (item.getStatus().equals(KylinTableStatusConst.ORDER_STATUS0)) {
                    try {
                        item.setRestTime(DateUtil.intervalSeconds(
                                DateUtil.parse(item.getOverdueAt(), "yyyy-MM-dd HH:mm:ss"),
                                DateUtil.parse(DateUtil.getNowTime(), "yyyy-MM-dd HH:mm:ss")
                        ));
                        if (item.getRestTime() <= 0L) {
                            item.setRestTime(0L);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    log.debug("item.getOverdueAt() = " + item.getOverdueAt());
                    log.debug("DateUtil.getNowTime() = " + DateUtil.getNowTime());
                    log.debug("item.getRestTime() = " + item.getRestTime());
                } else {
                    item.setRestTime(0L);
                }
                if (i >= 40) {
                    break;
                }
            }

            mPageInfo = new PageInfo(voList);
            mPageInfo.setTotal(voList.size());

            log.info(UserPathDto.setData("订单列表", "", voList));
            return mPageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return mPageInfo;
        }
    }

    @Override
    public OrderDetailsVo orderDetails(String orderId) {
        OrderDetailsVo vo = new OrderDetailsVo();
        try {
            String uid = CurrentUtil.getCurrentUid();
//            checkOrderTime(uid);
            KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
            if (!orderTicketVo.getUserId().equals(uid)) {
                return null;
            }
            if (null != orderTicketVo) {
                //TODO 顺丰快递
                Object expresses = null;
                KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(orderTicketVo.getPerformanceId());
                List<KylinOrderTicketEntitiesVo> kylinOrderTicketEntitiesVoList = orderTicketVo.getEntitiesVoList();
                KylinTicketVo ticketVo = null;

                //获取购票数据
                for (int x = 0; x < performanceVo.getTicketTimeList().size(); x++) {
                    KylinTicketTimesVo timeItem = performanceVo.getTicketTimeList().get(x);
                    for (int y = 0; y < timeItem.getTicketList().size(); y++) {
                        KylinTicketVo ticketItem = timeItem.getTicketList().get(y);
                        if (ticketItem.getTicketsId().equals(orderTicketVo.getTicketId())) {
                            ticketVo = ticketItem;
                            break;
                        }
                    }
                }

                orderTicketVo.setIsTrueName(ticketVo.getIsTrueName());
                orderTicketVo.setNoticeImage(performanceVo.getNoticeImage());
                orderTicketVo.setNotice(performanceVo.getNotice());
                orderTicketVo.setTicketType(ticketVo.getType());
                orderTicketVo.setFieldName(performanceVo.getFieldName());
                if (ticketVo.getIsShowCode() == 1 && orderTicketVo.getStatus()!=0 && orderTicketVo.getStatus()!=2 && orderTicketVo.getStatus()!=4 ) {
                    LocalDateTime date = DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketVo.getQrCodeShowTime());
                    if (LocalDateTime.now().isAfter(date)) {
                        orderTicketVo.setQrCode(orderTicketVo.getQrCode());
                    } else {
                        orderTicketVo.setQrCode("");
                    }
                } else {
                    orderTicketVo.setQrCode("");
                }

                // 数据脱敏
                for (KylinOrderTicketEntitiesVo item : kylinOrderTicketEntitiesVoList) {
                    if (item.getEnterIdCode().length() == 18) {
                        item.setEnterIdCode(item.getEnterIdCode().substring(0, 3) + "*************" + item.getEnterIdCode().substring(16));
                    }
                    if (item.getEnterMobile().length() == 11) {
                        item.setEnterMobile(item.getEnterMobile().substring(0, 3) + "****" + item.getEnterMobile().substring(7));
                    }
                }
                //计算 倒计时
                Date nowDate = DateUtil.parse(DateUtil.getNowTime(), "yyyy-MM-dd HH:mm:ss");
                if (orderTicketVo.getStatus().equals(KylinTableStatusConst.ORDER_STATUS0)) {
                    vo.setRestTime(DateUtil.intervalSeconds(
                            DateUtil.parse(orderTicketVo.getOverdueAt(), "yyyy-MM-dd HH:mm:ss"),
                            nowDate
                    ));
                    if (vo.getRestTime() <= 0L) {
                        vo.setRestTime(0L);
                    }
                } else {
                    vo.setRestTime(0L);
                }
                //快递
                if (null != expresses) {
                    vo.setExpress_number("");//expresses.getNumber()
                    vo.setExpress_company("");//expresses.getName()
                    vo.setKuaidi_status(-2);//expresses.getStatus()
                } else {
                    vo.setExpress_number("");
                    vo.setExpress_company("");
                    vo.setKuaidi_status(-2);
                }

                if (null != performanceVo.getIsCanRefund() && performanceVo.getIsCanRefund() == 1) {
                    LocalDateTime refundOpenDate = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getRefundOpenTime());
                    LocalDateTime refundCloseDate =  DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getRefundCloseTime());
                    if (LocalDateTime.now().isAfter(refundOpenDate) && LocalDateTime.now().isBefore(refundCloseDate)) {
                        vo.setIsCanRefund(1);
                    } else {
                        vo.setIsCanRefund(0);
                    }
                } else {
                    vo.setIsCanRefund(0);
                }

                List<KylinOrderRefundsOrderCodeVo> orderRefundsVoBaseList = new ArrayList<>();
                for (KylinOrderRefundsVoBase item : dataUtils.getOrderRefundVoByOrderId(orderId)) {
                    KylinOrderRefundsOrderCodeVo data = new KylinOrderRefundsOrderCodeVo();
                    data.setOrderRefundsId(item.getOrderRefundsId());
                    data.setOrderRefundCode(item.getOrderRefundCode());
                    data.setStatus(item.getStatus());
                }

                List<KylinOrderRefundsVoBase> orderRefundsVoList = dataUtils.getOrderRefundVoByOrderId(orderId);
                List<OrderRefundListVo> orderRefundListVos = new ArrayList<>();
                for (KylinOrderRefundsVoBase item : orderRefundsVoList){
                    OrderRefundListVo data = new OrderRefundListVo();
                    data.setOrderRefundCode(item.getOrderRefundCode().substring(item.getOrderRefundCode().length()-10));
                    data.setOrderRefundsId(item.getOrderRefundsId());
                    data.setStatus(item.getStatus());
                    orderRefundListVos.add(data);
                }
                orderTicketVo.setOrderRefundListVos(orderRefundListVos);
                orderTicketVo.setOrderCode(orderTicketVo.getOrderCode().substring(orderTicketVo.getOrderCode().length()-10));
                vo.setOrderRefundsVoList(orderRefundsVoBaseList);
                vo.setOrderTicketVo(orderTicketVo);
                vo.setEnterDescribe(dataUtils.getEnterInfo("1"));
            }
            log.info(UserPathDto.setData("订单详情", orderId, vo));
            return vo;
        } catch (Exception e) {
            e.printStackTrace();
            return vo;
        }
    }

    @Override
    public boolean checkOrderTime(String userId) {
        String lock = "order_lock:checkOrderTime:" + userId;
        List<OrderScriptDto> dtoData = orderTicketsMapper.orderScriptDto(userId);
        LocalDateTime now = LocalDateTime.now();
        Long currentTime = System.currentTimeMillis();
        HashMap<String, Integer> mapSurplusGeneral = new HashMap<>();
        ArrayList<String> orderDataList = new ArrayList<>();
        ArrayList<String> orderIdList = new ArrayList<>();
        HashMap<String, Object> mapMongo = new HashMap<>();

        for (OrderScriptDto item : dtoData) {
            if (item.getStatus().equals(KylinTableStatusConst.ORDER_STATUS0)) {
                try {
                    //vo
                    mapMongo.put("status", KylinTableStatusConst.ORDER_STATUS2);
                    mapMongo.put("updatedAt", DateUtil.Formatter.yyyyMMddHHmmssSSS.format(now));
                    mapMongo.put("changeDate", now);
                    orderDataList.add(item.getOrderTicketsId() + "," + item.getUserId());
                    orderIdList.add(item.getOrderTicketsId());
                    mapSurplusGeneral.put(item.getTicketId(), mapSurplusGeneral.get(item.getTicketId()) == null ? item.getNumber() : mapSurplusGeneral.get(item.getTicketId()) + item.getNumber());
                } catch (Exception e) {
                    log.debug("CHECK TIME SYNC = " + e.getMessage());
                    e.printStackTrace();
                    return false;
                }
            } else {
            }
        }
        currentTime = System.currentTimeMillis() - currentTime;
        log.debug("FOR 循环 -> time:" + (currentTime) + "毫秒");

        if (orderDataList.size() > 0) {
            //mysql
            String orderStr = "";
            for (int i = 0; i < orderIdList.size(); i++) {
                String orderTicketId = orderIdList.get(i);
                orderStr += "'" + orderTicketId + "',";
            }
            orderStr = orderStr.substring(0, orderStr.length() - 1);

            KylinOrderTickets orderTickets = new KylinOrderTickets();
            orderTickets.setUpdatedAt(now);
            orderTicketsMapper.update(orderTickets, new UpdateWrapper<KylinOrderTickets>().in("order_tickets_id", orderIdList));

            KylinOrderTicketStatus orderTicketStatus = new KylinOrderTicketStatus();
            orderTicketStatus.setStatus(2);
            orderTicketStatus.setUpdatedAt(now);
            orderTicketStatusMapper.update(orderTicketStatus, new UpdateWrapper<KylinOrderTicketStatus>().in("order_id", orderIdList));

            KylinOrderTicketRelations orderTicketRelations = new KylinOrderTicketRelations();
            orderTicketRelations.setUpdatedAt(now);
            orderTicketRelationsMapper.update(orderTicketRelations, new UpdateWrapper<KylinOrderTicketRelations>().in("order_id", orderIdList));

            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("mysql -> time:" + (currentTime) + "毫秒");

            //库存
            for (Map.Entry<String, Integer> entry : mapSurplusGeneral.entrySet()) {
                dataUtils.changeSurplusGeneral(entry.getKey(), entry.getValue());
            }
            currentTime = System.currentTimeMillis() - currentTime;
            log.debug("redis 库存 -> time:" + (currentTime) + "毫秒");

            try {
                //mongo
                mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateMany(
                        Query.query(Criteria.where("orderTicketsId").in(orderIdList)).getQueryObject(),
                        new BasicDBObject("$set", mongoConverter.convertToMongoType(mapMongo))
                );
                currentTime = System.currentTimeMillis() - currentTime;
                log.debug("mongo -> time:" + (currentTime) + "毫秒");
            } catch (Exception e) {

            }

            int forSize = 500;
            int forCount = orderDataList.size() % forSize == 0 ? orderDataList.size() / forSize : (orderDataList.size() / forSize) + 1;
            for (int i = 0; i < forCount; i++) {
                LinkedList<String> mqList = new LinkedList<>();
                for (int y = 0; y < forSize; y++) {
                    try {
                        String t = orderDataList.get(i * 500 + y);
                        mqList.add(t);
                    } catch (Exception e) {
                        break;
                    }
                }
                rabbitTemplate.convertAndSend(MQConst.EXCHANGES_LIQUIDNET_SQL_ORDER_CLOSE, MQConst.ROUTING_KEY_SQL_ORDER_CLOSE, OrderCloseMapping.get(mqList));
            }
        }
        return true;
    }

    @Override
    public ResponseDto<Integer> checkOrderResult(String orderId) {
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderTicketVo orderTicketData = dataUtils.getOrderTicketVo(orderId);
        if (!orderTicketData.getUserId().equals(uid)) {
            return null;
        }
        if (orderTicketData == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            String returnCheckData = HttpUtil.get(checkUrl + "?code=" + orderTicketData.getPayCode(), null);
            PayResultVo checkVo = JsonUtils.fromJson(returnCheckData, PayResultVo.class);
            if (checkVo.getStatus() == 1) {
                return ResponseDto.success(1);
            } else {
                return ResponseDto.success(0);
            }
        }
    }

    @Override
    public ResponseDto<Integer> orderUnPayCount() {
        String uid = CurrentUtil.getCurrentUid();
        List<KylinOrderListVo> voList = dataUtils.getOrderList(uid);
        int unPayCount = 0;
        for (KylinOrderListVo item : voList) {

            if (item.getStatus().equals(KylinTableStatusConst.ORDER_STATUS0)) {
                item.setRestTime(DateUtil.intervalSeconds(
                        DateUtil.parse(item.getOverdueAt(), "yyyy-MM-dd HH:mm:ss"),
                        DateUtil.parse(DateUtil.getNowTime(), "yyyy-MM-dd HH:mm:ss")
                ));
                if (item.getRestTime() <= 0L) {
                    item.setRestTime(0L);
                } else {
                    unPayCount += 1;
                }
            } else {
                item.setRestTime(0L);
            }
        }
        return ResponseDto.success(unPayCount);
    }

    @Override
    public KylinOrderTicketPreVo toOrderRefundDetails(String orderId) {
        try {
            KylinOrderTicketPreVo vo = new KylinOrderTicketPreVo();
            String uid = CurrentUtil.getCurrentUid();
            KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
            KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(orderTicketVo.getPerformanceId());
            List<KylinOrderRefundsVoBase> kylinOrderRefundsVoBaseList = dataUtils.getOrderRefundVoByOrderId(orderTicketVo.getOrderTicketsId());
            if (!orderTicketVo.getUserId().equals(uid)) {
                return null;
            }
            List<KylinOrderTicketEntitiesVo> kylinOrderTicketEntitiesVoList = orderTicketVo.getEntitiesVoList();
            List<KylinOrderTicketEntitiesPreRefundVo> kylinOrderTicketEntitiesPreRefundVos = new ArrayList<>();
            // 数据脱敏
            for (KylinOrderTicketEntitiesVo item : kylinOrderTicketEntitiesVoList) {
                KylinOrderTicketEntitiesPreRefundVo refundVo = new KylinOrderTicketEntitiesPreRefundVo();
                if (item.getEnterIdCode().length() == 18) {
                    item.setEnterIdCode(item.getEnterIdCode().substring(0, 3) + "*************" + item.getEnterIdCode().substring(16));
                }
                if (item.getEnterMobile().length() == 11) {
                    item.setEnterMobile(item.getEnterMobile().substring(0, 3) + "****" + item.getEnterMobile().substring(7));
                }
                item.setPriceActual(orderTicketVo.getPriceActual().subtract(orderTicketVo.getPriceExpress()).divide(new BigDecimal(orderTicketVo.getNumber())));
                item.setPriceCanRefund(dataUtils.getCanRefundOrderEntitiesPrice(orderTicketVo, kylinOrderRefundsVoBaseList, item.getOrderTicketEntitiesId()));
                BeanUtils.copyProperties(item,refundVo);
                kylinOrderTicketEntitiesPreRefundVos.add(refundVo);
            }
            orderTicketVo.setFieldName(performanceVo.getFieldName());

            BeanUtils.copyProperties(orderTicketVo,vo);
            vo.setIsTrueName(performanceVo.getIsTrueName());
            vo.setEntitiesPreRefundVos(kylinOrderTicketEntitiesPreRefundVos);
            return vo;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public OrderRefundVo orderRefundDetails(String orderId, String orderRefundId) {
        OrderRefundVo vo = new OrderRefundVo();
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
        if (!orderTicketVo.getUserId().equals(uid)) {
            return null;
        }
        KylinOrderRefundsVoBase kylinOrderRefundsVoBase = dataUtils.getOrderRefundVo(orderRefundId);
        vo.setKylinOrderRefundsVoBaseList(kylinOrderRefundsVoBase);
        vo.setOrderTicketVo(orderTicketVo);
        return vo;
    }

    @Override
    public ResponseDto<Boolean> sendOrderRefund(String orderId, String orderTicketEntitiesId, String reason, String picList) {
        KylinOrderTicketEntitiesVo orderTicketEntitiesVo = null;
        try {
            String uid = CurrentUtil.getCurrentUid();
            KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
            List<KylinOrderRefundsVoBase> kylinOrderRefundsVoBaseList = dataUtils.getOrderRefundVoByOrderId(orderTicketVo.getOrderTicketsId());

            if (!orderTicketVo.getUserId().equals(uid)) {
                return ResponseDto.failure(ErrorMapping.get("20003"));
            }

            List<KylinOrderTicketEntitiesVo> entitiesVos = orderTicketVo.getEntitiesVoList();
            for (KylinOrderTicketEntitiesVo item : entitiesVos) {
                if (item.getOrderTicketEntitiesId().equals(orderTicketEntitiesId)) {
                    orderTicketEntitiesVo = item;
                }
            }
            if (null == orderTicketEntitiesVo) {
                return ResponseDto.failure(ErrorMapping.get("20004"));
            }

            BigDecimal refundSinglePrice = dataUtils.getCanRefundOrderEntitiesPrice(orderTicketVo, kylinOrderRefundsVoBaseList, orderTicketEntitiesId);
            if(refundSinglePrice.doubleValue()<=0){
                return ResponseDto.failure("申请金额不得小于0");
            }
            Map token = CurrentUtil.getTokenClaims();
            String username = StringUtils.defaultString(((String) token.get("nickname")), "");
            boolean result = refundsStatusService.userOrderTicketRefunding(orderTicketVo, refundSinglePrice.doubleValue(), orderTicketEntitiesId, reason, picList, uid, username, kylinOrderRefundsVoBaseList.size());
            if (result) {
                return ResponseDto.success();
            } else {
                return ResponseDto.failure(ErrorMapping.get("20019"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDto.failure(ErrorMapping.get("20019"));
        }
    }

    @Override
    public Boolean orderRefundWithdraw(String orderRefundsId) {

        LinkedList<String> sqls = new LinkedList<>();
        LinkedList<Object[]> sqlsDataA = new LinkedList<>();
        LinkedList<Object[]> sqlsDataB = new LinkedList<>();
        LinkedList<Object[]> sqlsDataC = new LinkedList<>();

        LocalDateTime time = LocalDateTime.now();
        String strTime = DateUtil.Formatter.yyyyMMddHHmmss.format(time);
        try {
            KylinOrderRefundsVoBase orderRefundsVo = dataUtils.getOrderRefundVo(orderRefundsId);
            List<KylinOrderRefundEntitiesVo> refundEntities = orderRefundsVo.getOrderRefundEntitiesVoList();
            String orderTicketsId = orderRefundsVo.getOrderTicketsId();
            KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderTicketsId);

            // 更新数据
            // 订单状态表 判断是退到正在退款 已付款 部分退款？(取消，完成，失败)
            int newStatus;
            int refundingCount = 0;
            List<KylinOrderRefundsVoBase> orderRefundsVoList = dataUtils.getOrderRefundVoByOrderId(orderTicketsId);
            for (KylinOrderRefundsVoBase item : orderRefundsVoList) {
                int status = item.getStatus();
                if (status != 2 && status != 4 && status != 6) {
                    refundingCount += 1;
                }
            }

            if (refundingCount > 0) { // 存在其他正在退款的订单
                newStatus = KylinTableStatusConst.ORDER_STATUS3;
            } else {
                if (orderTicketVo.getPriceRefund().doubleValue() > 0) { // 已经有退完的 那就是部分退款了
                    newStatus = KylinTableStatusConst.ORDER_STATUS6;
                } else if (orderTicketVo.getStatus() != 2) {
                    newStatus = KylinTableStatusConst.ORDER_STATUS1;
                } else {
                    newStatus = KylinTableStatusConst.ORDER_STATUS2;
                }
            }

            KylinOrderTicketStatus orderStatusTable = new KylinOrderTicketStatus();
            orderStatusTable.setStatus(newStatus);
            orderStatusTable.setUpdatedAt(time);
            sqlsDataA.add(new Object[]{
                    orderStatusTable.getStatus(), orderStatusTable.getUpdatedAt(), orderTicketsId, orderTicketVo.getChangeDate(), orderTicketVo.getChangeDate()
            });

            KylinOrderTicketVo kylinOrderTicketVo = new KylinOrderTicketVo();
            kylinOrderTicketVo.setStatus(newStatus);
            kylinOrderTicketVo.setUpdatedAt(strTime);
            kylinOrderTicketVo.setChangeDate(time);
            BasicDBObject orderObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketVo)));
//            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
//                    Query.query(Criteria.where("orderTicketsId").is(orderTicketsId)).getQueryObject(),
//                    orderObject
//            );
            dataUtils.delOrderTicketRedis(orderTicketsId);
            mongoVoUtils.resetOrderListVo(orderTicketVo.getUserId(), 2, orderTicketsId, null);

            // 入场人
            for (KylinOrderRefundEntitiesVo item : refundEntities) {
                // 订单状态表 判断是退到正在退款 已付款 部分退款？(取消，完成，失败)
                int newIsPayment = 0;
                int refundingEntitiesCount = 0;
                for (KylinOrderRefundsVoBase item2 : orderRefundsVoList) {
                    int status = item2.getStatus();
                    if (!item2.getOrderRefundsId().equals(orderRefundsId) && (status != 2 && status != 4 && status != 6)) {
                        for (KylinOrderRefundEntitiesVo item3 : item2.getOrderRefundEntitiesVoList()) {
                            if (item3.getOrderTicketEntitiesId().equals(item.getOrderTicketEntitiesId())) {
                                refundingEntitiesCount += 1;
                            }
                        }
                    }
                }
                KylinOrderTicketEntitiesVo entitiesVo = null;
                for (KylinOrderTicketEntitiesVo entitiesVo1 : orderTicketVo.getEntitiesVoList()) {
                    if (entitiesVo1.getOrderTicketEntitiesId().equals(item.getOrderTicketEntitiesId())) {
                        entitiesVo = entitiesVo1;
                        break;
                    }
                }
                if (refundingEntitiesCount > 0) { // 存在其他正在退款的该入场人订单
                    newIsPayment = KylinTableStatusConst.ENTITIES_IS_PAYMENT2;
                } else {
                    if (entitiesVo.getRefundPrice().doubleValue() > 0) { // 已经有退完的 那就是部分退款了
                        newIsPayment = KylinTableStatusConst.ENTITIES_IS_PAYMENT4;
                    } else {
                        newIsPayment = KylinTableStatusConst.ENTITIES_IS_PAYMENT1;
                    }
                }
                KylinOrderTicketEntities entitiesTable = new KylinOrderTicketEntities();
                entitiesTable.setIsPayment(newIsPayment);
                entitiesTable.setUpdatedAt(time);

                sqlsDataB.add(new Object[]{
                        entitiesTable.getIsPayment(), entitiesTable.getUpdatedAt(), item.getOrderTicketEntitiesId(), entitiesVo.getChangeDate(), entitiesVo.getChangeDate()
                });

                KylinOrderTicketEntitiesVo kylinOrderTicketEntitiesVo = new KylinOrderTicketEntitiesVo();
                kylinOrderTicketEntitiesVo.setIsPayment(newIsPayment);
                kylinOrderTicketEntitiesVo.setUpdatedAt(strTime);
                kylinOrderTicketEntitiesVo.setChangeDate(time);
                BasicDBObject entitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketEntitiesVo)));
//                mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).updateOne(
//                        Query.query(Criteria.where("orderTicketEntitiesId").is(item.getOrderTicketEntitiesId())).getQueryObject(),
//                        entitiesObject
//                );

                dataUtils.delOrderTicketEntitiesRedis(item.getOrderTicketEntitiesId());
            }

            // 退款细节取消
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL);
            kylinOrderRefunds.setUpdatedAt(LocalDateTime.now());

            KylinOrderRefundsVoBase orderRefundsVoBase = new KylinOrderRefundsVoBase();
            orderRefundsVoBase.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL);
            orderRefundsVoBase.setUpdatedAt(strTime);
            BasicDBObject refundObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(orderRefundsVoBase)));
//            mongoTemplate.getCollection(KylinOrderRefundsVoBase.class.getSimpleName()).updateOne(
//                    Query.query(Criteria.where("orderRefundsId").is(orderRefundsId)).getQueryObject(),
//                    refundObject
//            );

            sqlsDataC.add(new Object[]{
                    orderRefundsVoBase.getStatus(), orderRefundsVoBase.getUpdatedAt(), orderRefundsId
            });

            sqls.add(SqlMapping.get("kylin_order_ticket_status.withDraw"));
            sqls.add(SqlMapping.get("kylin_order_ticket_entities.withDraw"));
            sqls.add(SqlMapping.get("kylin_order_refund.withDraw"));

            rabbitTemplate.convertAndSend(MQConst.EXCHANGES_LIQUIDNET_SQL_ORDER_WITHDRAW, MQConst.ROUTING_KEY_SQL_ORDER_WITHDRAW,
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public Boolean orderRefundAgain(String orderRefundsId) {
        LocalDateTime time = LocalDateTime.now();
        String strTime = DateUtil.Formatter.yyyyMMddHHmmss.format(time);
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderRefundsVoBase orderRefundVo = dataUtils.getOrderRefundVo(orderRefundsId);

        // 订单状态表 MQ
        KylinOrderTicketStatus orderStatusTable = new KylinOrderTicketStatus();
        orderStatusTable.setStatus(KylinTableStatusConst.ORDER_STATUS3);
        orderStatusTable.setUpdatedAt(time);
        // 订单入场人表 MQ
        KylinOrderTicketEntities entitiesTable = new KylinOrderTicketEntities();
        entitiesTable.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
        entitiesTable.setUpdatedAt(time);
        // 订单退款表
        KylinOrderRefunds orderRefunds = new KylinOrderRefunds();
        orderRefunds.setUpdatedAt(time);
        orderRefunds.setApplicantAt(time);
        orderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY);

        //订单状态表 MONGO
        KylinOrderTicketVo kylinOrderTicketVo = new KylinOrderTicketVo();
        kylinOrderTicketVo.setStatus(KylinTableStatusConst.ORDER_STATUS3);
        kylinOrderTicketVo.setUpdatedAt(DateUtil.Formatter.yyyyMMddHHmmss.format(time));
        BasicDBObject orderObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketVo)));
        mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderTicketsId").is(orderRefundVo.getOrderTicketsId())).getQueryObject(),
                orderObject
        );
        dataUtils.delOrderTicketRedis(orderRefundVo.getOrderTicketsId());
        mongoVoUtils.resetOrderListVo(uid, 2, orderRefundVo.getOrderTicketsId(), null);
        // 订单入场人表 MONGO
        KylinOrderTicketEntitiesVo kylinOrderTicketEntitiesVo = new KylinOrderTicketEntitiesVo();
        kylinOrderTicketEntitiesVo.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
        kylinOrderTicketEntitiesVo.setUpdatedAt(strTime);
        BasicDBObject entitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketEntitiesVo)));
        mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderTicketEntitiesId").is(orderRefundVo.getOrderRefundEntitiesVoList().get(0).getOrderTicketEntitiesId())).getQueryObject(),
                entitiesObject
        );
        dataUtils.delOrderTicketEntitiesRedis(orderRefundVo.getOrderRefundEntitiesVoList().get(0).getOrderTicketEntitiesId());
        // 订单退款表 MONGO
        KylinOrderRefundsVoBase orderRefundsVo = new KylinOrderRefundsVoBase();
        orderRefundsVo.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY);
        orderRefundsVo.setUpdatedAt(strTime);
        orderRefundsVo.setApplicantAt(strTime);
        BasicDBObject refundObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(orderRefundsVo)));
        mongoTemplate.getCollection(KylinOrderRefundsVoBase.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderRefundsId").is(orderRefundVo.getOrderRefundsId())).getQueryObject(),
                refundObject
        );

        return null;
    }

    public boolean checkAgent(String agentId, KylinTicketVo ticketData) {
        boolean isAgent = ticketData.getIsAgent() == 1;
        if (isAgent) {
            return redisUtil.sHasKey(KylinRedisConst.AGENT, agentId);
        } else {
            return true;
        }
    }

    private boolean sycDamaiOrder(String orderId) {
        try {
            KylinOrderTicketVo orderData = dataUtils.getOrderTicketVo(orderId);
            KylinPerformanceVo vo = dataUtils.getPerformanceVo(orderData.getPerformanceId());
            TaobaoClient client = taobaoTicketUtils.initTaobaoClient();
            int isSysDamai = 0;
            for (int x = 0; x < vo.getTicketTimeList().size(); x++) {
                KylinTicketTimesVo timeItem = vo.getTicketTimeList().get(x);
                for (int y = 0; y < timeItem.getTicketList().size(); y++) {
                    KylinTicketVo ticketItem = timeItem.getTicketList().get(y);
                    if (ticketItem.getTicketsId().equals(orderData.getTicketId())) {
                        isSysDamai = ticketItem.getSysDamai();
                        break;
                    }
                }
            }
            if (isSysDamai == 1) {
                KylinOrderTicketVo orderVo = dataUtils.getOrderTicketVo(orderId);
                List<KylinOrderTicketEntitiesVo> listData = orderVo.getEntitiesVoList();
                AlibabaDamaiMevOpenBatchpushticketRequest req = new AlibabaDamaiMevOpenBatchpushticketRequest();
                List<AlibabaDamaiMevOpenBatchpushticketRequest.ThirdTicketPushOpenParam> list2 = new ArrayList<AlibabaDamaiMevOpenBatchpushticketRequest.ThirdTicketPushOpenParam>();
                for (int i = 0; i < listData.size(); i++) {
                    KylinOrderTicketEntitiesVo item = listData.get(i);
                    AlibabaDamaiMevOpenBatchpushticketRequest.ThirdTicketPushOpenParam obj3 = new AlibabaDamaiMevOpenBatchpushticketRequest.ThirdTicketPushOpenParam();
                    list2.add(obj3);
                    obj3.setUserName(item.getEnterName());//用户名 入场人姓名
                    obj3.setCertificateNo(item.getEnterIdCode());//证件号 入场人身份证
                    obj3.setOrderUserMobile(item.getEnterMobile());//用户手机号 入场人手机号
                    obj3.setCertificateType(item.getEnterType().longValue());//证件内容 入场人证件type
                    obj3.setPayTime(DateUtils.parseDate(orderData.getTimePay(), new String[]{"yyyy-MM-dd HH:mm:ss"}));//支付时间
                    obj3.setPerformId(item.getTimemId().longValue());//场次id
                    obj3.setTicketItemId(item.getTicketsmId().longValue());
                    obj3.setVoucherId(item.getMid().longValue());//票单号 入场人id

                    obj3.setOrderId(Long.parseLong(orderData.getOrderTicketsId()));//订单id orderId
                    obj3.setMediumType(orderData.getGetTicketType().equals("express") ? 1L : 2L);//票类型 快递 电子
                    obj3.setSupplierSecret(taobaoTicketUtils.getSupplierSecret());
                    obj3.setSystemId(taobaoTicketUtils.getSystemId());
                    obj3.setSeatType(1L);
                    obj3.setTicketType(1L);//票类型
                }
                req.setThirdTicketSetOpenParamList(list2);
                if (list2.size() == 0) {
                    return true;
                } else {
                    AlibabaDamaiMevOpenBatchpushticketResponse rsp = client.execute(req);
                    return rsp.getResult().getSuccess();
                }
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
