package com.clx.performance.service.impl.settle;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.order.enums.InvoicingCompanyEnum;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.order.vo.pc.carrier.InvoicingCompanyVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.settle.SettlementDriverDetailDao;
import com.clx.performance.dao.settle.SettlementOwnerDetailDao;
import com.clx.performance.dto.excel.InvoiceData;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.settle.SettlementOwnerDetailEnum;
import com.clx.performance.enums.settle.SettlementOwnerEnum;
import com.clx.performance.enums.settle.SettlementWayEnum;
import com.clx.performance.extranal.order.InvoicingCompanyService;
import com.clx.performance.listener.excel.InvoiceDataListener;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.settle.SettlementDriverDetail;
import com.clx.performance.model.settle.SettlementOwnerDetail;
import com.clx.performance.param.pc.carrier.CarrierSettlementOwnerDetailCompanyUpdateParam;
import com.clx.performance.param.pc.carrier.ExportBatchOwnerSettlementDetailParam;
import com.clx.performance.param.pc.owner.PageCarrierSettlementOwnerDetailParam;
import com.clx.performance.param.pc.owner.PageInvoiceOwnerSettlementOwnerDetailParam;
import com.clx.performance.param.pc.owner.PageOwnerSettlementOwnerDetailParam;
import com.clx.performance.param.pc.owner.PagePendingCarrierSettlementOwnerDetailParam;
import com.clx.performance.service.broker.OrderChildBrokerMqService;
import com.clx.performance.service.settle.SettlementCommonService;
import com.clx.performance.service.settle.SettlementOwnerDetailService;
import com.clx.performance.service.settle.SettlementPostService;
import com.clx.performance.struct.settle.SettlementOwnerDetailStruct;
import com.clx.performance.utils.excel.ExcelData;
import com.clx.performance.utils.excel.ExcelField;
import com.clx.performance.utils.excel.ExcelSheet;
import com.clx.performance.utils.excel.ExcelUtil;
import com.clx.performance.vo.pc.carrier.settle.CarrierPagePendingSettlementOwnerDetailVO;
import com.clx.performance.vo.pc.carrier.settle.CarrierPageSettlementOwnerDetailVO;
import com.clx.performance.vo.pc.owner.settle.CountOwnerSettlementOwnerDetailVO;
import com.clx.performance.vo.pc.owner.settle.PageOwnerSettlementOwnerDetailVO;
import com.clx.performance.vo.pc.owner.settle.UploadBatchInvoiceFileResultVO;
import com.msl.common.exception.ServiceSystemException;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.msl.common.result.Result;
import com.msl.document.api.feign.FileUploadFeign;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import static com.clx.performance.enums.PerformanceResultEnum.DATA_NOT_FIND;


/**
 * @author liruixin
 * Date 2023-10-12
 * Time 09:43
 */
@Service
@Slf4j
public class SettlementOwnerDetailServiceImpl  implements SettlementOwnerDetailService {

    @Autowired
    private SettlementOwnerDetailDao settlementOwnerDetailDao;

    @Autowired
    private SettlementOwnerDetailStruct settlementOwnerDetailStruct;

    @Autowired
    private OrderChildDao orderChildDao;

    @Autowired
    private SettlementDriverDetailDao settlementDriverDetailDao;

    @Autowired
    private SettlementCommonService settlementCommonService;

    @Autowired
    private SettlementPostService settlementPostService;

    @Autowired
    private OrderChildBrokerMqService orderChildBrokerMqService;
    @Autowired
    private FileUploadFeign fileUploadFeign;

    @Autowired
    private InvoicingCompanyService invoicingCompanyService;
    @Autowired
    private OrderFeign orderFeign;

