Procházet zdrojové kódy

feat: 导入清单,支持导入单机版导出的excel工程量清单

vian před 5 roky
rodič
revize
571830178b
1 změnil soubory, kde provedl 82 přidání a 7 odebrání
  1. 82 7
      web/building_saas/main/js/views/importBills.js

+ 82 - 7
web/building_saas/main/js/views/importBills.js

@@ -36,7 +36,8 @@ const importBills = (function () {
     }
     const fileType = {
         gcl: 0, //工程量清单
-        qdsl: 1 //清单示例
+        qdsl: 1, //清单示例
+        gclex: 2, // 单机版导出的工程量清单预算表,需要转换成清单示例表来处理
     };
     //获取列字段对应
     function getColMapping(type) {
@@ -50,6 +51,10 @@ const importBills = (function () {
         let cell = dataRow[0];
         return cell && cell.value === '工程量清单';
     }
+    function isGCLExtendHead(dataRow) {
+        let cell = dataRow[0];
+        return cell && cell.value === '工程量清单预算表';
+    }
     //分析文件,1、工程量清单 2、清单示例表
     function getFileType(sheetData) {
         let dataTable = sheetData.data.dataTable,
@@ -58,6 +63,9 @@ const importBills = (function () {
             if (isGCLHead(dataTable[row])) {
                 return fileType.gcl;
             }
+            if (isGCLExtendHead(dataTable[row])) {
+                return fileType.gclex;
+            }
         }
         return fileType.qdsl;
     }
@@ -166,18 +174,77 @@ const importBills = (function () {
         return match ? match[1] : null;
     }
 
+    // 示例列映射
+    const slColMap = { code: 0, name: 1, unit: 2, quantity: 3 };
+
+    function isValidGCLExRow(rowData) {
+        if (rowData[0] && /编制[::]/.test(rowData[0].value)) {
+            return false;
+        }
+        if (rowData[1] && /合计/.test(rowData[1].value)) {
+            return false;
+        }
+        if ((!rowData[slColMap.code] || !rowData[slColMap.code].value) &&
+            (!rowData[slColMap.name] || !rowData[slColMap.name].value) &&
+            (!rowData[slColMap.unit] || !rowData[slColMap.unit].value) &&
+            (!rowData[slColMap.quantity] || !rowData[slColMap.quantity].value)) {
+            return false;
+        }
+        return true;
+    }
+
+    // 将“工程量清单预算表”去掉表头表尾,并转换成清单示例表。
+    // 工程量清单预算表的格式可参考需求:BUG #3037
+    function transformGCLExToSL(sheetData) {
+        const rst = {
+            data: { dataTable: [] },
+            rowCount: 0,
+        };
+        const dataTable = sheetData.data.dataTable;
+        const rowCount = sheetData.rowCount;
+        let preRootName;
+        for (let row = 0; row < rowCount; row++) {
+            const rowData = dataTable[row];
+            if (isGCLExtendHead(rowData)) {
+                const rootRowdata = dataTable[row + 3];
+                const name = rootRowdata[0].value;
+                if (name) {
+                    const rootName = name.replace('工程量清单', '清单');
+                    if (rootName !== preRootName) {
+                        preRootName = rootName;
+                        rst.data.dataTable.push({
+                            [slColMap.name]: { value: rootName }
+                        });
+                    }
+                }
+                row += 4;
+                continue;
+            }
+            if (isValidGCLExRow(rowData)) {
+                const cellData = {
+                    [slColMap.code]: { value: rowData[slColMap.code] && rowData[slColMap.code].value || null },
+                    [slColMap.name]: { value: rowData[slColMap.name] && rowData[slColMap.name].value || null },
+                    [slColMap.unit]: { value: rowData[slColMap.unit] && rowData[slColMap.unit].value || null },
+                    [slColMap.quantity]: { value: rowData[slColMap.quantity] && rowData[slColMap.quantity].value || null },
+                };
+                rst.data.dataTable.push(cellData);
+            }
+        }
+        rst.rowCount = rst.data.dataTable.length;
+        return rst;
+    }
+
     //提取清单示例数据
     function extractSLDatas(sheetData) {
-        let colMapping = { code: 0, name: 1, unit: 2, quantity: 3 };
         let dataTable = sheetData.data.dataTable,
             rowCount = sheetData.rowCount;
         let rst = [];
         let curRoot = null;
         for (let row = 0; row < rowCount; row++) {
-            let code = dataTable[row][colMapping.code] && dataTable[row][colMapping.code].value ? String(dataTable[row][colMapping.code].value).trim() : null,
-                name = dataTable[row][colMapping.name] ? _deNR(dataTable[row][colMapping.name].value) : null,
-                unit = dataTable[row][colMapping.unit] ? dataTable[row][colMapping.unit].value : null,
-                quantity = dataTable[row][colMapping.quantity] ? dataTable[row][colMapping.quantity].value : null;
+            let code = dataTable[row][slColMap.code] && dataTable[row][slColMap.code].value ? String(dataTable[row][slColMap.code].value).trim() : null,
+                name = dataTable[row][slColMap.name] ? _deNR(dataTable[row][slColMap.name].value) : null,
+                unit = dataTable[row][slColMap.unit] ? dataTable[row][slColMap.unit].value : null,
+                quantity = dataTable[row][slColMap.quantity] ? dataTable[row][slColMap.quantity].value : null;
             if (!code) {    //没有编号的数据,名称必须为:清单 第xx章,认为新的表根节点
                 const reg = /清单\s+第[^章]+章/;
                 //if (name && /清单 第\d+章/.test(name)) {
@@ -243,7 +310,15 @@ const importBills = (function () {
             }
             curSheetType = sheetType;
             let colMapping = getColMapping(sheetType);
-            let datas = sheetType === fileType.gcl ? extractGCLDatas(sheetData, colMapping) : extractSLDatas(sheetData, colMapping);
+            let datas = [];
+            if (sheetType === fileType.gcl) {
+                datas = extractGCLDatas(sheetData, colMapping);
+            } else if (sheetType === fileType.qdsl) {
+                datas = extractSLDatas(sheetData, colMapping);
+            } else {
+                const slSheetData = transformGCLExToSL(sheetData);
+                datas = extractSLDatas(slSheetData, colMapping);
+            }
             rst = rst.concat(datas);
         }
         //编号去除空格 清除多余数据 设置数据