| 
					
				 | 
			
			
				@@ -137,18 +137,18 @@ const TIME_OUT = 60000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const axiosInstance = axios.create({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   baseURL: 'http://www.cqsgczjxx.org/', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   timeout: TIME_OUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/*   proxy: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    host: "127.0.0.1", port: "8888" // Fiddler抓包,需要打开Fiddler否则会报connect error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }, */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /*   proxy: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      host: "127.0.0.1", port: "8888" // Fiddler抓包,需要打开Fiddler否则会报connect error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   headers: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'Cache-Control': 'max-age=0', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'Accept': 'application/json, text/javascript, */*; q=0.01', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'X-Requested-With': 'XMLHttpRequest', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'Accept-Encoding': 'gzip, deflate', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 'Cookie': 'ASP.NET_SessionId=uozdrp0hep5x344vq153muju' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'Cache-Control': 'max-age=0', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'Accept': 'application/json, text/javascript, */*; q=0.01', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'X-Requested-With': 'XMLHttpRequest', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'Accept-Encoding': 'gzip, deflate', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 'Cookie': 'ASP.NET_SessionId=uozdrp0hep5x344vq153muju' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // responseType: 'json' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -159,9 +159,9 @@ axiosInstance.interceptors.response.use(function (response) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // 对响应错误做点什么 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (error.message.includes('timeout')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return Promise.reject(`目标网络超时,请稍后再试。(${TIME_OUT}ms)`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return Promise.reject(`目标网络超时,请稍后再试。(${TIME_OUT}ms)`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return Promise.reject(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return Promise.reject(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -191,12 +191,12 @@ function month2quarter(period) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function setTimeoutSync(handle, time) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (handle && typeof handle === 'function') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              handle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }, time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (handle && typeof handle === 'function') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -245,7 +245,7 @@ async function queryPrice(period, area, groupType, classify) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     option: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     token: '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const res =  await post('/QueryInfoPrice', body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const res = await post('/QueryInfoPrice', body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return res && res.data && res.data.Data && res.data.Data._Items || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -256,7 +256,7 @@ async function queryArea(period, groupType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     period: period.replace('-', ''), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     token: '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const res =  await post('/QueryArea', body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const res = await post('/QueryArea', body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const areaData = res && res.data && res.data.Data && res.data.Data._Items || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return areaData.map(item => item.Area); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -313,7 +313,7 @@ async function crawlBetonMaterial(period) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const rst = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (const area of areas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const priceItems = await queryPrice(period, area, groupType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const item = { area, data: [ { classify: '预拌商品砂浆', priceItems }] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const item = { area, data: [{ classify: '预拌商品砂浆', priceItems }] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     rst.push(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return rst; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -351,49 +351,49 @@ async function crawlGardenMateiral(period) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const unit = 'CM'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const duplicateReg = /-/; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .entries(groupedData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .forEach(([kind, items]) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const classItem = { classify: kind, priceItems: [], subClass: [] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rootClass.subClass.push(classItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    items.forEach(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 拼接规格型号 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const specsList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (item.Height) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .entries(groupedData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .forEach(([kind, items]) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const classItem = { classify: kind, priceItems: [], subClass: [] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rootClass.subClass.push(classItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      items.forEach(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 拼接规格型号 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const specsList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (item.Height) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           specsList.push(`高度${item.Height}${unit}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (item.TrunkDiameter) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (item.TrunkDiameter) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           specsList.push(`干径${item.TrunkDiameter}${unit}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (item.TopDiameter) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (item.TopDiameter) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           specsList.push(`冠径${item.TopDiameter}${unit}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (item.BranchHeight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (item.BranchHeight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           specsList.push(`分枝高${item.BranchHeight}${unit}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      item.Model = specsList.join(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const isDuplicate = duplicateReg.test(item.TaxPrice) || duplicateReg.test(item.NoTaxPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isDuplicate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 分成最高低价最高价数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const taxPriceList = item.TaxPrice ? item.TaxPrice.split('-') : ['']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const noTaxPriceList = item.NoTaxPrice ? item.NoTaxPrice.split('-') : ['']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const minItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ...item, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          Name: `${item.Name}-最低价`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          TaxPrice: taxPriceList[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          NoTaxPrice: noTaxPriceList[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const maxItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ...item, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          Name: `${item.Name}-最高价`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          TaxPrice: taxPriceList[1] || '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          NoTaxPrice: noTaxPriceList[1] || '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        classItem.priceItems.push(minItem, maxItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        classItem.priceItems.push(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        item.Model = specsList.join(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const isDuplicate = duplicateReg.test(item.TaxPrice) || duplicateReg.test(item.NoTaxPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isDuplicate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 分成最高低价最高价数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const taxPriceList = item.TaxPrice ? item.TaxPrice.split('-') : ['']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const noTaxPriceList = item.NoTaxPrice ? item.NoTaxPrice.split('-') : ['']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const minItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ...item, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Name: `${item.Name}-最低价`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TaxPrice: taxPriceList[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            NoTaxPrice: noTaxPriceList[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const maxItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ...item, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Name: `${item.Name}-最高价`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TaxPrice: taxPriceList[1] || '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            NoTaxPrice: noTaxPriceList[1] || '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          classItem.priceItems.push(minItem, maxItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          classItem.priceItems.push(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -470,7 +470,7 @@ async function crawlGeneralMaterial(period) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function getPeriodData(from, to) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (from > to) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // 根据区间获取期数列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const reg = /(\d+)-(\d+)/; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -496,15 +496,15 @@ function getPeriodData(from, to) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     '10': '10月', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     '11': '11月', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     '12': '12月', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   while (curYear <= toYear && curMonth <= toMonth) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      list.push(`${curYear}年-${monthMap[curMonth]}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (curMonth === 12) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          curYear++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          curMonth = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          curMonth++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    list.push(`${curYear}年-${monthMap[curMonth]}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (curMonth === 12) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      curYear++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      curMonth = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      curMonth++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return list; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -514,16 +514,16 @@ async function areaPatch(compilationID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const areaData = await priceInfoAreaModel.find({ compilationID, serialNo: null }).lean(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const bulks = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   areaData.forEach(areaItem => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const serialNo = defaultAreas.indexOf(areaItem.name) + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      bulks.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          updateOne: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              filter: { ID: areaItem.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              update: { serialNo } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const serialNo = defaultAreas.indexOf(areaItem.name) + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bulks.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      updateOne: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filter: { ID: areaItem.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        update: { serialNo } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (bulks.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      await priceInfoAreaModel.bulkWrite(bulks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    await priceInfoAreaModel.bulkWrite(bulks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -550,7 +550,8 @@ async function save(allData, period, compilationID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // 将各部分数据按照地区进行合并 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const areaMap = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   allData.forEach(({ area, data }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (areaMap[area] || (areaMap[area] = [])).push(...data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const areaName = `重庆市-${area}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (areaMap[areaName] || (areaMap[areaName] = [])).push(...data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const libData = { period, compilationID, ID: v1(), name: `信息价(${period})`, createDate: Date.now() }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const curAreas = await priceInfoAreaModel.find({ compilationID }).sort({ serialNo: 1 }).lean(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -590,7 +591,7 @@ async function save(allData, period, compilationID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (areaData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     await priceInfoAreaModel.insertMany(areaData); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -614,35 +615,35 @@ async function save(allData, period, compilationID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 async function crawlData(from, to, compilationID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   let curPeriod; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const periods = getPeriodData(from, to); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!periods || !periods.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          throw '无效的期数区间。'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 地区补丁 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      await areaPatch(compilationID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 一期一期爬取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (const period of periods) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const labourData = await crawlLabour(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const localeData = await crawlLocaleMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const betonData = await crawlBetonMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const generalData = await crawlGeneralMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const allData = [...labourData, ...localeData, ...betonData, ...generalData]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!allData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          throw `${period}无有效数据`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        await save(allData, period, compilationID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        curPeriod = period; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const periods = getPeriodData(from, to); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!periods || !periods.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      throw '无效的期数区间。'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 地区补丁 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    await areaPatch(compilationID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 一期一期爬取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const period of periods) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const labourData = await crawlLabour(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const localeData = await crawlLocaleMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const betonData = await crawlBetonMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const generalData = await crawlGeneralMaterial(period); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const allData = [...labourData, ...localeData, ...betonData, ...generalData]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!allData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw `${period}无有效数据`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      await save(allData, period, compilationID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      curPeriod = period; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 错误时提示已经成功爬取的期数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let errTip = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (curPeriod) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          errTip += `\n成功爬取期数为:${periods[0]}到${curPeriod}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const errStr = String(err) + errTip; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      console.log(`err`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      console.log(errStr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      throw errStr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 错误时提示已经成功爬取的期数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let errTip = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (curPeriod) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      errTip += `\n成功爬取期数为:${periods[0]}到${curPeriod}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const errStr = String(err) + errTip; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log(`err`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log(errStr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    throw errStr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |