|
@@ -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,41 +338,68 @@ 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 = getFourCode(rowData.code);
|
|
|
- const toMatchSummary = code ? summaryGroupMap[code] || [] : noCodeSummary;
|
|
|
- if (toMatchSummary.length) {
|
|
|
- changedCells.push({ row: i });
|
|
|
- } else {
|
|
|
- noMatchRows.push(i);
|
|
|
- }
|
|
|
- }
|
|
|
- const classCodeCol = setting.header.findIndex(h => h.dataCode === 'classCode');
|
|
|
- const expStringCol = setting.header.findIndex(h => h.dataCode === 'expString');
|
|
|
+
|
|
|
+ const aiMatchData = getAIMatchData(summaryGroupMap, noCodeSummary);
|
|
|
+ percent = aiMatchData.curPercent;
|
|
|
+ curIndex = aiMatchData.curIndex;
|
|
|
+ changedCells = aiMatchData.changedCells;
|
|
|
+ noMatchRows = aiMatchData.noMatchRows;
|
|
|
+
|
|
|
if (!changedCells.length) {
|
|
|
return;
|
|
|
}
|
|
|
- const chunks = _.chunk(changedCells, 1); // 改成只能一条一条匹配,否则会很慢。经常把ai服务弄挂
|
|
|
- let percent = 0;
|
|
|
+ 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服务经常挂
|
|
|
$.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 = [];
|
|
@@ -380,14 +411,12 @@ 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 = 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();
|
|
@@ -398,7 +427,7 @@ const EMPTY_BOOK = (() => {
|
|
|
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;
|
|
@@ -421,7 +450,7 @@ const EMPTY_BOOK = (() => {
|
|
|
cache[chunkItem.row].expString = summaryItem.expString;
|
|
|
items.forEach(item => {
|
|
|
item.expString = summaryItem.expString;
|
|
|
- })
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
});
|
|
@@ -430,7 +459,7 @@ const EMPTY_BOOK = (() => {
|
|
|
percent += step;
|
|
|
$('#progress_modal_body').text(`正在进行AI填值,请稍后${i + 1}/${chunks.length}...`);
|
|
|
$("#progress_modal_bar").css('width', `${percent}%`);
|
|
|
- await setTimeoutSync(500);
|
|
|
+ await setTimeoutSync(100);
|
|
|
}
|
|
|
|
|
|
// 没匹配到的行,自动生成别名编码
|
|
@@ -449,10 +478,17 @@ 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);
|
|
@@ -518,6 +554,7 @@ $(document).ready(() => {
|
|
|
|
|
|
$('#empty-area').on('hidden.bs.modal', function () {
|
|
|
EMPTY_BOOK.clear();
|
|
|
+ $("#ai-match").text('AI填值');
|
|
|
});
|
|
|
|
|
|
// 保存至总表
|