Browse Source

feat: 信息价增加地区、重庆地区名称处理

vian 1 năm trước cách đây
mục cha
commit
b0fb2ab803

+ 2 - 2
modules/price_info_lib/facade/index.js

@@ -430,10 +430,10 @@ async function getAreas(compilationID) {
 
 async function updateAres(updateData) {
     const bulks = [];
-    updateData.forEach(({ ID, name }) => bulks.push({
+    updateData.forEach(({ ID, field, value }) => bulks.push({
         updateOne: {
             filter: { ID },
-            update: { name }
+            update: { [field]: value }
         }
     }));
     if (bulks.length) {

+ 1 - 1
web/maintain/price_info_lib/html/edit.html

@@ -24,7 +24,7 @@
 
         </nav>
     </div>
-    <div class="wrapper">
+    <div class="wrapper" style="overflow: hidden;">
         <div class="main">
             <div class="left">
                 <div class="top" id="area-spread"></div>

+ 36 - 20
web/maintain/price_info_lib/js/index.js

@@ -59,7 +59,10 @@ const locked = lockUtil.getLocked();
 const AREA_BOOK = (() => {
     const cache = areaList;
     const setting = {
-        header: [{ headerName: '地区', headerWidth: $('#area-spread').width(), dataCode: 'name', dataType: 'String', hAlign: 'center', vAlign: 'center' }]
+        header: [
+            { headerName: '序号', headerWidth: 60, dataCode: 'serialNo', dataType: 'Number', hAlign: 'center', vAlign: 'center' },
+            { headerName: '地区', headerWidth: $('#area-spread').width() - 80, dataCode: 'name', dataType: 'String', hAlign: 'center', vAlign: 'center' },
+        ]
     };
     // 初始化表格
     const workBook = initSheet($('#area-spread')[0], setting);
@@ -77,22 +80,35 @@ const AREA_BOOK = (() => {
 
     // 编辑处理
     async function handleEdit(changedCells) {
+        debugger;
         const updateData = [];
+        let reSort = false;
         changedCells.forEach(({ row, col }) => {
+            const field = setting.header[col].dataCode;
+            let value = sheet.getValue(row, col);
+            if (field === 'serialNo') {
+                reSort = true;
+                value = +value;
+            }
             updateData.push({
                 row,
+                field,
+                value,
                 ID: cache[row].ID,
-                name: sheet.getValue(row, col)
             });
         });
         try {
             await ajaxPost('/priceInfo/editArea', { updateData }, TIME_OUT);
-            updateData.forEach(({ row, name }) => cache[row].name = name);
+            updateData.forEach(({ row, field, value }) => cache[row][field] = value);
+            if (reSort) {
+                cache.sort((a, b) => a.serialNo - b.serialNo);
+                showData(sheet, cache, setting.header);
+            }
         } catch (err) {
             // 恢复各单元格数据
             sheetCommonObj.renderSheetFunc(sheet, () => {
-                changedCells.forEach(({ row }) => {
-                    sheet.setValue(cache[row].name);
+                changedCells.forEach(({ row, col, field }) => {
+                    sheet.setValue(row, col, cache[row][field]);
                 });
             });
         }
@@ -643,19 +659,19 @@ const CLASS_BOOK = (() => {
 
 
 
-    $calcPriceIndex.click(_.debounce(async()=>{
+    $calcPriceIndex.click(_.debounce(async () => {
         $.bootstrapLoading.start();
         try {
-        const data = await ajaxPost('/priceInfo/calcPriceIndex', { libID, period:curLibPeriod,compilationID }, TIME_OUT);
-          //alert(data);
-          
-          if(data){
-              const htmlStr = data.replace(/\n/gm,'<br>'); //replaceAll('\n','<br>',data);
-              $("#result-info-body").html(htmlStr);
-              $("#result-info").modal('show');
-          }else{
-              alert('计算完成!')
-          }  
+            const data = await ajaxPost('/priceInfo/calcPriceIndex', { libID, period: curLibPeriod, compilationID }, TIME_OUT);
+            //alert(data);
+
+            if (data) {
+                const htmlStr = data.replace(/\n/gm, '<br>'); //replaceAll('\n','<br>',data);
+                $("#result-info-body").html(htmlStr);
+                $("#result-info").modal('show');
+            } else {
+                alert('计算完成!')
+            }
 
 
         } catch (error) {
@@ -698,7 +714,7 @@ const KEYWORD_BOOK = (() => {
     }
 
     return {
-        showKeywordData 
+        showKeywordData
     }
 })();
 
@@ -706,8 +722,8 @@ const KEYWORD_BOOK = (() => {
 const PRICE_BOOK = (() => {
     const setting = {
         header: [
-            { headerName: '编码', headerWidth: 100, dataCode: 'code', dataType: 'String', hAlign: 'left', vAlign: 'center' ,formatter: "@"},
-            { headerName: '别名编码', headerWidth: 70, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center' ,formatter: "@"},
+            { headerName: '编码', headerWidth: 100, dataCode: 'code', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
+            { headerName: '别名编码', headerWidth: 70, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
             { headerName: '名称', headerWidth: 200, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' },
             { headerName: '规格型号', headerWidth: 120, dataCode: 'specs', dataType: 'String', hAlign: 'left', vAlign: 'center' },
             { headerName: '单位', headerWidth: 80, dataCode: 'unit', dataType: 'String', hAlign: 'center', vAlign: 'center' },
@@ -738,7 +754,7 @@ const PRICE_BOOK = (() => {
         $.bootstrapLoading.start();
         try {
             cache = await ajaxPost('/priceInfo/getPriceData', { classIDList }, TIME_OUT);
-            cache = _.sortBy(cache,'classCode');
+            cache = _.sortBy(cache, 'classCode');
             showData(sheet, cache, setting.header, 5);
             const row = sheet.getActiveRowIndex();
             const keywordList = cache[row] && cache[row].keywordList || [];

+ 108 - 107
web/over_write/crawler/chongqing_2018_price_crawler.js

@@ -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;
   }
 }