package cn.quantgroup.customer.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import cn.quantgroup.customer.entity.TransactionReceiptRecord;
import cn.quantgroup.customer.rest.enums.VoucherExportStatus;
import cn.quantgroup.customer.rest.param.mail.SendMailParam;
import cn.quantgroup.customer.rest.vo.transaction.TransactionReceiptRecordVO;
import cn.quantgroup.customer.repo.TransactionReceiptRecordRepo;
import cn.quantgroup.customer.rest.param.transactionreceipt.TransactionReceiptRecordQuery;
import cn.quantgroup.customer.rest.vo.JsonResult;
import cn.quantgroup.customer.rest.vo.transaction.*;
import cn.quantgroup.customer.service.ITransactionReceiptRecordService;
import cn.quantgroup.customer.service.http.IHttpService;
import cn.quantgroup.customer.util.*;
import cn.quantgroup.user.retbean.XUser;
import cn.quantgroup.user.vo.UserSysResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.io.InputStreamResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.List;


@Slf4j
@RefreshScope
@Service("transactionReceiptRecordService")
public class TransactionReceiptRecordServiceImpl implements ITransactionReceiptRecordService {

    @Autowired
    private TransactionReceiptRecordRepo transactionReceiptRecordRepo;
    @Autowired
    private ExcelUtil excelUtil;
    @Autowired
    private  IHttpService httpService;

    @Autowired
    private  UserSdkImpl userSdk;

    @Value("${kdsp-operation}")
    private String kdspOperationUrl;

    @Value("${pdf.quantgroup.cn.http}")
    private String contractUrl;

    @Value("${passportapi2.tjzimu.http}")
    private String userSysUrl;

    @Value("${customer.transaction.host}")
    private String host;
    @Value("${customer.transaction.port}")
    private int port;
    @Value("${customer.transaction.username}")
    private String username;
    @Value("${customer.transaction.password}")
    private String password;
    @Value("${customer.transaction.basePath}")
    private String basePath;
    @Value("${customer.transaction.local.file.uploadPath}")
    private String uploadLocalPath;
    @Value("${customer.transaction.local.file.downloadPath}")
    private String downloadLocalPath;
    @Value("${customer.transaction.local.file.size}")
    private int fileSize;
    //导出最多条数
    @Value("${customer.transaction.local.file.limit}")
    private int limit;

    //每次邮件可以接受的最大文件数
    @Value("${customer.transaction.local.file.mailSize}")
    private int mailSize;

