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