|
|
@@ -32,7 +32,8 @@ public class TjfxAnalysisDataServiceImpl implements TjfxAnalysisDataService { |
|
|
|
// 调用数据访问层方法获取原始数据 |
|
|
|
List<Map<String, Object>> rows = tjfxAnalysisDataMapper.select(tjfxAnalysisDataDTO); |
|
|
|
// 对获取的数据进行聚合处理后返回 |
|
|
|
return aggregate(rows); |
|
|
|
List<Map<String, Object>> aggregate = aggregate(rows); |
|
|
|
return aggregate; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -365,70 +366,7 @@ public class TjfxAnalysisDataServiceImpl implements TjfxAnalysisDataService { |
|
|
|
return s == null ? "" : s.trim(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 解析categorySpecs字符串,支持单个JSON对象或多个JSON对象拼接的情况 |
|
|
|
* |
|
|
|
* @param categorySpecs 规格字符串,可能是单个JSON或多个JSON拼接 |
|
|
|
* @param objectMapper Jackson ObjectMapper实例 |
|
|
|
* @return 合并后的规格Map |
|
|
|
* @throws Exception 解析异常 |
|
|
|
*/ |
|
|
|
private static Map<String, List<String>> parseCategorySpecs(String categorySpecs, ObjectMapper objectMapper) throws Exception { |
|
|
|
Map<String, List<String>> result = new LinkedHashMap<>(); |
|
|
|
|
|
|
|
if (categorySpecs == null || categorySpecs.trim().isEmpty()) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
String trimmed = categorySpecs.trim(); |
|
|
|
|
|
|
|
// 尝试直接解析为单个JSON对象 |
|
|
|
try { |
|
|
|
Map<String, List<String>> singleResult = objectMapper.readValue(trimmed, |
|
|
|
new com.fasterxml.jackson.core.type.TypeReference<Map<String, List<String>>>() { |
|
|
|
}); |
|
|
|
return singleResult; |
|
|
|
} catch (Exception e) { |
|
|
|
// 如果单个JSON解析失败,尝试解析多个JSON对象拼接的情况 |
|
|
|
log.debug("单个JSON解析失败,尝试解析多个JSON对象拼接: {}", e.getMessage()); |
|
|
|
} |
|
|
|
|
|
|
|
// 处理多个JSON对象拼接的情况 |
|
|
|
// 使用正则表达式分割JSON对象 |
|
|
|
// 匹配 { ... } 模式,但需要处理嵌套的大括号 |
|
|
|
List<String> jsonObjects = splitJsonObjects(trimmed); |
|
|
|
|
|
|
|
for (String jsonStr : jsonObjects) { |
|
|
|
if (jsonStr.trim().isEmpty()) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
Map<String, List<String>> jsonMap = objectMapper.readValue(jsonStr.trim(), |
|
|
|
new com.fasterxml.jackson.core.type.TypeReference<Map<String, List<String>>>() { |
|
|
|
}); |
|
|
|
|
|
|
|
// 合并到结果中 |
|
|
|
for (Map.Entry<String, List<String>> entry : jsonMap.entrySet()) { |
|
|
|
String key = entry.getKey(); |
|
|
|
List<String> values = entry.getValue(); |
|
|
|
|
|
|
|
if (result.containsKey(key)) { |
|
|
|
// 如果键已存在,合并值列表并去重 |
|
|
|
Set<String> uniqueValues = new LinkedHashSet<>(result.get(key)); |
|
|
|
uniqueValues.addAll(values); |
|
|
|
result.put(key, new ArrayList<>(uniqueValues)); |
|
|
|
} else { |
|
|
|
result.put(key, new ArrayList<>(values)); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
log.warn("解析JSON对象失败: {}", jsonStr, e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 分割多个JSON对象拼接的字符串 |
|
|
@@ -436,36 +374,6 @@ public class TjfxAnalysisDataServiceImpl implements TjfxAnalysisDataService { |
|
|
|
* @param jsonString 包含多个JSON对象的字符串 |
|
|
|
* @return JSON对象列表 |
|
|
|
*/ |
|
|
|
private static List<String> splitJsonObjects(String jsonString) { |
|
|
|
List<String> result = new ArrayList<>(); |
|
|
|
if (jsonString == null || jsonString.trim().isEmpty()) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
int braceCount = 0; |
|
|
|
int start = -1; |
|
|
|
|
|
|
|
for (int i = 0; i < jsonString.length(); i++) { |
|
|
|
char c = jsonString.charAt(i); |
|
|
|
|
|
|
|
if (c == '{') { |
|
|
|
if (braceCount == 0) { |
|
|
|
start = i; // 记录JSON对象开始位置 |
|
|
|
} |
|
|
|
braceCount++; |
|
|
|
} else if (c == '}') { |
|
|
|
braceCount--; |
|
|
|
if (braceCount == 0 && start != -1) { |
|
|
|
// 找到一个完整的JSON对象 |
|
|
|
String jsonObj = jsonString.substring(start, i + 1); |
|
|
|
result.add(jsonObj); |
|
|
|
start = -1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 按规格分组处理数据,返回按category_specs字段中所有key分组的Map结构 |
|
|
@@ -589,35 +497,36 @@ public class TjfxAnalysisDataServiceImpl implements TjfxAnalysisDataService { |
|
|
|
|
|
|
|
// 处理规格信息 |
|
|
|
String specs = (String) record.get("category_specs"); |
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
Map<String, String> specsMap = mapper.readValue(specs, new com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() { |
|
|
|
}); |
|
|
|
for (Map.Entry<String, String> courseEntry : specsMap.entrySet()) { |
|
|
|
categorySet.computeIfAbsent(courseEntry.getKey(), k -> new HashSet<>()) |
|
|
|
.add(courseEntry.getValue()); |
|
|
|
if (specs != null && !specs.isEmpty()) { |
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
Map<String, String> specsMap = mapper.readValue(specs, new com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() { |
|
|
|
}); |
|
|
|
for (Map.Entry<String, String> courseEntry : specsMap.entrySet()) { |
|
|
|
categorySet.computeIfAbsent(courseEntry.getKey(), k -> new HashSet<>()) |
|
|
|
.add(courseEntry.getValue()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 排序并转回 List<String> |
|
|
|
Map<String, List<String>> categorySets = new LinkedHashMap<>(); |
|
|
|
for (Map.Entry<String, Set<String>> courseEntry : categorySet.entrySet()) { |
|
|
|
List<String> sortedScores = new ArrayList<>(courseEntry.getValue()); |
|
|
|
Collections.sort(sortedScores); // 升序 |
|
|
|
List<String> scoresStr = sortedScores.stream() |
|
|
|
.map(String::valueOf) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
categorySets.put(courseEntry.getKey(), scoresStr); |
|
|
|
} |
|
|
|
// 排序并转回 List<String> |
|
|
|
Map<String, List<String>> categorySets = new LinkedHashMap<>(); |
|
|
|
for (Map.Entry<String, Set<String>> courseEntry : categorySet.entrySet()) { |
|
|
|
List<String> sortedScores = new ArrayList<>(courseEntry.getValue()); |
|
|
|
Collections.sort(sortedScores); // 升序 |
|
|
|
List<String> scoresStr = sortedScores.stream() |
|
|
|
.map(String::valueOf) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
categorySets.put(courseEntry.getKey(), scoresStr); |
|
|
|
} |
|
|
|
|
|
|
|
// 组装聚合结果 |
|
|
|
aggregated.put("brand", new ArrayList<>(brandNames)); |
|
|
|
aggregated.put("shop_name", new ArrayList<>(shopNames)); |
|
|
|
aggregated.put("customer_name", new ArrayList<>(customerNames)); |
|
|
|
aggregated.putAll(categorySets); |
|
|
|
// 组装聚合结果 |
|
|
|
aggregated.put("brand", new ArrayList<>(brandNames)); |
|
|
|
aggregated.put("shop_name", new ArrayList<>(shopNames)); |
|
|
|
aggregated.put("customer_name", new ArrayList<>(customerNames)); |
|
|
|
aggregated.putAll(categorySets); |
|
|
|
|
|
|
|
result.add(aggregated); |
|
|
|
result.add(aggregated); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
} |