package jnpf.onlinedev.util; import jnpf.model.visualjson.FieLdsModel; import jnpf.util.JsonUtil; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * 非持久化字段过滤。原始配置用于识别展示/虚拟属性,字段模型用于阻止相关字段参与 SQL。 */ public final class DisplayOnlyFieldUtils { private static final String CONFIG = "__config__"; private static final String CHILDREN = "children"; private static final String DISPLAY_ONLY = "isDisplayOnly"; private static final String VIRTUAL_FIELD = "isVirtualField"; private static final String CONTROL_KEY = "controlKey"; private static final String JNPF_KEY = "jnpfKey"; private static final String TABLE = "table"; private static final String V_MODEL = "__vModel__"; private DisplayOnlyFieldUtils() { } public static void filter(String fieldsJson, List fields, Map data) { if (fieldsJson == null || fieldsJson.isEmpty()) { return; } filterFields(JsonUtil.getJsonToListMap(fieldsJson), fields, data, true); } /** * 查询列表、编辑和详情数据前移除虚拟字段模型,展示字段仍需正常查询回显。 */ public static void filterVirtualFields(String fieldsJson, List fields) { if (fieldsJson == null || fieldsJson.isEmpty()) { return; } filterFields(JsonUtil.getJsonToListMap(fieldsJson), fields, null, false); } /** * 生成不含虚拟字段的表单配置副本,供编辑查询等基础模块解析使用。 */ public static String filterVirtualFormData(String formDataJson) { if (formDataJson == null || formDataJson.isEmpty()) { return formDataJson; } Map formData = JsonUtil.stringToMap(formDataJson); Object fieldsValue = formData.get("fields"); List> fields = fieldsValue instanceof String ? JsonUtil.getJsonToListMap((String) fieldsValue) : asMapList(fieldsValue); removeVirtualRawFields(fields); formData.put("fields", fieldsValue instanceof String ? JsonUtil.getObjectToString(fields) : fields); return JsonUtil.getObjectToString(formData); } /** * 从列表查询字段中移除虚拟字段,避免列表配置残留时将 controlKey 当成数据库列。 */ public static void filterVirtualFieldKeys(String fieldsJson, Collection fieldKeys) { if (fieldsJson == null || fieldsJson.isEmpty() || fieldKeys == null || fieldKeys.isEmpty()) { return; } Set virtualKeys = new HashSet<>(); collectVirtualFieldKeys(JsonUtil.getJsonToListMap(fieldsJson), null, false, virtualKeys); fieldKeys.removeIf(virtualKeys::contains); } public static boolean isVirtualFieldKey(String fieldsJson, String fieldKey) { if (fieldsJson == null || fieldsJson.isEmpty() || fieldKey == null || fieldKey.isEmpty()) { return false; } Set virtualKeys = new HashSet<>(); collectVirtualFieldKeys(JsonUtil.getJsonToListMap(fieldsJson), null, false, virtualKeys); return virtualKeys.contains(fieldKey); } private static void collectVirtualFieldKeys(List> fields, String parentKey, boolean parentVirtual, Set virtualKeys) { for (Map field : fields) { Map config = asMap(field.get(CONFIG)); if (config == null) { continue; } String vModel = asString(field.get(V_MODEL)); String controlKey = asString(field.get(CONTROL_KEY)); String fieldKey = controlKey != null ? controlKey : vModel; boolean virtualField = parentVirtual || Boolean.TRUE.equals(config.get(VIRTUAL_FIELD)); if (virtualField) { addVirtualKey(virtualKeys, parentKey, vModel); addVirtualKey(virtualKeys, parentKey, controlKey); } String childParentKey = fieldKey != null ? fieldKey : parentKey; collectVirtualFieldKeys(asMapList(config.get(CHILDREN)), childParentKey, virtualField, virtualKeys); } } private static void addVirtualKey(Set virtualKeys, String parentKey, String fieldKey) { if (fieldKey == null) { return; } virtualKeys.add(fieldKey); if (parentKey != null) { virtualKeys.add(parentKey + "-" + fieldKey); virtualKeys.add(parentKey + "." + fieldKey); } } private static void removeVirtualRawFields(List> fields) { if (fields == null || fields.isEmpty()) { return; } fields.removeIf(field -> { Map config = asMap(field.get(CONFIG)); return config != null && Boolean.TRUE.equals(config.get(VIRTUAL_FIELD)); }); for (Map field : fields) { Map config = asMap(field.get(CONFIG)); if (config == null) { continue; } List> children = asMapList(config.get(CHILDREN)); removeVirtualRawFields(children); config.put(CHILDREN, children); } } private static void filterFields(List> rawFields, List fields, Map data, boolean filterDisplayOnly) { if (rawFields == null || rawFields.isEmpty()) { return; } for (Map rawField : rawFields) { Map config = asMap(rawField.get(CONFIG)); if (config == null) { continue; } String vModel = asString(rawField.get(V_MODEL)); String controlKey = asString(rawField.get(CONTROL_KEY)); FieLdsModel modelField = findModelField(rawField, config, fields); boolean virtualField = Boolean.TRUE.equals(config.get(VIRTUAL_FIELD)); boolean displayOnly = Boolean.TRUE.equals(config.get(DISPLAY_ONLY)); if (virtualField || (filterDisplayOnly && displayOnly)) { if (data != null) { if (vModel != null) { data.remove(vModel); } if (controlKey != null) { data.remove(controlKey); } } if (fields != null && modelField != null) { fields.remove(modelField); } continue; } List> rawChildren = asMapList(config.get(CHILDREN)); if (rawChildren.isEmpty()) { continue; } List modelChildren = modelField != null && modelField.getConfig() != null ? modelField.getConfig().getChildren() : null; if (TABLE.equals(asString(config.get(JNPF_KEY))) && vModel != null) { filterFields(rawChildren, modelChildren, null, filterDisplayOnly); if (data != null && data.get(vModel) instanceof List) { for (Object row : (List) data.get(vModel)) { Map rowMap = asMap(row); if (rowMap != null) { filterFields(rawChildren, null, rowMap, filterDisplayOnly); } } } } else { filterFields(rawChildren, modelChildren, data, filterDisplayOnly); } } } private static FieLdsModel findModelField(Map rawField, Map config, List fields) { if (fields == null || fields.isEmpty()) { return null; } String vModel = asString(rawField.get(V_MODEL)); String formId = asString(config.get("formId")); String id = asString(rawField.get("id")); for (FieLdsModel field : fields) { if (vModel != null && Objects.equals(vModel, field.getVModel())) { return field; } if (formId != null && field.getConfig() != null && Objects.equals(formId, field.getConfig().getFormId())) { return field; } if (id != null && Objects.equals(id, field.getId())) { return field; } } return null; } @SuppressWarnings("unchecked") private static Map asMap(Object value) { return value instanceof Map ? (Map) value : null; } private static List> asMapList(Object value) { List> result = new ArrayList<>(); if (!(value instanceof List)) { return result; } for (Object item : (List) value) { Map map = asMap(item); if (map != null) { result.add(map); } } return result; } private static String asString(Object value) { if (value == null) { return null; } String text = String.valueOf(value); return text.isEmpty() ? null : text; } }