Explorar o código

发票跳过查验

zoufan_kd hai 11 meses
pai
achega
37ca2c6466

+ 202 - 0
src/main/java/kd/imc/rim/common/invoice/collector/InvoiceCollectTaskNew.java

@@ -0,0 +1,202 @@
+package kd.imc.rim.common.invoice.collector;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.mvc.cache.PageCache;
+import kd.bos.orm.util.CollectionUtils;
+import kd.imc.rim.common.invoice.recognition.impl.RecognitionProgress;
+import kd.imc.rim.common.invoice.recognition.impl.RecognitionProgressError;
+import kd.imc.rim.common.invoice.recognition.listener.IRecognitionListener;
+import kd.imc.rim.common.invoice.recognition.listener.RecognitionListenerResult;
+import kd.imc.rim.common.service.EInvoiceZipXmlDealService;
+import kd.imc.rim.common.service.ElectAccVoucherService;
+import kd.imc.rim.common.service.ExcelInvoiceUploadService;
+import kd.imc.rim.common.service.RecognitionCheckServiceEx;
+import kd.imc.rim.common.utils.FileUtils;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class InvoiceCollectTaskNew implements Runnable, IRecognitionListener {
+    private static Log logger = LogFactory.getLog(InvoiceCollectTaskNew.class);
+    private RequestContext rc;
+    private String pageId;
+    private List<Map<String, String>> fileUrls;
+    private RecognitionProgress recognitionProgress;
+    private JSONObject businessParam;
+
+    public InvoiceCollectTaskNew(RequestContext rc, String pageId, List<Map<String, String>> fileUrls, JSONObject businessParam) {
+        this.rc = rc;
+        this.pageId = pageId;
+        this.fileUrls = fileUrls;
+        this.businessParam = businessParam;
+        this.recognitionProgress = new RecognitionProgress();
+        Object[] urls = new Object[fileUrls.size()];
+        int i = 0;
+
+        for(Iterator var7 = fileUrls.iterator(); var7.hasNext(); ++i) {
+            Map<String, String> map = (Map)var7.next();
+            urls[i] = map.get("url");
+        }
+
+        this.recognitionProgress.setUrls(urls);
+        this.recognitionProgress.setProgress(1);
+        this.recognitionProgress.setUnHandleSize(fileUrls.size());
+    }
+
+    public void run() {
+        RequestContext.copyAndSet(this.rc);
+        this.doTask();
+    }
+
+    private void doTask() {
+        PageCache pageCache = new PageCache(this.pageId);
+        long taskStart = System.currentTimeMillis();
+        int size = this.fileUrls.size();
+
+        for(int i = 0; i < size; ++i) {
+            Map<String, String> map = (Map)this.fileUrls.get(i);
+            long start = System.currentTimeMillis();
+            String url = (String)map.get("url");
+            String fileName = (String)map.get("name");
+            String seqStr = (String)map.get("seq");
+
+            try {
+                if (StringUtils.isEmpty(fileName)) {
+                    fileName = url.substring(url.lastIndexOf(47) + 1);
+                }
+
+                this.recognitionProgress.setHandleUrl(url);
+                pageCache.put("progress", JSONObject.toJSONString(this.recognitionProgress));
+                long recognitionStart = System.currentTimeMillis();
+                this.businessParam.put("pageId", this.pageId);
+                this.businessParam.put("uploadIndex", start + (long)i);
+                Long orgId;
+                if (this.businessParam.get("orgId") == null) {
+                    orgId = RequestContext.get().getOrgId();
+                } else {
+                    orgId = (Long)this.businessParam.get("orgId");
+                }
+
+                JSONObject invoiceResult = new JSONObject();
+                boolean isZipXmlEI = FileUtils.checkFileType(fileName, new String[]{"zip", "xml"});
+                if (isZipXmlEI) {
+                    invoiceResult = EInvoiceZipXmlDealService.analysisAndCheckSave(url, fileName, orgId, this.businessParam, this);
+                }
+
+                boolean isNeedDeal = FileUtils.checkFileType(fileName, new String[]{"zip", "ofd", "xml"});
+                if (isNeedDeal && !"0000".equals(invoiceResult.getString("errcode"))) {
+                    invoiceResult = ElectAccVoucherService.dealVoucher(url, fileName, orgId, this.businessParam, this);
+                }
+
+                String xbrlErrCode = invoiceResult.getString("errcode");
+                boolean dealResult = StringUtils.isEmpty(xbrlErrCode) || !xbrlErrCode.equals("0000");
+                boolean isZip = FileUtils.checkFileType(fileName, new String[]{"zip"});
+                if (dealResult && !isZip) {
+                    if (FileUtils.isExcel(fileName)) {
+                        invoiceResult = ExcelInvoiceUploadService.getInstance().uploadExcelInvoice(url, fileName, this, this.businessParam);
+                    } else {
+                        invoiceResult = RecognitionCheckServiceEx.getInstance().recognitionCheckInvoice(url, fileName, this, this.businessParam);
+                    }
+                }
+
+                logger.info(url + "RecognitionCheckServiceEx识别结果:" + invoiceResult);
+                logger.info(String.format("文件%s中发票识别与查验完毕 共耗时%s", fileName, System.currentTimeMillis() - recognitionStart));
+                if (null == this.recognitionProgress.getRecognitionProgressErrors()) {
+                    this.recognitionProgress.setRecognitionProgressErrors(new ArrayList());
+                }
+
+                if (!"0000".equals(invoiceResult.getString("errcode"))) {
+                    String errdescription = "识别异常,请重试";
+                    if (StringUtils.isNotEmpty(invoiceResult.getString("description"))) {
+                        errdescription = invoiceResult.getString("description");
+                    }
+
+                    this.recognitionProgress.getRecognitionProgressErrors().add(new RecognitionProgressError(url, errdescription));
+                } else {
+                    JSONArray recognitionData = invoiceResult.getJSONArray("data");
+                    if (recognitionData != null) {
+                        for(int k = 0; k < recognitionData.size(); ++k) {
+                            JSONObject invoiceInfo = recognitionData.getJSONObject(k);
+                            if (invoiceInfo != null) {
+                                Object isFalse = invoiceInfo.get("isFalse");
+                                if (isFalse != null) {
+                                    String snapshotUrl = invoiceInfo.getString("pageUrl");
+                                    String pageIndex = invoiceInfo.getString("pageIndex");
+                                    StringBuilder description = new StringBuilder();
+                                    description.append(fileName).append('第').append(pageIndex).append("页识别失败,请重试");
+                                    this.recognitionProgress.getRecognitionProgressErrors().add(new RecognitionProgressError(snapshotUrl, description.toString()));
+                                }
+                            }
+                        }
+                    }
+
+                    JSONObject tips = invoiceResult.getJSONObject("tips");
+                    if (!ObjectUtils.isEmpty(tips) && FileUtils.isExcel(fileName)) {
+                        RecognitionProgressError recognitionProgressError = new RecognitionProgressError();
+                        recognitionProgressError.setUrl(url);
+                        recognitionProgressError.setTipDescription(tips.getString("tipDescription"));
+                        this.recognitionProgress.getRecognitionProgressErrors().add(recognitionProgressError);
+                    }
+                }
+
+                BigDecimal a = new BigDecimal(i + 1);
+                BigDecimal b = new BigDecimal(size);
+                int progress = a.divide(b, 2, 4).multiply(new BigDecimal("100")).intValue();
+                if (progress != 100) {
+                    this.recognitionProgress.setProgress(progress);
+                }
+            } catch (Throwable var31) {
+                if (!FileUtils.isExcel(fileName)) {
+                    if (null == this.recognitionProgress.getRecognitionProgressErrors()) {
+                        this.recognitionProgress.setRecognitionProgressErrors(new ArrayList());
+                    }
+
+                    this.recognitionProgress.getRecognitionProgressErrors().add(new RecognitionProgressError(url, var31.getMessage()));
+                }
+            } finally {
+                this.recognitionProgress.setUnHandleSize(size - i - 1);
+                pageCache.put("progress", JSONObject.toJSONString(this.recognitionProgress));
+                logger.info(String.format("文件%s第%s页,InvoiceCollectTask统计信息-共%s个,耗时%s", fileName, i + 1, size, System.currentTimeMillis() - start));
+            }
+        }
+
+        this.recognitionProgress.setProgress(100);
+        PageCache pageCacheEnd = new PageCache(this.pageId);
+        pageCacheEnd.put("progress", JSONObject.toJSONString(this.recognitionProgress));
+        logger.info(String.format("%s任务统计信息总耗时%s", this.rc.getTraceId(), System.currentTimeMillis() - taskStart));
+    }
+
+    public void handle(RecognitionListenerResult recognitionListenerResult) {
+        PageCache pageCache = new PageCache(this.pageId);
+        String fileUrl = recognitionListenerResult.getFileUrl();
+        this.recognitionProgress.setHandleUrl(fileUrl);
+        if (StringUtils.isNotEmpty(recognitionListenerResult.getErrDescription())) {
+            logger.info(fileUrl + "识别失败/中断," + recognitionListenerResult.getErrDescription());
+            this.recognitionProgress.setHandleUrlIndex(recognitionListenerResult.getRecognitionIndex());
+            this.recognitionProgress.setHandleUrlErrorDescription(recognitionListenerResult.getErrDescription());
+            pageCache.put("progress", JSONObject.toJSONString(this.recognitionProgress));
+            pageCache.put("task_" + fileUrl, "0");
+        } else {
+            int index = recognitionListenerResult.getRecognitionIndex();
+            logger.info(fileUrl + "第" + index + "页识别完成:" + recognitionListenerResult.getRecognitionInvoice().toJSONString());
+            this.recognitionProgress.setHandleUrlIndex(index);
+            this.recognitionProgress.setHandleUrlSize(recognitionListenerResult.getRecognitionSize());
+            pageCache.put("progress", JSONObject.toJSONString(this.recognitionProgress));
+            pageCache.put("task_" + fileUrl, recognitionListenerResult.getRecognitionSize() + "");
+            pageCache.put("task_" + fileUrl + "_" + index, recognitionListenerResult.getRecognitionInvoice().toJSONString());
+            if (!CollectionUtils.isEmpty(recognitionListenerResult.getImportFailInvoice())) {
+                pageCache.put("failed_task_" + fileUrl + "_" + index, recognitionListenerResult.getImportFailInvoice().toJSONString());
+            }
+        }
+
+    }
+}

