Ver Fonte

质检资料保存优化

lvy há 10 horas atrás
pai
commit
6672f2b6a4

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -2436,7 +2436,8 @@ public class ExcelTabController extends BladeController {
         }
 
         //保存数据到数据库
-        R<Object> result = this.excelTabService.saveOrUpdateInfo(tableInfoList,singnType,flag);
+//        R<Object> result = this.excelTabService.saveOrUpdateInfo(tableInfoList,singnType,flag);
+        R<Object> result = this.excelTabService.saveOrUpdateInfo1(tableInfoList,flag);
         RandomNumberHolder.RandomTemplateTypeclear();
         RandomNumberHolder.RandomWbsTreeContractclear();
         executionTime.info("----数据保存结束----");

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java

@@ -109,6 +109,7 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
      * 结果信息持久化
      */
     R<Object> saveOrUpdateInfo(List<TableInfo> tableInfoList,String singType,Boolean flag) throws SQLException;
+    R<Object> saveOrUpdateInfo1(List<TableInfo> tableInfoList,Boolean flag) throws SQLException;
 
     Map<String, String> getTablbCols(String pkeyid, String colkey) throws FileNotFoundException;
 

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java

@@ -43,6 +43,7 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     List<WbsTreeContractTreeVO3> lazyTreeThree(String contractIdRelation, Long parentId, String contractId);
 
     List<AppWbsTreeContractVO> searchNodeAllTable(String primaryKeyId, String tableOwner, String contractId, String projectId, HttpServletRequest request);
+    List<AppWbsTreeContractVO> searchNodeAllTable(String primaryKeyId, String tableOwner);
 
     List<WbsTreeContract> searchParentAllNode(long primaryKeyId, Long contractId);
 

