package com.liquidnet.client.admin.zhengzai.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.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.utils.DateUtils;
import com.liquidnet.client.admin.common.utils.ShiroUtils;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dao.KylinOrderRefundsEntitiesDao;
import com.liquidnet.service.kylin.dao.KylinOrderTicketEntitiesDao;
import com.liquidnet.service.kylin.dao.OrderRefundDao;
import com.liquidnet.service.kylin.dto.param.RefundApplyParam;
import com.liquidnet.service.kylin.dto.param.RefundCallbackParam;
import com.liquidnet.service.kylin.dto.param.RefundSearchParam;
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.KylinOrderRefundsAdminVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderRefundsVo;
import com.liquidnet.service.kylin.dto.vo.returns.RefundOrderDetailsVo;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.IKylinOrderRefundsService;
import com.mongodb.BasicDBObject;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
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.convert.MongoConverter;
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.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单退款表 服务实现类 处理逻辑判断
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-26
 */
@Slf4j
@Service
public class KylinOrderRefundsServiceImpl extends ServiceImpl<KylinOrderRefundsMapper, KylinOrderRefunds> implements IKylinOrderRefundsService {
    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinRefundsStatusServiceImpl kylinRefundsStatusServiceImpl;

    @Autowired
    private KylinOrderRefundsMapper kylinOrderRefundsMapper;

    @Autowired
    private KylinOrderTicketStatusMapper kylinOrderTicketStatusMapper;

    @Autowired
    private KylinOrderTicketEntitiesMapper kylinOrderTicketEntitiesMapper;

    @Autowired
    private KylinOrderTicketRelationsMapper kylinOrderTicketRelationsMapper;

    @Autowired
    private KylinPerformancesMapper kylinPerformancesMapper;

    @Autowired
    private KylinOrderRefundsEntitiesMapper kylinOrderRefundsEntitiesMapper;

    @Autowired
    private KylinOrderRefundPicMapper kylinOrderRefundPicMapper;

    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;

    public ResponseDto refundApply(RefundApplyParam refundApplyParam, String authId, String authName) {
        String orderTicketsId = refundApplyParam.getOrderTicketsId();
        List<String> ticketEntityIds = refundApplyParam.getTicketEntityIds();
        List<BigDecimal> entitiesPrice = refundApplyParam.getEntitiesPrice();
        BigDecimal RefundPriceExpress = refundApplyParam.getRefundPriceExpress();
        if (null == RefundPriceExpress) {
            RefundPriceExpress = new BigDecimal(0);
        }

        KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                new QueryWrapper<KylinOrderTickets>().eq("order_tickets_id", orderTicketsId)
        );
        KylinOrderTicketStatus orderStatus = kylinOrderTicketStatusMapper.selectOne(
                new QueryWrapper<KylinOrderTicketStatus>().eq("order_id", orderTicketsId)
        );
        int thisOrderStatus = orderStatus.getStatus();
        int thisPayStatus = orderStatus.getPayStatus();
        BigDecimal priceExpress = orderInfo.getPriceExpress();

        // todo 转增是否能退
        // 订单状态需已付款
        if (thisOrderStatus != KylinTableStatusConst.ORDER_STATUS1 && thisOrderStatus != KylinTableStatusConst.ORDER_STATUS3 && thisOrderStatus != KylinTableStatusConst.ORDER_STATUS6) {
            return ResponseDto.failure("当前订单状态不支持退款申请");
        }
        if (!(orderStatus.getTransferStatus() == 0 || orderStatus.getTransferStatus() == 5)) {
            return ResponseDto.failure("当前转增状态不可退款");
        }
        // 订单支付状态需为已支付
        if (thisPayStatus != KylinTableStatusConst.ORDER_PAY_STATUS1) {
            return ResponseDto.failure("订单支付状态需为已支付");
        }
        // TODO: 2021/6/16 是否能单独退快递飞 批量退款是否退快递费 现在做的是自动退剩余快递费
        // 传的快递费不能大于实际的快递费=（支付的快递费-已退的快递费）
        BigDecimal refundPriceExpressSum = kylinOrderRefundsMapper.RefundPriceExpressSum(// 已退快递费
                orderTicketsId,
                KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL
        );
        if (null == refundPriceExpressSum) {
            refundPriceExpressSum = new BigDecimal(0);
        }
        if (null == refundApplyParam.getOrderRefundBatchesId() || refundApplyParam.getOrderRefundBatchesId().isEmpty()) { // 不是批量退款
            if (RefundPriceExpress.compareTo(priceExpress.subtract(refundPriceExpressSum)) > 0) {
                return ResponseDto.failure("快递费不能大于实际减去已退的快递费");
            }
        } else {
            RefundPriceExpress = priceExpress.subtract(refundPriceExpressSum);
        }

