刘光辉
5 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package jnpf.flowable.util;
 
import jnpf.util.JsonUtil;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
 
/** Renders the selected audit fields of the current form for a flow notification. */
final class FlowAuditTitleUtil {
 
    interface ValueResolver {
        String resolve(Map<String, Object> field, Map<String, Object> config, Object value, Map<String, Object> row);
    }
 
    private static final int MAX_SUFFIX_LENGTH = 200;
 
    private FlowAuditTitleUtil() {
    }
 
    static String append(String title, String suffix) {
        if (title == null || title.trim().isEmpty() || suffix == null || suffix.trim().isEmpty()
                || title.endsWith("/" + suffix)) {
            return title;
        }
        return title + "/" + suffix;
    }
 
    static String suffix(String formDataJson, Map<String, Object> data) {
        return suffix(formDataJson, data, (field, config, value, row) -> display(value));
    }
 
    static String suffix(String formDataJson, Map<String, Object> data, ValueResolver resolver) {
        if (formDataJson == null || data == null || data.isEmpty()) {
            return null;
        }
        try {
            Map<String, Object> form = JsonUtil.stringToMap(formDataJson);
            if (form == null) {
                return null;
            }
            List<String> values = new ArrayList<>();
            collect(list(form.get("fields")), data, values, resolver);
            if (values.isEmpty()) {
                return null;
            }
            String suffix = String.join("/", values);
            return suffix.length() > MAX_SUFFIX_LENGTH ? suffix.substring(0, MAX_SUFFIX_LENGTH) : suffix;
        } catch (RuntimeException ignored) {
            return null;
        }
    }
 
    @SuppressWarnings("unchecked")
    private static void collect(List<?> fields, Map<String, Object> row, List<String> values,
                                ValueResolver resolver) {
        for (Object raw : fields) {
            if (!(raw instanceof Map)) {
                continue;
            }
            Map<String, Object> field = (Map<String, Object>) raw;
            Object rawConfig = field.containsKey("config") ? field.get("config") : field.get("__config__");
            if (!(rawConfig instanceof Map)) {
                continue;
            }
            Map<String, Object> config = (Map<String, Object>) rawConfig;
            List<?> children = list(config.get("children"));
            if ("table".equals(config.get("jnpfKey"))) {
                Object tableData = value(row, model(field));
                List<?> rows = list(tableData);
                // A configured child table contributes values from its actual first row only.
                if (!rows.isEmpty() && rows.get(0) instanceof Map) {
                    collect(children, (Map<String, Object>) rows.get(0), values, resolver);
                }
                continue;
            }
            String model = model(field);
            if (model != null && Boolean.parseBoolean(String.valueOf(config.get("biz_log_enabled")))
                    && !sensitive(model, config)) {
                String display;
                try {
                    display = resolver.resolve(field, config, value(row, model), row);
                } catch (RuntimeException ignored) {
                    display = null;
                }
                if (display != null) {
                    values.add(display);
                }
            }
            if (!children.isEmpty()) {
                collect(children, row, values, resolver);
            }
        }
    }
 
    private static String model(Map<String, Object> field) {
        Object raw = field.containsKey("vModel") ? field.get("vModel") : field.get("__vModel__");
        return raw == null || String.valueOf(raw).trim().isEmpty() ? null : String.valueOf(raw).trim();
    }
 
    private static Object value(Map<String, Object> row, String model) {
        if (model == null) {
            return null;
        }
        Object direct = row.get(model);
        if (direct != null) {
            return direct;
        }
        for (Map.Entry<String, Object> entry : row.entrySet()) {
            if (entry.getKey() != null && model.equalsIgnoreCase(entry.getKey())) {
                return entry.getValue();
            }
        }
        return null;
    }
 
    static String display(Object raw) {
        if (raw == null || raw instanceof Map) {
            return null;
        }
        if (raw instanceof List) {
            List<String> parts = new ArrayList<>();
            for (Object item : (List<?>) raw) {
                if (item != null && !(item instanceof Map) && !String.valueOf(item).trim().isEmpty()) {
                    parts.add(String.valueOf(item).trim());
                }
            }
            return parts.isEmpty() ? null : String.join(",", parts);
        }
        String value = String.valueOf(raw).trim();
        return value.isEmpty() || "***".equals(value) ? null : value;
    }
 
    private static boolean sensitive(String model, Map<String, Object> config) {
        String name = model.toLowerCase(Locale.ROOT);
        String key = String.valueOf(config.get("jnpfKey")).toLowerCase(Locale.ROOT);
        return name.equals("biz_sign") || name.equals("bizsign") || name.equals("sign_id")
                || name.equals("signid") || name.endsWith("sign") || name.endsWith("signid")
                || name.contains("password") || name.contains("mima") || key.contains("password")
                || key.contains("signature");
    }
 
    @SuppressWarnings("unchecked")
    private static List<?> list(Object raw) {
        if (raw instanceof List) {
            return (List<?>) raw;
        }
        if (raw instanceof String && !((String) raw).trim().isEmpty()) {
            List<?> parsed = JsonUtil.getJsonToList((String) raw, Map.class);
            return parsed == null ? Collections.emptyList() : parsed;
        }
        return Collections.emptyList();
    }
}