Files
data-engine/entities/response.go
2026-04-02 11:51:44 +08:00

159 lines
4.4 KiB
Go

package entities
import (
"encoding/json"
"fmt"
)
// APIResponse API响应
type APIResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data *ReportData `json:"data"`
}
// ReportData 报表数据
type ReportData struct {
Sum *ReportSum `json:"sum"`
Detail []*ReportDetail `json:"detail"`
TotalCount int `json:"total_count"`
}
// ReportSum 汇总数据
type ReportSum struct {
// 基础信息
T0OrderPaymentAmt string `json:"t0_order_payment_amt"`
CreativeMaterialType string `json:"creative_material_type"`
LiveName string `json:"live_name"`
AuthorID string `json:"author_id"`
PicURL string `json:"pic_url"`
PicName string `json:"pic_name"`
PicID string `json:"pic_id"`
CoverURL string `json:"cover_url"`
CoverID int64 `json:"cover_id"`
PhotoName string `json:"photo_name"`
PhotoIDStr string `json:"photo_id_str"`
PhotoID string `json:"photo_id"`
ModPriceSegment string `json:"mod_price_segment"`
AgeSegment string `json:"age_segment"`
Province string `json:"province"`
Gender string `json:"gender"`
MerchantProductID string `json:"merchant_product_id"`
ReportDateStr string `json:"report_date_str"`
CampaignID int64 `json:"campaign_id"`
CampaignName string `json:"campaign_name"`
UnitID int64 `json:"unit_id"`
UnitName string `json:"unit_name"`
CreativeID int64 `json:"creative_id"`
CreativeName string `json:"creative_name"`
// 核心指标
Impression int64 `json:"impression"`
Click int64 `json:"click"`
CostTotal float64 `json:"cost_total"`
GMV float64 `json:"gmv"`
T0GMV float64 `json:"t0_gmv"`
ROI float64 `json:"roi"`
T0ROI float64 `json:"t0_roi"`
T0OrderCnt int64 `json:"t0_order_cnt"`
// 其他指标(简化版)
PhotoClick int64 `json:"photo_click"`
ActionbarClick int64 `json:"actionbar_click"`
AdItemClick int64 `json:"ad_item_click"`
Share int64 `json:"share"`
Comment int64 `json:"comment"`
Likes int64 `json:"likes"`
PhotoClickRatio float64 `json:"photo_click_ratio"`
Play3sRatio float64 `json:"play3s_ratio"`
Play5sRatio float64 `json:"play5s_ratio"`
EffectivePlayRatio float64 `json:"effective_play_ratio"`
// 自定义字段
T0OrderPaymentAmtFloat float64 `json:"-"`
}
// ReportDetail 明细数据
type ReportDetail struct {
ReportSum
}
// UnmarshalJSON 自定义JSON解析
func (rs *ReportSum) UnmarshalJSON(data []byte) error {
temp := make(map[string]interface{})
if err := json.Unmarshal(data, &temp); err != nil {
return err
}
// 特殊处理t0_order_payment_amt字段
if val, ok := temp["t0_order_payment_amt"]; ok {
switch v := val.(type) {
case string:
rs.T0OrderPaymentAmt = v
if v != "" && v != "0" {
if f, err := stringToFloat64(v); err == nil {
rs.T0OrderPaymentAmtFloat = f
}
}
case float64:
rs.T0OrderPaymentAmt = fmt.Sprintf("%.0f", v)
rs.T0OrderPaymentAmtFloat = v
case int64:
rs.T0OrderPaymentAmt = fmt.Sprintf("%d", v)
rs.T0OrderPaymentAmtFloat = float64(v)
}
delete(temp, "t0_order_payment_amt")
}
jsonData, _ := json.Marshal(temp)
type Alias ReportSum
var alias Alias
if err := json.Unmarshal(jsonData, &alias); err != nil {
return err
}
*rs = ReportSum(alias)
return nil
}
// stringToFloat64 字符串转浮点数
func stringToFloat64(s string) (float64, error) {
var f float64
_, err := fmt.Sscanf(s, "%f", &f)
return f, err
}
// MergeData 合并多个响应数据
func MergeData(responses []*APIResponse) *APIResponse {
if len(responses) == 0 {
return &APIResponse{
Code: 0,
Message: "无数据",
Data: &ReportData{
Detail: []*ReportDetail{},
TotalCount: 0,
},
}
}
// 以第一个响应为基础
merged := &APIResponse{
Code: responses[0].Code,
Message: responses[0].Message,
Data: &ReportData{
Sum: responses[0].Data.Sum, // 汇总数据通常只取第一页的
Detail: []*ReportDetail{},
TotalCount: responses[0].Data.TotalCount,
},
}
// 合并所有明细数据
for _, resp := range responses {
if resp != nil && resp.Data != nil && resp.Data.Detail != nil {
merged.Data.Detail = append(merged.Data.Detail, resp.Data.Detail...)
}
}
return merged
}