124 lines
4.4 KiB
Java
124 lines
4.4 KiB
Java
|
|
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();
|
|||
|
|
}
|
|||
|
|
}
|