| 
					
				 | 
			
			
				@@ -711,7 +711,7 @@ function transfromGeneralData(period, compilationID, generalData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ID: uuidV1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         name: `${area}信息价(${period})`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         period, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        area, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        areas: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         compilationID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         createDate: Date.now(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -735,16 +735,24 @@ function transfromGeneralData(period, compilationID, generalData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 绿色节能分类数据:绿色、节能建筑工程材料 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const energyData = [{ materialClass: '绿色、节能建筑工程材料', items: energy }]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     handleClassAndItems(energyData, TableType.ENERGY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { libData: [libData], classData, priceData }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 有数据才将地区push入areas中,必须返回非空的libData,后续转换地区数据需要这个libData(一期只生成一个库) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (classData.length || priceData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        libData.areas.push(area); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { libData, classData, priceData }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function handleClassAndItems(sourceData, tableType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!sourceData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sourceData.forEach(({ materialClass, treeData, items }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const classItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ID: treeData && treeData.ID || uuidV1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ParentID: treeData && treeData.ParentID || '-1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 NextSiblingID: treeData && treeData.NextSiblingID || '-1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 name: materialClass, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                libID: libData.ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                libID: libData.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                area, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 设置上一个节点数据的NextID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let count = 1; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -769,14 +777,16 @@ function transfromGeneralData(period, compilationID, generalData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * 转换跟地区相关的数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 地区作为期数库的子项 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {String} period - 日期: 2020年01月 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {String} compilationID - 费用定额ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {String} className - 分类名称  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param {Object} libData - 当前期数库数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {Array<object>} areaData - 各区县地方材料工地价格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {Array<object>} mixedData - 预拌砂浆信息价格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function transformAreaData(period, compilationID, areaData, mixedData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 根据地区进行分类,一个地区一个信息价库 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function transformAreaData(period, compilationID, libData, areaData, mixedData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 根据地区进行分类 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const data = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const hashMap = {}; // 保证地区顺序跟网页爬取数据的顺序一致。(object for in无法保证顺序) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function hash(area) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -810,19 +820,10 @@ function transformAreaData(period, compilationID, areaData, mixedData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     buildData(areaData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     buildData(mixedData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const libData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const classData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const priceData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     data.forEach(({ area, subData }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const libItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ID: uuidV1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            name: `${area}信息价(${period})`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            period, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            area, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            compilationID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            createDate: Date.now(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        libData.push(libItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        libData.areas.push(area); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let preClass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         subData.forEach(subItem => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (!subItem) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -834,18 +835,19 @@ function transformAreaData(period, compilationID, areaData, mixedData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ParentID: '-1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 NextSiblingID: '-1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 name: className, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                libID: libItem.ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                libID: libData.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                area, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             classData.push(classItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (preClass) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 preClass.NextSiblingID = classItem.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             preClass = classItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const newItems = transformPriceItems(libItem.ID, classItem.ID, period, area, compilationID, items, TableType.AREA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const newItems = transformPriceItems(libData.ID, classItem.ID, period, area, compilationID, items, TableType.AREA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             newItems.forEach(item => priceData.push(item)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { libData, classData, priceData }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { classData, priceData }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -865,19 +867,32 @@ async function save(period, generalData, areaData, mixedData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const compilationID = compilation._id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 转换数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const generalSaveData = transfromGeneralData(period, compilationID, generalData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const areaSaveData = transformAreaData(period, compilationID, areaData, mixedData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const libData = generalSaveData.libData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const areaSaveData = transformAreaData(period, compilationID, libData, areaData, mixedData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 入库 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const libData = [...generalSaveData.libData, ...areaSaveData.libData]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const classData = [...generalSaveData.classData, ...areaSaveData.classData]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const priceData = [...generalSaveData.priceData, ...areaSaveData.priceData]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 删除已有的相同期数数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoItemModel.deleteMany({ period }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoClassModel.deleteMany({ period }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoLibModel.deleteMany({ period }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const originalLibs = await priceInfoLibModel.find({ period }, '-_id ID').lean(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const originalLibIDList = originalLibs.reduce((acc, cur) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        acc.push(cur.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return acc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (originalLibIDList.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoItemModel.deleteMany({ period }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoClassModel.deleteMany({ libID: { $in: originalLibIDList } }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoLibModel.deleteMany({ period }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 插入数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoItemModel.insertMany(priceData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoClassModel.insertMany(classData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await priceInfoLibModel.insertMany(libData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (priceData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoItemModel.insertMany(priceData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (classData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoClassModel.insertMany(classData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (libData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await priceInfoLibModel.insertMany([libData]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 |