diff --git a/consts/errors.go b/consts/errors.go index 306c8f1..a56a011 100644 --- a/consts/errors.go +++ b/consts/errors.go @@ -1,5 +1,7 @@ package consts +import "errors" + // 广告管理错误码 const ( ErrAdNotFound = 1001 // 广告不存在 @@ -32,3 +34,23 @@ const ( ErrReportExpired = 4003 // 报表已过期 ErrReportInvalidFormat = 4004 // 报表格式无效 ) + +// 配置验证错误 +var ( + ErrInvalidPriority = errors.New("优先级必须为非负数") + ErrInvalidWeight = errors.New("权重必须在0到1之间") + ErrInvalidBidAmount = errors.New("出价金额必须为非负数") + ErrInvalidBidRange = errors.New("最小出价不能大于最大出价") + ErrInvalidROAS = errors.New("ROAS必须为非负数") + ErrInvalidBudget = errors.New("预算金额必须为非负数") + ErrInvalidTimeRange = errors.New("开始时间不能大于结束时间") + ErrInvalidTimeout = errors.New("超时时间必须为正数") + ErrInvalidRetryCount = errors.New("重试次数必须为非负数") + ErrInvalidFileSize = errors.New("文件大小必须为正数") + ErrInvalidDuration = errors.New("时长必须为正数") + ErrInvalidRateLimit = errors.New("速率限制必须为正数") + ErrInvalidCommission = errors.New("佣金比例必须在0到1之间") + ErrInvalidRevShare = errors.New("收入分成比例必须在0到1之间") + ErrInvalidAge = errors.New("年龄必须为正数且最小年龄不能大于最大年龄") + ErrInvalidFrequency = errors.New("频次限制必须为非负数") +) diff --git a/model/config/config.go b/model/config/config.go index 6177577..ee67a0f 100644 --- a/model/config/config.go +++ b/model/config/config.go @@ -1,5 +1,10 @@ package config +import ( + "cid/consts" + "errors" +) + // BaseConfig 基础配置结构 type BaseConfig struct { // 优先级和权重 @@ -18,6 +23,17 @@ type BaseConfig struct { Remark string `bson:"remark" json:"remark"` // 备注 } +// Validate 基础配置验证 +func (c *BaseConfig) Validate() error { + if c.Priority < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.Weight < 0 || c.Weight > 1 { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil +} + // BiddingConfig 竞价配置 type BiddingConfig struct { // 竞价类型 @@ -31,32 +47,51 @@ type BiddingConfig struct { BidIncrement int64 `bson:"bidIncrement" json:"bidIncrement"` // 出价增量(分) // 自动优化 - AutoOptimization bool `bson:"autoOptimization" json:"autoOptimization"` // 是否自动优化 - TargetCPA int64 `bson:"targetCPA" json:"targetCPA"` // 目标CPA(分) - TargetROAS float64 `bson:"targetROAS" json:"targetROAS"` // 目标ROAS - ConversionValue int64 `bson:"conversionValue" json:"conversionValue"` // 转化价值 - AttributionWindow string `bson:"attributionWindow" json:"attributionWindow"` // 归因窗口 - OptimizationGoal string `bson:"optimizationGoal" json:"optimizationGoal"` // 优化目标:impressions、clicks、conversions、revenue等 + AutoOptimization bool `bson:"autoOptimization" json:"autoOptimization"` // 是否自动优化 + TargetCPA int64 `bson:"targetCPA" json:"targetCPA"` // 目标CPA(分) + TargetROAS float64 `bson:"targetROAS" json:"targetROAS"` // 目标ROAS + OptimizationGoal string `bson:"optimizationGoal" json:"optimizationGoal"` // 优化目标:impressions、clicks、conversions、revenue等 +} + +// Validate 竞价配置验证 +func (c *BiddingConfig) Validate() error { + if c.MinBidAmount < 0 || c.MaxBidAmount < 0 || c.DefaultBidAmount < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.MinBidAmount > c.MaxBidAmount { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.TargetROAS < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil } // BudgetConfig 预算配置 type BudgetConfig struct { // 预算设置 - TotalBudget int64 `bson:"totalBudget" json:"totalBudget"` // 总预算(分) - DailyBudget int64 `bson:"dailyBudget" json:"dailyBudget"` // 日预算(分) - HourlyBudget int64 `bson:"hourlyBudget" json:"hourlyBudget"` // 小时预算(分) + TotalBudget int64 `bson:"totalBudget" json:"totalBudget"` // 总预算(分) + DailyBudget int64 `bson:"dailyBudget" json:"dailyBudget"` // 日预算(分) // 投放节奏 PaceType string `bson:"paceType" json:"paceType"` // 投放节奏:even、accelerated、standard IsBudgetPacing bool `bson:"isBudgetPacing" json:"isBudgetPacing"` // 是否预算匀速投放 // 时间配置 - StartDate int64 `bson:"startDate" json:"startDate"` // 开始投放时间 - EndDate int64 `bson:"endDate" json:"endDate"` // 结束投放时间 - TimeSlots []string `bson:"timeSlots" json:"timeSlots"` // 投放时间段 - DaysOfWeek []int `bson:"daysOfWeek" json:"daysOfWeek"` // 投放日期(0-6,0表示周日) - Timezone string `bson:"timezone" json:"timezone"` // 时区 - IsTimeLimited bool `bson:"isTimeLimited" json:"isTimeLimited"` // 是否限时投放 + StartDate int64 `bson:"startDate" json:"startDate"` // 开始投放时间 + EndDate int64 `bson:"endDate" json:"endDate"` // 结束投放时间 + Timezone string `bson:"timezone" json:"timezone"` // 时区 +} + +// Validate 预算配置验证 +func (c *BudgetConfig) Validate() error { + if c.TotalBudget < 0 || c.DailyBudget < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.StartDate > c.EndDate { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil } // APIConfig API配置 @@ -75,8 +110,21 @@ type APIConfig struct { Headers string `bson:"headers" json:"headers"` // 请求头配置(JSON字符串) // 限流配置 - RateLimit int64 `bson:"rateLimit" json:"rateLimit"` // 速率限制 - MaxRequestsPerHour int64 `bson:"maxRequestsPerHour" json:"maxRequestsPerHour"` // 每小时最大请求数 + RateLimit int64 `bson:"rateLimit" json:"rateLimit"` // 速率限制 +} + +// Validate API配置验证 +func (c *APIConfig) Validate() error { + if c.Timeout <= 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.RetryCount < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.RateLimit <= 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil } // CreativeConfig 创意配置 @@ -87,15 +135,25 @@ type CreativeConfig struct { ExcludedCreatives []string `bson:"excludedCreatives" json:"excludedCreatives"` // 排除的创意列表 // 技术要求 - MaxFileSize int64 `bson:"maxFileSize" json:"maxFileSize"` // 最大文件大小(bytes) - MaxDuration int64 `bson:"maxDuration" json:"maxDuration"` // 最大时长(秒) - SupportedMimeTypes []string `bson:"supportedMimeTypes" json:"supportedMimeTypes"` // 支持的MIME类型 + MaxFileSize int64 `bson:"maxFileSize" json:"maxFileSize"` // 最大文件大小(bytes) + MaxDuration int64 `bson:"maxDuration" json:"maxDuration"` // 最大时长(秒) // 支持的格式 SupportedFormats []string `bson:"supportedFormats" json:"supportedFormats"` // 支持的格式 SupportedSizes []string `bson:"supportedSizes" json:"supportedSizes"` // 支持的尺寸 } +// Validate 创意配置验证 +func (c *CreativeConfig) Validate() error { + if c.MaxFileSize <= 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.MaxDuration <= 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil +} + // PaymentConfig 支付配置 type PaymentConfig struct { // 计费模式 @@ -109,10 +167,26 @@ type PaymentConfig struct { Currency string `bson:"currency" json:"currency"` // 货币单位 // 收入分成 - RevShareRate float64 `bson:"revShareRate" json:"revShareRate"` // 收入分成比例(0-1) - MinPayment int64 `bson:"minPayment" json:"minPayment"` // 最小支付金额(分) - TaxInclusive bool `bson:"taxInclusive" json:"taxInclusive"` // 是否含税 - EarlyPaymentDiscount float64 `bson:"earlyPaymentDiscount" json:"earlyPaymentDiscount"` // 提前付款折扣 + RevShareRate float64 `bson:"revShareRate" json:"revShareRate"` // 收入分成比例(0-1) + MinPayment int64 `bson:"minPayment" json:"minPayment"` // 最小支付金额(分) + TaxInclusive bool `bson:"taxInclusive" json:"taxInclusive"` // 是否含税 +} + +// Validate 支付配置验证 +func (c *PaymentConfig) Validate() error { + if c.CommissionRate < 0 || c.CommissionRate > 1 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.RevShareRate < 0 || c.RevShareRate > 1 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.MinimumBudget < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + if c.MinPayment < 0 { + return errors.New(consts.ErrInvalidConfiguration) + } + return nil } // FrequencyCapConfig 频次控制配置 diff --git a/model/dto/ad_source_dto.go b/model/dto/ad_source_dto.go index a6354ef..e4955d6 100644 --- a/model/dto/ad_source_dto.go +++ b/model/dto/ad_source_dto.go @@ -173,128 +173,13 @@ type TestAdSourceReq struct { } type TestAdSourceRes struct { - Success bool `json:"success"` // 测试是否成功 - ResponseTime int64 `json:"responseTime"` // 响应时间(毫秒) - ErrorMessage string `json:"errorMessage"` // 错误信息 - SupportedFormats []string `json:"supportedFormats"` // 支持的广告格式 - QualityMetrics *AdSourceTestMetrics `json:"qualityMetrics"` // 质量指标 + Success bool `json:"success"` // 测试是否成功 + ResponseTime int64 `json:"responseTime"` // 响应时间(毫秒) + ErrorMessage string `json:"errorMessage"` // 错误信息 + SupportedFormats []string `json:"supportedFormats"` // 支持的广告格式 } // DeleteAdSourceRes 删除广告源响应 type DeleteAdSourceRes struct { Success bool `json:"success"` // 删除是否成功 } - -// AdSourceTestMetrics 广告源测试质量指标 -type AdSourceTestMetrics struct { - SuccessRate float64 `json:"successRate"` // 成功率 - AverageResponseTime float64 `json:"averageResponseTime"` // 平均响应时间(毫秒) - FillRate float64 `json:"fillRate"` // 填充率 - CTR float64 `json:"ctr"` // 点击率 -} - -// GetAdSourceStatisticsReq 获取广告源统计数据请求 -type GetAdSourceStatisticsReq struct { - // g.Meta `path:"/adsource-statistics" method:"get" tags:"广告源管理" summary:"获取广告源统计数据" dc:"获取广告源的详细统计数据"` // 暂时注释,缺少对应的controller方法 - - Id string `json:"id" v:"required"` // 广告源ID - StartDate int64 `json:"startDate" v:"required"` // 开始日期 - EndDate int64 `json:"endDate" v:"required"` // 结束日期 - Dimension string `json:"dimension"` // 统计维度:day、week、month -} - -type GetAdSourceStatisticsRes struct { - // 概览数据 - Overview AdSourceOverviewStats `json:"overview"` - - // 趋势数据 - Trends []AdSourceTrendData `json:"trends"` - - // 性能数据 - Performance AdSourcePerformanceStats `json:"performance"` - - // 错误统计 - Errors []AdSourceErrorStats `json:"errors"` -} - -// AdSourceOverviewStats 广告源概览统计 -type AdSourceOverviewStats struct { - TotalRequests int64 `json:"totalRequests"` // 总请求数 - SuccessfulRequests int64 `json:"successfulRequests"` // 成功请求数 - FailedRequests int64 `json:"failedRequests"` // 失败请求数 - TotalImpressions int64 `json:"totalImpressions"` // 总展示次数 - TotalClicks int64 `json:"totalClicks"` // 总点击次数 - TotalConversions int64 `json:"totalConversions"` // 总转化次数 - TotalRevenue int64 `json:"totalRevenue"` // 总收入(分) - SuccessRate float64 `json:"successRate"` // 成功率 - ErrorRate float64 `json:"errorRate"` // 错误率 - CTR float64 `json:"ctr"` // 点击率 - CVR float64 `json:"cvr"` // 转化率 - FillRate float64 `json:"fillRate"` // 填充率 - eCPM int64 `json:"ecpm"` // 有效千次展示成本(分) - eCPC int64 `json:"ecpc"` // 有效点击成本(分) - AverageResponseTime float64 `json:"averageResponseTime"` // 平均响应时间(毫秒) - Uptime float64 `json:"uptime"` // 可用性(百分比) -} - -// AdSourceTrendData 广告源趋势数据 -type AdSourceTrendData struct { - Date int64 `json:"date"` // 日期 - Requests int64 `json:"requests"` // 请求数 - Impressions int64 `json:"impressions"` // 展示次数 - Clicks int64 `json:"clicks"` // 点击次数 - Conversions int64 `json:"conversions"` // 转化次数 - Revenue int64 `json:"revenue"` // 收入(分) - SuccessRate float64 `json:"successRate"` // 成功率 - ErrorRate float64 `json:"errorRate"` // 错误率 - CTR float64 `json:"ctr"` // 点击率 - CVR float64 `json:"cvr"` // 转化率 - FillRate float64 `json:"fillRate"` // 填充率 - eCPM int64 `json:"ecpm"` // 有效千次展示成本(分) - ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) -} - -// AdSourcePerformanceStats 广告源性能统计 -type AdSourcePerformanceStats struct { - // 响应时间分布 - ResponseTimeDistribution map[string]int64 `json:"responseTimeDistribution"` // 响应时间分布 - - // 错误类型统计 - ErrorTypes map[string]int64 `json:"errorTypes"` // 错误类型统计 - - // 地区性能 - RegionalPerformance map[string]AdSourceRegionalStats `json:"regionalPerformance"` // 地区性能 - - // 设备性能 - DevicePerformance map[string]AdSourceDeviceStats `json:"devicePerformance"` // 设备性能 -} - -// AdSourceErrorStats 广告源错误统计 -type AdSourceErrorStats struct { - ErrorType string `json:"errorType"` // 错误类型 - Count int64 `json:"count"` // 错误次数 - Percentage float64 `json:"percentage"` // 占比 - LastOccurred int64 `json:"lastOccurred"` // 最后发生时间 -} - -// AdSourceRegionalStats 广告源地区统计 -type AdSourceRegionalStats struct { - Region string `json:"region"` // 地区 - Requests int64 `json:"requests"` // 请求数 - Impressions int64 `json:"impressions"` // 展示次数 - Clicks int64 `json:"clicks"` // 点击次数 - Revenue int64 `json:"revenue"` // 收入(分) - CTR float64 `json:"ctr"` // 点击率 - ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) -} - -// AdSourceDeviceStats 广告源设备统计 -type AdSourceDeviceStats struct { - Device string `json:"device"` // 设备类型 - Requests int64 `json:"requests"` // 请求数 - Impressions int64 `json:"impressions"` // 展示次数 - Clicks int64 `json:"clicks"` // 点击次数 - Revenue int64 `json:"revenue"` // 收入(分) - CTR float64 `json:"ctr"` // 点击率 - ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) -} diff --git a/model/dto/ad_source_statistics_dto.go b/model/dto/ad_source_statistics_dto.go new file mode 100644 index 0000000..774565e --- /dev/null +++ b/model/dto/ad_source_statistics_dto.go @@ -0,0 +1,117 @@ +package dto + +import "github.com/gogf/gf/v2/frame/g" + +// GetAdSourceStatisticsReq 获取广告源统计数据请求 +type GetAdSourceStatisticsReq struct { + g.Meta `path:"/adsource-statistics" method:"get" tags:"广告源管理" summary:"获取广告源统计数据" dc:"获取广告源的详细统计数据"` + + Id string `json:"id" v:"required"` // 广告源ID + StartDate int64 `json:"startDate" v:"required"` // 开始日期 + EndDate int64 `json:"endDate" v:"required"` // 结束日期 + Dimension string `json:"dimension"` // 统计维度:day、week、month +} + +type GetAdSourceStatisticsRes struct { + // 概览数据 + Overview AdSourceOverviewStats `json:"overview"` + + // 趋势数据 + Trends []AdSourceTrendData `json:"trends"` + + // 性能数据 + Performance AdSourcePerformanceStats `json:"performance"` + + // 错误统计 + Errors []AdSourceErrorStats `json:"errors"` +} + +// AdSourceOverviewStats 广告源概览统计 +type AdSourceOverviewStats struct { + TotalRequests int64 `json:"totalRequests"` // 总请求数 + SuccessfulRequests int64 `json:"successfulRequests"` // 成功请求数 + FailedRequests int64 `json:"failedRequests"` // 失败请求数 + TotalImpressions int64 `json:"totalImpressions"` // 总展示次数 + TotalClicks int64 `json:"totalClicks"` // 总点击次数 + TotalConversions int64 `json:"totalConversions"` // 总转化次数 + TotalRevenue int64 `json:"totalRevenue"` // 总收入(分) + SuccessRate float64 `json:"successRate"` // 成功率 + ErrorRate float64 `json:"errorRate"` // 错误率 + CTR float64 `json:"ctr"` // 点击率 + CVR float64 `json:"cvr"` // 转化率 + FillRate float64 `json:"fillRate"` // 填充率 + ECPM int64 `json:"ecpm"` // 有效千次展示成本(分) + ECPC int64 `json:"ecpc"` // 有效点击成本(分) + AverageResponseTime float64 `json:"averageResponseTime"` // 平均响应时间(毫秒) + Uptime float64 `json:"uptime"` // 可用性(百分比) +} + +// AdSourceTrendData 广告源趋势数据 +type AdSourceTrendData struct { + Date int64 `json:"date"` // 日期 + Requests int64 `json:"requests"` // 请求数 + Impressions int64 `json:"impressions"` // 展示次数 + Clicks int64 `json:"clicks"` // 点击次数 + Conversions int64 `json:"conversions"` // 转化次数 + Revenue int64 `json:"revenue"` // 收入(分) + SuccessRate float64 `json:"successRate"` // 成功率 + ErrorRate float64 `json:"errorRate"` // 错误率 + CTR float64 `json:"ctr"` // 点击率 + CVR float64 `json:"cvr"` // 转化率 + FillRate float64 `json:"fillRate"` // 填充率 + ECPM int64 `json:"ecpm"` // 有效千次展示成本(分) + ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) +} + +// AdSourcePerformanceStats 广告源性能统计 +type AdSourcePerformanceStats struct { + // 响应时间分布 + ResponseTimeDistribution map[string]int64 `json:"responseTimeDistribution"` // 响应时间分布 + + // 错误类型统计 + ErrorTypes map[string]int64 `json:"errorTypes"` // 错误类型统计 + + // 地区性能 + RegionalPerformance map[string]AdSourceRegionalStats `json:"regionalPerformance"` // 地区性能 + + // 设备性能 + DevicePerformance map[string]AdSourceDeviceStats `json:"devicePerformance"` // 设备性能 +} + +// AdSourceErrorStats 广告源错误统计 +type AdSourceErrorStats struct { + ErrorType string `json:"errorType"` // 错误类型 + Count int64 `json:"count"` // 错误次数 + Percentage float64 `json:"percentage"` // 占比 + LastOccurred int64 `json:"lastOccurred"` // 最后发生时间 +} + +// AdSourceRegionalStats 广告源地区统计 +type AdSourceRegionalStats struct { + Region string `json:"region"` // 地区 + Requests int64 `json:"requests"` // 请求数 + Impressions int64 `json:"impressions"` // 展示次数 + Clicks int64 `json:"clicks"` // 点击次数 + Revenue int64 `json:"revenue"` // 收入(分) + CTR float64 `json:"ctr"` // 点击率 + ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) +} + +// AdSourceDeviceStats 广告源设备统计 +type AdSourceDeviceStats struct { + Device string `json:"device"` // 设备类型 + Requests int64 `json:"requests"` // 请求数 + Impressions int64 `json:"impressions"` // 展示次数 + Clicks int64 `json:"clicks"` // 点击次数 + Revenue int64 `json:"revenue"` // 收入(分) + CTR float64 `json:"ctr"` // 点击率 + ResponseTime float64 `json:"responseTime"` // 平均响应时间(毫秒) +} + +// AdSourceTestMetrics 广告源测试质量指标 +type AdSourceTestMetrics struct { + SuccessRate float64 `json:"successRate"` // 成功率 + AverageResponseTime float64 `json:"averageResponseTime"` // 平均响应时间(毫秒) + FillRate float64 `json:"fillRate"` // 填充率 + CTR float64 `json:"ctr"` // 点击率 +}