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

import com.github.pagehelper.PageInfo;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.dto.vo.AdamEntersVo;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.UserPathDto;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
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.mongo.KylinOrderTicketEntitiesVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.returns.*;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.service.IKylinOrderTicketsService;
import com.liquidnet.service.kylin.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

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


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

    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private QueueUtils queueUtils;

    @Override
    public PageInfo<List<KylinOrderListVo>> orderList() {
        //TODO 缺快递
        PageInfo<List<KylinOrderListVo>> mPageInfo = null;
        String uid = CurrentUtil.getCurrentUid();
        try {
            List<KylinOrderListVo> voList = dataUtils.getOrderList(uid);
            for (int i = 0; i < voList.size(); i++) {
                KylinOrderListVo item = voList.get(i);
                item.setStatus(item.getStatus());
                Integer orderExpressStatus = dataUtils.getOrderExpressInfo(item.getOrderTicketsId());
                item.setExpressStatus(orderExpressStatus);

                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();
                    }
                } else {
                    item.setRestTime(0L);
                }
                if (i >= 40) {
                    break;
                }
            }

            KylinOrderTicketVo orderTicketVo = dataUtils.getTransferOrder(uid);
            if (orderTicketVo != null) {
                voList.add(0, KylinOrderListVo.getNew().copy(orderTicketVo));
            }

            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) {
        try {
            OrderDetailsVo vo = OrderDetailsVo.getNew();
            String uid = CurrentUtil.getCurrentUid();
            KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
            if (orderTicketVo == null) {
                orderTicketVo = dataUtils.getTransferOrder(uid);
            }
            if (uid.equals("809406") || uid.equals("773650")) {
            } else {
                if (!orderTicketVo.getUserId().equals(uid)) {
                    return null;
                }
            }
            if (null != orderTicketVo) {
                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());

                List<KylinOrderRefundsVo> orderRefundsVoList = dataUtils.getOrderRefundVoByOrderId(orderId);

                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());
                        vo.setIsShowQrCode(ticketVo.getIsShowCode());
                        vo.setShowQrCodeTime(ticketVo.getQrCodeShowTime() == null ? "" : ticketVo.getQrCodeShowTime());
                    } else {
                        orderTicketVo.setQrCode("");
                        vo.setIsShowQrCode(ticketVo.getIsShowCode());
                        vo.setShowQrCodeTime(ticketVo.getQrCodeShowTime() == null ? "" : ticketVo.getQrCodeShowTime());
                    }
                } else {
                    orderTicketVo.setQrCode("");
                    vo.setIsShowQrCode(0);
                    vo.setShowQrCodeTime("");
                }
                // 数据脱敏
                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 (orderTicketVo.getTransferTime() != null && (orderTicketVo.getTransferStatus().equals(1) || orderTicketVo.getTransferStatus().equals(4))) {
                    vo.setRestTransferTime(DateUtil.intervalSeconds(
                            DateUtil.parse(DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.parse(orderTicketVo.getTransferTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).plusMinutes(120)),
                                    "yyyy-MM-dd HH:mm:ss"),
                            nowDate
                    ));
                    if (vo.getRestTransferTime() <= 0L) {
                        vo.setRestTransferTime(0L);
                    }
                } else {
                    vo.setRestTransferTime(0L);
                }

                Integer orderExpressStatus = dataUtils.getOrderExpressInfo(orderTicketVo.getOrderTicketsId());
                vo.setExpressStatus(orderExpressStatus);

                List<OrderRefundListVo> orderRefundListVos = new ArrayList<>();
                BigDecimal lockPrice = BigDecimal.valueOf(0.00);
                for (KylinOrderRefundsVo item : orderRefundsVoList) {
                    if (item.getType().equals(1)) {
                        break;
                    }
                    OrderRefundListVo data = OrderRefundListVo.getNew();
                    if (item.getOrderRefundCode().length() > 20) {
                        data.setOrderRefundCode(item.getOrderRefundCode().substring(item.getOrderRefundCode().length() - 10));
                    }
                    data.setOrderRefundsId(item.getOrderRefundsId());
                    data.setStatus(item.getStatus());
                    data.setPrice(item.getPrice());
                    data.setIsMine(uid.equals(item.getApplicantId()) ? 1 : 0);
                    if (item.getStatus().equals(0) || item.getStatus().equals(1) || item.getStatus().equals(7) || item.getStatus().equals(3) || item.getStatus().equals(4)) {
                        lockPrice = lockPrice.add(item.getPrice());
                    }
                    orderRefundListVos.add(data);
                }

                //是否可退
                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)
                            && ticketVo.getCounts() == 1 && lockPrice.compareTo(orderTicketVo.getPriceActual()) != 0
                            && (orderTicketVo.getStatus().equals(1) || orderTicketVo.getStatus().equals(3) || orderTicketVo.getStatus().equals(6))
                            && (orderTicketVo.getTransferStatus().equals(0) || orderTicketVo.getTransferStatus().equals(5))) {
                        vo.setIsCanRefund(1);
                    } else {
                        vo.setIsCanRefund(0);
                    }
                } else {
                    vo.setIsCanRefund(0);
                }
                //是否可转
                if (null != performanceVo.getIsTransfer() && performanceVo.getIsTransfer() == 1) {
                    LocalDateTime transferStartTime = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getTransferStartTime());
                    LocalDateTime transferEndTime = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getTransferEndTime());
                    if (LocalDateTime.now().isAfter(transferStartTime) && LocalDateTime.now().isBefore(transferEndTime)
                            && orderTicketVo.getExpressAddress().trim().equals("")
                            && orderTicketVo.getStatus().equals(1) && orderTicketVo.getTransferStatus().equals(0)) {
                        vo.setIsCanTransfer(1);
                    } else {
                        vo.setIsCanTransfer(0);
                    }
                } else {
                    vo.setIsCanTransfer(0);
                }
                //是否可回退
                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)
                            && orderTicketVo.getTransferStatus().equals(3)) {
                        vo.setIsCanBack(1);
                    } else {
                        vo.setIsCanBack(0);
                    }
                } else {
                    vo.setIsCanBack(0);
                }
                // 快递票不可退
                if (orderTicketVo.getGetTicketType().equals("express")) {
                    vo.setIsCanBack(0);
                }

                orderTicketVo.setOrderRefundListVos(orderRefundListVos);
                if (orderTicketVo.getOrderCode().length() > 20) {
                    orderTicketVo.setOrderCode(orderTicketVo.getOrderCode().substring(orderTicketVo.getOrderCode().length() - 10));
                }
                vo.setOrderTicketVo(orderTicketVo);
                vo.setEnterDescribe(dataUtils.getEnterInfo(performanceVo.getType(), orderTicketVo.getGetTicketType(), orderTicketVo.getIsStudent(), ticketVo.getIsTrueName()));
                // 添加 优惠券相关
                vo.setOrderCouponsList(dataUtils.getOrderCoupon(orderId));
            }
            log.info(UserPathDto.setData("订单详情", orderId, vo));
            return vo;
        } catch (Exception e) {
            log.info("订单详情异常:", e);
            return null;
        }
    }

    @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 ResponseDto<String> orderTransfer(String orderId, String transferUid, String transferMobile) {
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
        LocalDateTime now = LocalDateTime.now();
        if (null != orderTicketVo) {
            if (!orderTicketVo.getUserId().equals(uid)) {
                return ResponseDto.success("无权查看");
            }
            if (!orderTicketVo.getTransferStatus().equals(0)) {
                return ResponseDto.failure("已转票一次，无法再次转票");
            }
            Boolean isCanTransfer;
            KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(orderTicketVo.getPerformanceId());

            //判断是否可转增
            if (null != performanceVo.getIsTransfer() && performanceVo.getIsTransfer() == 1) {
                LocalDateTime transferStartTime = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getTransferStartTime());
                LocalDateTime transferEndTime = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getTransferEndTime());
                if (LocalDateTime.now().isAfter(transferStartTime) && LocalDateTime.now().isBefore(transferEndTime)
                        && orderTicketVo.getStatus().equals(1) && orderTicketVo.getTransferStatus().equals(0)) {
                    isCanTransfer = true;
                } else {
                    isCanTransfer = false;
                }
            } else {
                isCanTransfer = false;
            }
            if (!isCanTransfer) {
                return ResponseDto.failure("该订单不支持转赠");
            }

            //判断对方是否有转赠订单
            if (dataUtils.hasTransferOrder(transferUid)) {
                return ResponseDto.failure("该用户有待接收的转赠订单，暂不能转赠");
            }

            LinkedList<String> sqls = CollectionUtil.linkedListString();
            //持久化数据
            sqls.add(SqlMapping.get("kylin_order_task.insert"));
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            sqlsDataA.add(new Object[]{
                    orderTicketVo.getOrderTicketsId(), 10, now
            });

            String transferTime = DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.now());
            //修改被转赠订单 redis
            orderTicketVo.setTransferStatus(1);
            orderTicketVo.setTransferTime(transferTime);
            orderTicketVo.setTransferUid(transferUid);

            dataUtils.setOrderTicketVo(orderTicketVo.getOrderTicketsId(), orderTicketVo);
            orderUtils.resetOrderListVo(uid, 2, orderTicketVo.getOrderTicketsId(), orderTicketVo);
            //修改被转赠订单 mongo
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderTicketVo.getOrderTicketsId())).getQueryObject(),
                    new Document("$set", new Document("transferStatus", orderTicketVo.getTransferStatus())
                            .append("transferUid", transferUid).append("transferTime", transferTime).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
            );
            //修改被转赠订单 mysql
            sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            sqlsDataB.add(new Object[]{
                    1, now, orderTicketVo.getOrderTicketsId(), now, now
            });
            sqls.add(SqlMapping.get("kylin_order_ticket_relation.transfer.update"));
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            sqlsDataC.add(new Object[]{
                    transferUid, orderTicketVo.getOrderTicketsId(), now, orderTicketVo.getOrderTicketsId(), now, now
            });

            //生成被转赠订单独立redis
            orderTicketVo.setOrderTicketsId(IDGenerator.nextSnowId());
            orderTicketVo.setQrCode(IDGenerator.ticketQrCode(orderTicketVo.getOrderTicketsId()));
            orderTicketVo.setTransferId(orderId);
            orderTicketVo.setTransferStatus(4);
            orderTicketVo.setUserId(transferUid);
            orderTicketVo.setUserMobile(transferMobile);
            dataUtils.setTransferOrder(transferUid, orderTicketVo);

            //入库
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_TRANSFER.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC));

        } else {
            return ResponseDto.failure("转票失败");
        }
        return ResponseDto.success("转票成功");
    }

    @Override
    public ResponseDto<String> orderTransferWithdraw(String orderId) {
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderTicketVo orderTicketVo = dataUtils.getOrderTicketVo(orderId);
        LocalDateTime now = LocalDateTime.now();
        if (null != orderTicketVo) {
            if (!orderTicketVo.getUserId().equals(uid)) {
                return ResponseDto.success("无权查看");
            }
            if (!orderTicketVo.getTransferStatus().equals(1)) {
                return ResponseDto.failure("无法撤回");
            }
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            //删除持久化数据
            sqls.add(SqlMapping.get("kylin_order_task.delete"));
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            sqlsDataA.add(new Object[]{
                    orderTicketVo.getOrderTicketsId()
            });
            //修改被转赠订单 redis
            orderTicketVo.setTransferStatus(0);
            dataUtils.setOrderTicketVo(orderTicketVo.getOrderTicketsId(), orderTicketVo);
            orderUtils.resetOrderListVo(uid, 2, orderTicketVo.getOrderTicketsId(), orderTicketVo);
            //修改被转赠订单 mongo
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderTicketVo.getOrderTicketsId())).getQueryObject(),
                    new Document("$set", new Document("transferStatus", orderTicketVo.getTransferStatus()).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
            );
            //修改被转赠订单 mysql
            sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            sqlsDataB.add(new Object[]{
                    0, now, orderTicketVo.getOrderTicketsId(), now, now
            });
            sqls.add(SqlMapping.get("kylin_order_ticket_relation.transfer.update"));
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            sqlsDataC.add(new Object[]{
                    "", "", now, orderTicketVo.getOrderTicketsId(), now, now
            });
            //删除被转赠订单独立redis
            dataUtils.delTransferOrder(orderTicketVo.getTransferUid());
            //入库
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_TRANSFER.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC));
        } else {
            return ResponseDto.failure("撤回失败");
        }
        return ResponseDto.success("撤回成功");
    }

    @Override
    public ResponseDto<String> orderTransferAccept(String enterIdList) {
        String uid = CurrentUtil.getCurrentUid();
        Integer enterSize;
        if (enterIdList == null || enterIdList.equals("")) {
            enterSize = 0;
            enterIdList = "";
        } else {
            enterSize = enterIdList.split(",").length;
        }
        KylinOrderTicketVo orderTicketVo = dataUtils.getTransferOrder(uid);
        if (orderTicketVo == null) {
            return ResponseDto.failure("无订单");
        }
        if (!orderTicketVo.getTransferStatus().equals(4)) {
            return ResponseDto.failure("无法接收");
        }
        LocalDateTime now = LocalDateTime.now();
        if (orderTicketVo != null) {
            KylinPerformanceVo performanceData = dataUtils.getPerformanceVo(orderTicketVo.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(orderTicketVo.getTimeId())) {
                    ticketTimesData = timeItem;
                    for (int y = 0; y < ticketTimesData.getTicketList().size(); y++) {
                        KylinTicketVo ticketItem = ticketTimesData.getTicketList().get(y);
                        if (ticketItem.getTicketsId().equals(orderTicketVo.getTicketId())) {
                            ticketData = ticketItem;
                            break;
                        }
                    }
                    break;
                }
            }

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

            //实名判断
            if (isTrueName == 1 && enterSize <= 0) {
                return ResponseDto.failure(ErrorMapping.get("20015"));//需要实名 未实名
            }
            if (isTrueName == 1 && enterSize != orderTicketVo.getNumber()) {
                return ResponseDto.failure(ErrorMapping.get("20015"));//入场人数量错误
            }

            //学生票 判断
            List<AdamEntersVo> entersVoList = ObjectUtil.cloneArrayListObject();
            if (isTrueName == 1) {
                List<AdamEntersVo> adamEnters = orderUtils.getEnters(enterIdList, uid);
                if (adamEnters == null) {
                    return ResponseDto.failure("入场人数据异常");//乱七八糟异常
                }
                for (AdamEntersVo item : adamEnters) {
                    entersVoList.add(item);
                    if (ticketData.getIsStudent() == 1) {
                        if (!item.getType().equals(1)) {
                            return ResponseDto.failure("学生票优惠核验失败，无法转票");
                        }
                        int age = IDCard.getAgeByIdCard(item.getIdCard());
                        if (age > 25) {
                            return ResponseDto.failure(ErrorMapping.get("20017"));//学生票年龄问题
                        }
                    }
                }
            }

            //限购判断 如果实名 则身份证维度限购 如果不实名则数量限购
            if (entersVoList.size() > 0) {
                for (int i = 0; i < entersVoList.size(); i++) {
                    String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, entersVoList.get(i).getIdCard(), performanceData.getPerformancesId(), ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, 1, 1, 0, isTrueName);
                    if (!res1.equals("")) {
                        return ResponseDto.failure(res1);//乱七八糟异常
                    }
                }
            } else {
                String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, "", performanceData.getPerformancesId(), ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, orderTicketVo.getNumber(), orderTicketVo.getNumber(), 0, isTrueName);
                if (!res1.equals("")) {
                    return ResponseDto.failure(res1);//乱七八糟异常
                }
            }

            LinkedList<String> sqls = CollectionUtil.linkedListString();
            //删除持久化数据
            sqls.add(SqlMapping.get("kylin_order_task.delete"));
            LinkedList<Object[]> sqlsDataE = CollectionUtil.linkedListObjectArr();
            sqlsDataE.add(new Object[]{
                    orderTicketVo.getTransferId()
            });

            String source = orderTicketVo.getOrderType();
            String version = orderTicketVo.getOrderVersion();

            //生成订单 order_ticket
            KylinOrderTickets orderTickets = KylinOrderTickets.getNew();
            String orderTicketId = orderTicketVo.getOrderTicketsId();
            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(orderTicketVo.getPerformanceTitle());
            orderTickets.setOrderCode(IDGenerator.ticketOrderCode(orderTicketId));
            orderTickets.setPayCode(orderTicketVo.getPayCode());
            orderTickets.setQrCode(orderTicketVo.getQrCode());
            orderTickets.setOrderType(source);
            orderTickets.setOrderVersion(version);
            orderTickets.setNumber(orderTicketVo.getNumber());
            orderTickets.setPrice(orderTicketVo.getPrice());
            orderTickets.setPriceMember(orderTicketVo.getPriceMember());
            orderTickets.setPriceTotal(orderTicketVo.getPriceTotal());
            orderTickets.setPriceActual(orderTickets.getPriceActual() == null ? BigDecimal.ZERO : orderTickets.getPriceActual());
            orderTickets.setPriceVoucher(orderTicketVo.getPriceVoucher());
            orderTickets.setPriceExpress(orderTicketVo.getPriceExpress());
            orderTickets.setPriceRefund(orderTicketVo.getPriceRefund());
            orderTickets.setRefundNumber(orderTicketVo.getRefundNumber());
            orderTickets.setPayType(orderTicketVo.getPayType());
            orderTickets.setPaymentType(orderTicketVo.getPaymentType());
            orderTickets.setTimePay(orderTicketVo.getTimePay());
            orderTickets.setPaymentId("TRANSFER");

            orderTickets.setExpressContacts(orderTicketVo.getExpressContacts());
            orderTickets.setExpressAddress(orderTicketVo.getExpressAddress());
            orderTickets.setExpressPhone(orderTicketVo.getExpressPhone());
            orderTickets.setCity("");//            orderTickets.setCity(addressesVo.getCity());
            orderTickets.setProvince("");//            orderTickets.setProvince(addressesVo.getProvince());
            orderTickets.setCounty("");//            orderTickets.setCounty(addressesVo.getCounty());
            orderTickets.setGetTicketType(orderTicketVo.getGetTicketType());
            orderTickets.setCouponType(orderTicketVo.getCouponType());
            orderTickets.setGetTicketDescribe(orderTicketVo.getGetTicketDescribe());
            orderTickets.setPayCountdownMinute(orderTicketVo.getPayCountdownMinute());
            orderTickets.setCreatedAt(now);
            orderTickets.setUpdatedAt(null);

            //生成订单 order_ticket_status
            KylinOrderTicketStatus orderTicketStatus = KylinOrderTicketStatus.getNew();
            String orderTicketStatusId = IDGenerator.nextSnowId();
            orderTicketStatus.setOrderTicketStatusId(orderTicketStatusId);
            orderTicketStatus.setOrderId(orderTicketId);
            orderTicketStatus.setExpressType(orderTicketVo.getExpressType());
            orderTicketStatus.setTransferStatus(3);
            orderTicketStatus.setStatus(orderTicketVo.getStatus());
            orderTicketStatus.setIsStudent(orderTicketVo.getIsStudent());
            orderTicketStatus.setPayStatus(orderTicketVo.getPayStatus());
            orderTicketStatus.setCreatedAt(now);
            orderTicketStatus.setUpdatedAt(null);
            sqls.add(SqlMapping.get("kylin_order_ticket_status.add"));
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            sqlsDataB.add(orderTicketStatus.getAddObject());

            //生成订单 order_ticket_relation
            KylinOrderTicketRelations orderTicketRelations = KylinOrderTicketRelations.getNew();
            String orderTicketRelationId = IDGenerator.nextSnowId();
            orderTicketRelations.setOrderTicketRelationsId(orderTicketRelationId);
            orderTicketRelations.setOrderId(orderTicketId);
            orderTicketRelations.setTransferId(orderTicketVo.getTransferId());
            orderTicketRelations.setLiveId(orderTicketVo.getLiveId());
            orderTicketRelations.setAgentId(orderTicketVo.getAgentId());
            orderTicketRelations.setIsMember(orderTicketVo.getIsMember());
            orderTicketRelations.setPerformanceId(performanceData.getPerformancesId());
            orderTicketRelations.setTimeId(ticketTimesData.getTimeId());
            orderTicketRelations.setTicketId(ticketData.getTicketsId());
            orderTicketRelations.setCreatedAt(now);
            orderTicketRelations.setUpdatedAt(null);
            sqls.add(SqlMapping.get("kylin_order_ticket_relation.add"));
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            sqlsDataC.add(orderTicketRelations.getAddObject());

            //生成票
            KylinOrderTicketEntities orderTicketEntities = KylinOrderTicketEntities.getNew();
            LinkedList<Object[]> sqlsDataD = CollectionUtil.linkedListObjectArr();
            sqls.add(SqlMapping.get("kylin_order_ticket_entities.add"));
            for (int i = 0; i < orderTicketVo.getEntitiesVoList().size(); i++) {
                KylinOrderTicketEntitiesVo entitiesVo = orderTicketVo.getEntitiesVoList().get(i);
                String orderTicketEntitiesId = entitiesVo.getOrderTicketEntitiesId();
                orderTicketEntities.setOrderTicketEntitiesId(IDGenerator.nextSnowId());
                orderTicketEntities.setOrderId(orderTicketId);
                orderTicketEntities.setTicketId(ticketData.getTicketsId());
                orderTicketEntities.setUserId(uid);
                orderTicketEntities.setPerformanceId(performanceData.getPerformancesId());
                orderTicketEntities.setTimeId(ticketTimesData.getTicketTimesId());
                orderTicketEntities.setEnterType(entitiesVo.getEnterType());

                if (entersVoList.size() > 0) {
                    orderTicketEntities.setEnterName(entersVoList.get(i).getName());
                    orderTicketEntities.setEnterMobile(entersVoList.get(i).getMobile());
                    orderTicketEntities.setEnterIdCode(entersVoList.get(i).getIdCard());
                } else {
                    orderTicketEntities.setEnterName(entitiesVo.getEnterName());
                    orderTicketEntities.setEnterMobile(entitiesVo.getEnterMobile());
                    orderTicketEntities.setEnterIdCode(entitiesVo.getEnterIdCode());
                }

                orderTicketEntities.setStatus(entitiesVo.getStatus());
                orderTicketEntities.setSysDamai(entitiesVo.getSysDamai());
                orderTicketEntities.setCheckClient(entitiesVo.getCheckClient());
                orderTicketEntities.setIsPayment(entitiesVo.getIsPayment());
                orderTicketEntities.setRefundPrice(entitiesVo.getRefundPrice());
                orderTicketEntities.setComment("");
                orderTicketEntities.setCreatedAt(now);
                orderTicketEntities.setUpdatedAt(null);
                sqlsDataD.add(orderTicketEntities.getAddObject());
                // 生成vo
                KylinOrderTicketEntitiesVo orderTicketEntitiesVo = KylinOrderTicketEntitiesVo.getNew();
                BeanUtils.copyProperties(orderTicketEntities, orderTicketEntitiesVo);
                orderTicketEntitiesVo.setPerformanceTitle(performanceData.getTitle());
                orderTicketEntitiesVo.setTicketTitle(ticketData.getTitle());
                orderTicketEntitiesVo.setUseStart(ticketData.getUseStart());
                orderTicketEntitiesVo.setUseEnd(ticketData.getUseEnd());
                orderTicketEntitiesVo.setCreatedAt(orderTicketEntities.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orderTicketEntitiesVo.setUpdatedAt(null);
                orderTicketEntitiesVo.setChangeDate(orderTicketEntities.getCreatedAt());
                mongoTemplate.insert(orderTicketEntitiesVo, KylinOrderTicketEntitiesVo.class.getSimpleName());
                dataUtils.changeBuyInfo(orderTicketEntitiesVo.getUserId(), orderTicketEntitiesVo.getEnterIdCode(), orderTicketEntitiesVo.getPerformanceId(), orderTicketEntitiesVo.getTicketId(), 1);
            }

            orderTickets.setPayType(orderTicketVo.getPayType());
            orderTickets.setPayCode(orderTicketVo.getPayCode());

            sqls.add(SqlMapping.get("kylin_order_ticket.add"));
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            sqlsDataA.add(orderTickets.getAddObject());
            //删除被转赠订单独立redis
            dataUtils.delTransferOrder(uid);
            // 生成vo
            orderTicketVo.setTransferStatus(3);
            orderTicketVo.setOrderCode(orderTickets.getOrderCode());
            orderTicketVo.setCreatedAt(orderTickets.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderTicketVo.setChangeDate(orderTickets.getCreatedAt());
            orderUtils.resetOrderListVo(uid, 1, orderTicketVo.getOrderTicketsId(), orderTicketVo);
            mongoTemplate.insert(orderTicketVo, KylinOrderTicketVo.class.getSimpleName());

            //原来vo
            KylinOrderTicketVo orderTicketVoTransfer = dataUtils.getOrderTicketVo(orderTicketVo.getTransferId());
            orderTicketVoTransfer.setTransferStatus(2);
            orderTicketVoTransfer.setChangeDate(now);
            orderTicketVoTransfer.setUpdatedAt(DateUtil.Formatter.yyyyMMddHHmmss.format(now));
            dataUtils.setOrderTicketVo(orderTicketVoTransfer.getOrderTicketsId(), orderTicketVoTransfer);
            orderUtils.resetOrderListVo(orderTicketVoTransfer.getUserId(), 2, orderTicketVoTransfer.getOrderTicketsId(), orderTicketVoTransfer);
            //原订单mongo
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderTicketVoTransfer.getOrderTicketsId())).getQueryObject(),
                    new Document("$set", new Document("transferStatus", orderTicketVoTransfer.getTransferStatus()).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
            );
            //sql
            sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
            LinkedList<Object[]> sqlsDataA2 = CollectionUtil.linkedListObjectArr();
            sqlsDataA2.add(new Object[]{
                    orderTicketVoTransfer.getTransferStatus(), now, orderTicketVoTransfer.getOrderTicketsId(), now, now
            });

            // 执行sql
            String sqlData = SqlMapping.gets(sqls, sqlsDataE, sqlsDataB, sqlsDataC, sqlsDataD, sqlsDataA, sqlsDataA2);
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_TRANSFER_RESULT.getKey(),
                    sqlData);
            log.info(UserPathDto.setData("接收转赠订单", enterIdList, "SUCCESS"));
        } else {
            return ResponseDto.failure("接收失败");
        }
        return ResponseDto.success("接收成功");
    }

    @Override
    public ResponseDto<String> orderTransferReject() {
        String uid = CurrentUtil.getCurrentUid();
        KylinOrderTicketVo orderTicketVo = dataUtils.getTransferOrder(uid);
        LocalDateTime now = LocalDateTime.now();
        if (null != orderTicketVo) {
            if (!orderTicketVo.getUserId().equals(uid)) {
                return ResponseDto.success("无权查看");
            }
            if (!orderTicketVo.getTransferStatus().equals(4)) {
                return ResponseDto.failure("无法拒收");
            }
            KylinOrderTicketVo orderTicketVoTransfer = dataUtils.getOrderTicketVo(orderTicketVo.getTransferId());

            LinkedList<String> sqls = CollectionUtil.linkedListString();
            //删除持久化数据
            sqls.add(SqlMapping.get("kylin_order_task.delete"));
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            sqlsDataA.add(new Object[]{
                    orderTicketVo.getTransferId()
            });
            //修改被转赠订单 redis
            orderTicketVoTransfer.setTransferStatus(0);
            dataUtils.setOrderTicketVo(orderTicketVoTransfer.getOrderTicketsId(), orderTicketVoTransfer);
            orderUtils.resetOrderListVo(orderTicketVoTransfer.getUserId(), 2, orderTicketVoTransfer.getOrderTicketsId(), orderTicketVoTransfer);
            //修改被转赠订单 mongo
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderTicketVoTransfer.getOrderTicketsId())).getQueryObject(),
                    new Document("$set", new Document("transferStatus", orderTicketVoTransfer.getTransferStatus()).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
            );
            //修改被转赠订单 mysql
            sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            sqlsDataB.add(new Object[]{
                    0, now, orderTicketVoTransfer.getOrderTicketsId(), now, now
            });
            sqls.add(SqlMapping.get("kylin_order_ticket_relation.transfer.update"));
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            sqlsDataC.add(new Object[]{
                    "", "", now, orderTicketVoTransfer.getOrderTicketsId(), now, now
            });
            //删除被转赠订单独立redis
            dataUtils.delTransferOrder(orderTicketVo.getUserId());
            //入库
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_TRANSFER_RESULT.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC));
        } else {
            return ResponseDto.failure("拒收失败");
        }
        return ResponseDto.success("拒收成功");
    }

    @Override
    public ResponseDto<String> orderTransferBack(String orderId) {
        KylinOrderTicketVo vo = dataUtils.getOrderTicketVo(orderId);
        KylinOrderTicketVo vo2 = dataUtils.getOrderTicketVo(vo.getTransferId());
        LocalDateTime now = LocalDateTime.now();
        LinkedList<String> sqls = CollectionUtil.linkedListString();

        //必须开启退款
        String performanceId = vo.getPerformanceId();
        KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(performanceId);
        LocalDateTime refundOpenDate = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getRefundOpenTime());
        LocalDateTime refundCloseDate = DateUtil.Formatter.yyyyMMddHHmmss.parse(performanceVo.getRefundCloseTime());
        if (!(performanceVo.getIsCanRefund().equals(1) && LocalDateTime.now().isAfter(refundOpenDate) && LocalDateTime.now().isBefore(refundCloseDate))) {
            return ResponseDto.failure("未开启退款，不支持回退");
        }
        if (!vo.getTransferStatus().equals(3)) {
            return ResponseDto.failure("无法退回");
        }

        //修改 自己的订单 vo
        //redis
        vo.setTransferStatus(6);
        dataUtils.setOrderTicketVo(orderId, vo);
        orderUtils.resetOrderListVo(vo.getUserId(), 2, orderId, vo);
        //mongo
        mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderTicketsId").is(orderId)).getQueryObject(),
                new Document("$set", new Document("transferStatus", vo.getTransferStatus()).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
        );
        //mysql
        sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
        LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
        sqlsDataA.add(new Object[]{
                vo.getTransferStatus(), now, orderId, now, now
        });
        sqls.add(SqlMapping.get("kylin_order_ticket_relation.transfer.update"));
        LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
        sqlsDataB.add(new Object[]{
                vo.getTransferUid(), vo.getTransferId(), now, orderId, now, now
        });

        //修改 回退订单 vo2
        //redis
        vo2.setTransferStatus(5);
        dataUtils.setOrderTicketVo(vo2.getOrderTicketsId(), vo2);
        orderUtils.resetOrderListVo(vo2.getUserId(), 2, vo2.getOrderTicketsId(), vo2);
        //mongo
        mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderTicketsId").is(vo2.getOrderTicketsId())).getQueryObject(),
                new Document("$set", new Document("transferStatus", vo2.getTransferStatus()).append("updatedAt", DateUtil.Formatter.yyyyMMddHHmmss.format(now)))
        );
        //mysql
        sqls.add(SqlMapping.get("kylin_order_ticket_status.transfer.update"));
        LinkedList<Object[]> sqlsDataA2 = CollectionUtil.linkedListObjectArr();
        sqlsDataA2.add(new Object[]{
                vo2.getTransferStatus(), now, vo2.getOrderTicketsId(), now, now
        });
        sqls.add(SqlMapping.get("kylin_order_ticket_relation.transfer.update"));
        LinkedList<Object[]> sqlsDataB2 = CollectionUtil.linkedListObjectArr();
        sqlsDataB2.add(new Object[]{
                vo2.getTransferUid(), vo2.getTransferId(), now, vo2.getOrderTicketsId(), now, now
        });
        //入库
        queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_TRANSFER_RESULT.getKey(),
                SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataA2, sqlsDataB2));
        return ResponseDto.success("回退成功");
    }

}
