diff --git a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java index 876a8c9..d3638cc 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java @@ -1824,17 +1824,17 @@ public class MarketingAnalysisService { Map competitorData = new HashMap<>(); competitorData.put("name", comp.getOrDefault("name", "Неизвестный конкурент")); + // Создаем вложенную структуру digitalMetrics @SuppressWarnings("unchecked") Map digitalMetrics = (Map) comp.get("digitalMetrics"); - if (digitalMetrics != null) { - competitorData.put("reach", digitalMetrics.getOrDefault("reach", 10000)); - competitorData.put("followers", digitalMetrics.getOrDefault("followers", 0)); - competitorData.put("activity", digitalMetrics.getOrDefault("activityIndex", 50)); - } else { - competitorData.put("reach", 10000); - competitorData.put("followers", 0); - competitorData.put("activity", 50); - } + Map metrics = new HashMap<>(); + metrics.put("reach", + digitalMetrics != null ? digitalMetrics.getOrDefault("reach", 10000) : 10000); + metrics.put("followers", + digitalMetrics != null ? digitalMetrics.getOrDefault("followers", 0) : 0); + metrics.put("activityIndex", + digitalMetrics != null ? digitalMetrics.getOrDefault("activityIndex", 50) : 50); + competitorData.put("digitalMetrics", metrics); competitorData.put("priceStrategy", comp.getOrDefault("priceStrategy", "Не указано")); competitorData.put("channelsHeatmap", comp.getOrDefault("channelsHeatmap", new HashMap<>())); @@ -2715,8 +2715,13 @@ public class MarketingAnalysisService { fullAnalysis != null ? fullAnalysis.length() : 0, chartsData != null ? chartsData.keySet() : "null"); - if (fullAnalysis == null || fullAnalysis.trim().isEmpty()) { - logger.warn("replaceChartPlaceholders: fullAnalysis is null or empty"); + if (fullAnalysis == null) { + logger.warn("replaceChartPlaceholders: fullAnalysis is null, returning empty string"); + return ""; + } + + if (fullAnalysis.trim().isEmpty()) { + logger.warn("replaceChartPlaceholders: fullAnalysis is empty"); return fullAnalysis; } @@ -2748,28 +2753,37 @@ public class MarketingAnalysisService { for (Map.Entry entry : placeholderMap.entrySet()) { String placeholder = entry.getKey(); ChartMapping mapping = entry.getValue(); + // Используем Pattern.quote, чтобы спецсимволы в плейсхолдере не ломали regex String regex = java.util.regex.Pattern.quote(placeholder); if (result.contains(placeholder)) { processedPlaceholders.add(placeholder); - Object chartData = chartsData.get(mapping.dataKey); + Object chartData = chartsData != null ? chartsData.get(mapping.dataKey) : null; if (!isEmptyChartData(chartData)) { try { String jsonStr = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(chartData); + // Используем Matcher.quoteReplacement для безопасной вставки JSON String jsonBlock = "\n```json:" + mapping.chartKey + "\n" + jsonStr + "\n```\n"; String replacement = java.util.regex.Matcher.quoteReplacement(jsonBlock); result = result.replaceAll(regex, replacement); - logger.info("Inserted chart data for placeholder: {}", placeholder); + logger.info("Successfully replaced placeholder: {} with data from key: {}", placeholder, + mapping.dataKey); } catch (JsonProcessingException e) { - logger.error("Failed to serialize data for placeholder {}: {}", placeholder, e.getMessage()); + logger.error("Error serializing data for placeholder {} (key: {}): {}", + placeholder, mapping.dataKey, e.getMessage(), e); // Удаляем плейсхолдер при ошибке сериализации result = result.replaceAll(regex, ""); + } catch (Exception e) { + logger.error("Unexpected error processing placeholder {} (key: {}): {}", + placeholder, mapping.dataKey, e.getMessage(), e); + // Удаляем плейсхолдер при неожиданной ошибке + result = result.replaceAll(regex, ""); } } else { - // ВОТ ЗДЕСЬ ВАЖНЫЙ ЛОГ - когда данных нет - logger.warn("MISSING_CHART: No data found for placeholder {} (key: {})", + logger.warn("MISSING DATA for placeholder: {} (key: {}). Removing placeholder.", placeholder, mapping.dataKey); + // Если данных нет, удаляем плейсхолдер, чтобы не светить им пользователю result = result.replaceAll(regex, ""); } }