9 小时以前 9bad721754fe8bbe2e5f459d0706e0fefac569f3
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package cn.iocoder.yudao.module.qcreport.engine.rule;
 
import java.util.Map;
 
/**
 * 判定规则定义。
 * <p>
 * 与前端 {@code engine/report-evaluator.ts} 的 QualityRuleDefinition 一一对应,
 * 也就是模板 Schema 的 {@code rules} 数组里每一项的契约:
 * {@code { id, name, scope: 'item' | 'report', expression, enabled }}。
 *
 * @param id         规则标识,用于出错时定位
 * @param name       规则名称
 * @param scope      作用域:逐项判定 / 报告级汇总
 * @param expression 判定表达式,求值为真视为合格
 * @param enabled    是否参与判定,null 等同 true
 */
public record QualityRuleDefinition(String id, String name, RuleScope scope,
                                    String expression, Boolean enabled) {
 
    /** 是否参与判定,与前端 {@code rule.enabled !== false} 同语义 */
    public boolean active() {
        return enabled == null || enabled;
    }
 
    /** 出错提示里用的原始名,两者都缺时为空串(与前端 {@code rule.name ?? rule.id ?? ''} 一致) */
    public String rawLabel() {
        if (name != null) {
            return name;
        }
        return id == null ? "" : id;
    }
 
    /** 出错提示里用的规则名 */
    public String label() {
        String trimmed = name == null ? "" : name.trim();
        if (!trimmed.isEmpty()) {
            return trimmed;
        }
        return id == null || id.isEmpty() ? "未命名规则" : id;
    }
 
    /**
     * 从 Schema 的 rules 项解析,缺字段的按默认值兜底。
     * <p>
     * 只做取值不做校验:Schema 是设计器存的,格式问题会在执行时报出来,
     * 读的时候再抛一次异常只会把「一处坏数据」放大成「整份模板打不开」。
     */
    public static QualityRuleDefinition from(Map<?, ?> raw) {
        if (raw == null) {
            return null;
        }
        return new QualityRuleDefinition(
                text(raw.get("id")),
                text(raw.get("name")),
                RuleScope.of(text(raw.get("scope"))),
                text(raw.get("expression")),
                flag(raw.get("enabled")));
    }
 
    private static String text(Object value) {
        return value == null ? null : String.valueOf(value);
    }
 
    /** 只把明确的 false / "false" / 0 当作停用,缺省视为启用 */
    private static Boolean flag(Object value) {
        if (value instanceof Boolean bool) {
            return bool;
        }
        if (value instanceof Number number) {
            return number.intValue() != 0;
        }
        if (value instanceof String text) {
            return !"false".equalsIgnoreCase(text.trim());
        }
        return null;
    }
 
}