package com.inkasso.factoring.file.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.inkasso.adapter.enums.FileBusinessInterface;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.exception.ServiceException;
import com.inkasso.adapter.exception.enums.ExceptionEnum;
import com.inkasso.adapter.service.KafubaoServiceImpl;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.adapter.web.LoginUserHolder;
import com.inkasso.factoring.common.util.DateUtil;
import com.inkasso.factoring.creditmanagement.entity.Enterprise;
import com.inkasso.factoring.creditmanagement.service.IEnterpriseService;
import com.inkasso.factoring.file.dao.FileStorageDAO;
import com.inkasso.factoring.file.entity.FileStorageDO;
import com.inkasso.factoring.file.enums.FileStorageTypeEnum;
import com.inkasso.factoring.file.enums.FileTypeEnum;
import com.inkasso.factoring.file.enums.FileUploadExceptionEnum;
import com.inkasso.factoring.file.model.dto.FileStorageDTO;
import com.inkasso.factoring.file.service.FileService;
import com.inkasso.factoring.file.util.FileStorageUtil;
import com.inkasso.factoring.file.util.FileUtil;
import com.inkasso.factoring.financingmanagement.entity.*;
import com.inkasso.factoring.financingmanagement.service.*;
import com.inkasso.factoring.purchManagement.entity.CPurchContractElectronicInfo;
import com.inkasso.factoring.purchManagement.entity.CPurchContractSupplementElectronicInfo;
import com.inkasso.factoring.purchManagement.service.ICPurchContractElectronicInfoService;
import com.inkasso.factoring.purchManagement.service.ICPurchContractSupplementElectronicInfoService;
import com.inkasso.factoring.settlement.entity.SettlementBasicInfo;
import com.inkasso.factoring.settlement.entity.SettlementGoodsInfo;
import com.inkasso.factoring.settlement.service.SettlementBasicInfoService;
import com.inkasso.factoring.settlement.service.SettlementGoodsInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class FileServiceImpl extends
        KafubaoServiceImpl<FileStorageDAO, FileStorageDO, FileStorageDTO> implements FileService {

    @Autowired
    private SettlementBasicInfoService settlementBasicInfoService;
    @Autowired
    private SettlementGoodsInfoService settlementGoodsInfoService;
    @Autowired
    private ICPurchContractElectronicInfoService purchContractElectronicInfoService;
    @Autowired
    private ICPurchContractSupplementElectronicInfoService supplementElectronicInfoService;
    @Autowired
    private ReviewQuotaDisburseService reviewQuotaDisburseService;
    @Autowired
    private ICFinancingBasicInfoService financingBasicInfoService;
    @Autowired
    private IContractElectronicInfoService contractElectronicInfoService;
    @Autowired
    private IContractElectronicCustomerInfoService contractElectronicCustomerInfoService;
    @Autowired
    private IContractInfoService contractInfoService;
    @Autowired
    private IEnterpriseService enterpriseService;

    public static final String FILE_NAME = "file";

    @Override
    public FileStorageDO uploadFile(HttpServletRequest request, FileBusinessInterface fileBusinessEnum) {
        if (fileBusinessEnum == null) {
            throw new ServiceException(FileUploadExceptionEnum.REQUEST_OBJECT_ERROR);
        }
        if (request instanceof MultipartHttpServletRequest) {
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFile = multipartHttpServletRequest.getFile(FILE_NAME);
            FileStorageDO fileStorageDO = uploadFile(multipartFile, fileBusinessEnum);
            return fileStorageDO;
        }
        throw new ServiceException(400, FileUploadExceptionEnum.REQUEST_OBJECT_ERROR);
    }

    @Override
    public FileStorageDO uploadFile(MultipartFile multipartFile, FileBusinessInterface fileBusinessEnum) {
        if (multipartFile == null) {
            return null;
        }
        FileStorageDO fileStorage = FileStorageUtil.createFileStorage(multipartFile, fileBusinessEnum);
        fileStorage.setStorageType(FileStorageTypeEnum.DISK.getCode());
        //文件存储到本地
        try {
            String absolutePath = fileStorage.getAbsolutePath();
            File file = new File(absolutePath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            multipartFile.transferTo(file);


//                //大于100kb的要压缩图片
//                if (!FileTypeEnum.PRECISE_ASSESS_VIDEO.equals(fileBusinessEnum.getCode())){
//                    String path = fileStorage.getAbsolutePath();
//                    String[] split = path.split(fileStorage.getType());
//                    String newPath = split[0] + "_c" + fileStorage.getType();
//                    String result = PicUtils.compressPicForScale(path, newPath, 100, 0.9);
//                    if (result != null){
//                        fileStorage.setAbsolutePath(newPath);
//                        String storagePath = fileStorage.getPath();
//                        String[] split2 = storagePath.split(fileStorage.getType());
//                        String newPath2 = split2[0] + "_c" + fileStorage.getType();
//                        fileStorage.setPath(newPath2);
//                    }
//                }
//
//                if (FileTypeEnum.PRECISE_ASSESS_VIDEO.getCode().equals(fileBusinessEnum.getCode())){
//                    String originalFilename = multipartFile.getOriginalFilename();
//                    String suffix = FileStorageUtil.getSuffix(originalFilename);
//                    if (!suffix.equalsIgnoreCase(".mp4")){
//                        String newPath = absolutePath.replace(suffix, ".mp4");
//                        VideoConverter.change(absolutePath,newPath);
//                        fileStorage.setType(".mp4");
//                        fileStorage.setAbsolutePath(newPath);
//                        String path = fileStorage.getPath();
//                        String replace = path.replace(suffix, ".mp4");
//                        fileStorage.setPath(replace);
//                        String newName = originalFilename.replace(suffix, ".mp4");
//                        fileStorage.setOriginalName(newName);
//                    }
//                }

//                //将精准评估照片上传至oss
//                if (FileTypeEnum.PRECISE_ASSESS_VIDEO.getCode().equals(fileBusinessEnum.getCode()) ||
//                    FileTypeEnum.PRECISE_ASSESS_PHOTOS.getCode().equals(fileBusinessEnum.getCode())){
//                    String filePath = fileStorage.getPath();
//                    filePath = filePath.replace("\\", "/");
//                    OSSUtil.uploadFile(fileStorage.getAbsolutePath(),filePath);
//                    fileStorage.setPath(OSSUtil.getUrl(filePath));
//                    fileStorage.setStorageType(FileStorageTypeEnum.OSS.getCode());
//                }
            this.save(fileStorage);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(500, "文件上传失败");
        }
        return fileStorage;
    }

    @Override
    public List<FileStorageDO> uploadFiles(HttpServletRequest request, List<FileBusinessInterface> list) {
        List<FileStorageDO> returnList = Lists.newArrayList();
        if (request instanceof MultipartHttpServletRequest) {
            MultiValueMap<String, MultipartFile> multiValueMap = ((MultipartHttpServletRequest) request)
                    .getMultiFileMap();
            if (CollectionUtil.isEmpty(multiValueMap.values())) {
                throw new ServiceException(400, FileUploadExceptionEnum.REQUEST_OBJECT_ERROR);
            }
            if (CollectionUtil.isEmpty(list)) {
                return null;
            }
            for (FileBusinessInterface fbi : list) {
                String code = fbi.getCode();
                List<MultipartFile> multipartFiles = multiValueMap.get(code);
                if (CollectionUtil.isNotEmpty(multipartFiles)) {
                    for (MultipartFile multipartFile : multipartFiles) {
                        FileStorageDO fileStorage = FileStorageUtil.createFileStorage(multipartFile, fbi);
                        //文件存储到本地
                        try {
                            multipartFile.transferTo(new File(fileStorage.getAbsolutePath()));
                            this.save(fileStorage);
                        } catch (IOException e) {
                            e.printStackTrace();
                            throw new ServiceException(500, "文件上传失败");
                        }
                        returnList.add(fileStorage);
                    }
                }

            }

        }
        return returnList;
    }

    @Override
    public List<FileStorageDO> findByBusinessId(Long businessId, String businessType) {
        LambdaQueryWrapper<FileStorageDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FileStorageDO::getBusinessId, businessId);
        if (!StringUtils.isEmpty(businessType)) {
            lambdaQueryWrapper.eq(FileStorageDO::getBusinessType, businessType);
        }
        List<FileStorageDO> fileStorageDOS = this.baseMapper.selectList(lambdaQueryWrapper);
        return fileStorageDOS;
    }

    @Override
    public FileStorageDO findOneByBusinessId(Long businessId, String businessType) {
        LambdaQueryWrapper<FileStorageDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FileStorageDO::getBusinessId, businessId)
                .eq(FileStorageDO::getBusinessType, businessType);
        lambdaQueryWrapper.last("limit 1");
        lambdaQueryWrapper.orderByDesc(FileStorageDO::getId);
        FileStorageDO fileStorageDO = this.baseMapper.selectOne(lambdaQueryWrapper);
        return fileStorageDO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBusinessId(List<Long> fileIds, Long businessId) {
        if (CollectionUtil.isNotEmpty(fileIds)) {
            lambdaUpdate().in(FileStorageDO::getId, fileIds).set(FileStorageDO::getBusinessId, businessId).update();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBusinessId(Long fileId, Long businessId) {
        if (fileId != null) {
            lambdaUpdate().eq(FileStorageDO::getId, fileId).set(FileStorageDO::getBusinessId, businessId).update();
        }
    }

    /**
     * 该接口 只能删除 图片上传人 和  操作人 一致的 数据
     * 删除id
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        Long userId = LoginUserHolder.get().getId();
        FileStorageDO one = this.lambdaQuery().eq(FileStorageDO::getId, id).eq(FileStorageDO::getUserCreate, userId).one();
        if (one == null) {
            throw new ServiceException(ExceptionEnum.SYSTEM_DATE_ERROR);
        }
        this.baseMapper.deleteById(one);
    }

    /**
     * 通过Url下载 采购合同文件、出征文件 并存储
     *
     * @param contractId
     * @param fileType
     * @param downUrl
     * @return
     */
    @Override
    public FileStorageDO addFileStorageWithBelongAndName(String contractId, FileTypeEnum fileType, String downUrl) {
        //文件重命名
        String fileName = "";
        if (FileTypeEnum.PURCHASE_CONTRACT_FILE.getCode().equals(fileType.getCode()) ||
                FileTypeEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT.getCode().equals(fileType.getCode()) ||
                FileTypeEnum.PURCHASE_CONTRACT_SIGN_FILE.getCode().equals(fileType.getCode())) {
            CPurchContractElectronicInfo purchContractElectronicInfo = purchContractElectronicInfoService.lambdaQuery().eq(CPurchContractElectronicInfo::getContractId, contractId).one();
            fileName = purchContractElectronicInfo.getContractName();
        } else if (FileTypeEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT.getCode().equals(fileType.getCode())) {
            SettlementBasicInfo settlementBasicInfo = settlementBasicInfoService.getById(Long.valueOf(contractId));
            fileName = settlementBasicInfo.getSettlementNumber();
        } else if (FileTypeEnum.SETTLEMENT_UPSTREAM_SIGNED_FILE.getCode().equals(fileType.getCode())) {
            SettlementBasicInfo settlementBasicInfo = settlementBasicInfoService.getById(Long.valueOf(contractId));
            List<SettlementGoodsInfo> settlementGoodsInfos = settlementGoodsInfoService.list(new QueryWrapper<SettlementGoodsInfo>()
                    .eq("c_settlement_basic_info_id", settlementBasicInfo.getId()));
            BigDecimal allPurchaseTotalPrice = BigDecimal.ZERO;
            if (CollectionUtil.isNotEmpty(settlementGoodsInfos)) {
                allPurchaseTotalPrice = settlementGoodsInfos.stream().map(SettlementGoodsInfo::getPurchaseTotalPrice)
                        .reduce(BigDecimal::add).orElse(new BigDecimal(0.00));
            }
            fileName = settlementBasicInfo.getSettlementNumber() + "-" + allPurchaseTotalPrice + "-上游结算已签署";
        } else if (FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN.getCode().equals(fileType)) {
            //文件重命名
            fileName = contractId;
        } else if (FileTypeEnum.PURCHASE_CONTRACT_SUPPLEMENT_SIGN_FILE.getCode().equals(fileType.getCode()) ||
                FileTypeEnum.PURCHASE_CONTRACT_SUPPLEMENT_FILE_REPORT.getCode().equals(fileType.getCode()) ||
                FileTypeEnum.PURCHASE_CONTRACT_SUPPLEMENT_FILE.getCode().equals(fileType.getCode())) {
            CPurchContractSupplementElectronicInfo purchContractSupplementElectronicInfo = supplementElectronicInfoService.lambdaQuery().eq(CPurchContractSupplementElectronicInfo::getContractId, contractId).one();
            fileName = purchContractSupplementElectronicInfo.getContractName();

        } else {
            fileName = contractId;
        }
        String name = fileType.getDesc();
        String suffix = ".pdf";
        if (
                FileTypeEnum.SETTLEMENT_UPSTREAM_SIGNED_FILE != fileType &&
                        FileTypeEnum.PURCHASE_CONTRACT_SUPPLEMENT_SIGN_FILE != fileType &&
                        FileTypeEnum.PURCHASE_CONTRACT_SUPPLEMENT_FILE != fileType &&
                        FileTypeEnum.PURCHASE_CONTRACT_FILE != fileType &&
                        FileTypeEnum.PURCHASE_CONTRACT_SIGN_FILE != fileType) {
            fileName = fileName + name;
        }

        FileStorageDO fileStorageDo = FileStorageUtil.createFileStorage2(fileName, suffix, fileType);
        String absolutePath = fileStorageDo.getAbsolutePath();
        File file = new File(absolutePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            FileUtil.downloadFile(downUrl, absolutePath);
            this.save(fileStorageDo);
            return fileStorageDo;
        } catch (Exception ve) {
            file.delete();
            throw new BusinessException(CodeUtil.FAIL, ve.getMessage());
        }
    }

    @Override
    public FileStorageDO addFileStorageWithBelongAndName(String contractId, String transactionId, FileTypeEnum fileType, String downUrl) {
        ContractElectronicInfo contractElectronicInfo;
        if (StringUtils.isEmpty(transactionId)) {
            contractElectronicInfo = contractElectronicInfoService.getOne(new QueryWrapper<ContractElectronicInfo>().eq("contract_id", contractId));
        } else {
            contractElectronicInfo = contractElectronicInfoService.getOne(new QueryWrapper<ContractElectronicInfo>().eq("auto_sign_transaction_id", transactionId));
        }
        ContractElectronicCustomerInfo contractElectronicCustomerInfo = contractElectronicCustomerInfoService.getOne(new QueryWrapper<ContractElectronicCustomerInfo>()
                .eq("transaction_id", transactionId));
        String fileName = contractId;
        if (contractElectronicInfo != null) {
            String[] split = contractElectronicInfo.getContractName().split("_");
            String contractName = split[0];
            ContractInfo contractInfo = contractInfoService.getById(contractElectronicInfo.getContractInfoId());
            ReviewQuotaDisburse reviewQuotaDisburse = reviewQuotaDisburseService.getById(contractInfo.getId());
            CFinancingBasicInfo financingBasicInfo = financingBasicInfoService.getById(reviewQuotaDisburse.getFinancingBasicInfoId());

            String customerName = "";
            if (financingBasicInfo != null && financingBasicInfo.getMainEnterpriseId() != null) {
                Enterprise enterprise = enterpriseService.getById(financingBasicInfo.getMainEnterpriseId());
                customerName = enterprise.getCorporateName();
            }
            //文件重命名
            fileName = customerName + contractName + contractInfo.getContractNo() + "_" + contractInfo.getQuotaDisburseBatch() + "_" + System.currentTimeMillis();
        } else if (contractElectronicCustomerInfo != null) {
            contractElectronicInfo = contractElectronicInfoService.getById(contractElectronicCustomerInfo.getContractElectronicInfoId());
            ContractInfo contractInfo = contractInfoService.getById(contractElectronicInfo.getContractInfoId());
            ReviewQuotaDisburse reviewQuotaDisburse = reviewQuotaDisburseService.getById(contractInfo.getReviewQuotaDisburseId());
            CFinancingBasicInfo financingBasicInfo = financingBasicInfoService.getById(reviewQuotaDisburse.getFinancingBasicInfoId());

            String customerName = "";
            if (financingBasicInfo != null && financingBasicInfo.getMainEnterpriseId() != null) {
                Enterprise enterprise = enterpriseService.getById(financingBasicInfo.getMainEnterpriseId());
                customerName = enterprise.getCorporateName();
            }
            //文件重命名
            fileName = customerName + "_" + contractElectronicInfo.getContractName() + "_" + contractInfo.getContractNo() + "_" + contractInfo.getQuotaDisburseBatch() + "_" + System.currentTimeMillis();
        }

        if (fileType.getCode().equals(FileTypeEnum.CONTRACT_REPORT_FIlE.getCode())) {
            fileName = FileTypeEnum.CONTRACT_REPORT_FIlE.getDesc() + fileName;
        }
        String suffix = ".pdf";

        FileStorageDO fileStorageDo = FileStorageUtil.createFileStorage2(fileName, suffix, fileType);
        String absolutePath = fileStorageDo.getAbsolutePath();
        File file = new File(absolutePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            FileUtil.downloadFile(downUrl, absolutePath);
            this.save(fileStorageDo);
            return fileStorageDo;
        } catch (Exception ve) {
            file.delete();
            throw new BusinessException(CodeUtil.FAIL, ve.getMessage());
        }
    }


    @Override
    public ResponseEntity<Object> downloadFile(Long id) {
        FileStorageDO fileStorage = this.getById(id);
        if (fileStorage != null) {
            String fileName = fileStorage.getOriginalName();
            String fileNameEncodeStr = "null";
            try {
                fileNameEncodeStr = java.net.URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                fileNameEncodeStr = "";
            }
            String path = fileStorage.getAbsolutePath();
            File file = new File(path);

            try {
                InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

                HttpHeaders headers = new HttpHeaders();
                headers.add("Content-Disposition", "attachment; filename=" + fileNameEncodeStr);
                headers.add("Cache-Control", "no-cache,no-store,must-revalidate");
                headers.add("Pragma", "no-cache");
                headers.add("Expires", "0");

                ResponseEntity<Object> responseEntity = ResponseEntity.ok()
                        .headers(headers)
                        .contentLength(file.length())
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .body(resource);
                return responseEntity;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void downloadZipFile(List<FileStorageDO> settlementAllFiles, String name, FileTypeEnum settlementZipFile, HttpServletResponse response) {
        File zipFile = downloadZip(settlementAllFiles, settlementZipFile);
        doDownloadZip(response, zipFile,name);
    }

    @Override
    public void renameFileStorageList(List<FileStorageDO> settlementAllFiles) {
        //根据文件原名进行去重
        Map<String, Integer> nameCounts = new HashMap<>();
        for (FileStorageDO file : settlementAllFiles) {
            nameCounts.put(file.getOriginalName(), nameCounts.getOrDefault(file.getOriginalName(), 0) + 1);
        }
        Set<String> duplicates = new HashSet<>();
        for (Map.Entry<String, Integer> entry : nameCounts.entrySet()) {
            if (entry.getValue() > 1) {
                duplicates.add(entry.getKey());
            }
        }
        Map<String, Integer> renameCounts = new HashMap<>();
        for (int i = 0; i < settlementAllFiles.size(); i++) {
            FileStorageDO fileStorage = settlementAllFiles.get(i);
            if (duplicates.contains(fileStorage.getOriginalName())) {
                int count = renameCounts.getOrDefault(fileStorage.getOriginalName(), 0) + 1;
                int index = fileStorage.getOriginalName().lastIndexOf(".");
                String newName = fileStorage.getOriginalName().substring(0, index) + DateUtil.dateToString(new Date(), "yyyyMMdd") + "-" + count + fileStorage.getBusinessType();
                renameCounts.put(fileStorage.getOriginalName(), count);
                fileStorage.setOriginalName(newName);
                settlementAllFiles.set(i, fileStorage);
            }
        }
    }

    @Override
    public void downloadPdfFile(HttpServletResponse response, File file) {
        OutputStream out = null;
        BufferedInputStream inputStream = null;
        try {
            response.setHeader("Content-Type", "application/vnd.ms-exce");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(file.getName(), "UTF-8"));
            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
            out = response.getOutputStream();
            inputStream = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[1024];
            while ((inputStream.read(buffer)) > 0) {
                out.write(buffer);
                out.flush();
            }

        } catch (Exception e) {
            throw new BusinessException(CodeUtil.FAIL, "下载失败!");
        } finally {
            try {
                inputStream.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 打包zip文件
     *
     * @param fileStorageList 文件
     * @param moduleType      文件所属模块枚举实例
     */
    public File downloadZip(List<FileStorageDO> fileStorageList, FileTypeEnum moduleType) {

//        try {
//            name = new String(name.getBytes("UTF-8"));
//        } catch (UnsupportedEncodingException e1) {
//            throw new BusinessException(CodeUtil.FAIL, "下载附件转码失败：" + e1.getMessage());
//        }
        String desPath = FileStorageUtil.getAbsolutePath(UUID.randomUUID().toString(), ".zip", moduleType);
        File zipFile = new File(desPath);
        if (!zipFile.getParentFile().exists()) {
            zipFile.getParentFile().mkdirs();
        }
        ZipOutputStream zipStream = null;
        FileInputStream zipSource = null;
        BufferedInputStream bufferStream = null;
        try {
            // 构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            for (FileStorageDO fileStorage : fileStorageList) {
                String path = fileStorage.getAbsolutePath();
                File file = new File(path);
                // 将需要压缩的文件格式化为输入流
                zipSource = new FileInputStream(file);
                // 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样
                ZipEntry zipEntry = new ZipEntry(fileStorage.getOriginalName());
                // 定位该压缩条目位置，开始写入文件到压缩包中
                zipStream.putNextEntry(zipEntry);
                // 输入缓冲流
                bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
                int read = 0;
                // 创建读写缓冲区
                byte[] buf = new byte[1024 * 10];
                while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
                    zipStream.write(buf, 0, read);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                if (null != bufferStream) {
                    bufferStream.close();
                }
                if (null != zipStream) {
                    zipStream.close();
                }
                if (null != zipSource) {
                    zipSource.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return zipFile;
    }

    /**
     * 下载文件夹
     *
     * @param res
     * @param file
     */
    public void doDownloadZip(HttpServletResponse res, File file,String name) {
        try {
            if (file.exists()) {
                //fileName = new String(fileName.getBytes("UTF-8"));
                String basePath = file.getAbsolutePath();
                InputStream in = new FileInputStream(new File(basePath));
                String fileName = URLEncoder.encode(name, "UTF-8");
                String type = file.getName().substring(file.getName().lastIndexOf("."));

                res.setHeader("content-disposition", "attachment;filename=" + fileName+type);
                OutputStream out = res.getOutputStream();
                byte[] b = new byte[1024];
                int len = -1;
                while ((len = in.read(b)) != -1) {
                    out.write(b, 0, len);
                }
                // 关闭
                out.close();
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
