Browse Source

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/ConstructionOperation

Tony Kang 3 months atrás
parent
commit
956e10a0bd

+ 25 - 24
public/web/tree_sheet/tree_sheet_controller.js

@@ -31,7 +31,7 @@ var TREE_SHEET_CONTROLLER = {
                 var sels = me.sheet.getSelections();
                 newNodes.sort(function (a, b) {
                     let rst = 0;
-                    if(a.serialNo() > b.serialNo()){
+                    if (a.serialNo() > b.serialNo()) {
                         rst = 1;
                     }
                     else {
@@ -39,10 +39,10 @@ var TREE_SHEET_CONTROLLER = {
                     }
                     return rst;
                 });
-                for(let newNode of newNodes){
+                for (let newNode of newNodes) {
                     me.sheet.addRows(newNode.serialNo(), 1);
                 }
-                for(let newNode of newNodes){
+                for (let newNode of newNodes) {
                     me.setTreeSelected(newNode);
                     TREE_SHEET_HELPER.refreshTreeNodeData(me.setting, me.sheet, [newNode], false);
                     me.sheet.setSelection(newNode.serialNo(), sels[0].col, 1, 1);
@@ -51,7 +51,7 @@ var TREE_SHEET_CONTROLLER = {
         };
 
         controller.prototype.insert = function () {
-            var newNode = null, that = this,  sels = this.sheet.getSelections();
+            var newNode = null, that = this, sels = this.sheet.getSelections();
             if (this.tree) {
                 if (this.tree.selected) {
                     newNode = this.tree.insert(this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
@@ -70,10 +70,10 @@ var TREE_SHEET_CONTROLLER = {
             }
         };
         controller.prototype.m_insert = function (datas) {
-            let nodes = [], that = this,  sels = this.sheet.getSelections();
-            if(this.tree){
+            let nodes = [], that = this, sels = this.sheet.getSelections();
+            if (this.tree) {
                 if (this.tree.selected) {
-                    nodes = this.tree.m_insert(datas,this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
+                    nodes = this.tree.m_insert(datas, this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
                 } else {
                     nodes = this.tree.m_insert(datas);
                 }
@@ -88,11 +88,12 @@ var TREE_SHEET_CONTROLLER = {
                     //that.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                 });
             }
+            return nodes;
         };
 
 
         controller.prototype.insertByID = function (ID) {
-            var newNode = null, that = this,  sels = this.sheet.getSelections();
+            var newNode = null, that = this, sels = this.sheet.getSelections();
             if (this.tree) {
                 if (this.tree.selected) {
                     newNode = this.tree.insertByID(ID, this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
@@ -112,7 +113,7 @@ var TREE_SHEET_CONTROLLER = {
             return newNode;
         };
         controller.prototype.insertByIDS = function (ID, ParentID, NexSiblingID) {
-            var newNode = null, that = this,  sels = this.sheet.getSelections();
+            var newNode = null, that = this, sels = this.sheet.getSelections();
             if (this.tree) {
                 if (this.tree.selected) {
                     newNode = this.tree.insertByID(ID, ParentID, NexSiblingID);
@@ -132,7 +133,7 @@ var TREE_SHEET_CONTROLLER = {
             return newNode;
         };
         controller.prototype.insertToChild = function (ID, ParentID, NextSiblingID) {
-            var newNode = null, that = this,  sels = this.sheet.getSelections();
+            var newNode = null, that = this, sels = this.sheet.getSelections();
             if (this.tree) {
                 if (this.tree.selected) {
                     newNode = this.tree.insertByID(ID, ParentID, NextSiblingID);
@@ -164,16 +165,16 @@ var TREE_SHEET_CONTROLLER = {
         };
         controller.prototype.m_delete = function (nodes) {
             var that = this, sels = this.sheet.getSelections();
-            if(nodes.length > 0){
-                if(this.tree.m_delete(nodes)){
+            if (nodes.length > 0) {
+                if (this.tree.m_delete(nodes)) {
                     TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
                         let rowCount = 0;
-                        for(let node of nodes){
-                            rowCount = rowCount+node.posterityCount() + 1;
+                        for (let node of nodes) {
+                            rowCount = rowCount + node.posterityCount() + 1;
                         }
                         that.sheet.deleteRows(sels[0].row, rowCount);
                         that.setTreeSelected(that.tree.items[sels[0].row]);
-                        that.sheet.setSelection(sels[0].row,sels[0].col,1,sels[0].colCount);
+                        that.sheet.setSelection(sels[0].row, sels[0].col, 1, sels[0].colCount);
                     });
                 }
             }
@@ -184,7 +185,7 @@ var TREE_SHEET_CONTROLLER = {
                 if (this.tree.selected.upLevel()) {
                     TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
                         TREE_SHEET_HELPER.refreshNodesVisible([that.tree.selected], that.sheet, true);
-                       // that.sheet.showRow(that.tree.selected.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                        // that.sheet.showRow(that.tree.selected.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                         if (that.event.refreshBaseActn) {
                             that.event.refreshBaseActn(that.tree);
                         }
@@ -235,12 +236,12 @@ var TREE_SHEET_CONTROLLER = {
             var that = this, sels = this.sheet.getSelections();
             if (this.tree.selected) {
                 TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
-                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo(),true);//为了处理移动前子项是隐藏的情况,先把所有的列设置为显示
-                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.preSibling,that.tree.selected.preSibling.serialNo(),true);
+                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected, that.tree.selected.serialNo(), true);//为了处理移动前子项是隐藏的情况,先把所有的列设置为显示
+                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected.preSibling, that.tree.selected.preSibling.serialNo(), true);
                     if (that.tree.selected.upMove()) {
                         TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.nextSibling], true);
-                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo());
-                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.nextSibling,that.tree.selected.nextSibling.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected, that.tree.selected.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected.nextSibling, that.tree.selected.nextSibling.serialNo());
                         that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
                         if (that.event.refreshBaseActn) {
                             that.event.refreshBaseActn(that.tree);
@@ -253,12 +254,12 @@ var TREE_SHEET_CONTROLLER = {
             var that = this, sels = this.sheet.getSelections();
             if (this.tree.selected) {
                 TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
-                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo(),true);//为了处理移动前子项是隐藏的情况,先把所有的列设置为显示
-                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.nextSibling,that.tree.selected.nextSibling.serialNo(),true);
+                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected, that.tree.selected.serialNo(), true);//为了处理移动前子项是隐藏的情况,先把所有的列设置为显示
+                    TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected.nextSibling, that.tree.selected.nextSibling.serialNo(), true);
                     if (that.tree.selected.downMove()) {
                         TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.preSibling], true);
-                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo());
-                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.preSibling,that.tree.selected.preSibling.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected, that.tree.selected.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet, that.tree, that.tree.selected.preSibling, that.tree.selected.preSibling.serialNo());
                         that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
                         if (that.event.refreshBaseActn) {
                             that.event.refreshBaseActn(that.tree);

+ 16 - 12
web/maintain/bills_lib/scripts/db_controller.js

@@ -32,7 +32,8 @@ function getNewBIlls(controller, rowCount, billsLibId) {
     };
     if (i === rowCount - 1) {
       tem.NextSiblingID = NextSiblingID;
-    } else if (i !== 0) {
+    }
+    if (i !== 0) {
       insertBills[i - 1].NextSiblingID = tem.ID;
     }
 
@@ -74,14 +75,17 @@ var dbController = {
           type: "new",
           data: item,
         }));
-        controller.m_insert(treeData);
-        controller.tree.selected.jobs = new Array();
-        controller.tree.selected.items = new Array();
-        controller.sheet.setTag(
-          controller.tree.selected.serialNo(),
-          0,
-          controller.tree.selected.getID()
-        );
+        const newNodes = controller.m_insert(treeData);
+        newNodes.forEach(n => {
+          n.jobs = [];
+          n.items = [];
+          console.log(n.serialNo(), n.getID());
+          controller.sheet.setTag(
+            n.serialNo(),
+            0,
+            n.getID()
+          );
+        });
         sheetBillsDatas = tools.getsheetDatas(
           controller.sheet,
           "bills",
@@ -299,9 +303,9 @@ var dbController = {
       }
       let updateNode = node.preSibling
         ? {
-            ID: node.preSibling.getID(),
-            NextSiblingID: node.getNextSiblingID(),
-          }
+          ID: node.preSibling.getID(),
+          NextSiblingID: node.getNextSiblingID(),
+        }
         : null;
       billsAjax.deleteBills(
         userAccount,

+ 183 - 146
web/maintain/price_info_lib/js/priceEmpty.js

@@ -84,10 +84,14 @@ const EMPTY_BOOK = (() => {
     }
   }
 
+  // ai填值缓存,用于ai填值报错时,可以从当前报错处开始匹配,而不用重头开始匹配
+  let aiMatchCache = null;
+
   // 清空
   function clear() {
     cache.length = 0;
     workBookObj.sheet.setRowCount(0);
+    aiMatchCache = null;
   }
 
   let curRow = 0;
@@ -334,43 +338,69 @@ const EMPTY_BOOK = (() => {
     return code.substring(0, 4);
   }
 
+
+  const getAIMatchData = (summaryGroupMap, noCodeSummary) => {
+    if (aiMatchCache && aiMatchCache.changedCells.length && aiMatchCache.curIndex > 0) {
+      return aiMatchCache;
+    }
+    const curPercent = 0;
+    const curIndex = 0;
+    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);
+      }
+    }
+    return {
+      curPercent,
+      curIndex,
+      changedCells,
+      noMatchRows,
+    }
+  }
+
   // ai填值
   const aiMatch = async () => {
+    let percent = 0;
+    let curIndex = 0;
+    let noMatchRows = [];
+    let changedCells = [];
     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);
-        }
-      }
+
+      const aiMatchData = getAIMatchData(summaryGroupMap, noCodeSummary);
+      percent = aiMatchData.curPercent;
+      curIndex = aiMatchData.curIndex;
+      changedCells = aiMatchData.changedCells;
+      noMatchRows = aiMatchData.noMatchRows;
+
       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;
+      const chunks = _.chunk(changedCells, 1); // 只能一条一条匹配改成,否则经常ai服务经常挂
       $.bootstrapLoading.progressStart('AI填值', false);
-      $("#progress_modal_body").text('正在进行AI填值,请稍后...');
+      $('#progress_modal_body').text(`正在进行AI填值,请稍后${curIndex + 1}/${chunks.length}...`);
       await setTimeoutSync(500);
       const matchResCache = {};
 
       // 分块进行ai匹配
       const step = 100 / (chunks.length || 1);
-      for (let i = 0; i < chunks.length; i++) {
+      for (let i = curIndex; i < chunks.length; i++) {
+        curIndex = i;
         const chunk = chunks[i];
         const listA = [];
         const listB = [];
@@ -378,7 +408,6 @@ const EMPTY_BOOK = (() => {
         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);
@@ -387,7 +416,6 @@ const EMPTY_BOOK = (() => {
         });
         const test = listB.map(item => item.length);
         console.log(test);
-
         const matchRes = matchResCache[listA[0]] ? matchResCache[listA[0]] : await ajaxPost('/priceInfoSummary/aiMatch', { listA, listB }, 1000 * 60 * 5);
         matchResCache[listA[0]] = matchRes;
         // 填匹配值到表格,不实时保存,因为需要人工核查
@@ -430,7 +458,7 @@ const EMPTY_BOOK = (() => {
         workBookObj.sheet.resumeEvent();
         workBookObj.sheet.resumePaint();
         percent += step;
-        $('#progress_modal_body').text(`正在进行AI填值,请稍后${i + 1}/${chunks.length}...`)
+        $('#progress_modal_body').text(`正在进行AI填值,请稍后${i + 1}/${chunks.length}...`);
         $("#progress_modal_bar").css('width', `${percent}%`);
         await setTimeoutSync(100);
       }
@@ -451,139 +479,147 @@ const EMPTY_BOOK = (() => {
       }
       workBookObj.sheet.resumeEvent();
       workBookObj.sheet.resumePaint();
-
-
+      aiMatchCache = null;
+      $("#ai-match").text('AI填值');
     } catch (error) {
       console.log(error);
+      aiMatchCache = {
+        curPercent: percent,
+        curIndex,
+        noMatchRows,
+        changedCells,
+      }
+      $("#ai-match").text('继续AI填值');
       alert(error);
     }
     await setTimeoutSync(500);
     $.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();
-   } */
+
+  /*   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); // 只能一条一条匹配改成,否则经常ai服务经常挂
+        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 (let i = 0; i < chunks.length; i++) {
+          const chunk = chunks[i];
+          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 = getFourCode(rowData.code);
+            const toMatchSummary = code ? summaryGroupMap[code] || [] : noCodeSummary;
+            summaryData.push(toMatchSummary);
+            const summaryKeys = toMatchSummary.map(summary => `${summary.name || ''} ${summary.specs || ''}`);
+            listB.push([...new Set(summaryKeys)]);
+          });
+          const test = listB.map(item => item.length);
+          console.log(test);
+          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();
+          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_body').text(`正在进行AI填值,请稍后${i + 1}/${chunks.length}...`);
+          $("#progress_modal_bar").css('width', `${percent}%`);
+          await setTimeoutSync(100);
+        }
+  
+        // 没匹配到的行,自动生成别名编码
+        workBookObj.sheet.suspendEvent();
+        workBookObj.sheet.suspendPaint();
+        let curMaxClassCode = getMaxClassCode(priceInfoSummary);
+        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 () => {
@@ -643,6 +679,7 @@ $(document).ready(() => {
 
   $('#empty-area').on('hidden.bs.modal', function () {
     EMPTY_BOOK.clear();
+    $("#ai-match").text('AI填值');
   });
 
   // 保存至总表