.
This commit is contained in:
@@ -13,6 +13,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -1084,115 +1085,32 @@ public class MarketingAnalysisService {
|
||||
if (chartsData != null && !chartsData.isEmpty()) {
|
||||
markdown.append("## 📊 Числовые данные для графиков\n\n");
|
||||
|
||||
// Seasonality table
|
||||
// Seasonality JSON block
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Integer> seasonality = (Map<String, Integer>) chartsData.get("seasonality");
|
||||
if (seasonality != null && !seasonality.isEmpty()) {
|
||||
markdown.append("### 1️⃣ Сезонность спроса (12 месяцев)\n\n");
|
||||
markdown.append("| Месяц | Уровень спроса (0–100) |\n");
|
||||
markdown.append("|-------|------------------------|\n");
|
||||
for (Map.Entry<String, Integer> entry : seasonality.entrySet()) {
|
||||
markdown.append("| ").append(entry.getKey()).append(" | ").append(entry.getValue()).append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
appendJsonChart(markdown, "### 1️⃣ Сезонность спроса (12 месяцев)", "seasonality", seasonality);
|
||||
|
||||
// Competitors table
|
||||
// Competitors JSON block
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> competitors = (List<Map<String, Object>>) chartsData.get("competitors");
|
||||
if (competitors != null && !competitors.isEmpty()) {
|
||||
markdown.append("### 2️⃣ Сравнительный анализ конкурентов\n\n");
|
||||
markdown.append(
|
||||
"| Конкурент | Охват аудитории | Активность в соцсетях (0–100) | Количество отзывов | Сильные стороны | Слабые стороны |\n");
|
||||
markdown.append(
|
||||
"|-----------|-----------------|-------------------------------|-------------------|----------------|----------------|\n");
|
||||
for (Map<String, Object> comp : competitors) {
|
||||
markdown.append("| ").append(comp.get("name")).append(" | ")
|
||||
.append(comp.get("reach")).append(" | ")
|
||||
.append(comp.get("activity")).append(" | ")
|
||||
.append(comp.get("reviews")).append(" | ")
|
||||
.append(comp.get("strengths")).append(" | ")
|
||||
.append(comp.get("weaknesses")).append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
appendJsonChart(markdown, "### 2️⃣ Сравнительный анализ конкурентов", "competitors", competitors);
|
||||
|
||||
// Audience segmentation tables
|
||||
// Audience segmentation JSON block
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> audienceSegmentation = (Map<String, Object>) chartsData.get("audienceSegmentation");
|
||||
if (audienceSegmentation != null && !audienceSegmentation.isEmpty()) {
|
||||
markdown.append("### 3️⃣ Сегментация целевой аудитории\n\n");
|
||||
appendJsonChart(markdown, "### 3️⃣ Сегментация целевой аудитории", "audienceSegmentation",
|
||||
audienceSegmentation);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, String>> ageGroups = (List<Map<String, String>>) audienceSegmentation.get("ageGroups");
|
||||
if (ageGroups != null && !ageGroups.isEmpty()) {
|
||||
markdown.append("#### Возрастные группы\n\n");
|
||||
markdown.append("| Возрастная группа | Процент (%) |\n");
|
||||
markdown.append("|-------------------|-------------|\n");
|
||||
for (Map<String, String> group : ageGroups) {
|
||||
markdown.append("| ").append(group.get("label")).append(" | ").append(group.get("value"))
|
||||
.append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, String>> genders = (List<Map<String, String>>) audienceSegmentation.get("genders");
|
||||
if (genders != null && !genders.isEmpty()) {
|
||||
markdown.append("#### Пол\n\n");
|
||||
markdown.append("| Пол | Процент (%) |\n");
|
||||
markdown.append("|-----|-------------|\n");
|
||||
for (Map<String, String> gender : genders) {
|
||||
markdown.append("| ").append(gender.get("label")).append(" | ").append(gender.get("value"))
|
||||
.append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, String>> segments = (List<Map<String, String>>) audienceSegmentation.get("segments");
|
||||
if (segments != null && !segments.isEmpty()) {
|
||||
markdown.append("#### Сегменты ЦА\n\n");
|
||||
markdown.append("| Сегмент | Процент (%) |\n");
|
||||
markdown.append("|---------|-------------|\n");
|
||||
for (Map<String, String> segment : segments) {
|
||||
markdown.append("| ").append(segment.get("label")).append(" | ").append(segment.get("value"))
|
||||
.append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Channels potential table
|
||||
// Channels potential JSON block
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> channelsPotential = (List<Map<String, Object>>) chartsData
|
||||
.get("channelsPotential");
|
||||
if (channelsPotential != null && !channelsPotential.isEmpty()) {
|
||||
markdown.append("### 4️⃣ Потенциал каналов продвижения\n\n");
|
||||
markdown.append("| Канал | Потенциал (0–100) | Обоснование |\n");
|
||||
markdown.append("|-------|-------------------|-------------|\n");
|
||||
for (Map<String, Object> channel : channelsPotential) {
|
||||
markdown.append("| ").append(channel.get("name")).append(" | ")
|
||||
.append(channel.get("potential")).append(" | ")
|
||||
.append(channel.get("justification")).append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
appendJsonChart(markdown, "### 4️⃣ Потенциал каналов продвижения", "channelsPotential", channelsPotential);
|
||||
|
||||
// Conversion funnel table
|
||||
// Conversion funnel JSON block
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> conversionFunnel = (List<Map<String, Object>>) chartsData.get("conversionFunnel");
|
||||
if (conversionFunnel != null && !conversionFunnel.isEmpty()) {
|
||||
markdown.append("### 5️⃣ Конверсионная воронка\n\n");
|
||||
markdown.append("| Этап | Значение | Конверсия (%) |\n");
|
||||
markdown.append("|------|----------|---------------|\n");
|
||||
for (Map<String, Object> stage : conversionFunnel) {
|
||||
markdown.append("| ").append(stage.get("stage")).append(" | ")
|
||||
.append(stage.get("value")).append(" | ")
|
||||
.append(stage.get("conversion")).append(" |\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
}
|
||||
appendJsonChart(markdown, "### 5️⃣ Конверсионная воронка", "funnel", conversionFunnel);
|
||||
|
||||
// SWOT table (if available from JSON)
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -1404,6 +1322,34 @@ public class MarketingAnalysisService {
|
||||
return markdown.toString();
|
||||
}
|
||||
|
||||
private void appendJsonChart(StringBuilder markdown, String heading, String chartKey, Object data) {
|
||||
if (isEmptyChartData(data)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String jsonStr = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
|
||||
markdown.append(heading).append("\n\n");
|
||||
markdown.append("```json:").append(chartKey).append("\n");
|
||||
markdown.append(jsonStr);
|
||||
markdown.append("\n```\n\n");
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Failed to serialize chart data for " + chartKey, e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmptyChartData(Object data) {
|
||||
if (data == null) {
|
||||
return true;
|
||||
}
|
||||
if (data instanceof Map<?, ?>) {
|
||||
return ((Map<?, ?>) data).isEmpty();
|
||||
}
|
||||
if (data instanceof Collection<?>) {
|
||||
return ((Collection<?>) data).isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public MarketingAnalysisResult getAnalysisResult(String analysisId) {
|
||||
Optional<MarketingAnalysis> optAnalysis = repository.findById(analysisId);
|
||||
if (optAnalysis.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user