package com.dxhy.sign.controller;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.api.model.config.Business;
import com.dxhy.api.model.config.UserInfo;
import com.dxhy.api.model.sign.ElecInvoiceRespVO;
import com.dxhy.api.model.sign.ElecQueryReqVO;
import com.dxhy.api.model.sign.TDxInvoiceImg;
import com.dxhy.common.aspect.SysLog;
import com.dxhy.common.constant.CommonConstants;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.controller.AbstractController;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.util.*;
import com.dxhy.common.utils.R;
import com.dxhy.jxpt.baseService.sign.service.elec.SignElecInvoiceService;
import com.dxhy.jxpt.baseService.sign.service.elec.SignInvoiceImgService;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.FileService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author peipei.li
 * @date 2019-04-29 电票管理相关入口
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
@RestController
@RequestMapping("elec")

@Slf4j
public class SignElecInvoiceController extends AbstractController {

    @Resource
    private SignElecInvoiceService signElecInvoiceService;
    @Resource
    private FileService fileService;

    @Value("${ftp.connection.size}")
    private String size;
    /**
     * 上传时本地文件暂存路径
     */
    @Value("${ftp.connection.tempPath}")
    private String tempPath;
    /**
     * 上传时本地文件存放路径
     */
    @Value("${ftp.connection.depositPath}")
    private String depositPath;

    @Resource
    private SignInvoiceImgService signInvoiceImgService;

