刘光辉
4 小时以前 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
package jnpf.flowable.service.dev;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jnpf.flowable.model.templatenode.nodejson.NodeModel;
import jnpf.permission.entity.UserEntity;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
 
/** Test data only, derived from the published native component schema. Existing values are preserved. */
public final class DevApprovalFill {
    private DevApprovalFill() {}
 
    public static List<String> fill(NodeModel node, String formJson, Map<String, Object> data,
                                    UserEntity signer, String signId) {
        return fill(node, formJson, data, signer, signId, type -> null);
    }
 
    public static List<String> fill(NodeModel node, String formJson, Map<String, Object> data,
                                    UserEntity signer, String signId, Function<String, JSONArray> dictionaries) {
        List<String> problems = new ArrayList<>();
        Map<String, JSONObject> fields = new LinkedHashMap<>();
        JSONObject form = formJson == null ? null : JSON.parseObject(formJson);
        if (form != null) index(form.getJSONArray("fields"), "", fields);
        if (node.getFormOperates() == null) return problems;
        for (Map<String, Object> permission : node.getFormOperates()) {
            if (!Boolean.TRUE.equals(permission.get("required"))) continue;
            String path = String.valueOf(permission.get("id"));
            String label = String.valueOf(permission.getOrDefault("name", path)).replace('\n', ' ');
            JSONObject field = fields.get(path);
            if (field != null && "dictionary".equals(field.getJSONObject("__config__").getString("dataType"))) {
                JSONObject config = field.getJSONObject("__config__");
                field.put("options", dictionaries.apply(config.getString("dictionaryType")));
                config.put("dataType", "static");
            }
            int separator = path.indexOf('-');
            if (separator < 0) fillOne(data, path, field, signer, signId, label, problems);
            else {
                Object rows = data.get(path.substring(0, separator));
                if (rows instanceof String && ((String) rows).trim().startsWith("[")) {
                    rows = JSON.parseArray((String) rows);
                    data.put(path.substring(0, separator), rows);
                }
                // Native child-field required rules validate existing rows; they do not require creating a business row.
                if (rows instanceof List) {
                    int rowIndex = 0;
                    for (Object row : (List<?>) rows) {
                        rowIndex++;
                        if (row instanceof Map) fillOne((Map<String, Object>) row, path.substring(separator + 1), field,
                                signer, signId, label + "(第" + rowIndex + "行)", problems);
                    }
                }
            }
        }
        return problems;
    }
 
    private static void index(JSONArray items, String prefix, Map<String, JSONObject> fields) {
        if (items == null) return;
        for (Object raw : items) {
            if (!(raw instanceof JSONObject)) continue;
            JSONObject field = (JSONObject) raw;
            JSONObject config = field.getJSONObject("__config__");
            if (config == null) continue;
            String id = field.getString("__vModel__");
            if (id != null) fields.put(prefix + id, field);
            index(config.getJSONArray("children"), "table".equals(config.getString("jnpfKey")) ? id + "-" : prefix, fields);
        }
    }
 
    private static void fillOne(Map<String, Object> data, String id, JSONObject field, UserEntity signer,
                                String signId, String label, List<String> problems) {
        if (!DevApprovalValidation.empty(data.get(id))) return;
        Object value = value(field, signer, signId);
        if (DevApprovalValidation.empty(value)) problems.add("必填项无法自动补齐:" + label + "(" + id + "),请先填写有效数据");
        else data.put(id, value);
    }
 
    static Object value(JSONObject field, UserEntity signer, String signId) {
        if (field == null) return null;
        JSONObject config = field.getJSONObject("__config__");
        String key = config.getString("jnpfKey");
        if ("biz_sign".equals(field.getString("__vModel__"))) return signId;
        boolean multiple = field.getBooleanValue("multiple");
        switch (key == null ? "" : key) {
            case "input": case "textarea": case "editor":
                return field.getString("__vModel__").endsWith("_id") ? null : "已输入";
            case "inputNumber": case "slider": case "rate":
                Number minimum = field.getBigDecimal("min");
                return minimum == null ? 0 : minimum;
            case "switch": return field.containsKey("activeValue") ? field.get("activeValue") : 1;
            case "datePicker": return System.currentTimeMillis();
            case "timePicker": return LocalTime.now().format(DateTimeFormatter.ofPattern(
                    "HH:mm".equals(field.getString("format")) ? "HH:mm" : "HH:mm:ss"));
            case "dateRange": return List.of(System.currentTimeMillis(), System.currentTimeMillis());
            case "userSelect": return selection(signer == null ? null : signer.getId(), multiple);
            case "organizeSelect": case "depSelect": return selection(signer == null ? null : signer.getOrganizeId(), multiple);
            case "posSelect":
                String positions = signer == null ? null : signer.getPositionId();
                return selection(positions == null ? null : positions.split(",")[0], multiple);
            case "select": case "radio": case "checkbox":
                // Do not invent IDs for dictionaries, remote options or related business records.
                if (config.containsKey("dataType") && !"static".equals(config.getString("dataType"))) return null;
                JSONObject slot = field.getJSONObject("__slot__");
                JSONArray options = slot == null ? field.getJSONArray("options") : slot.getJSONArray("options");
                JSONObject props = field.getJSONObject("props");
                String valueKey = props == null ? "id" : props.getString("value");
                if (valueKey == null) valueKey = "id";
                if (options != null) for (Object option : options) {
                    if (!(option instanceof JSONObject)) continue;
                    JSONObject item = (JSONObject) option;
                    if (item.getBooleanValue("disabled")) continue;
                    Object result = item.get(valueKey);
                    if (result != null) return multiple || "checkbox".equals(key) ? List.of(result) : result;
                }
                return null;
            default: return null;
        }
    }
 
    private static Object selection(String id, boolean multiple) {
        return id == null || id.isBlank() ? null : multiple ? List.of(id) : id;
    }
}