    @Override
    public Integer saveSettlementDetail(OrderChild orderChild, OrderGoods orderGoods, SettlementDriverDetail settlementDriverDetail) {

        SettlementOwnerDetail settlementOwnerDetail = new SettlementOwnerDetail();
        //设置结算方式
        settlementOwnerDetail.setSettlementWay(orderGoods.getSettlementWay());
        settlementOwnerDetail.setChildNo(orderChild.getChildNo());
        settlementOwnerDetail.setOrderGoodsNo(orderChild.getOrderGoodsNo());
        settlementOwnerDetail.setOrderNo(orderChild.getOrderNo());

        settlementOwnerDetail.setOwnerUserNo(orderChild.getOwnerUserNo());
        settlementOwnerDetail.setOwnerName(orderChild.getOwnerName());

        settlementOwnerDetail.setSendAddressId(orderChild.getSendAddressId());
        settlementOwnerDetail.setSendAddress(orderChild.getSendAddress());
        settlementOwnerDetail.setReceiveAddressId(orderChild.getReceiveAddressId());
        settlementOwnerDetail.setReceiveAddress(orderChild.getReceiveAddress());

        settlementOwnerDetail.setGoodsId(orderChild.getGoodsId());
        settlementOwnerDetail.setGoodsName(orderChild.getGoodsName());

        // 运费
        settlementOwnerDetail.setFreightPrice(orderChild.getOrderFreightPrice());     //平台运费
        settlementOwnerDetail.setWeight(weightCalc(orderGoods.getSettlementWay(),orderChild.getLoadNet(), orderChild.getUnloadNet()));
        settlementOwnerDetail.setFreight(freightCalc(settlementOwnerDetail.getFreightPrice(), settlementOwnerDetail.getWeight()));
        settlementOwnerDetail.setDriverFreight(settlementDriverDetail.getSettlementFreight());

        settlementOwnerDetail.setLoadRough(orderChild.getLoadRough());
        settlementOwnerDetail.setLoadTare(orderChild.getLoadTare());
        settlementOwnerDetail.setLoadNet(orderChild.getLoadNet());
        settlementOwnerDetail.setUnloadRough(orderChild.getUnloadRough());
        settlementOwnerDetail.setUnloadTare(orderChild.getUnloadTare());
        settlementOwnerDetail.setUnloadNet(orderChild.getUnloadNet());

        // 亏吨
        settlementOwnerDetail.setLossPrice(orderChild.getLossPrice());
        settlementOwnerDetail.setLossWeight(lossWeightCalc(orderChild.getLoadNet(), orderChild.getUnloadNet()));
        settlementOwnerDetail.setLossFreight(lossFreightCalc(settlementOwnerDetail.getLossPrice(), settlementOwnerDetail.getLossWeight()));

        // 预付运费
        settlementOwnerDetail.setPrepayFreight(BigDecimal.ZERO);

        //借款抵扣金额初始化
        settlementOwnerDetail.setLoanFreight(BigDecimal.ZERO);

        // 开票配置
        Integer invoiceConfigType = invoicingCompanyService.getInvoicingConfigTypeByOrderNo(orderChild.getOrderNo());
        settlementOwnerDetail.setInvoiceConfigType(invoiceConfigType);

        // 开票服务率
        settlementOwnerDetail.setInvoiceServiceFeeRate(BigDecimal.ZERO);

        if (orderChild.getInvoicingCompanyId() != null) {
            FeignOrderVO feignOrderVO = orderFeign.getOrderInfoFeign(orderChild.getOrderNo());
            if (Objects.equals(feignOrderVO.getPlatformFreightQuotationTaxType(),
                    InvoicingCompanyEnum.TaxType.TAX_EXCLUDED.getCode())) {

                if (Objects.equals(settlementOwnerDetail.getInvoiceConfigType(), InvoicingCompanyEnum.YesAndNo.YES.getCode())) {

                    //设置开票公司信息
                    settlementOwnerDetail.setInvoicingCompanyId(orderChild.getInvoicingCompanyId());
                    settlementOwnerDetail.setInvoicingCompanyShorterName(orderChild.getInvoicingCompanyShorterName());
                    settlementOwnerDetail.setInvoicingCompanyGroupCode(orderChild.getInvoicingCompanyGroupCode());

                    // 查询开票公司
                    InvoicingCompanyVO invoiceCompany = invoicingCompanyService.getInvoicingCompany(
                            settlementOwnerDetail.getInvoicingCompanyId()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

                    settlementOwnerDetail.setInvoiceServiceFeeRate(
                            invoiceCompany.getServiceFeeRate() == null ? BigDecimal.ZERO : invoiceCompany.getServiceFeeRate());
                }
            }
        }

        // 开票服务费
        settlementOwnerDetail.setInvoiceServiceFee(
                settlementCommonService.invoiceServiceFeeCalc(orderChild.getSettlementWay(), settlementOwnerDetail));
        // 开票金额
        settlementOwnerDetail.setInvoiceFreight(
                settlementCommonService.invoiceFreightCalc(orderChild.getSettlementWay(),
                orderGoods.getInvoiceServiceFeeRate(), settlementOwnerDetail));

        // 结算金额
        settlementOwnerDetail.setSettlementFreight(
                settlementCommonService.settlementFreightCalc(orderGoods.getSettlementWay(),settlementOwnerDetail));

        settlementOwnerDetail.setFinalPaymentStatus(SettlementOwnerDetailEnum.FinalPaymentStatus.NO.getCode());

        settlementOwnerDetail.setReportFlag(orderChild.getReportFlag());

        settlementOwnerDetail.setInvoiceChannel(SettlementOwnerDetailEnum.InvoiceChannel.BROKER.getCode());

        settlementOwnerDetail.setPoundAuditTime(LocalDateTime.now());

        settlementOwnerDetailDao.saveEntity(settlementOwnerDetail);
        return settlementOwnerDetail.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateInvoiceCompany(CarrierSettlementOwnerDetailCompanyUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        List<SettlementOwnerDetail> list = settlementOwnerDetailDao.findListByIdList(param.getIdList());
        for (SettlementOwnerDetail item : list) {
            if (item.getInvoicingCompanyId() != null) {
                throw new ServiceSystemException(PerformanceResultEnum.SETTLEMENT_OWNER_DETAIL_COMPANY_ADD_ERROR);
            }
        }

        settlementOwnerDetailDao.updateInvoiceCompany(param.getIdList(), param.getCompanyId(),
                param.getCompanyShorterName(), param.getCompanyGroupCode(),
                loginUserInfo.getUserName(), LocalDateTime.now());

        // 更新开票公司
        settlementPostService.updateInvoiceCompany(list);
    }

    /**
     * 吨数计算
     */
    private BigDecimal weightCalc(Integer settlementWay,BigDecimal loadNet, BigDecimal unLoadNet){
        if(Objects.equals(settlementWay, SettlementWayEnum.WayType.LOAD.getCode())){ //如果该货主的结算方式为“装车净重”时，那么实际净重=装车净重。
            return loadNet;
        }else{ //如果货主的结算方式为“卸车净重”时，那么实际净重=卸车净重。如果卸车净重>装车净重，那么卸车净重=装车净重。
            return unLoadNet.compareTo(loadNet) > 0? loadNet : unLoadNet;
        }
    }

    /**
     *  运费计算
     */
    public BigDecimal freightCalc(BigDecimal freightPrice, BigDecimal weight){

        return freightPrice.multiply(weight).setScale(0, RoundingMode.HALF_UP);
    }

    /**
     * 亏吨计算
     */
    private BigDecimal lossWeightCalc(BigDecimal loadNet, BigDecimal unLoadNet){
        return unLoadNet.compareTo(loadNet) < 0? loadNet.subtract(unLoadNet) : BigDecimal.ZERO;
    }

    /**
     * 亏吨运费
     */
    private BigDecimal lossFreightCalc(BigDecimal freightPrice, BigDecimal weight){
        return freightPrice.multiply(weight).setScale(0, RoundingMode.HALF_UP);

    }

    @Override
    public IPage<CarrierPageSettlementOwnerDetailVO> pageSettlementOwnerDetail(
            PageCarrierSettlementOwnerDetailParam param) {
        IPage<SettlementOwnerDetail> result = settlementOwnerDetailDao.pageSettlementOwnerDetail(param);
        List<CarrierPageSettlementOwnerDetailVO> list = settlementOwnerDetailStruct.covertList(result.getRecords());
        return new Page<CarrierPageSettlementOwnerDetailVO>().setRecords(list).setTotal(result.getTotal()).setPages(result.getPages());
    }

    @Override
    public IPage<PageOwnerSettlementOwnerDetailVO> pageOwnerSettlementOrderDetailList(PageOwnerSettlementOwnerDetailParam param) {
        IPage<SettlementOwnerDetail> settlementOwnerDetail = settlementOwnerDetailDao.pageOwnerSettlementOrderDetailList(param);
        List<PageOwnerSettlementOwnerDetailVO> list = settlementOwnerDetailStruct.covertToOwnerList(settlementOwnerDetail.getRecords());
        return new Page<PageOwnerSettlementOwnerDetailVO>().setRecords(list).setTotal(settlementOwnerDetail.getTotal()).setPages(settlementOwnerDetail.getPages());

    }

    @Override
    public IPage<PageOwnerSettlementOwnerDetailVO> pageInvoiceOwnerSettlementOrderDetailList(PageInvoiceOwnerSettlementOwnerDetailParam param) {
        IPage<SettlementOwnerDetail> settlementOwnerDetail = settlementOwnerDetailDao.pageInvoiceOwnerSettlementOrderDetailList(param);
        List<PageOwnerSettlementOwnerDetailVO> list = settlementOwnerDetailStruct.covertToOwnerList(settlementOwnerDetail.getRecords());
        return new Page<PageOwnerSettlementOwnerDetailVO>().setRecords(list).setTotal(settlementOwnerDetail.getTotal()).setPages(settlementOwnerDetail.getPages());

    }

    @Override
    public CountOwnerSettlementOwnerDetailVO countInvoiceOwnerSettlementOrderDetailList(PageInvoiceOwnerSettlementOwnerDetailParam param) {
        param.setPage(1);
        param.setPageSize(1000000);
        IPage<SettlementOwnerDetail> page = settlementOwnerDetailDao.pageInvoiceOwnerSettlementOrderDetailList(param);
        CountOwnerSettlementOwnerDetailVO vo = new CountOwnerSettlementOwnerDetailVO();
        vo.setOrderChildSum(page.getTotal());
        vo.setLoadNetSum(page.getRecords().stream().map(SettlementOwnerDetail::getLoadNet).filter(Objects::nonNull).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setInvoiceFreightSum(page.getRecords().stream().map(SettlementOwnerDetail::getInvoiceFreight).filter(Objects::nonNull).reduce(BigDecimal.ZERO,BigDecimal::add).movePointLeft(2));
        return vo;
    }

    @Override
    public SXSSFWorkbook exportOwnerSettlementOrderDetail(PageOwnerSettlementOwnerDetailParam param) {
        param.setPage(1);
        param.setPageSize(1000000);
        IPage<PageOwnerSettlementOwnerDetailVO> settlementOwnerDetail = pageOwnerSettlementOrderDetailList(param);

        List<PageOwnerSettlementOwnerDetailVO> list = settlementOwnerDetail.getRecords();

        // 组装表头
        List<ExcelField> fieldList = new ArrayList<>();
        fieldList.add(new ExcelField(0, "序号", "index", 2000));
        fieldList.add(new ExcelField(1, "运单编号", "childNo", 5000));
        fieldList.add(new ExcelField(2, "货主编码", "ownerUserNno", 5000));
        fieldList.add(new ExcelField(3, "结算方式", "settlementWay", 5000));
        fieldList.add(new ExcelField(4, "货物名称", "goodsName", 5000));
        fieldList.add(new ExcelField(5, "装车皮重（吨）", "loadTare", 5000));
        fieldList.add(new ExcelField(6, "装车毛重（吨）", "loadRough", 5000));
        fieldList.add(new ExcelField(7, "装车净重（吨）", "loadNet", 5000));
        fieldList.add(new ExcelField(8, "卸车毛重（吨）", "unloadRough", 5000));
        fieldList.add(new ExcelField(9, "卸车皮重（吨）", "unloadTare", 5000));
        fieldList.add(new ExcelField(10, "卸车净重（吨）", "unloadNet", 5000));
        fieldList.add(new ExcelField(11, "实际净重（吨）", "weight", 5000));
        fieldList.add(new ExcelField(12, "平台运费报价", "freightPrice", 5000));
        fieldList.add(new ExcelField(13, "应付运费", "freight", 5000));
        fieldList.add(new ExcelField(14, "货损吨数", "lossWeight", 5000));
        fieldList.add(new ExcelField(15, "货损单价", "lossPrice", 5000));
        fieldList.add(new ExcelField(16, "货损金额", "lossFreight", 5000));
        fieldList.add(new ExcelField(17, "司机实收", "driverActualIncome", 5000));
        fieldList.add(new ExcelField(18, "管理费率（%）", "invoiceServiceFeeRate", 5000));
        fieldList.add(new ExcelField(19, "管理费", "invoiceServiceFee", 5000));
        fieldList.add(new ExcelField(20, "预付运费金额", "prepayFreight", 5000));
        fieldList.add(new ExcelField(21, "借款抵扣金额", "loanFreight", 5000));
        fieldList.add(new ExcelField(22, "结算金额", "settlementFreight", 5000));

        fieldList.add(new ExcelField(23, "开票金额", "invoiceFreight", 5000));
        fieldList.add(new ExcelField(24, "开票公司", "invoicingCompanyShorterName", 5000));
        fieldList.add(new ExcelField(25, "开票标识", "invoiceType", 5000));
        fieldList.add(new ExcelField(26, "订单编号", "orderNo", 5000));
        fieldList.add(new ExcelField(27, "结算单号", "settlementNo", 15000));
        fieldList.add(new ExcelField(28, "结算子单号", "settlementSubNo", 15000));
        fieldList.add(new ExcelField(29, "创建时间", "createTime", 5000));
        fieldList.add(new ExcelField(30, "是否已付尾款", "finalPaymentStatus", 5000));
        fieldList.add(new ExcelField(31, "是否已开票", "invoiceStatus", 5000));
        fieldList.add(new ExcelField(32, "备注", "remark", 5000));

        // 组装数据
        List<List<ExcelData>> dataList = new ArrayList<>();
        for (int i=0; i<list.size(); i++){

            PageOwnerSettlementOwnerDetailVO dto = list.get(i);
            List<ExcelData> rowData = new ArrayList<>();

            Optional<SettlementWayEnum.WayType> byCode = SettlementWayEnum.WayType.getByCode(dto.getSettlementWay());
            String settlementWay = byCode.isPresent()?byCode.get().getMsg():"";
            rowData.add(new ExcelData(i+1));
            rowData.add(new ExcelData(dto.getChildNo()));
            rowData.add(new ExcelData(dto.getOwnerUserNo()+""));
            rowData.add(new ExcelData(settlementWay));
            rowData.add(new ExcelData(dto.getGoodsName()));
            rowData.add(new ExcelData(dto.getLoadTare()));
            rowData.add(new ExcelData(dto.getLoadRough()));
            rowData.add(new ExcelData(dto.getLoadNet()));
            rowData.add(new ExcelData(dto.getUnloadRough()));
            rowData.add(new ExcelData(dto.getUnloadTare()));
            rowData.add(new ExcelData(dto.getUnloadNet()));
            rowData.add(new ExcelData(dto.getWeight()));
            rowData.add(new ExcelData(dto.getFreightPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossWeight()));
            rowData.add(new ExcelData(dto.getLossPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getDriverFreight()==null?null:dto.getDriverFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceServiceFeeRate().toString()+ "%"));
            rowData.add(new ExcelData(dto.getInvoiceServiceFee().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getPrepayFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLoanFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getSettlementFreight().movePointLeft(2)));

            rowData.add(new ExcelData(dto.getInvoiceFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoicingCompanyShorterName()));
            rowData.add(new ExcelData(dto.getInvoiceTypeMsg()));
            rowData.add(new ExcelData(dto.getOrderNo()));
            rowData.add(new ExcelData(dto.getSettlementNo()));
            rowData.add(new ExcelData(dto.getSettlementSubNo()));
            rowData.add(new ExcelData(dto.getCreateTime()));
            rowData.add(new ExcelData(dto.getFinalPaymentStatusMsg()));
            rowData.add(new ExcelData(dto.getInvoiceStatusMsg()));
            rowData.add(new ExcelData(dto.getRemark()));
            dataList.add(rowData);
        }

        ExcelSheet excelSheet = new ExcelSheet("货主结算运单明细", "货主结算运单明细", fieldList, dataList);

        //创建excel
        return ExcelUtil.create(excelSheet);
    }

    @Override
    public Integer getInvoiceType(String orderNo) {
        return settlementOwnerDetailDao.getInvoiceType(orderNo);
    }

    @Override
    public Boolean thawAndLockSettlement(String orderNo) {
        boolean orderChildrenFlag = false;
        boolean ownerDetailsFlag = false;
        boolean loanFlag = false;

        List<OrderChild> orderChildren = orderChildDao.selectInTransitOrderChildLtUnsettle(orderNo);

        if (CollectionUtil.isNotEmpty(orderChildren)) {
            log.info("当前订单{},存在在途运单,不予锁定", orderNo);
            orderChildrenFlag = true;
        } else {
            List<SettlementOwnerDetail> ownerDetails = settlementOwnerDetailDao.selectListByOrderNo(orderNo);
            if (CollectionUtil.isNotEmpty(ownerDetails)) {
                log.info("当前订单{},存在结算单编号是null的货主计费,不予锁定", orderNo);

                ownerDetailsFlag = true;
            } else {
                //开票标识“网运单”，预付标识“未预付”，借款标识”未借款“的车主计费，如存在不允许锁定
                SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao.selectLoanFlag(orderNo);
                if (settlementDriverDetail != null) {
                    log.info("当前订单{},开票标识“网运单”，预付标识“未预付”，借款标识”未借款“的车主计费,不予锁定", orderNo);
                    loanFlag = true;
                } else {
                    //开票标识“网运单”，预付标识“未预付”，借款类型“虚拟货币”，借款标识”已借款“的车主计费，如存在不允许锁定
                    settlementDriverDetail = settlementDriverDetailDao.selectLoanTypeFlag(orderNo);
                    if (settlementDriverDetail != null) {
                        log.info("当前订单{},开票标识“网运单”，预付标识“未预付”，借款标识”未借款“的车主计费,不予锁定", orderNo);
                        loanFlag = true;
                    }
                }

            }
        }

        if (ownerDetailsFlag || orderChildrenFlag || loanFlag) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public IPage<CarrierPagePendingSettlementOwnerDetailVO> pagePendingSettlementOwnerDetail(PagePendingCarrierSettlementOwnerDetailParam param) {
        IPage<SettlementOwnerDetail> result = settlementOwnerDetailDao.pagePendingSettlementOwnerDetail(param);
        List<CarrierPagePendingSettlementOwnerDetailVO> list = settlementOwnerDetailStruct.covertPendingList(result.getRecords());
        list.forEach(vo->{
            vo.setHandleStatus(Objects.isNull(vo.getInvoicingCompanyId())? SettlementOwnerDetailEnum.HandleStatus.NO.getCode(): SettlementOwnerDetailEnum.HandleStatus.YES.getCode());
        });
        return new Page<CarrierPagePendingSettlementOwnerDetailVO>().setRecords(list).setTotal(result.getTotal()).setPages(result.getPages());
    }

    @Override
    public SXSSFWorkbook exportPendingSettlementOwnerDetail(PagePendingCarrierSettlementOwnerDetailParam param) {
        param.setPage(1);
        param.setPageSize(1000000);
        IPage<CarrierPagePendingSettlementOwnerDetailVO> settlementOwnerDetailPage = pagePendingSettlementOwnerDetail(param);

        List<CarrierPagePendingSettlementOwnerDetailVO> list = settlementOwnerDetailPage.getRecords();

        // 组装表头
        List<ExcelField> fieldList = new ArrayList<>();
        fieldList.add(new ExcelField(0, "运单编号", "childNo", 5000));
        fieldList.add(new ExcelField(1, "公司编码", "ownerUserNo", 5000));
        fieldList.add(new ExcelField(2, "公司名称", "ownerName", 5000));
        fieldList.add(new ExcelField(3, "结算方式", "settlementWay", 5000));
        fieldList.add(new ExcelField(4, "货物名称", "goodsName", 5000));
        fieldList.add(new ExcelField(5, "实际净重（吨）", "weight", 5000));
        fieldList.add(new ExcelField(6, "平台运费报价", "freightPrice", 5000));
        fieldList.add(new ExcelField(7, "应付运费", "freight", 5000));
        fieldList.add(new ExcelField(8, "货损吨数", "lossWeight", 5000));
        fieldList.add(new ExcelField(9, "货损单价", "lossPrice", 5000));
        fieldList.add(new ExcelField(10, "货损金额", "lossFreight", 5000));
        fieldList.add(new ExcelField(11, "管理费率（%）", "invoiceServiceFeeRate", 5000));
        fieldList.add(new ExcelField(12, "管理费", "invoiceServiceFee", 5000));
        fieldList.add(new ExcelField(13, "预付运费金额", "prepayFreight", 5000));
        fieldList.add(new ExcelField(14, "借款抵扣金额", "loanFreight", 5000));

        fieldList.add(new ExcelField(15, "结算金额", "settlementFreight", 5000));
        fieldList.add(new ExcelField(16, "开票金额", "invoiceFreight", 5000));
        fieldList.add(new ExcelField(17, "开票标识", "invoiceType", 5000));
        fieldList.add(new ExcelField(18, "开票公司", "invoicingCompanyShorterName", 5000));
        fieldList.add(new ExcelField(19, "状态", "handleStatus", 5000));

        fieldList.add(new ExcelField(20, "订单编号", "orderNo", 5000));
        fieldList.add(new ExcelField(21, "结算单号", "settlementNo", 5000));
        fieldList.add(new ExcelField(22, "磅单审核通过时间", "poundAuditTime", 5000));
        fieldList.add(new ExcelField(23, "创建时间", "createTime", 5000));
        fieldList.add(new ExcelField(24, "操作人", "invoicingCompanyModifiedBy", 5000));

        fieldList.add(new ExcelField(25, "操作时间", "invoicingCompanyModifiedTime", 5000));

        // 组装数据
        List<List<ExcelData>> dataList = new ArrayList<>();
        for (CarrierPagePendingSettlementOwnerDetailVO dto : list) {

            List<ExcelData> rowData = new ArrayList<>();

            rowData.add(new ExcelData(dto.getChildNo()));
            rowData.add(new ExcelData(dto.getOwnerUserNo()+""));
            rowData.add(new ExcelData(dto.getOwnerName()));
            rowData.add(new ExcelData(SettlementWayEnum.WayType.getMsgByCode(dto.getSettlementWay())));

            rowData.add(new ExcelData(dto.getGoodsName()));
            rowData.add(new ExcelData(dto.getWeight()));
            rowData.add(new ExcelData(dto.getFreightPrice()==null?null:dto.getFreightPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getFreight()==null?null:dto.getFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossWeight()));
            rowData.add(new ExcelData(dto.getLossPrice()==null?null:dto.getLossPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossFreight()==null?null:dto.getLossFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceServiceFeeRate()));
            rowData.add(new ExcelData(dto.getInvoiceServiceFee()==null?null:dto.getInvoiceServiceFee().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getPrepayFreight()==null?null:dto.getPrepayFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLoanFreight()==null?null:dto.getLoanFreight().movePointLeft(2)));

            rowData.add(new ExcelData(dto.getSettlementFreight()==null?null:dto.getSettlementFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceFreight()==null?null:dto.getInvoiceFreight().movePointLeft(2)));
            rowData.add(new ExcelData(SettlementOwnerEnum.InvoiceType.getMsgByCode(dto.getInvoiceType())));
            rowData.add(new ExcelData(dto.getInvoicingCompanyShorterName(),"-"));
            rowData.add(new ExcelData(SettlementOwnerDetailEnum.HandleStatus.getMsgByCode(dto.getHandleStatus())));

            rowData.add(new ExcelData(dto.getOrderNo()));
            rowData.add(new ExcelData(dto.getSettlementNo()));
            rowData.add(new ExcelData(dto.getPoundAuditTime()));
            rowData.add(new ExcelData(dto.getCreateTime()));
            rowData.add(new ExcelData(dto.getInvoicingCompanyModifiedBy()));
            rowData.add(new ExcelData(dto.getInvoicingCompanyModifiedTime()));

            dataList.add(rowData);
        }

        ExcelSheet excelSheet = new ExcelSheet("货主运单计费-待处理", "货主运单计费-待处理", fieldList, dataList);

        //创建excel
        return ExcelUtil.create(excelSheet);
    }

    @Override
    public SXSSFWorkbook exportSettlementOwnerDetail(PageCarrierSettlementOwnerDetailParam param) {
        param.setPage(1);
        param.setPageSize(1000000);
        IPage<CarrierPageSettlementOwnerDetailVO> settlementOwnerDetailPage = pageSettlementOwnerDetail(param);

        List<CarrierPageSettlementOwnerDetailVO> list = settlementOwnerDetailPage.getRecords();

        // 组装表头
        List<ExcelField> fieldList = new ArrayList<>();
        fieldList.add(new ExcelField(0, "运单编号", "childNo", 5000));
        fieldList.add(new ExcelField(1, "公司编码", "ownerUserNo", 5000));
        fieldList.add(new ExcelField(2, "公司名称", "ownerName", 5000));
        fieldList.add(new ExcelField(3, "结算方式", "settlementWay", 5000));
        fieldList.add(new ExcelField(4, "货物名称", "goodsName", 5000));
        fieldList.add(new ExcelField(5, "实际净重（吨）", "weight", 5000));
        fieldList.add(new ExcelField(6, "平台运费报价", "freightPrice", 5000));
        fieldList.add(new ExcelField(7, "应付运费", "freight", 5000));
        fieldList.add(new ExcelField(8, "货损吨数", "lossWeight", 5000));
        fieldList.add(new ExcelField(9, "货损单价", "lossPrice", 5000));
        fieldList.add(new ExcelField(10, "货损金额", "lossFreight", 5000));
        fieldList.add(new ExcelField(11, "管理费率（%）", "invoiceServiceFeeRate", 5000));
        fieldList.add(new ExcelField(12, "管理费", "invoiceServiceFee", 5000));
        fieldList.add(new ExcelField(13, "预付运费金额", "prepayFreight", 5000));
        fieldList.add(new ExcelField(14, "借款抵扣金额", "loanFreight", 5000));
        fieldList.add(new ExcelField(15, "结算金额", "settlementFreight", 5000));
        fieldList.add(new ExcelField(16, "开票金额", "invoiceFreight", 5000));
        fieldList.add(new ExcelField(17, "开票公司", "invoicingCompanyShorterName", 5000));
        fieldList.add(new ExcelField(18, "开票标识", "invoiceType", 5000));
        fieldList.add(new ExcelField(19, "开票配置", "invoiceConfigType", 5000));
        fieldList.add(new ExcelField(20, "订单编号", "orderNo", 5000));
        fieldList.add(new ExcelField(21, "结算单号", "settlementNo", 5000));
        fieldList.add(new ExcelField(22, "创建时间", "createTime", 5000));

        // 组装数据
        List<List<ExcelData>> dataList = new ArrayList<>();
        for (CarrierPageSettlementOwnerDetailVO dto : list) {

            List<ExcelData> rowData = new ArrayList<>();

            rowData.add(new ExcelData(dto.getChildNo()));
            rowData.add(new ExcelData(dto.getOwnerUserNo()+""));
            rowData.add(new ExcelData(dto.getOwnerName()));
            rowData.add(new ExcelData(dto.getSettlementWay()==null?null:SettlementWayEnum.WayType.getMsgByCode(dto.getSettlementWay())));

            rowData.add(new ExcelData(dto.getGoodsName()));
            rowData.add(new ExcelData(dto.getWeight()));
            rowData.add(new ExcelData(dto.getFreightPrice()==null?null:dto.getFreightPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getFreight()==null?null:dto.getFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossWeight()));
            rowData.add(new ExcelData(dto.getLossPrice()==null?null:dto.getLossPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossFreight()==null?null:dto.getLossFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceServiceFeeRate()));
            rowData.add(new ExcelData(dto.getInvoiceServiceFee()==null?null:dto.getInvoiceServiceFee().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getPrepayFreight()==null?null:dto.getPrepayFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLoanFreight()==null?null:dto.getLoanFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getSettlementFreight()==null?null:dto.getSettlementFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceFreight()==null?null:dto.getInvoiceFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoicingCompanyShorterName()));
            rowData.add(new ExcelData(dto.getInvoiceType()==null?null:SettlementOwnerEnum.InvoiceType.getMsgByCode(dto.getInvoiceType())));
            rowData.add(new ExcelData(dto.getInvoiceConfigType()==null?null:SettlementOwnerEnum.InvoiceConfigType.getMsgByCode(dto.getInvoiceConfigType())));
            rowData.add(new ExcelData(dto.getOrderNo()));
            rowData.add(new ExcelData(dto.getSettlementNo()));
            rowData.add(new ExcelData(dto.getCreateTime()));

            dataList.add(rowData);
        }

        ExcelSheet excelSheet = new ExcelSheet("货主运单计费", "货主运单计费", fieldList, dataList);

        //创建excel
        return ExcelUtil.create(excelSheet);
    }

    @Override
    public SXSSFWorkbook exportBatchSettlementOwnerDetail(ExportBatchOwnerSettlementDetailParam param) {
        //通过结算单号查询结算运单明细
        List<SettlementOwnerDetail> settlementOwnerDetails = settlementOwnerDetailDao.listSettlementOwnerDetailBySettlementNos(param);
        //对象转化
        List<PageOwnerSettlementOwnerDetailVO> pageOwnerSettlementOwnerDetailVOS = settlementOwnerDetailStruct.covertToOwnerList(settlementOwnerDetails);
        // 组装表头
        List<ExcelField> fieldList = new ArrayList<>();
        fieldList.add(new ExcelField(0, "序号", "index", 2000));
        fieldList.add(new ExcelField(1, "运单编号", "childNo", 5000));
        fieldList.add(new ExcelField(2, "货主编码", "ownerUserNno", 5000));
        fieldList.add(new ExcelField(3, "结算方式", "settlementWay", 5000));
        fieldList.add(new ExcelField(4, "货物名称", "goodsName", 5000));
        fieldList.add(new ExcelField(5, "装车皮重（吨）", "loadTare", 5000));
        fieldList.add(new ExcelField(6, "装车毛重（吨）", "loadRough", 5000));
        fieldList.add(new ExcelField(7, "装车净重（吨）", "loadNet", 5000));
        fieldList.add(new ExcelField(8, "卸车毛重（吨）", "unloadRough", 5000));
        fieldList.add(new ExcelField(9, "卸车皮重（吨）", "unloadTare", 5000));
        fieldList.add(new ExcelField(10, "卸车净重（吨）", "unloadNet", 5000));

        fieldList.add(new ExcelField(11, "实际净重（吨）", "weight", 5000));
        fieldList.add(new ExcelField(12, "平台运费报价", "freightPrice", 5000));
        fieldList.add(new ExcelField(13, "应付运费", "freight", 5000));
        fieldList.add(new ExcelField(14, "货损吨数", "lossWeight", 5000));
        fieldList.add(new ExcelField(15, "货损单价", "lossPrice", 5000));
        fieldList.add(new ExcelField(16, "货损金额", "lossFreight", 5000));
        fieldList.add(new ExcelField(17, "司机实收", "driverActualIncome", 5000));
        fieldList.add(new ExcelField(18, "管理费率（%）", "invoiceServiceFeeRate", 5000));
        fieldList.add(new ExcelField(19, "管理费", "invoiceServiceFee", 5000));
        fieldList.add(new ExcelField(20, "预付运费金额", "prepayFreight", 5000));
        fieldList.add(new ExcelField(21, "借款抵扣金额", "loanFreight", 5000));
        fieldList.add(new ExcelField(22, "结算金额", "settlementFreight", 5000));

        fieldList.add(new ExcelField(23, "开票金额", "invoiceFreight", 5000));
        fieldList.add(new ExcelField(24, "开票公司", "invoicingCompanyShorterName", 5000));
        fieldList.add(new ExcelField(25, "开票标识", "invoiceType", 5000));
        fieldList.add(new ExcelField(26, "订单编号", "orderNo", 5000));
        fieldList.add(new ExcelField(27, "结算单号", "settlementNo", 15000));
        fieldList.add(new ExcelField(28, "结算子单号", "settlementSubNo", 15000));
        fieldList.add(new ExcelField(29, "创建时间", "createTime", 5000));
        fieldList.add(new ExcelField(30, "是否已付尾款", "finalPaymentStatus", 5000));
        fieldList.add(new ExcelField(31, "是否已开票", "invoiceStatus", 5000));
        fieldList.add(new ExcelField(32, "备注", "remark", 5000));

        // 组装数据
        List<List<ExcelData>> dataList = new ArrayList<>();
        for (int i=0; i<pageOwnerSettlementOwnerDetailVOS.size(); i++){

            PageOwnerSettlementOwnerDetailVO dto = pageOwnerSettlementOwnerDetailVOS.get(i);
            List<ExcelData> rowData = new ArrayList<>();

            Optional<SettlementWayEnum.WayType> byCode = SettlementWayEnum.WayType.getByCode(dto.getSettlementWay());
            String settlementWay = byCode.isPresent()?byCode.get().getMsg():"";
            rowData.add(new ExcelData(i+1));
            rowData.add(new ExcelData(dto.getChildNo()));
            rowData.add(new ExcelData(dto.getOwnerUserNo()+""));
            rowData.add(new ExcelData(settlementWay));
            rowData.add(new ExcelData(dto.getGoodsName()));
            rowData.add(new ExcelData(dto.getLoadTare()));
            rowData.add(new ExcelData(dto.getLoadRough()));
            rowData.add(new ExcelData(dto.getLoadNet()));
            rowData.add(new ExcelData(dto.getUnloadRough()));
            rowData.add(new ExcelData(dto.getUnloadTare()));
            rowData.add(new ExcelData(dto.getUnloadNet()));
            rowData.add(new ExcelData(dto.getWeight()));
            rowData.add(new ExcelData(dto.getFreightPrice()==null?null:dto.getFreightPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getFreight()==null?null:dto.getFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossWeight()));
            rowData.add(new ExcelData(dto.getLossPrice()==null?null:dto.getLossPrice().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLossFreight()==null?null:dto.getLossFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getDriverFreight()==null?null:dto.getDriverFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoiceServiceFeeRate().toString()+ "%"));
            rowData.add(new ExcelData(dto.getInvoiceServiceFee()==null?null:dto.getInvoiceServiceFee().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getPrepayFreight()==null?null:dto.getPrepayFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getLoanFreight()==null?null:dto.getLoanFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getSettlementFreight()==null?null:dto.getSettlementFreight().movePointLeft(2)));

            rowData.add(new ExcelData(dto.getInvoiceFreight()==null?null:dto.getInvoiceFreight().movePointLeft(2)));
            rowData.add(new ExcelData(dto.getInvoicingCompanyShorterName()));
            rowData.add(new ExcelData(dto.getInvoiceTypeMsg()));
            rowData.add(new ExcelData(dto.getOrderNo()));
            rowData.add(new ExcelData(dto.getSettlementNo()));
            rowData.add(new ExcelData(dto.getSettlementSubNo()));
            rowData.add(new ExcelData(dto.getCreateTime()));
            rowData.add(new ExcelData(dto.getFinalPaymentStatusMsg()));
            rowData.add(new ExcelData(dto.getInvoiceStatusMsg()));
            rowData.add(new ExcelData(dto.getRemark()));
            dataList.add(rowData);
        }

        ExcelSheet excelSheet = new ExcelSheet("货主结算运单明细", "货主结算运单明细", fieldList, dataList);

        //创建excel
        return ExcelUtil.create(excelSheet);
    }

    @Override
    public SXSSFWorkbook exportInvoiceOwnerSettlementOrderDetail(PageInvoiceOwnerSettlementOwnerDetailParam param) {
        param.setPage(1);
        param.setPageSize(1000000);
        IPage<PageOwnerSettlementOwnerDetailVO> settlementOwnerDetailPage = pageInvoiceOwnerSettlementOrderDetailList(param);

        List<PageOwnerSettlementOwnerDetailVO> list = settlementOwnerDetailPage.getRecords();

        // 组装表头
        List<ExcelField> fieldList = new ArrayList<>();
        fieldList.add(new ExcelField(0, "运单编号", "childNo", 5000));
        fieldList.add(new ExcelField(1, "公司名称", "ownerName", 15000));
        fieldList.add(new ExcelField(2, "结算方式", "settlementWayMsg", 5000));
        fieldList.add(new ExcelField(3, "开票公司", "invoicingCompanyShorterName", 5000));
        fieldList.add(new ExcelField(4, "开票标识", "invoiceTypeMsg", 5000));
        fieldList.add(new ExcelField(5, "货物名称", "goodsName", 5000));
        fieldList.add(new ExcelField(6, "装车净重（吨）", "loadNet", 5000));
        fieldList.add(new ExcelField(7, "卸车净重（吨）", "unloadNet", 5000));
        fieldList.add(new ExcelField(8, "实际净重（吨）", "weight", 5000));
        fieldList.add(new ExcelField(9, "平台运费报价", "freightPrice", 5000));
        fieldList.add(new ExcelField(10, "应付运费", "freight", 5000));
        fieldList.add(new ExcelField(11, "货损吨数", "lossWeight", 5000));
        fieldList.add(new ExcelField(12, "货损单价", "lossPrice", 5000));
        fieldList.add(new ExcelField(13, "货损金额", "lossFreight", 5000));
        fieldList.add(new ExcelField(14, "管理费率（%）", "invoiceServiceFeeRate", 5000));
        fieldList.add(new ExcelField(15, "管理费", "invoiceServiceFee", 5000));
        fieldList.add(new ExcelField(16, "预付运费金额", "prepayFreight", 5000));
        fieldList.add(new ExcelField(17, "借款抵扣金额", "loanFreight", 5000));
        fieldList.add(new ExcelField(18, "结算金额", "settlementFreight", 5000));
        fieldList.add(new ExcelField(19, "开票金额", "invoiceFreight", 5000));
        fieldList.add(new ExcelField(20, "订单编号", "orderNo", 5000));
        fieldList.add(new ExcelField(21, "结算单号", "settlementNo", 5000));
        fieldList.add(new ExcelField(22, "创建时间", "createTime", 5000));
        fieldList.add(new ExcelField(23, "是否已付尾款", "finalPaymentStatusMsg", 5000));
        fieldList.add(new ExcelField(24, "是否已开票", "invoiceStatusMsg", 5000));
        if (param.getInvoiceStatus().equals(SettlementOwnerDetailEnum.InvoiceStatus.NO.getCode())) {
            fieldList.add(new ExcelField(25, "备注", "separateRemark", 5000));
        }else {
            fieldList.add(new ExcelField(25, "开票时间", "invoiceTime", 5000));
            fieldList.add(new ExcelField(26, "备注", "separateRemark", 5000));
        }

        // 组装数据
        List<List<ExcelData>> dataList = new ArrayList<>();
        for (PageOwnerSettlementOwnerDetailVO vo : list) {

            List<ExcelData> rowData = new ArrayList<>();

            rowData.add(new ExcelData(vo.getChildNo()));
            rowData.add(new ExcelData(vo.getOwnerName()));
            rowData.add(new ExcelData(vo.getSettlementWayMsg()));
            rowData.add(new ExcelData(vo.getInvoicingCompanyShorterName()));
            rowData.add(new ExcelData(vo.getInvoiceTypeMsg()));
            rowData.add(new ExcelData(vo.getGoodsName()));
            rowData.add(new ExcelData(vo.getLoadNet()));
            rowData.add(new ExcelData(vo.getUnloadNet()));
            rowData.add(new ExcelData(vo.getWeight()));
            rowData.add(new ExcelData(vo.getFreightPrice()==null?null:vo.getFreightPrice().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getFreight()==null?null:vo.getFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getLossWeight()));
            rowData.add(new ExcelData(vo.getLossPrice()==null?null:vo.getLossPrice().movePointLeft(2)));

            rowData.add(new ExcelData(vo.getLossFreight()==null?null:vo.getLossFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getInvoiceServiceFeeRate()));
            rowData.add(new ExcelData(vo.getInvoiceServiceFee()==null?null:vo.getInvoiceServiceFee().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getPrepayFreight()==null?null:vo.getPrepayFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getLoanFreight()==null?null:vo.getLoanFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getSettlementFreight()==null?null:vo.getSettlementFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getInvoiceFreight()==null?null:vo.getInvoiceFreight().movePointLeft(2)));
            rowData.add(new ExcelData(vo.getOrderNo()));
            rowData.add(new ExcelData(vo.getSettlementNo()));
            rowData.add(new ExcelData(vo.getCreateTime()));
            rowData.add(new ExcelData(vo.getFinalPaymentStatusMsg()));
            rowData.add(new ExcelData(vo.getInvoiceStatusMsg()));
            if (param.getInvoiceStatus().equals(SettlementOwnerDetailEnum.InvoiceStatus.NO.getCode())) {
                rowData.add(new ExcelData(vo.getSeparateRemark()));
            }else {
                rowData.add(new ExcelData(vo.getInvoiceTime()));
                rowData.add(new ExcelData(vo.getSeparateRemark()));
            }

            dataList.add(rowData);
        }

        String name = "已开票列表";
        if (param.getInvoiceStatus().equals(SettlementOwnerDetailEnum.InvoiceStatus.NO.getCode())) {
            name = "待开票列表";;
        }
        ExcelSheet excelSheet = new ExcelSheet(name, name, fieldList, dataList);

        //创建excel
        return ExcelUtil.create(excelSheet);
    }

    @Override
    public UploadBatchInvoiceFileResultVO uploadBatchInvoiceFile(MultipartFile file) throws IOException {
        List<InvoiceData> invoiceDataList = new ArrayList<>();
        // 解析上传的Excel文件
        EasyExcel.read(file.getInputStream(), InvoiceData.class, new InvoiceDataListener(invoiceDataList,settlementOwnerDetailDao)).sheet().doRead();

        if (invoiceDataList.isEmpty()) {
            throw new ServiceSystemException(DATA_NOT_FIND,"上传文件为空");
        }

        boolean verifyResult = invoiceDataList.stream().allMatch(item -> "校验通过".equals(item.getRemark()));
        Result<String> uploadResult = null;
        if (!verifyResult) {
            // 将校验后的数据写入新的Excel文件
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            EasyExcel.write(outputStream, InvoiceData.class).sheet("校验结果").doWrite(invoiceDataList);
            // 将文件上传到OSS
            uploadResult = fileUploadFeign.uploadBytes(outputStream.toByteArray(), "performance", "批量开票校验结果.xlsx");
        }

        UploadBatchInvoiceFileResultVO vo = new UploadBatchInvoiceFileResultVO();
        vo.setVerifyResult(verifyResult);
        vo.setErrorFileUrl(uploadResult==null?null:uploadResult.getData());
        vo.setOrderChildSum(invoiceDataList.size());
        vo.setLoadWeightSum(invoiceDataList.stream().map(InvoiceData::getLoadNet).filter(Objects::nonNull).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setInvoiceFreightSum(invoiceDataList.stream().map(InvoiceData::getInvoiceFreight).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setChildNoList(invoiceDataList.stream().map(InvoiceData::getChildNo).collect(Collectors.toList()));
        return vo;
    }

    @Override
    public void confirmBatchInvoice(List<String> childNoList) {
        settlementOwnerDetailDao.updateSettlementByChildNoList(childNoList);
        // 发送mq (运单更新)
        orderChildBrokerMqService.orderChildUpdate(childNoList);

        settlementPostService.updateInvoice(childNoList);

    }
}
