This commit is contained in:
root
2025-12-20 16:15:48 +05:00
parent 5c0f569fc2
commit f6c50cdab7
@@ -259,7 +259,6 @@ public class MarketingAnalysisService {
logger.info("Starting parallel JSON analysis generation");
// Создаем CompletableFuture для каждого типа анализа
@SuppressWarnings("unchecked")
CompletableFuture<Map<String, Object>> audienceFuture = (CompletableFuture<Map<String, Object>>) CompletableFuture
.<Map<String, Object>>supplyAsync(() -> {
logger.info("Starting audience analysis generation");
@@ -276,7 +275,6 @@ public class MarketingAnalysisService {
return new HashMap<>();
});
@SuppressWarnings("unchecked")
CompletableFuture<Map<String, Object>> competitorFuture = (CompletableFuture<Map<String, Object>>) CompletableFuture
.<Map<String, Object>>supplyAsync(() -> {
logger.info("Starting competitor analysis generation");
@@ -293,7 +291,6 @@ public class MarketingAnalysisService {
return new HashMap<>();
});
@SuppressWarnings("unchecked")
CompletableFuture<Map<String, Object>> seasonalityFuture = (CompletableFuture<Map<String, Object>>) CompletableFuture
.<Map<String, Object>>supplyAsync(() -> {
logger.info("Starting seasonality and market analysis generation");
@@ -310,7 +307,6 @@ public class MarketingAnalysisService {
return new HashMap<>();
});
@SuppressWarnings("unchecked")
CompletableFuture<Map<String, Object>> strategyFuture = (CompletableFuture<Map<String, Object>>) CompletableFuture
.<Map<String, Object>>supplyAsync(() -> {
logger.info("Starting strategy and funnel analysis generation");
@@ -1234,7 +1230,22 @@ public class MarketingAnalysisService {
// Новая структура: competitorAnalysis (marketShareChart, comparisonTable,
// competitorsDetails, swotCompetitors, etc.)
if (fullJson.containsKey("competitorAnalysis")) {
context.put("competitorAnalysis", fullJson.get("competitorAnalysis"));
Object competitorAnalysisObj = fullJson.get("competitorAnalysis");
context.put("competitorAnalysis", competitorAnalysisObj);
// Aliases для совместимости: плоские ключи для секции конкурентов
// (данные физически лежат в competitorAnalysis.*)
if (competitorAnalysisObj instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> competitorAnalysis = (Map<String, Object>) competitorAnalysisObj;
if (competitorAnalysis != null) {
if (competitorAnalysis.containsKey("marketShareChart")) {
context.put("marketShareChart", competitorAnalysis.get("marketShareChart"));
}
if (competitorAnalysis.containsKey("comparisonTable")) {
context.put("comparisonTable", competitorAnalysis.get("comparisonTable"));
}
}
}
} else {
// Backward compatibility (старая структура)
if (fullJson.containsKey("competitors")) {
@@ -1574,6 +1585,8 @@ public class MarketingAnalysisService {
"Детально проанализируй аудиторию на основе audienceAnalysis (segments, ageGroups, genderDistribution):\n");
promptBuilder.append(
"- Не просто опиши сегменты, а проанализируй данные графиков [[CHART_AGE_DISTRIBUTION]] и [[CHART_GENDER_DISTRIBUTION]].\n");
promptBuilder.append(
"- Обязательно вставь тег [[CHART_AGE_DISTRIBUTION]] после анализа возраста и [[CHART_GENDER_DISTRIBUTION]] после анализа пола. Опиши данные этих графиков.\n");
promptBuilder.append(
"- Объясни, почему именно эти группы принесут больше денег (через частоту, удержание, вероятность апсейла, LTV).\n");
promptBuilder.append(
@@ -1647,6 +1660,10 @@ public class MarketingAnalysisService {
promptBuilder.append("4. Данные: используй ТОЛЬКО данные из JSON, не выдумывай цифры\n");
promptBuilder.append(
"5. Это должен быть самый мощный раздел отчёта: каждое утверждение подтверждай цифрами из competitorAnalysis.marketShareChart / competitorAnalysis.comparisonTable.\n\n");
promptBuilder.append(
"КРИТИЧНО (ОБЯЗАТЕЛЬНЫЕ ТЕГИ): Ты ОБЯЗАН вставить тег [[CHART_MARKET_SHARE]] в начале раздела и [[TABLE_COMPARISON]] в середине. Без этих тегов отчет будет неполным.\n");
promptBuilder.append(
"КРИТИЧНО (ТАБЛИЦА): Опиши каждую строку сравнительной таблицы (каждый feature) и сделай практический вывод.\n\n");
promptBuilder.append("6. Сделай этот раздел самым длинным во всём отчёте.\n");
promptBuilder.append(
"7. Проведи детальный баттл: Наш бренд vs Конкурент А vs Конкурент B. Используй данные из [[TABLE_COMPARISON]].\n");
@@ -1667,13 +1684,13 @@ public class MarketingAnalysisService {
promptBuilder.append("- Рекомендации по дифференциации и конкурентным преимуществам\n\n");
promptBuilder.append("КРИТИЧНО - ВСТАВКА ГРАФИКА И ТАБЛИЦЫ:\n");
promptBuilder.append(
"1. После анализа долей рынка вставь плейсхолдер [[CHART_MARKET_SHARE]] на отдельной строке\n");
"1. В НАЧАЛЕ раздела (сразу после заголовка V. Анализ конкурентов) вставь плейсхолдер [[CHART_MARKET_SHARE]] на отдельной строке\n");
promptBuilder.append(
" - ПЕРЕД графиком: вводный абзац (2-3 предложения), начинающийся с: \"Анализ данных на графике ниже показывает...\"\n");
promptBuilder.append(
" - ПОСЛЕ графика: интерпретация (2-3 предложения), начинающаяся с: \"Из этих показателей следует, что...\"\n");
promptBuilder.append(
"2. Затем вставь плейсхолдер [[TABLE_COMPARISON]] на отдельной строке (это сравнительная таблица)\n");
"2. В СЕРЕДИНЕ раздела вставь плейсхолдер [[TABLE_COMPARISON]] на отдельной строке (это сравнительная таблица)\n");
promptBuilder.append(
" - ПЕРЕД таблицей: короткий ввод (1-2 предложения), что именно сравниваем\n");
promptBuilder.append(
@@ -3173,6 +3190,12 @@ public class MarketingAnalysisService {
placeholderMap.put("[[CHART_SEASONALITY]]", new ChartMapping("seasonality", "seasonality"));
placeholderMap.put("[[CHART_AUDIENCE]]", new ChartMapping("audienceSegmentation", "audienceSegmentation"));
placeholderMap.put("[[CHART_COMPETITORS]]", new ChartMapping("competitors", "competitors"));
// CRITICAL mapping (front-end expects exactly these keys in ```json:<key>
// blocks):
// [[CHART_MARKET_SHARE]] -> marketShareChart
// [[TABLE_COMPARISON]] -> comparisonTable
// [[CHART_AGE_DISTRIBUTION]] -> audienceAge
// [[CHART_GENDER_DISTRIBUTION]] -> audienceGender
placeholderMap.put("[[CHART_MARKET_SHARE]]", new ChartMapping("marketShareChart", "marketShareChart"));
placeholderMap.put("[[TABLE_COMPARISON]]", new ChartMapping("comparisonTable", "comparisonTable"));
placeholderMap.put("[[CHART_AGE_DISTRIBUTION]]", new ChartMapping("audienceAge", "audienceAge"));