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;
|
}
|
}
|