gaoluyang
4 天以前 c2398150b44b54a1f08e7af4b6a64f0c170046f0
fix: 支持计算值和最终值按批注格式化
已修改3个文件
74 ■■■■■ 文件已修改
src/utils/excelFountion.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/inspectionValueFormat.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/workers/InspectionWorker.worker.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/excelFountion.js
@@ -61,21 +61,18 @@
 */
function AVERAGE(...val) {
  try {
    let num = null;
    let arr = [];
    if (val && val.length > 0) {
      arr = val.filter((item) => item != null && item !== "");
      arr.forEach((item) => {
        num += item;
      });
      if (arr.length > 0) {
        return num / arr.length;
      } else {
        return null;
    // 单元格值经常以字符串形式传入;先展开参数并转成数字,避免
    // `AVERAGE(C3:D3)` 在展开后收到字符串而得到 NaN。
    const values = [];
    const flatten = (items) => items.forEach((item) => {
      if (Array.isArray(item)) return flatten(item);
      if (item !== null && item !== undefined && item !== "" && item !== " ") {
        const number = Number(item);
        if (Number.isFinite(number)) values.push(number);
      }
    } else {
      return null;
    }
    });
    flatten(val);
    return values.length ? values.reduce((sum, item) => sum + item, 0) / values.length : null;
  } catch (error) {}
}
/**
src/utils/inspectionValueFormat.js
@@ -1,9 +1,10 @@
/**
 * 解析原始记录模板中的检验值批注。
 * 兼容旧格式“检验值”,并支持:检验值,2、检验值,2,科学计数法。
 * 支持检验值、计算值、最终值的批注,例如:检验值,2、计算值,2,最终值,2,科学计数法。
 */
export function parseInspectionValueAnnotation(annotation) {
  if (typeof annotation !== 'string' || !annotation.includes('检验值')) return null;
  const targetNames = ['检验值', '计算值', '最终值'];
  if (typeof annotation !== 'string') return null;
  // 批注允许中文逗号、英文逗号以及“和”连接格式参数。
  const parts = annotation
    .replace(/,/g, ',')
@@ -12,6 +13,7 @@
    .split(',')
    .map(item => item.trim())
    .filter(Boolean);
  if (!targetNames.includes(parts[0])) return null;
  const decimalIndex = parts.findIndex((item, index) => index > 0 && /^\d+$/.test(item));
  const decimalPlaces = decimalIndex < 0 ? null : Number(parts[decimalIndex]);
  if (decimalPlaces != null && (!Number.isInteger(decimalPlaces) || decimalPlaces < 0 || decimalPlaces > 15)) {
@@ -31,9 +33,10 @@
    item && index + 1 !== decimalIndex && item !== '科学计数法' && !roundingNames[item]
  );
  if (unsupported.length || parts.length > 4) {
    return { error: '检验值批注格式应为:检验值,2,四舍五入 或 检验值,2,科学计数法,四舍五入' };
    return { error: '批注格式应为:检验值,2,四舍五入;计算值,2;最终值,2,科学计数法' };
  }
  return {
    target: parts[0],
    decimalPlaces,
    displayMode,
    // 参数顺序决定处理顺序:科学计数法在小数位前表示先转科学计数法。
src/workers/InspectionWorker.worker.js
@@ -1,5 +1,6 @@
// 多线程里面需要保存的数据
import Big from "big.js";
import { parseInspectionValueAnnotation, formatInspectionValue } from "../utils/inspectionValueFormat";
let code = "";
// 表格数据(渲染)
@@ -405,7 +406,12 @@
              // 判断当前行是否为当前检验项所在行,如果为当前行,则给表格数据赋值
              for (var b in a) {
                if (a[b].c == item.c) {
                  a[b].v.v = comResult;
                  // 计算值、最终值也按单元格批注的小数位数格式化,避免计算结果绕过前端输入校验。
                  const annotation = a[b].v && a[b].v.ps && a[b].v.ps.value;
                  const formatConfig = parseInspectionValueAnnotation(annotation);
                  a[b].v.v = formatConfig && !formatConfig.error
                    ? formatInspectionValue(comResult, formatConfig)
                    : comResult;
                  hasComputedWrite = true;
                  break;
                }
@@ -704,29 +710,17 @@
 */
function AVERAGE(...val) {
  try {
    let num = null;
    let arr = [];
    if (
      val != null &&
      val != undefined &&
      val != "undefined" &&
      val != "NaN" &&
      val.length > 0
    ) {
      arr = val.filter(
        (item) => item !== null && item !== "" && item != undefined
      );
      arr.forEach((item) => {
        num += item;
      });
      if (arr.length > 0) {
        return num / arr.length;
      } else {
        return null;
    // 单元格值可能是字符串;统一转数字后再计算,兼容区间参数。
    const values = [];
    const flatten = (items) => items.forEach((item) => {
      if (Array.isArray(item)) return flatten(item);
      if (item !== null && item !== undefined && item !== "" && item !== " ") {
        const number = Number(item);
        if (Number.isFinite(number)) values.push(number);
      }
    } else {
      return null;
    }
    });
    flatten(val || []);
    return values.length ? values.reduce((sum, item) => sum + item, 0) / values.length : null;
  } catch (error) {
    console.log("error---", error);
  }