package com.testor.module.hire.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.testor.biz.file.model.dto.FileDTO;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.common.constant.StatusEnum;
import com.testor.common.core.utils.StringUtils;
import com.testor.common.core.utils.uuid.IdUtils;
import com.testor.common.util.DateUtil;
import com.testor.common.util.ExcelUtils;
import com.testor.module.duty.util.PoiExcelUtils;
import com.testor.module.hire.dao.DepositoryManageBaseMapper;
import com.testor.module.hire.entity.*;
import com.testor.module.hire.entity.vo.*;
import com.testor.module.hire.enums.ZlmyFileTokenConst;
import com.testor.module.hire.service.*;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.service.NewSysOrgService;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import io.jsonwebtoken.lang.Collections;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 租赁库管理-客商基本信息 服务实现类
 * </p>
 *
 * @author caoqiang
 * @since 2024-08-29
 */
@Slf4j
@Service
public class DepositoryManageBaseServiceImpl extends ServiceImpl<DepositoryManageBaseMapper, DepositoryManageBase> implements DepositoryManageBaseService {

    @Autowired
    private DepositoryManageBaseMapper depositoryManageBaseMapper;
    @Autowired
    private DepositoryInfoService depositoryInfoService;
    @Autowired
    private DepositoryAccessInfoService depositoryAccessInfoService;
    @Autowired
    private DepositoryFileInfoService depositoryFileInfoService;
    @Autowired
    private NewSysOrgService newSysOrgService;

    @Autowired
    private THireOrgService tHireOrgService;
    @Autowired
    private ZlmyFileTokenConst zlmyFileTokenConst;


    @Value("${hire.depository.queryFileList}")
    private String queryFileListUrl;
    @Value("${hire.depository.downloadFile}")
    private String downloadFileUrl;
    @Value("${hire.depository.realDownloadUrl}")
    private String realDownloadUrl;


