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 + "老师竞品报告"
|
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])
|
// 亮点表现分析摘要(D列,row[3])
|
||||||
if len(row) > 4 && utils.CleanString(row[4]) != "" {
|
if len(row) > 3 {
|
||||||
temp.ImageUrl = utils.CleanString(row[4])
|
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 == "" {
|
if artistNum == "" {
|
||||||
temp.Remark = "艺人编号不能为空"
|
temp.Remark = "艺人编号不能为空"
|
||||||
@ -389,82 +459,129 @@ func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证报告内容和图片不能同时为空
|
// 验证亮点表现分析(D列:Summary)
|
||||||
if temp.ReportContent == "" && temp.ImageUrl == "" {
|
if highlightAnalysis.Summary == "" {
|
||||||
temp.Remark = "报告内容和图片不能同时为空"
|
temp.Remark = "亮点表现分析摘要不能为空"
|
||||||
req.Reports = append(req.Reports, temp)
|
req.Reports = append(req.Reports, temp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果已经有错误信息,跳过PDF生成
|
// 验证标题亮点(E列)
|
||||||
if temp.Remark != "" {
|
if highlightAnalysis.Points.Theme == "" {
|
||||||
|
temp.Remark = "标题亮点不能为空"
|
||||||
req.Reports = append(req.Reports, temp)
|
req.Reports = append(req.Reports, temp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查图片URL是否包含阿里云,如果包含则下载并重新上传到OSS
|
// 验证题材亮点(F列)
|
||||||
if temp.ImageUrl != "" {
|
if highlightAnalysis.Points.Narrative == "" {
|
||||||
newImageUrl, err := checkAndReuploadImageForReport(temp.ImageUrl)
|
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 {
|
if err != nil {
|
||||||
temp.Remark = fmt.Sprintf("图片处理失败: %v", err)
|
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)
|
req.Reports = append(req.Reports, temp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
temp.ImageUrl = newImageUrl
|
competitorReportData.ImageURL = newImageUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果提供了报告内容,则生成PDF并上传
|
// 生成PDF并上传
|
||||||
if temp.ReportContent != "" {
|
// 生成临时PDF文件路径
|
||||||
// 生成临时PDF文件路径
|
today := time.Now().Format("20060102")
|
||||||
today := time.Now().Format("20060102")
|
timestamp := time.Now().UnixMicro()
|
||||||
timestamp := time.Now().UnixMicro()
|
pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, temp.ArtistName, timestamp)
|
||||||
pdfFileName := fmt.Sprintf("%s%s老师的竞品报告%d.pdf", today, temp.ArtistName, timestamp)
|
pdfFilePath := "./runtime/report_pdf/" + pdfFileName
|
||||||
pdfFilePath := "./runtime/report_pdf/" + pdfFileName
|
|
||||||
|
|
||||||
// 确保目录存在
|
// 确保目录存在
|
||||||
_, err = utils.CheckDirPath("./runtime/report_pdf/", true)
|
_, err = utils.CheckDirPath("./runtime/report_pdf/", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
temp.Remark = fmt.Sprintf("创建PDF目录失败: %v", err)
|
temp.Remark = fmt.Sprintf("创建PDF目录失败: %v", err)
|
||||||
req.Reports = append(req.Reports, temp)
|
req.Reports = append(req.Reports, temp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成PDF文件
|
// 模板路径
|
||||||
fontPath := "./data/simfang.ttf"
|
templatePath := "./data/竞品报告pdf模板.pdf"
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传PDF到OSS
|
// 使用新的 GenerateCompetitorReportPDF 生成PDF
|
||||||
pdfUrl, uploadErr := upload.PutBos(pdfFilePath, upload.PdfType, true)
|
err = utils.GenerateCompetitorReportPDF(templatePath, pdfFilePath, competitorReportData)
|
||||||
if uploadErr != nil {
|
if err != nil {
|
||||||
zap.L().Error("上传PDF失败", zap.Error(uploadErr))
|
zap.L().Error("生成PDF失败", zap.Error(err))
|
||||||
temp.Remark = "上传PDF失败"
|
temp.Remark = "生成PDF失败"
|
||||||
req.Reports = append(req.Reports, temp)
|
req.Reports = append(req.Reports, temp)
|
||||||
// 清理临时PDF文件
|
continue
|
||||||
if _, err := os.Stat(pdfFilePath); err == nil {
|
}
|
||||||
os.Remove(pdfFilePath)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将上传后的PDF链接设置到请求中
|
|
||||||
temp.PdfUrl = pdfUrl
|
|
||||||
|
|
||||||
|
// 上传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文件
|
// 清理临时PDF文件
|
||||||
if _, err := os.Stat(pdfFilePath); err == nil {
|
if _, err := os.Stat(pdfFilePath); err == nil {
|
||||||
if err := os.Remove(pdfFilePath); err != nil {
|
os.Remove(pdfFilePath)
|
||||||
zap.L().Warn("删除临时PDF文件失败", zap.String("path", pdfFilePath), zap.Error(err))
|
}
|
||||||
}
|
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)
|
req.Reports = append(req.Reports, temp)
|
||||||
@ -497,7 +614,7 @@ func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
|||||||
// 通过请求对象找到对应的Excel行号
|
// 通过请求对象找到对应的Excel行号
|
||||||
if excelRowNum, ok := reportRowMap[reqReport]; ok {
|
if excelRowNum, ok := reportRowMap[reqReport]; ok {
|
||||||
// 将错误信息写入最后一列(F列)
|
// 将错误信息写入最后一列(F列)
|
||||||
excelData.SetCellValue("Sheet1", fmt.Sprintf("F%d", excelRowNum), v.Remark)
|
excelData.SetCellValue("Sheet1", fmt.Sprintf("P%d", excelRowNum), v.Remark)
|
||||||
hasValueRows[excelRowNum] = true
|
hasValueRows[excelRowNum] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user