From 47976a39cfb278acf1218868e151b2a9351f4707 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 19 Dec 2025 23:48:13 +0500 Subject: [PATCH] . --- .../service/MarketingAnalysisService.java | 183 +++++++++++++++--- 1 file changed, 160 insertions(+), 23 deletions(-) diff --git a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java index dfa4cb2..e7ac416 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java @@ -1448,6 +1448,65 @@ public class MarketingAnalysisService { return true; } + /** + * Удаляет сообщения об ошибках и отказах AI из текста отчета + * + * @param text Текст отчета + * @return Очищенный текст без сообщений об ошибках + */ + private String removeErrorMessages(String text) { + if (text == null || text.trim().isEmpty()) { + return text; + } + + String cleaned = text; + + // Паттерны для удаления (включая различные варианты) + String[] errorPatterns = { + "I'm sorry, but I can't assist with that request.", + "I'm sorry, but I can't assist with that request", + "I'm sorry, but I cannot assist with that request.", + "I'm sorry, but I cannot assist with that request", + "I'm sorry, but I can't help with that request.", + "I'm sorry, but I can't help with that request", + "I'm sorry, but I cannot help with that request.", + "I'm sorry, but I cannot help with that request", + "I'm sorry, but I'm unable to assist with that request.", + "I'm sorry, but I'm unable to assist with that request", + "Sorry, but I can't assist with that request.", + "Sorry, but I can't assist with that request", + "I cannot assist with that request.", + "I cannot assist with that request", + "I can't assist with that request.", + "I can't assist with that request" + }; + + for (String pattern : errorPatterns) { + // Удаляем паттерн в любом регистре (case-insensitive) + String quotedPattern = java.util.regex.Pattern.quote(pattern); + // Удаляем паттерн как есть + cleaned = cleaned.replaceAll("(?i)" + quotedPattern, ""); + // Также удаляем с пробелами и переносами строк вокруг + cleaned = cleaned.replaceAll("(?i)(?m)^\\s*" + quotedPattern + "\\s*$", ""); + cleaned = cleaned.replaceAll("(?i)\\s+" + quotedPattern + "\\s+", " "); + cleaned = cleaned.replaceAll("(?i)" + quotedPattern + "\\s*", ""); + } + + // Удаляем множественные пустые строки + cleaned = cleaned.replaceAll("\\n{3,}", "\n\n"); + + // Удаляем пробелы в начале и конце + cleaned = cleaned.trim(); + + if (!cleaned.equals(text)) { + logger.warn( + "removeErrorMessages: Removed error messages from text. Original length: {}, Cleaned length: {}", + text.length(), cleaned.length()); + } + + return cleaned; + } + /** * Подготавливает контекстный JSON для конкретного раздела отчета. * Извлекает только релевантные данные для экономии токенов. @@ -3159,8 +3218,15 @@ public class MarketingAnalysisService { StringBuilder fullReportBuilder = new StringBuilder(); try { String s1 = section1.get(); - if (s1 != null && !s1.trim().isEmpty()) { - fullReportBuilder.append(s1).append("\n\n"); + if (s1 != null && !s1.trim().isEmpty() && isValidAiResponse(s1)) { + // Очищаем от ошибок перед добавлением + String cleaned = removeErrorMessages(s1); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section I (Summary) contained only error messages"); + fullReportBuilder.append("I. Краткое резюме\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section I (Summary) failed to generate"); fullReportBuilder.append("I. Краткое резюме\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3172,8 +3238,14 @@ public class MarketingAnalysisService { try { String s2 = section2.get(); - if (s2 != null && !s2.trim().isEmpty()) { - fullReportBuilder.append(s2).append("\n\n"); + if (s2 != null && !s2.trim().isEmpty() && isValidAiResponse(s2)) { + String cleaned = removeErrorMessages(s2); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section II (Product) contained only error messages"); + fullReportBuilder.append("II. Анализ продукта\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section II (Product) failed to generate"); fullReportBuilder.append("II. Анализ продукта\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3185,8 +3257,15 @@ public class MarketingAnalysisService { try { String s3 = section3.get(); - if (s3 != null && !s3.trim().isEmpty()) { - fullReportBuilder.append(s3).append("\n\n"); + if (s3 != null && !s3.trim().isEmpty() && isValidAiResponse(s3)) { + String cleaned = removeErrorMessages(s3); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section III (Market) contained only error messages"); + fullReportBuilder + .append("III. Анализ рынка и сезонности\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section III (Market) failed to generate"); fullReportBuilder.append("III. Анализ рынка и сезонности\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3198,8 +3277,15 @@ public class MarketingAnalysisService { try { String s4 = section4.get(); - if (s4 != null && !s4.trim().isEmpty()) { - fullReportBuilder.append(s4).append("\n\n"); + if (s4 != null && !s4.trim().isEmpty() && isValidAiResponse(s4)) { + String cleaned = removeErrorMessages(s4); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section IV (Audience) contained only error messages"); + fullReportBuilder + .append("IV. Анализ целевой аудитории\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section IV (Audience) failed to generate"); fullReportBuilder.append("IV. Анализ целевой аудитории\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3211,8 +3297,14 @@ public class MarketingAnalysisService { try { String s5 = section5.get(); - if (s5 != null && !s5.trim().isEmpty()) { - fullReportBuilder.append(s5).append("\n\n"); + if (s5 != null && !s5.trim().isEmpty() && isValidAiResponse(s5)) { + String cleaned = removeErrorMessages(s5); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section V (Competitors) contained only error messages"); + fullReportBuilder.append("V. Анализ конкурентов\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section V (Competitors) failed to generate"); fullReportBuilder.append("V. Анализ конкурентов\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3224,8 +3316,14 @@ public class MarketingAnalysisService { try { String s6 = section6.get(); - if (s6 != null && !s6.trim().isEmpty()) { - fullReportBuilder.append(s6).append("\n\n"); + if (s6 != null && !s6.trim().isEmpty() && isValidAiResponse(s6)) { + String cleaned = removeErrorMessages(s6); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section VI (SWOT) contained only error messages"); + fullReportBuilder.append("VI. SWOT-анализ\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section VI (SWOT) failed to generate"); fullReportBuilder.append("VI. SWOT-анализ\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3237,8 +3335,15 @@ public class MarketingAnalysisService { try { String s7 = section7.get(); - if (s7 != null && !s7.trim().isEmpty()) { - fullReportBuilder.append(s7).append("\n\n"); + if (s7 != null && !s7.trim().isEmpty() && isValidAiResponse(s7)) { + String cleaned = removeErrorMessages(s7); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section VII (Channels) contained only error messages"); + fullReportBuilder + .append("VII. Каналы продвижения и их потенциал\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section VII (Channels) failed to generate"); fullReportBuilder @@ -3251,8 +3356,14 @@ public class MarketingAnalysisService { try { String s8 = section8.get(); - if (s8 != null && !s8.trim().isEmpty()) { - fullReportBuilder.append(s8).append("\n\n"); + if (s8 != null && !s8.trim().isEmpty() && isValidAiResponse(s8)) { + String cleaned = removeErrorMessages(s8); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section VIII (Funnel) contained only error messages"); + fullReportBuilder.append("VIII. Воронка спроса\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section VIII (Funnel) failed to generate"); fullReportBuilder.append("VIII. Воронка спроса\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3264,8 +3375,15 @@ public class MarketingAnalysisService { try { String s9 = section9.get(); - if (s9 != null && !s9.trim().isEmpty()) { - fullReportBuilder.append(s9).append("\n\n"); + if (s9 != null && !s9.trim().isEmpty() && isValidAiResponse(s9)) { + String cleaned = removeErrorMessages(s9); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section IX (Positioning) contained only error messages"); + fullReportBuilder.append( + "IX. Рекомендации по позиционированию и УТП\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section IX (Positioning) failed to generate"); fullReportBuilder.append( @@ -3279,8 +3397,14 @@ public class MarketingAnalysisService { try { String s10 = section10.get(); - if (s10 != null && !s10.trim().isEmpty()) { - fullReportBuilder.append(s10).append("\n\n"); + if (s10 != null && !s10.trim().isEmpty() && isValidAiResponse(s10)) { + String cleaned = removeErrorMessages(s10); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned).append("\n\n"); + } else { + logger.warn("generateMarketingReport: Section X (Content) contained only error messages"); + fullReportBuilder.append("X. Рекомендации по контенту\n\nНе удалось сгенерировать раздел.\n\n"); + } } else { logger.warn("generateMarketingReport: Section X (Content) failed to generate"); fullReportBuilder.append("X. Рекомендации по контенту\n\nНе удалось сгенерировать раздел.\n\n"); @@ -3292,8 +3416,15 @@ public class MarketingAnalysisService { try { String s11 = section11.get(); - if (s11 != null && !s11.trim().isEmpty()) { - fullReportBuilder.append(s11); + if (s11 != null && !s11.trim().isEmpty() && isValidAiResponse(s11)) { + String cleaned = removeErrorMessages(s11); + if (cleaned != null && !cleaned.trim().isEmpty()) { + fullReportBuilder.append(cleaned); + } else { + logger.warn("generateMarketingReport: Section XI (Strategy) contained only error messages"); + fullReportBuilder.append( + "XI. Итоговая стратегия: что делать в первую очередь\n\nНе удалось сгенерировать раздел."); + } } else { logger.warn("generateMarketingReport: Section XI (Strategy) failed to generate"); fullReportBuilder.append( @@ -3343,8 +3474,14 @@ public class MarketingAnalysisService { // Сохраняем данные анализа report.put("analysisTypes", analysisTypeNames); report.put("detailLevel", detailLevelName); + + // Очищаем текст от сообщений об ошибках AI перед сохранением + String cleanedTextReport = processedTextReport != null ? removeErrorMessages(processedTextReport) : null; + if (cleanedTextReport != null && cleanedTextReport.trim().isEmpty()) { + cleanedTextReport = "Анализ не удалось сгенерировать."; + } report.put("fullAnalysis", - processedTextReport != null ? processedTextReport : "Анализ не удалось сгенерировать."); + cleanedTextReport != null ? cleanedTextReport : "Анализ не удалось сгенерировать."); // Summary содержит только короткую вводную фразу String summary = "Маркетинговый анализ для " + request.getProduct();