吴羡
4 小时以前 6f90e7110190d146fde06cf1f5b2272fd49b53d6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * 解析原始记录模板中的检验值批注。
 * 兼容旧格式“检验值”,并支持:检验值,2、检验值,2,科学计数法。
 */
export function parseInspectionValueAnnotation(annotation) {
  if (typeof annotation !== 'string' || !annotation.includes('检验值')) return null;
  // 批注允许中文逗号、英文逗号以及“和”连接格式参数。
  const parts = annotation
    .replace(/,/g, ',')
    .replace(/\s+/g, '')
    .replace(/和/g, ',')
    .split(',')
    .map(item => item.trim())
    .filter(Boolean);
  const decimalPlaces = parts[1] === '' || parts[1] == null ? null : Number(parts[1]);
  if (decimalPlaces != null && (!Number.isInteger(decimalPlaces) || decimalPlaces < 0 || decimalPlaces > 15)) {
    return { error: '小数位数必须是 0 到 15 的整数' };
  }
  const displayMode = parts.slice(2).includes('科学计数法') ? 'SCIENTIFIC' : 'NORMAL';
  const roundingNames = {
    '四舍五入': 'HALF_UP',
    '四舍六入': 'HALF_UP_6',
    '向上舍入': 'CEILING',
    '向下舍入': 'FLOOR',
    '截断': 'DOWN'
  };
  const roundingPart = parts.slice(2).find(item => Object.prototype.hasOwnProperty.call(roundingNames, item));
  const unsupported = parts.slice(2).filter(item => item && item !== '科学计数法' && !roundingNames[item]);
  if (unsupported.length || parts.length > 4) {
    return { error: '检验值批注格式应为:检验值,2,四舍五入 或 检验值,2,科学计数法,四舍五入' };
  }
  return { decimalPlaces, displayMode, roundingMode: roundingPart ? roundingNames[roundingPart] : 'HALF_UP' };
}
 
export function formatInspectionValue(value, config) {
  if (!config || config.error || config.decimalPlaces == null || value === '' || value == null) return value;
  const number = Number(value);
  if (!Number.isFinite(number)) return value;
  const factor = 10 ** config.decimalPlaces;
  let rounded;
  if (config.roundingMode === 'CEILING') rounded = Math.ceil(number * factor) / factor;
  else if (config.roundingMode === 'FLOOR') rounded = Math.floor(number * factor) / factor;
  else if (config.roundingMode === 'DOWN') rounded = (number < 0 ? Math.ceil(number * factor) : Math.floor(number * factor)) / factor;
  else if (config.roundingMode === 'HALF_UP_6') {
    const absolute = Math.abs(number) * factor;
    const base = Math.floor(absolute);
    const fraction = absolute - base;
    rounded = (number < 0 ? -1 : 1) * ((fraction >= 0.6 ? base + 1 : base) / factor);
  } else rounded = Math.round((number + (number >= 0 ? Number.EPSILON : -Number.EPSILON)) * factor) / factor;
  return config.displayMode === 'SCIENTIFIC'
    ? rounded.toExponential(config.decimalPlaces)
    : rounded.toFixed(config.decimalPlaces);
}
 
export function validateInspectionValueAnnotation(annotation) {
  const config = parseInspectionValueAnnotation(annotation);
  return config && config.error ? config.error : null;
}