| 
					
				 | 
			
			
				@@ -17,6 +17,8 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         arrayValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         getFee, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         mergeFees, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assignAttr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeDataRecur, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         getFlag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         getBool, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         getItemsRecur, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -35,6 +37,7 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         '5': 3, // 控制价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         'control': 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 一些数据是需要从后端获取自增数字后赋值的,这里是记录,用完会在extractProject清空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const countData = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         projectCount: 0,    //项目数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         projectGLJCount: 0,  //项目人材机数量 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -42,7 +45,17 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unitPriceCount: 0,   //单价数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unitPriceFileCount: 0,  //单价文件数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 精度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Decimal = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 工料机消耗量、含量、用量类小数精度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        GLJ: 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 工程量、数量类小数精度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QUANTITY: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 金额、合价、费用类小数精度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FEE: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 费率、指数、比例(%)类小数精度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RATE: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /*  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 从导入的xml文件中提取有用的数据 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -57,7 +70,7 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const projectSrc = getValue(projectXMLObj, ['ConstructionProject']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         importFileKind = FileKind[getValue(projectSrc, ['_FileKind'])]; // 标记当前导入的文件类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const rst = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            projectType: projectType.Project, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            projType: projectType.Project, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: getValue(projectSrc, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             engs: extractEngs(projectSrc, xmlObjMap), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             property: { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -280,13 +293,16 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             jobContent: getJobContent(workElementSrc), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             unit: getValue(workElementSrc, ['_Unit']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             quantity: getValue(workElementSrc, ['_Quantity']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            calcBase: getValue(workElementSrc, ['_QtyFormula']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: getValue(workElementSrc, ['_Rate']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             mainBills: getBool(getValue(workElementSrc, ['_Major'])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeCode: getValue(workElementSrc, ['_Code']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             remark: getValue(workElementSrc, ['_Remark']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             rations: extractRations(workElementSrc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (type === billType.BILL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 分项不需要基数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills.calcBase = getValue(workElementSrc, ['_QtyFormula']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 投标和控制价,需要导入最高限价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if ([FileKind.tender, FileKind.control].includes(importFileKind)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const maxPrice = getValue(workElementSrc, ['_PriceHigh']); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -469,11 +485,17 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const sundryCosts = getValue(sundry, ['SundryCosts']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 其他项目汇总费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const sundryFees = [{ fieldName: 'common', totalFee: getValue(sundryCosts, ['_Total']) }]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        debugger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const provisionalMaterialEquipment = getValue(sundry, ['ProvisionalMaterialEquipment']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fees: importFileKind === FileKind.tender ? sundryFees : [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             sundryCosts: extractData(sundry, 'SundryCosts', [['SundryCostsGroup'], ['SundryCostsItem']]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             provisional: extractData(sundry, 'ProvisionalSums', [['ProvisionalSumsGroup'], ['ProvisionalSumsItem']]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ProvisionalMaterialEquipment: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name: getValue(provisionalMaterialEquipment, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                feeCode: getValue(provisionalMaterialEquipment, ['_Code']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                remark: getValue(provisionalMaterialEquipment, ['_Remark']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                fees: [{ fieldName: 'common', totalFee: getValue(provisionalMaterialEquipment, ['_Total']) }], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             specialty: extractData(sundry, 'SpecialtyProvisionalPrice', [['SpecialtyProvisionalPriceGroup'], ['SpecialtyProvisionalPriceItem']], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { engineeringContent: ['_Content'] }, { engineeringContent: ['_Content'] }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dayWork: extractData(sundry, 'DayWorkRate', [['DayWorkRateGroup'], ['DayWorkRateItem']]), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -505,25 +527,28 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 提取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         function extractData(sundry, srcName, fields, groupExtendMap, itemExtendMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const src = getValue(sundry, [srcName]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return extractItemsRecur(src, fields, (itemSrc, curField) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const groupExtend = groupExtendMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ? Object.keys(groupExtendMap).reduce((acc, key) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        acc[key] = getValue(itemSrc, groupExtendMap[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }, {}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const itemExtend = itemExtendMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ? Object.keys(itemExtendMap).reduce((acc, key) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        acc[key] = getValue(itemSrc, itemExtendMap[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }, {}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return curField[0] === fields[0][0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ? extractGroupOrItem(itemSrc, true, groupExtend) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    : extractGroupOrItem(itemSrc, false, itemExtend); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                fees: importFileKind === FileKind.tender ? [{ fieldName: 'common', totalFee: getValue(src, ['_Total']) }] : [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                feeCode: getValue(src, ['_Code']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                items: extractItemsRecur(src, fields, (itemSrc, curField) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const groupExtend = groupExtendMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ? Object.keys(groupExtendMap).reduce((acc, key) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            acc[key] = getValue(itemSrc, groupExtendMap[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }, {}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const itemExtend = itemExtendMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ? Object.keys(itemExtendMap).reduce((acc, key) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            acc[key] = getValue(itemSrc, itemExtendMap[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }, {}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return curField[0] === fields[0][0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ? extractGroupOrItem(itemSrc, true, groupExtend) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        : extractGroupOrItem(itemSrc, false, itemExtend); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO 材料设备暂估价明细 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 提取税金 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function extractTax(tenderSrc) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -547,9 +572,9 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 供料方式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const Provider = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        '1': [commonConstants.supplyType.ZXCG], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        '2': [commonConstants.supplyType.BFJG], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        '3': [commonConstants.supplyType.WQJG] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        '1': commonConstants.supplyType.ZXCG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        '2': commonConstants.supplyType.BFJG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        '3': commonConstants.supplyType.WQJG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 提取人材机汇总相关(人材机汇总表、承包材料表) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -562,8 +587,14 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const gljListSrc = arrayValue(tenderSrc, ['LabourMaterialsEquipmentsMachinesSummary']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return gljListSrc.reduce((acc, gljSrc) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             acc.gljSummary.push(extractGLJ(gljSrc)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            acc.differentiaSummary.push(extractDifferentiaGLJ(gljSrc)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            acc.exponentialSummary.push(extractExponentialGLJ(gljSrc)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const differentiaGLJ = extractDifferentiaGLJ(gljSrc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (differentiaGLJ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                acc.differentiaSummary.push(differentiaGLJ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const exponentialGLJ = extractExponentialGLJ(gljSrc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (exponentialGLJ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                acc.exponentialSummary.push(exponentialGLJ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }, initData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -638,29 +669,42 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 提取造价信息差额调整法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         function extractDifferentiaGLJ(gljSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                code: getValue(gljSrc, ['_Number']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                name: getValue(gljSrc, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                specs: getValue(gljSrc, ['_Specification']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                unit: getValue(gljSrc, ['_Unit']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                quantity: getValue(gljSrc, ['_Quantity']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                riskCoe: getValue(gljSrc, ['_ProviderExp']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                standardPrice: getValue(gljSrc, ['_ProviderBase']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                market_price: getPriceByTaxType(gljSrc, taxType).market_price, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                remark: getValue(gljSrc, ['_Remark']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 风险系数或者基准单价有值,才算一条差额数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const riskCoe = getValue(gljSrc, ['_ProviderExp']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const standardPrice = getValue(gljSrc, ['_ProviderBase']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if ((riskCoe && riskCoe !== '0') || (standardPrice && standardPrice !== '0')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    code: getValue(gljSrc, ['_Number']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    name: getValue(gljSrc, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    specs: getValue(gljSrc, ['_Specification']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    unit: getValue(gljSrc, ['_Unit']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    quantity: getValue(gljSrc, ['_Quantity']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    riskCoe, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    standardPrice, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    market_price: getPriceByTaxType(gljSrc, taxType).market_price, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    remark: getValue(gljSrc, ['_Remark']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 提取价格指数调整法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         function extractExponentialGLJ(gljSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                code: getValue(gljSrc, ['_Number']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                name: getValue(gljSrc, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                specs: getValue(gljSrc, ['_Specification']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                varWeight: getValue(gljSrc, ['_Weight']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                FO: getValue(gljSrc, ['_BasicPrice']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                FI: getValue(gljSrc, ['_CurrentPrice']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                remark: getValue(gljSrc, ['_Remark']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 变值权重或基本、现行价格指数有值,才算一条指数数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const varWeight = getValue(gljSrc, ['_Weight']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const FO = getValue(gljSrc, ['_BasicPrice']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const FI = getValue(gljSrc, ['_CurrentPrice']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if ((varWeight && varWeight !== '0') || (FO && FO !== '0') || (FI && FI !== '0')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    code: getValue(gljSrc, ['_Number']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    name: getValue(gljSrc, ['_Name']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    specs: getValue(gljSrc, ['_Specification']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    varWeight: varWeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    FO: FO, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    FI: FI, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    remark: getValue(gljSrc, ['_Remark']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 提取评标材料 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -669,7 +713,7 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const srcList = arrayValue(tenderSrc, ['BidEvaluationMainMaterial']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return srcList.map(src => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return srcList.map(gljSrc => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             seq: getValue(gljSrc, ['_Code']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: getValue(gljSrc, ['_Number']), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: getValue(gljSrc, ['_Name']), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -747,22 +791,33 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     preTender.tender.NextSiblingID = curTender.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // 项目清单模板(后台清单模板中提取含有固定类别的数据) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const projectBills = _.cloneDeep(templateMapping[curTender.property.templateLibID]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                debugger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const billsTemplate = _.cloneDeep(templateMapping[curTender.property.templateLibID]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // 重设模板树结构数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                BILLS_UTIL.resetTreeData(projectBills, uuid.v1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                console.log(projectBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const tenderData = transformTender(curTender, IDPlaceholder, projectBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BILLS_UTIL.resetTreeData(billsTemplate, uuid.v1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                console.log(billsTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const tenderData = transformTender(curTender, IDPlaceholder, billsTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 tenderData.tender.property.rootProjectID = transformedData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 engData.tenders.push(tenderData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(`transformedData`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(transformedData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return transformedData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 获取承包人材料类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function getAdjustType(tenderData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (tenderData.differentiaSummary.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return AdjustType.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (tenderData.exponentialSummary.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return AdjustType.coe; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return AdjustType.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 获取当前文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 转换单位工程的数据(直接可插入数据库的数据),返回{tender: {}, bills: [], ration: [], rationGLJ: [], projectGLJ: [], unitPrice: [], mixRatio: []} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    function transformTender(tenderData, IDPlaceholder, projectBills) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const detailData = transformDetail(tenderData, IDPlaceholder, projectBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformTender(tenderData, IDPlaceholder, billsTemplate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const detailData = transformDetail(tenderData, IDPlaceholder, billsTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 提取需要插入的单位工程数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const transformedTender = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ID: tenderData.ID, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -779,20 +834,554 @@ const importXML = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             gljLibIDs: tenderData.gljLibIDs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             shareInfo: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        transformedTender.property.gljAdjustType = AdjustType.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformedTender.property.gljAdjustType = getAdjustType(tenderData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         detailData.tender = transformedTender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return detailData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 转换清单 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    function transformBills(tenderData, IDPlaceholder, projectBills) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 过滤掉相关费用代号的数据(递归地) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 返回被过滤掉的数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function filterDataByFeeCodes(billsData, feeCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const filterd = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        billsData.forEach(bills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (bills.items && bills.items.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const newItems = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.items.forEach(subBills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!feeCodes.includes(subBills.feeCode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        newItems.push(subBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        filterd.push(subBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.items = newItems; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // bills.items = bills.items.filter(subBills => !feeCodes.includes(subBills.feeCode)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const subFilterd = filterDataByFeeCodes(bills.items, feeCodes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filterd.push(...subFilterd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return filterd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 转换详细的项目数据,清单、定额、定额人材机、项目人材机、单价文件等 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    function transformDetail() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 合并清单,将提取出来的清单相关数据,合并进项目清单(模板) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function mergeBills(tenderData, billsTemplate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        debugger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const mergedBills = [...billsTemplate]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const roots = billsTemplate.filter(bills => bills.ParentID === -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let lastRoot = roots.find(root => root.NextSiblingID === -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeWorkSummary(tenderData.workSummary); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeFBFX(tenderData.fbfx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeCSXM(tenderData.csxm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeOther(tenderData.other); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mergeTax(tenderData.tax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return mergedBills; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并清单数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeitems(fixedBills, items) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const daryWorkMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                '人工': fixedFlag.LABOUR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                '材料': fixedFlag.MATERIAL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                '机械': fixedFlag.MACHINE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                '施工机械': fixedFlag.MACHINE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                '施工机具': fixedFlag.MACHINE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const fixedBillsFlag = getFlag(fixedBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let preBills = billsTemplate.find(bills => bills.ParentID === fixedBills.ID && bills.NextSiblingID === -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            items.forEach(bills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 计日工需要特殊处理,兼容广联达的数据,广联达的计日工下的人工、材料、机械的费用字典不对,因此用名称匹配 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let matched; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (fixedBillsFlag === fixedFlag.DAYWORK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const dayWorkSubFlag = daryWorkMap[bills.name]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    matched = dayWorkSubFlag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ? billsTemplate.find(templateBills => getFlag(templateBills) === dayWorkSubFlag) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    matched = billsTemplate.find(templateBills => FlagFeeCodeMap[getFlag(templateBills)] === bills.feeCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (matched) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    assignAttr(matched, bills, ['items'], true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (bills.items && bills.items.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        mergeitems(matched, bills.items); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //mergedBills.push(...mergeDataRecur(fixedBills, [bills]))     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    preBills = matched; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const nextID = preBills && preBills.NextSiblingID || -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mergedBills.push(...mergeDataRecur(fixedBills, [bills])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    bills.NextSiblingID = nextID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (preBills) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        preBills.NextSiblingID = bills.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    preBills = bills; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 简单地合并: 设置某清单的金额,数据递归插入到某清单的子项 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function simpleMerge(flag, src) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const fixedBills = billsTemplate.find(bills => getFlag(bills) === flag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (fixedBills) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                assignAttr(fixedBills, src, ['fees', 'feeCode']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mergedBills.push(...mergeDataRecur(fixedBills, src.items)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并大项费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeWorkSummary(workSummary) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 首层数据与清单模板根据费用字典进行匹配,匹配到的则赋值一些属性,匹配不到则将其及其所有子数据插入到模板最末大项费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            workSummary.forEach(summaryBills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const matched = roots.find(root => FlagFeeCodeMap[getFlag(root)] === summaryBills.feeCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (matched) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!summaryBills.calcBase) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        summaryBills.calcBase = matched.calcBase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        matched.ignoreValidator = true; // 用了模板的基数,基数无视基数验证 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    assignAttr(matched, summaryBills, ['items'], true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mergedBills.push(...mergeDataRecur(null, [summaryBills])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (lastRoot) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        lastRoot.NextSiblingID = summaryBills.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        lastRoot = summaryBills; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并分部分项 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeFBFX(fbfxSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.SUB_ENGINERRING, fbfxSrc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并措施项目 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeCSXM(csxmSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const fixedBills = billsTemplate.find(bills => getFlag(bills) === fixedFlag.MEASURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fixedBills.fees = csxmSrc.fees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mergeitems(fixedBills, csxmSrc.items); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并其他项目 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeOther(otherSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const fixedBills = billsTemplate.find(bills => getFlag(bills) === fixedFlag.OTHER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fixedBills.fees = otherSrc.fees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并其他项目费 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // SundryCosts其他项目费会包含暂列金额等后续会再次出现的数据,因此合并SundryCosts的数据时,过滤掉一部分数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const feeCodeFilter = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.PROVISIONAL], // 暂列金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.MATERIAL_PROVISIONAL], // 材料暂估 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.ENGINEERING_ESITIMATE], // 专业工程暂估 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.DAYWORK], // 计日工 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.TURN_KEY_CONTRACT], // 总承包服务费 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.CLAIM], // 索赔 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlagFeeCodeMap[fixedFlag.VISA], // 现场签证 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const filterdBills = filterDataByFeeCodes([otherSrc.sundryCosts], feeCodeFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             * 有些源xml文件中,被过滤掉SundryCosts中的子项,相对于Sundry的子项会多一些属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             * 比如:Sundry->SunryCosts->SundryCostsGroup->SundryCostsItem中的材料暂估价,含有QtyFormula属性,但是Sundry->ProvisionalMaterialEquipment中不含有QtyFormula 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             * 因此,即使后续Sundry的子项会赋值给模板,也要将被过滤掉的子项的属性先赋给模板 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            filterdBills.forEach(filterdItem => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const matched = billsTemplate.find(templateBills => FlagFeeCodeMap[getFlag(templateBills)] === filterdItem.feeCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (matched) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    assignAttr(matched, filterdItem, ['items'], true); // 不拷贝item属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    matched.ignoreA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const sundryCostsBills = otherSrc.sundryCosts.items; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mergeitems(fixedBills, sundryCostsBills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并暂列金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.PROVISIONAL, otherSrc.provisional); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并材料暂估,由于材料暂估的子元素是暂估人材机,因此对清单来说,只需处理材料暂估根元素的属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const zgcFixedBills = billsTemplate.find(bills => getFlag(bills) === fixedFlag.MATERIAL_PROVISIONAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assignAttr(zgcFixedBills, otherSrc.ProvisionalMaterialEquipment); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并专业工程暂估价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.ENGINEERING_ESITIMATE, otherSrc.specialty); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并计日工 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const dayWorkFixedBills = billsTemplate.find(bills => getFlag(bills) === fixedFlag.DAYWORK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assignAttr(dayWorkFixedBills, otherSrc.dayWork, ['fees', 'feeCode']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mergeitems(dayWorkFixedBills, otherSrc.dayWork.items); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并总承包服务费 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.TURN_KEY_CONTRACT, otherSrc.mainContractor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并索赔 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.CLAIM, otherSrc.claim); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 合并现场签证 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            simpleMerge(fixedFlag.VISA, otherSrc.visa); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并税金 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function mergeTax(taxSrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const taxFixedBills = billsTemplate.find(bills => getFlag(bills) === fixedFlag.TAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!taxSrc.calcBase) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                taxSrc.calcBase = taxFixedBills.calcBase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                taxFixedBills.ignoreValidator = true; // 用了模板的基数,基数无视基数验证 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                taxFixedBills.ignoreValidator = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assignAttr(taxFixedBills, taxSrc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 给固定清单设置上费用字典,因为在合并清单的时候,清单模板中可能有一些数据应该有规定的费用字典,但是没有被设置上费用字典。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function setupFeeCode(billsData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        billsData.forEach(bills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (bills.feeCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills.feeCode = FlagFeeCodeMap[getFlag(bills)] || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 检查清单是否引用了自身,比如广联达导出文件中 材料保管费基数为CLBGF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function isCalcBaseCycle(bills) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return bills.calcBase.match(new RegExp(`\\b${bills.feeCode}\\b`)); // \b: 匹配前一个字符和后一个字符不全为\w的位置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 转换计算基数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 1.有子项数据,则清空基数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 2.引用的基数造成自身循环,比如分部分项部分引用了QDF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 3.费用代号匹配清单基数的代号 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 4.费用代号匹配不到清单基数的代号,则匹配此费用代号的清单,作为行引用(即ID引用) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 5.对应字典里找不到则设置成金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformCalcBase(billsData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 费用代号 - 计算基数映射 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const feeCodeFormulaMap = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .entries(FormulaFeeCodeMap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .forEach(([formula, feeCode]) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                feeCodeFormulaMap[feeCode] = formula; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 费用代号 - ID映射 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const feeCodeIDMap = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        billsData.forEach(data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (data.feeCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                feeCodeIDMap[data.feeCode] = data.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (const bills of billsData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!bills.calcBase || bills.ignoreValidator) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const sub = billsData.find(data => data.ParentID === bills.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 有子项数据,则清空基数,费率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (sub) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.calcBase = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.feeRate = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (typeof bills.calcBase !== 'string') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.calcBase = String(bills.calcBase); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 引用的基数造成自循环,清空基数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const isCycle = isCalcBaseCycle(bills); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (isCycle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.calcBase = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 提取基数中的费用代号 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills.calcBase = bills.calcBase.replace(/\s/g, ''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const feeCodes = bills.calcBase.split(/[\+\-\*\/]/g); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 提取操作符 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const oprs = bills.calcBase.match(/[\+\-\*\/]/g); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 转换后的基数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const newBase = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let illegal = false;    //不合法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (const feeCode of feeCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const formula = feeCodeFormulaMap[feeCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const refID = feeCodeIDMap[feeCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (formula) { // 匹配到公式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newBase.push(formula); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (refID) { // 匹配到行引用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newBase.push(`@${refID}`) // 转换成ID引用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { // 无法识别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    illegal = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (illegal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const fee = getFee(bills.fees, ['common', 'totalFee']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const feeRate = bills.feeRate && parseFloat(bills.feeRate) !== 0 ? parseFloat(bills.feeRate) : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (fee && parseFloat(fee) !== 0 && feeRate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    bills.calcBase = scMathUtil.roundForObj(parseFloat(fee) * 100 / feeRate, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    bills.calcBase = fee !== '0' ? fee : ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let newCalcBase = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (let i = 0; i < newBase.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newCalcBase += newBase[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (oprs && oprs[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        newCalcBase += oprs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.calcBase = newCalcBase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 转换清单 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformBills(tenderData, billsTemplate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const billsData = mergeBills(tenderData, billsTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        setupFeeCode(billsData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformCalcBase(billsData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 处理综合单价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 没有子清单,且没有综合单价,且有综合合价,则综合单价 = 综合合价 / 工程量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        billsData.forEach(bills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const hasChild = billsData.some(data => data.ParentID === bills.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let unitFee = getFee(bills.fees, ['common', 'unitFee']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const totalFee = getFee(bills.fees, ['common', 'totalFee']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!hasChild && !parseFloat(unitFee) && totalFee && parseFloat(totalFee)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 不存工程量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!bills.quantity || !parseFloat(bills.quantity)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    unitFee = totalFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // 源不存在工程量,没有计算基数、但是却有综合合价,工程量要设置为1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!bills.calcBase) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        bills.quantity = '1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // 综合合价的小数位数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const totalFeeDecimal = totalFee.match(/\.\d+/); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    unitFee = scMathUtil.roundForObj(totalFee / bills.quantity, totalFeeDecimal ? totalFeeDecimal[0] : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const commonFee = bills.fees.find(fee => fee.fieldName === 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (commonFee) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    commonFee.unitFee = unitFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills.projectID = tenderData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills.quantityEXP = bills.quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // TODO 删除items rations feeCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return billsData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 转换人材机汇总相关数据(人材机汇总、承包人材料、评标材料、暂估价材料、组成物、单价文件) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformGLJList(tenderData, IDPlaceholder, projectGLJMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const rst = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            projectGLJ: [], // 项目人材机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            contractorList: [], // 承包人材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bidEvaluationList: [], // 评标材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            evaluationList: [], // 暂估材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            unitPrice: [], // 单价文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mixRatio: [] // 组成物 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformGLJSummary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformContractorSummary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformRelatedGLJList(tenderData.bidEvaluationSummary, rst.bidEvaluationList, 'is_eval_material'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transformEvalSummary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换项目人材机、组成物 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function transformGLJSummary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 项目人材机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tenderData.gljSummary.forEach(projectGLJ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectGLJ.project_id = tenderData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectGLJ.id = IDPlaceholder.projectGLJ++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectGLJMap[projectGLJ.code] = projectGLJ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tenderData.gljSummary.forEach(projectGLJ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //组成物数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectGLJ.ratios.forEach(ratio => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const matched = projectGLJMap[ratio.code]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.code = matched.code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.projectGLJID = projectGLJ.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.id = IDPlaceholder.ratio++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.unit_price_file_id = tenderData.property.unitPriceFile.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.unit = matched && matched.unit || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.name = matched && matched.name || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.specs = matched && matched.specs || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.type = matched && matched.type || 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ratio.connect_key = [projectGLJ.code || 'null', projectGLJ.name || 'null', projectGLJ.specs || 'null', projectGLJ.unit || 'null', projectGLJ.type].join('|-|'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rst.mixRatio.push(ratio); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rst.projectGLJ.push(projectGLJ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 单价文件数据: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rst.unitPrice.push(generateUnitPrice(projectGLJ)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // TODO 删除ratios 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换与项目人材机关联的材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function transformRelatedGLJList(list, container, relatedType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            list.forEach(glj => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glj.ID = uuid.v1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glj.projectID = tenderData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glj.projectGLJID = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (typeof glj.seq === 'undefined') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    glj.seq = glj.code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const projectGLJ = projectGLJMap[glj.code]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (projectGLJ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    projectGLJ[relatedType] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    glj.is_related = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    glj.projectGLJID = projectGLJ.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                container.push(glj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换承包人材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function transformContractorSummary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 由于承包人差额数据和指数数据共用承包人材料表,因此需要合并差额数据和指数数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const mergedList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tenderData.exponentialSummary.forEach(eGLJ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const matched = tenderData.differentiaSummary.find(dGLJ => dGLJ.code === eGLJ.code); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (matched) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    assignAttr(matched, eGLJ, ['varWeight', 'FO', 'FI']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mergedList.push(eGLJ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mergedList.push(...tenderData.differentiaSummary); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            transformRelatedGLJList(mergedList, rst.contractorList, 'is_contractor_material'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换暂估价材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function transformEvalSummary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const evalGLJList = tenderData.gljSummary 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .filter(glj => glj.is_evaluate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .map(glj => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const evalGLJ = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    assignAttr(evalGLJ, glj, [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        'code', 'name', 'specs', 'unit', 'quantity', 'market_price', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        'originPlace', 'vender', 'remark' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    evalGLJ.seq = evalGLJ.code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return evalGLJ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            transformRelatedGLJList(evalGLJList, rst.evaluationList, 'is_evaluate'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成单价文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function generateUnitPrice(projectGLJ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectGLJID: projectGLJ.id,    //做个标记,后端查找标准数据后,方便更新组成物数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                unit_price_file_id: tenderData.property.unitPriceFile.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                id: IDPlaceholder.unitPrice++, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                code: projectGLJ.code, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                original_code: projectGLJ.original_code, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name: projectGLJ.name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                unit: projectGLJ.unit, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                specs: projectGLJ.specs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: projectGLJ.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                short_name: projectGLJ.shortName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                base_price: projectGLJ.base_price, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                market_price: projectGLJ.market_price 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 转换定额、定额人材机、定额系数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // @param {Object} tenderData - 提取的单位工程数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // @param {Array} billsData - 转换后的清单数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // @param {Object} projectGLJMap - 转换项目人材机时生成的项目人材机编码-数据的映射 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformRations(tenderData, billsData, projectGLJMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const rst = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ration: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rationGLJ: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rationCoe: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        billsData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .filter(bills => bills.rations && bills.rations.length) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .forEach(bills => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bills.rations.forEach(ration => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // TODO 取费专业不知如何取,暂时取单位工程取费专业 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ration.programID = tenderData.property.projectEngineering; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ration.ID = uuid.v1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ration.projectID = tenderData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ration.billsItemID = bills.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ration.contain = getContain(bills, ration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rst.ration.push(ration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // 定额人材机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rst.rationGLJ.push(...transformRationGLJs(bills, ration)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // 定额系数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rst.rationCoe.push(generateRationCoe(ration)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // TODO 删除rationGljs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 含量:定额工程量/清单工程量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function getContain(bills, ration) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!bills.quantity || !ration.quantity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return '0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const tempQuantity = ration.quantity / bills.quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return isFinite(tempQuantity) ? scMathUtil.roundForObj(tempQuantity, Decimal.QUANTITY) : '0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换定额人材机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function transformRationGLJs(bills, ration) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ration.rationGLJs.map(rationGLJ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const matched = projectGLJMap[rationGLJ.code]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (matched) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.projectGLJID = matched.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.code = matched.code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.type = matched.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.shortName = matched.shortName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.name = matched.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.original_code = matched.original_code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.unit = matched.unit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    rationGLJ.specs = matched.specs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.ID = uuid.v1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.projectID = tenderData.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.billsItemID = bills.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.rationID = ration.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.rationCode = ration.code;  // 暂时跟定额编码关联,后端好匹配标准数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationGLJ.rationItemQuantity = rationGLJ.quantity;  // 定额消耗,暂时取消耗量,需要后端匹配标准数据后更新 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return rationGLJ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成定额系数(项目数据处理的方法很有可能无法共用,因此不把重庆的方法抽离了) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function generateRationCoe(ration) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                projectID: ration.projectID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rationID: ration.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                coeID: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ID: uuid.v1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                seq: 1, // 以前排序有的字段,暂时没什么用,不过还是赋上一个值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name: '自定义系数', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                content: '人工×1,材料×1,机械×1,主材×1,设备×1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                coes: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '定额' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '人工' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '材料' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '机械' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '主材' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { amount: 1, operator: '*', gljCode: null, coeType: '设备' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                option_list: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 删除一些无用属性,减少通信数据量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function clean(detailData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ration, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            projectGLJ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } = detailData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bills.forEach(item => delete item.items && delete item.rations && delete item.feeCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ration.forEach(item => delete item.rationGLJs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        projectGLJ.forEach(item => delete item.ratios); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 需要给清单、定额价格字段赋上调价数据,不然打开项目后会被重算: project_view.js -> loadProjectData方法内 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function setupTenderFees(detailData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const { bills, ration } = detailData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        [...bills, ...ration].forEach(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (item.fees && item.fees.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                item.fees.forEach(feeItem => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (commonUtil.isDef(feeItem.unitFee)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        feeItem.tenderUnitFee = feeItem.unitFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (commonUtil.isDef(feeItem.totalFee)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        feeItem.tenderTotalFee = feeItem.totalFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 转换详细的项目数据,清单、定额、定额人材机、项目人材机、单价文件等 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function transformDetail(tenderData, IDPlaceholder, billsTemplate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const bills = transformBills(tenderData, billsTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换定额的处理依赖转换后的项目人材机数据,因此需要先转换项目人材机相关的数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const projectGLJMap = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const relatedljGLJData = transformGLJList(tenderData, IDPlaceholder, projectGLJMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const relatedRationData = transformRations(tenderData, bills, projectGLJMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const detailData = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bills, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ...relatedRationData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ...relatedljGLJData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clean(detailData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        setupTenderFees(detailData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(`detailData`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(detailData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return detailData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 解压cos、zip文件 
			 |