lc/tqq9/lc123/cloud/app/api/utils/GyDeliverySyncMappingUtil.java

124 lines
4.4 KiB
Java
Raw Normal View History

package tqq9.lc123.cloud.app.api.utils;
import com.fasterxml.jackson.databind.JsonNode;
import tqq9.lc123.cloud.app.api.utils.mapping.GyDeliveryMapping;
import java.util.*;
/**
* delivery 节点全部拍扁
*/
public final class GyDeliverySyncMappingUtil {
/* 1. 缓存key = 全路径value = 值或List<Map> */
private static final Map<String, Object> CACHE = new HashMap<>();
/* 2. 入口 */
public static void parse(JsonNode delivery) {
CACHE.clear();
flatten(null, delivery);
}
/* 3. 统一取值 */
public static Object get(String outerKey) {
String path = GyDeliveryMapping.FIELD_MAP.get(outerKey);
if (path == null) return null;
/* 3.1 整段数组或对象 */
if (isWholeBlock(path)) return CACHE.get(path);
/* 3.2 数组模板details[].field 或 details[1].field */
if (path.contains("[") && path.contains("].")) {
return handleArrayTemplate(path);
}
/* 3.3 普通根字段 */
return CACHE.get(path);
}
/* 4. 拍扁:对象展开;数组既存整段,又明细到 CACHE */
private static void flatten(String parent, JsonNode node) {
if (node.isObject()) {
Iterator<Map.Entry<String, JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> e = it.next();
flatten(join(parent, e.getKey()), e.getValue());
}
} else if (node.isArray()) {
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < node.size(); i++) {
JsonNode child = node.get(i);
Map<String, Object> row = new LinkedHashMap<>();
Iterator<Map.Entry<String, JsonNode>> it = child.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> f = it.next();
String key = f.getKey();
Object val = convert(f.getValue());
row.put(key, val);
/* 字段别名item_code -> material */
String alias = GyDeliveryMapping.ALIAS_MAP.get(key);
if (alias != null) row.put(alias, val);
}
list.add(row);
/* 明细拍扁details[0].xxx */
String idxKey = parent + "[" + i + "]";
for (Map.Entry<String, Object> entry : row.entrySet()) {
CACHE.put(idxKey + "." + entry.getKey(), entry.getValue());
}
}
CACHE.put(parent, list); // 整段也保留
} else {
CACHE.put(parent, convert(node));
}
}
/* 5. 数组模板处理 */
private static Object handleArrayTemplate(String path) {
int dot = path.indexOf("].");
String listPart = path.substring(0, dot + 1);
String field = path.substring(dot + 2);
String listKey = listPart.substring(0, listPart.indexOf("["));
Object block = CACHE.get(listKey);
if (!(block instanceof List)) return null;
List<Map<String, Object>> list = (List<Map<String, Object>>) block;
String idxPart = listPart.substring(listPart.indexOf("[") + 1, listPart.length() - 1);
/* 5.1 通配details[].field */
if (idxPart.isEmpty()) {
List<Object> res = new ArrayList<>(list.size());
for (Map<String, Object> row : list) {
res.add(row.get(field));
}
return res;
}
/* 5.2 单条details[1].field */
int i = Integer.parseInt(idxPart);
return i < 0 || i >= list.size() ? null : list.get(i).get(field);
}
/* 6. 工具方法 */
private static boolean isWholeBlock(String path) {
return path.equals("details") || path.equals("payments")
|| path.equals("invoices") || path.equals("tags")
|| path.equals("stock_location")
|| path.equals("delivery_statusInfo")
|| path.equals("store_info");
}
private static String join(String parent, String key) {
return parent == null ? key : parent + "." + key;
}
private static Object convert(JsonNode n) {
if (n.isTextual()) return n.asText();
if (n.isNumber()) return n.isFloatingPointNumber() ? n.asDouble() : n.asLong();
if (n.isBoolean()) return n.asBoolean();
return n.asText();
}
}