Commit 061fb63a by 彭芳

[feat]: add ad report api

parent f493fde3
......@@ -33,8 +33,9 @@ func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*
if err != nil {
return nil, nil, err
}
campaignRepo := data.NewReportRepo(dataData, logger)
reportUsecase := biz.NewReportUsecase(campaignRepo, logger)
campaignRepo := data.NewCampaignRepo(dataData, logger)
adRepo := data.NewAdRepo(dataData, logger)
reportUsecase := biz.NewReportUsecase(campaignRepo, adRepo, logger)
reportService := service.NewReportService(reportUsecase, logger)
web := &router.Web{
Common: common,
......
......@@ -18,7 +18,7 @@ const (
StatTimeGranularityHourly TimeGranularity = "STAT_TIME_GRANULARITY_HOURLY" // 按小时维度
)
type ListCampaignRequest struct {
type ListReportRequest struct {
common.PageRequest
TimeGranularity TimeGranularity `form:"time_granularity" json:"time_granularity"` // 时间粒度(0:按天维度;1:按小时维度)
StartDate string `form:"start_date" json:"start_date"` // 开始时间(格式YYYY-MM-DD)
......@@ -36,35 +36,7 @@ type CampaignList []*Campaign
func (p CampaignList) PrepareRateAndCost() {
for _, campaign := range p {
campaign.AvgShowCost = campaign.getAvgShowCost()
campaign.AvgClickCost = campaign.getAvgClickCost()
campaign.Ctr = campaign.getCtr()
campaign.ConvertCost = campaign.getConvertCost()
campaign.ConvertRate = campaign.getConvertRate()
campaign.DeepConvertCost = campaign.getDeepConvertCost()
campaign.DeepConvertRate = campaign.getDeepConvertRate()
campaign.AttributionConvertCost = campaign.getAttributionConvertCost()
campaign.AttributionDeepConvertCost = campaign.getAttributionDeepConvertCost()
campaign.DownloadStartCost = campaign.getDownloadStartCost()
campaign.DownloadStartRate = campaign.getDownloadStartRate()
campaign.DownloadFinishCost = campaign.getDownloadFinishCost()
campaign.DownloadFinishRate = campaign.getDownloadFinishRate()
campaign.InstallFinishCost = campaign.getInstallFinishCost()
campaign.InstallFinishRate = campaign.getInstallFinishRate()
campaign.ActiveCost = campaign.getActiveCost()
campaign.ActiveRate = campaign.getActiveRate()
campaign.ActiveRegisterCost = campaign.getActiveRegisterCost()
campaign.ActiveRegisterRate = campaign.getActiveRegisterRate()
campaign.AttributionNextDayOpenCost = campaign.getAttributionNextDayOpenCost()
campaign.AttributionNextDayOpenRate = campaign.getAttributionNextDayOpenRate()
campaign.GameAddictionCost = campaign.getGameAddictionCost()
campaign.GameAddictionRate = campaign.getGameAddictionRate()
campaign.ActivePayCost = campaign.getActivePayCost()
campaign.ActivePayRate = campaign.getActivePayRate()
campaign.ValidPlayCost = campaign.getValidPlayCost()
campaign.ValidPlayRate = campaign.getValidPlayRate()
campaign.AveragePlayTimePerPlay = campaign.getAveragePlayTimePerPlay()
campaign.PlayOverRate = campaign.getPlayOverRate()
campaign.PrepareRateAndCost()
}
}
......@@ -141,6 +113,38 @@ type Campaign struct {
PlayOverRate float64 `json:"play_over_rate"` // 播完率
}
func (p *Campaign) PrepareRateAndCost() {
p.AvgShowCost = p.getAvgShowCost()
p.AvgClickCost = p.getAvgClickCost()
p.Ctr = p.getCtr()
p.ConvertCost = p.getConvertCost()
p.ConvertRate = p.getConvertRate()
p.DeepConvertCost = p.getDeepConvertCost()
p.DeepConvertRate = p.getDeepConvertRate()
p.AttributionConvertCost = p.getAttributionConvertCost()
p.AttributionDeepConvertCost = p.getAttributionDeepConvertCost()
p.DownloadStartCost = p.getDownloadStartCost()
p.DownloadStartRate = p.getDownloadStartRate()
p.DownloadFinishCost = p.getDownloadFinishCost()
p.DownloadFinishRate = p.getDownloadFinishRate()
p.InstallFinishCost = p.getInstallFinishCost()
p.InstallFinishRate = p.getInstallFinishRate()
p.ActiveCost = p.getActiveCost()
p.ActiveRate = p.getActiveRate()
p.ActiveRegisterCost = p.getActiveRegisterCost()
p.ActiveRegisterRate = p.getActiveRegisterRate()
p.AttributionNextDayOpenCost = p.getAttributionNextDayOpenCost()
p.AttributionNextDayOpenRate = p.getAttributionNextDayOpenRate()
p.GameAddictionCost = p.getGameAddictionCost()
p.GameAddictionRate = p.getGameAddictionRate()
p.ActivePayCost = p.getActivePayCost()
p.ActivePayRate = p.getActivePayRate()
p.ValidPlayCost = p.getValidPlayCost()
p.ValidPlayRate = p.getValidPlayRate()
p.AveragePlayTimePerPlay = p.getAveragePlayTimePerPlay()
p.PlayOverRate = p.getPlayOverRate()
}
func (p *Campaign) getAvgShowCost() float64 {
return calcRate(p.Cost, float64(p.Show))
}
......@@ -266,22 +270,46 @@ func calcRate(x float64, y float64) float64 {
// CampaignRepo is a Report camRepo.
type CampaignRepo interface {
List(ctx context.Context, customerId int64, req *ListCampaignRequest) (int64, CampaignList, error)
List(ctx context.Context, customerId int64, req *ListReportRequest) (int64, CampaignList, error)
}
type ListAdResponse struct {
List AdList `json:"list"` // 数据信息
PageInfo *common.PageInfo `json:"page_info"` // 页码信息
}
type AdList []*Ad
func (p AdList) PrepareRateAndCost() {
for _, ad := range p {
ad.PrepareRateAndCost()
}
}
type Ad struct {
AdId string `json:"ad_id"`
AdName string `json:"ad_name"`
Campaign
}
type AdRepo interface {
List(ctx context.Context, customerId int64, req *ListReportRequest) (int64, AdList, error)
}
// ReportUsecase is a Report usecase.
type ReportUsecase struct {
camRepo CampaignRepo
adRepo AdRepo
log *log.Helper
}
// NewReportUsecase new a Report usecase.
func NewReportUsecase(repo CampaignRepo, logger log.Logger) *ReportUsecase {
return &ReportUsecase{camRepo: repo, log: log.NewHelper(logger)}
func NewReportUsecase(repo CampaignRepo, adRepo AdRepo, logger log.Logger) *ReportUsecase {
return &ReportUsecase{camRepo: repo, adRepo: adRepo, log: log.NewHelper(logger)}
}
// ListCampaignData list campaign data.
func (p *ReportUsecase) ListCampaignData(ctx context.Context, customerId int64, req *ListCampaignRequest) (*ListCampaignResponse, error) {
func (p *ReportUsecase) ListCampaignData(ctx context.Context, customerId int64, req *ListReportRequest) (*ListCampaignResponse, error) {
p.log.WithContext(ctx).Infof("req: %v", req)
if req.StartDate != "" {
parse, err := time.Parse("2006-01-02", req.StartDate)
......@@ -308,3 +336,32 @@ func (p *ReportUsecase) ListCampaignData(ctx context.Context, customerId int64,
PageInfo: req.PageInfo(total),
}, nil
}
// ListAdData list ad data.
func (p *ReportUsecase) ListAdData(ctx context.Context, customerId int64, req *ListReportRequest) (*ListAdResponse, error) {
p.log.WithContext(ctx).Infof("req: %v", req)
if req.StartDate != "" {
parse, err := time.Parse("2006-01-02", req.StartDate)
if err != nil {
return nil, errs.ErrorArgs.WithMessage("开始时间格式错误")
}
req.StartDateLong = util.NewSecond(parse)
}
if req.EndDate != "" {
parse, err := time.Parse("2006-01-02", req.EndDate)
if err != nil {
return nil, errs.ErrorArgs.WithMessage("结束时间格式错误")
}
req.EndDateLong = util.NewSecond(parse)
}
total, list, err := p.adRepo.List(ctx, customerId, req)
if err != nil {
return nil, err
}
list.PrepareRateAndCost()
return &ListAdResponse{
List: list,
PageInfo: req.PageInfo(total),
}, nil
}
package data
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"demo/internal/biz"
)
type adRepo struct {
data *Data
log *log.Helper
}
func NewAdRepo(data *Data, logger log.Logger) biz.AdRepo {
return &adRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (p *adRepo) List(ctx context.Context, customerId int64, req *biz.ListReportRequest) (int64, biz.AdList, error) {
db := p.data.db.Table("ads_report_advertise_hour").
Select("advertise_id as ad_id,advertise_name as ad_name, campaign_id, campaign_name, advertiser_id, date_long AS stat_datetime, cost, `show`, click, `convert`, "+
"deep_convert, attribution_convert, attribution_deep_convert, download_start, download_finish, click_install, "+
"install_finish, active, register, next_day_open, next_day_open_cost, next_day_open_rate, attribution_next_day_open_cnt,"+
" game_addiction, pay_count, in_app_uv, in_app_detail_uv, in_app_cart, in_app_pay, in_app_order, attribution_game_pay_7d_count,"+
" game_pay_count, total_play, valid_play, play_25_feed_break, play_50_feed_break, play_75_feed_break, play_100_feed_break, "+
"play_duration_sum, attribution_active_pay_intra_one_day_count, attribution_active_pay_intra_one_day_amount, gmt_modified AS timestamp").
Where("customer_id = ?", customerId).
Where("is_delete = ?", 0)
// add start_date and end_date condition
if req.StartDate != "" {
db = db.Where("date_long >= ?", req.StartDateLong)
}
if req.EndDate != "" {
db = db.Where("date_long <= ?", req.EndDateLong)
}
var total int64
if err := db.Count(&total).Error; err != nil {
return 0, nil, err
}
var list biz.AdList
if err := db.Order(req.GetOrderBy("id") + " " + req.GetOrderByMode()).
Limit(req.Limit()).Offset(req.Offset()).Scan(&list).Error; err != nil {
return total, nil, err
}
return total, list, nil
}
......@@ -13,14 +13,14 @@ type campaignRepo struct {
log *log.Helper
}
func NewReportRepo(data *Data, logger log.Logger) biz.CampaignRepo {
func NewCampaignRepo(data *Data, logger log.Logger) biz.CampaignRepo {
return &campaignRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (p *campaignRepo) List(ctx context.Context, customerId int64, req *biz.ListCampaignRequest) (int64, biz.CampaignList, error) {
func (p *campaignRepo) List(ctx context.Context, customerId int64, req *biz.ListReportRequest) (int64, biz.CampaignList, error) {
tableName := "ads_report_campaign_day"
if req.TimeGranularity == biz.StatTimeGranularityHourly {
tableName = "ads_report_campaign_hour"
......
......@@ -15,7 +15,7 @@ import (
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewReportRepo)
var ProviderSet = wire.NewSet(NewData, NewCampaignRepo, NewAdRepo)
// Data .
type Data struct {
......
......@@ -29,6 +29,10 @@ func (p *Web) RouterInit(engine *gin.Engine) {
engine.GET("/hello/:name", p.Greeter.SayHello)
api := engine.Group("/api", p.Jwt.CheckToken)
{
api.POST("/report", p.Report.ListCampaignData)
report := api.Group("/report")
{
report.POST("/campaign", p.Report.ListCampaignData)
report.POST("/ad", p.Report.ListAdData)
}
}
}
......@@ -23,7 +23,7 @@ func NewReportService(uc *biz.ReportUsecase, logger log.Logger) *ReportService {
// ListCampaignData 查询广告组数据报表
func (p *ReportService) ListCampaignData(ctx *gin.Context) {
var req biz.ListCampaignRequest
var req biz.ListReportRequest
if err := ctx.ShouldBind(&req); err != nil {
p.log.Error("ShouldBind err:", err)
ResponseError(ctx, errs.ErrorArgs)
......@@ -44,3 +44,27 @@ func (p *ReportService) ListCampaignData(ctx *gin.Context) {
}
ResponseSuccess(ctx, data)
}
// ListAdData 查询广告计划数据报表
func (p *ReportService) ListAdData(ctx *gin.Context) {
var req biz.ListReportRequest
if err := ctx.ShouldBind(&req); err != nil {
p.log.Error("ShouldBind err:", err)
ResponseError(ctx, errs.ErrorArgs)
return
}
customerIdStr := ctx.GetString(util.CustomerId)
customerId, err := strconv.Atoi(customerIdStr)
if err != nil {
p.log.Error("Atoi err:", err)
ResponseError(ctx, err)
return
}
data, err := p.uc.ListAdData(ctx, int64(customerId), &req)
if err != nil {
p.log.Error("ListAdData err:", err)
ResponseError(ctx, err)
return
}
ResponseSuccess(ctx, data)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment