代码初始化
This commit is contained in:
158
entities/response.go
Normal file
158
entities/response.go
Normal file
@@ -0,0 +1,158 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user