Sfoglia il codice sorgente

feat: 优化ai填值

vian 3 mesi fa
parent
commit
eb0dcc965d
3 ha cambiato i file con 152 aggiunte e 7 eliminazioni
  1. 16 0
      config/config.js
  2. 2 1
      package.json
  3. 134 6
      web/maintain/price_info_lib/js/priceEmpty.js

+ 16 - 0
config/config.js

@@ -111,6 +111,22 @@ module.exports = {
             useMongoClient: true
         }
     },
+    local2prod_wc: {
+        title: "大司空V2.0",
+        startPort: 1002,
+        server: "112.74.42.187",//数据库ID
+        port: "28033",//数据库端口
+        dbName: 'stdBuilding',
+        options: {
+            user: 'wisecost',
+            pass: 'Smartcost3850888',
+            auth: {
+                "authSource": "admin"
+            },
+            connectTimeoutMS: 60000,
+            useMongoClient: true
+        }
+    },
     prod_wc: {
         title: "大司空V2.0",
         startPort: 1002,

+ 2 - 1
package.json

@@ -46,6 +46,7 @@
     "uat_server": "SET NODE_ENV=uat&& babel-node operation.js",
     "uat_WC_server": "SET NODE_ENV=uat_wc&& babel-node operation.js",
     "prod_server": "SET NODE_ENV=prod_s&& babel-node operation.js",
-    "prod_WC_server": "SET NODE_ENV=prod_wc&& babel-node operation.js"
+    "prod_WC_server": "SET NODE_ENV=prod_wc&& babel-node operation.js",
+    "local2prod_wc": "SET NODE_ENV=local2prod_wc&& babel-node operation.js"
   }
 }

+ 134 - 6
web/maintain/price_info_lib/js/priceEmpty.js

