161 lines
4.2 KiB
Go
161 lines
4.2 KiB
Go
package copydata
|
||
|
||
import (
|
||
"context"
|
||
consts "dataengine/consts/public"
|
||
dto "dataengine/model/dto/copydata"
|
||
entity "dataengine/model/entity/copydata"
|
||
"errors"
|
||
|
||
"gitea.redpowerfuture.com/red-future/common/db/gfdb"
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
"github.com/sirupsen/logrus"
|
||
)
|
||
|
||
var CidAccountReportDetail = new(cidAccountReportDetailDao)
|
||
|
||
type cidAccountReportDetailDao struct{}
|
||
|
||
// Insert 插入广告数据报表详情
|
||
func (d *cidAccountReportDetailDao) Insert(ctx context.Context, req *dto.CidAccountReportDetailItem) (id int64, err error) {
|
||
var entityData *entity.CidAccountReportDetail
|
||
if err = gconv.Struct(req, &entityData); err != nil {
|
||
return
|
||
}
|
||
|
||
r, err := gfdb.DB(ctx).Model(ctx, consts.CidAccountReportDetailTable).Data(&entityData).Insert()
|
||
if err != nil {
|
||
return
|
||
}
|
||
return r.LastInsertId()
|
||
}
|
||
|
||
// BatchInsert 批量插入广告数据报表详情(使用 OnConflict 实现幂等性)
|
||
func (d *cidAccountReportDetailDao) BatchInsert(ctx context.Context, reqs []*dto.CidAccountReportDetailItem) (successCount int64, failCount int64, failedIndexes []int64, err error) {
|
||
if len(reqs) == 0 {
|
||
return 0, 0, nil, errors.New("批量插入数据不能为空")
|
||
}
|
||
|
||
// 分批处理,每批100条
|
||
batchSize := 100
|
||
successCount = 0
|
||
failCount = 0
|
||
failedIndexes = make([]int64, 0)
|
||
|
||
for i := 0; i < len(reqs); i += batchSize {
|
||
end := i + batchSize
|
||
if end > len(reqs) {
|
||
end = len(reqs)
|
||
}
|
||
|
||
batch := reqs[i:end]
|
||
entityList := make([]*entity.CidAccountReportDetail, len(batch))
|
||
|
||
for j, req := range batch {
|
||
var entityData entity.CidAccountReportDetail
|
||
if err = gconv.Struct(req, &entityData); err != nil {
|
||
failCount++
|
||
failedIndexes = append(failedIndexes, int64(i+j))
|
||
continue
|
||
}
|
||
entityList[j] = &entityData
|
||
}
|
||
|
||
if len(entityList) == 0 {
|
||
continue
|
||
}
|
||
|
||
// 执行批量插入,使用 OnConflict 实现幂等性
|
||
_, err = gfdb.DB(ctx).Model(ctx, consts.CidAccountReportDetailTable).
|
||
Data(entityList).
|
||
OnConflict(
|
||
"report_date_str",
|
||
"page_number",
|
||
"campaign_id",
|
||
"creative_id",
|
||
).
|
||
Save()
|
||
|
||
if err != nil {
|
||
logrus.Warnf("批量插入失败,尝试逐条插入: %v", err)
|
||
// 批量插入失败,尝试逐条插入
|
||
for k := range batch {
|
||
_, singleErr := d.Insert(ctx, batch[k])
|
||
if singleErr != nil {
|
||
failCount++
|
||
failedIndexes = append(failedIndexes, int64(i+k))
|
||
} else {
|
||
successCount++
|
||
}
|
||
}
|
||
} else {
|
||
successCount += int64(len(entityList))
|
||
}
|
||
}
|
||
|
||
return successCount, failCount, failedIndexes, nil
|
||
}
|
||
|
||
// DeleteByDateRange 按日期范围删除数据(用于补偿前去重)
|
||
func (d *cidAccountReportDetailDao) DeleteByDateRange(ctx context.Context, advertiserID int64, startDateStr, endDateStr string) (int64, error) {
|
||
cols := (&entity.CidAccountReportDetail{}).GetCols()
|
||
|
||
result, err := gfdb.DB(ctx).Model(ctx, consts.CidAccountReportDetailTable).
|
||
Where(cols.ReportDateStr+" >= ? AND "+cols.ReportDateStr+" <= ?", startDateStr, endDateStr).
|
||
Delete()
|
||
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
|
||
affected, _ := result.RowsAffected()
|
||
return affected, nil
|
||
}
|
||
|
||
// BatchInsertInTx 在事务中批量插入
|
||
func (d *cidAccountReportDetailDao) BatchInsertInTx(ctx context.Context, tx interface{}, reqs []*dto.CidAccountReportDetailItem) (successCount int64, failCount int64, err error) {
|
||
if len(reqs) == 0 {
|
||
return 0, 0, errors.New("批量插入数据不能为空")
|
||
}
|
||
|
||
batchSize := 100
|
||
successCount = 0
|
||
failCount = 0
|
||
|
||
for i := 0; i < len(reqs); i += batchSize {
|
||
end := i + batchSize
|
||
if end > len(reqs) {
|
||
end = len(reqs)
|
||
}
|
||
|
||
batch := reqs[i:end]
|
||
entityList := make([]*entity.CidAccountReportDetail, 0, len(batch))
|
||
|
||
for _, req := range batch {
|
||
var entityData entity.CidAccountReportDetail
|
||
if err = gconv.Struct(req, &entityData); err != nil {
|
||
failCount++
|
||
logrus.Errorf("数据转换失败: %v", err)
|
||
continue
|
||
}
|
||
entityList = append(entityList, &entityData)
|
||
}
|
||
|
||
if len(entityList) == 0 {
|
||
continue
|
||
}
|
||
|
||
_, txErr := gfdb.DB(ctx).Model(ctx, consts.CidAccountReportDetailTable).Data(entityList).Insert()
|
||
if txErr != nil {
|
||
logrus.Errorf("批量插入失败 batch[%d:%d]: %v", i, end, txErr)
|
||
failCount += int64(len(entityList))
|
||
err = txErr
|
||
continue
|
||
}
|
||
|
||
successCount += int64(len(entityList))
|
||
}
|
||
|
||
return successCount, failCount, err
|
||
}
|