diff --git a/src/views/pages/marketing/MarketingAnalysis.vue b/src/views/pages/marketing/MarketingAnalysis.vue index ece6631..3b5bd9b 100644 --- a/src/views/pages/marketing/MarketingAnalysis.vue +++ b/src/views/pages/marketing/MarketingAnalysis.vue @@ -609,6 +609,12 @@ + +
+
+

Неизвестный тип сегмента: {{ segment.type }}

+
+
@@ -1321,6 +1327,19 @@ const mapChartsDataToSegments = (chartsData) => { const segments = []; + // Handle case when chartsData is an array (shouldn't happen, but handle it) + if (Array.isArray(chartsData)) { + // If it's an array of competitors, process it + if (chartsData.length > 0 && chartsData[0]?.name && chartsData[0]?.channelsHeatmap) { + segments.push({ + type: 'competitors', + competitors: chartsData, + competitorsHeatmap: buildCompetitorsHeatmapData(chartsData) + }); + } + return segments; + } + // 1. Audience Segmentation if (chartsData.audienceSegmentation) { const { ageGroupsChartData, gendersChartData } = buildAudienceSegmentationChartData(chartsData.audienceSegmentation); @@ -1860,9 +1879,14 @@ const parseFullAnalysisWithCharts = (fullAnalysis, chartsData) => { const segment = mapJsonBlockToSegment(jsonIdentifier, parsedData, fullMatch); if (segment) { segments.push(segment); + } else { + // If segment is null, don't add anything - the JSON block will be ignored + // This prevents raw JSON from being displayed + console.warn(`Не удалось обработать JSON блок ${jsonIdentifier}`); } } catch (error) { console.error(`Не удалось распарсить блок ${jsonIdentifier}:`, error); + // Don't add raw JSON block to segments - it will be ignored } } } @@ -1882,61 +1906,125 @@ const parseFullAnalysisWithCharts = (fullAnalysis, chartsData) => { // New computed property for chartsData const chartsDataSegments = computed(() => { if (!report.value?.chartsData) return []; - return mapChartsDataToSegments(report.value.chartsData); + + const chartsData = report.value.chartsData; + + // Handle case when chartsData is an array directly (shouldn't happen, but handle it) + if (Array.isArray(chartsData)) { + // If it's an array of competitors, process it + if (chartsData.length > 0 && chartsData[0]?.name && chartsData[0]?.channelsHeatmap) { + return [ + { + type: 'competitors', + competitors: chartsData, + competitorsHeatmap: buildCompetitorsHeatmapData(chartsData) + } + ]; + } + // If it's an array with audienceSegmentation-like structure, process it + if (chartsData.length > 0 && (chartsData[0]?.genders || chartsData[0]?.ageGroups)) { + const { ageGroupsChartData, gendersChartData } = buildAudienceSegmentationChartData(chartsData[0]); + if (ageGroupsChartData || gendersChartData) { + return [ + { + type: 'audienceSegmentation', + ageGroupsChartData, + gendersChartData, + segmentsChannelMatrix: buildSegmentsChannelMatrix(chartsData[0].segmentsChannelMatrix), + keyTakeaways: chartsData[0].keyTakeaways || [] + } + ]; + } + } + return []; + } + + return mapChartsDataToSegments(chartsData); }); // Main parsedContent that combines fullAnalysis with chartsData const parsedContent = computed(() => { + let segments = []; + // If we have both fullAnalysis and chartsData, parse fullAnalysis and inject charts if (report.value?.fullAnalysis && report.value?.chartsData) { - return parseFullAnalysisWithCharts(report.value.fullAnalysis, report.value.chartsData); + segments = parseFullAnalysisWithCharts(report.value.fullAnalysis, report.value.chartsData); } - // If only chartsData exists, use it - if (report.value?.chartsData) { - return chartsDataSegments.value; + else if (report.value?.chartsData) { + segments = chartsDataSegments.value; } - // Otherwise, fall back to parsing fullAnalysis with JSON blocks (for old data) - if (!report.value?.fullAnalysis) return []; + else if (report.value?.fullAnalysis) { + const content = report.value.fullAnalysis; + const regex = /```json:(\w+)\n([\s\S]*?)\n```/g; + let lastIndex = 0; + let match; - const content = report.value.fullAnalysis; - const regex = /```json:(\w+)\n([\s\S]*?)\n```/g; - const segments = []; - let lastIndex = 0; - let match; + while ((match = regex.exec(content)) !== null) { + const [fullMatch, identifier, jsonBlock] = match; - while ((match = regex.exec(content)) !== null) { - const [fullMatch, identifier, jsonBlock] = match; - - if (match.index > lastIndex) { - const textBefore = content.slice(lastIndex, match.index); - if (textBefore.trim()) { - segments.push({ type: 'markdown', html: renderMarkdown(textBefore) }); + if (match.index > lastIndex) { + const textBefore = content.slice(lastIndex, match.index); + if (textBefore.trim()) { + segments.push({ type: 'markdown', html: renderMarkdown(textBefore) }); + } } + + let parsedData = null; + try { + parsedData = JSON.parse(jsonBlock); + } catch (error) { + console.error(`Не удалось распарсить блок ${identifier}:`, error); + } + + const segment = mapJsonBlockToSegment(identifier, parsedData, fullMatch); + if (segment) { + segments.push(segment); + } + + lastIndex = regex.lastIndex; } - let parsedData = null; - try { - parsedData = JSON.parse(jsonBlock); - } catch (error) { - console.error(`Не удалось распарсить блок ${identifier}:`, error); + const remaining = content.slice(lastIndex); + if (remaining.trim()) { + segments.push({ type: 'markdown', html: renderMarkdown(remaining) }); } - - const segment = mapJsonBlockToSegment(identifier, parsedData, fullMatch); - if (segment) { - segments.push(segment); - } - - lastIndex = regex.lastIndex; } - const remaining = content.slice(lastIndex); - if (remaining.trim()) { - segments.push({ type: 'markdown', html: renderMarkdown(remaining) }); - } - - return segments; + // Filter out any segments without a valid type and ensure all segments are properly formatted + return segments.filter((segment) => { + // If segment doesn't have a type, try to process it + if (!segment || !segment.type) { + // If it's an array (like competitors), process it + if (Array.isArray(segment) && segment.length > 0 && segment[0]?.name) { + const processed = { + type: 'competitors', + competitors: segment, + competitorsHeatmap: buildCompetitorsHeatmapData(segment) + }; + segments[segments.indexOf(segment)] = processed; + return true; + } + // If it's an object with audienceSegmentation-like structure, process it + if (segment && typeof segment === 'object' && (segment.genders || segment.ageGroups || segment.segments)) { + const { ageGroupsChartData, gendersChartData } = buildAudienceSegmentationChartData(segment); + if (ageGroupsChartData || gendersChartData) { + const processed = { + type: 'audienceSegmentation', + ageGroupsChartData, + gendersChartData, + segmentsChannelMatrix: buildSegmentsChannelMatrix(segment.segmentsChannelMatrix), + keyTakeaways: segment.keyTakeaways || [] + }; + segments[segments.indexOf(segment)] = processed; + return true; + } + } + return false; + } + return true; + }); }); const pieChartOptions = {