    @Value("${customer.transaction.mail.from}")
    private String sender;
    @Value("${customer.transaction.mail.url}")
    private String receiver;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public JsonResult<Page<TransactionReceiptRecordVO>> findRecordsByQuery(TransactionReceiptRecordQuery query) {
        log.info("[TransactionReceiptRecordServiceImpl findRecordsByQuery begin]，query={}", query);
        Page<TransactionReceiptRecord> page = transactionReceiptRecordRepo.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            //交易单号
            if (StringUtils.isNotEmpty(query.getOrderNo())) {
                predicates.add(criteriaBuilder.equal(root.get("orderNo"), query.getOrderNo()));
            }
            if (StringUtils.isNotEmpty(query.getImportStatus())) {
                predicates.add(criteriaBuilder.equal(root.get("importStatus"), query.getImportStatus()));
            }
            if (StringUtils.isNotEmpty(query.getExportStatus())) {
                predicates.add(criteriaBuilder.equal(root.get("exportStatus"), query.getExportStatus()));
            }
            // 设置查询条件
            criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
            // 指定排序
            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id")));

            return criteriaQuery.getRestriction();

        }, new PageRequest(query.getPageNo(), query.getPageSize()));
        log.info("[TransactionReceiptRecordServiceImpl findRecordsByQuery] end，query={} ", query);
        Page<TransactionReceiptRecordVO> map = page.map(it -> {
            TransactionReceiptRecordVO workOrderVO = new TransactionReceiptRecordVO();
            workOrderVO.setTradeNo(it.getOrderNo());
            workOrderVO.setUserId(it.getUserId());
            workOrderVO.setUserName(it.getUserName());
            workOrderVO.setSerialNo(it.getSerialNo());
            workOrderVO.setExportStatus(it.getExportStatus());
            workOrderVO.setImportStatus(it.getImportStatus());
            workOrderVO.setId(workOrderVO.getId());
            return workOrderVO;
        });
        if (map != null) {
            return JsonResult.buildSuccessResult("查询成功", map);
        } else {
            return JsonResult.buildErrorStateResult("查询失败");
        }
    }

    /**
     *校验是否有其他人在导入、导出
     */
    @Override
    public String checkRedis(String str){
        log.info("redis add TransactionReceiptRecordServiceImpl."+str+".userId", redisTemplate);
        String obj = (String) redisTemplate.opsForValue().get("TransactionReceiptRecordServiceImpl."+str+".userId");
        if(StringUtils.isBlank(obj)){
            redisTemplate.opsForValue().set("TransactionReceiptRecordServiceImpl."+str+".userId", str);
            return "";
        }
        return obj;
    }

    /**
     * 删除redis中的值
     */
    public void deleteRedis(String str){
        log.info("redis delete TransactionReceiptRecordServiceImpl."+str+".userId", redisTemplate);
        String obj = (String) redisTemplate.opsForValue().get("TransactionReceiptRecordServiceImpl."+str+".userId");
        if(StringUtils.isNotBlank(obj)){
            redisTemplate.opsForValue().set("TransactionReceiptRecordServiceImpl."+str+".userId", "");
        }
    }

    @Override
    @Transactional
    public JsonResult importTransactionReceiptRecord(MultipartFile file) throws RuntimeException {
        String str = checkRedis("importTransactionReceiptRecord");
        if(StringUtils.isNotBlank(str)){
            throw new RuntimeException("只能一个人导入，当前有其他人正在导入，请稍后重试");
        }
        log.info("[TransactionReceiptRecordServiceImpl importTransactionReceiptRecord] end，query={} ", file);
        //查询未导出数据最大批次号
        Integer maxBatchNo = transactionReceiptRecordRepo.findMaxBatchNo(0);
        if(maxBatchNo == null || maxBatchNo ==0 ){
            maxBatchNo = 1;
        }

        //读取所有数据
        log.info("TransactionReceiptRecordServiceImpl importTransactionReceiptRecord read begin");
        long begin = System.currentTimeMillis();
        List<TransactionReceiptRecord> readList = null;
        try {
            readList = read(file.getOriginalFilename(), file.getInputStream());
            if(CollectionUtils.isEmpty(readList)){
                deleteRedis("importTransactionReceiptRecord");
                throw new  RuntimeException("文件中没有数据");
            }
            if(readList !=null && readList.size() > fileSize){
                deleteRedis("importTransactionReceiptRecord");
                throw new  RuntimeException("文件太大，最多可以读取"+fileSize+"条数据！");
            }
        } catch (IOException e) {
            deleteRedis("importTransactionReceiptRecord");
            throw new  RuntimeException("读取数据异常");
        }
        long end = System.currentTimeMillis();
        log.info("TransactionReceiptRecordServiceImpl importTransactionReceiptRecord read end,读取数据总耗时:",end-begin);
        log.info("TransactionReceiptRecordServiceImpl importTransactionReceiptRecord save begin");
        if(readList.size()>0){
            //0代表初始状态，1代表导入成功，2代表导入失败
            for(TransactionReceiptRecord record : readList){
                //如果三项同时为空的话则不落库
                if((record.getUserId() == null || record.getUserId() == 0)
                    && StringUtils.isEmpty(record.getUserName()) && StringUtils.isEmpty(record.getOrderNo())
                ){
                    continue;
                }
                //查询是否存在相同单号的数据，如果存在则不能导入
                List<TransactionReceiptRecord> records =
                        transactionReceiptRecordRepo.selectRecordsByOrderNo(record.getOrderNo(),record.getUserId(),record.getUserName());
                if(CollectionUtils.isNotEmpty(records)){
                    deleteRedis("importTransactionReceiptRecord");
                    throw new RuntimeException("存在userid为"+record.getUserId()+"，姓名为"+record.getUserName()+"，交易单号为"+record.getOrderNo()+"数据还未导出,不能再次导入");
                }
                //保存时如果有其中一项为空则默认为导入失败，其他则默认初始状态
                if(record.getUserId() ==null || record.getUserId() ==0
                        || StringUtils.isEmpty(record.getUserName())
                        || (StringUtils.isEmpty(record.getOrderNo()) && StringUtils.isEmpty(record.getConsumeNo()))){
                    record.setImportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                    //默认导出失败
                    record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                }else{
                    record.setImportStatus(VoucherExportStatus.INIT.getCode());
                    //默认导出初始状态
                    record.setExportStatus(VoucherExportStatus.INIT.getCode());
                }
                //存储批次号
                record.setBatchNo(maxBatchNo.intValue()+1);
                transactionReceiptRecordRepo.save(record);
            }
            log.info("TransactionReceiptRecordServiceImpl importTransactionReceiptRecord save end");
            return updateTransactionRecordsStatus();
        }
        deleteRedis("importTransactionReceiptRecord");
        return JsonResult.buildErrorStateResult("未读取到数据或读取失败");
    }

    public  List<TransactionReceiptRecord> read(String filename, InputStream is) throws IOException {
        log.info(" read excel file");
        /**
         * 总行数
         */
        int totalRows = 0;
        /**
         * 总列数
         */
        int totalCols = 0;

        /** 验证文件是否合法 */
        if (!excelUtil.validateExcel(filename)) {
            throw new RuntimeException("文件格式不合法 ");
        }
        /** 判断文件的类型，是2003还是2007 */
        Workbook wb = null;
        if (!excelUtil.isExcel2007(filename)) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        List<TransactionReceiptRecord> recordList = new ArrayList<>();
        /** 得到第一个shell */
        Sheet sheet = wb.getSheetAt(0);
        /** 得到Excel的行数 */
        totalRows = sheet.getPhysicalNumberOfRows();
        /** 得到Excel的列数 */
        if (totalRows >= 1 && sheet.getRow(0) != null) {
            totalCols = sheet.getRow(0).getPhysicalNumberOfCells();
        }
        /** 循环Excel的行 */
        for (int r = 0; r < totalRows; r++) {
            log.info(" read excel file");
            if(r == 0){
                continue;
            }
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            /** 循环Excel的列 */
            TransactionReceiptRecord record = new TransactionReceiptRecord();
            for (int c = 0; c < totalCols; c++) {
                Cell cell = row.getCell(c);
                log.info("cell "+cell);
                if(cell == null){
                    continue;
                }
                cell.setCellType(cell.CELL_TYPE_STRING);
                String cellValue = cell.getStringCellValue();
                if (org.springframework.util.StringUtils.isEmpty(cellValue)) {
                    continue;
                }

                if(c == 1){
                    record.setSerialNo(cellValue);
                }else if(c == 2){
                    record.setUserId(Integer.valueOf(cellValue));
                }else if(c == 3){
                    record.setUserName(cellValue);
                }else if(c == 4){
                    record.setOrderNo(cellValue);
                } else if (c == 5) {
                    record.setConsumeNo(cellValue);
                }
            }
            recordList.add(record);
        }
        return recordList;
    }

    //导出zip压缩包文件
    @Override
    @Async
    public void  exportZipFile(HttpServletRequest request, HttpServletResponse response) throws RuntimeException {
        //调用电商接口获取对应数据
        log.info("[TransactionReceiptRecordServiceImpl.exportZipFile begin]");
        //查询需要导出的数据-导入成功的数据,但未导出成功的数据
        String accessToken = request.getHeader("Access-Token");
        List<TransactionReceiptRecord> transactionReceiptRecordList= transactionReceiptRecordRepo.selectRecordsByImportStatusAndExportStatus(VoucherExportStatus.EXPORT_SUCCESS.getCode(),limit);
        log.info("[TransactionReceiptRecordServiceImpl.exportZipFile transactionReceiptRecordList] 可导出数据为：",transactionReceiptRecordList.size());
        if(CollectionUtils.isEmpty(transactionReceiptRecordList)){
            deleteRedis("exportZipFile");
            log.info("没有可以导出得数据");
            throw new RuntimeException("没有可以导出得数据");
        }
        //查询导入成功数据的导出的最大批次号
        Integer maxExportBatchNo = transactionReceiptRecordRepo.findExportMaxBatchNo(VoucherExportStatus.EXPORT_SUCCESS.getCode());
        if(maxExportBatchNo == null || maxExportBatchNo ==0 ){
            maxExportBatchNo = 1;
        }
        maxExportBatchNo = maxExportBatchNo.intValue()+1;
        List <Map<String,Object>> emailList =new ArrayList<>();
        log.info("[TransactionReceiptRecordServiceImpl.kdspOperationUrl  调用kdsp-op 接口begin]", System.currentTimeMillis());
        SFTPUtil sftpUtil = new SFTPUtil(username,password,host,port);
        sftpUtil.login();
        log.info("uploadFile | 成功连接ftp");
        for(TransactionReceiptRecord record : transactionReceiptRecordList){
            Integer userId = record.getUserId();
            String orderNo = record.getOrderNo();
            String consumeNo = record.getConsumeNo();
            //调用kdsp接口获取交易凭证订单信息
            String url = kdspOperationUrl + "/api/kdsp/op/fa-cui/transaction-proof/query";
            //String url = "http://kdsp-operation-test7.liangkebang.net/api/kdsp/op/fa-cui/transaction-proof/query";
            try {
                Map<String, String> header = Maps.newHashMap();
                header.put("Content-type", "application/json");
                header.put("qg-tenant-id", "560761");
                Map param = Maps.newHashMap();
                if (Objects.nonNull(userId)) {
                    param.put("userId", userId);
                }
                if (StringUtils.isNotBlank(orderNo)) {
                    param.put("orderNo", orderNo);
                }
                if (StringUtils.isNotBlank(consumeNo)) {
                    param.put("tradeNo", consumeNo);
                }
                List<Map> paramList =new ArrayList<>();
                paramList.add(param);
                //得到json字符串
                String result = httpService.post(url, header, paramList);
                log.info("调用kdsp查询订单接口返回结果，result:",result);
                //转换成json 对象
                if(StringUtils.isBlank(result)){
                    deleteRedis("exportZipFile");
                    throw new RuntimeException("未查询到订单数据");
                }
                JSONObject json = JSONObject.parseObject(result);
                String jsonResult = json.getString("data");
                String businessCode = json.getString("businessCode");
                //查询报错
                if(!"0000".equals(businessCode)){
                    //导出失败，跳过
                    record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                    transactionReceiptRecordRepo.save(record);
                    continue;
                }
                if(jsonResult != null){
                    JSONObject jsonObject = JSONObject.parseObject(jsonResult);
                    JSONArray jsonArray = jsonObject.getJSONArray("dataList");
                    if(jsonArray.isEmpty()){
                        //导出失败，跳过
                        record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        transactionReceiptRecordRepo.save(record);
                        continue;
                    }
                    List<TransactionReceiptVO> transactionReceiptVOList = jsonArray.toJavaList(TransactionReceiptVO.class);
                    if(transactionReceiptVOList.isEmpty()){
                        //导出失败，跳过
                        record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        transactionReceiptRecordRepo.save(record);
                        continue;
                    }
                    TransactionReceiptVO vo = transactionReceiptVOList.get(0);
                    Integer logisticsDetailCount = 0;
                    for (LogisticsVO logisticsVO: vo.getLogisticsList()) {
                        logisticsDetailCount += logisticsVO.getDetailList().size();
                    }

                    if(logisticsDetailCount <= 5) {
                        // 物流信息异常
                        record.setExportStatus(VoucherExportStatus.EXPORT_WARN.getCode());
                        transactionReceiptRecordRepo.save(record);
                        continue;
                    }
                    record.setExportBatchNo(maxExportBatchNo);
                    //生成pdf
                    String directory =record.getSerialNo()+record.getUserName();
                    String pdfFileName = record.getUserId()+"-"+record.getUserName()+"-"+record.getOrderNo()+".pdf";
                    FileToZip.mkdir(uploadLocalPath+directory);
                    log.info("导出文件生成pdf begin:"+pdfFileName);
                    generatePDF(transactionReceiptVOList.get(0),uploadLocalPath+"/"+directory+"/"+pdfFileName);
                    log.info("导出文件生成pdf end:"+pdfFileName);
                    File file1 = new File(uploadLocalPath+"/"+directory+"/"+pdfFileName);
                    InputStream inputStream = new FileInputStream(file1);
                    sftpUtil.upload(basePath+maxExportBatchNo+"/交易凭证/",directory,pdfFileName,inputStream);
                    //将文件路径和useId放入list，进行签章
                    List <Map<String,Object>> filePathList =new ArrayList<>();
                    Map<String,Object> map =Maps.newHashMap();
                    map.put("userId",record.getUserId());
                    map.put("fileAddress",maxExportBatchNo+"/交易凭证/"+directory+"/"+pdfFileName);
                    log.info("需要签章得pdf路径:"+maxExportBatchNo+"/交易凭证/"+directory+"/"+pdfFileName);
                    filePathList.add(map);
                    //调用合同中心进行签章
                    restContract(filePathList, emailList, accessToken);
                }
            } catch (Exception e) {
                sftpUtil.logout();
                log.info("uploadFile | 断开ftp");
                deleteRedis("exportZipFile");
                log.error("[TransactionReceiptRecordServiceImpl][exportZipFile] 网络通讯异常,userId:{},ex:{}", ExceptionUtils.getStackTrace(e));
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new RuntimeException("导出文件出错了");
            }
        }
        sftpUtil.logout();
        log.info("uploadFile | 断开ftp");
        log.info("[TransactionReceiptRecordServiceImpl.kdspOperationUrl  调用kdsp-op 接口end]");
        if(CollectionUtils.isEmpty(emailList)){
            log.info("没有签章成功的文件可以发送");
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } else {
            log.info("[TransactionReceiptRecordServiceImpl.sendCustomerTransactionHtmlMail  发送邮件begin]");
            sendCustomerTransactionHtmlMail(transactionReceiptRecordList.size(),emailList.size(),transactionReceiptRecordList.size()-emailList.size());
            log.info("[TransactionReceiptRecordServiceImpl.sendCustomerTransactionHtmlMail  发送邮件end]");
        }
        deleteRedis("exportZipFile");

    }

    private  void getHeaders(HttpServletRequest request) {
        log.info("[TransactionReceiptRecordServiceImpl.getHeaders] begin");
        Map<String, String> headerMap = new HashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String name	= enumeration.nextElement();
            String value = request.getHeader(name);
            headerMap.put(name, value);
            log.info("[TransactionReceiptRecordServiceImpl.getHeaders],name:{},value:{}",name,value);
        }
       // return headerMap;
    }

    /**
     * 调用签章接口
     * @param filePathList
     */
    private void restContract(List <Map<String,Object>> filePathList,List <Map<String,Object>> emailList,String accessToken){
        log.info("contractUrl /contract/batch/sign 调用签章接口,accessToken:{}",accessToken);
        if(filePathList.isEmpty()){
            deleteRedis("exportZipFile");
            throw new RuntimeException("没有可以导出的数据");
        }
        String url = contractUrl + "/contract/batch/sign";
        Map<String, String> header = Maps.newHashMap();
        header.put("Content-type", "application/json");
        header.put("Access-Token", accessToken);
        log.info("contractUrl /contract/batch/sign 调用签章接口 accessToken,"+accessToken);
        log.info("contractUrl /contract/batch/sign 调用签章接口 begin,"+filePathList);
        String contractResult = httpService.post(url, header, filePathList);
        JSONObject json = JSONObject.parseObject(contractResult);
        log.info("contractUrl /contract/batch/sign 调用签章接口 end,"+json);
        String jsonResult = json.getString("data");
        String businessCode = json.getString("businessCode");
        if(!"0000".equals(businessCode)){
            deleteRedis("exportZipFile");
            throw new RuntimeException("签章失败！");
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonResult);
        JSONArray jsonArray = jsonObject.getJSONArray("successList");
        log.info("contractUrl /contract/batch/sign jsonArray,"+jsonArray);
        List<String> updateSuccessList = new ArrayList<>();
        if(jsonArray != null && jsonArray.size()>0){
            String path = (String) jsonArray.get(0);
            String filepath = basePath + path.substring(1);
            int totalLength =filepath.length();
            int length = filepath.lastIndexOf("/");
            Map<String,Object>map = Maps.newHashMap();
            String fileName =filepath.substring(length+1,totalLength);
            map.put("fileName",fileName);
            int length2 = fileName.lastIndexOf("-");
            fileName = fileName.substring(length2+1,fileName.length());
            updateSuccessList.add(fileName.substring(0,fileName.indexOf(".")));
            filepath =filepath.substring(0,length+1);
            map.put("filePath",filepath);
            emailList.add(map);
        }else{
            deleteRedis("exportZipFile");
            throw new RuntimeException("签章失败！");
        }
        log.info("contractUrl /contract/batch/sign updateSuccessList,"+updateSuccessList);
        //更新数据
        JSONArray failList = jsonObject.getJSONArray("failList");
        log.info("contractUrl /contract/batch/sign failList,"+failList);
        List<String> updateFailList = new ArrayList<>();
        if(failList !=null && failList.size()>0){
            //String path = "/result/47/交易凭证/1张三/70454371-张三-1499341519604432896.pdf";
            String path = (String) failList.get(0);
            int begin = path.lastIndexOf("/")+1;
            int end = path.indexOf(".");
            String fileName =path.substring(begin,end);
            int totalLength =fileName.length();
            int length = fileName.lastIndexOf("-");
            fileName = fileName.substring(length+1,totalLength);
            updateFailList.add(fileName);
        }
        //更新导出状态
        log.info("交易凭证导出接口更新导出状态 begin");
        updatePDFSignStatus(updateSuccessList,updateFailList);
        log.info("交易凭证导出接口更新导出状态 end");
    }

    /**
     * 删除文件
     * @param file
     */
    private void deleteDirectory(File file){
        if(file.isFile()){//表示该文件不是文件夹
            file.delete();
        }else{
            //首先得到当前路径
            String [] childPaths =file.list();
            for(String childPath :childPaths){
                File childFile = new File(file.getAbsolutePath()+"/"+childPath);
                deleteDirectory(childFile);
            }
            file.delete();
        }
    }

    /**
     * 根据byte数组，生成文件
     */
    public void getFile(byte[] bfile, String filePath,String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
                dir.mkdirs();
            }
            FileToZip.mkdir(filePath);
            file = new File(filePath+"/"+fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 校验是否可以导出
     * @return
     */
    @Override
    public JsonResult checkCanExport() {
        //查询初始状态的数据-如果存在则说明未全部更新状态
        Long count = transactionReceiptRecordRepo.selectCountByImportStatus(0);
        if(count != null && count > 0){
            //异步多线程更新数据
            return JsonResult.buildErrorStateResult("导入处理中，请稍后重试");
        }else{
            return JsonResult.buildSuccessResult("数据全部导入成功",null);
        }
    }

    /**
     * 更新交易凭证导入状态
     * @return
     */
    @Override
    @Transactional
    public JsonResult updateTransactionRecordsStatus() throws RuntimeException{
        log.error("TransactionReceiptRecordServiceImpl updateTransactionRecordsStatus 校验更新数据 begin");
        //查询所有初始化的数据
        List<TransactionReceiptRecord> transactionReceiptRecordList
                = transactionReceiptRecordRepo.selectRecordsByImportStatus(VoucherExportStatus.INIT.getCode());
        //没有校验成功的放入一个list
        List<TransactionReceiptRecord> failList = new ArrayList<>();
        List<TransactionReceiptRecord> successList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(transactionReceiptRecordList)){
            for(TransactionReceiptRecord record :transactionReceiptRecordList){
                try{
                    log.info("TransactionReceiptRecordServiceImpl updateTransactionRecordsStatus 调用商城接口 begin");
                    if(StringUtils.isNotBlank(record.getUserName())){
                        Map<String, String> header = Maps.newHashMap();
                        header.put("Content-type", "application/json");
                        header.put("qg-tenant-id", "560761");
                        //调用电商接口
                        String kUrl = kdspOperationUrl + "/api/kdsp/op/fa-cui/transaction-proof/check";
                        //String kUrl = "http://kdsp-operation-test7.liangkebang.net/api/kdsp/op/fa-cui/transaction-proof/check";
                        //得到json字符串
                        Map param1 = Maps.newHashMap();
                        param1.put("userId",record.getUserId());
                        param1.put("orderNo",record.getOrderNo());
                        param1.put("tradeNo", record.getConsumeNo());
                        List<Map> paramList =new ArrayList<>();
                        paramList.add(param1);
                        String kResult = httpService.post(kUrl, header, paramList);
                        JSONObject kJson =JSONObject.parseObject(kResult);
                        log.info("TransactionReceiptRecordServiceImpl kResult ="+kResult);
                        String businessCode = kJson.getString("businessCode");
                        if(!"0000".equals(businessCode)){
                            deleteRedis("importTransactionReceiptRecord");
                            throw new RuntimeException("调用电商接口报错");
                        }
                        log.info("TransactionReceiptRecordServiceImpl updateTransactionRecordsStatus 调用商城接口 end");
                        //只有数据不存在的时候返回data
                        if(StringUtils.isNotBlank(kJson.getString("data"))){
                            String kJsonResult = kJson.getString("data");
                            JSONObject kJsonObject = JSONObject.parseObject(kJsonResult);
                            List<TransactionReceiptRecord> errorList = (List<TransactionReceiptRecord>) kJsonObject.get("verifyErrorList");
                            if(errorList.size()>0){
                                record.setImportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                                record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                                failList.add(record);
                                continue;
                            }
                        }
                        record.setImportStatus(VoucherExportStatus.EXPORT_SUCCESS.getCode());
                        successList.add(record);
                    }else{
                        record.setImportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        record.setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        failList.add(record);
                    }
                }catch(Exception e){
                    deleteRedis("importTransactionReceiptRecord");
                   throw new RuntimeException("调用接口报错");
                }
            }
            //校验全部通过则更新状态
            for(TransactionReceiptRecord record :failList){
                transactionReceiptRecordRepo.updateTransactionStatusByImportStatus(VoucherExportStatus.EXPORT_FAIL.getCode(), record.getOrderNo());
            }
            for(TransactionReceiptRecord record :successList){
                transactionReceiptRecordRepo.updateTransactionStatusByImportStatus(VoucherExportStatus.EXPORT_SUCCESS.getCode(), record.getOrderNo());
            }
            log.error("TransactionReceiptRecordServiceImpl updateTransactionRecordsStatus 校验更新数据 end");
        }
        deleteRedis("importTransactionReceiptRecord");
        return JsonResult.buildSuccessResult("数据导入成功",null);
    }

    /**
     * 更新数据状态
     * @param successList
     * @param failList
     */
    public void updatePDFSignStatus(List<String> successList,List<String>failList) {
        log.info("contractUrl /contract/batch/sign successList,"+successList);
        //pdf签章成功
        if(!successList.isEmpty()){
            for(String orderNo :successList){
                if(StringUtils.isNotBlank(orderNo)){
                    List<TransactionReceiptRecord> list = transactionReceiptRecordRepo.selectRecords(orderNo);
                    if(!list.isEmpty()){
                        list.get(0).setExportStatus(VoucherExportStatus.EXPORT_SUCCESS.getCode());
                        list.get(0).setSignStatus(VoucherExportStatus.EXPORT_SUCCESS.getCode());
                        transactionReceiptRecordRepo.save(list.get(0));
                    }
                }
            }
        }
        log.info("contractUrl /contract/batch/sign failList,"+failList);
        //pdf签章失败
        if(!failList.isEmpty()){
            for(String orderNo :failList){
                if(StringUtils.isNotBlank(orderNo)) {
                    List<TransactionReceiptRecord> list = transactionReceiptRecordRepo.selectRecords(orderNo);
                    if(!list.isEmpty()){
                        list.get(0).setExportStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        list.get(0).setSignStatus(VoucherExportStatus.EXPORT_FAIL.getCode());
                        transactionReceiptRecordRepo.save(list.get(0));
                    }
                }
            }
        }
    }

    /**
     * 切分list
     * @param records
     * @param groupSize
     * @return
     */
    private List<List<Map<String,Object>>> splitList(List<Map<String,Object>> records,int groupSize){
        int length = records.size();
        //计算可以分为多少组
        int num = (length+groupSize-1)/groupSize;
        List<List<Map<String,Object>>> newList = new ArrayList<>();
        for(int i= 0;i < num; i++){
            //开始位置
            int fromIndex = i * groupSize;
            //结束位置
            int toIndex = (i+1) * groupSize < length ? (i+1) * groupSize : length;
            newList.add(records.subList(fromIndex,toIndex));
        }
        return newList;
    }

    /**
     * 生成PDF
     * @param transactionReceiptVO
     */
    public void generatePDF(TransactionReceiptVO transactionReceiptVO,String filePath){
        final String LOG_PRE = "TransactionReceiptRecordServiceImpl.generatePDF";
        log.info("{} 传入参数 transactionReceiptVO={}", LOG_PRE, transactionReceiptVO);
        //订单信息
        OrderVO orderVO = transactionReceiptVO.getOrder();
        //商品信息
        List<SkuVO> skuVOList = transactionReceiptVO.getSkuList();
        //收货人信息
        ReceiverVO receiverVO =transactionReceiptVO.getReceiver();
        //物流信息
        List<LogisticsVO> logisticsVOList = transactionReceiptVO.getLogisticsList();
        // 贷款信息
        LoanVO loanVo = transactionReceiptVO.getLoan();
        log.info("generatePDF 开始生成pdf begin",LOG_PRE,filePath);
        Document document = new Document(PageSize.A4);
        try {
            PdfWriter.getInstance(document, new FileOutputStream(filePath));
            document.open();
            document.addTitle("交易凭证");//标题
            PdfPTable table = new PdfPTable(6);
            Font font = ITextPDFUtil.getColorFont(BaseColor.BLACK,7,"宋体");

            table.setWidths(ITextPDFUtil.getColumnWiths(35,35,35,35,25,35));
            //订单信息
            //第一行合并单元格
            PdfPCell cell;
            cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("订单信息"), font));
            cell.setColspan(6);
            cell.setMinimumHeight(18);
            table.addCell(cell);
            //第二行标题
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("订单ID"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("供应商订单ID"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("供应链订单号"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("商品渠道"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("下单平台"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("平台账号id"), font))).setMinimumHeight(18);

            //第三行数据iTextITextPDFUtil.
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getOrderNo())?"/":orderVO.getOrderNo()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getMerchantOrderId()) ?"/":orderVO.getMerchantOrderId()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getKeyStoneOrderNo())?"":orderVO.getKeyStoneOrderNo()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getSkuSourceName())?"/":orderVO.getOrderNo()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getTenantName())?"/":orderVO.getTenantName()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(orderVO.getUserId() ==null ? "/":orderVO.getUserId().toString()), font))).setMinimumHeight(18);


            //第4行标题iTextITextPDFUtil.
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("平台绑定手机号"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("订单创建时间"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("支付完成时间"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("订单金额"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("实付金额"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("支付方式"), font))).setMinimumHeight(18);
            //查询手机号
            UserSysResult<XUser> user = userSdk.getService().findUserByUserId(orderVO.getUserId());
            //第5行数据
            if(user !=null && user.getData() !=null){
                table.addCell(new Phrase(ITextPDFUtil.getUTF8String(user.getData().getPhoneNo()), font));
            }else{
                table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            }

            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getCreatedAt())?"/":orderVO.getCreatedAt()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getPayTime())?"/":orderVO.getPayTime()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getOrderAmount())?"":orderVO.getOrderAmount()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getPayAmount())?"/":orderVO.getPayAmount()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getPayTypeName())?"/":orderVO.getPayTypeName()), font))).setMinimumHeight(18);
            // 第六行数据
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("享花卡支付"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("其他方式支付"), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            // 第七行数据
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getVccPayAmount())?"0":orderVO.getVccPayAmount()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(orderVO.getOtherPayAmount())?"0":orderVO.getOtherPayAmount()), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font))).setMinimumHeight(18);
            //有多个物流信息,重复展示物流信息，商品信息，收货信息，物流详情
            log.info("生成pdf 物流信息logisticsVOList"+logisticsVOList.size());
            if(logisticsVOList.size() > 1){
                //展示多个
                for(int j= 0;j<logisticsVOList.size();j++){
                    table = generateMultiParagraph(cell,font,table,logisticsVOList,skuVOList,receiverVO,j);
                }
            }else{
                //展示一个
                table=generateMultiParagraph(cell,font,table,logisticsVOList,skuVOList,receiverVO,0);
            }
            //贷款信息
            cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("贷款信息"), font));
            cell.setColspan(6);
            cell.setMinimumHeight(18);
            table.addCell(cell);
            //贷款信息详情
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("合同编号/贷字"), font));
            //todo: 贷款信息只有一个,选择？
            if (loanVo != null) {
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(loanVo.getContractNo())?"":loanVo.getContractNo()), font));
                cell.setColspan(5);
                cell.setMinimumHeight(18);
                table.addCell(cell);
            } else {
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(""), font));
                cell.setColspan(5);
                cell.setMinimumHeight(18);
                table.addCell(cell);
            }
            log.info("generatePDF 开始生成pdf end",LOG_PRE,table.getBody());
            document.add(table);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成pdf文件内容
     * @param font
     * @param table
     * @param logisticsVOList
     * @param skuVOList
     * @param receiverVO
     * @param count
     * @return
     */
    private PdfPTable generateMultiParagraph(PdfPCell cell,Font font,
                                        PdfPTable table,List<LogisticsVO> logisticsVOList,List<SkuVO> skuVOList,ReceiverVO receiverVO,int count){
        //物流信息
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("物流信息"), font));
        cell.setColspan(6);
        cell.setMinimumHeight(18);
        table.addCell(cell);

        if(logisticsVOList.size()>0){
            //第一行标题
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("发货时间"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("确认收货时间"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("订单状态"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("订单类型"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("物流公司"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("物流单号"), font));
            //第二行数据

            LogisticsVO logisticsVO=logisticsVOList.get(count);
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getPostTime())?"/":logisticsVO.getPostTime()), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getCompleteTime())?"/":logisticsVO.getCompleteTime()), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getStatusName())?"/":logisticsVO.getStatusName()), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getTypeName())?"/":logisticsVO.getTypeName()), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getExpressCompany())?"/":logisticsVO.getExpressCompany()), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(logisticsVO.getDeliveryNo())?"/":logisticsVO.getDeliveryNo()), font));
        }else{
            //第一行标题
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("发货时间"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("确认收货时间"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("订单状态"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("订单类型"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("物流公司"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("物流单号"), font));

            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
            table.addCell(new Phrase(ITextPDFUtil.getUTF8String("/"), font));
        }

        //商品信息
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("商品信息"),font));
        cell.setColspan(6);
        cell.setMinimumHeight(18);
        table.addCell(cell);
        //商品信息标题
        //合并3行
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("商品名称"), font));
        cell.setColspan(3);
        cell.setMinimumHeight(18);
        table.addCell(cell);
        //合并2行
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("商品属性"), font));
        cell.setColspan(2);
        cell.setMinimumHeight(18);
        table.addCell(cell);
        table.addCell(new Phrase(ITextPDFUtil.getUTF8String("商品件数"), font));

        //商品信息数据
        if(CollectionUtils.isNotEmpty(skuVOList)){
            for(SkuVO skuVO:skuVOList){
                //商品名称取值
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(skuVO.getSkuName())?"/":skuVO.getSkuName()), font));
                cell.setColspan(3);
                cell.setMinimumHeight(18);
                table.addCell(cell);
                //商品属性取值
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(skuVO.getSkuAttr())?"/":skuVO.getSkuAttr()), font));
                cell.setColspan(2);
                cell.setMinimumHeight(18);
                table.addCell(cell);
                //商品件数取值
                table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(skuVO.getCount())?"/":skuVO.getCount()), font));
            }
        }

        //收货人信息
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("收货人信息"), font));
        cell.setMinimumHeight(18);
        cell.setColspan(6);
        table.addCell(cell);

        //收货人信息标题
        table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("收货人手机"), font))).setMinimumHeight(18);
        table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("收货人姓名"), font))).setMinimumHeight(18);
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("收货地址"), font));
        cell.setMinimumHeight(18);
        cell.setColspan(4);
        table.addCell(cell);

        //收货人信息数据
        table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(receiverVO.getReceiverMobile())?"/":receiverVO.getReceiverMobile()), font))).setMinimumHeight(18);
        table.addCell(new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(receiverVO.getReceiverName())?"/":receiverVO.getReceiverName()), font))).setMinimumHeight(18);
        cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(receiverVO.getFullAddress())?"/":receiverVO.getFullAddress()), font));
        cell.setMinimumHeight(18);
        cell.setColspan(4);
        table.addCell(cell);

        //物流详情
        if(logisticsVOList.size()>0){
            List<logisticsDetailVO> logisticsDetails =logisticsVOList.get(count).getDetailList();
            //物流详情数据
            if(CollectionUtils.isNotEmpty(logisticsDetails)){
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("物流详情"), font));
                cell.setColspan(6);
                cell.setMinimumHeight(18);
                table.addCell(cell);
                //物流详情标题
                table.addCell(new Phrase(ITextPDFUtil.getUTF8String("时间"), font));
                cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String("状态"), font));
                cell.setColspan(5);
                cell.setMinimumHeight(18);
                table.addCell(cell);
                for(logisticsDetailVO vo : logisticsDetails){
                    table.addCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(vo.getTime())?"/":vo.getTime()), font));
                    cell = new PdfPCell(new Phrase(ITextPDFUtil.getUTF8String(StringUtils.isEmpty(vo.getDesc())?"/":vo.getDesc()), font));
                    cell.setColspan(5);
                    cell.setMinimumHeight(18);
                    table.addCell(cell);
                }
            }
        }
        return table;
    }

    /**
     *发送一个支持html
     */
    public void sendCustomerTransactionHtmlMail(Integer total,Integer success,Integer fail){
        SendMailParam sendMailParam = new SendMailParam();
        sendMailParam.setSender(sender);
        sendMailParam.setReceiver(receiver.split(","));
        sendMailParam.setSubject("客服系统交易凭证");
        sendMailParam.setContentText(String.format("客服系统交易凭证本次总共导出")+total+"条数据，导出成功"+success+"条，导出失败"+fail+"条");
        MailUtil.sendHtmlMail(sendMailParam);
    }
    /**
     * 发送一个支持html 和 附件 的邮件
     * @param inputStreamResource
     * @throws RuntimeException
     */
    public void sendCustomerTransactionMail(InputStreamResource inputStreamResource) throws RuntimeException {
        try {
            //FileInputStream is  = new FileInputStream("D:\\tmp1\\交易凭证.zip");
            //InputStreamResource  inputStreamResource1  =new InputStreamResource(is);
            SendMailParam sendMailParam = new SendMailParam();
            sendMailParam.setSender(sender);
            sendMailParam.setReceiver(receiver.split(","));
            sendMailParam.setSubject("交易凭证");
            sendMailParam.setContentText("客服系统交易凭证文件");
            sendMailParam.setAttachmentFileName("交易凭证".concat(".zip"));
            sendMailParam.setInputStreamSource(inputStreamResource);
            MailUtil.sendHtmlAndAttachmentMail(sendMailParam);

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }

    }

}