+ 668 - 0
src/main/java/kd/imc/rim/common/service/RecognitionCheckServiceEx.java

@@ -0,0 +1,668 @@
+package kd.imc.rim.common.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Maps;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.fileservice.FileServiceFactory;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.threads.ThreadPool;
+import kd.bos.threads.ThreadPools;
+import kd.imc.rim.common.constant.CheckContant;
+import kd.imc.rim.common.constant.InputInvoiceTypeEnum;
+import kd.imc.rim.common.constant.InvoiceUploadErrorType;
+import kd.imc.rim.common.helper.RecognitionCheckHelper;
+import kd.imc.rim.common.invoice.collector.InvoiceCollectService;
+import kd.imc.rim.common.invoice.model.ConvertFieldUtil;
+import kd.imc.rim.common.invoice.recognition.listener.IRecognitionListener;
+import kd.imc.rim.common.invoice.recognition.listener.RecognitionListenerResult;
+import kd.imc.rim.common.invoice.recognitionnew.task.FileUploadAndSignTask;
+import kd.imc.rim.common.invoice.save.InvoiceSaveService;
+import kd.imc.rim.common.message.exception.MsgException;
+import kd.imc.rim.common.utils.*;
+import kd.imc.rim.common.utils.itextpdf.UrlServiceUtils;
+import kd.imc.rim.file.model.FileConvertResult;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.compress.utils.Lists;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+public class RecognitionCheckServiceEx {
+    private static RecognitionCheckServiceEx instance = null;
+    private static Log logger = LogFactory.getLog(RecognitionCheckServiceEx.class);
+    private RecognitionCheckHelper recognitionCheckHelper = new RecognitionCheckHelper();
+    private InvoiceCollectService invoiceCollectService = new InvoiceCollectService();
+    private static Integer recheckorginPage = 999123413;
+    private static ThreadPool uploadThreadPool = ThreadPools.newFixedThreadPool("recognitionUploadThread_2", Runtime.getRuntime().availableProcessors() + 1);
+
+    private RecognitionCheckServiceEx() {
+    }
+
+    public static RecognitionCheckServiceEx getInstance() {
+        Class var0 = RecognitionCheckServiceEx.class;
+        synchronized(RecognitionCheckServiceEx.class) {
+            if (instance == null) {
+                instance = new RecognitionCheckServiceEx();
+            }
+        }
+
+        return instance;
+    }
+
+    public JSONObject recognitionCheckInvoice(String fileUrl, String fileName, IRecognitionListener recognitionListener, JSONObject businessParam) {
+        logger.info("识别查验fileName:{},businessParam:{}", fileName, businessParam);
+        this.markDeleteByVerifySave(businessParam);
+        boolean isCheck = this.getCheckFlag(businessParam);
+        return this.extracted_new(fileUrl, fileName, recognitionListener, businessParam, isCheck);
+    }
+
+    private void markDeleteByVerifySave(JSONObject businessParam) {
+        if (businessParam != null) {
+            String verifySaveFlag = RimConfigUtils.getConfig("verify_save");
+            if ("0".equals(verifySaveFlag)) {
+                businessParam.put("delete", "2");
+            }
+        }
+
+    }
+
+    private JSONObject extracted_new(String fileUrl, String fileName, IRecognitionListener recognitionListener, JSONObject businessParam, boolean isCheck) {
+        long startTime = System.currentTimeMillis();
+        JSONObject result = null;
+        RecognitionListenerResult listener = new RecognitionListenerResult(fileUrl, fileName, 0, 0, new JSONArray());
+
+        JSONArray finalResult;
+        JSONArray attachResult;
+        try {
+            long fileStartTime = System.currentTimeMillis();
+            FormFileEntity fileEntity = this.recognitionCheckHelper.getFormFileEntity(fileUrl, fileName);
+            if (!fileEntity.getSuccess()) {
+                this.handle(recognitionListener, listener);
+                return InvoiceUploadErrorType.getSplitErrorResult();
+            }
+
+            int totalPage = CollectionUtils.isEmpty(fileEntity.getSubFileList()) ? 1 : fileEntity.getSubFileList().size();
+            Map<String, Object> extMap = this.recognitionCheckHelper.getRecognitionCheckExtMap(businessParam);
+            String originalStateDefault = fileEntity.getOriginalStateDefault();
+            if ("1".equals(originalStateDefault)) {
+                extMap.put("originalStateDefault", originalStateDefault);
+            }
+
+            String fileType = fileEntity.getFileType();
+            Map<Integer, Object> subFileFutureMap = this.syncUploadSubFile(fileEntity);
+            logger.info("RecognitionCheckServiceEx 文件解析耗时:{}", System.currentTimeMillis() - fileStartTime);
+
+            List recognitionResultList;
+            try {
+                long recognitionStartTime = System.currentTimeMillis();
+                recognitionResultList = this.recognitionCheckHelper.recognitionInvoiceFile(fileEntity, extMap);
+                logger.info("RecognitionCheckServiceEx 识别总耗时:{}", System.currentTimeMillis() - recognitionStartTime);
+                this.checkOriginal(fileEntity, subFileFutureMap, recognitionResultList);
+                finalResult = JSONObject.parseArray(JSONObject.toJSONString(recognitionResultList));
+            } catch (Throwable var26) {
+                this.handle(recognitionListener, listener);
+                if (var26 instanceof MsgException) {
+                    return JSON.parseObject(var26.toString());
+                }
+
+                logger.info("识别程序错误:", var26);
+                return InvoiceUploadErrorType.getRecognitionErrorResult();
+            }
+            //改了的地方
+            isCheck=false;
+
+            if (isCheck && recognitionResultList.size() > 0) {
+                try {
+                    long checkStartTime = System.currentTimeMillis();
+                    List<JSONObject> checkResultList = this.recognitionCheckHelper.checkInvoiceByRecognitionInfo(recognitionResultList, extMap);
+                    logger.info("RecognitionCheckServiceEx 查验总耗时:{}", System.currentTimeMillis() - checkStartTime);
+                    finalResult = JSONObject.parseArray(JSONObject.toJSONString(checkResultList));
+                } catch (Throwable var25) {
+                    this.handle(recognitionListener, listener);
+                    logger.info("查验程序错误:", var25);
+                    return InvoiceUploadErrorType.getCheckErrorResult();
+                }
+            }
+
+            Map<String, Object> fileBaseInfo = Maps.newHashMap();
+            fileBaseInfo.put("fileType", fileType);
+            fileBaseInfo.put("fileUrl", fileUrl);
+            fileBaseInfo.put("fileName", fileName);
+            fileBaseInfo.put("size", fileEntity.getFileSize());
+            finalResult = this.putFileInfo(fileBaseInfo, finalResult, subFileFutureMap, originalStateDefault);
+            attachResult = this.dealSaleList(finalResult, businessParam);
+            boolean isHandleAttach = attachResult.size() > 0 && finalResult.size() == 0;
+            logger.info("isHandleAttach:{}", isHandleAttach);
+            if (isHandleAttach) {
+                this.handleAttach(attachResult, recognitionListener, fileUrl, fileName, totalPage);
+            }
+
+            try {
+                if (fileBaseInfo.get("totalPage") == null) {
+                    fileBaseInfo.put("totalPage", totalPage);
+                }
+
+                this.saveInvoice(finalResult, attachResult, isHandleAttach, fileBaseInfo, businessParam, recognitionListener);
+                FileUploadUtils.saveBasAttachment(fileUrl, fileName, "rim_invoice", "", fileEntity.getFileSize());
+            } catch (Throwable var24) {
+                this.handle(recognitionListener, listener);
+                logger.info("发票保存错误:", var24);
+            }
+        } catch (IOException var27) {
+            logger.info("RecognitionCheckServiceEx IOException :{}", var27);
+            this.handle(recognitionListener, listener);
+            return InvoiceUploadErrorType.getSplitErrorResult();
+        } catch (MsgException var28) {
+            logger.info("RecognitionCheckServiceEx MsgException :{}", var28);
+            this.handle(recognitionListener, listener);
+            JSONObject errorInfo = new JSONObject();
+            errorInfo.put("errcode", var28.getErrorCode());
+            errorInfo.put("description", var28.getMessage());
+            return errorInfo;
+        } catch (Throwable var29) {
+            logger.info("RecognitionCheckServiceEx BaseErrorResult Throwable:{}", var29);
+            this.handle(recognitionListener, listener);
+            return InvoiceUploadErrorType.getBaseErrorResult();
+        }
+
+        boolean resultFlag = finalResult.size() != 0 || attachResult.size() != 0;
+        logger.info("RecognitionCheckServiceEx 识别查验入库总耗时:{}", System.currentTimeMillis() - startTime);
+        if (resultFlag) {
+            return InvoiceUploadErrorType.getSuccessResult(finalResult, attachResult);
+        } else {
+            this.handle(recognitionListener, listener);
+            return InvoiceUploadErrorType.getFailResult();
+        }
+    }
+
+    private void checkOriginal(FormFileEntity fileEntity, Map<Integer, Object> subFileFutureMap, List<JSONObject> recognitionResultList) {
+        if (!StringUtils.isBlank(fileEntity.getSecondPageText()) && !CollectionUtils.isEmpty(recognitionResultList)) {
+            JSONObject firstInvoice = (JSONObject)recognitionResultList.get(0);
+            Long invoiceType = firstInvoice.getLong("invoiceType");
+            String invoiceNo = firstInvoice.getString("invoiceNo");
+            String invoiceCode = firstInvoice.getString("invoiceCode");
+            int i;
+            if (InputInvoiceTypeEnum.isCheckOriginalFile(invoiceType) && StringUtils.isNotEmpty(invoiceCode) && StringUtils.isNotEmpty(invoiceNo)) {
+                i = fileEntity.getSecondPageText().indexOf(invoiceCode);
+                int noidx = fileEntity.getSecondPageText().indexOf(invoiceNo);
+                if (i < 0 || noidx < 0) {
+                    return;
+                }
+            }
+
+            for(i = 1; i < recognitionResultList.size(); ++i) {
+                JSONObject invoice = (JSONObject)recognitionResultList.get(i);
+                Long invoiceType1 = invoice.getLong("invoiceType");
+                if (InputInvoiceTypeEnum.OTHER_INVOICE.getCode().equals(invoiceType1)) {
+                    String title = invoice.getString("title");
+                    boolean saleTitle = !StringUtils.isEmpty(title) && title.indexOf("清单") > 0;
+                    if (!saleTitle) {
+                        return;
+                    }
+                }
+            }
+
+            FileUploadAndSignTask task = new FileUploadAndSignTask(fileEntity.getFileUrl(), (byte[])null, "pdf", true, RequestContext.get());
+            task.setSignOnly(true);
+            Future<JSONObject> subUploadFuture = uploadThreadPool.submit(task);
+            subFileFutureMap.put(recheckorginPage, subUploadFuture);
+        }
+
+    }
+
+    private void handleAttach(JSONArray attachResult, IRecognitionListener recognitionListener, String fileUrl, String fileName, int totalPage) {
+        if (attachResult != null && attachResult.size() != 0) {
+            if (recognitionListener != null) {
+                Map<Integer, List<Object>> handleMap = (Map)attachResult.stream().collect(Collectors.groupingBy((v) -> {
+                    return ((JSONObject)v).getInteger("pageNo");
+                }));
+                logger.info("handleAttach handleMap:{}", handleMap);
+                Iterator var7 = handleMap.entrySet().iterator();
+
+                while(var7.hasNext()) {
+                    Map.Entry<Integer, List<Object>> entry = (Map.Entry)var7.next();
+                    int pageNo = (Integer)entry.getKey();
+                    logger.info("附件通知前端pageNo:{}", pageNo);
+                    JSONArray invoiceArray = JSONArray.parseArray(JSON.toJSONString(entry.getValue()));
+                    RecognitionListenerResult listener = new RecognitionListenerResult(fileUrl, fileName, pageNo, totalPage, invoiceArray);
+                    recognitionListener.handle(listener);
+                }
+            }
+
+        }
+    }
+
+    private JSONArray dealSaleList(JSONArray finalResult, JSONObject businessParam) {
+        if (finalResult.size() == 0) {
+            return new JSONArray();
+        } else {
+            JSONArray targetArray = this.recognitionCheckHelper.getTargetArray(finalResult);
+            finalResult.removeAll(targetArray);
+            Map<String, String> configMap = ImcConfigUtil.getValue("rim_recog_check");
+            String isDealSaleList = (String)configMap.get("is_dealsalelist");
+            if ("0".equals(isDealSaleList)) {
+                return new JSONArray();
+            } else {
+                JSONArray attachArray = this.recognitionCheckHelper.bindAttachInvoice(targetArray, businessParam);
+                List<String> finishList = Lists.newArrayList();
+                if (attachArray.size() > 0) {
+                    for(int i = 0; i < attachArray.size(); ++i) {
+                        JSONObject attachInfo = attachArray.getJSONObject(i);
+                        String invoiceCode = attachInfo.getString("invoiceCode");
+                        String invoiceNo = attachInfo.getString("invoiceNo");
+                        String isVat = attachInfo.getString("isVat");
+                        if ("1".equals(isVat)) {
+                            StringBuilder attachNo = new StringBuilder();
+                            attachNo.append(invoiceCode).append('_').append(invoiceNo);
+                            if (!finishList.contains(attachNo.toString())) {
+                                JSONObject numObject = this.recognitionCheckHelper.calcSaleListComplete(invoiceCode, invoiceNo, attachNo.toString());
+                                int salelistSum = numObject.getInteger("salelistSum");
+                                if (salelistSum == 0) {
+                                    salelistSum = attachInfo.getInteger("page_sum");
+                                }
+
+                                attachInfo.put("salelistSum", salelistSum);
+                                attachInfo.put("bindNum", numObject.getInteger("bindNum"));
+                                finishList.add(attachNo.toString());
+                            }
+                        }
+                    }
+                }
+
+                return attachArray;
+            }
+        }
+    }
+
+    public void handle(IRecognitionListener recognitionListener, RecognitionListenerResult listener) {
+        if (recognitionListener != null) {
+            recognitionListener.handle(listener);
+        }
+
+    }
+
+    public static void setInvoiceSeq(JSONObject invoiceInfo, JSONObject businessParam, int pageNo, int invoiceIndex) {
+        if (invoiceInfo != null) {
+            String uploadIndex;
+            if (businessParam == null) {
+                uploadIndex = String.valueOf(System.currentTimeMillis());
+            } else {
+                uploadIndex = businessParam.getString("uploadIndex");
+                if (StringUtils.isEmpty(uploadIndex)) {
+                    uploadIndex = String.valueOf(System.currentTimeMillis());
+                    businessParam.put("uploadIndex", uploadIndex);
+                }
+            }
+
+            invoiceInfo.put("uploadSeq", getInvoiceSeq(uploadIndex, pageNo, invoiceIndex));
+        }
+    }
+
+    public static Long getInvoiceSeq(String uploadIndex, int pageNo, int invoiceIndex) {
+        DecimalFormat decimalFormat = new DecimalFormat("000");
+        return Long.valueOf(uploadIndex + decimalFormat.format((long)pageNo) + decimalFormat.format((long)invoiceIndex));
+    }
+
+    private JSONArray putFileInfo(Map<String, Object> fileBaseInfo, JSONArray finalResult, Map<Integer, Object> subFileFutureMap, String originalStateDefault) throws ExecutionException, InterruptedException {
+        String updateFileType = String.valueOf(fileBaseInfo.get("fileType"));
+        String updateFileUrl = String.valueOf(fileBaseInfo.get("fileUrl"));
+        int size = finalResult.size();
+        boolean pdfSplit = false;
+        if (size > 1 && "pdf".equals(updateFileType)) {
+            pdfSplit = true;
+        }
+
+        Object refeature = subFileFutureMap.get(recheckorginPage);
+        boolean returnFirst = false;
+
+        for(int i = 0; i < finalResult.size(); ++i) {
+            JSONObject invoiceInfo = (JSONObject)finalResult.get(i);
+            invoiceInfo.put("fileName", fileBaseInfo.get("fileName"));
+            int pageNo = (Integer)invoiceInfo.get("pageNo");
+            Object feature = subFileFutureMap.get(pageNo);
+            if (feature != null) {
+                long start = System.currentTimeMillis();
+                JSONObject fileReuslt = this.getUploadResult(feature);
+                if (refeature != null && i == 0) {
+                    JSONObject fileReuslt2 = this.getUploadResult(refeature);
+                    if (fileReuslt2 != null) {
+                        returnFirst = "true".equals(fileReuslt2.getString("isOriginal"));
+                    }
+                }
+
+                String path;
+                if (fileReuslt != null) {
+                    path = fileReuslt.getString("isOriginal");
+                    if (!"1".equals(invoiceInfo.getString("originalState"))) {
+                        if ("true".equals(path)) {
+                            invoiceInfo.put("originalState", "1");
+                        } else {
+                            invoiceInfo.put("originalState", "0");
+                        }
+                    }
+
+                    invoiceInfo.put("snapshotUrl", fileReuslt.getString("snapshotUrl"));
+                    invoiceInfo.put("imageUrl", fileReuslt.getString("imageUrl"));
+                    invoiceInfo.put("ofdUrl", fileReuslt.getString("ofdUrl"));
+                    invoiceInfo.put("pdfUrl", fileReuslt.getString("pdfUrl"));
+                    if (pdfSplit) {
+                        invoiceInfo.put("pdfUrl", updateFileUrl);
+                    }
+
+                    invoiceInfo.put("localUrl", "");
+                    invoiceInfo.put("kdcloudUrl", "");
+                    if ("pdf".equals(FileUtils.getFileType((String)fileBaseInfo.get("fileName")))) {
+                        invoiceInfo.put("fileType", "1");
+                    } else if ("ofd".equals(FileUtils.getFileType((String)fileBaseInfo.get("fileName")))) {
+                        invoiceInfo.put("fileType", "4");
+                    } else {
+                        invoiceInfo.put("fileType", "2");
+                    }
+
+                    invoiceInfo.put("synConvert", fileReuslt.getString("synConvert"));
+                } else if (!StringUtils.isEmpty(updateFileUrl)) {
+                    path = FileUploadUtils.getSnapshotPathByUploadUrl(updateFileUrl);
+                    String imageUrl = path + ".jpg";
+                    if ("pdf".equals(updateFileType)) {
+                        invoiceInfo.put("pdfUrl", updateFileUrl);
+                        invoiceInfo.put("snapshotUrl", imageUrl);
+                        invoiceInfo.put("imageUrl", imageUrl);
+                        invoiceInfo.put("synConvert", true);
+                        invoiceInfo.put("fileType", "1");
+                        FileUploadAndSignTask.saveFileAws(new FileConvertResult(), updateFileUrl, "1");
+                    } else if ("ofd".equals(updateFileType)) {
+                        invoiceInfo.put("ofdUrl", updateFileUrl);
+                        invoiceInfo.put("pdfUrl", path + ".pdf");
+                        invoiceInfo.put("snapshotUrl", imageUrl);
+                        invoiceInfo.put("imageUrl", imageUrl);
+                        invoiceInfo.put("synConvert", true);
+                        invoiceInfo.put("fileType", "4");
+                        FileUploadAndSignTask.saveFileAws(new FileConvertResult(), updateFileUrl, "4");
+                    } else {
+                        invoiceInfo.put("snapshotUrl", updateFileUrl);
+                        invoiceInfo.put("imageUrl", updateFileUrl);
+                    }
+                }
+
+                logger.info("获取文件处理结果等待时长{},{}", System.currentTimeMillis() - start, fileReuslt);
+                if (returnFirst) {
+                    JSONArray finalResult2 = new JSONArray();
+                    invoiceInfo.put("originalState", "1");
+                    finalResult2.add(invoiceInfo);
+                    fileBaseInfo.put("totalPage", 1);
+                    return finalResult2;
+                }
+            } else {
+                logger.info("获取文件处理结果第{}页结果为空", pageNo);
+            }
+        }
+
+        return finalResult;
+    }
+
+    private JSONObject getUploadResult(Object feature) {
+        long timeOut = 10L;
+        if (feature instanceof Future) {
+            try {
+                return (JSONObject)((Future)feature).get(timeOut, TimeUnit.SECONDS);
+            } catch (InterruptedException var5) {
+                logger.info("获取文件处理结果等待超时-{} InterruptedException", timeOut);
+            } catch (ExecutionException var6) {
+                logger.info("获取文件处理结果等待超时-{} ExecutionException", timeOut);
+            } catch (TimeoutException var7) {
+                logger.info("获取文件处理结果等待超时-{} TimeoutException", timeOut);
+            }
+        } else if (feature instanceof JSONObject) {
+            return (JSONObject)feature;
+        }
+
+        return null;
+    }
+
+    private Map<Integer, Object> syncUploadSubFile(FormFileEntity fileFile) {
+        if (fileFile != null && fileFile.getSuccess()) {
+            Map<Integer, Object> result = Maps.newHashMap();
+            int pageNo = 0;
+            if (CollectionUtils.isEmpty(fileFile.getSubFileList())) {
+                result.put(1, this.syncUploadOneFile(fileFile, 1));
+            } else {
+                int totalPage = fileFile.getSubFileList().size();
+                Iterator var5 = fileFile.getSubFileList().iterator();
+
+                while(var5.hasNext()) {
+                    FormFileEntity subFile = (FormFileEntity)var5.next();
+                    ++pageNo;
+                    result.put(pageNo, this.syncUploadOneFile(subFile, totalPage));
+                }
+            }
+
+            return result;
+        } else {
+            return null;
+        }
+    }
+
+    private Object syncUploadOneFile(FormFileEntity fileFile, int totalPage) {
+        Future<JSONObject> subUploadFuture = null;
+        RequestContext context = RequestContext.get();
+        if (!"ofd".equalsIgnoreCase(fileFile.getFileType()) && !"pdf".equalsIgnoreCase(fileFile.getFileType())) {
+            JSONObject result = new JSONObject();
+            result.put("isOriginal", false);
+            result.put("fileType", "2");
+            result.put("imageUrl", fileFile.getFileUrl());
+            result.put("snapshotUrl", fileFile.getFileUrl());
+            return result;
+        } else {
+            try {
+                InputStream fileInputStream = UrlServiceUtils.getAttachmentDecodedStream(FileServiceFactory.getAttachmentFileService().getInputStream(fileFile.getFileUrl()));
+                Throwable var6 = null;
+
+                try {
+                    byte[] streamByte = FileUtils.getByte(fileInputStream);
+                    subUploadFuture = uploadThreadPool.submit(new FileUploadAndSignTask(fileFile.getFileUrl(), streamByte, fileFile.getFileType(), fileFile.getSignatureFlag(), context));
+                } catch (Throwable var16) {
+                    var6 = var16;
+                    throw var16;
+                } finally {
+                    if (fileInputStream != null) {
+                        if (var6 != null) {
+                            try {
+                                fileInputStream.close();
+                            } catch (Throwable var15) {
+                                var6.addSuppressed(var15);
+                            }
+                        } else {
+                            fileInputStream.close();
+                        }
+                    }
+
+                }
+            } catch (IOException var18) {
+                logger.error("文件处理失败:" + fileFile.getFileUrl(), var18);
+            }
+
+            return subUploadFuture;
+        }
+    }
+
+    private void saveInvoice(JSONArray finalResult, JSONArray attachResult, boolean isHandleAttach, Map<String, Object> fileBaseInfo, JSONObject businessParam, IRecognitionListener recognitionListener) {
+        String fileUrl = (String)fileBaseInfo.get("fileUrl");
+        String fileName = (String)fileBaseInfo.get("fileName");
+        int totalPage = (Integer)fileBaseInfo.get("totalPage");
+        JSONArray handleResult = new JSONArray();
+        JSONArray mayErrorResult = new JSONArray();
+
+        for(int i = 0; i < finalResult.size(); ++i) {
+            try {
+                JSONObject invoiceInfo = finalResult.getJSONObject(i);
+                int pageNo = (Integer)invoiceInfo.get("pageNo");
+                setInvoiceSeq(invoiceInfo, businessParam, pageNo, i + 1);
+                Set<String> serialNosSet = new HashSet(8);
+                String snapshotUrl = null;
+                String awsInvoiceType = invoiceInfo.getString("invoiceType");
+                Long invoiceType = InputInvoiceTypeEnum.getInvoiceTypeByAwsType(awsInvoiceType);
+                if (InputInvoiceTypeEnum.ELECTRIC_ORDINARY.getCode().equals(invoiceType) || InputInvoiceTypeEnum.ELECTRIC_SPECIAL.getCode().equals(invoiceType)) {
+                    String originalConfig = RimConfigUtils.getConfig("rim_config", "einvoice_auto_sign");
+                    if (!StringUtils.isEmpty(originalConfig) && !"0".equals(originalConfig)) {
+                        invoiceInfo.put("originalState", "1");
+                    } else {
+                        invoiceInfo.put("originalState", "0");
+                    }
+                }
+
+                invoiceInfo.put("invoiceType", invoiceType);
+                Long tax_org = null;
+                String resourcePlugin = "";
+                if (null != businessParam) {
+                    invoiceInfo.putAll(businessParam);
+                    tax_org = businessParam.getLong("tax_org");
+                    resourcePlugin = businessParam.getString("resourcePlugin");
+                }
+
+                if (!ObjectUtils.isEmpty(tax_org)) {
+                    invoiceInfo.put("tax_org", tax_org);
+                }
+
+                if (StringUtils.isNotEmpty(invoiceInfo.getString("snapshotUrl"))) {
+                    snapshotUrl = FileUtils.downLoadAndUpload(invoiceInfo.getString("snapshotUrl"));
+                }
+
+                if (StringUtils.isNotEmpty(snapshotUrl)) {
+                    invoiceInfo.put("snapshotUrl", snapshotUrl);
+                }
+
+                logger.info("发票识别查验返回数据:" + invoiceInfo);
+                ConvertFieldUtil.getStandardInvoice(invoiceInfo);
+                if (StringUtils.isEmpty(invoiceInfo.getString("serialNo")) || serialNosSet.add(invoiceInfo.getString("serialNo"))) {
+                    if ("sign_by_expense".equals(resourcePlugin)) {
+                        InvoiceSaveService invoiceSaveService = InvoiceSaveService.newInstance(invoiceInfo.getString("invoiceType"));
+                        if (invoiceSaveService != null) {
+                            invoiceInfo.put("delete", invoiceSaveService.setInvoiceFiled(invoiceInfo));
+                        }
+                    }
+
+                    String fileHash = invoiceInfo.getString("fileHash");
+                    String resourceSys = invoiceInfo.getString("resourceSys");
+                    String errcode = invoiceInfo.getString("errcode");
+                    if ("4999".equals(errcode) && InvoiceConvertUtils.isVatInvoiceType(invoiceInfo.getLong("invoiceType"))) {
+                        invoiceInfo.put("checkStatus", "3");
+                    }
+
+                    try {
+                        Object invoiceDate = invoiceInfo.get("invoiceDate");
+                        if (invoiceDate instanceof Long) {
+                            Date date = new Date((Long)invoiceDate);
+                            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+                            String dateString = formatter.format(date);
+                            invoiceInfo.put("invoiceDate", dateString);
+                        }
+
+                        this.invoiceCollectService.saveInvoice(invoiceInfo, fileUrl, fileHash);
+                    } catch (Exception var28) {
+                        mayErrorResult.add(invoiceInfo);
+                    }
+
+                    String isSaleListInvoice = invoiceInfo.getString("isSaleListInvoice");
+                    Map<String, String> configMap = ImcConfigUtil.getValue("rim_recog_check");
+                    String isDealSaleList = (String)configMap.get("is_dealsalelist");
+                    if ("1".equals(isSaleListInvoice) && !"0".equals(isDealSaleList)) {
+                        this.recognitionCheckHelper.dealInvoiceAttachRelation(invoiceInfo);
+                    }
+
+                    logger.info("发票助手本地上传保存发票后的数据:" + invoiceInfo);
+                }
+
+                handleResult.add(invoiceInfo);
+            } catch (Throwable var29) {
+                handleResult.add(mayErrorResult);
+                logger.info("发票入库失败:", var29);
+            }
+        }
+
+        if (recognitionListener != null) {
+            this.finallyHandleResult(handleResult, isHandleAttach, attachResult, fileUrl, fileName, totalPage, recognitionListener);
+        }
+
+    }
+
+    private void finallyHandleResult(JSONArray handleResult, boolean isHandleAttach, JSONArray attachResult, String fileUrl, String fileName, int totalPage, IRecognitionListener recognitionListener) {
+        Map<Integer, List<Object>> handleMap = (Map)handleResult.stream().collect(Collectors.groupingBy((v) -> {
+            return ((JSONObject)v).getInteger("pageNo");
+        }));
+        Map<Integer, List<Object>> handleAttachMap = Maps.newLinkedHashMap();
+        if (!isHandleAttach) {
+            handleAttachMap = (Map)attachResult.stream().collect(Collectors.groupingBy((v) -> {
+                return ((JSONObject)v).getInteger("pageNo");
+            }));
+        }
+
+        JSONArray handleAttachArray = new JSONArray();
+        Iterator var11 = handleMap.entrySet().iterator();
+
+        while(var11.hasNext()) {
+            Map.Entry<Integer, List<Object>> entry = (Map.Entry)var11.next();
+            int pageNo = (Integer)entry.getKey();
+            JSONArray invoiceArray = JSONArray.parseArray(JSON.toJSONString(entry.getValue()));
+            logger.info("handleAttachMap:{}", handleAttachMap);
+            if (!((Map)handleAttachMap).isEmpty()) {
+                logger.info("添加清单到发票结果集通知前端:{}", pageNo);
+                Iterator var15 = ((Map)handleAttachMap).entrySet().iterator();
+
+                while(var15.hasNext()) {
+                    Map.Entry<Integer, List<Object>> attachEntry = (Map.Entry)var15.next();
+                    int attachPageNo = (Integer)attachEntry.getKey();
+                    if (pageNo == attachPageNo) {
+                        invoiceArray.addAll(JSONArray.parseArray(JSON.toJSONString(attachEntry.getValue())));
+                    } else {
+                        handleAttachArray.addAll(JSONArray.parseArray(JSON.toJSONString(attachEntry.getValue())));
+                    }
+                }
+            }
+
+            RecognitionListenerResult listener = new RecognitionListenerResult(fileUrl, fileName, pageNo, totalPage, invoiceArray);
+            recognitionListener.handle(listener);
+        }
+
+        if (!handleAttachArray.isEmpty()) {
+            Map<Integer, List<Object>> handleAttach = (Map)handleAttachArray.stream().collect(Collectors.groupingBy((v) -> {
+                return ((JSONObject)v).getInteger("pageNo");
+            }));
+            Iterator var19 = handleAttach.entrySet().iterator();
+
+            while(var19.hasNext()) {
+                Map.Entry<Integer, List<Object>> entry = (Map.Entry)var19.next();
+                int pageNo = (Integer)entry.getKey();
+                JSONArray attachArray = JSONArray.parseArray(JSON.toJSONString(entry.getValue()));
+                RecognitionListenerResult listener = new RecognitionListenerResult(fileUrl, fileName, pageNo, totalPage, attachArray);
+                recognitionListener.handle(listener);
+            }
+        }
+
+    }
+
+    private boolean getCheckFlag(JSONObject businessParam) {
+        boolean isCheck = true;
+        if (businessParam != null) {
+            isCheck = !"1".equals(businessParam.getString("notCheck"));
+        }
+        if (!isCheck) {
+            businessParam.put("errcode", "4999");
+            businessParam.put("description", CheckContant.getCheckResultDesc("4999"));
+        }
+
+        return isCheck;
+    }
+}