+ 132 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -675,7 +675,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     private List<NodeTable> createNodeTables(Long nodeId, String contractId, String projectId, ExecuteType type ,String tableOwner, String recordId) {
         List<NodeTable> tableAll = new ArrayList<>();
         if (type.equals(ExecuteType.INSPECTION)) {
-            List<AppWbsTreeContractVO> treeNode = wbsTreeContractService.searchNodeAllTable(nodeId.toString(), tableOwner, contractId, projectId, null);
+            List<AppWbsTreeContractVO> treeNode = wbsTreeContractService.searchNodeAllTable(nodeId.toString(), tableOwner);
             tableAll = BeanUtil.copyProperties(treeNode, NodeTable.class);
         } else if (type.equals(ExecuteType.TESTING)) {
             List<WbsTreePrivateVO4> wbsTreePrivateVO4s = wbsTreePrivateService.searchNodeAllTable(nodeId.toString(), "1", "9", contractId, projectId, null, null);
@@ -711,8 +711,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             } else {
                 List<WbsTreeContract> list = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>query().lambda().in(WbsTreeContract::getPKeyId, pkeyIds));
                 if (list.size() > 0) {
+                    Map<String, Map<String, String>> htmlElementCellMap = new HashMap<>();
                     list.forEach(e -> {
-                        Map<String, String> elementCell = FormulaUtils.getElementCell(e.getHtmlUrl());
+                        Map<String, String> map = htmlElementCellMap.get(e.getHtmlUrl());
+                        if (map == null) {
+                            map = FormulaUtils.getElementCell(e.getHtmlUrl());
+                            htmlElementCellMap.put(e.getHtmlUrl(), map);
+                        }
+                        Map<String, String> elementCell = map;
                         //扩展中间元素开发 获取字段是辅助字段  并且在html上没有这个字段
                         List<String> collect = keyMappers.stream().filter(f -> f.getAssist() == 1
                                 && elementCell.get(f.getField()) == null).map(KeyMapper::getField).collect(Collectors.toList());
@@ -1862,6 +1868,123 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
        return R.data(tableInfoList2);
        // return R.success(fileName1);
     }
+
+    /**
+     * 保存数据, 仅针对同一节点下的表
+     * @param tableInfoList 表数据
+     * @param flag 是否回滚
+     * @return
+     */
+    @Override
+    public R<Object> saveOrUpdateInfo1(List<TableInfo> tableInfoList,Boolean flag) {
+        List<TableInfo> tableInfoList2 = new ArrayList<>();
+        String fileName1="";
+        if (ListUtils.isNotEmpty(tableInfoList)) {
+            //施工资料填报
+            String pkids = "";
+            StringBuilder log = new StringBuilder("异常:");
+            StringBuilder saveData = new StringBuilder(tableInfoList.toString());
+            try {
+                Set<Long> pKeyIds = tableInfoList.stream().filter(item -> StringUtil.isNumeric(item.getPkeyId())).map(item -> Long.parseLong(item.getPkeyId())).collect(Collectors.toSet());
+                Map<String, WbsTreeContract> contractMap = new HashMap<>();
+                WbsTreeContract wbsTreeContractByP = null;
+                if (!pKeyIds.isEmpty()) {
+                    List<WbsTreeContract> list = wbsTreeContractService.list(Wrappers.<WbsTreeContract>query().lambda().in(WbsTreeContract::getPKeyId, pKeyIds));
+                    contractMap = list.stream().collect(toMap(item -> item.getPKeyId() + "", item -> item, (k1, k2) -> k1));
+                    Set<Long> pIds = list.stream().filter(item -> item.getPId() != null && item.getPId() > 0).map(WbsTreeContract::getPId).collect(Collectors.toSet());
+                    if (!pIds.isEmpty()) {
+                        wbsTreeContractByP = wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>query().lambda().in(WbsTreeContract::getPKeyId, pIds).last( " limit 1"));
+                    }
+                }
+                if (wbsTreeContractByP == null) {
+                    return R.fail("没有找到表单数据对应的节点");
+                }
+                for (TableInfo tableInfo : tableInfoList) {
+                    WbsTreeContract wbsTreeContract = contractMap.get(tableInfo.getPkeyId());
+                    StringBuilder tableName = new StringBuilder("");
+                    if (wbsTreeContract == null) {
+                        continue;
+                    }
+                    tableInfo.setIsTypePrivatePid(wbsTreeContract.getExcelId()+"");
+                    tableInfoList2.add(tableInfo);
+                    pkids += tableInfo.getPkeyId() + ",";
+                    String tabName = wbsTreeContract.getInitTableName();
+                    // 判读修改还是 添加
+                    String delSql = "delete from " + tabName + " where p_key_id=" + tableInfo.getPkeyId();
+                    String sqlInfo = "";
+                    LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+                    /*检查发现有p_key_id缺失的情况,导致表单数据丢失,所以强制覆盖*/
+                    dataMap2.put("p_key_id", tableInfo.getPkeyId());
+                    dataMap2=isPartition(wbsTreeContract,tabName,dataMap2);
+                    sqlInfo = buildMTableInsertSql(tabName, dataMap2, SnowFlakeUtil.getId(), null, null).toString();
+
+                    UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
+                    updateWrapper.in("p_key_id", tableInfo.getPkeyId());
+                    updateWrapper.set("is_tab_pdf", 2);
+                    BladeUser user = AuthUtil.getUser();
+                    TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
+                    try {
+                        wbsTreeContractService.update(updateWrapper);
+                        //添加被张表的操作日志
+                        StringBuffer sb = new StringBuffer();
+                        String sqlInfoNew = sqlInfo.replace("\"", "'");
+                        sb.append("insert into blade_tab_sql(p_key_id,user_id,create_time,sql_info) VALUES(");
+                        sb.append(tableInfo.getPkeyId());sb.append(",");sb.append(user.getUserId());
+                        sb.append(","); sb.append("SYSDATE()");sb.append(",\"");sb.append(sqlInfoNew);
+                        sb.append("\")");
+
+                        jdbcTemplate.execute(delSql);
+                        jdbcTemplate.execute(sqlInfo.replace("\\","\\\\"));
+                        jdbcTemplate.execute(sb.toString());
+
+                        transactionManager1.commit(transactionStatus);
+                    } catch (Exception e) {
+                        //是否回滚
+                        if(flag){
+                            transactionManager1.rollback(transactionStatus);
+                            log.append(e.getMessage()).append("@@");
+                            e.printStackTrace();
+                            return R.fail(reason(e.getMessage()));
+                        }else {
+                            tableName.append(wbsTreeContract.getNodeName()+",");
+                            RandomNumberHolder.setLogMessage(tableName.toString());
+                        }
+                    }
+                }
+                //处理文件提名
+                fileName1= this.wbsParamService.createFileTitle(wbsTreeContractByP);
+                if(wbsTreeContractByP.getMajorDataType()!=null&&wbsTreeContractByP.getMajorDataType()==4){
+                    String sql1="Select sg_suffix,jl_suffix from m_project_info where id="+wbsTreeContractByP.getProjectId()+" and is_deleted=0";
+                    List<ProjectInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ProjectInfo.class));
+                    if(query.size()>0){
+                        if(tableInfoList.get(0).getClassify()!=null&&tableInfoList.get(0).getClassify().equals("1")){
+                            fileName1=fileName1+(query.get(0).getSgSuffix()==null?"":query.get(0).getSgSuffix());
+                        }else {
+                            fileName1=fileName1+(query.get(0).getJlSuffix()==null?"":query.get(0).getJlSuffix());
+                        }
+                    }
+                }
+                //huangjn 保存成功后调用生成资料查询列表数据
+                this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName1, Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
+                JSONObject json = new JSONObject();
+                json.put("operationObjIds", Func.toStrList(pkids));
+                json.put("operationObjName", wbsTreeContractByP.getNodeName() + "节点数据操作");
+                json.put("saveData", saveData.toString());
+                json.put("projectId", wbsTreeContractByP.getProjectId());
+                json.put("contractId", wbsTreeContractByP.getContractId());
+
+                //保存操作记录
+                this.operationLogClient.saveUserOperationLog(1, "资料填报", "工序填报页面", json);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return R.fail("操作失败");
+            }
+            if (log.length() > 5) {
+                return R.fail(reason(log.toString()));
+            }
+        }
+        return R.data(tableInfoList2);
+    }
     public LinkedHashMap<String ,String> isPartition(WbsTreeContract wbsTreeContract,String tabName,LinkedHashMap<String, String> dataMap2){
         //判断是否需要移除编号 当工序 子分项 分项的划分编码有一个不为null就移除编号
         String sqlContractInfo="select * from m_contract_info where id="+wbsTreeContract.getContractId();
@@ -3316,7 +3439,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     public void getBussPdfs(String nodeId, String classify, String contractId, String projectId) throws Exception {
         String file_path = FileUtils.getSysLocalFileUrl();
         // 获取有权限的节点信息
-        List<AppWbsTreeContractVO> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId, null);
+//        List<AppWbsTreeContractVO> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId, null);
+        List<AppWbsTreeContractVO> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify);
         List<String> data = new ArrayList<>();
         if (nodeId.indexOf(":") >= 0) {
             nodeId = nodeId.split(":")[0];
@@ -3346,8 +3470,12 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
         if (data.size() >= 1) {
             //资料填报原始pdf合并
-            FileUtils.mergePdfPublicMethods(data, listPdf);
+//            FileUtils.mergePdfPublicMethods(data, listPdf);
+            long startTime = System.currentTimeMillis();
+            FileUtils.mergePDFParallel(data, listPdf);
+            long endTime = System.currentTimeMillis();
             BladeFile bladeFile = this.newIOSSClient.uploadFile(nodeId + ".pdf", listPdf);
+            System.out.println("pdf合并耗时:" + (endTime - startTime) + "ms, pdf合并个数:" + data.size() + ", pdf 上传耗时:" + (System.currentTimeMillis() - endTime) + "ms");
             if(bladeFile == null){
                 System.out.println("Oss上传失败");
             }

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -236,7 +236,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             tec.constantMap.put(WP, getWpMap(one, tec));
 
             /*表格名称*/
-            List<AppWbsTreeContractVO> tableList = wbsTreeContractService.searchNodeAllTable(one.getPkId().toString(), "1", tec.getContractId().toString(), tec.getProjectId().toString(), null);
+            List<AppWbsTreeContractVO> tableList = wbsTreeContractService.searchNodeAllTable(one.getPkId().toString(), "1");
             tec.constantMap.put(TABLE_LIST, tableList);
 
             /*监表质量附件,过滤掉隐藏表格*/

+ 61 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -673,6 +673,67 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return resultTabs;
     }
 
+    /**
+     * 根据节点pKeyId获取节点下所属 tableOwer 表单
+     * 没有用户填报信息
+     */
+    @Override
+    public List<AppWbsTreeContractVO> searchNodeAllTable(String primaryKeyId, String tableOwner) {
+        WbsTreeContract wbsTreeContract = baseMapper.selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                .eq(WbsTreeContract::getPKeyId, primaryKeyId));
+        if (wbsTreeContract == null) {
+            return Collections.emptyList();
+        }
+        //接口请求表单类型(施工质检 或 监理抽检)
+        Set<String> tabTableOwnerSets = new HashSet<>();
+        /*tableOwner!=null,表示从资料填报查询,查权限数据,roleTableOwnerSets=取交集后*/
+        if (StringUtils.isNotEmpty(tableOwner)) {
+            String tableOwners;
+            if (tableOwner.equals("1")) {
+                tableOwners = "1,2,3";
+            } else if (tableOwner.equals("2")) {
+                tableOwners = "4,5,6";
+            } else {
+                tableOwners = "7,8,9";
+            }
+            tabTableOwnerSets.addAll(Func.toStrList(tableOwners));
+        }
+        //判断是客户端还是APP
+        List<AppWbsTreeContractVO> resultTabs;
+        //其他接口调用默认保持原始调用方式查询
+        if (!tabTableOwnerSets.isEmpty()) {
+            List<WbsTreeContract> wbsTreeContracts = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+                    .eq(WbsTreeContract::getProjectId, wbsTreeContract.getProjectId()).eq(WbsTreeContract::getWbsId, wbsTreeContract.getWbsId())
+                    .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()).eq(WbsTreeContract::getParentId, wbsTreeContract.getId()).eq(WbsTreeContract::getType, 2)
+                    .eq(WbsTreeContract::getStatus, 1).eq(StringUtil.hasText(wbsTreeContract.getContractIdRelation()) , WbsTreeContract::getContractId, wbsTreeContract.getContractIdRelation())
+                    .in(WbsTreeContract::getTableOwner, tabTableOwnerSets).last(" ORDER BY sort,full_name,create_time"));
+            resultTabs = wbsTreeContracts.stream().map(item -> {
+                AppWbsTreeContractVO appWbsTreeContractVO = new AppWbsTreeContractVO();
+                BeanUtil.copy(item, appWbsTreeContractVO);
+                return appWbsTreeContractVO;
+            }).collect(Collectors.toList());
+        } else {
+            resultTabs = new ArrayList<>();
+        }
+        if (ObjectUtil.isNotEmpty(wbsTreeContract.getMajorDataType()) && wbsTreeContract.getMajorDataType().equals(2)) {
+            resultTabs.sort(Comparator.comparing((WbsTreeContract contract) -> contract.getNodeName().contains("JS107"))
+                    .thenComparing(WbsTreeContract::getNodeName));
+        }
+        if (Optional.ofNullable(wbsTreeContract.getIsUseSort()).orElse(0) == 0) {
+            //表单排序
+            if (!resultTabs.isEmpty()) {
+                sortTabsByIsTypePrivatePid(resultTabs);
+                // 使用自定义 Comparator 进行排序
+                resultTabs.sort(new WbsTreeContractComparator());
+                List<AppWbsTreeContractVO> resultTabsToCopy = this.sortTabs(resultTabs, "__"); //复制表排序
+                return this.sortTabs(resultTabsToCopy, "_PL_"); //频率表排序
+            }
+        }
+        // 使用自定义 Comparator 进行排序
+        resultTabs.sort(new WbsTreeContractComparator());
+        return resultTabs;
+    }
+
     private void sortTabsByIsTypePrivatePid(List<AppWbsTreeContractVO> resultTabs) {
         if(!resultTabs.isEmpty()){
            StringBuilder ids=new StringBuilder("");

+ 110 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java

@@ -28,6 +28,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.utils.DigestUtil;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -55,6 +56,7 @@ import java.net.URLEncoder;
 import java.nio.file.*;
 import java.util.List;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
@@ -302,6 +304,114 @@ public class FileUtils {
             doc.close();
         }
     }
+    private static void mergeChunkSequentially(List<String> urlList, String outputFile) {
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try {
+            pdfCopy = new PdfCopy(doc, Files.newOutputStream(Paths.get(outputFile)));
+            doc.open();
+            for (String urlStr : urlList) {
+                try (InputStream inputStream = CommonUtil.getOSSInputStream(urlStr)) {
+                    if (inputStream == null) {
+                        continue;
+                    }
+                    PdfReader reader = new PdfReader(inputStream);
+                    PdfReader.unethicalreading = true;
+
+                    int pageCount = reader.getNumberOfPages();
+                    for (int i = 1; i <= pageCount; i++) {
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader, i));
+                    }
+                    reader.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            doc.close();
+            if (pdfCopy != null) {
+                pdfCopy.close();
+            }
+        }
+    }
+
+    private static void mergeTempFiles(List<String> tempFiles, String outputFile) {
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try {
+            pdfCopy = new PdfCopy(doc, new FileOutputStream(outputFile));
+            doc.open();
+
+            for (String tempFile : tempFiles) {
+                try (FileInputStream fis = new FileInputStream(tempFile)) {
+                    PdfReader reader = new PdfReader(fis);
+                    int pageCount = reader.getNumberOfPages();
+                    for (int i = 1; i <= pageCount; i++) {
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader, i));
+                    }
+                    reader.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            doc.close();
+            if (pdfCopy != null) {
+                pdfCopy.close();
+            }
+        }
+    }
+    public static void mergePDFParallel(List<String> urlList, String localImgUrl) {
+        int chunkSize = 50; // 每块处理的PDF数量
+        long tempId = SnowFlakeUtil.getId();
+        try {
+            if (urlList.size() % chunkSize != 0) {
+                int numChunks =  urlList.size() / chunkSize + 1;
+                chunkSize = urlList.size() / numChunks + 1;
+            }
+            // 将URL列表分块
+            List<Map<Integer, List<String>>> chunks = new ArrayList<>();
+            for (int i = 0; i < urlList.size(); i += chunkSize) {
+                int end = Math.min(i + chunkSize, urlList.size());
+                Map<Integer, List<String>> chunkMap = new HashMap<>();
+                chunkMap.put(i,urlList.subList(i, end));
+                chunks.add(chunkMap);
+            }
+            // 并行处理每个块,生成临时文件
+            Map<String, Integer> tempFilesSortMap = new ConcurrentHashMap<>();
+            chunks.parallelStream().forEach(chunk -> {
+                try {
+                    String tempFile = System.getProperty("java.io.tmpdir") + "/temp_" + tempId + "_" + SnowFlakeUtil.getId() + ".pdf";
+                    chunk.forEach((key, value) -> {
+                        tempFilesSortMap.put(tempFile, key);
+                        mergeChunkSequentially(value, tempFile);
+                    });
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            });
+            if (!tempFilesSortMap.isEmpty()) {
+                List<String> tempFiles = new ArrayList<>(tempFilesSortMap.keySet());
+                tempFiles.sort(Comparator.comparingInt(tempFilesSortMap::get));
+                // 最后合并所有临时文件
+                mergeTempFiles(tempFiles, localImgUrl);
+                // 清理临时文件
+                tempFiles.forEach(tempFile -> {
+                    try {
+                        Files.deleteIfExists(Paths.get(tempFile));
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                });
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 
     /**
      * Excel 转 PDF(完整缩放到 A4 纸张)