    @Override
    public BaseResponseList<HireDepositoryListVo> findHireDepositoryList(HireDepositoryListVo vo) {

        BaseResponseList<HireDepositoryListVo> baseResponseList = new BaseResponseList<>();
        Page<DepositoryManageBase> resultPage = new Page<>(vo.getPage(), vo.getLimit());
        IPage<HireDepositoryDto> depositoryList = depositoryManageBaseMapper.findDepositoryList(resultPage, vo);
        if (depositoryList == null) {
            return baseResponseList;
        }
        baseResponseList.setTotal(depositoryList.getTotal());
        List<HireDepositoryDto> records = depositoryList.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return baseResponseList;
        }
        List<HireDepositoryListVo> hireDepositoryListVoList = new ArrayList<>();
        records.forEach(item -> {
            HireDepositoryListVo hireDepositoryListVo = new HireDepositoryListVo();
            BeanUtils.copyProperties(item, hireDepositoryListVo);
            String lessorOrgId = item.getLessorOrgId();
            if (StringUtils.isNotBlank(lessorOrgId)) {
                String orgFullPathName = getOrgFullPathName(item.getId());
                hireDepositoryListVo.setOrgName(orgFullPathName);
            }
            LocalDateTime now = LocalDateTime.now();
            hireDepositoryListVo.setAccessStatus("2");
            Date accessHireStartTime = item.getAccessHireStartTime();
            if (accessHireStartTime != null) {
                hireDepositoryListVo.setAccessHireStartTime(DateUtil.convertDateToStr(accessHireStartTime, DatePattern.NORM_DATE_PATTERN));
            }
            Date accessHireEndTime = item.getAccessHireEndTime();
            if (accessHireEndTime != null) {
                hireDepositoryListVo.setAccessHireEndTime(DateUtil.convertDateToStr(accessHireEndTime, DatePattern.NORM_DATE_PATTERN));
            }

            if (accessHireStartTime != null && accessHireEndTime != null &&
                    now.isAfter(DateUtil.dateToLocalDateTime(accessHireStartTime)) && now.isBefore(DateUtil.dateToLocalDateTime(item.getAccessHireEndTime()))) {
                hireDepositoryListVo.setAccessStatus("0");
            }
            hireDepositoryListVoList.add(hireDepositoryListVo);
        });
        baseResponseList.setData(hireDepositoryListVoList);
        return baseResponseList;
    }

    public String getOrgFullPathName(String orgId) {
        String fullName = "";
        NewSysOrg sysOrg = newSysOrgService.getById(orgId);
        if (sysOrg == null || org.apache.commons.lang.StringUtils.isBlank(sysOrg.getParentIds())) {
            return "";
        }
        String paid = StringUtils.substringAfter(sysOrg.getParentIds(), ",");
        paid = StringUtils.substringAfter(paid, ",");
        List<String> pIds = Collections.arrayToList(StringHelper.split(paid, ","));
        for (String pid : pIds) {
            NewSysOrg pOrg = newSysOrgService.getById(pid);
            if (ObjectHelper.isNotEmpty(pOrg)) {
                fullName = fullName + pOrg.getOrgName() + "/";
            }
        }
        return StringUtils.substringBeforeLast(fullName, "/");

    }


    @Override
    public HireDepositoryDetailVo findHireDepositoryDetail(String id,String updateStatus) {
        DepositoryManageBase depositoryManageBase = this.getById(id);
        DepositoryInfo depositoryInfo = depositoryInfoService.lambdaQuery().eq(DepositoryInfo::getHireDepositoryManageBaseId, id).one();
        DepositoryAccessInfo depositoryAccessInfo = depositoryAccessInfoService.lambdaQuery().eq(DepositoryAccessInfo::getHireDepositoryManageBaseId, id).one();
        DepositoryFileInfo depositoryFileInfo = depositoryFileInfoService.lambdaQuery().eq(DepositoryFileInfo::getHireDepositoryManageBaseId, id).one();
        HireDepositoryDetailVo hireDepositoryDetailVo = new HireDepositoryDetailVo();
        String depositoryDesc = depositoryInfo.getDepositoryDesc();
        if (StringUtils.isNotBlank(depositoryDesc)) {
            depositoryInfo.setDepositoryDesc("本次为第" + depositoryDesc + "次准入");
        }
        hireDepositoryDetailVo.setBaseInfo(depositoryManageBase);
        hireDepositoryDetailVo.setDepositoryInfo(depositoryInfo);
        hireDepositoryDetailVo.setAccessInfo(depositoryAccessInfo);
        hireDepositoryDetailVo.setFileInfo(depositoryFileInfo);
        if (StringUtils.isBlank(updateStatus)){
            hireDepositoryDetailVo.setFileDto(convertFileVo(depositoryFileInfo));
        }
        hireDepositoryDetailVo.setId(id);
        return hireDepositoryDetailVo;
    }

    @Override
    public void updateHireDepositoryOrgCode(String id, String orgCode) {
        UserInfo loginUser = ContextUtils.getLoginUser();
        //查询改租赁库是否已经在组织结构下
        NewSysOrg sysOrg = newSysOrgService.getById(id);
        if (sysOrg == null) {
            HireDepositoryDetailVo hireDepositoryDetail = findHireDepositoryDetail(id,"1");
            DepositoryManageBase baseInfo = hireDepositoryDetail.getBaseInfo();
            NewSysOrg fatherOrg = newSysOrgService.getById(orgCode);
            String orgId = fatherOrg.getOrgId();
            String parentIds = fatherOrg.getParentIds();
            TSysOrg tSysOrg = new TSysOrg();
            tSysOrg.setParentId(orgId);
            tSysOrg.setOrgName("(租赁库)" + baseInfo.getLessorFullName());
            tSysOrg.setOrgCode(baseInfo.getLessorCode());
            tSysOrg.setParentIds(parentIds + "," + orgId);
            //租赁库表的id作为机构id
            tSysOrg.setOrgId(id);
            tSysOrg.setCreateDate(new Date());
            tSysOrg.setUpdateDate(new Date());
            tSysOrg.setNature("4");
            tSysOrg.setIsDept("0");
            tSysOrg.setStatus("0");
            tSysOrg.setIsRent("1");
            tSysOrg.setTreeLevel(new BigDecimal("4"));
            tSysOrg.setTreeSort(new BigDecimal("1"));
            TSysOrg byId = tHireOrgService.getById(id);
            if (byId == null) {
                tSysOrg.setCreateBy(loginUser.getUserId());
                tSysOrg.setCreateDate(new Date());
                tSysOrg.setUpdateBy(loginUser.getUserId());
                tSysOrg.setUpdateDate(new Date());
                tHireOrgService.save(tSysOrg);
            } else {
                tSysOrg.setUpdateBy(loginUser.getUserId());
                tSysOrg.setUpdateDate(new Date());
                tHireOrgService.updateById(tSysOrg);
            }
            this.lambdaUpdate().set(DepositoryManageBase::getLessorOrgId, fatherOrg.getOrgId())
                    .set(DepositoryManageBase::getLessorOrgName, fatherOrg.getOrgName())
                    .set(DepositoryManageBase::getUpdateBy, loginUser.getUserId())
                    .set(DepositoryManageBase::getUpdateDate, new Date())
                    .eq(DepositoryManageBase::getId, id).update();

        } else {
            NewSysOrg fatherOrg = newSysOrgService.getById(orgCode);
            if (fatherOrg != null) {
                sysOrg.setParentId(orgCode);
                sysOrg.setParentIds(fatherOrg.getParentIds() + "," + orgCode);
                TSysOrg tSysOrg = new TSysOrg();
                BeanUtils.copyProperties(sysOrg, tSysOrg);
                tHireOrgService.updateById(tSysOrg);
                this.lambdaUpdate().set(DepositoryManageBase::getLessorOrgId, fatherOrg.getOrgId())
                        .set(DepositoryManageBase::getLessorOrgName, fatherOrg.getOrgName())
                        .set(DepositoryManageBase::getUpdateBy, loginUser.getUserId())
                        .set(DepositoryManageBase::getUpdateDate, new Date())
                        .eq(DepositoryManageBase::getId, id).update();
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<HireDepositoryDetailVo> saveHireDepositoryInfo(HireDepositoryDetailVo vo) {
        BaseResponse<HireDepositoryDetailVo> baseResponse = new BaseResponse<>();
        String id = vo.getId();
        if (StringUtils.isBlank(id)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("ID不能为空");
            return baseResponse;
        }
        DepositoryManageBase baseInfo = vo.getBaseInfo();
        baseInfo.setId(id);
        baseInfo.setCreateDate(new Date());
        baseInfo.setUpdateDate(new Date());

        NewSysOrg fatherOrg = addSysOrgTree(vo);
        if (ObjectHelper.isNotEmpty(fatherOrg) && StringUtils.isNotBlank(fatherOrg.getOrgId())) {
            baseInfo.setLessorOrgId(fatherOrg.getOrgId());
            baseInfo.setLessorOrgName(fatherOrg.getOrgName());
        }

        List<DepositoryManageBase> list = this.lambdaQuery().eq(DepositoryManageBase::getLessorFullName, baseInfo.getLessorFullName())
                .orderByDesc(DepositoryManageBase::getCreateDate).list();

        if (CollectionUtils.isNotEmpty(list)) {
            DepositoryManageBase depositoryManageBase = list.get(0);
            baseInfo.setLessorOrgId(depositoryManageBase.getLessorOrgId());
            baseInfo.setLessorOrgName(depositoryManageBase.getLessorOrgName());
            String oldId = depositoryManageBase.getId();
            this.removeById(oldId);
            depositoryInfoService.remove(new QueryWrapper<DepositoryInfo>().eq("hire_depository_manage_base_id", oldId));
            depositoryAccessInfoService.remove(new QueryWrapper<DepositoryAccessInfo>().eq("hire_depository_manage_base_id", oldId));
            depositoryFileInfoService.remove(new QueryWrapper<DepositoryFileInfo>().eq("hire_depository_manage_base_id", oldId));
        }
        this.saveOrUpdate(baseInfo);

        DepositoryInfo depositoryInfo = vo.getDepositoryInfo();
        depositoryInfo.setId(id);
        depositoryInfo.setHireDepositoryManageBaseId(id);
        depositoryInfo.setCreateDate(new Date());
        depositoryInfo.setUpdateDate(new Date());
        depositoryInfoService.saveOrUpdate(depositoryInfo);
        DepositoryAccessInfo accessInfo = vo.getAccessInfo();
        accessInfo.setId(id);
        accessInfo.setHireDepositoryManageBaseId(id);
        accessInfo.setCreateDate(new Date());
        accessInfo.setUpdateDate(new Date());
        depositoryAccessInfoService.saveOrUpdate(accessInfo);

        DepositoryFileInfo fileInfo = vo.getFileInfo();
        fileInfo.setId(id);
        fileInfo.setHireDepositoryManageBaseId(id);
        fileInfo.setCreateDate(new Date());
        fileInfo.setUpdateDate(new Date());
        depositoryFileInfoService.saveOrUpdate(fileInfo);
        baseResponse.setData(vo);
        return baseResponse;
    }

    private NewSysOrg addSysOrgTree(HireDepositoryDetailVo vo) {
        DepositoryManageBase baseInfo = vo.getBaseInfo();
        DepositoryInfo depositoryInfo = vo.getDepositoryInfo();
        if (baseInfo == null) {
            return null;
        }
        String orgName = "(租赁库)" + baseInfo.getLessorFullName();
        NewSysOrg newSysOrg = newSysOrgService.lambdaQuery()
                .eq(NewSysOrg::getOrgName, orgName)
                .eq(SysOrg::getIsDept, "0")
                .eq(NewSysOrg::getStatus, "0")
                .last("limit 1")
                .one();
        if (ObjectHelper.isNotEmpty(newSysOrg)) {
            log.info("已存在租赁库，无需重复添加,租赁库信息：{}", JSON.toJSONString(baseInfo));
            return newSysOrg;
        }

        String lessorOrgName = convertLessorOrgName(baseInfo.getLessorOrgName());
        NewSysOrg fatherOrg = newSysOrgService.lambdaQuery()
                .and(wrapper -> wrapper.eq(NewSysOrg::getOrgName, lessorOrgName)
                        .or().eq(NewSysOrg::getOrgName, lessorOrgName.replace("公司", "经营部")))
                .le(SysOrg::getTreeLevel, 3)
                .eq(SysOrg::getIsDept, "0")
                .eq(NewSysOrg::getStatus, "0")
                .last("limit 1")
                .one();
        if (ObjectHelper.isEmpty(fatherOrg) || StringUtils.isBlank(fatherOrg.getOrgId())) {
            log.info("未找到对应的父级组织机构，无法添加租赁库,租赁库信息：{}", JSON.toJSONString(baseInfo));
            return null;
        }
        String orgId = fatherOrg.getOrgId();
        String parentIds = fatherOrg.getParentIds();
        BigDecimal treeLevel = fatherOrg.getTreeLevel();
        BigDecimal newTreeLevel = treeLevel.add(new BigDecimal("1"));
        TSysOrg sysOrg = new TSysOrg();
        sysOrg.setParentId(orgId);
        sysOrg.setOrgName("(租赁库)" + baseInfo.getLessorFullName());
        sysOrg.setOrgCode(baseInfo.getLessorCode());
        sysOrg.setParentIds(parentIds + "," + orgId);
        //租赁库表的id作为机构id
        sysOrg.setOrgId(vo.getId());
        sysOrg.setCreateDate(new Date());
        sysOrg.setUpdateDate(new Date());
        sysOrg.setNature(newTreeLevel.toString());
        sysOrg.setIsDept("0");
        sysOrg.setStatus("0");
        sysOrg.setIsRent("1");
        sysOrg.setTreeLevel(newTreeLevel);
        sysOrg.setTreeSort(new BigDecimal("99"));
        sysOrg.setProvince(depositoryInfo.getDepositoryProvinceName());
        sysOrg.setCity(depositoryInfo.getDepositoryCityName());
        sysOrg.setCounty(depositoryInfo.getDepositoryCountyName());
        sysOrg.setAddress(depositoryInfo.getDepositoryAddress());

        //检查记录是否存在
        TSysOrg existing = tHireOrgService.getById(vo.getId());
        try {
            if (existing == null) {
                // 新增逻辑
                sysOrg.setCreateDate(new Date());
                sysOrg.setUpdateDate(new Date());
                tHireOrgService.save(sysOrg);
            } else {
                // 更新逻辑
                sysOrg.setUpdateDate(new Date());
                tHireOrgService.updateById(sysOrg);
            }
        } catch (DataIntegrityViolationException e) {
            // 捕获主键冲突（可能在高并发时发生）
            log.error("主键冲突，自动转为更新模式: {}", vo.getId());
            sysOrg.setUpdateDate(new Date());
            tHireOrgService.updateById(sysOrg);
        }
        return fatherOrg;
    }

    private String convertLessorOrgName(String orgName) {
        if (orgName.contains("-")) {
            // 找到"-"的位置
            int dashIndex = orgName.indexOf("-");
            // 截取"-"之后的内容
            orgName = orgName.substring(dashIndex + 1);
        }
        if ("黑龙江公司".equals(orgName)) {
            orgName = "哈尔滨经营部";
        }
        if ("深圳公司".equals(orgName)) {
            orgName = "广西经营部";
        }
        if ("辽宁公司".equals(orgName)) {
            orgName = "沈阳经营部";
        }
        return orgName;
    }


    /**
     * 附件内容转换
     *
     * @return
     */
    private DepositoryFileInfoVo convertFileVo(DepositoryFileInfo depositoryFileInfo) {
        if (depositoryFileInfo == null) {
            return null;
        }
        DepositoryFileInfoVo fileInfoVo = new DepositoryFileInfoVo();

        //{\"17296453681279891101\":[\"67198ccbdddd9a3419a3cc0f\",\"67198ccedddd9a3419a3cc10\"]}
        String fileDepositoryPath = depositoryFileInfo.getFileDepositoryPath();
        fileInfoVo.setFileDepository(convert(fileDepositoryPath));

        String fileFinancePath = depositoryFileInfo.getFileFinancePath();
        fileInfoVo.setFileFinance(convert(fileFinancePath));

        String fileOtherPath = depositoryFileInfo.getFileOtherPath();
        fileInfoVo.setFileOther(convert(fileOtherPath));

        String filePersionPath = depositoryFileInfo.getFilePersionPath();
        fileInfoVo.setFilePersion(convert(filePersionPath));

        String fileRiskPath = depositoryFileInfo.getFileRiskPath();
        fileInfoVo.setFileRisk(convert(fileRiskPath));

        String fileSafetyPath = depositoryFileInfo.getFileSafetyPath();
        fileInfoVo.setFileSafety(convert(fileSafetyPath));

        String fileScorePath = depositoryFileInfo.getFileScorePath();
        fileInfoVo.setFileScore(convert(fileScorePath));

        return fileInfoVo;
    }


    private List<FileDTO> convert(String paraString) {
        List<FileDTO> fileDTOList = new ArrayList<>();
        if (StringUtils.isNotBlank(paraString)) {
            JSONObject jsonObject = JSON.parseObject(paraString);
            jsonObject.keySet().forEach(key -> {
                List<String> fileIdList = JSON.parseArray(jsonObject.get(key).toString(), String.class);
                List<FileDTO> dtoList = convertFileList(key, fileIdList);
                if (CollectionUtils.isNotEmpty(dtoList)) {
                    fileDTOList.addAll(dtoList);
                }
            });
        }
        return fileDTOList;
    }

    private List<FileDTO> convertFileList(String processCode, List<String> fileIdList) {
        List<FileDTO> fileDTOList = new ArrayList<>();
        if (StringUtils.isNotBlank(processCode) && CollectionUtils.isNotEmpty(fileIdList)) {
            for (String fileId : fileIdList) {
                FileDTO fileDTO = convertFileDto(processCode, fileId);
                if (fileDTO != null) {
                    fileDTOList.add(fileDTO);
                }
            }
        }
        return fileDTOList;
    }

    @Override
    public FileDTO convertFileDto(String processCode, String fileId) {

        String urlSux = "&processCode=" + processCode + "&id=" + fileId;
        String url = queryFileListUrl + urlSux;
        String result = "";
        try {
            result = HttpRequest.get(url).timeout(10000)
                    .header("Authorization", zlmyFileTokenConst.getToken()).execute().body();
            log.info("租赁库_调用中粮查询文件接口返回数据：{},接口地址：{}", result, url);
        } catch (Exception e) {
            log.error("租赁库_调用中粮查询文件接口失败，接口地址：{}", url, e);
        }
        if (StringUtils.isBlank(result) || JSON.parseObject(result).getJSONArray("body") == null) {
            return null;
        }

        JSONArray body = JSON.parseObject(result).getJSONArray("body");
        if (CollectionUtils.isEmpty(body)) {
            return null;
        }
        JSONObject bodyObject = body.getJSONObject(0);
        String aliasName = bodyObject.getString("aliasName");
        String fileUrl = realDownloadUrl + urlSux + "&fileName=" + aliasName;
        FileDTO fileDTO = new FileDTO();
        fileDTO.setFileId(fileId);
        fileDTO.setFileName(aliasName);
        fileDTO.setFilePath(fileUrl);
        fileDTO.setFileDowName(aliasName);
        return fileDTO;

    }

    @Override
    public void dowonLoadFile(String processCode, String id, String fileName, HttpServletResponse httpServletResponse) throws UnsupportedEncodingException {

        String urlSux = "&processCode=" + processCode + "&id=" + id;
        // 第三方文件下载URL，这里需要替换成实际的第三方接口URL
        String fileUrl = downloadFileUrl + urlSux;
        // 创建HttpRequest对象
        HttpRequest request = HttpRequest.get(fileUrl).header("Authorization", zlmyFileTokenConst.getToken());

        String fileType = StringUtils.substringAfterLast(fileName, ".");

        // 发送请求并获取响应
        HttpResponse response = request.execute();
        // 设置响应类型
        httpServletResponse.setContentType("application/octet-stream");
        // 设置下载文件的名称（根据实际情况设置）


        String fileNameBefore = StringUtils.substringBeforeLast(fileName, ".");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileNameBefore, "UTF-8") + "." + fileType);

        //String fileNewName = System.currentTimeMillis() + "." + fileType;
        //httpServletResponse.setHeader("Content-Disposition", "attachment; filename="+fileNewName);

        // 获取响应内容并写入到输出流
        try (OutputStream out = httpServletResponse.getOutputStream()) {
            long l = response.writeBody(out, false, null);
            out.flush();
        } catch (IOException e) {
            log.error("租赁库文件下载-下载文件失败，文件地址：{}", fileUrl, e);
        }
    }

    @Override
    public BaseResponse<String> historicalDataImport(MultipartFile file) throws IOException {
        BaseResponse<String> baseResponse = new BaseResponse<>();

        //判断是否为null
        if (file.equals("") || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        List<HireDepositoryDetailVo> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), HistoricalDepositoryImport.class, new AnalysisEventListener<HistoricalDepositoryImport>() {
            @SneakyThrows
            @Override
            public void invoke(HistoricalDepositoryImport depositoryImport, AnalysisContext analysisContext) {
                ReadRowHolder readRowHolder = analysisContext.readRowHolder();
                int rowIndex = readRowHolder.getRowIndex() + 1;
                if (rowIndex > 1) {
                    HireDepositoryDetailVo detailVo = convertImportToVo(depositoryImport);
                    list.add(detailVo);
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet().doRead();

        if (CollectionUtils.isEmpty(list)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        // 使用Map去重，保留创建时间最大的对象
        Map<String, HireDepositoryDetailVo> uniqueMap = new HashMap<>();
        for (HireDepositoryDetailVo obj : list) {
            String name = obj.getLessorFullName();
            if (!uniqueMap.containsKey(name) || obj.getCreateDate().after(uniqueMap.get(name).getCreateDate())) {
                uniqueMap.put(name, obj);
            }
        }
        // 将结果转换为List
        List<HireDepositoryDetailVo> uniqueList = new ArrayList<>(uniqueMap.values());
        uniqueList.forEach(this::saveHireDepositoryInfo);
        return baseResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<String> dataImport(MultipartFile file) {
        BaseResponse<String> baseResponse = new BaseResponse<>();
        List<HireDepositoryDetailVo> hireDepositoryDetailVos = new ArrayList<>();
        try {
            InputStream inputStream = file.getInputStream();

            Workbook sheets = PoiExcelUtils.readFile(inputStream, Objects.requireNonNull(file.getOriginalFilename()));
            Sheet sheet = sheets.getSheetAt(0);
            //获取文件内数据
            List<Map<Integer, Object>> dataList = PoiExcelUtils.getBody(sheet, 7, 3);
            if (dataList == null || dataList.isEmpty()) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("请填写数据");
                return baseResponse;
            }
            StringBuffer errorMsg = new StringBuffer();
            int rowIndex = 3;
            for (Map<Integer, Object> map : dataList) {
                rowIndex++;
                //大区名称
                String regionName = map.get(0).toString();
                //经营部名称
                String businessDeptName = map.get(1).toString();
                //租赁库
                String leaseOfGrainDepotsName = map.get(3).toString();

                NewSysOrg businessDeptData = null;
                //大区
                List<NewSysOrg> regionOrgList = newSysOrgService.getOrgByOrgName(regionName);

                boolean shouldBreak = false;
                for (NewSysOrg regionOrg : regionOrgList) {
                    if (shouldBreak) {
                        break;
                    }
                    String regionOrgId = regionOrg.getOrgId();
                    //经营部
                    List<NewSysOrg> businessDeptList = newSysOrgService.getOrgByOrgName(businessDeptName);
                    for (NewSysOrg businessDept : businessDeptList) {
                        if (businessDept != null && businessDept.getParentId().equals(regionOrgId)) {
                            businessDeptData = businessDept;
                            shouldBreak = true;
                            break;
                        }
                    }
                }

                if (businessDeptData == null) {
                    errorMsg.append("第"+rowIndex+"行，经营部名称"+businessDeptName+"不存在;\n");
                    continue;
                }


                HireDepositoryDetailVo vo = new HireDepositoryDetailVo();

                String orgName = "(租赁库)" + leaseOfGrainDepotsName;
                NewSysOrg newSysOrg = newSysOrgService.lambdaQuery()
                        .eq(NewSysOrg::getOrgName, orgName)
                        .eq(SysOrg::getIsDept, "0")
                        .eq(NewSysOrg::getStatus, "0")
                        .last("limit 1")
                        .one();
                if (newSysOrg == null) {
                    vo.setId(IdUtils.randomUUID());
                }else {
                    errorMsg.append("第"+rowIndex+"行，租赁库:"+leaseOfGrainDepotsName+"已存在;\n");
                    continue;
                }

                DepositoryManageBase basInfo = new DepositoryManageBase();
                basInfo.setLessorFullName(leaseOfGrainDepotsName);
                basInfo.setLessorShortName(leaseOfGrainDepotsName);
                basInfo.setLessorOrgId(businessDeptData.getOrgId());
                basInfo.setLessorOrgName(businessDeptData.getOrgName());
                vo.setBaseInfo(basInfo);

                DepositoryInfo depositoryInfo = new DepositoryInfo();
                depositoryInfo.setDepositoryProvinceName(map.get(5).toString());
                depositoryInfo.setDepositoryAddress(map.get(6).toString());
                depositoryInfo.setDepositoryShortName(leaseOfGrainDepotsName);
                depositoryInfo.setDepositoryFullName(leaseOfGrainDepotsName);
                vo.setDepositoryInfo(depositoryInfo);

                DepositoryAccessInfo accessInfo = new DepositoryAccessInfo();
                vo.setAccessInfo(accessInfo);
                DepositoryFileInfo depositoryFileInfo = new DepositoryFileInfo();
                vo.setFileInfo(depositoryFileInfo);
                hireDepositoryDetailVos.add(vo);
            }
            if (errorMsg.length() > 0) {
                baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
                baseResponse.setMsg(errorMsg.toString());
                return baseResponse;
            }
            hireDepositoryDetailVos.forEach(this::saveHireDepositoryInfo);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return baseResponse;
    }

    private HireDepositoryDetailVo convertImportToVo(HistoricalDepositoryImport depositoryImport) {

        Date date = DateUtil.convertStrToDate(depositoryImport.getCreateDate(), DatePattern.NORM_DATETIME_PATTERN);

        HireDepositoryDetailVo detailVo = new HireDepositoryDetailVo();
        detailVo.setId(depositoryImport.getId());
        DepositoryManageBase baseInfo = new DepositoryManageBase();
        BeanUtils.copyProperties(depositoryImport, baseInfo);
        baseInfo.setCreateDate(date);
        baseInfo.setUpdateDate(date);
        baseInfo.setId(depositoryImport.getId());
        baseInfo.setStatus(StatusEnum.USE.getCode());
        detailVo.setBaseInfo(baseInfo);

        DepositoryInfo depositoryInfo = new DepositoryInfo();
        BeanUtils.copyProperties(depositoryImport, depositoryInfo);
        depositoryInfo.setHireDepositoryManageBaseId(depositoryImport.getId());
        depositoryInfo.setCreateDate(date);
        depositoryInfo.setUpdateDate(date);
        depositoryInfo.setStatus(StatusEnum.USE.getCode());
        detailVo.setDepositoryInfo(depositoryInfo);

        DepositoryAccessInfo accessInfo = new DepositoryAccessInfo();
        BeanUtils.copyProperties(depositoryImport, accessInfo);
        accessInfo.setHireDepositoryManageBaseId(depositoryImport.getId());
        accessInfo.setCreateDate(date);
        accessInfo.setUpdateDate(date);
        accessInfo.setAccessHireStartTime(DateUtil.convertStrToDate(depositoryImport.getAccessHireStartTime(), DatePattern.NORM_DATETIME_PATTERN));
        accessInfo.setAccessHireEndTime(DateUtil.convertStrToDate(depositoryImport.getAccessHireEndTime(), DatePattern.NORM_DATETIME_PATTERN));
        accessInfo.setAccessSignEndTime(DateUtil.convertStrToDate(depositoryImport.getAccessSignEndTime(), DatePattern.NORM_DATE_PATTERN));

        //张三A:13655558888,历史B:13455556666
        String accessPersonArry = depositoryImport.getAccessPersonArry();
        if (StringUtils.isNotBlank(accessPersonArry)) {
            List<JSONObject> list = new ArrayList<>();
            String[] split = StringUtils.split(accessPersonArry, ",");
            for (String s : split) {
                if (StringUtils.isBlank(s)) {
                    continue;
                }
                String[] split1 = StringUtils.split(s, ":");
                if (split1 == null || split1.length == 0) {
                    continue;
                }
                JSONObject jsonObject = new JSONObject();
                String key = split1[0];
                if (split1.length > 1) {
                    String value = split1[1];
                    jsonObject.put("key", key);
                    jsonObject.put("value", value);
                } else {
                    jsonObject.put("key", key);
                    jsonObject.put("value", "");
                }
                list.add(jsonObject);
            }
            accessInfo.setAccessPersonArry(JSONArray.toJSONString(list));
        }
        accessInfo.setStatus(StatusEnum.USE.getCode());
        detailVo.setAccessInfo(accessInfo);

        DepositoryFileInfo fileInfo = new DepositoryFileInfo();
        BeanUtils.copyProperties(depositoryImport, fileInfo);
        fileInfo.setHireDepositoryManageBaseId(depositoryImport.getId());
        fileInfo.setCreateDate(date);
        fileInfo.setUpdateDate(date);
        fileInfo.setStatus(StatusEnum.USE.getCode());
        detailVo.setFileInfo(fileInfo);


        detailVo.setLessorFullName(depositoryImport.getLessorFullName());
        detailVo.setCreateDate(date);

        return detailVo;
    }


    public static void main(String[] args) {
        String accessPersonArry = "张三A:13655558888,历史B:";
        String[] split = StringUtils.split(accessPersonArry, ",");
        for (String s : split) {
            String[] split1 = StringUtils.split(s, ":");
            JSONObject jsonObject = new JSONObject();
            if (split1.length > 1) {
                String key = split1[0];
                String value = split1[1];
                jsonObject.put("key", key);
                jsonObject.put("value", value);
            } else {
                String key = split1[0];
                jsonObject.put("key", key);
                jsonObject.put("value", "");
            }
            System.out.println(jsonObject.toJSONString());
        }
    }


}