        // todo 出票未出票
        // 选择退款的入场人是否正确
        Integer[] entitiesStatus = new Integer[]{KylinTableStatusConst.ENTITIES_IS_PAYMENT1, KylinTableStatusConst.ENTITIES_IS_PAYMENT2, KylinTableStatusConst.ENTITIES_IS_PAYMENT4};
        int choiceCount = kylinOrderTicketEntitiesMapper.selectCount(
                new QueryWrapper<KylinOrderTicketEntities>()
                        .eq("order_id", orderTicketsId)
                        .in("is_payment", entitiesStatus)
                        .in("order_ticket_entities_id", ticketEntityIds)
        );
        if (choiceCount < 0 || choiceCount != ticketEntityIds.size()) {
            return ResponseDto.failure("入场人订单有误");
        }
        // 该订单正在退款或已有退款 因支持填入价格所有取消判断
        // 各个入场人订单填写的退款金额是否正确
        BigDecimal priceActual = orderInfo.getPriceActual();
        int allEntitiesCount = kylinOrderTicketEntitiesMapper.selectCount(// 总入场人数量 排出未付款的 用来计算单入场人的价格
                new QueryWrapper<KylinOrderTicketEntities>()
                        .eq("order_id", orderTicketsId)
                        .ne("is_payment", KylinTableStatusConst.ENTITIES_IS_PAYMENT0)
        );
        BigDecimal onePrice = priceActual.subtract(priceExpress).divide(BigDecimal.valueOf(allEntitiesCount));//单价
        List<BigDecimal> realRefundPriceList = new ArrayList<>();
        if (null == refundApplyParam.getOrderRefundBatchesId() || refundApplyParam.getOrderRefundBatchesId().isEmpty()) { // 不是批量退款
            for (int i = 0; i <= ticketEntityIds.size() - 1; i++) {
                BigDecimal price = entitiesPrice.get(i);
                if (price.compareTo(BigDecimal.ZERO) <= 0) {
                    return ResponseDto.failure(ErrorMapping.get("20021"));
                } else {
                    BigDecimal refundedPrice = kylinOrderTicketEntitiesMapper.getRefundEntitiesPrice(//已退
                            orderTicketsId,
                            KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL,
                            ticketEntityIds.get(i)
                    );
                    if (null == refundedPrice) {
                        refundedPrice = new BigDecimal(0);
                    }
                    if (price.compareTo(onePrice.subtract(refundedPrice)) > 0) {
                        return ResponseDto.failure("超过可退款金额");
                    }
                }
            }
            realRefundPriceList = entitiesPrice;
        } else { // 批量 计算入场人订单可退金额
            List<String> ticketEntityIdsNew = new ArrayList<>();
            for (int i = 0; i <= ticketEntityIds.size() - 1; i++) {
                BigDecimal refundedPrice = kylinOrderTicketEntitiesMapper.getRefundEntitiesPrice(//已退 包含退款中
                        orderTicketsId,
                        KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL,
                        ticketEntityIds.get(i)
                );
                if (null == refundedPrice) {
                    refundedPrice = new BigDecimal(0);
                }
                BigDecimal price = onePrice.subtract(refundedPrice); // 计算可退金额
                if (price.compareTo(BigDecimal.ZERO) > 0) {
                    realRefundPriceList.add(price);
                    ticketEntityIdsNew.add(ticketEntityIds.get(i));
                }
            }
            // 剔除掉已经退完的入场人订单 可能包含正在退的
            ticketEntityIds = ticketEntityIdsNew;
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefunding(
                refundApplyParam, orderInfo, orderTicketsId,
                RefundPriceExpress,
                ticketEntityIds, realRefundPriceList
                , authId, authName
        );

        HashMap<String, Object> map = new HashMap<>();
        map.put("isHaveRefundDetails", 1);
        BasicDBObject obj = new BasicDBObject("$set", mongoConverter.convertToMongoType(map));
        mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderTicketsId").is(orderTicketsId)).getQueryObject(),
                obj);

