feat: 实现新模板下的竞品报告批量导入
This commit is contained in:
parent
6242962b43
commit
9c4c4b1c66
Binary file not shown.
Binary file not shown.
@ -372,16 +372,86 @@ func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
||||
temp.Title = nowDate + temp.ArtistName + "老师竞品报告"
|
||||
}
|
||||
}
|
||||
// 解析报告内容(D列,row[3])
|
||||
if len(row) > 3 {
|
||||
temp.ReportContent = row[3]
|
||||
|
||||
// 构建竞品报告数据(新模板格式)
|
||||
// D列(row[3]):亮点表现分析 - 对应Summary字段
|
||||
// E列(row[4]):标题亮点
|
||||
// F列(row[5]):题材亮点
|
||||
// G列(row[6]):内容亮点
|
||||
// H列(row[7]):文案亮点
|
||||
// I列(row[8]):数据亮点
|
||||
// J列(row[9]):配乐亮点
|
||||
// K列(row[10]):浏览量
|
||||
// L列(row[11]):完播率
|
||||
// M列(row[12]):点赞/分享/评论
|
||||
// N列(row[13]):整体总结及可优化建议
|
||||
// O列(row[14]):图片
|
||||
|
||||
var competitorReportData utils.CompetitorReportData
|
||||
|
||||
// 解析亮点表现分析
|
||||
highlightAnalysis := utils.HighlightAnalysisData{
|
||||
Points: utils.PointsData{},
|
||||
}
|
||||
|
||||
// 解析图片URL(E列,row[4])
|
||||
if len(row) > 4 && utils.CleanString(row[4]) != "" {
|
||||
temp.ImageUrl = utils.CleanString(row[4])
|
||||
// 亮点表现分析摘要(D列,row[3])
|
||||
if len(row) > 3 {
|
||||
highlightAnalysis.Summary = utils.CleanString(row[3])
|
||||
}
|
||||
|
||||
// 标题亮点(E列,row[4])
|
||||
if len(row) > 4 {
|
||||
highlightAnalysis.Points.Theme = utils.CleanString(row[4])
|
||||
}
|
||||
// 题材亮点(F列,row[5])
|
||||
if len(row) > 5 {
|
||||
highlightAnalysis.Points.Narrative = utils.CleanString(row[5])
|
||||
}
|
||||
// 内容亮点(G列,row[6])
|
||||
if len(row) > 6 {
|
||||
highlightAnalysis.Points.Content = utils.CleanString(row[6])
|
||||
}
|
||||
// 文案亮点(H列,row[7])
|
||||
if len(row) > 7 {
|
||||
highlightAnalysis.Points.Copywriting = utils.CleanString(row[7])
|
||||
}
|
||||
// 数据亮点(I列,row[8])
|
||||
if len(row) > 8 {
|
||||
highlightAnalysis.Points.Data = utils.CleanString(row[8])
|
||||
}
|
||||
// 配乐亮点(J列,row[9])
|
||||
if len(row) > 9 {
|
||||
highlightAnalysis.Points.Music = utils.CleanString(row[9])
|
||||
}
|
||||
|
||||
// 解析数据表现
|
||||
dataPerformance := utils.DataPerformanceData{}
|
||||
// 浏览量(K列,row[10])
|
||||
if len(row) > 10 {
|
||||
dataPerformance.Views = utils.CleanString(row[10])
|
||||
}
|
||||
// 完播率(L列,row[11])
|
||||
if len(row) > 11 {
|
||||
dataPerformance.Completion = utils.CleanString(row[11])
|
||||
}
|
||||
// 点赞/分享/评论(M列,row[12])
|
||||
if len(row) > 12 {
|
||||
dataPerformance.Engagement = utils.CleanString(row[12])
|
||||
}
|
||||
|
||||
// 整体总结及可优化建议(N列,row[13])
|
||||
if len(row) > 13 {
|
||||
competitorReportData.OverallSummary = utils.CleanString(row[13])
|
||||
}
|
||||
|
||||
// 图片URL(O列,row[14])
|
||||
if len(row) > 14 && utils.CleanString(row[14]) != "" {
|
||||
competitorReportData.ImageURL = utils.CleanString(row[14])
|
||||
}
|
||||
|
||||
competitorReportData.HighlightAnalysis = highlightAnalysis
|
||||
competitorReportData.DataPerformance = dataPerformance
|
||||
|
||||
// 验证必填字段
|
||||
if artistNum == "" {
|
||||
temp.Remark = "艺人编号不能为空"
|
||||
@ -389,82 +459,129 @@ func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证报告内容和图片不能同时为空
|
||||
if temp.ReportContent == "" && temp.ImageUrl == "" {
|
||||
temp.Remark = "报告内容和图片不能同时为空"
|
||||
// 验证亮点表现分析(D列:Summary)
|
||||
if highlightAnalysis.Summary == "" {
|
||||
temp.Remark = "亮点表现分析摘要不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果已经有错误信息,跳过PDF生成
|
||||
if temp.Remark != "" {
|
||||
// 验证标题亮点(E列)
|
||||
if highlightAnalysis.Points.Theme == "" {
|
||||
temp.Remark = "标题亮点不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查图片URL是否包含阿里云,如果包含则下载并重新上传到OSS
|
||||
if temp.ImageUrl != "" {
|
||||
newImageUrl, err := checkAndReuploadImageForReport(temp.ImageUrl)
|
||||
// 验证题材亮点(F列)
|
||||
if highlightAnalysis.Points.Narrative == "" {
|
||||
temp.Remark = "题材亮点不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证内容亮点(G列)
|
||||
if highlightAnalysis.Points.Content == "" {
|
||||
temp.Remark = "内容亮点不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证文案亮点(H列)
|
||||
if highlightAnalysis.Points.Copywriting == "" {
|
||||
temp.Remark = "文案亮点不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证数据亮点(I列)
|
||||
if highlightAnalysis.Points.Data == "" {
|
||||
temp.Remark = "数据亮点不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证浏览量(K列)
|
||||
if dataPerformance.Views == "" {
|
||||
temp.Remark = "浏览量不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证点赞/分享/评论(M列)
|
||||
if dataPerformance.Engagement == "" {
|
||||
temp.Remark = "点赞/分享/评论不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 验证整体总结及可优化建议(N列)
|
||||
if competitorReportData.OverallSummary == "" {
|
||||
temp.Remark = "整体总结及可优化建议不能为空"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 处理图片URL
|
||||
if competitorReportData.ImageURL != "" {
|
||||
newImageUrl, err := checkAndReuploadImageForReport(competitorReportData.ImageURL)
|
||||
if err != nil {
|
||||
temp.Remark = fmt.Sprintf("图片处理失败: %v", err)
|
||||
zap.L().Error("图片重新上传失败", zap.String("imageUrl", temp.ImageUrl), zap.Error(err))
|
||||
zap.L().Error("图片重新上传失败", zap.String("imageUrl", competitorReportData.ImageURL), zap.Error(err))
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
temp.ImageUrl = newImageUrl
|
||||
competitorReportData.ImageURL = newImageUrl
|
||||
}
|
||||
|
||||
// 如果提供了报告内容,则生成PDF并上传
|
||||
if temp.ReportContent != "" {
|
||||
// 生成临时PDF文件路径
|
||||
today := time.Now().Format("20060102")
|
||||
timestamp := time.Now().UnixMicro()
|
||||
pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, temp.ArtistName, timestamp)
|
||||
pdfFilePath := "./runtime/report_pdf/" + pdfFileName
|
||||
// 生成PDF并上传
|
||||
// 生成临时PDF文件路径
|
||||
today := time.Now().Format("20060102")
|
||||
timestamp := time.Now().UnixMicro()
|
||||
pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, temp.ArtistName, timestamp)
|
||||
pdfFilePath := "./runtime/report_pdf/" + pdfFileName
|
||||
|
||||
// 确保目录存在
|
||||
_, err = utils.CheckDirPath("./runtime/report_pdf/", true)
|
||||
if err != nil {
|
||||
temp.Remark = fmt.Sprintf("创建PDF目录失败: %v", err)
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
// 确保目录存在
|
||||
_, err = utils.CheckDirPath("./runtime/report_pdf/", true)
|
||||
if err != nil {
|
||||
temp.Remark = fmt.Sprintf("创建PDF目录失败: %v", err)
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 生成PDF文件
|
||||
fontPath := "./data/simfang.ttf"
|
||||
err = utils.GeneratePDF(temp.ReportContent, temp.ImageUrl, pdfFilePath, fontPath)
|
||||
if err != nil {
|
||||
zap.L().Error("生成PDF失败", zap.Error(err))
|
||||
temp.Remark = "生成PDF失败"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
// 模板路径
|
||||
templatePath := "./data/竞品报告pdf模板.pdf"
|
||||
|
||||
// 上传PDF到OSS
|
||||
pdfUrl, uploadErr := upload.PutBos(pdfFilePath, upload.PdfType, true)
|
||||
if uploadErr != nil {
|
||||
zap.L().Error("上传PDF失败", zap.Error(uploadErr))
|
||||
temp.Remark = "上传PDF失败"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
// 清理临时PDF文件
|
||||
if _, err := os.Stat(pdfFilePath); err == nil {
|
||||
os.Remove(pdfFilePath)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 将上传后的PDF链接设置到请求中
|
||||
temp.PdfUrl = pdfUrl
|
||||
// 使用新的 GenerateCompetitorReportPDF 生成PDF
|
||||
err = utils.GenerateCompetitorReportPDF(templatePath, pdfFilePath, competitorReportData)
|
||||
if err != nil {
|
||||
zap.L().Error("生成PDF失败", zap.Error(err))
|
||||
temp.Remark = "生成PDF失败"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
continue
|
||||
}
|
||||
|
||||
// 上传PDF到OSS
|
||||
pdfUrl, uploadErr := upload.PutBos(pdfFilePath, upload.PdfType, true)
|
||||
if uploadErr != nil {
|
||||
zap.L().Error("上传PDF失败", zap.Error(uploadErr))
|
||||
temp.Remark = "上传PDF失败"
|
||||
req.Reports = append(req.Reports, temp)
|
||||
// 清理临时PDF文件
|
||||
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))
|
||||
}
|
||||
os.Remove(pdfFilePath)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 将上传后的PDF链接设置到请求中
|
||||
temp.PdfUrl = pdfUrl
|
||||
|
||||
// 清理临时PDF文件
|
||||
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 {
|
||||
// 如果没有报告内容,则将图片URL设置为PDF URL
|
||||
temp.PdfUrl = temp.ImageUrl
|
||||
}
|
||||
|
||||
req.Reports = append(req.Reports, temp)
|
||||
@ -497,7 +614,7 @@ func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
||||
// 通过请求对象找到对应的Excel行号
|
||||
if excelRowNum, ok := reportRowMap[reqReport]; ok {
|
||||
// 将错误信息写入最后一列(F列)
|
||||
excelData.SetCellValue("Sheet1", fmt.Sprintf("F%d", excelRowNum), v.Remark)
|
||||
excelData.SetCellValue("Sheet1", fmt.Sprintf("P%d", excelRowNum), v.Remark)
|
||||
hasValueRows[excelRowNum] = true
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user