Files
cid/service/advertisement_service.go
2025-12-06 15:24:30 +08:00

202 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"cidservice/dao"
"cidservice/model/dto"
"cidservice/model/entity"
"context"
"time"
"github.com/gogf/gf/v2/util/gconv"
)
var Advertisement = new(advertisement)
type advertisement struct{}
// Add 添加广告
func (s *advertisement) Add(ctx context.Context, req *dto.AddAdvertisementReq) (res *dto.AddAdvertisementRes, err error) {
advertisement := &entity.Advertisement{}
if err = gconv.Struct(req, advertisement); err != nil {
return
}
// 设置基础字段
now := time.Now()
advertisement.CreatedAt = now
advertisement.UpdatedAt = now
advertisement.IsDeleted = false
// 设置初始状态
advertisement.Status = "待审核"
advertisement.AuditStatus = "待审核"
// 初始化统计字段
advertisement.Impressions = 0
advertisement.Clicks = 0
advertisement.Conversions = 0
advertisement.Cost = 0
advertisement.CTR = 0
advertisement.CVR = 0
advertisement.CPM = 0
advertisement.CPC = 0
if err = dao.Advertisement.Insert(ctx, advertisement); err != nil {
return
}
res = &dto.AddAdvertisementRes{Id: advertisement.Id.Hex()}
return
}
// Update 更新广告
func (s *advertisement) Update(ctx context.Context, req *dto.UpdateAdvertisementReq) (err error) {
// 更新修改时间不需要设置DAO层会处理
return dao.Advertisement.Update(ctx, req)
}
// UpdateStatus 更新广告状态
func (s *advertisement) UpdateStatus(ctx context.Context, req *dto.UpdateAdStatusReq) (err error) {
return dao.Advertisement.UpdateStatus(ctx, req.Id, req.Status)
}
// Audit 审核广告
func (s *advertisement) Audit(ctx context.Context, req *dto.AuditAdvertisementReq) (err error) {
return dao.Advertisement.Audit(ctx, req.Id, req.AuditStatus, req.AuditReason)
}
// GetOne 获取广告详情
func (s *advertisement) GetOne(ctx context.Context, req *dto.GetAdvertisementReq) (res *dto.GetAdvertisementRes, err error) {
advertisement, err := dao.Advertisement.GetOne(ctx, req.Id)
if err != nil {
return
}
res = &dto.GetAdvertisementRes{
Advertisement: advertisement,
}
return
}
// List 获取广告列表
func (s *advertisement) List(ctx context.Context, req *dto.ListAdvertisementReq) (res *dto.ListAdvertisementRes, err error) {
list, total, err := dao.Advertisement.List(ctx, req)
if err != nil {
return
}
res = &dto.ListAdvertisementRes{
List: list,
Total: int(total),
}
return
}
// GetStatistics 获取广告统计数据
func (s *advertisement) GetStatistics(ctx context.Context, req *dto.GetAdStatisticsForAdvertisementReq) (res *dto.GetAdStatisticsForAdvertisementRes, err error) {
statReq := &dto.GetAdStatisticsReq{
StatType: "advertisement",
StatDimension: req.StatType,
TargetId: req.Id,
StartDate: req.StartDate,
EndDate: req.EndDate,
DeviceType: "",
Platform: "",
Region: "",
Gender: "",
AgeGroup: "",
SortBy: "",
SortDirection: "",
}
list, _, err := dao.AdStatistics.GetStatistics(ctx, statReq)
if err != nil {
return
}
res = &dto.GetAdStatisticsForAdvertisementRes{
Statistics: list,
}
// Total字段不存在已移除
return
}
// UpdateAdStatistics 更新广告统计
func (s *advertisement) UpdateAdStatistics(ctx context.Context, id string, impressions, clicks, conversions int64, cost int64) (err error) {
// 获取广告信息
ad, err := dao.Advertisement.GetOne(ctx, id)
if err != nil {
return
}
// 计算统计数据
totalImpressions := ad.Impressions + impressions
totalClicks := ad.Clicks + clicks
totalConversions := ad.Conversions + conversions
totalCost := ad.Cost + cost
// 计算比率
ctr := 0.0
if totalImpressions > 0 {
ctr = float64(totalClicks) / float64(totalImpressions)
}
cvr := 0.0
if totalClicks > 0 {
cvr = float64(totalConversions) / float64(totalClicks)
}
cpm := int64(0)
if totalImpressions > 0 {
cpm = totalCost * 1000 / totalImpressions
}
cpc := int64(0)
if totalClicks > 0 {
cpc = totalCost / totalClicks
}
// 构建更新数据
stats := map[string]interface{}{
"impressions": totalImpressions,
"clicks": totalClicks,
"conversions": totalConversions,
"cost": totalCost,
"ctr": ctr,
"cvr": cvr,
"cpm": cpm,
"cpc": cpc,
"updatedAt": time.Now(),
}
// 更新广告统计
err = dao.Advertisement.UpdateStatistics(ctx, id, stats)
if err != nil {
return
}
// 插入统计记录
today := time.Now()
todayStart := time.Date(today.Year(), today.Month(), today.Day(), 0, 0, 0, 0, today.Location()).Unix()
statistics := &entity.AdStatistics{
StatType: "advertisement",
StatDimension: "day",
TargetId: id,
TargetName: ad.Title,
StatDate: todayStart,
Impressions: impressions,
Clicks: clicks,
Conversions: conversions,
Cost: cost,
CTR: ctr,
CVR: cvr,
CPM: cpm,
CPC: cpc,
// CreatedAt、UpdatedAt、IsDeleted字段是嵌入字段无需单独设置
}
err = dao.AdStatistics.Upsert(ctx, statistics)
return
}