    /**
     * 电票查询
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    @RequestMapping("list/listElecQuery")
    @SysLog("电票查询")
    public ResponseEntity<R> listElecQuery(@RequestBody ElecQueryReqVO reqVO) {
        try {
            reqVO.setUserInfo(getUserInfo());
            return ResponseEntity.ok(R.ok().put("data", signElecInvoiceService.listPageElecInvoice(reqVO)));
        } catch (Exception e) {
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    /**
     * 获取电票图片
     *
     * @param response
     *            请求参数
     * @throws Exception
     *             异常
     */
    @RequestMapping("list/getImg")
    @SysLog("查看图片")
    public ResponseEntity<R> getImg(@RequestBody Map<String, String> pramsMap, HttpServletResponse response)
        throws Exception {
        if (StringHelper.isBlank(pramsMap.get("uuid"))) {
            return ResponseEntity.ok(R.error("请检查参数！"));
        }
        ServletOutputStream out = null;
        FileInputStream ips = null;
        String localPath = fileService.getLocalPathDefault() + "img/" + getUserName() + "/";
        String imgPath = signElecInvoiceService.getImgByUuid(pramsMap.get("uuid"), getUserInfo(), localPath);
        // 获取图片存放路径
        if (StringHelper.isBlank(imgPath)) {
            return ResponseEntity.ok(R.error("该发票无图片！"));
        }
        File imgFile = new File(imgPath);
        try {
            ips = new FileInputStream(imgFile);
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            out = response.getOutputStream();
            // 读取文件流
            int len;
            byte[] buffer = new byte[1024 * 10];
            while ((len = ips.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.flush();

        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
        } finally {
            // 删除临时文件
            // 清空临时文件里面的文件
            FileUtils.deleteDir(new File(localPath));
            if (out != null) {
                out.close();
            }
            if (ips != null) {
                ips.close();
            }
        }
        return null;
    }

    @RequestMapping("/getFile")
    @ResponseBody
    @SysLog("获取文件流信息")
    public Object getImg(@RequestBody Map<String, String> pramsMap) {

        if (StringHelper.isBlank(pramsMap.get("imgOrFile"))) {
            return ResponseEntity.ok(R.error("请检查参数！"));
        }
        if(!"3".equals(pramsMap.get("imgOrFile"))){
            if (StringHelper.isBlank(pramsMap.get("scanId"))) {
                return ResponseEntity.ok(R.error("请检查参数！"));
            }
        }

        try {
            String localPath = fileService.getLocalPathDefault() + "file/" + getUserName() + "/";
            //0进项详情  1销项详情
            return signElecInvoiceService.getFileByScanId(pramsMap.get("scanId"), pramsMap.get("imgOrFile"),pramsMap.get("uuid"),pramsMap.get("downloadType"),pramsMap.get("pageType"),
                getUserInfo(), localPath);
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    /**
     * 上传发票文件
     *
     * @param file
     *            文件
     * @return 返回结果
     */
    @PostMapping("edit/uploadFile")
    @SysLog("上传电子发票")
    public ResponseEntity<R> uploadFile(MultipartFile file, String businessCode) {
        try {
            log.debug("businessCode =--------------- " + businessCode);
            // 业务单元信息设置
            UserInfo userInfo = getUserInfo();
            String businessName = "";
            if (StringUtils.isNoneBlank(businessCode) && !"99".equals(businessCode)) {
                List<Business> businessList = userInfo.getBusiness();
                for (Business business : businessList) {
                    if (business.getBusinessCode().equals(businessCode)) {
                        businessName = business.getBusinessName();
                    }
                }
            } else {
                businessCode = "";
            }
            boolean checkFileSize = FileUtils.checkFileSize(file.getSize(), Integer.parseInt(size), "M");
            if (!checkFileSize) {
                return ResponseEntity.ok(R.error("上传文件大于 " + size + "M").put("code", "505"));
            }
            String filename = file.getOriginalFilename();
            String prefix = filename != null ? filename.substring(filename.lastIndexOf(".") + 1) : null;
            if (!"zip".equals(prefix) && !"pdf".equals(prefix) && !"ZIP".equals(prefix) && !"PDF".equals(prefix)
                && !"ofd".equals(prefix) && !"OFD".equals(prefix)
                && !"xml".equals(prefix) && !"XML".equals(prefix)
            ) {
                return ResponseEntity.ok(R.error("请上传pdf、ofd、xml文件或者pdf、ofd、xml的压缩文件(.zip)！"));
            }

            // 文件名称
            String fileName = signElecInvoiceService.getOriginalFilename(file.getOriginalFilename());
            // 上传文件重新命名
            String pdfFileName = userInfo.getUsername() + "_" + DateTimeHelper.formatNowDate("yyyyMMddHHmmss")
                + fileName.substring(fileName.indexOf("."));
            // 创建临时存储文件夹
            String tempPathPdf =
                tempPath + userInfo.getUsername() + "_" + DateTimeHelper.formatNowDate("yyyyMMddHHmmss") + "/";
            signElecInvoiceService.createFileDir(tempPathPdf);
            File newFile = new File(tempPathPdf + pdfFileName);
            try {
                file.transferTo(newFile.getAbsoluteFile());
                boolean sourseIsZip = false;
                if (fileName.contains("zip") || fileName.contains("ZIP")) {
                    // 若用户上传的是zip压缩文件,对文件进行解压
                    ZipUtil.unzip(tempPathPdf + pdfFileName);
                    // 对上传的文件进行移动保存
                    FileUtil.move(newFile, new File(depositPath), true);
                    sourseIsZip = true;
                } else if (fileName.contains("ofd") || fileName.contains("OFD")) {
                    // 对用ofd上传，压缩ofd文件，然后保存
                    ZipUtil.zip(newFile, Boolean.FALSE);
                    List<File> zipFiles = FileUtils.findFile(tempPathPdf, "zip");
                    for (File zipFile : zipFiles) {
                        // 对上传的文件进行移动保存
                        FileUtil.move(zipFile, new File(depositPath), true);
                    }
                } else if (fileName.contains("xml") || fileName.contains("XML")) {
                    // 对用xml上传，压缩xml文件，然后保存
                    ZipUtil.zip(newFile, Boolean.FALSE);
                    List<File> zipFiles = FileUtils.findFile(tempPathPdf, "zip");
                    for (File zipFile : zipFiles) {
                        // 对上传的文件进行移动保存
                        FileUtil.move(zipFile, new File(depositPath), true);
                    }
                } else {
                    // 对用pdf上传，压缩pdf文件，然后保存
                    ZipUtil.zip(newFile, Boolean.FALSE);
                    List<File> zipFiles = FileUtils.findFile(tempPathPdf, "zip");
                    for (File zipFile : zipFiles) {
                        // 对上传的文件进行移动保存
                        FileUtil.move(zipFile, new File(depositPath), true);
                    }
                }
                // 获取临时文件夹里的所有pdf文件
                List<File> files = null;
                //压缩包判断里面是否还有压缩包
                if(fileName.contains("zip")
                        || fileName.contains("ZIP")){
                    log.info("开始验证zip包里不支持的文件后缀并做提示");
                    Map<String,Object> result = findZipAllFiles(tempPathPdf , pdfFileName ,fileName);
                    //如果压缩包里有问题，提示出去
                    if(((List<NotAllowShowDto>) result.get("notAllowlist")).size()>0){
                        return ResponseEntity.ok(R.error("请上传pdf、ofd、xml文件或者pdf、ofd、xml的压缩文件(.zip)！").put("notAllowlist", result.get("notAllowlist")));
                    }
                    //找到所有支持的文件
                    files = (List<File>) result.get("allFiles");
                }
                //单张的保持原有逻辑
                else if (fileName.contains("pdf") || fileName.contains("PDF")
                      || fileName.contains("ofd") || fileName.contains("OFD")
                        || fileName.contains("xml") || fileName.contains("XML")
                        //||fileName.contains("zip")
                        //|| fileName.contains("ZIP")
                ) {
                    files = FileUtils.findFile(tempPathPdf, "");
                }
                List<File> pdfFile = new ArrayList<>();
                List<File> ofdFile = new ArrayList<>();
                List<File> xmlFile = new ArrayList<>();
                if (files != null && files.size() > 0) {
                    for (File fi : files) {
                        String name = fi.getName();
                        if (!name.contains("pdf") && !name.contains("PDF") && !name.contains("ZIP")
                            && !name.contains("zip") && !name.contains("ofd") && !name.contains("OFD")
                                && !name.contains("xml") && !name.contains("XML")
                        ) {
                            return ResponseEntity.ok(R.error("请上传pdf、ofd、xml文件或者pdf、ofd、xml的压缩文件(.zip)！"));
                        }
                        if (name.contains("pdf") || name.contains("PDF")) {
                            pdfFile.add(fi);
                        }
                        if (name.contains("ofd") || name.contains("OFD")) {
                            ofdFile.add(fi);
                        }
                        if (name.contains("xml") || name.contains("XML")) {
                            xmlFile.add(fi);
                        }
                    }

                    JSONObject saveUploadElecFile = signElecInvoiceService.saveUploadElecFile(pdfFile, ofdFile,xmlFile,
                        userInfo, pdfFileName, tempPathPdf, businessName, businessCode,sourseIsZip,fileName);
                    return ResponseEntity.ok(R.ok().put("data", saveUploadElecFile));
                } else {
                    return ResponseEntity.ok(R.error("请上传pdf、ofd、xml文件或者pdf、ofd、xml的压缩文件(.zip)！"));
                }
            } catch (Exception e) {
               log.info("业务处理异常：{}", e);
                return ResponseEntity.ok(R.error("业务处理异常，请联系管理员").put("code", "9999"));
            } finally {
                //if(fileName.contains("zip")
                //        || fileName.contains("ZIP")){
                //    //删除文件夹
                //    FileUtil.del(tempPathPdf);
                //}
            }

        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error("上传失败，请查看上传文件是否正确。"));
        }
    }

    /**
    * @Description 获取到压缩包里所有压缩文件，包括二次压缩
    * @Author wangruwei
    * @Date 2023/8/28 10:20
    **/
    private Map<String,Object> findZipAllFiles(String tempPathPdf, String pdfFileName, String sourceFileName) throws Exception {
        //String tempPathPdf = "E:\\a\\yasuo\\";
        //FileUtil.del(tempPathPdf+"\\XXXX0");
        ////String pdfFileName = "1成1败xml.zip";
        //String pdfFileName = "XXXX0.zip";

        sourceFileName = sourceFileName.substring(0, sourceFileName.indexOf("."));

        Map<String,Object> resultMap = new HashMap();
        //第一次解压
        ZipUtil.unzip(tempPathPdf + pdfFileName);
        //获取解压的文件
        List<File> files = FileUtils.findFile(tempPathPdf, "");
        //定义不允许的文件列表
        List<NotAllowFile> notAllowlist = new LinkedList();
        //返回给前端的列表，按顺序展示
        List<NotAllowShowDto> notAllowShowlist = new LinkedList();
        //定义获取到的文件
        List<AllowFileDto> allFiles = new LinkedList();
        for (int i = 0; i < files.size(); i++) {
            //如果解压开的文件是压缩包，继续解压
            if(files.get(i).getName().endsWith("zip")||files.get(i).getName().endsWith("ZIP")){
                // 第二次解压，也是最后一层
                String nextZipfolderPath = ZipUtil.unzipCreateFolder(tempPathPdf + File.separator + files.get(i).getName());
                //获取解压的文件
                List<File> nextFiles = FileUtils.findFile(nextZipfolderPath, "");
                for (int j = 0; j < nextFiles.size(); j++) {
                    //只要不是pdf，ofd,xml，都打印出错误来
                    String name = nextFiles.get(j).getName();
                    if(name.contains("xlsx")||name.contains("XLSX")||name.contains("xls")||name.contains("XLS")){
                        log.info("二级压缩包里的excel文件不做处理");
                        continue;
                    }
                    if (!name.contains("pdf") && !name.contains("PDF") && !name.contains("ZIP")
                            && !name.contains("zip") && !name.contains("ofd") && !name.contains("OFD")
                            && !name.contains("xml") && !name.contains("XML")){
                        NotAllowFile notAllowFile = new NotAllowFile();
                        notAllowFile.setParentPath(sourceFileName + File.separator +nextFiles.get(j).getParent().replace("\\","/").replace(tempPathPdf, "").replace("\\","/"));
                        notAllowFile.setFileName(name);
                        notAllowFile.setSortNum(1);
                        notAllowlist.add(notAllowFile);
                    }else{
                        AllowFileDto item = new AllowFileDto();
                        item.setSortNum(1);
                        item.setFile(new File(nextZipfolderPath+File.separator+name));
                        allFiles.add(item);
                    }
                }
            }else if(files.get(i).getName().contains("pdf") || files.get(i).getName().contains("PDF")
                    || files.get(i).getName().contains("ofd") || files.get(i).getName().contains("OFD")
                    || files.get(i).getName().contains("xml") || files.get(i).getName().contains("XML")
            ){
                //根目录下允许的文件
                AllowFileDto item = new AllowFileDto();
                item.setSortNum(0);
                item.setFile(new File(tempPathPdf + File.separator + files.get(i).getName()));
                allFiles.add(item);
            } else{
                if(files.get(i).getName().contains("xlsx")||files.get(i).getName().contains("XLSX")||files.get(i).getName().contains("xls")||files.get(i).getName().contains("XLS")){
                    log.info("压缩包里的excel文件不做处理");
                    continue;
                }
                //根目录下不允许的文件
                NotAllowFile notAllowFile = new NotAllowFile();
                //notAllowFile.setParentPath(sourceFileName + File.separator + tempPathPdf.replace("\\","/").replace(tempPathPdf, "").replace("\\","/"));
                notAllowFile.setParentPath(sourceFileName);
                notAllowFile.setFileName(files.get(i).getName());
                notAllowFile.setSortNum(0);
                notAllowlist.add(notAllowFile);
            }
        }

        //按文件夹分组显示
        LinkedHashMap<String, List<NotAllowFile>> collect = notAllowlist.stream()
                .sorted(Comparator.comparing(item->item.getSortNum()))
                .collect(Collectors.groupingBy(e -> e.getParentPath(), LinkedHashMap::new, Collectors.toList()) );

        //给前端展示的实体处理
        collect.forEach((key, list) -> {
            NotAllowShowDto item = new NotAllowShowDto();
            item.setShowPath(key);
            item.setFileList(list);
            notAllowShowlist.add(item);
        });

        resultMap.put("notAllowlist", notAllowShowlist);
        //排序展示，最外层的放外面
        List<File> useFileList = allFiles.stream().sorted((Comparator.comparing(item -> item.getSortNum()))).map(e -> e.getFile()).collect(Collectors.toList());
        resultMap.put("allFiles", useFileList);
        log.info("不被允许导入的文件:{}",JSON.toJSONString(notAllowlist));

        log.info("最后获取到的所有文件个数{}",allFiles.size());

        System.out.println("最后把解压文件的根目录删除掉");
        return resultMap;
    }

    @Data
    public static class NotAllowFile {
        //文件所处目录，不包括当前文件名
        private String parentPath;
        //文件名
        private String fileName;
        //排序,最外层0，第二层1
        private int sortNum;
    }

    @Data
    public static class NotAllowShowDto {
        //文件所处目录
        private String showPath;
        //目录下不被允许的文件列表
        private List<NotAllowFile> fileList;
    }

    @Data
    public static class AllowFileDto {
        //文件所处目录
        private File file;
        //排序,最外层0，第二层1
        private int sortNum;
    }

    public static void main(String[] args) throws Exception {
        String tempPath = "/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230830102147/";
        String key = "/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230830102147/";
        key = key.replace(tempPath, "").replace("\\", "");
        System.out.println(key);

        if(true){
            return;
        }

        String tempPathPdf = "E:\\a\\yasuo\\";
        FileUtil.del(tempPathPdf+"\\XXXX0");
        //String pdfFileName = "1成1败xml.zip";
        String pdfFileName = "XXXX0.zip";

        Map<String,Object> resultMap = new HashMap();
        //第一次解压
        ZipUtil.unzip(tempPathPdf + pdfFileName);
        //String folderPath = tempPathPdf;

        List<String> allFilesPath = new LinkedList();
        //获取解压的文件
        List<File> files = FileUtils.findFile(tempPathPdf, "");
        //定义不允许的文件列表
        List<NotAllowFile> notAllowlist = new LinkedList();
        //定义获取到的文件
        List<File> allFiles = new LinkedList();
        for (int i = 0; i < files.size(); i++) {
            //判断，如果是压缩包，继续压缩
            //System.out.println(files.get(i).getName());

            //如果解压开的文件是压缩包，继续解压
            if(files.get(i).getName().endsWith("zip")||files.get(i).getName().endsWith("ZIP")){
                // 第二次解压，也是最后一层
                String nextZipfolderPath = ZipUtil.unzipCreateFolder(tempPathPdf + File.separator + files.get(i).getName());
                //获取解压的文件
                List<File> nextFiles = FileUtils.findFile(nextZipfolderPath, "");
                for (int j = 0; j < nextFiles.size(); j++) {
                    //只要不是pdf，ofd,xml，都打印出错误来
                    String name = nextFiles.get(j).getName();

                    if(name.contains("xlsx")||name.contains("XLSX")||name.contains("xls")||name.contains("XLS")){
                        log.info("二级压缩包里的excel文件不做处理");
                        continue;
                    }

                    if (!name.contains("pdf") && !name.contains("PDF") && !name.contains("ZIP")
                            && !name.contains("zip") && !name.contains("ofd") && !name.contains("OFD")
                            && !name.contains("xml") && !name.contains("XML")){
                        //System.out.println(nextFiles.get(j).getParent()+"**此文件夹内有问题**"+name);
                        NotAllowFile notAllowFile = new NotAllowFile();
                        notAllowFile.setParentPath(nextFiles.get(j).getParent().replace("\\","/"));
                        notAllowFile.setFileName(name);
                        notAllowlist.add(notAllowFile);
                        //notAllowlist.add(nextFiles.get(j).getParent().replace("\\","/")+"下"+name);
                    }else{
                        allFilesPath.add(nextZipfolderPath+File.separator+name);
                        allFiles.add(new File(nextZipfolderPath+File.separator+name));
                    }
                }
            }else if(files.get(i).getName().contains("pdf") || files.get(i).getName().contains("PDF")
                    || files.get(i).getName().contains("ofd") || files.get(i).getName().contains("OFD")
                    || files.get(i).getName().contains("xml") || files.get(i).getName().contains("XML")
            ){
                //根目录下允许的文件
                allFilesPath.add(files.get(i).getName());
                allFiles.add(new File(tempPathPdf + File.separator + files.get(i).getName()));
            } else{
                //System.out.println(tempPathPdf+"**此文件夹内有问题**"+files.get(i).getName());
                //notAllowlist.add(tempPathPdf.replace("\\","/")+"下"+files.get(i).getName());
                NotAllowFile notAllowFile = new NotAllowFile();
                notAllowFile.setParentPath(tempPathPdf.replace("\\","/"));
                notAllowFile.setFileName(files.get(i).getName());
                notAllowlist.add(notAllowFile);
            }
        }

        //按文件夹分组显示
        Map<String, List<NotAllowFile>> notAllowlistMap = notAllowlist.stream().collect(Collectors.groupingBy(e -> e.getParentPath()));
        resultMap.put("notAllowlist", notAllowlistMap);
        resultMap.put("allFiles", allFiles);
        log.info("不被允许导入的文件:{}",JSON.toJSONString(notAllowlistMap));

        log.info("最后获取到的所有文件"+allFiles);

        System.out.println("最后把解压文件的根目录删除掉");

        if(true){
            return;
        }

        String result = "[\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"company\": \"150001205110278555\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/123.xml\",\n" +
                "            \"readPdfSuccess\": false,\n" +
                "            \"readPdfSuccessDesc\": \"123.xml解析发票失败\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"checkCode\": \"\",\n" +
                "            \"delState\": true,\n" +
                "            \"editState\": true,\n" +
                "            \"eleInvoiceNo\": \"23942000000001906905\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX/数电票.xml\",\n" +
                "            \"imgPath\": \"/data/sftp/jxpt/elec/image/20230828/1693207086510-f52cd896ae9e45aeaa929c018d3a7747.png\",\n" +
                "            \"imgState\": true,\n" +
                "            \"invoiceAmount\": \"470400.00\",\n" +
                "            \"invoiceCode\": \"239420000000\",\n" +
                "            \"invoiceDate\": \"2023-03-30\",\n" +
                "            \"invoiceNo\": \"01906905\",\n" +
                "            \"invoiceType\": \"31\",\n" +
                "            \"qsDesc\": \"超过该张票当天查验次数\",\n" +
                "            \"qsStatusName\": \"签收失败\",\n" +
                "            \"readPdfSuccess\": true,\n" +
                "            \"readPdfSuccessDesc\": \"数电票.xml解析xml成功\",\n" +
                "            \"scanId\": \"6f23a78cdd924ffca246a7b251fbbfcf\",\n" +
                "            \"totalAmount\": \"470400.00\",\n" +
                "            \"uuid\": \"23942000000001906905\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"checkCode\": \"\",\n" +
                "            \"delState\": true,\n" +
                "            \"editState\": true,\n" +
                "            \"eleInvoiceNo\": \"23942000000001906905\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX/数电票2.xml\",\n" +
                "            \"imgPath\": \"/data/sftp/jxpt/elec/image/20230828/1693207091193-4e5ac45fdae642d2a9d3028da3444da3.png\",\n" +
                "            \"imgState\": true,\n" +
                "            \"invoiceAmount\": \"470400.00\",\n" +
                "            \"invoiceCode\": \"239420000000\",\n" +
                "            \"invoiceDate\": \"2023-03-30\",\n" +
                "            \"invoiceNo\": \"01906905\",\n" +
                "            \"invoiceType\": \"31\",\n" +
                "            \"qsDesc\": \"超过该张票当天查验次数\",\n" +
                "            \"qsStatusName\": \"签收失败\",\n" +
                "            \"readPdfSuccess\": true,\n" +
                "            \"readPdfSuccessDesc\": \"数电票2.xml解析xml成功\",\n" +
                "            \"scanId\": \"baf409f66d6c4d17991be706ad3914fb\",\n" +
                "            \"totalAmount\": \"470400.00\",\n" +
                "            \"uuid\": \"23942000000001906905\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"company\": \"150001205110278555\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX/数电票3空内容.xml\",\n" +
                "            \"readPdfSuccess\": false,\n" +
                "            \"readPdfSuccessDesc\": \"数电票3空内容.xml解析发票失败\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"company\": \"150001205110278555\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX1\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX1/1111空内容.xml\",\n" +
                "            \"readPdfSuccess\": false,\n" +
                "            \"readPdfSuccessDesc\": \"1111空内容.xml解析发票失败\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"businessCode\": \"AQB\",\n" +
                "            \"businessName\": \"安全部\",\n" +
                "            \"checkCode\": \"\",\n" +
                "            \"delState\": true,\n" +
                "            \"editState\": true,\n" +
                "            \"eleInvoiceNo\": \"23942000000001906905\",\n" +
                "            \"fileParentPath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX2\",\n" +
                "            \"filePath\": \"/home/dxhy/data/tertiary/jxfp/pdf/item/wrw_20230828151803/XXXX2/数电票01.xml\",\n" +
                "            \"imgPath\": \"/data/sftp/jxpt/elec/image/20230828/1693207096751-375c03b17170488081e616b90a3eaf80.png\",\n" +
                "            \"imgState\": true,\n" +
                "            \"invoiceAmount\": \"470400.00\",\n" +
                "            \"invoiceCode\": \"239420000000\",\n" +
                "            \"invoiceDate\": \"2023-03-30\",\n" +
                "            \"invoiceNo\": \"01906905\",\n" +
                "            \"invoiceType\": \"31\",\n" +
                "            \"qsDesc\": \"超过该张票当天查验次数\",\n" +
                "            \"qsStatusName\": \"签收失败\",\n" +
                "            \"readPdfSuccess\": true,\n" +
                "            \"readPdfSuccessDesc\": \"数电票01.xml解析xml成功\",\n" +
                "            \"scanId\": \"07f65dbc3ec84454ab521025bbafd07a\",\n" +
                "            \"totalAmount\": \"470400.00\",\n" +
                "            \"uuid\": \"23942000000001906905\"\n" +
                "        }\n" +
                "    ]";

        List<ElecInvoiceRespVO> vos = JSON.parseArray(result, ElecInvoiceRespVO.class);
        //筛选出出错的文件，并按所属位置分组
        Map<String, List<ElecInvoiceRespVO>> collect = vos.stream()
                //.filter(e -> e.getReadPdfSuccess() == false)
                .collect(Collectors.groupingBy(ElecInvoiceRespVO::getFileParentPath));
        System.out.println(JSON.toJSONString(collect));


        Map<String,List<ElecInvoiceRespVO>> showMap = new HashMap();
        for (Map.Entry<String,  List<ElecInvoiceRespVO>> entry : collect.entrySet()) {
            String key_ = entry.getKey();
            List<ElecInvoiceRespVO> value = entry.getValue();
            showMap.put(key_, value);
        }

        if(true){
            return;
        }





    }

    /**
     * 手工录入电子发票
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    @PostMapping("edit/saveManualElec")
    @SysLog("手工录入电子发票")
    public ResponseEntity<R> saveManualElec(@RequestBody ElecInvoiceRespVO reqVO) {
        try {
//            if (StringHelper.isBlank(reqVO.getInvoiceCode())) {
//                return ResponseEntity.ok(R.error("发票代码不能为空！"));
//            }
            if (StringHelper.isBlank(reqVO.getInvoiceNo())) {
                return ResponseEntity.ok(R.error("发票号码不能为空！"));
            }
            if(reqVO.getInvoiceNo().length()!=20){
                InvoiceUtil iu = new InvoiceUtil(reqVO.getInvoiceCode());
                if (!(FplxEnum.QDZZP.getFplxDm().equals(reqVO.getInvoiceType()) || FplxEnum.QDPP.getFplxDm().equals(reqVO.getInvoiceType()))) {
                    reqVO.setInvoiceType(iu.getFplxdm());
                    if(reqVO.getInvoiceNo().length()!=20){
                        if (StringHelper.isBlank(reqVO.getInvoiceCode())) {
                            return ResponseEntity.ok(R.error("发票代码不能为空！"));
                        }
                    }
                }
            }else{
                //发票号码为20位，种类设为31，后续查验后以查验结果的票种为准
                reqVO.setInvoiceType(FplxEnum.QDZZP.getFplxDm());
            }

            if (FplxEnum.QDZZP.getFplxDm().equals(reqVO.getInvoiceType())
                    || FplxEnum.QDPP.getFplxDm().equals(reqVO.getInvoiceType())) {
                //reqVO.setInvoiceAmount(reqVO.getTotalAmount());
            }
            if (FplxEnum.ZP.getFplxDm().equals(reqVO.getInvoiceType())
                || FplxEnum.JDC.getFplxDm().equals(reqVO.getInvoiceType())
                || FplxEnum.DZZP.getFplxDm().equals(reqVO.getInvoiceType())
                || FplxEnum.QDZZP.getFplxDm().equals(reqVO.getInvoiceType())
                || FplxEnum.QDPP.getFplxDm().equals(reqVO.getInvoiceType())
                || reqVO.getInvoiceNo().length()==20
            ) {
                if (StringHelper.isBlank(reqVO.getInvoiceAmount())) {
                    return ResponseEntity.ok(R.error("金额不能为空！"));
                }
            } else {
                if (StringHelper.isBlank(reqVO.getCheckCode())) {
                    return ResponseEntity.ok(R.error("校验码不能为空！"));
                }
            }
            if (reqVO.getInvoiceDate() == null) {
                return ResponseEntity.ok(R.error("开票日期不能为空！"));
            }

            // 业务单元参数设置
            UserInfo userInfo = getUserInfo();
            String businessName = "";
            String businessCode = reqVO.getBusinessCode();
            if (StringUtils.isNoneBlank(businessCode) && !"99".equals(businessCode)) {
                List<Business> businessList = userInfo.getBusiness();
                for (Business business : businessList) {
                    if (business.getBusinessCode().equals(reqVO.getBusinessCode())) {
                        businessName = business.getBusinessName();
                    }
                }
            } else {
                businessCode = "";
            }
            reqVO.setBusinessCode(businessCode);
            reqVO.setBusinessName(businessName);
            reqVO.setCompany(userInfo.getCompany());
            return ResponseEntity.ok(R.ok().put("data", signElecInvoiceService.saveManualElec(reqVO, userInfo)));
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    @RequestMapping("/deleteElec")
    @SysLog("删除签收失败发票")
    public ResponseEntity<R> deleteElec(@RequestBody Map<String, String> pramsMap) {
        try {
            // 删除 扫描表信息
            boolean deleteElec = signElecInvoiceService.deleteElec(pramsMap.get("scanId"), getUserInfo().getDbName());
            if (deleteElec) {
                return ResponseEntity.ok(R.ok().put("data", "删除成功！"));
            } else {
                return ResponseEntity.ok(R.error("删除失败！"));
            }
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    @RequestMapping("/deleteElecByID")
    @SysLog("删除签收失败发票")
    public ResponseEntity<R> deleteElecByID(@RequestBody Map<String, String> pramsMap) {
        try {
            // 删除 扫描表信息
            boolean deleteElec = signElecInvoiceService.deleteElecByID(pramsMap.get("id"), getUserInfo().getDbName());
            if (deleteElec) {
                return ResponseEntity.ok(R.ok().put("data", "删除成功！"));
            } else {
                return ResponseEntity.ok(R.error("删除失败！"));
            }
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    @ResponseBody
    @RequestMapping(value = "/updownImg")
    public void getImg(HttpServletRequest request, String scanId, HttpServletResponse response) {
        TDxInvoiceImg img;
        String downLondFile = "";
        try {

            DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
            img = signInvoiceImgService.selectByUuid(scanId);

            if (null != img) {
                String[] fileAccount = null;
                if (img.getImagePath() != null) {
                    fileAccount = img.getImagePath().split("/");
                }
                String name = fileAccount[fileAccount.length - 1];
                downLondFile =
                    fileService.getLocalPathDefault() + "img/" + new SimpleDateFormat("yyyyMMdd").format(new Date())
                        + "/" + new File(img.getImagePath()).getName();
                FileModel fileModel = fileService.downFile(img.getImagePath(), downLondFile);
                byte[] zipFile;

                if (name.contains(".zip")) {
                    zipFile = ZipUtils.readZipFile(fileModel.getFilePath());
                } else {

                    zipFile = ZipUtils.readInputStream(new FileInputStream(new File(fileModel.getFilePath())));
                }
                // 从网盘下载照片的流
                InputStream in = new ByteArrayInputStream(zipFile);

                // 声明输出流，但是要从HttpServletResponse中获取才管用
                BufferedOutputStream bout = new BufferedOutputStream(response.getOutputStream());
                // 从输入流到输出流
                byte[] b = new byte[1024];
                int len = in.read(b);
                while (len > 0) {
                    bout.write(b, 0, len);
                    len = in.read(b);
                }

            }

        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
        } finally {
            try {
                if (org.apache.commons.lang3.StringUtils.isNotBlank(downLondFile)) {
                    String path = new File(downLondFile).getParent();
                    cn.hutool.core.io.FileUtil.del(new File(path));
                }

            } catch (Exception e) {
               log.info("业务处理异常：{}", e);
            }
        }
    }
}
