.
This commit is contained in:
@@ -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. Твой кастомный рендерер на фронтенде (о котором я писал выше) увидит эти блоки и нарисует графики.
|
||||
@@ -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
|
||||
String markdownContent = buildMarkdownFromReport(reportData, request);
|
||||
// Save markdown content into report data so frontend gets JSON code blocks
|
||||
reportData.put("fullAnalysis", markdownContent);
|
||||
|
||||
// Generate PDF
|
||||
byte[] pdfBytes = researchPdfService.generatePdfReport(
|
||||
|
||||
Reference in New Issue
Block a user