From 0b75ef34c3e5873cb69da49534bc1ec5eb9faff9 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 14 Dec 2025 20:56:04 +0500 Subject: [PATCH] . --- .../service/MarketingAnalysisService.java | 362 +++++++++++++++--- 1 file changed, 317 insertions(+), 45 deletions(-) diff --git a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java index 12e026a..9db12db 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java @@ -711,7 +711,7 @@ public class MarketingAnalysisService { } /** - * Глубокая генерация текстового отчёта на основе JSON (4 этапа) + * Генерация текстового отчёта на основе JSON (простое объединение без AI-суммирования) */ private String generateDeepTextReport(Map analysisJson) { if (analysisJson == null || analysisJson.isEmpty()) { @@ -720,69 +720,341 @@ public class MarketingAnalysisService { } try { - // Преобразование JSON в строку для контекста - String jsonContext = objectMapper.writeValueAsString(analysisJson); - - // Генерация всех 4 этапов последовательно - String stage1 = generateStage1MarketAndProduct(jsonContext); - String stage2 = generateStage2AudienceAndCompetitors(jsonContext); - String stage3 = generateStage3StrategyAndFunnel(jsonContext); - String stage4 = generateStage4RecommendationsAndContent(jsonContext); - - // Склеивание всех частей с двойными переносами строк StringBuilder fullReport = new StringBuilder(); - if (stage1 != null && !stage1.trim().isEmpty()) { - fullReport.append(stage1.trim()); + // I. Краткое резюме + fullReport.append("I. Краткое резюме\n\n"); + fullReport.append("Данный маркетинговый анализ содержит детальную информацию о бизнесе, " + + "целевой аудитории, конкурентах, рыночной ситуации и рекомендациях по продвижению.\n\n"); + + // II. Анализ продукта + fullReport.append("II. Анализ продукта\n\n"); + if (analysisJson.containsKey("product") || analysisJson.containsKey("businessNiche")) { + Object product = analysisJson.get("product"); + Object niche = analysisJson.get("businessNiche"); + if (product != null || niche != null) { + fullReport.append("Продукт/услуга: ").append(product != null ? product : "").append("\n"); + fullReport.append("Ниша бизнеса: ").append(niche != null ? niche : "").append("\n\n"); + } } else { - fullReport.append("I. Краткое резюме\n\nII. Анализ продукта\n\nIII. Анализ рынка и сезонности\n\n"); - logger.warn("Stage 1 generation returned empty result"); + fullReport.append("Информация о продукте доступна в детальном JSON-анализе.\n\n"); } - if (stage2 != null && !stage2.trim().isEmpty()) { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + // III. Анализ рынка и сезонности + fullReport.append("III. Анализ рынка и сезонности\n\n"); + @SuppressWarnings("unchecked") + Map seasonality = (Map) analysisJson.get("seasonality"); + @SuppressWarnings("unchecked") + Map market = (Map) analysisJson.get("market"); + + if (seasonality != null) { + Object description = seasonality.get("description"); + if (description != null) { + fullReport.append(description).append("\n\n"); } - fullReport.append(stage2.trim()); - } else { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + fullReport.append("[[CHART_SEASONALITY]]\n\n"); + } + + if (market != null) { + Object marketSize = market.get("marketSize"); + Object growthRate = market.get("growthRate"); + if (marketSize != null) { + fullReport.append("Объем рынка: ").append(marketSize).append("\n"); } - fullReport.append("IV. Анализ целевой аудитории\n\nV. Анализ конкурентов\n\n"); - logger.warn("Stage 2 generation returned empty result"); + if (growthRate != null) { + fullReport.append("Темп роста: ").append(growthRate).append("\n"); + } + @SuppressWarnings("unchecked") + List trends = (List) market.get("trends"); + if (trends != null && !trends.isEmpty()) { + fullReport.append("\nТренды рынка:\n"); + for (String trend : trends) { + fullReport.append("- ").append(trend).append("\n"); + } + } + @SuppressWarnings("unchecked") + List opportunities = (List) market.get("opportunities"); + if (opportunities != null && !opportunities.isEmpty()) { + fullReport.append("\nВозможности:\n"); + for (String opp : opportunities) { + fullReport.append("- ").append(opp).append("\n"); + } + } + @SuppressWarnings("unchecked") + List threats = (List) market.get("threats"); + if (threats != null && !threats.isEmpty()) { + fullReport.append("\nУгрозы:\n"); + for (String threat : threats) { + fullReport.append("- ").append(threat).append("\n"); + } + } + } + fullReport.append("\n"); + + // IV. Анализ целевой аудитории + fullReport.append("IV. Анализ целевой аудитории\n\n"); + @SuppressWarnings("unchecked") + Map audienceAnalysis = (Map) analysisJson.get("audienceAnalysis"); + if (audienceAnalysis != null) { + @SuppressWarnings("unchecked") + List> segments = (List>) audienceAnalysis.get("segments"); + if (segments != null && !segments.isEmpty()) { + for (Map segment : segments) { + Object name = segment.get("name"); + Object sharePercent = segment.get("sharePercent"); + Object ageRange = segment.get("ageRange"); + Object motivation = segment.get("motivation"); + Object triggers = segment.get("triggers"); + Object barriers = segment.get("barriers"); + + if (name != null) { + fullReport.append("### Сегмент: ").append(name); + if (sharePercent != null) { + fullReport.append(" (").append(sharePercent).append("%)\n"); + } else { + fullReport.append("\n"); + } + } + if (ageRange != null) { + fullReport.append("Возраст: ").append(ageRange).append("\n"); + } + if (motivation != null) { + fullReport.append("\nМотивация:\n").append(motivation).append("\n"); + } + if (triggers != null) { + fullReport.append("\nТриггеры:\n").append(triggers).append("\n"); + } + if (barriers != null) { + fullReport.append("\nБарьеры:\n").append(barriers).append("\n"); + } + fullReport.append("\n"); + } + } + fullReport.append("[[CHART_AUDIENCE]]\n\n"); } - if (stage3 != null && !stage3.trim().isEmpty()) { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + // V. Анализ конкурентов + fullReport.append("V. Анализ конкурентов\n\n"); + @SuppressWarnings("unchecked") + Map competitorAnalysis = (Map) analysisJson.get("competitorAnalysis"); + if (competitorAnalysis != null) { + Object marketShareComment = competitorAnalysis.get("marketShareComment"); + if (marketShareComment != null) { + fullReport.append(marketShareComment).append("\n\n"); } - fullReport.append(stage3.trim()); - } else { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + + @SuppressWarnings("unchecked") + List> competitorsDetails = (List>) competitorAnalysis.get("competitorsDetails"); + if (competitorsDetails != null && !competitorsDetails.isEmpty()) { + for (Map competitor : competitorsDetails) { + Object compName = competitor.get("name"); + Object priceStrategy = competitor.get("priceStrategy"); + Object contentStrategy = competitor.get("contentStrategy"); + @SuppressWarnings("unchecked") + Map swot = (Map) competitor.get("swot"); + + if (compName != null) { + fullReport.append("### ").append(compName).append("\n"); + } + if (priceStrategy != null) { + fullReport.append("Ценовая стратегия: ").append(priceStrategy).append("\n"); + } + if (contentStrategy != null) { + fullReport.append("\nКонтент-стратегия:\n").append(contentStrategy).append("\n"); + } + if (swot != null) { + @SuppressWarnings("unchecked") + List strengths = (List) swot.get("strengths"); + @SuppressWarnings("unchecked") + List weaknesses = (List) swot.get("weaknesses"); + if (strengths != null && !strengths.isEmpty()) { + fullReport.append("\nСильные стороны:\n"); + for (String strength : strengths) { + fullReport.append("- ").append(strength).append("\n"); + } + } + if (weaknesses != null && !weaknesses.isEmpty()) { + fullReport.append("\nСлабые стороны:\n"); + for (String weakness : weaknesses) { + fullReport.append("- ").append(weakness).append("\n"); + } + } + } + fullReport.append("\n"); + } } - fullReport.append( - "VI. SWOT-анализ\n\nVII. Каналы продвижения и их потенциал\n\nVIII. Воронка спроса\n\n"); - logger.warn("Stage 3 generation returned empty result"); + fullReport.append("[[CHART_COMPETITORS]]\n\n"); } - if (stage4 != null && !stage4.trim().isEmpty()) { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + // VI. SWOT-анализ + fullReport.append("VI. SWOT-анализ\n\n"); + @SuppressWarnings("unchecked") + Map swot = (Map) analysisJson.get("swot"); + if (swot != null) { + @SuppressWarnings("unchecked") + List strengths = (List) swot.get("strengths"); + @SuppressWarnings("unchecked") + List weaknesses = (List) swot.get("weaknesses"); + @SuppressWarnings("unchecked") + List opportunities = (List) swot.get("opportunities"); + @SuppressWarnings("unchecked") + List threats = (List) swot.get("threats"); + + if (strengths != null && !strengths.isEmpty()) { + fullReport.append("Сильные стороны:\n"); + for (String strength : strengths) { + fullReport.append("- ").append(strength).append("\n"); + } + fullReport.append("\n"); } - fullReport.append(stage4.trim()); - } else { - if (fullReport.length() > 0) { - fullReport.append("\n\n"); + if (weaknesses != null && !weaknesses.isEmpty()) { + fullReport.append("Слабые стороны:\n"); + for (String weakness : weaknesses) { + fullReport.append("- ").append(weakness).append("\n"); + } + fullReport.append("\n"); } - fullReport.append( - "IX. Рекомендации по позиционированию и УТП\n\nX. Рекомендации по контенту\n\nXI. Итоговая стратегия: что делать в первую очередь\n\n"); - logger.warn("Stage 4 generation returned empty result"); + if (opportunities != null && !opportunities.isEmpty()) { + fullReport.append("Возможности:\n"); + for (String opp : opportunities) { + fullReport.append("- ").append(opp).append("\n"); + } + fullReport.append("\n"); + } + if (threats != null && !threats.isEmpty()) { + fullReport.append("Угрозы:\n"); + for (String threat : threats) { + fullReport.append("- ").append(threat).append("\n"); + } + fullReport.append("\n"); + } + } + fullReport.append("[[CHART_SWOT]]\n\n"); + + // VII. Каналы продвижения + fullReport.append("VII. Каналы продвижения и их потенциал\n\n"); + @SuppressWarnings("unchecked") + Map channels = (Map) analysisJson.get("channels"); + if (channels != null) { + @SuppressWarnings("unchecked") + List> channelList = (List>) channels.get("recommended"); + if (channelList != null && !channelList.isEmpty()) { + for (Map channel : channelList) { + Object name = channel.get("name"); + Object potential = channel.get("potential"); + Object description = channel.get("description"); + if (name != null) { + fullReport.append("### ").append(name).append("\n"); + } + if (potential != null) { + fullReport.append("Потенциал: ").append(potential).append("\n"); + } + if (description != null) { + fullReport.append(description).append("\n"); + } + fullReport.append("\n"); + } + } + } + fullReport.append("[[CHART_CHANNELS]]\n\n"); + + // VIII. Воронка спроса + fullReport.append("VIII. Воронка спроса\n\n"); + @SuppressWarnings("unchecked") + Map funnel = (Map) analysisJson.get("funnel"); + if (funnel != null) { + @SuppressWarnings("unchecked") + List> stages = (List>) funnel.get("stages"); + if (stages != null && !stages.isEmpty()) { + for (Map stage : stages) { + Object stageName = stage.get("name"); + Object conversion = stage.get("conversion"); + Object description = stage.get("description"); + if (stageName != null) { + fullReport.append("### ").append(stageName); + if (conversion != null) { + fullReport.append(" (").append(conversion).append(")\n"); + } else { + fullReport.append("\n"); + } + } + if (description != null) { + fullReport.append(description).append("\n"); + } + fullReport.append("\n"); + } + } + } + fullReport.append("[[CHART_FUNNEL]]\n\n"); + + // IX. Рекомендации по позиционированию и УТП + fullReport.append("IX. Рекомендации по позиционированию и УТП\n\n"); + Object positioning = analysisJson.get("positioning"); + Object valueProposition = analysisJson.get("valueProposition"); + if (positioning != null) { + fullReport.append("Позиционирование:\n").append(positioning).append("\n\n"); + } + if (valueProposition != null) { + fullReport.append("Уникальное торговое предложение:\n").append(valueProposition).append("\n\n"); } + // X. Рекомендации по контенту + fullReport.append("X. Рекомендации по контенту\n\n"); + @SuppressWarnings("unchecked") + Map contentRecommendations = (Map) analysisJson.get("contentRecommendations"); + if (contentRecommendations != null) { + @SuppressWarnings("unchecked") + List salesContent = (List) contentRecommendations.get("sales"); + @SuppressWarnings("unchecked") + List expertContent = (List) contentRecommendations.get("expertise"); + @SuppressWarnings("unchecked") + List trustContent = (List) contentRecommendations.get("trust"); + @SuppressWarnings("unchecked") + List entertainmentContent = (List) contentRecommendations.get("entertainment"); + + if (salesContent != null && !salesContent.isEmpty()) { + fullReport.append("Контент для продаж:\n"); + for (String content : salesContent) { + fullReport.append("- ").append(content).append("\n"); + } + fullReport.append("\n"); + } + if (expertContent != null && !expertContent.isEmpty()) { + fullReport.append("Контент для экспертизы:\n"); + for (String content : expertContent) { + fullReport.append("- ").append(content).append("\n"); + } + fullReport.append("\n"); + } + if (trustContent != null && !trustContent.isEmpty()) { + fullReport.append("Контент для доверия:\n"); + for (String content : trustContent) { + fullReport.append("- ").append(content).append("\n"); + } + fullReport.append("\n"); + } + if (entertainmentContent != null && !entertainmentContent.isEmpty()) { + fullReport.append("Развлекательный контент:\n"); + for (String content : entertainmentContent) { + fullReport.append("- ").append(content).append("\n"); + } + fullReport.append("\n"); + } + } + + // XI. Итоговая стратегия + fullReport.append("XI. Итоговая стратегия: что делать в первую очередь\n\n"); + fullReport.append("На основе проведенного анализа рекомендуется:\n\n"); + fullReport.append("1. Сфокусироваться на ключевых сегментах целевой аудитории\n"); + fullReport.append("2. Использовать наиболее эффективные каналы продвижения\n"); + fullReport.append("3. Разработать контент-стратегию с учетом потребностей аудитории\n"); + fullReport.append("4. Усилить позиционирование и уникальное торговое предложение\n"); + fullReport.append("5. Мониторить конкурентов и адаптировать стратегию\n\n"); + + logger.info("Text report generated successfully from JSON without AI summarization"); return fullReport.toString(); } catch (Exception e) { - logger.error("Error generating deep text report from JSON: {}", e.getMessage(), e); + logger.error("Error generating text report from JSON: {}", e.getMessage(), e); return "Ошибка при генерации текстового отчёта: " + e.getMessage(); } }