This commit is contained in:
root
2025-12-10 19:05:55 +05:00
parent 5a4cd9748d
commit 8d749cf53c
3 changed files with 112 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
Я внимательно изучил поле `fullAnalysis` в присланном JSON. Там всё ещё обычный текст и списки, а не Markdown-блоки с JSON.
**Вот пример того, что мы видим сейчас (в `fullAnalysis`):**
```markdown
## VIII. Воронка спроса
Воронка продаж показывает следующие этапы:
- Охват: 1000
- Вовлечённость: 300 (30%)
...
```
**А должны были увидеть (согласно плану):**
````markdown
## VIII. Воронка спроса
```json:conversionFunnel
[
{ "stage": "Охват", "value": 1000, "conversion": 0 },
...
]
```
````
````
---
### Почему так произошло?
Проблема в архитектуре метода `processAnalysis` в вашем Java-коде.
1. Вы изменили метод `buildMarkdownFromReport`, и он, скорее всего, работает правильно и генерирует строку с JSON-блоками.
2. **НО** эта строка (`markdownContent`) используется **только для генерации PDF**.
3. В базу данных и во фронтенд (в поле `reportData`) сохраняется старая версия текста, сгенерированная AI (Промпт №2), которая не знает о нашей новой логике встраивания графиков.
### Как исправить?
Нам нужно сказать Cursor'у, чтобы он **перезаписал** поле `fullAnalysis` внутри `reportData` тем Markdown-контентом, который генерирует метод `buildMarkdownFromReport`.
**Промпт для Cursor (отправь это, чтобы починить):**
```text
Я не вижу изменений в JSON-ответе для фронтенда. Проблема в методе `processAnalysis` класса `MarketingAnalysisService`.
Сейчас переменная `markdownContent` (результат метода `buildMarkdownFromReport`) используется только для генерации PDF.
А в `analysis.setReportData(reportData)` попадает старый текст, сгенерированный AI.
Пожалуйста, сделай следующее изменение в методе `processAnalysis`:
1. После вызова:
String markdownContent = buildMarkdownFromReport(reportData, request);
2. Добавь строку, которая обновляет reportData:
reportData.put("fullAnalysis", markdownContent);
Это нужно, чтобы фронтенд получал именно сформированный Markdown с JSON-блоками (charts), а не просто текст от AI.
````
### Что произойдет после этого исправления:
1. Backend сгенерирует Markdown с JSON-блоками.
2. Этот Markdown сохранится в базу данных как `fullAnalysis`.
3. Фронтенд получит JSON, где внутри поля `report.fullAnalysis` будут блоки кода ` ```json:seasonality... `.
4. Твой кастомный рендерер на фронтенде (о котором я писал выше) увидит эти блоки и нарисует графики.
+42
View File
@@ -0,0 +1,42 @@
## Frontend notes: rendering chart JSON blocks
- Markdown now emits chart data as fenced code blocks with language tags like `json:seasonality`, `json:competitors`, `json:audienceSegmentation`, `json:channelsPotential`, and `json:funnel`.
- Each block is pretty-printed JSON; parse the string inside the fence to feed the relevant chart component.
- Headings stay the same; only tables were replaced by these code fences.
### Expected shapes
- `seasonality` object map: `{ "Январь": 70, "Февраль": 60, ... }`.
- `competitors` array of objects: `{ name, reach, activity, reviews, strengths, weaknesses }`.
- `audienceSegmentation` object with optional arrays: `ageGroups[]`, `genders[]`, `segments[]`, each item `{ label, value }`.
- `channelsPotential` array of objects: `{ name, potential, justification }`.
- `funnel` array of objects: `{ stage, value, conversion }`.
### Rendering hook (React + react-markdown)
```javascript
components={{
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+):([\w-]+)/.exec(className || "");
if (!inline && match && match[1] === "json") {
const chartType = match[2];
const data = JSON.parse(String(children).replace(/\n$/, ""));
switch (chartType) {
case "seasonality": return <SeasonalityChart data={data} />;
case "competitors": return <CompetitorsChart data={data} />;
case "audienceSegmentation": return <AudienceSegmentationChart data={data} />;
case "channelsPotential": return <ChannelsPotentialChart data={data} />;
case "funnel": return <FunnelChart data={data} />;
default: return <pre>{children}</pre>;
}
}
return <code className={className} {...props}>{children}</code>;
}
}}
```
### Tips
- Trim trailing newline before `JSON.parse` to avoid parse errors.
- Keep a safe fallback (`<pre>`) for unknown chart types.
- If using another markdown renderer, ensure it preserves the code fence language string in a similar `json:<chart>` format.
@@ -99,6 +99,8 @@ public class MarketingAnalysisService {
// Generate markdown content for PDF // Generate markdown content for PDF
String markdownContent = buildMarkdownFromReport(reportData, request); String markdownContent = buildMarkdownFromReport(reportData, request);
// Save markdown content into report data so frontend gets JSON code blocks
reportData.put("fullAnalysis", markdownContent);
// Generate PDF // Generate PDF
byte[] pdfBytes = researchPdfService.generatePdfReport( byte[] pdfBytes = researchPdfService.generatePdfReport(