| | |
| | | // 当前这次输入对应的原始检验项。计算过程中 pId 会切换到下游计算项, |
| | | // 保存时必须同时带回原始检验项,否则只会保存计算结果。 |
| | | let sourceInsItemId = null; |
| | | // 当前消息版本。Worker 单线程串行处理消息,供递归公式计算完成后回传给主线程。 |
| | | let currentRevision = null; |
| | | // 本次输入是否往单元格写入过计算结果。链式公式只有最外层会回传保存, |
| | | // 用它在最外层判断计算的中间值是否也需要落库。 |
| | | let hasComputedWrite = false; |
| | | |
| | | /** |
| | | * 生成模板结构签名 |
| | |
| | | self.onmessage = function (event) { |
| | | // 保存主线程传过来的值 |
| | | const data = JSON.parse(event.data); |
| | | currentRevision = data.revision; |
| | | // 模板内容变了(不只是模板id变了)也要刷新表格,否则改完模版后 Worker 仍用旧模板计算并把旧版式回写页面 |
| | | const nextTemplateSig = buildTemplateSig(data.tableList); |
| | | if ( |
| | |
| | | comparisonList = JSON.parse(JSON.stringify(data.comparisonList)); |
| | | currentSample = JSON.parse(JSON.stringify(data.currentSample)); |
| | | PROJECT = data.PROJECT; |
| | | // 执行计算方法 |
| | | // 执行计算方法。每次输入重置标记,由本次调用栈的最外层决定是否回传保存 |
| | | hasComputedWrite = false; |
| | | changeInput("", code); |
| | | }; |
| | | |
| | |
| | | return !(typeof r === "number" && isNaN(r)); |
| | | } |
| | | |
| | | function changeInput(m, code) { |
| | | function changeInput(m, code, isComputed) { |
| | | let str = code.split("-"); |
| | | let r = str[1]; //当前行 |
| | | let c = str[2]; //当前列 |
| | |
| | | a[b].v.v = comResult; |
| | | console.log("error---", error); |
| | | } |
| | | hasComputedWrite = true; |
| | | break; |
| | | } |
| | | } |
| | |
| | | // 如果此计算结果所属单元格,同时也是另一个excel函数的参数,那么就需要递归进行计算 |
| | | // 只有算出有效结果才继续向下游公式传递,避免把空值/NaN 传染给其它单元格 |
| | | if (isValidComputedResult(comResult)) { |
| | | changeInput(comResult, `${id}-${item.r}-${item.c}-${pId}`); //改变最终值 |
| | | // 标记为计算层:它可能是下游公式的参数(isSave 会被置成 false),但自身也是结果, |
| | | // 保存交给最外层统一回传,中间值不会被漏掉,也不会每一级都发一次保存请求 |
| | | changeInput(comResult, `${id}-${item.r}-${item.c}-${pId}`, true); //改变最终值 |
| | | } |
| | | currentInsItemId = item.i; |
| | | } catch (error) { |
| | |
| | | } |
| | | } |
| | | }); |
| | | if (index === -1 || (inputType === undefined && isSave === "true")) { |
| | | if ( |
| | | !isComputed && |
| | | (hasComputedWrite || index === -1 || (inputType === undefined && isSave === "true")) |
| | | ) { |
| | | // 赋值传递到主线程的数据,method:saveInsContext表示此消息需要保存数据 |
| | | result = { |
| | | method: "saveInsContext", |
| | | revision: currentRevision, |
| | | value: { |
| | | tableList, // 表格数据 |
| | | param: getParam(), //传给后端的参数 |
| | |
| | | // 赋值多线程传输数据 |
| | | result = { |
| | | method: "tableList", |
| | | revision: currentRevision, |
| | | value: tableList, |
| | | }; |
| | | // 发送主线程数据 |
| | |
| | | const resultParam = {}; |
| | | tableList.forEach((t) => { |
| | | resultParam[t.templateId] = {}; |
| | | const cells = (t.arr || []).reduce((all, row) => all.concat(row), []); |
| | | const resultHeader = cells.find((cell) => |
| | | cell.v && String(cell.v.v || "").trim() === "检验结果" |
| | | ); |
| | | const exportRows = new Set(cells.filter((cell) => |
| | | cell.v && cell.v.ps && cell.v.ps.value === "导出值" |
| | | ).map((cell) => cell.r)); |
| | | (t.arr || []).forEach((a) => { |
| | | a.forEach((b) => { |
| | | const isEditable = |
| | |
| | | b.v.ps.value === "计算值" || |
| | | b.v.ps.value === "最终值" || |
| | | b.v.ps.value === "设备名称"); |
| | | if (!isEditable) { |
| | | const isExportResult = resultHeader && exportRows.has(b.r) && b.c === resultHeader.c; |
| | | if (!isEditable && !isExportResult) { |
| | | return; |
| | | } |
| | | if ( |
| | | isEditable && |
| | | b.v.ps.value.includes("检验值") && |
| | | (b.v.v === "" || b.v.v === null || b.v.v === undefined) |
| | | ) { |