|
@@ -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 {
|