| | |
| | | return leftText === rightText ? 0 : leftText > rightText ? 1 : -1; |
| | | } |
| | | |
| | | function compareNumbers(left: unknown, right: unknown): number { |
| | | const leftNumber = toNumber(left); |
| | | const rightNumber = toNumber(right); |
| | | if (!Number.isFinite(leftNumber) || !Number.isFinite(rightNumber)) { |
| | | throw new RuleRuntimeError('数值比较缺少有效实测值或规格限值'); |
| | | } |
| | | return leftNumber === rightNumber ? 0 : leftNumber > rightNumber ? 1 : -1; |
| | | } |
| | | |
| | | /** 判定结果类取值统一成 PASS / FAIL:兼容中文、布尔与数字 1/0 */ |
| | | const PASS_TOKENS = new Set(['PASS', 'TRUE', '合格', 'OK', '1', '是']); |
| | | const FAIL_TOKENS = new Set(['FAIL', 'FALSE', '不合格', 'NG', '0', '否']); |
| | |
| | | case 'between': { |
| | | const value = evaluateNode(node.value, context); |
| | | const hit = |
| | | compare(value, evaluateNode(node.lower, context)) >= 0 && |
| | | compare(value, evaluateNode(node.upper, context)) <= 0; |
| | | compareNumbers(value, evaluateNode(node.lower, context)) >= 0 && |
| | | compareNumbers(value, evaluateNode(node.upper, context)) <= 0; |
| | | return node.negated ? !hit : hit; |
| | | } |
| | | case 'in': { |
| | |
| | | return compare(left, right) !== 0; |
| | | } |
| | | case '>': { |
| | | return compare(left, right) > 0; |
| | | return compareNumbers(left, right) > 0; |
| | | } |
| | | case '>=': { |
| | | return compare(left, right) >= 0; |
| | | return compareNumbers(left, right) >= 0; |
| | | } |
| | | case '<': { |
| | | return compare(left, right) < 0; |
| | | return compareNumbers(left, right) < 0; |
| | | } |
| | | case '<=': { |
| | | return compare(left, right) <= 0; |
| | | return compareNumbers(left, right) <= 0; |
| | | } |
| | | case '+': { |
| | | const leftNumber = toNumber(left); |
| | |
| | | visit(node); |
| | | // 统计函数作用在数组路径上,这里去掉末端字段只保留数组本身 |
| | | return [...new Set(paths.map((path) => parsePath(path).join('.')))]; |
| | | } |
| | | } |