.
This commit is contained in:
@@ -711,7 +711,7 @@ public class MarketingAnalysisService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Глубокая генерация текстового отчёта на основе JSON (4 этапа)
|
||||
* Генерация текстового отчёта на основе JSON (простое объединение без AI-суммирования)
|
||||
*/
|
||||
private String generateDeepTextReport(Map<String, Object> 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<String, Object> seasonality = (Map<String, Object>) analysisJson.get("seasonality");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> market = (Map<String, Object>) 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<String> trends = (List<String>) 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<String> opportunities = (List<String>) 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<String> threats = (List<String>) 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<String, Object> audienceAnalysis = (Map<String, Object>) analysisJson.get("audienceAnalysis");
|
||||
if (audienceAnalysis != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> segments = (List<Map<String, Object>>) audienceAnalysis.get("segments");
|
||||
if (segments != null && !segments.isEmpty()) {
|
||||
for (Map<String, Object> 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<String, Object> competitorAnalysis = (Map<String, Object>) 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<Map<String, Object>> competitorsDetails = (List<Map<String, Object>>) competitorAnalysis.get("competitorsDetails");
|
||||
if (competitorsDetails != null && !competitorsDetails.isEmpty()) {
|
||||
for (Map<String, Object> competitor : competitorsDetails) {
|
||||
Object compName = competitor.get("name");
|
||||
Object priceStrategy = competitor.get("priceStrategy");
|
||||
Object contentStrategy = competitor.get("contentStrategy");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> swot = (Map<String, Object>) 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<String> strengths = (List<String>) swot.get("strengths");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> weaknesses = (List<String>) 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<String, Object> swot = (Map<String, Object>) analysisJson.get("swot");
|
||||
if (swot != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> strengths = (List<String>) swot.get("strengths");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> weaknesses = (List<String>) swot.get("weaknesses");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> opportunities = (List<String>) swot.get("opportunities");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> threats = (List<String>) 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<String, Object> channels = (Map<String, Object>) analysisJson.get("channels");
|
||||
if (channels != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> channelList = (List<Map<String, Object>>) channels.get("recommended");
|
||||
if (channelList != null && !channelList.isEmpty()) {
|
||||
for (Map<String, Object> 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<String, Object> funnel = (Map<String, Object>) analysisJson.get("funnel");
|
||||
if (funnel != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> stages = (List<Map<String, Object>>) funnel.get("stages");
|
||||
if (stages != null && !stages.isEmpty()) {
|
||||
for (Map<String, Object> 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<String, Object> contentRecommendations = (Map<String, Object>) analysisJson.get("contentRecommendations");
|
||||
if (contentRecommendations != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> salesContent = (List<String>) contentRecommendations.get("sales");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> expertContent = (List<String>) contentRecommendations.get("expertise");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> trustContent = (List<String>) contentRecommendations.get("trust");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> entertainmentContent = (List<String>) 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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user