diff --git a/pkg/service/cast/report.go b/pkg/service/cast/report.go index 8388a8ab..1f9c1e2e 100644 --- a/pkg/service/cast/report.go +++ b/pkg/service/cast/report.go @@ -2,6 +2,7 @@ package cast import ( "context" + "encoding/json" "errors" "fmt" "fonchain-fiee/api/accountFiee" @@ -32,15 +33,23 @@ import ( "go.uber.org/zap" ) +// CreateCompetitiveReportReqEx 扩展的竞品报告请求(包含AI生成的JSON数据) +type CreateCompetitiveReportReqEx struct { + *cast.CreateCompetitiveReportReq // 嵌入原有请求 + ReportData string `json:"reportData"` // AI生成的竞品报告JSON数据 +} + // CreateCompetitiveReport 创建竞品报告 func CreateCompetitiveReport(ctx *gin.Context) { - var req *cast.CreateCompetitiveReportReq + var reqEx CreateCompetitiveReportReqEx var err error - if err = ctx.ShouldBind(&req); err != nil { + if err = ctx.ShouldBindJSON(&reqEx); err != nil { service.Error(ctx, err) return } - resp, err := CreateCompetitiveReportCore(ctx, req) + // 转换为原有类型 + req := reqEx.CreateCompetitiveReportReq + resp, err := CreateCompetitiveReportCore(ctx, req, reqEx.ReportData) if err != nil { service.Error(ctx, err) return @@ -49,7 +58,7 @@ func CreateCompetitiveReport(ctx *gin.Context) { return } -func CreateCompetitiveReportCore(ctx *gin.Context, req *cast.CreateCompetitiveReportReq) (*cast.CreateCompetitiveReportResp, error) { +func CreateCompetitiveReportCore(ctx *gin.Context, req *cast.CreateCompetitiveReportReq, reportData string) (*cast.CreateCompetitiveReportResp, error) { loginInfo := login.GetUserInfoFromC(ctx) lockKey := fmt.Sprintf("lock_create_competitive_report_%d", loginInfo.ID) reply := cache.RedisClient.SetNX(lockKey, time.Now().Format("2006-01-02 15:04:05"), time.Second*5) @@ -103,8 +112,9 @@ func CreateCompetitiveReportCore(ctx *gin.Context, req *cast.CreateCompetitiveRe } req.BundleOrderUuid = resp1.OrderUUID - if req.ReportContent == "" && req.ImageUrl == "" { - return nil, errors.New("报告内容和图片不能同时为空") + // 验证:报告内容、AI生成的JSON数据和图片不能同时为空 + if req.ReportContent == "" && reportData == "" && req.ImageUrl == "" { + return nil, errors.New("报告内容、AI数据和图片不能同时为空") } if req.ImageUrl != "" { @@ -116,7 +126,59 @@ func CreateCompetitiveReportCore(ctx *gin.Context, req *cast.CreateCompetitiveRe req.ImageUrl = newImageUrl } - if req.ReportContent != "" { + // 判断使用哪种方式生成PDF + if reportData != "" { + // 使用 GenerateCompetitorReportPDF 生成PDF + // 解析 JSON 数据 + var competitorReportData utils.CompetitorReportData + if err := json.Unmarshal([]byte(reportData), &competitorReportData); err != nil { + zap.L().Error("解析竞品报告数据失败", zap.String("reportData", reportData), zap.Error(err)) + return nil, errors.New("竞品报告数据格式错误") + } + + // 如果有图片URL,设置到reportData中 + if req.ImageUrl != "" { + competitorReportData.ImageURL = req.ImageUrl + } + + today := time.Now().Format("20060102") + timestamp := time.Now().UnixMicro() + pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, req.ArtistName, timestamp) + pdfFilePath := "./runtime/report_pdf/" + pdfFileName + + _, err = utils.CheckDirPath("./runtime/report_pdf/", true) + if err != nil { + return nil, fmt.Errorf("创建PDF目录失败: %v", err) + } + + // 模板路径 + templatePath := "./data/竞品报告pdf模板.pdf" + + // 调用 GenerateCompetitorReportPDF + err = utils.GenerateCompetitorReportPDF(templatePath, pdfFilePath, competitorReportData) + if err != nil { + zap.L().Error("生成PDF失败", zap.Error(err)) + return nil, errors.New("生成PDF失败") + } + + defer func() { + if _, err := os.Stat(pdfFilePath); err == nil { + if err := os.Remove(pdfFilePath); err != nil { + zap.L().Warn("删除临时PDF文件失败", zap.String("path", pdfFilePath), zap.Error(err)) + } else { + zap.L().Info("删除临时PDF文件成功", zap.String("path", pdfFilePath)) + } + } + }() + + pdfUrl, uploadErr := upload.PutBos(pdfFilePath, upload.PdfType, true) + if uploadErr != nil { + zap.L().Error("上传PDF失败: %v", zap.Error(uploadErr)) + return nil, errors.New("上传PDF失败") + } + req.PdfUrl = pdfUrl + } else if req.ReportContent != "" { + // 使用原有的 GeneratePDF 生成PDF today := time.Now().Format("20060102") timestamp := time.Now().UnixMicro() pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, req.ArtistName, timestamp) diff --git a/pkg/service/taskbench/taskBench.go b/pkg/service/taskbench/taskBench.go index de41db92..527dfbe3 100644 --- a/pkg/service/taskbench/taskBench.go +++ b/pkg/service/taskbench/taskBench.go @@ -384,6 +384,7 @@ type CreateWorkAnalysisWithTaskUUIDReq struct { type CreateCompetitiveReportWithTaskUUIDReq struct { *cast.CreateCompetitiveReportReq AssignRecordsUUID string `json:"assignRecordsUUID"` + ReportData string `json:"reportData"` // AI生成的竞品报告JSON数据 } func UpdateWorkImageWithTaskUUID(ctx *gin.Context) { @@ -575,7 +576,7 @@ func CreateCompetitiveReportWithTaskUUID(ctx *gin.Context) { service.Error(ctx, errors.New("任务已中止")) return } - resp, err := castService.CreateCompetitiveReportCore(ctx, req.CreateCompetitiveReportReq) + resp, err := castService.CreateCompetitiveReportCore(ctx, req.CreateCompetitiveReportReq, req.ReportData) if err != nil { service.Error(ctx, err) return