        if (res) {
            return ResponseDto.success();
        } else {
            return ResponseDto.failure("操作失败");
        }
    }

    public ResponseDto refundCheckStatus(RefundApplyParam refundApplyParam, String authId, String authName) {
        String type = refundApplyParam.getType();
        List<String> orderRefundsIdList = refundApplyParam.getIds();
        if (orderRefundsIdList.size() <= 0) {
            return ResponseDto.failure("无退款订单");
        }
        List<Integer> orderRefundStatus = null;
        List<Integer> orderTypeList = null;
        switch (type) {
            default:
                return ResponseDto.failure("type类型错误");
            case "cancel":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED);
                orderTypeList = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY, KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY2, KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY3);
                break;
            case "reapply":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT);
                break;
            case "approved":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE);
                break;
            case "reject": // 运营驳回
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE);
                orderTypeList = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY, KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY2, KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY3);
                break;
            case "ticketAudit":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED);
                orderTypeList = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY3);
                break;
            case "unfilled":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR, KylinTableStatusConst.ORDER_REFUND_STATUS_TICKET);
                break;
            case "refuse":
                orderRefundStatus = Arrays.asList(KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR, KylinTableStatusConst.ORDER_REFUND_STATUS_TICKET);
                break;
        }

        QueryWrapper<KylinOrderRefunds> listQuery = new QueryWrapper();
        listQuery.in("order_refunds_id", orderRefundsIdList).in("status", orderRefundStatus);
        if (null != orderTypeList) {
            listQuery.in("type", orderTypeList);
        }
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(listQuery);
        if (orderRefundsIdList.size() != refundList.size()) {
            return ResponseDto.failure("当前状态不允许操作");
        }

        if (type.equals("unfilled") || type.equals("refuse")) {
            for (KylinOrderRefunds info : refundList) {
                if (info.getType() == KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY3) {
                    if (info.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED) {
                        return ResponseDto.failure("存在待确认收货的订单，当前不允许操作");
                    }
                }
            }
        }

        boolean res = false;
        String reject = refundApplyParam.getReject();
        String refuse = refundApplyParam.getRefuse();
        switch (type) {
            case "cancel":
                res = kylinRefundsStatusServiceImpl.orderTicketRefundCancel(refundList, true);
                break;
            case "reapply":
                res = kylinRefundsStatusServiceImpl.orderRefundChangeStatus(refundList, refundApplyParam, authId, authName);
                break;
            case "approved":
                res = kylinRefundsStatusServiceImpl.orderRefundChangeStatus(refundList, refundApplyParam, authId, authName);
                break;
            case "reject":
                boolean cancelRes = kylinRefundsStatusServiceImpl.orderTicketRefundCancel(refundList, false);
                res = kylinRefundsStatusServiceImpl.orderRefundChangeStatus(refundList, refundApplyParam, authId, authName);
                break;
            case "ticketAudit":
                res = kylinRefundsStatusServiceImpl.orderRefundChangeStatus(refundList, refundApplyParam, authId, authName);
                break;
            case "unfilled":
                kylinRefundsStatusServiceImpl.orderTicketRefundUnfilled(refundList, refundApplyParam, authId, authName);
                res = true;
                break;
            case "refuse":
                res = kylinRefundsStatusServiceImpl.orderRefundChangeStatus(refundList, refundApplyParam, authId, authName);
                break;
        }
        if (res) {
            return ResponseDto.success();
        } else {
            return ResponseDto.failure("操作失败");
        }
    }

    public ResponseDto refundCompleted(RefundApplyParam refundApplyParam) {
        List<String> orderRefundsIdList = refundApplyParam.getIds();

        KylinOrderRefunds refundInfo = kylinOrderRefundsMapper.selectOne(
                new QueryWrapper<KylinOrderRefunds>()
                        .in("order_refunds_id", orderRefundsIdList)
        );
        if (null == refundInfo) {
            return ResponseDto.failure("退款订单查询失败");
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL) {
            return ResponseDto.failure("退款订单已取消");
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_REFUNDED) {
            return ResponseDto.failure("退款订单已完成");
        }

        RefundCallbackParam refundCallbackParam = new RefundCallbackParam();
        refundCallbackParam.setRefundCode(refundInfo.getRefundCode());
        BigDecimal refundPrice = refundInfo.getPrice().add(refundInfo.getPriceExpress());
        refundCallbackParam.setRefundPrice(refundPrice);
        refundCallbackParam.setRefundId(refundInfo.getRefundId());
        refundCallbackParam.setRefundAt(DateUtils.dateTimeNow());
        refundCallbackParam.setRefundError(refundInfo.getRefundError());
        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefunded(refundCallbackParam, refundInfo);
        if (res) {
            String authId = ShiroUtils.getUserId().toString();
            String authName = ShiroUtils.getLoginName();
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            if (refundInfo.getAuditorId().isEmpty()) {
                kylinOrderRefunds.setAuditorAt(LocalDateTime.now());
                kylinOrderRefunds.setAuditorId(authId);
                kylinOrderRefunds.setAuditorName(authName);
            }
            kylinOrderRefunds.setExecutorAt(LocalDateTime.now());
            kylinOrderRefunds.setExecutorId(authId);
            kylinOrderRefunds.setExecutorName(authName);
            kylinOrderRefundsMapper.update(
                    kylinOrderRefunds,
                    new UpdateWrapper<KylinOrderRefunds>().in("order_refunds_id", refundInfo.getOrderRefundsId())
            );
            // 修改缓存
            KylinOrderRefundsVo kylinOrderRefundsVo = new KylinOrderRefundsVo();
            BeanUtils.copyProperties(kylinOrderRefunds, kylinOrderRefundsVo);
            BasicDBObject object = new BasicDBObject("$set", mongoConverter.convertToMongoType(kylinOrderRefundsVo));
            UpdateResult updateResult = mongoTemplate.getCollection(KylinOrderRefundsVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderRefundsId").is(refundInfo.getOrderRefundsId())).getQueryObject(),
                    object
            );
            return ResponseDto.success();
        } else {
            return ResponseDto.failure("fail");
        }
    }

    public KylinOrderRefundsAdminVo detail(String orderRefundId) {
        // 退款订单数据
        KylinOrderRefunds data = kylinOrderRefundsMapper.selectOne(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("order_refunds_id", orderRefundId)
        );
        // 退款票种
        List<KylinOrderRefundEntities> refundEntities = kylinOrderRefundsEntitiesMapper.selectList(
                new QueryWrapper<KylinOrderRefundEntities>().eq("order_refunds_id", orderRefundId)
        );
        List<String> orderTicketEntitiesIdsArr = refundEntities.stream().map(KylinOrderTicketEntities -> KylinOrderTicketEntities.getOrderTicketEntitiesId()).collect(Collectors.toList());
        List<KylinOrderRefundsEntitiesDao> entities = kylinOrderTicketEntitiesMapper.selectEntitiesList(orderTicketEntitiesIdsArr);
        for (KylinOrderRefundsEntitiesDao item : entities) {
            item.setPaymentName(item.getIsPayment());
        }
        // 退款申请图片
        KylinOrderRefundsAdminVo kylinOrderRefundsVo = KylinOrderRefundsAdminVo.getNew();
        kylinOrderRefundsVo.setEntities(entities);
        BeanUtils.copyProperties(data, kylinOrderRefundsVo);
        KylinOrderRefundPic kylinOrderRefundPic = kylinOrderRefundPicMapper.selectOne(new UpdateWrapper<KylinOrderRefundPic>().eq("order_refunds_id", orderRefundId));
        if (kylinOrderRefundPic != null) {
            String picStr = kylinOrderRefundPic.getPicUrl();
            List<String> strList = JsonUtils.fromJson(picStr, new TypeReference<List<String>>() {
            });
            kylinOrderRefundsVo.setPicList(strList);
        }
        // 订单表
        KylinOrderTickets kylinOrderTickets = kylinOrderTicketsMapper.selectOne(
                Wrappers.lambdaQuery(KylinOrderTickets.class).eq(KylinOrderTickets::getOrderTicketsId, data.getOrderTicketsId())
        );
        if (kylinOrderTickets.getGetTicketType().equals("express")) {
            kylinOrderRefundsVo.setGetTicketType("快递票");
        } else {
            kylinOrderRefundsVo.setGetTicketType("电子票");
        }
        String typeName = "";
        switch (kylinOrderRefundsVo.getType()) {
            case 0:
                typeName = "客服申请";
                break;
            case 1:
                typeName = "超时退款";
                break;
            case 2:
                typeName = "用户申请普通退款";
                break;
            case 3:
                typeName = "用户申请快递退款";
                break;
        }
        kylinOrderRefundsVo.setTypeName(typeName);
        kylinOrderRefundsVo.setPayType(kylinOrderTickets.getPayType());

        return kylinOrderRefundsVo;
    }

    public PageInfo<OrderRefundDao> refundList(RefundSearchParam refundSearchParam) {
        PageInfo<OrderRefundDao> pageInfoTmp = null;
        try {
            if (!ShiroUtils.getSysUser().isAdmin()) {
                if (ShiroUtils.getSubject().hasRole("kylin:refund:ticketAudit")) {
                    // 票务
                    refundSearchParam.setRoleType(1);
                }
                if (ShiroUtils.getSubject().hasRole("kylin:refund:execute")) {
                    // 财务
                    refundSearchParam.setRoleType(2);
                }
            }

            PageHelper.startPage(refundSearchParam.getPageNum(), refundSearchParam.getPageSize());
            if (!refundSearchParam.getStatus().isEmpty()) {
                refundSearchParam.setStatusStr(Arrays.asList(refundSearchParam.getStatus().split(",")));
            }
            List<OrderRefundDao> voList = kylinOrderRefundsMapper.misRefundList(BeanUtil.convertBeanToMap(refundSearchParam));
            for (OrderRefundDao item : voList) {
                item.setStatusName(item.getStatus());
            }
            pageInfoTmp = new PageInfo(voList);
        } catch (Exception e) {
            return new PageInfo(new ArrayList());
        }
        return pageInfoTmp;
    }

    public AjaxResult orderDetails(String orderCode) {
        try {
            // 订单
            KylinOrderTickets kylinOrderTickets = kylinOrderTicketsMapper.selectOne(
                    new QueryWrapper<KylinOrderTickets>().eq("order_code", orderCode)
            );
            KylinOrderTicketStatus kylinOrderTicketStatus = kylinOrderTicketStatusMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTicketStatus.class).eq(KylinOrderTicketStatus::getOrderId, kylinOrderTickets.getOrderTicketsId())
            );
            if (!(kylinOrderTicketStatus.getTransferStatus() == 0 || kylinOrderTicketStatus.getTransferStatus() == 5)) {
                return AjaxResult.error("当前转增状态不可退款");
            }
            BigDecimal oldPriceExpress = kylinOrderTickets.getPriceExpress();
            // 传的快递费不能大于实际的快递费=（支付的快递费-已退的快递费）
            BigDecimal refundPriceExpressSum = kylinOrderRefundsMapper.RefundPriceExpressSum(// 已退快递费
                    kylinOrderTickets.getOrderTicketsId(),
                    KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL
            );
            if (null == refundPriceExpressSum) {
                refundPriceExpressSum = new BigDecimal(0);
            }
            BigDecimal RefundPriceExpress = kylinOrderTickets.getPriceExpress().subtract(refundPriceExpressSum);
            kylinOrderTickets.setPriceExpress(RefundPriceExpress);

            // 订单关联 获取演出id
            KylinOrderTicketRelations kylinOrderTicketRelations = kylinOrderTicketRelationsMapper.selectOne(
                    new QueryWrapper<KylinOrderTicketRelations>().eq("order_id", kylinOrderTickets.getOrderTicketsId())
            );

            // 演出
            KylinPerformances kylinPerformances = kylinPerformancesMapper.selectOne(
                    new QueryWrapper<KylinPerformances>().eq("performances_id", kylinOrderTicketRelations.getPerformanceId())
            );

            List<KylinOrderTicketEntitiesDao> entitiesListTemp = kylinOrderTicketEntitiesMapper.getRefundEntitiesList(kylinOrderTickets.getOrderTicketsId());
            List<KylinOrderTicketEntitiesDao> entitiesList = new ArrayList<>();
            if (entitiesListTemp.size() > 0) {
                BigDecimal priceActual = kylinOrderTickets.getPriceActual();
                BigDecimal priceExpress = kylinOrderTickets.getPriceExpress();
                int allEntitiesCount = kylinOrderTicketEntitiesMapper.selectCount(// 总入场人数量 排出未付款的 用来计算单入场人的价格
                        new QueryWrapper<KylinOrderTicketEntities>()
                                .eq("order_id", kylinOrderTickets.getOrderTicketsId())
                                .ne("is_payment", KylinTableStatusConst.ENTITIES_IS_PAYMENT0)
                );
                BigDecimal onePrice = (priceActual.subtract(oldPriceExpress)).divide(BigDecimal.valueOf(allEntitiesCount));//单价
                for (KylinOrderTicketEntitiesDao entities : entitiesListTemp) {
                    BigDecimal refundedPrice = kylinOrderTicketEntitiesMapper.getRefundEntitiesPrice(//已退 包含退款中
                            kylinOrderTickets.getOrderTicketsId(),
                            KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL,
                            entities.getOrderTicketEntitiesId()
                    );
                    BigDecimal canRefundedPrice;
                    if (null != refundedPrice) {
                        canRefundedPrice = onePrice.subtract(refundedPrice);
                    } else {
                        canRefundedPrice = onePrice;
                    }
                    entities.setCanRefundedPrice(canRefundedPrice);
                    if (canRefundedPrice.compareTo(BigDecimal.ZERO) > 0) { // 退款中但是可退款金额为0不展示
                        entitiesList.add(entities);
                    }
                }
            }

            KylinOrderTicketVo kylinOrderTicketVo = new KylinOrderTicketVo();
            BeanUtil.copy(kylinOrderTickets, kylinOrderTicketVo);

            KylinPerformanceVo performanceVo = new KylinPerformanceVo();
            BeanUtil.copy(kylinPerformances, performanceVo);

            RefundOrderDetailsVo refundOrderDetailsVo = new RefundOrderDetailsVo();
            refundOrderDetailsVo.setOrderTicketVo(kylinOrderTicketVo);
            refundOrderDetailsVo.setKylinPerformanceVo(performanceVo);
            refundOrderDetailsVo.setKylinOrderTicketEntitiesDao(entitiesList);

            return AjaxResult.success(refundOrderDetailsVo);
        } catch (Exception e) {
            log.error("orderDetailsException e[{}]", e);
            return AjaxResult.error("未找到该订单信息");
        }
    }

    @Override
    public String getOrderRefundCode(String code, int type) {
        String orderCode = null;
        try {
            if (type == 1) {
                KylinOrderRefunds data = kylinOrderRefundsMapper.selectOne(new UpdateWrapper<KylinOrderRefunds>().like("order_refund_code", code));
                if (data == null) {
                    return null;
                } else {
                    orderCode = data.getOrderRefundCode();
                }
            } else if (type == 2) {
                KylinOrderTickets data = kylinOrderTicketsMapper.selectOne(new UpdateWrapper<KylinOrderTickets>().like("order_code", code));
                if (data == null) {
                    return null;
                } else {
                    orderCode = data.getOrderCode();
                }
            }
        } catch (Exception e) {

        }
        return orderCode;
    }
}
