/** * 解析原始记录模板中的检验值批注。 * 兼容旧格式“检验值”,并支持:检验值,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; }