feat: ai 生成竞品报告增加一个字段json,用来后续生成pdf。

This commit is contained in:
cjy 2026-02-28 14:28:36 +08:00
parent cb1345a55d
commit ce9edf513c

View File

@ -1,6 +1,7 @@
package ai package ai
import ( import (
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"fonchain-fiee/pkg/common/qwen" "fonchain-fiee/pkg/common/qwen"
@ -74,6 +75,93 @@ type CompetitorReportRequest struct {
type CompetitorReportResponse struct { type CompetitorReportResponse struct {
ImageURL string `json:"image_url,omitempty"` // 生成的图片URL1024*1024非必须返回 ImageURL string `json:"image_url,omitempty"` // 生成的图片URL1024*1024非必须返回
Text string `json:"text,omitempty"` // 竞品报告文本内容,非必须返回 Text string `json:"text,omitempty"` // 竞品报告文本内容,非必须返回
JSON string `json:"json,omitempty"` // 竞品报告JSON格式非必须返回
}
// CompetitorReportJSON AI返回的JSON结构
type CompetitorReportJSON struct {
HighlightAnalysis HighlightAnalysis `json:"highlight_analysis"`
DataPerformance DataPerformance `json:"data_performance_analysis"`
OverallSummary string `json:"overall_summary_and_optimization"`
}
type HighlightAnalysis struct {
Summary string `json:"summary"`
Points Points `json:"points"`
}
type Points struct {
Theme string `json:"theme"`
Narrative string `json:"narrative"`
Content string `json:"content"`
Copywriting string `json:"copywriting"`
Data string `json:"data"`
Music string `json:"music,omitempty"`
}
type DataPerformance struct {
Views string `json:"views"`
Completion string `json:"completion_rate,omitempty"`
Engagement string `json:"engagement"`
}
// convertJSONToText 将 JSON 转换为纯文本格式
func convertJSONToText(data CompetitorReportJSON, isVideo bool) string {
var sb strings.Builder
// 一、亮点表现分析
sb.WriteString("一、亮点表现分析\n")
sb.WriteString(data.HighlightAnalysis.Summary)
sb.WriteString("\n\n")
sb.WriteString("1. 标题亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Theme)
sb.WriteString("\n")
sb.WriteString("2. 题材亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Narrative)
sb.WriteString("\n")
sb.WriteString("3. 内容亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Content)
sb.WriteString("\n")
sb.WriteString("4. 文案亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Copywriting)
sb.WriteString("\n")
sb.WriteString("5. 数据亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Data)
sb.WriteString("\n")
if isVideo && data.HighlightAnalysis.Points.Music != "" {
sb.WriteString("6. 配乐亮点:")
sb.WriteString(data.HighlightAnalysis.Points.Music)
sb.WriteString("\n")
}
// 二、数据表现分析
sb.WriteString("\n二、数据表现分析\n")
sb.WriteString("1. 浏览量表现:")
sb.WriteString(data.DataPerformance.Views)
sb.WriteString("\n")
if isVideo && data.DataPerformance.Completion != "" {
sb.WriteString("2. 完播率表现:")
sb.WriteString(data.DataPerformance.Completion)
sb.WriteString("\n")
sb.WriteString("3. 点赞/分享/评论表现:")
} else {
sb.WriteString("2. 点赞/分享/评论表现:")
}
sb.WriteString(data.DataPerformance.Engagement)
sb.WriteString("\n")
// 三、整体总结及可优化建议
sb.WriteString("\n三、整体总结及可优化建议\n")
sb.WriteString(data.OverallSummary)
return sb.String()
} }
// AICompetitorReport 生成竞品报告接口 // AICompetitorReport 生成竞品报告接口
@ -335,7 +423,16 @@ func AICompetitorReport(ctx *gin.Context) {
// 返回结果(只返回实际生成的内容) // 返回结果(只返回实际生成的内容)
result := CompetitorReportResponse{} result := CompetitorReportResponse{}
if needText { if needText {
result.Text = textRes.text result.JSON = textRes.text // JSON 字段直接返回 AI 生成的 JSON
// 将 JSON 解析并转换为纯文本
var jsonData CompetitorReportJSON
if err := json.Unmarshal([]byte(textRes.text), &jsonData); err != nil {
// 如果解析失败,回退使用原始文本
result.Text = textRes.text
} else {
result.Text = convertJSONToText(jsonData, len(req.Videos) > 0)
}
} }
if needImage { if needImage {
result.ImageURL = imageRes.imageURL result.ImageURL = imageRes.imageURL