package cn.iocoder.yudao.module.order.service.order.impl;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.apollo.core.event.box.BoxCheckOrderSchedulingEvent;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.service.order.OrderBusinessService;
import cn.iocoder.yudao.module.order.service.order.OrderGuanlianService;
import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import cn.iocoder.yudao.module.order.vo.order.OrderBackVO;
import cn.iocoder.yudao.module.order.vo.order.OrderQueryVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.order.vo.orderGuanlian.*;
import cn.iocoder.yudao.module.order.dal.dataobject.orderGuanlian.OrderGuanlianDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.order.convert.orderGuanlian.OrderGuanlianConvert;
import cn.iocoder.yudao.module.order.dal.mysql.orderGuanlian.OrderGuanlianMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.*;

/**
 * 订单关联 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class OrderGuanlianServiceImpl extends AbstractService<OrderGuanlianMapper, OrderGuanlianDO> implements OrderGuanlianService {

    @Resource
    @Lazy // 解决循环依赖
    private OrderService orderService;

    @Resource
    @Lazy // 解决循环依赖
    private OrderBusinessService orderBusinessService;

    @Resource
    private OrderQueryService orderQueryService;

    @Resource
    private OrderGuanlianMapper guanlianMapper;

    @Resource
    private ApplicationContext applicationContext;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createGuanlian(OrderGuanlianCreateReqVO createReqVO) {
        OrderGuanlianDO orderGuanlianDO = guanlianMapper.selectOne(OrderGuanlianDO::getOrderId, createReqVO.getOrderId(), OrderGuanlianDO::getRelateOrderId, createReqVO.getRelateOrderId());
        OrderGuanlianDO orderGuanlianDO1 = guanlianMapper.selectOne(OrderGuanlianDO::getOrderId, createReqVO.getRelateOrderId(), OrderGuanlianDO::getRelateOrderId, createReqVO.getOrderId());
        if (orderGuanlianDO != null || orderGuanlianDO1 != null) {
            throw exception(ORDER_GUANLIAN_IS_EXISTS);
        }

        applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVO.getOrderId()));
        applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVO.getRelateOrderId()));

        // 插入
        OrderGuanlianDO guanlian = OrderGuanlianConvert.INSTANCE.convert(createReqVO);
        guanlianMapper.insert(guanlian);
        OrderDO orderDO = orderService.getById(guanlian.getOrderId());
        orderService.updateGuanlianOrderStatus(orderDO);
        OrderDO relateOrderDO = orderService.getById(guanlian.getRelateOrderId());
        orderService.updateGuanlianOrderStatus(relateOrderDO);

        orderBusinessService.addOrderOperateLog(guanlian.getOrderId(), "", "新增关联订单", "");
        orderBusinessService.addOrderOperateLog(guanlian.getRelateOrderId(),"","新增关联订单","");
        // 返回
        return guanlian.getId();
    }

    @Override
    public void updateGuanlian(OrderGuanlianUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateGuanlianExists(updateReqVO.getId());
        // 更新
        OrderGuanlianDO updateObj = OrderGuanlianConvert.INSTANCE.convert(updateReqVO);
        guanlianMapper.updateById(updateObj);
    }

    @Override
    public void deleteGuanlian(Long id) {
        // 校验存在
        this.validateGuanlianExists(id);
        // 删除
        guanlianMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealGuanlianByOrderId(Long orderId,List<Long> splitOrderIds,int type) {
        if (type == 1) {
            List<OrderGuanlianDO> guanlianListByOrderId = getGuanlianListByOrderId(orderId);
            if (CollectionUtil.isNotEmpty(guanlianListByOrderId)) {
                //继承关联关系
                guanlianListByOrderId.stream().forEach(item -> {
                    splitOrderIds.stream().forEach(id ->{
                        OrderGuanlianDO orderGuanlianDO = new OrderGuanlianDO();
                        BeanUtils.copyProperties(item,orderGuanlianDO);
                        if (item.getOrderId().longValue() == orderId.longValue()) {
                            orderGuanlianDO.setOrderId(id);
                        } else {
                            orderGuanlianDO.setRelateOrderId(id);
                        }
                        orderGuanlianDO.setId(null);
                        guanlianMapper.insert(orderGuanlianDO);
                    });
                    guanlianMapper.deleteById(item);
                    orderService.cancelGuanlianOrderStatus(item.getOrderId(), item.getRelateOrderId());
                    orderService.cancelGuanlianOrderStatus(item.getRelateOrderId(), item.getOrderId());
                });
            }
        } else if (type == 2) {
            if (CollectionUtil.isNotEmpty(splitOrderIds)) {
                //删除拆单后的关联订单，不管后面有没有新增关联，都删除才对
                List<OrderGuanlianDO> orderGuanlianDOS = guanlianMapper.selectList(new LambdaQueryWrapperX<OrderGuanlianDO>().and(i -> i.in(OrderGuanlianDO::getOrderId, splitOrderIds).or().in(OrderGuanlianDO::getRelateOrderId, splitOrderIds)));
                orderGuanlianDOS.stream().forEach(item -> {
                    if (splitOrderIds.contains(item.getOrderId())) {
                        guanlianMapper.updateGuanlianBackByRelatId(item);
                    } else if (splitOrderIds.contains(item.getRelateOrderId())) {
                        guanlianMapper.updateGuanlianBackByOrderId(item);
                    }
                    orderService.cancelGuanlianOrderStatus(item.getOrderId(), item.getRelateOrderId());
                    orderService.cancelGuanlianOrderStatus(item.getRelateOrderId(), item.getOrderId());
                });
                if (CollectionUtil.isNotEmpty(orderGuanlianDOS)) {
                    guanlianMapper.deleteBatchIds(orderGuanlianDOS.stream().map(OrderGuanlianDO::getId).collect(Collectors.toList()));
                }
            }
        }
    }

    private void validateGuanlianExists(Long id) {
        if (guanlianMapper.selectById(id) == null) {
            throw exception(GUANLIAN_NOT_EXISTS);
        }
    }

    @Override
    public OrderGuanlianDO getGuanlian(Long id) {
        return guanlianMapper.selectById(id);
    }

    @Override
    public List<OrderGuanlianDO> getGuanlianList(Collection<Long> ids) {
        return guanlianMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderGuanlianDO> getGuanlianPage(OrderGuanlianQueryVO query, PageVO page) {
        return guanlianMapper.selectPage(page, query);
    }

    @Override
    public List<OrderGuanlianDO> getGuanlianList(OrderGuanlianQueryVO query) {
        return guanlianMapper.selectList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateGuanlian(List<OrderGuanlianCreateReqVO> createReqVOList) {
        if (createReqVOList != null && createReqVOList.size() > 0) {
            Date date = new Date();
            for (OrderGuanlianCreateReqVO orderGuanlianCreateReqVO : createReqVOList) {
                applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(orderGuanlianCreateReqVO.getRelateOrderId()));
                // 插入
                orderGuanlianCreateReqVO.setAddTime(date);
                OrderGuanlianDO guanlian = OrderGuanlianConvert.INSTANCE.convert(orderGuanlianCreateReqVO);
                guanlianMapper.insert(guanlian);

                OrderDO orderDO = orderService.getById(guanlian.getOrderId());
                orderService.updateGuanlianOrderStatus(orderDO);
                OrderDO relateOrderDO = orderService.getById(guanlian.getRelateOrderId());
                orderService.updateGuanlianOrderStatus(relateOrderDO);

                orderBusinessService.addOrderOperateLog(guanlian.getRelateOrderId(),"","新增关联订单","");
                // 返回
            }
            applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVOList.get(0).getOrderId()));
            orderBusinessService.addOrderOperateLog(createReqVOList.get(0).getOrderId(), "", "新增关联订单", "");
        }
    }

    @Override
    public PageResult<OrderGuanlianBackVO> getGuanlianOrderByOrderId(OrderGuanlianQueryVO orderGuanlianQueryVO, PageParam pageParam) {
        PageResult<OrderGuanlianBackVO> pageResult = new PageResult<>();
        if (StringUtils.isBlank(orderGuanlianQueryVO.getRelateOrderNo())) {
            IPage<OrderGuanlianDO> mpPage = MyBatisUtils.buildPage(pageParam);
            guanlianMapper.getGuanlianOrderByOrderId(mpPage,orderGuanlianQueryVO.getOrderId());
            PageResult<OrderGuanlianDO> orderGuanlianDOPageResult = PageResult.of(mpPage);
            List<OrderGuanlianBackVO> collect = orderGuanlianDOPageResult.getList().stream().map(item -> {
                OrderBackVO order = null;
                if (orderGuanlianQueryVO.getOrderId().longValue() == item.getRelateOrderId().longValue()) {
                    order = orderQueryService.getOrder(item.getOrderId());
                } else {
                    order = orderQueryService.getOrder(item.getRelateOrderId());
                }
                OrderGuanlianBackVO convert = OrderGuanlianConvert.INSTANCE.convert(item);
                convert.setOrderBackVO(order);
                return convert;
            }).collect(Collectors.toList());
            pageResult.setList(collect);
            pageResult.setPage(orderGuanlianDOPageResult.getPage());
            pageResult.setPages(orderGuanlianDOPageResult.getPages());
            pageResult.setRows(orderGuanlianDOPageResult.getRows());
            pageResult.setTotal(orderGuanlianDOPageResult.getTotal());
        } else {
            List<OrderGuanlianBackVO> list = new ArrayList<>();
            OrderDO orderDO = orderService.selectOne(OrderDO::getOrderNo, orderGuanlianQueryVO.getRelateOrderNo());
            if (orderDO == null) {
                throw exception(ORDER_NOT_EXISTS);
            }
            OrderGuanlianDO orderGuanlianDO = guanlianMapper.selectOne(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getOrderId(), OrderGuanlianDO::getRelateOrderId, orderDO.getOrderId());
            pageResult.setTotal(0L);
            if (orderGuanlianDO != null) {
                OrderBackVO order = orderQueryService.getOrder(orderGuanlianDO.getRelateOrderId());
                OrderGuanlianBackVO convert = OrderGuanlianConvert.INSTANCE.convert(orderGuanlianDO);
                convert.setOrderBackVO(order);
                list.add(convert);
                pageResult.setTotal(1L);
            }
            pageResult.setList(list);
            pageResult.setPage(1L);
            pageResult.setPages(1L);
            pageResult.setRows(10L);
        }
        return pageResult;
    }

    @Override
    public PageResult<OrderBackVO> getUnGuanlianOrderByOrderId(OrderGuanlianQueryVO orderGuanlianQueryVO, PageVO pageVO) {
        OrderBackVO order = orderQueryService.getOrder(orderGuanlianQueryVO.getOrderId());
        OrderQueryVO orderQueryVo = new OrderQueryVO();
        orderQueryVo.setParentOrderId(orderGuanlianQueryVO.getOrderId());
        orderQueryVo.setTransportId(order.getTransportId());
        orderQueryVo.setDepartureId(order.getDepartureId());
        orderQueryVo.setObjectiveId(order.getObjectiveId());
        if (StringUtils.isNotBlank(orderGuanlianQueryVO.getRelateOrderNo())) {
            orderQueryVo.setOrderNo(orderGuanlianQueryVO.getRelateOrderNo());
        }
        PageResult<OrderBackVO> pageResult = orderQueryService.getUnGuanlianOrderPage(orderQueryVo, pageVO);
//        orderList.addAll(OrderConvert.INSTANCE.convertList(orderPage.getList()));
//        pageResult.setList(orderList);
//        pageResult.setTotal(orderPage.getTotal());
//        pageResult.setRows(orderPage.getRows());
//        pageResult.setPages(orderPage.getPages());
//        pageResult.setPage(orderPage.getPage());
//        if(orderList!=null&&orderList.size()>0){
//            List<OrderGuanlianDO> orderGuanlianDOS = guanlianMapper.selectList(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getOrderId());
//            if(orderGuanlianDOS!=null){
//                for (OrderBackVO orderBackVO : orderList) {
//                    boolean flag = true;
//                    for (OrderGuanlianDO orderGuanlianDO : orderGuanlianDOS){
//                        if(orderBackVO.getOrderId().equals(orderGuanlianDO.getRelateOrderId())){
//                            flag = false;
//                        }
//                    }
//                    if(flag){
//                        list.add(orderBackVO);
//                    }
//                }
//            } else {
//                list.addAll(orderList);
//            }
//        }
        return pageResult;
    }

    @Override
    public void deleteGuanlianOrderByOrderId(OrderGuanlianQueryVO orderGuanlianQueryVO) {
        guanlianMapper.delete(new LambdaQueryWrapperX<OrderGuanlianDO>()
                .eqIfPresent(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getOrderId())
                .eqIfPresent(OrderGuanlianDO::getRelateOrderId, orderGuanlianQueryVO.getRelateOrderId()));
        guanlianMapper.delete(new LambdaQueryWrapperX<OrderGuanlianDO>()
                .eqIfPresent(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getRelateOrderId())
                .eqIfPresent(OrderGuanlianDO::getRelateOrderId, orderGuanlianQueryVO.getOrderId()));
        // 同步更新关联订单上级所有订单关联状态
        orderService.cancelGuanlianOrderStatus(orderGuanlianQueryVO.getOrderId(), orderGuanlianQueryVO.getRelateOrderId());
        orderService.cancelGuanlianOrderStatus(orderGuanlianQueryVO.getRelateOrderId(), orderGuanlianQueryVO.getOrderId());
        orderBusinessService.addOrderOperateLog(orderGuanlianQueryVO.getOrderId(), "", "移出关联订单", "");
        orderBusinessService.addOrderOperateLog(orderGuanlianQueryVO.getRelateOrderId(), "", "移出关联订单", "");
    }

    @Override
    public void deleteBatchGuanlianOrderByOrderId(List<OrderGuanlianQueryVO> orderGuanlianQueryVOList) {
        if (orderGuanlianQueryVOList != null && orderGuanlianQueryVOList.size() > 0) {
            for (OrderGuanlianQueryVO orderGuanlianQueryVO : orderGuanlianQueryVOList) {
                guanlianMapper.delete(new LambdaQueryWrapperX<OrderGuanlianDO>()
                        .eqIfPresent(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getOrderId())
                        .eqIfPresent(OrderGuanlianDO::getRelateOrderId, orderGuanlianQueryVO.getRelateOrderId()));
                guanlianMapper.delete(new LambdaQueryWrapperX<OrderGuanlianDO>()
                        .eqIfPresent(OrderGuanlianDO::getOrderId, orderGuanlianQueryVO.getRelateOrderId())
                        .eqIfPresent(OrderGuanlianDO::getRelateOrderId, orderGuanlianQueryVO.getOrderId()));
                // 同步更新关联订单上级所有订单关联状态
                orderService.cancelGuanlianOrderStatus(orderGuanlianQueryVO.getOrderId(), orderGuanlianQueryVO.getRelateOrderId());
                orderService.cancelGuanlianOrderStatus(orderGuanlianQueryVO.getRelateOrderId(), orderGuanlianQueryVO.getOrderId());
                orderBusinessService.addOrderOperateLog(orderGuanlianQueryVOList.get(0).getRelateOrderId(), "", "批量移出关联订单", "");
            }
            orderBusinessService.addOrderOperateLog(orderGuanlianQueryVOList.get(0).getOrderId(), "", "批量移出关联订单", "");
        }
    }

    @Override
    public List<OrderGuanlianDO> getGuanlianList(List<Long> orderIdList) {
        return guanlianMapper.selectList(new LambdaQueryWrapperX<OrderGuanlianDO>()
                .and(i -> i.in(OrderGuanlianDO::getRelateOrderId, orderIdList)
                        .or()
                        .in(OrderGuanlianDO::getOrderId, orderIdList)
                )
        );
    }

    @Override
    public List<OrderGuanlianDO> getGuanlianListByOrderId(Long orderId) {
        return guanlianMapper.selectList(new LambdaQueryWrapperX<OrderGuanlianDO>()
                .and(i -> i.eq(OrderGuanlianDO::getRelateOrderId, orderId)
                        .or()
                        .eq(OrderGuanlianDO::getOrderId, orderId)
                )
        );
    }

    @Override
    public List<OrderDO> getRelateOrderListByOrderId(Long orderId) {
        List<OrderGuanlianDO> relateList = guanlianMapper.selectList(new LambdaQueryWrapperX<OrderGuanlianDO>()
                .and(i -> i.eq(OrderGuanlianDO::getRelateOrderId, orderId)
                        .or()
                        .eq(OrderGuanlianDO::getOrderId, orderId)
                )
        );
        if (CollectionUtil.isEmpty(relateList)) return null;
        List<Long> rIdList = new ArrayList<>();
        for (OrderGuanlianDO orderGuanlianDO : relateList) {
            Long oId = orderGuanlianDO.getOrderId();
            Long rId = orderGuanlianDO.getRelateOrderId();
            if (oId.equals(orderId)) {
                rIdList.add((rId));
            } else if (rId.equals(orderId)) {
                rIdList.add(oId);
            }
        }
        if (CollectionUtil.isEmpty(rIdList)) return null;
        return orderQueryService.getOrderList(rIdList);
    }

    public Set<Long> findRelatedOrderIds(Long orderId) {
        Set<Long> relateIds = new HashSet<>();
        List<Long> orderIdsToSearch = new ArrayList<>();
        orderIdsToSearch.add(orderId);

        while (!orderIdsToSearch.isEmpty()) {
            Long currentOrderId = orderIdsToSearch.get(0);
            List<OrderGuanlianDO> relatedOrders = baseMapper.getOrderRelationList(currentOrderId);
            for (OrderGuanlianDO relatedOrder : relatedOrders) {
                Long relateOrderId = relatedOrder.getRelateOrderId();
                Long oId = relatedOrder.getOrderId();
                if (relateIds.contains(relatedOrder.getId())) continue;
                relateIds.add(relatedOrder.getId());

                if (!orderIdsToSearch.contains(relateOrderId)) {
                    orderIdsToSearch.add(relateOrderId);
                }
                if (!orderIdsToSearch.contains(oId)) {
                    orderIdsToSearch.add(oId);
                }
            }
            orderIdsToSearch.remove(0);
        }

        return relateIds;
    }

    @Override
    public List<OrderGuanlianDO> getRelationList(Long orderId) {
        List<OrderGuanlianDO> orderRelationList = baseMapper.getOrderRelationList(orderId);
        if (CollectionUtil.isEmpty(orderRelationList)) return null;

        Set<Long> idSets = findRelatedOrderIds(orderId);

        orderRelationList = getGuanlianList(idSets);
        return orderRelationList;
    }

    @Override
    public OrderTree getAllRelateOrderList(String orderParentNo, List<OrderGuanlianDO> orderRelationList) {
        Set<Long> orderIdSet = orderRelationList.stream()
                .flatMap(o -> Stream.of(o.getOrderId(), o.getRelateOrderId()))
                .collect(Collectors.toSet());

        List<OrderDO> orderList = orderService.listByIds(orderIdSet);

        Map<Long, String> orderMap = orderList.stream()
                .collect(Collectors.toMap(OrderDO::getOrderId, OrderDO::getOrderNo));

        List<OrderTree.OrderRelation> orderRelations = new ArrayList<>();
        for (OrderGuanlianDO orderGuanlianDO : orderRelationList) {
            String orderNo = orderMap.get(orderGuanlianDO.getOrderId());
            String relateOrderNo = orderMap.get(orderGuanlianDO.getRelateOrderId());
            if(StringUtils.isEmpty(orderNo) || StringUtils.isEmpty(relateOrderNo)) continue;
            orderRelations.add(new OrderTree.OrderRelation(orderNo, relateOrderNo));
        }
        OrderTree orderTree = OrderTree.buildTree(orderRelations, orderParentNo);

        removeCorrelate(orderTree);
        return orderTree;
    }

    @Override
    public OrderTree getAllRelateOrderList(Long orderId, String parentOrderNo) {
        List<OrderGuanlianDO> orderRelationList = getRelationList(orderId);
        if (CollectionUtil.isEmpty(orderRelationList)) return null;
        return getAllRelateOrderList(parentOrderNo, orderRelationList);
    }

    private void removeCorrelate(OrderTree orderTree) {
        List<OrderTree> children = orderTree.getChildren();
        Iterator<OrderTree> it = children.iterator();
        while (it.hasNext()) {
            OrderTree childTree = it.next();
            childTree.getOrder().getRelateOrderNos().remove(orderTree.getOrder().getOrderNo());
            if (CollectionUtil.isEmpty(childTree.getChildren())) {
                it.remove();
            } else {
                removeCorrelate(childTree);
            }
        }
    }

    @Override
    public void getGuanlianOrderByRelateOrderId(Long relateOrderId, List<OrderDO> orderDOList) {
        // TODO 关联异常订单修改为不管层级关系，获取所有相互关联的订单信息，后面如果需要避免程序的堆栈溢出，需要限定关联上限
        // 向上搜索
        List<OrderGuanlianDO> orderGuanlianDOList = guanlianMapper.selectList(new LambdaQueryWrapper<OrderGuanlianDO>().eq(OrderGuanlianDO::getRelateOrderId, relateOrderId));
        if (CollectionUtil.isNotEmpty(orderGuanlianDOList)) {
            for (OrderGuanlianDO orderGuanlianDO : orderGuanlianDOList) {
                OrderDO orderDO = orderService.getById(orderGuanlianDO.getOrderId());
                if (Objects.nonNull(orderDO) && !orderDOList.contains(orderDO)) {
                    // 此订单不为空，且参数订单列表中不包含此订单，则添加此订单到上级订单列表，然后查询此订单的上级
                    orderDOList.add(orderDO);
                    getGuanlianOrderByRelateOrderId(orderDO.getOrderId(), orderDOList);
                }
            }
        }
        // 向下搜索
        List<OrderGuanlianDO> subordinateOrderGuanlianDOList = guanlianMapper.selectList(new LambdaQueryWrapper<OrderGuanlianDO>().eq(OrderGuanlianDO::getOrderId, relateOrderId));
        if (CollectionUtil.isNotEmpty(subordinateOrderGuanlianDOList)) {
            for (OrderGuanlianDO orderGuanlianDO : subordinateOrderGuanlianDOList) {
                OrderDO orderDO = orderService.getById(orderGuanlianDO.getRelateOrderId());
                if (Objects.nonNull(orderDO) && !orderDOList.contains(orderDO)) {
                    // 此订单不为空，且参数订单列表中不包含此订单，则添加此订单到上级订单列表，然后查询此订单的上级
                    orderDOList.add(orderDO);
                    getGuanlianOrderByRelateOrderId(orderDO.getOrderId(), orderDOList);
                }
            }
        }
    }

    @Override
    public List<OrderDO> guanlianOrderList(List<String> orderNumbers) {
        return guanlianMapper.guanlianOrderList(orderNumbers);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRelationByOrderId(Long orderId) {
        List<OrderGuanlianDO> orderGuanlianDOS = guanlianMapper.selectList(OrderGuanlianDO::getOrderId, orderId);
        if (CollectionUtil.isNotEmpty(orderGuanlianDOS)) {
            orderGuanlianDOS.stream().forEach(item -> {
                guanlianMapper.deleteById(item.getId());
                orderService.cancelGuanlianOrderStatus(item.getOrderId(), item.getRelateOrderId());
                orderService.cancelGuanlianOrderStatus(item.getRelateOrderId(), item.getOrderId());
                orderBusinessService.addOrderOperateLog(item.getOrderId(), "", "自动移出关联订单", "");
                orderBusinessService.addOrderOperateLog(item.getRelateOrderId(), "", "自动移出关联订单", "");
            });
        }
        List<OrderGuanlianDO> orderGuanlianDOS1 = guanlianMapper.selectList(OrderGuanlianDO::getRelateOrderId, orderId);
        if (CollectionUtil.isNotEmpty(orderGuanlianDOS1)) {
            orderGuanlianDOS1.stream().forEach(item -> {
                guanlianMapper.deleteById(item.getId());
                orderService.cancelGuanlianOrderStatus(item.getOrderId(), item.getRelateOrderId());
                orderService.cancelGuanlianOrderStatus(item.getRelateOrderId(), item.getOrderId());
                orderBusinessService.addOrderOperateLog(item.getOrderId(), "", "自动移出关联订单", "");
                orderBusinessService.addOrderOperateLog(item.getRelateOrderId(), "", "自动移出关联订单", "");
            });
        }
    }

    public static void main(String[] args) {
        List<OrderTree.OrderRelation> orderRelations = new ArrayList<>();
        orderRelations.add(new OrderTree.OrderRelation("1", "2"));
        orderRelations.add(new OrderTree.OrderRelation("2", "1"));
        orderRelations.add(new OrderTree.OrderRelation("2", "3"));
        orderRelations.add(new OrderTree.OrderRelation("4", "1"));
        orderRelations.add(new OrderTree.OrderRelation("4", "5"));

        OrderTree orderTree = OrderTree.buildTree(orderRelations, "1");
        System.out.println(orderTree);
    }
}