+ 129 - 0
src/main/java/kd/imc/rim/formplugin/collector/InvoiceCollectPluginEx.java

@@ -0,0 +1,129 @@
+package kd.imc.rim.formplugin.collector;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.serialization.SerializationUtils;
+import kd.bos.ext.form.control.CustomControl;
+import kd.bos.form.IPageCache;
+import kd.bos.form.control.events.UploadEvent;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.util.CollectionUtils;
+import kd.bos.threads.ThreadPools;
+import kd.bos.util.StringUtils;
+import kd.imc.rim.common.constant.CollectTypeEnum;
+import kd.imc.rim.common.invoice.collector.InvoiceCollectTask;
+import kd.imc.rim.common.invoice.collector.InvoiceCollectTaskNew;
+import kd.imc.rim.common.service.DialogService;
+import kd.imc.rim.common.utils.BigDecimalUtil;
+import kd.imc.rim.common.utils.PermissionUtils;
+import kd.imc.rim.common.utils.RimConfigUtils;
+
+import java.util.*;
+
+public class InvoiceCollectPluginEx extends InvoiceCollectPlugin{
+    private static Log logger = LogFactory.getLog(InvoiceCollectPluginEx.class);
+
+    @Override
+    public void afterUpload(UploadEvent evt) {
+        {
+            String itemKey = evt.getCallbackKey();
+            Object[] urls = evt.getUrls();
+            logger.info("上传文件:{}-{}", itemKey, urls);
+            if (urls.length > 0) {
+                StringJoiner taskUrls = new StringJoiner(",");
+                List<Map<String, String>> fileUrls = new ArrayList(urls.length);
+                String mapSeqStr = this.getPageCache().get("upload_seq");
+                Map<String, Object> nameSeq = new HashMap(urls.length);
+                if (StringUtils.isNotEmpty(mapSeqStr)) {
+                    nameSeq = (Map) SerializationUtils.fromJsonString(mapSeqStr, nameSeq.getClass());
+                }
+
+                int i = 0;
+
+                for(int size = urls.length; i < size; ++i) {
+                    String url = urls[i].toString();
+                    String fileName = url.substring(url.lastIndexOf(47) + 1);
+                    Map<String, String> map = new HashMap(2);
+                    map.put("url", url);
+                    map.put("name", fileName);
+                    if (!CollectionUtils.isEmpty((Map)nameSeq)) {
+                        String seq = String.valueOf(((Map)nameSeq).get(fileName));
+                        if (StringUtils.isNotEmpty(seq)) {
+                            map.put("seq", seq);
+                        }
+                    }
+
+                    fileUrls.add(map);
+                }
+
+                Collections.sort(fileUrls, (o1, o2) -> {
+                    Long uploadSeq1 = BigDecimalUtil.transDecimal(o1.get("seq")).longValue();
+                    Long uploadSeq2 = BigDecimalUtil.transDecimal(o2.get("seq")).longValue();
+                    return uploadSeq1.compareTo(uploadSeq2);
+                });
+                Iterator var14 = fileUrls.iterator();
+
+                while(var14.hasNext()) {
+                    Map<String, String> fileUrl = (Map)var14.next();
+                    taskUrls.add((CharSequence)fileUrl.get("url"));
+                }
+
+                this.getPageCache().put("upload_itemKey", itemKey);
+                this.getPageCache().remove("upload_seq");
+                this.getPageCache().put("taskUrls", taskUrls.toString());
+                this.progressBarVisible(Boolean.TRUE, new String[]{"进行中..."});
+                this.getPageCache().put("startprogress", "true");
+                JSONObject businessParam = this.getBusinessParam(CollectTypeEnum.PC_UPLOAD.getCode());
+                businessParam.put("itemKey", itemKey);
+                InvoiceCollectTaskNew collectTask = new InvoiceCollectTaskNew(RequestContext.get(), this.getView().getPageId(), fileUrls, businessParam);
+                ThreadPools.executeOnce("CollectorProgressPool", collectTask);
+            }
+
+        }
+    }
+    private JSONObject getBusinessParam(String collectType) {
+        JSONObject businessParam = new JSONObject();
+        IPageCache pageCache = this.getView().getPageCache();
+        String businessParamCache = pageCache.get("businessParam");
+        if (businessParamCache != null) {
+            businessParam = JSON.parseObject(businessParamCache);
+        } else {
+            RequestContext request = RequestContext.get();
+            businessParam.put("collect_type", collectType);
+            businessParam.put("resource", "收票管理");
+            businessParam.put("isAdmin", PermissionUtils.checkPermission(request.getUserId(), request.getOrgId(), this.getView(), "1PAFGP5MO1NU"));
+            String state = RimConfigUtils.getConfig("original_state");
+            if ("1".equals(state)) {
+                businessParam.put("originalState", "1");
+            }
+
+            Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
+            if (!CollectionUtils.isEmpty(customParams)) {
+                businessParam.putAll(customParams);
+            }
+
+            businessParam.put("billType", "fpqs");
+            pageCache.put("businessParam", businessParam.toJSONString());
+        }
+
+        logger.info("发票签收采集参数:" + businessParam);
+        return businessParam;
+    }
+
+    private void progressBarVisible(Boolean visibleFlag, String[] descriptionArray) {
+        CustomControl customcontrol = (CustomControl)this.getControl("progressBar_customcontrol");
+        DialogService service = new DialogService(customcontrol);
+        if (visibleFlag) {
+            if (null != descriptionArray) {
+                service.show("1", descriptionArray, 500);
+            } else {
+                service.show("1", new String[]{"进行中..."}, 500);
+            }
+        } else {
+            service.hide();
+        }
+
+    }
+}