feat:批量导入竞品报告
This commit is contained in:
parent
e6ca737fb1
commit
8fa9f89db9
@ -4,18 +4,23 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fonchain-fiee/api/accountFiee"
|
||||||
"fonchain-fiee/api/bundle"
|
"fonchain-fiee/api/bundle"
|
||||||
"fonchain-fiee/api/cast"
|
"fonchain-fiee/api/cast"
|
||||||
|
"fonchain-fiee/cmd/config"
|
||||||
"fonchain-fiee/pkg/cache"
|
"fonchain-fiee/pkg/cache"
|
||||||
"fonchain-fiee/pkg/e"
|
"fonchain-fiee/pkg/e"
|
||||||
modelCast "fonchain-fiee/pkg/model/cast"
|
modelCast "fonchain-fiee/pkg/model/cast"
|
||||||
|
"fonchain-fiee/pkg/model/login"
|
||||||
"fonchain-fiee/pkg/service"
|
"fonchain-fiee/pkg/service"
|
||||||
"fonchain-fiee/pkg/utils"
|
"fonchain-fiee/pkg/utils"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/xuri/excelize/v2"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,19 +53,211 @@ func CreateCompetitiveReport(ctx *gin.Context) {
|
|||||||
|
|
||||||
// ImportCompetitiveReportBatch 批量导入竞品报告
|
// ImportCompetitiveReportBatch 批量导入竞品报告
|
||||||
func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
func ImportCompetitiveReportBatch(ctx *gin.Context) {
|
||||||
var req *cast.ImportCompetitiveReportBatchReq
|
// 获取上传的Excel文件
|
||||||
var err error
|
excelFile, err := ctx.FormFile("file")
|
||||||
if err = ctx.ShouldBind(&req); err != nil {
|
|
||||||
service.Error(ctx, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
newCtx := NewCtxWithUserInfo(ctx)
|
|
||||||
resp, err := service.CastProvider.ImportCompetitiveReportBatch(newCtx, req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
service.Error(ctx, err)
|
service.Error(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.Success(ctx, resp)
|
|
||||||
|
loginInfo := login.GetUserInfoFromC(ctx)
|
||||||
|
lockKey := fmt.Sprintf("import_competitive_report_batch:%d", loginInfo.ID)
|
||||||
|
replay := cache.RedisClient.SetNX(lockKey, time.Now().Format("20060102150405"), 5*time.Minute)
|
||||||
|
if !replay.Val() {
|
||||||
|
service.Error(ctx, errors.New("有导入任务正在进行,请稍后再试"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cache.RedisClient.Del(lockKey)
|
||||||
|
|
||||||
|
tempDir := "./runtime/report"
|
||||||
|
_, err = utils.CheckDirPath(tempDir, true)
|
||||||
|
if err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成文件名并保存文件
|
||||||
|
fileName := fmt.Sprintf("%d_competitive_report.xlsx", time.Now().UnixMicro())
|
||||||
|
excelPath := filepath.Join(tempDir, fileName)
|
||||||
|
if err = ctx.SaveUploadedFile(excelFile, excelPath); err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开Excel文件
|
||||||
|
excelData, err := excelize.OpenFile(excelPath)
|
||||||
|
if err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer excelData.Close()
|
||||||
|
|
||||||
|
// 解析Excel中的数据
|
||||||
|
rows, err := excelData.GetRows("Sheet1")
|
||||||
|
if err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化请求结构
|
||||||
|
req := cast.ImportCompetitiveReportBatchReq{
|
||||||
|
Reports: make([]*cast.CreateCompetitiveReportReq, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成结果文件URL
|
||||||
|
urlHost := config.AppConfig.System.FieeHost
|
||||||
|
urlResult := fmt.Sprintf("%s/api/fiee/static/report/%s", urlHost, fileName)
|
||||||
|
|
||||||
|
// 记录每行数据对应的Excel行号(用于后续匹配失败记录)
|
||||||
|
reportRowMap := make(map[*cast.CreateCompetitiveReportReq]int)
|
||||||
|
|
||||||
|
for line, row := range rows {
|
||||||
|
// 跳过表头
|
||||||
|
if line == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 跳过空行
|
||||||
|
if len(row) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建报告请求对象
|
||||||
|
temp := &cast.CreateCompetitiveReportReq{
|
||||||
|
Source: 2, // 来源:2 导入
|
||||||
|
}
|
||||||
|
// 记录Excel行号(line+1是因为Excel行号从1开始,且跳过表头)
|
||||||
|
excelRowNum := line + 1
|
||||||
|
reportRowMap[temp] = excelRowNum
|
||||||
|
|
||||||
|
// 解析艺人编号(B列,row[1])
|
||||||
|
var artistNum string
|
||||||
|
if len(row) > 1 && utils.CleanString(row[1]) != "" {
|
||||||
|
artistNum = utils.CleanString(row[1])
|
||||||
|
artistSubNum := utils.CleanString(row[1])
|
||||||
|
if artistSubNum == "" {
|
||||||
|
temp.Remark = "艺人编号不能为空"
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var subInfoResp *accountFiee.UserInfoResponse
|
||||||
|
subInfoResp, err := service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
|
||||||
|
SubNum: artistSubNum,
|
||||||
|
Domain: "app",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
temp.Remark = fmt.Sprintf("自媒体用户查询失败:%s", err.Error())
|
||||||
|
zap.L().Error("AccountFieeProvider.SubNumGetInfo", zap.Error(err))
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if subInfoResp == nil || subInfoResp.Id == 0 {
|
||||||
|
temp.Remark = "自媒体用户不存在"
|
||||||
|
zap.L().Error("AccountFieeProvider.SubNumGetInfo user not found", zap.String("subNum", artistSubNum))
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置艺人信息
|
||||||
|
temp.SubNum = artistSubNum
|
||||||
|
temp.ArtistID = fmt.Sprint(subInfoResp.Id)
|
||||||
|
temp.ArtistName = subInfoResp.Name
|
||||||
|
temp.ArtistPhone = subInfoResp.TelNum
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析标题(C列,row[2])
|
||||||
|
if len(row) > 2 {
|
||||||
|
temp.Title = utils.CleanString(row[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析报告内容(D列,row[3])
|
||||||
|
if len(row) > 3 {
|
||||||
|
temp.ReportContent = row[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析图片URL(E列,row[4])
|
||||||
|
if len(row) > 4 && utils.CleanString(row[4]) != "" {
|
||||||
|
temp.ImageUrl = utils.CleanString(row[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析PDF URL(F列,row[5]),可选
|
||||||
|
if len(row) > 5 && utils.CleanString(row[5]) != "" {
|
||||||
|
temp.PdfUrl = utils.CleanString(row[5])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证必填字段
|
||||||
|
if artistNum == "" {
|
||||||
|
temp.Remark = "艺人编号不能为空"
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if temp.PdfUrl == "" {
|
||||||
|
temp.Remark = "PDF URL不能为空"
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Reports = append(req.Reports, temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有数据
|
||||||
|
if len(req.Reports) == 0 {
|
||||||
|
service.Error(ctx, errors.New(e.ErrNoData))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用批量导入接口
|
||||||
|
newCtx := NewCtxWithUserInfo(ctx)
|
||||||
|
resp, err := service.CastProvider.ImportCompetitiveReportBatch(newCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有失败的数据,生成结果文件
|
||||||
|
if resp.FailCount > 0 {
|
||||||
|
hasValueRows := make(map[int]bool, resp.FailCount)
|
||||||
|
// 遍历响应结果,标记失败的行
|
||||||
|
// resp.Reports的顺序应该与req.Reports的顺序一致
|
||||||
|
for i, v := range resp.Reports {
|
||||||
|
if !v.Success {
|
||||||
|
// 根据索引找到对应的请求对象
|
||||||
|
if i < len(req.Reports) {
|
||||||
|
reqReport := req.Reports[i]
|
||||||
|
// 通过请求对象找到对应的Excel行号
|
||||||
|
if excelRowNum, ok := reportRowMap[reqReport]; ok {
|
||||||
|
// 将错误信息写入最后一列(G列,可根据实际模板调整)
|
||||||
|
excelData.SetCellValue("Sheet1", fmt.Sprintf("G%d", excelRowNum), v.Remark)
|
||||||
|
hasValueRows[excelRowNum] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除成功的行(从后往前删除,避免行号变化)
|
||||||
|
for i := len(rows) - 1; i >= 1; i-- {
|
||||||
|
if !hasValueRows[i+1] {
|
||||||
|
if err = excelData.RemoveRow("Sheet1", i+1); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 保存结果文件
|
||||||
|
resultPath := fmt.Sprintf("./runtime/report/%s", fileName)
|
||||||
|
if err = excelData.SaveAs(resultPath); err != nil {
|
||||||
|
service.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
service.Success(ctx, map[string]interface{}{
|
||||||
|
"successCount": resp.SuccessCount,
|
||||||
|
"failCount": resp.FailCount,
|
||||||
|
"resultUrl": urlResult,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user