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

124 lines
4.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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