.
This commit is contained in:
@@ -112,7 +112,7 @@ public class MarketingAnalysisService {
|
||||
// Match lines like: "I. Title" or "## I. Title"
|
||||
java.util.regex.Pattern p = java.util.regex.Pattern.compile(
|
||||
"^(\\s*)(#{0,6}\\s*)?(" + java.util.regex.Pattern.quote(roman)
|
||||
+ ")\\.(\\s+[^\\n\\r]+)\\s*$",
|
||||
+ ")\\.(\\s*\\S[^\\n\\r]*)\\s*$",
|
||||
java.util.regex.Pattern.MULTILINE);
|
||||
java.util.regex.Matcher m = p.matcher(result);
|
||||
if (!m.find()) {
|
||||
@@ -142,8 +142,8 @@ public class MarketingAnalysisService {
|
||||
}
|
||||
for (String roman : SECTION_ROMANS) {
|
||||
java.util.regex.Pattern p = java.util.regex.Pattern.compile(
|
||||
"^(?:\\s*<a\\s+id=\"[^\"]+\"\\s*></a>\\s*\\n)?\\s*##\\s*(" + java.util.regex.Pattern.quote(roman)
|
||||
+ ")\\.(\\s+[^\\n\\r]+)\\s*$",
|
||||
"^(?:\\s*<a\\s+id=\"[^\"]+\"\\s*></a>\\s*\\n)?\\s*(?:#{1,6}\\s*)?("
|
||||
+ java.util.regex.Pattern.quote(roman) + ")\\.(\\s*\\S[^\\n\\r]*)\\s*$",
|
||||
java.util.regex.Pattern.MULTILINE);
|
||||
java.util.regex.Matcher m = p.matcher(fullAnalysis);
|
||||
if (m.find()) {
|
||||
@@ -2038,6 +2038,10 @@ public class MarketingAnalysisService {
|
||||
promptBuilder.append("2. Стиль: деловой, убедительный для владельца бизнеса\n");
|
||||
promptBuilder.append("3. Глубина: аналитические инсайты с практическими выводами\n");
|
||||
promptBuilder.append("4. Данные: используй ТОЛЬКО данные из JSON, не выдумывай цифры\n");
|
||||
promptBuilder.append(
|
||||
"ВНИМАНИЕ: Проверяй математическую логику. Количество покупок НЕ МОЖЕТ быть больше количества заявок. "
|
||||
+ "Конверсия не может превышать 100%. Если данные в JSON противоречивы, используй логические значения "
|
||||
+ "(например, конверсия 10%) и сделай пометку 'Требуется уточнение данных'.\n");
|
||||
promptBuilder.append("5. РАЗДЕЛ НЕЛЬЗЯ ПРОПУСКАТЬ:\n");
|
||||
promptBuilder.append(
|
||||
" - Если в JSON нет funnel/conversionFunnel: построй воронку как ГИПОТЕЗУ (этапы + логика), но все числа замени на переменные (X1, X2...) и подпиши \"нет данных в JSON\".\n");
|
||||
@@ -2233,6 +2237,10 @@ public class MarketingAnalysisService {
|
||||
promptBuilder.append("КРИТИЧНО - ПРОГНОЗ И РАСЧЕТЫ НА ОСНОВЕ ВОРОНКИ:\n");
|
||||
promptBuilder.append(
|
||||
"1. Возьми воронку из strategyAnalysis.funnel (или из funnel, если strategyAnalysis отсутствует) и выполни расчеты.\n");
|
||||
promptBuilder.append(
|
||||
"ВНИМАНИЕ: Проверяй математическую логику. Количество покупок НЕ МОЖЕТ быть больше количества заявок. "
|
||||
+ "Конверсия не может превышать 100%. Если данные в JSON противоречивы, используй логические значения "
|
||||
+ "(например, конверсия 10%) и сделай пометку 'Требуется уточнение данных'.\n");
|
||||
promptBuilder.append(
|
||||
"2. Дай минимум 3 прогнозных показателя с формулами и подстановкой чисел из JSON (например: конверсия между этапами, ожидаемое число покупок, требуемый объем верхнего этапа для достижения цели).\n");
|
||||
promptBuilder.append(
|
||||
@@ -3378,6 +3386,9 @@ public class MarketingAnalysisService {
|
||||
for (String roman : SECTION_ROMANS) {
|
||||
String id = ROMAN_TO_ANCHOR_ID.get(roman);
|
||||
String label = sectionTitles.getOrDefault(roman, "Раздел " + roman);
|
||||
if ("V".equals(roman) && ("Раздел V".equals(label) || label == null || label.isBlank())) {
|
||||
label = "V. Анализ конкурентов";
|
||||
}
|
||||
markdown.append("- [").append(label).append("](#").append(id).append(")\n");
|
||||
}
|
||||
markdown.append("\n");
|
||||
@@ -3711,6 +3722,15 @@ public class MarketingAnalysisService {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Если JSON-блок для этого графика уже присутствует в секции — значит он уже
|
||||
// вставлен/обработан; не добавляем повторно в конец секции
|
||||
if (mapping.chartKey != null && sectionContainsJsonBlock(sectionText, mapping.chartKey)) {
|
||||
if (processedPlaceholders != null) {
|
||||
processedPlaceholders.add(normalizedPlaceholder);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Если данные отсутствуют — не добавляем тег (он будет удален final pass-ом)
|
||||
if (chartsData == null || !chartsData.containsKey(mapping.dataKey)) {
|
||||
logger.warn(
|
||||
@@ -3764,6 +3784,19 @@ public class MarketingAnalysisService {
|
||||
.find();
|
||||
}
|
||||
|
||||
private boolean sectionContainsJsonBlock(String sectionText, String chartKey) {
|
||||
if (sectionText == null || sectionText.isEmpty() || chartKey == null || chartKey.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
// Matches blocks like:
|
||||
// ```json:seasonality
|
||||
// {...}
|
||||
// ```
|
||||
String regex = "```\\s*json\\s*:\\s*" + java.util.regex.Pattern.quote(chartKey.trim()) + "\\b";
|
||||
return java.util.regex.Pattern.compile(regex, java.util.regex.Pattern.CASE_INSENSITIVE).matcher(sectionText)
|
||||
.find();
|
||||
}
|
||||
|
||||
public MarketingAnalysisResult getAnalysisResult(String analysisId) {
|
||||
Optional<MarketingAnalysis> optAnalysis = repository.findById(analysisId);
|
||||
if (optAnalysis.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user