@@ -360,15 +360,18 @@ const EMPTY_BOOK = (() => {
       }
       const classCodeCol = setting.header.findIndex(h => h.dataCode === 'classCode');
       const expStringCol = setting.header.findIndex(h => h.dataCode === 'expString');
-      const chunks = _.chunk(changedCells, 20);
+      // const chunks = _.chunk(changedCells, 20);
+      const chunks = _.chunk(changedCells, 1); // 
       let percent = 0;
       $.bootstrapLoading.progressStart('AI填值', false);
       $("#progress_modal_body").text('正在进行AI填值,请稍后...');
       await setTimeoutSync(500);
+      const matchResCache = {};
 
       // 分块进行ai匹配
       const step = 100 / (chunks.length || 1);
-      for (const chunk of chunks) {
+      for (let i = 0; i < chunks.length; i++) {
+        const chunk = chunks[i];
         const listA = [];
         const listB = [];
         const summaryData = [];
@@ -380,12 +383,13 @@ const EMPTY_BOOK = (() => {
           const toMatchSummary = code ? summaryGroupMap[code] || [] : noCodeSummary;
           summaryData.push(toMatchSummary);
           const summaryKeys = toMatchSummary.map(summary => `${summary.name || ''} ${summary.specs || ''}`);
-          listB.push(summaryKeys)
+          listB.push([...new Set(summaryKeys)]);
         });
         const test = listB.map(item => item.length);
         console.log(test);
 
-        const matchRes = await ajaxPost('/priceInfoSummary/aiMatch', { listA, listB }, 1000 * 60 * 5);
+        const matchRes = matchResCache[listA[0]] ? matchResCache[listA[0]] : await ajaxPost('/priceInfoSummary/aiMatch', { listA, listB }, 1000 * 60 * 5);
+        matchResCache[listA[0]] = matchRes;
         // 填匹配值到表格,不实时保存,因为需要人工核查
         workBookObj.sheet.suspendEvent();
         workBookObj.sheet.suspendPaint();
@@ -426,15 +430,15 @@ const EMPTY_BOOK = (() => {
         workBookObj.sheet.resumeEvent();
         workBookObj.sheet.resumePaint();
         percent += step;
+        $('#progress_modal_body').text(`正在进行AI填值,请稍后${i + 1}/${chunks.length}...`)
         $("#progress_modal_bar").css('width', `${percent}%`);
-        await setTimeoutSync(500);
+        await setTimeoutSync(100);
       }
 
       // 没匹配到的行,自动生成别名编码
       workBookObj.sheet.suspendEvent();
       workBookObj.sheet.suspendPaint();
       let curMaxClassCode = getMaxClassCode(priceInfoSummary);
-      debugger;
       for (const row of noMatchRows) {
         const newClassCode = getNewMaxClassCode(curMaxClassCode);
         workBookObj.sheet.setValue(row, classCodeCol, newClassCode);
@@ -457,6 +461,130 @@ const EMPTY_BOOK = (() => {
     $.bootstrapLoading.progressEnd();
   }
 
+  /*  const aiMatch = async () => {
+     try {
+       // 获取信息价总表
+       const priceInfoSummary = await ajaxPost('/priceInfoSummary/getData', {}, 1000 * 60 * 5);
+       const summaryGroupMap = _.groupBy(priceInfoSummary, item => getFourCode(item.code));
+       const noCodeSummary = priceInfoSummary.filter(item => !item.code);
+       const totalRows = workBookObj.sheet.getRowCount();
+       const changedCells = [];
+       const noMatchRows = []; // 没有匹配、ai没有命中的行,后续需要自动生成别名编码(最大的别名编码+1)
+       for (let i = 0; i < totalRows; i++) {
+         const rowData = getRowData(workBookObj.sheet, i, setting.header);
+         // const code = rowData.code || '';
+         const code = getFourCode(rowData.code);
+         const toMatchSummary = code ? summaryGroupMap[code] || [] : noCodeSummary;
+         if (toMatchSummary.length) {
+           changedCells.push({ row: i });
+         } else {
+           noMatchRows.push(i);
+         }
+       }
+       if (!changedCells.length) {
+         return;
+       }
+       const classCodeCol = setting.header.findIndex(h => h.dataCode === 'classCode');
+       const expStringCol = setting.header.findIndex(h => h.dataCode === 'expString');
+       // const chunks = _.chunk(changedCells, 20);
+       const chunks = _.chunk(changedCells, 1);
+       let percent = 0;
+       $.bootstrapLoading.progressStart('AI填值', false);
+       $("#progress_modal_body").text('正在进行AI填值,请稍后...');
+       await setTimeoutSync(500);
+       debugger;
+ 
+       // 分块进行ai匹配
+       const step = 100 / (chunks.length || 1);
+       for (const chunk of chunks) {
+         const listA = [];
+         const listB = [];
+         const summaryData = [];
+         chunk.forEach(item => {
+           const rowData = getRowData(workBookObj.sheet, item.row, setting.header);
+           listA.push(`${rowData.name || ''} ${rowData.specs}`);
+           // const code = rowData.code || '';
+           const code = getFourCode(rowData.code);
+           const toMatchSummary = code ? summaryGroupMap[code] || [] : noCodeSummary;
+           summaryData.push(toMatchSummary);
+           const summaryKeys = toMatchSummary.map(summary => `${summary.name || ''} ${summary.specs || ''}`);
+           listB.push(summaryKeys)
+         });
+         const test = listB.map(item => item.length);
+         console.log(test);
+ 
+         const matchRes = await ajaxPost('/priceInfoSummary/aiMatch', { listA, listB }, 1000 * 60 * 5);
+         // 填匹配值到表格,不实时保存,因为需要人工核查
+         workBookObj.sheet.suspendEvent();
+         workBookObj.sheet.suspendPaint();
+         matchRes.forEach((item, index) => {
+           const firstMatch = item[0];
+           const chunkItem = chunk[index];
+           const summaryIndex = item[0].index;
+           const summaryItem = summaryData[index][summaryIndex];
+           const curUnit = cache[chunkItem.row]?.unit || '';
+           const summaryItemUnit = summaryItem?.unit || '';
+           // 相似度过低的、单位不一致的,不命中
+           if (firstMatch.similarity < 70 || curUnit !== summaryItemUnit) {
+             noMatchRows.push(chunkItem.row);
+             return;
+           };
+           if (chunkItem && summaryItem) {
+             workBookObj.sheet.setValue(chunkItem.row, classCodeCol, summaryItem.classCode);
+             cache[chunkItem.row].classCode = summaryItem.classCode;
+             const items = getItemsFromTableItem(cache[chunkItem.row]);
+             items.forEach(item => {
+               item.classCode = summaryItem.classCode;
+             });
+             // 如果实际行存在珠海地区的,才填计算式
+             const tableItems = getItemsFromTableItem(cache[chunkItem.row]);
+             const needExpString = tableItems.some(tItem => {
+               const area = AREA_BOOK.cache.find(areaItem => areaItem.ID === tItem.areaID)
+               return area && area.name && /珠海/.test(area.name);
+             });
+             if (needExpString) {
+               workBookObj.sheet.setValue(chunkItem.row, expStringCol, summaryItem.expString);
+               cache[chunkItem.row].expString = summaryItem.expString;
+               items.forEach(item => {
+                 item.expString = summaryItem.expString;
+               });
+             }
+           }
+         });
+         workBookObj.sheet.resumeEvent();
+         workBookObj.sheet.resumePaint();
+         percent += step;
+         $("#progress_modal_bar").css('width', `${percent}%`);
+         await setTimeoutSync(100);
+       }
+ 
+       // 没匹配到的行,自动生成别名编码
+       workBookObj.sheet.suspendEvent();
+       workBookObj.sheet.suspendPaint();
+       let curMaxClassCode = getMaxClassCode(priceInfoSummary);
+       debugger;
+       for (const row of noMatchRows) {
+         const newClassCode = getNewMaxClassCode(curMaxClassCode);
+         workBookObj.sheet.setValue(row, classCodeCol, newClassCode);
+         cache[row].classCode = newClassCode;
+         const items = getItemsFromTableItem(cache[row]);
+         items.forEach(item => {
+           item.classCode = newClassCode;
+         });
+         curMaxClassCode = newClassCode;
+       }
+       workBookObj.sheet.resumeEvent();
+       workBookObj.sheet.resumePaint();
+ 
+ 
+     } catch (error) {
+       console.log(error);
+       alert(error);
+     }
+     await setTimeoutSync(500);
+     $.bootstrapLoading.progressEnd();
+   } */
+
   // 保存ai填值
   const saveData = async () => {
     try {