刘光辉
昨天 bb638871a7fb692d80f1b7a758f991dc0879002c
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
package jnpf.bizcommon.audit.service.title;
 
import jnpf.util.JsonUtil;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
 
/**
 * 从已发布列表 JSON({@code base_visual_release.F_COLUMN_DATA})解析
 * {@code columnList[].biz_log_enabled} 勾选。
 *
 * <p>与 {@link AuditTitleSpecParser} 的三处差异,别混:
 * <ul>
 *   <li>开关在**列项顶层**,不在 {@code __config__} 里;</li>
 *   <li>字段编码取 {@code prop}(表单侧取 {@code __vModel__})——前端设计文档
 *       「服务端接入建议」第 3 条明确了这两套口径;</li>
 *   <li>{@code columnList} 是平铺数组,没有布局容器嵌套,**不递归**。</li>
 * </ul>
 *
 * <p><b>纯静态、无依赖、永不抛异常</b>:解析失败一律返回 {@link AuditTitleSpec#EMPTY}——
 * 标题缺席可以,「这次删过」不能缺。
 *
 * <p>列表侧没有子表概念,故 {@link AuditTitleSpec#subTables()} 恒为空。
 */
public final class AuditListTitleSpecParser {
 
    private AuditListTitleSpecParser() {
    }
 
    @SuppressWarnings("rawtypes")
    public static AuditTitleSpec parse(String columnDataJson) {
        if (columnDataJson == null || columnDataJson.trim().isEmpty()) {
            return AuditTitleSpec.EMPTY;
        }
        try {
            Map<String, Object> root = JsonUtil.stringToMap(columnDataJson);
            if (root == null) {
                return AuditTitleSpec.EMPTY;
            }
            Object raw = root.get("columnList");
            if (!(raw instanceof List)) {
                return AuditTitleSpec.EMPTY;
            }
            List<String> main = new ArrayList<String>();
            for (Object item : (List) raw) {
                if (!(item instanceof Map)) {
                    continue;
                }
                Map col = (Map) item;
                if (!Boolean.TRUE.equals(col.get("biz_log_enabled"))) {
                    continue;
                }
                Object prop = col.get("prop");
                if (prop == null) {
                    continue;
                }
                String field = String.valueOf(prop).trim();
                // 主表字段口径与 AuditTitleSpec.mainFields() 一致:小写
                if (!field.isEmpty() && !main.contains(field.toLowerCase(Locale.ROOT))) {
                    main.add(field.toLowerCase(Locale.ROOT));
                }
            }
            if (main.isEmpty()) {
                return AuditTitleSpec.EMPTY;
            }
            return new AuditTitleSpec(main, new ArrayList<AuditTitleSpec.SubTableSpec>());
        } catch (Throwable t) {
            // 同 AuditTitleSpecParser:不记日志,每次操作都会走到这里,报错会刷爆日志
            return AuditTitleSpec.EMPTY;
        }
    }
}