定时任务抽取数据
This commit is contained in:
1
go.mod
1
go.mod
@@ -8,6 +8,7 @@ require (
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.5
|
||||
github.com/gogf/gf/v2 v2.10.0
|
||||
github.com/olekukonko/errors v1.1.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
golang.org/x/net v0.47.0
|
||||
)
|
||||
|
||||
|
||||
39
scheduler/run_account_report_task.go
Normal file
39
scheduler/run_account_report_task.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cid/sync"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := gctx.New()
|
||||
syncService := sync.NewSyncService()
|
||||
|
||||
req := &sync.CampaignReportRequest{
|
||||
AdvertiserID: 10001,
|
||||
StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
EndTime: time.Now().UnixNano() / 1e6,
|
||||
SelectColumns: []string{"impression", "click", "cost", "t0GMV"},
|
||||
GroupType: 1,
|
||||
QueryVersion: 1,
|
||||
}
|
||||
|
||||
logrus.Info("=== 开始执行定时同步任务 ===")
|
||||
result, err := syncService.SyncCampaignReportWithPagination(ctx, req, true, 3)
|
||||
if err != nil {
|
||||
logrus.Errorf("定时同步任务失败:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("✓ 定时同步完成:\n")
|
||||
fmt.Printf(" 汇总数据:成功=%v, ID=%d\n", result.SumSuccess, result.SumID)
|
||||
fmt.Printf(" 明细数据:总数=%d, 成功=%d, 失败=%d\n",
|
||||
result.DetailCount, result.DetailSuccessCount, result.DetailFailCount)
|
||||
}
|
||||
@@ -68,7 +68,7 @@ func (s *cidAccountReportDetailService) BatchCreate(ctx context.Context, req *dt
|
||||
return
|
||||
}
|
||||
|
||||
// Create 创建广告数据报表汇总
|
||||
// CreateSum Create 创建广告数据报表汇总
|
||||
func (s *cidAccountReportDetailService) CreateSum(ctx context.Context, req *dto.CidAccountReportSumItem) (res *dto.CreateCidAccountReportSumRes, err error) {
|
||||
// 验证必要字段
|
||||
if req.DataType == "" {
|
||||
@@ -90,7 +90,7 @@ func (s *cidAccountReportDetailService) CreateSum(ctx context.Context, req *dto.
|
||||
return
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建广告数据报表汇总
|
||||
// BatchCreateSum 批量创建广告数据报表汇总
|
||||
func (s *cidAccountReportDetailService) BatchCreateSum(ctx context.Context, req *dto.BatchCreateCidAccountReportSumReq) (res *dto.BatchCreateCidAccountReportSumRes, err error) {
|
||||
ctx = context.WithValue(ctx, "user", &beans.User{UserName: "admin"})
|
||||
// 验证数据
|
||||
|
||||
79
sync/base_report_sync.go
Normal file
79
sync/base_report_sync.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type ReportSyncable interface {
|
||||
FetchReport(ctx context.Context, params interface{}) (interface{}, error)
|
||||
ConvertToSum(apiData interface{}, dataType string) interface{}
|
||||
ConvertToDetails(apiData interface{}, dataType string) []interface{}
|
||||
SaveSum(ctx context.Context, data interface{}) (int64, error)
|
||||
SaveDetails(ctx context.Context, data []interface{}) (successCount, failCount int64, err error)
|
||||
}
|
||||
|
||||
type BaseReportSync struct {
|
||||
httpClient *HttpClient
|
||||
}
|
||||
|
||||
func NewBaseReportSync() *BaseReportSync {
|
||||
return &BaseReportSync{
|
||||
httpClient: NewHttpClient("", 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) FetchReport(ctx context.Context, params interface{}) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) ConvertToSum(apiData interface{}, dataType string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) ConvertToDetails(apiData interface{}, dataType string) []interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) SaveSum(ctx context.Context, data interface{}) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) SaveDetails(ctx context.Context, data []interface{}) (int64, int64, error) {
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
func (b *BaseReportSync) ExecuteSync(ctx context.Context, syncer ReportSyncable, params interface{}, dataType string, useMock bool) (*SyncResult, error) {
|
||||
result := &SyncResult{}
|
||||
|
||||
apiData, err := syncer.FetchReport(ctx, params)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
return result, err
|
||||
}
|
||||
|
||||
sumData := syncer.ConvertToSum(apiData, dataType)
|
||||
if sumData != nil {
|
||||
sumID, err := syncer.SaveSum(ctx, sumData)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
return result, err
|
||||
}
|
||||
result.SumSuccess = true
|
||||
result.SumID = sumID
|
||||
}
|
||||
|
||||
detailData := syncer.ConvertToDetails(apiData, dataType)
|
||||
if len(detailData) > 0 {
|
||||
successCount, failCount, err := syncer.SaveDetails(ctx, detailData)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
return result, err
|
||||
}
|
||||
result.DetailSuccess = true
|
||||
result.DetailCount = len(detailData)
|
||||
result.DetailSuccessCount = successCount
|
||||
result.DetailFailCount = failCount
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
115
sync/campaign_report_sync.go
Normal file
115
sync/campaign_report_sync.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
dto "cid/model/dto/copydata"
|
||||
"cid/service/copydata"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type CampaignReportSync struct {
|
||||
*BaseReportSync
|
||||
converter *DataConverter
|
||||
mockGen *MockDataGenerator
|
||||
}
|
||||
|
||||
func NewCampaignReportSync() *CampaignReportSync {
|
||||
return &CampaignReportSync{
|
||||
BaseReportSync: NewBaseReportSync(),
|
||||
converter: NewDataConverter(),
|
||||
mockGen: NewMockDataGenerator(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CampaignReportSync) FetchReport(ctx context.Context, params interface{}) (interface{}, error) {
|
||||
req, ok := params.(*CampaignReportRequest)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("参数类型错误,期望 CampaignReportRequest 类型")
|
||||
}
|
||||
|
||||
useMock := false
|
||||
|
||||
if useMock {
|
||||
logrus.Info("使用 Mock 数据")
|
||||
return c.mockGen.GenerateCampaignReportResponse(), nil
|
||||
}
|
||||
|
||||
respBytes, err := NewHttpClient("https://ad.e.kuaishou.com", 0).Post(ctx, "/rest/openapi/gw/esp/report/campaignReport", req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("调用 API 失败:%w", err)
|
||||
}
|
||||
|
||||
var response CampaignReportResponse
|
||||
if err := json.Unmarshal(respBytes, &response); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败:%w", err)
|
||||
}
|
||||
|
||||
if response.Code != 0 {
|
||||
return nil, fmt.Errorf("API 返回错误:code=%d, message=%s", response.Code, response.Message)
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (c *CampaignReportSync) ConvertToSum(apiData interface{}, dataType string) interface{} {
|
||||
response, ok := apiData.(*CampaignReportResponse)
|
||||
if !ok || response.Data == nil || response.Data.Sum == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.converter.ConvertToSumItem(response.Data.Sum, dataType)
|
||||
}
|
||||
|
||||
func (c *CampaignReportSync) ConvertToDetails(apiData interface{}, dataType string) []interface{} {
|
||||
response, ok := apiData.(*CampaignReportResponse)
|
||||
if !ok || response.Data == nil || len(response.Data.Detail) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
detailItems := c.converter.ConvertToDetailItems(response.Data.Detail, dataType)
|
||||
|
||||
result := make([]interface{}, len(detailItems))
|
||||
for i, item := range detailItems {
|
||||
result[i] = item
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *CampaignReportSync) SaveSum(ctx context.Context, data interface{}) (int64, error) {
|
||||
sumItem, ok := data.(*dto.CidAccountReportSumItem)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("数据类型错误,期望 CidAccountReportSumItem 类型")
|
||||
}
|
||||
|
||||
res, err := copydata.CidAccountReportDetail.CreateSum(ctx, sumItem)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return res.Id, nil
|
||||
}
|
||||
|
||||
func (c *CampaignReportSync) SaveDetails(ctx context.Context, data []interface{}) (int64, int64, error) {
|
||||
detailItems := make([]*dto.CidAccountReportDetailItem, len(data))
|
||||
for i, item := range data {
|
||||
detailItem, ok := item.(*dto.CidAccountReportDetailItem)
|
||||
if !ok {
|
||||
return 0, 0, fmt.Errorf("第 %d 条数据类型错误", i)
|
||||
}
|
||||
detailItems[i] = detailItem
|
||||
}
|
||||
|
||||
req := &dto.BatchCreateCidAccountReportDetailReq{
|
||||
Items: detailItems,
|
||||
}
|
||||
|
||||
res, err := copydata.CidAccountReportDetail.BatchCreate(ctx, req)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return res.SuccessCount, res.FailCount, nil
|
||||
}
|
||||
235
sync/campaign_report_types.go
Normal file
235
sync/campaign_report_types.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package sync
|
||||
|
||||
type CampaignReportRequest struct {
|
||||
AdvertiserID int64 `json:"advertiser_id"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
SelectColumns []string `json:"select_columns"`
|
||||
GroupType int `json:"group_type"`
|
||||
QueryVersion int `json:"query_version"`
|
||||
SelectParam *CampaignSelectParam `json:"select_param,omitempty"`
|
||||
PageInfo *PageInfo `json:"page_info,omitempty"`
|
||||
}
|
||||
|
||||
type CampaignSelectParam struct {
|
||||
CampaignIDs []int64 `json:"campaign_ids,omitempty"`
|
||||
AuthorID int64 `json:"author_id,omitempty"`
|
||||
AdTypeStr string `json:"ad_type_str,omitempty"`
|
||||
MarketingObjective int `json:"marketing_objective,omitempty"`
|
||||
DeliveryScenario int `json:"delivery_scenario,omitempty"`
|
||||
DeliveryMethod int `json:"delivery_method,omitempty"`
|
||||
SupportType string `json:"support_type,omitempty"`
|
||||
OcpcActionType string `json:"ocpc_action_type,omitempty"`
|
||||
SpeedType string `json:"speed_type,omitempty"`
|
||||
ItemType string `json:"item_type,omitempty"`
|
||||
CreativeBuildType string `json:"creative_build_type,omitempty"`
|
||||
AdScene string `json:"ad_scene,omitempty"`
|
||||
IncrementExploreType []int `json:"increment_explore_type,omitempty"`
|
||||
}
|
||||
|
||||
type PageInfo struct {
|
||||
CurrentPage int `json:"current_page"`
|
||||
PageSize int `json:"page_size"`
|
||||
TotalCount int `json:"total_count"`
|
||||
}
|
||||
|
||||
type CampaignReportResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data *CampaignReportData `json:"data"`
|
||||
}
|
||||
|
||||
type CampaignReportData struct {
|
||||
Sum *CampaignReportSum `json:"sum"`
|
||||
Detail []*CampaignReportItem `json:"detail"`
|
||||
TotalCount int `json:"total_count"`
|
||||
}
|
||||
|
||||
type CampaignReportSum 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"`
|
||||
ItemOrderConversionRatio *float64 `json:"item_order_conversion_ratio"`
|
||||
ItemCardClickRatio *float64 `json:"item_card_click_ratio"`
|
||||
ItemCardClkCnt *int64 `json:"item_card_clk_cnt"`
|
||||
LivePlayCntCost *float64 `json:"live_play_cnt_cost"`
|
||||
AdMerchantFollowCost *float64 `json:"ad_merchant_follow_cost"`
|
||||
AdMerchantFollow *int64 `json:"ad_merchant_follow"`
|
||||
NetT0OrderCnt *int64 `json:"net_t0_order_cnt"`
|
||||
NetT0Roi *float64 `json:"net_t0_roi"`
|
||||
NetT0Gmv *float64 `json:"net_t0_gmv"`
|
||||
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"`
|
||||
AdPhotoPlayedFiveRatio *float64 `json:"ad_photo_played_five_ratio"`
|
||||
AdPhotoPlayedThreeRatio *float64 `json:"ad_photo_played_three_ratio"`
|
||||
OrderSubmitRoi *float64 `json:"order_submit_roi"`
|
||||
OrderSubmitAmt *int64 `json:"order_submit_amt"`
|
||||
EventOrderSubmitCost *float64 `json:"event_order_submit_cost"`
|
||||
EventOrderSubmit *int64 `json:"event_order_submit"`
|
||||
EventOrderPaidRoi *float64 `json:"event_order_paid_roi"`
|
||||
EventAppInvoked *int64 `json:"event_app_invoked"`
|
||||
EventAddShoppingCart *int64 `json:"event_add_shopping_cart"`
|
||||
ConversionNumCost *float64 `json:"conversion_num_cost"`
|
||||
AdEffectivePlayNum *int64 `json:"ad_effective_play_num"`
|
||||
AdItemClick *int64 `json:"ad_item_click"`
|
||||
MerchantProductId string `json:"merchant_product_id"`
|
||||
CostTotal *float64 `json:"cost_total"`
|
||||
AdShow *int64 `json:"ad_show"`
|
||||
AdShow1kCost *float64 `json:"ad_show1k_cost"`
|
||||
Impression *int64 `json:"impression"`
|
||||
PhotoClick *int64 `json:"photo_click"`
|
||||
PhotoClickRatio *float64 `json:"photo_click_ratio"`
|
||||
Click *int64 `json:"click"`
|
||||
ActionbarClick *int64 `json:"actionbar_click"`
|
||||
ActionbarClickCost *float64 `json:"actionbar_click_cost"`
|
||||
EspClickRatio *float64 `json:"esp_click_ratio"`
|
||||
ActionRatio *float64 `json:"action_ratio"`
|
||||
AdItemClickCount *int64 `json:"ad_item_click_count"`
|
||||
EspLivePlayedSeconds *int64 `json:"esp_live_played_seconds"`
|
||||
PlayedThreeSeconds *int64 `json:"played_three_seconds"`
|
||||
Play3sRatio *float64 `json:"play3s_ratio"`
|
||||
PlayedFiveSeconds *int64 `json:"played_five_seconds"`
|
||||
Play5sRatio *float64 `json:"play5s_ratio"`
|
||||
PlayedEnd *int64 `json:"played_end"`
|
||||
PlayEndRatio *float64 `json:"play_end_ratio"`
|
||||
Share *int64 `json:"share"`
|
||||
Comment *int64 `json:"comment"`
|
||||
Likes *int64 `json:"likes"`
|
||||
Report *int64 `json:"report"`
|
||||
Block *int64 `json:"block"`
|
||||
ItemNegative *int64 `json:"item_negative"`
|
||||
LiveShare *int64 `json:"live_share"`
|
||||
LiveComment *int64 `json:"live_comment"`
|
||||
LiveReward *int64 `json:"live_reward"`
|
||||
EffectivePlayCount *int64 `json:"effective_play_count"`
|
||||
EffectivePlayRatio *float64 `json:"effective_play_ratio"`
|
||||
ConversionNum *int64 `json:"conversion_num"`
|
||||
ConversionCostEsp *float64 `json:"conversion_cost_esp"`
|
||||
Roi *float64 `json:"roi"`
|
||||
Gmv *float64 `json:"gmv"`
|
||||
T0Gmv *float64 `json:"t0_gmv"`
|
||||
T1Gmv *float64 `json:"t1_gmv"`
|
||||
T7Gmv *float64 `json:"t7_gmv"`
|
||||
T15Gmv *float64 `json:"t15_gmv"`
|
||||
T30Gmv *float64 `json:"t30_gmv"`
|
||||
T0Roi *float64 `json:"t0_roi"`
|
||||
T1Roi *float64 `json:"t1_roi"`
|
||||
T7Roi *float64 `json:"t7_roi"`
|
||||
T15Roi *float64 `json:"t15_roi"`
|
||||
T30Roi *float64 `json:"t30_roi"`
|
||||
PaiedOrder *int64 `json:"paied_order"`
|
||||
OrderRatio *float64 `json:"order_ratio"`
|
||||
T0OrderCnt *int64 `json:"t0_order_cnt"`
|
||||
T0OrderCntCost *float64 `json:"t0_order_cnt_cost"`
|
||||
T0OrderCntRatio *float64 `json:"t0_order_cnt_ratio"`
|
||||
T1OrderCnt *int64 `json:"t1_order_cnt"`
|
||||
T3OrderCnt *int64 `json:"t3_order_cnt"`
|
||||
T7OrderCnt *int64 `json:"t7_order_cnt"`
|
||||
T15OrderCnt *int64 `json:"t15_order_cnt"`
|
||||
T30OrderCnt *int64 `json:"t30_order_cnt"`
|
||||
MerchantRecoFans *int64 `json:"merchant_reco_fans"`
|
||||
T1Retention *float64 `json:"t1_retention"`
|
||||
T7Retention *float64 `json:"t7_retention"`
|
||||
T15Retention *float64 `json:"t15_retention"`
|
||||
T30Retention *float64 `json:"t30_retention"`
|
||||
T1RetentionRatio *float64 `json:"t1_retention_ratio"`
|
||||
T7RetentionRatio *float64 `json:"t7_retention_ratio"`
|
||||
T15RetentionRatio *float64 `json:"t15_retention_ratio"`
|
||||
T30RetentionRatio *float64 `json:"t30_retention_ratio"`
|
||||
ReservationSuccess *int64 `json:"reservation_success"`
|
||||
ReservationCost *float64 `json:"reservation_cost"`
|
||||
StandardLivePlayedStarted *int64 `json:"standard_live_played_started"`
|
||||
AdLivePlayCnt *int64 `json:"ad_live_play_cnt"`
|
||||
AdLivePlayCntCost *float64 `json:"ad_live_play_cnt_cost"`
|
||||
LiveAudienceCost *float64 `json:"live_audience_cost"`
|
||||
LiveEventGoodsView *int64 `json:"live_event_goods_view"`
|
||||
GoodsClickRatio *float64 `json:"goods_click_ratio"`
|
||||
DirectAttrPlatNewBuyerCnt *int64 `json:"direct_attr_plat_new_buyer_cnt"`
|
||||
T30AttrPlatTotalBuyerCnt *int64 `json:"t30_attr_plat_total_buyer_cnt"`
|
||||
DirectAttrSellerNewBuyerCnt *int64 `json:"direct_attr_seller_new_buyer_cnt"`
|
||||
T30AttrSellerTotalBuyerCnt *int64 `json:"t30_attr_seller_total_buyer_cnt"`
|
||||
T3Gmv *float64 `json:"t3_gmv"`
|
||||
T3Roi *float64 `json:"t3_roi"`
|
||||
T7IndirectOrderAmt *float64 `json:"t7_indirect_order_amt"`
|
||||
T7IndirectOrderCnt *int64 `json:"t7_indirect_order_cnt"`
|
||||
FansT0GmvPerFans *float64 `json:"fans_t0_gmv_per_fans"`
|
||||
FansT3GmvPerFans *float64 `json:"fans_t3_gmv_per_fans"`
|
||||
FansT7GmvPerFans *float64 `json:"fans_t7_gmv_per_fans"`
|
||||
FansT15GmvPerFans *float64 `json:"fans_t15_gmv_per_fans"`
|
||||
FansT30GmvPerFans *float64 `json:"fans_t30_gmv_per_fans"`
|
||||
RecoFansCost *float64 `json:"reco_fans_cost"`
|
||||
QcpxWhiteboxDirectOrderPaymentAmt *float64 `json:"qcpx_whitebox_direct_order_payment_amt"`
|
||||
QcpxWhiteboxDirectOrderCnt *int64 `json:"qcpx_whitebox_direct_order_cnt"`
|
||||
FansT0Gmv *float64 `json:"fans_t0_gmv"`
|
||||
FansT1Gmv *float64 `json:"fans_t1_gmv"`
|
||||
FansT7Gmv *float64 `json:"fans_t7_gmv"`
|
||||
FansT15Gmv *float64 `json:"fans_t15_gmv"`
|
||||
FansT30Gmv *float64 `json:"fans_t30_gmv"`
|
||||
FansT0Roi *float64 `json:"fans_t0_roi"`
|
||||
FansT1Roi *float64 `json:"fans_t1_roi"`
|
||||
FansT7Roi *float64 `json:"fans_t7_roi"`
|
||||
FansT15Roi *float64 `json:"fans_t15_roi"`
|
||||
FansT30Roi *float64 `json:"fans_t30_roi"`
|
||||
T0ShopNewBuyerOrderPaymentAmt *float64 `json:"t0_shop_new_buyer_order_payment_amt"`
|
||||
T1ShopNewBuyerOrderPaymentAmt *float64 `json:"t1_shop_new_buyer_order_payment_amt"`
|
||||
T3ShopNewBuyerOrderPaymentAmt *float64 `json:"t3_shop_new_buyer_order_payment_amt"`
|
||||
T7ShopNewBuyerOrderPaymentAmt *float64 `json:"t7_shop_new_buyer_order_payment_amt"`
|
||||
T15ShopNewBuyerOrderPaymentAmt *float64 `json:"t15_shop_new_buyer_order_payment_amt"`
|
||||
T30ShopNewBuyerOrderPaymentAmt *float64 `json:"t30_shop_new_buyer_order_payment_amt"`
|
||||
T0ShopNewBuyerOrderCnt *int64 `json:"t0_shop_new_buyer_order_cnt"`
|
||||
T1ShopNewBuyerOrderCnt *int64 `json:"t1_shop_new_buyer_order_cnt"`
|
||||
T3ShopNewBuyerOrderCnt *int64 `json:"t3_shop_new_buyer_order_cnt"`
|
||||
T7ShopNewBuyerOrderCnt *int64 `json:"t7_shop_new_buyer_order_cnt"`
|
||||
T15ShopNewBuyerOrderCnt *int64 `json:"t15_shop_new_buyer_order_cnt"`
|
||||
T30ShopNewBuyerOrderCnt *int64 `json:"t30_shop_new_buyer_order_cnt"`
|
||||
T1NewBuyerRepurchaseRatio *float64 `json:"t1_new_buyer_repurchase_ratio"`
|
||||
T3NewBuyerRepurchaseRatio *float64 `json:"t3_new_buyer_repurchase_ratio"`
|
||||
T7NewBuyerRepurchaseRatio *float64 `json:"t7_new_buyer_repurchase_ratio"`
|
||||
T15NewBuyerRepurchaseRatio *float64 `json:"t15_new_buyer_repurchase_ratio"`
|
||||
T30NewBuyerRepurchaseRatio *float64 `json:"t30_new_buyer_repurchase_ratio"`
|
||||
T0ShopNewBuyerRoi *float64 `json:"t0_shop_new_buyer_roi"`
|
||||
T1ShopNewBuyerRoi *float64 `json:"t1_shop_new_buyer_roi"`
|
||||
T3ShopNewBuyerRoi *float64 `json:"t3_shop_new_buyer_roi"`
|
||||
T7ShopNewBuyerRoi *float64 `json:"t7_shop_new_buyer_roi"`
|
||||
T15ShopNewBuyerRoi *float64 `json:"t15_shop_new_buyer_roi"`
|
||||
T30ShopNewBuyerRoi *float64 `json:"t30_shop_new_buyer_roi"`
|
||||
CreateCardOrderCnt *int64 `json:"create_card_order_cnt"`
|
||||
ForwardTsCreateCardOrderCnt *int64 `json:"forward_ts_create_card_order_cnt"`
|
||||
CreateCardOrderCost *float64 `json:"create_card_order_cost"`
|
||||
ForwardTsCreateCardOrderCost *float64 `json:"forward_ts_create_card_order_cost"`
|
||||
ActivateCardOrderCnt *int64 `json:"activate_card_order_cnt"`
|
||||
ForwardTsActivateCardOrderCnt *int64 `json:"forward_ts_activate_card_order_cnt"`
|
||||
ActivateCardOrderCost *float64 `json:"activate_card_order_cost"`
|
||||
ForwardTsActivateCardOrderCost *float64 `json:"forward_ts_activate_card_order_cost"`
|
||||
CreateCardOrderRatio *float64 `json:"create_card_order_ratio"`
|
||||
ForwardTsCreateCardOrderRatio *float64 `json:"forward_ts_create_card_order_ratio"`
|
||||
ActivateCardOrderCntRatio *float64 `json:"activate_card_order_cnt_ratio"`
|
||||
ForwardTsActivateCardOrderRatio *float64 `json:"forward_ts_activate_card_order_ratio"`
|
||||
LivePlayCnt *int64 `json:"live_play_cnt"`
|
||||
ItemEntranceClkCnt *int64 `json:"item_entrance_clk_cnt"`
|
||||
ShowCnt *int64 `json:"show_cnt"`
|
||||
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"`
|
||||
CidActualRoiAfterSubsidy *float64 `json:"cid_actual_roi_after_subsidy"`
|
||||
CidCouponAmount *int64 `json:"cid_coupon_amount"`
|
||||
CidCouponCallbackPaidRefundAmount *int64 `json:"cid_coupon_callback_paid_refund_amount"`
|
||||
CidVoucherCost *float64 `json:"cid_voucher_cost"`
|
||||
}
|
||||
|
||||
type CampaignReportItem CampaignReportSum
|
||||
415
sync/data_converter.go
Normal file
415
sync/data_converter.go
Normal file
@@ -0,0 +1,415 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"cid/model/dto/copydata"
|
||||
)
|
||||
|
||||
type DataConverter struct{}
|
||||
|
||||
func NewDataConverter() *DataConverter {
|
||||
return &DataConverter{}
|
||||
}
|
||||
|
||||
func (c *DataConverter) ConvertToSumItem(apiData *CampaignReportSum, dataType string) *copydata.CidAccountReportSumItem {
|
||||
if apiData == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ©data.CidAccountReportSumItem{
|
||||
DataType: dataType,
|
||||
T0OrderPaymentAmt: apiData.T0OrderPaymentAmt,
|
||||
CreativeMaterialType: apiData.CreativeMaterialType,
|
||||
LiveName: apiData.LiveName,
|
||||
AuthorId: apiData.AuthorId,
|
||||
PicUrl: apiData.PicUrl,
|
||||
PicName: apiData.PicName,
|
||||
PicId: apiData.PicId,
|
||||
CoverUrl: apiData.CoverUrl,
|
||||
CoverId: apiData.CoverId,
|
||||
ItemOrderConversionRatio: apiData.ItemOrderConversionRatio,
|
||||
ItemCardClickRatio: apiData.ItemCardClickRatio,
|
||||
ItemCardClkCnt: apiData.ItemCardClkCnt,
|
||||
LivePlayCntCost: apiData.LivePlayCntCost,
|
||||
AdMerchantFollowCost: apiData.AdMerchantFollowCost,
|
||||
AdMerchantFollow: apiData.AdMerchantFollow,
|
||||
NetT0OrderCnt: apiData.NetT0OrderCnt,
|
||||
NetT0Roi: apiData.NetT0Roi,
|
||||
NetT0Gmv: apiData.NetT0Gmv,
|
||||
PhotoName: apiData.PhotoName,
|
||||
PhotoIdStr: apiData.PhotoIdStr,
|
||||
PhotoId: apiData.PhotoId,
|
||||
ModPriceSegment: apiData.ModPriceSegment,
|
||||
AgeSegment: apiData.AgeSegment,
|
||||
Province: apiData.Province,
|
||||
Gender: apiData.Gender,
|
||||
AdPhotoPlayedFiveRatio: apiData.AdPhotoPlayedFiveRatio,
|
||||
AdPhotoPlayedThreeRatio: apiData.AdPhotoPlayedThreeRatio,
|
||||
OrderSubmitRoi: apiData.OrderSubmitRoi,
|
||||
OrderSubmitAmt: apiData.OrderSubmitAmt,
|
||||
EventOrderSubmitCost: apiData.EventOrderSubmitCost,
|
||||
EventOrderSubmit: apiData.EventOrderSubmit,
|
||||
EventOrderPaidRoi: apiData.EventOrderPaidRoi,
|
||||
EventAppInvoked: apiData.EventAppInvoked,
|
||||
EventAddShoppingCart: apiData.EventAddShoppingCart,
|
||||
ConversionNumCost: apiData.ConversionNumCost,
|
||||
AdEffectivePlayNum: apiData.AdEffectivePlayNum,
|
||||
AdItemClick: apiData.AdItemClick,
|
||||
MerchantProductId: apiData.MerchantProductId,
|
||||
CostTotal: apiData.CostTotal,
|
||||
AdShow: apiData.AdShow,
|
||||
AdShow1kCost: apiData.AdShow1kCost,
|
||||
Impression: apiData.Impression,
|
||||
PhotoClick: apiData.PhotoClick,
|
||||
PhotoClickRatio: apiData.PhotoClickRatio,
|
||||
Click: apiData.Click,
|
||||
ActionbarClick: apiData.ActionbarClick,
|
||||
ActionbarClickCost: apiData.ActionbarClickCost,
|
||||
EspClickRatio: apiData.EspClickRatio,
|
||||
ActionRatio: apiData.ActionRatio,
|
||||
AdItemClickCount: apiData.AdItemClickCount,
|
||||
EspLivePlayedSeconds: apiData.EspLivePlayedSeconds,
|
||||
PlayedThreeSeconds: apiData.PlayedThreeSeconds,
|
||||
Play3sRatio: apiData.Play3sRatio,
|
||||
PlayedFiveSeconds: apiData.PlayedFiveSeconds,
|
||||
Play5sRatio: apiData.Play5sRatio,
|
||||
PlayedEnd: apiData.PlayedEnd,
|
||||
PlayEndRatio: apiData.PlayEndRatio,
|
||||
Share: apiData.Share,
|
||||
Comment: apiData.Comment,
|
||||
Likes: apiData.Likes,
|
||||
Report: apiData.Report,
|
||||
Block: apiData.Block,
|
||||
ItemNegative: apiData.ItemNegative,
|
||||
LiveShare: apiData.LiveShare,
|
||||
LiveComment: apiData.LiveComment,
|
||||
LiveReward: apiData.LiveReward,
|
||||
EffectivePlayCount: apiData.EffectivePlayCount,
|
||||
EffectivePlayRatio: apiData.EffectivePlayRatio,
|
||||
ConversionNum: apiData.ConversionNum,
|
||||
ConversionCostEsp: apiData.ConversionCostEsp,
|
||||
Roi: apiData.Roi,
|
||||
Gmv: apiData.Gmv,
|
||||
T0Gmv: apiData.T0Gmv,
|
||||
T1Gmv: apiData.T1Gmv,
|
||||
T3Gmv: apiData.T3Gmv,
|
||||
T7Gmv: apiData.T7Gmv,
|
||||
T15Gmv: apiData.T15Gmv,
|
||||
T30Gmv: apiData.T30Gmv,
|
||||
T0Roi: apiData.T0Roi,
|
||||
T1Roi: apiData.T1Roi,
|
||||
T3Roi: apiData.T3Roi,
|
||||
T7Roi: apiData.T7Roi,
|
||||
T15Roi: apiData.T15Roi,
|
||||
T30Roi: apiData.T30Roi,
|
||||
PaiedOrder: apiData.PaiedOrder,
|
||||
OrderRatio: apiData.OrderRatio,
|
||||
T0OrderCnt: apiData.T0OrderCnt,
|
||||
T0OrderCntCost: apiData.T0OrderCntCost,
|
||||
T0OrderCntRatio: apiData.T0OrderCntRatio,
|
||||
T1OrderCnt: apiData.T1OrderCnt,
|
||||
T3OrderCnt: apiData.T3OrderCnt,
|
||||
T7OrderCnt: apiData.T7OrderCnt,
|
||||
T15OrderCnt: apiData.T15OrderCnt,
|
||||
T30OrderCnt: apiData.T30OrderCnt,
|
||||
MerchantRecoFans: apiData.MerchantRecoFans,
|
||||
T1Retention: apiData.T1Retention,
|
||||
T7Retention: apiData.T7Retention,
|
||||
T15Retention: apiData.T15Retention,
|
||||
T30Retention: apiData.T30Retention,
|
||||
T1RetentionRatio: apiData.T1RetentionRatio,
|
||||
T7RetentionRatio: apiData.T7RetentionRatio,
|
||||
T15RetentionRatio: apiData.T15RetentionRatio,
|
||||
T30RetentionRatio: apiData.T30RetentionRatio,
|
||||
ReservationSuccess: apiData.ReservationSuccess,
|
||||
ReservationCost: apiData.ReservationCost,
|
||||
StandardLivePlayedStarted: apiData.StandardLivePlayedStarted,
|
||||
AdLivePlayCnt: apiData.AdLivePlayCnt,
|
||||
AdLivePlayCntCost: apiData.AdLivePlayCntCost,
|
||||
LiveAudienceCost: apiData.LiveAudienceCost,
|
||||
LiveEventGoodsView: apiData.LiveEventGoodsView,
|
||||
GoodsClickRatio: apiData.GoodsClickRatio,
|
||||
DirectAttrPlatNewBuyerCnt: apiData.DirectAttrPlatNewBuyerCnt,
|
||||
T30AttrPlatTotalBuyerCnt: apiData.T30AttrPlatTotalBuyerCnt,
|
||||
DirectAttrSellerNewBuyerCnt: apiData.DirectAttrSellerNewBuyerCnt,
|
||||
T30AttrSellerTotalBuyerCnt: apiData.T30AttrSellerTotalBuyerCnt,
|
||||
T7IndirectOrderAmt: apiData.T7IndirectOrderAmt,
|
||||
T7IndirectOrderCnt: apiData.T7IndirectOrderCnt,
|
||||
FansT0GmvPerFans: apiData.FansT0GmvPerFans,
|
||||
FansT3GmvPerFans: apiData.FansT3GmvPerFans,
|
||||
FansT7GmvPerFans: apiData.FansT7GmvPerFans,
|
||||
FansT15GmvPerFans: apiData.FansT15GmvPerFans,
|
||||
FansT30GmvPerFans: apiData.FansT30GmvPerFans,
|
||||
RecoFansCost: apiData.RecoFansCost,
|
||||
QcpxWhiteboxDirectOrderPaymentAmt: apiData.QcpxWhiteboxDirectOrderPaymentAmt,
|
||||
QcpxWhiteboxDirectOrderCnt: apiData.QcpxWhiteboxDirectOrderCnt,
|
||||
FansT0Gmv: apiData.FansT0Gmv,
|
||||
FansT1Gmv: apiData.FansT1Gmv,
|
||||
FansT7Gmv: apiData.FansT7Gmv,
|
||||
FansT15Gmv: apiData.FansT15Gmv,
|
||||
FansT30Gmv: apiData.FansT30Gmv,
|
||||
FansT0Roi: apiData.FansT0Roi,
|
||||
FansT1Roi: apiData.FansT1Roi,
|
||||
FansT7Roi: apiData.FansT7Roi,
|
||||
FansT15Roi: apiData.FansT15Roi,
|
||||
FansT30Roi: apiData.FansT30Roi,
|
||||
T0ShopNewBuyerOrderPaymentAmt: apiData.T0ShopNewBuyerOrderPaymentAmt,
|
||||
T1ShopNewBuyerOrderPaymentAmt: apiData.T1ShopNewBuyerOrderPaymentAmt,
|
||||
T3ShopNewBuyerOrderPaymentAmt: apiData.T3ShopNewBuyerOrderPaymentAmt,
|
||||
T7ShopNewBuyerOrderPaymentAmt: apiData.T7ShopNewBuyerOrderPaymentAmt,
|
||||
T15ShopNewBuyerOrderPaymentAmt: apiData.T15ShopNewBuyerOrderPaymentAmt,
|
||||
T30ShopNewBuyerOrderPaymentAmt: apiData.T30ShopNewBuyerOrderPaymentAmt,
|
||||
T0ShopNewBuyerOrderCnt: apiData.T0ShopNewBuyerOrderCnt,
|
||||
T1ShopNewBuyerOrderCnt: apiData.T1ShopNewBuyerOrderCnt,
|
||||
T3ShopNewBuyerOrderCnt: apiData.T3ShopNewBuyerOrderCnt,
|
||||
T7ShopNewBuyerOrderCnt: apiData.T7ShopNewBuyerOrderCnt,
|
||||
T15ShopNewBuyerOrderCnt: apiData.T15ShopNewBuyerOrderCnt,
|
||||
T30ShopNewBuyerOrderCnt: apiData.T30ShopNewBuyerOrderCnt,
|
||||
T1NewBuyerRepurchaseRatio: apiData.T1NewBuyerRepurchaseRatio,
|
||||
T3NewBuyerRepurchaseRatio: apiData.T3NewBuyerRepurchaseRatio,
|
||||
T7NewBuyerRepurchaseRatio: apiData.T7NewBuyerRepurchaseRatio,
|
||||
T15NewBuyerRepurchaseRatio: apiData.T15NewBuyerRepurchaseRatio,
|
||||
T30NewBuyerRepurchaseRatio: apiData.T30NewBuyerRepurchaseRatio,
|
||||
T0ShopNewBuyerRoi: apiData.T0ShopNewBuyerRoi,
|
||||
T1ShopNewBuyerRoi: apiData.T1ShopNewBuyerRoi,
|
||||
T3ShopNewBuyerRoi: apiData.T3ShopNewBuyerRoi,
|
||||
T7ShopNewBuyerRoi: apiData.T7ShopNewBuyerRoi,
|
||||
T15ShopNewBuyerRoi: apiData.T15ShopNewBuyerRoi,
|
||||
T30ShopNewBuyerRoi: apiData.T30ShopNewBuyerRoi,
|
||||
CreateCardOrderCnt: apiData.CreateCardOrderCnt,
|
||||
ForwardTsCreateCardOrderCnt: apiData.ForwardTsCreateCardOrderCnt,
|
||||
CreateCardOrderCost: apiData.CreateCardOrderCost,
|
||||
ForwardTsCreateCardOrderCost: apiData.ForwardTsCreateCardOrderCost,
|
||||
ActivateCardOrderCnt: apiData.ActivateCardOrderCnt,
|
||||
ForwardTsActivateCardOrderCnt: apiData.ForwardTsActivateCardOrderCnt,
|
||||
ActivateCardOrderCost: apiData.ActivateCardOrderCost,
|
||||
ForwardTsActivateCardOrderCost: apiData.ForwardTsActivateCardOrderCost,
|
||||
CreateCardOrderRatio: apiData.CreateCardOrderRatio,
|
||||
ForwardTsCreateCardOrderRatio: apiData.ForwardTsCreateCardOrderRatio,
|
||||
ActivateCardOrderCntRatio: apiData.ActivateCardOrderCntRatio,
|
||||
ForwardTsActivateCardOrderRatio: apiData.ForwardTsActivateCardOrderRatio,
|
||||
LivePlayCnt: apiData.LivePlayCnt,
|
||||
ItemEntranceClkCnt: apiData.ItemEntranceClkCnt,
|
||||
ShowCnt: apiData.ShowCnt,
|
||||
ReportDateStr: apiData.ReportDateStr,
|
||||
CampaignId: apiData.CampaignId,
|
||||
CampaignName: apiData.CampaignName,
|
||||
UnitId: apiData.UnitId,
|
||||
UnitName: apiData.UnitName,
|
||||
CreativeId: apiData.CreativeId,
|
||||
CreativeName: apiData.CreativeName,
|
||||
CidActualRoiAfterSubsidy: apiData.CidActualRoiAfterSubsidy,
|
||||
CidCouponAmount: apiData.CidCouponAmount,
|
||||
CidCouponCallbackPaidRefundAmount: apiData.CidCouponCallbackPaidRefundAmount,
|
||||
CidVoucherCost: apiData.CidVoucherCost,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *DataConverter) ConvertToDetailItems(apiItems []*CampaignReportItem, dataType string) []*copydata.CidAccountReportDetailItem {
|
||||
if len(apiItems) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]*copydata.CidAccountReportDetailItem, 0, len(apiItems))
|
||||
for _, item := range apiItems {
|
||||
detailItem := c.convertItemToDetail(item, dataType)
|
||||
result = append(result, detailItem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *DataConverter) convertItemToDetail(apiItem *CampaignReportItem, dataType string) *copydata.CidAccountReportDetailItem {
|
||||
if apiItem == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
item := (*CampaignReportSum)(apiItem)
|
||||
sumItem := c.ConvertToSumItem(item, dataType)
|
||||
|
||||
return ©data.CidAccountReportDetailItem{
|
||||
DataType: sumItem.DataType,
|
||||
T0OrderPaymentAmt: sumItem.T0OrderPaymentAmt,
|
||||
CreativeMaterialType: sumItem.CreativeMaterialType,
|
||||
LiveName: sumItem.LiveName,
|
||||
AuthorId: sumItem.AuthorId,
|
||||
PicUrl: sumItem.PicUrl,
|
||||
PicName: sumItem.PicName,
|
||||
PicId: sumItem.PicId,
|
||||
CoverUrl: sumItem.CoverUrl,
|
||||
CoverId: sumItem.CoverId,
|
||||
ItemOrderConversionRatio: sumItem.ItemOrderConversionRatio,
|
||||
ItemCardClickRatio: sumItem.ItemCardClickRatio,
|
||||
ItemCardClkCnt: sumItem.ItemCardClkCnt,
|
||||
LivePlayCntCost: sumItem.LivePlayCntCost,
|
||||
AdMerchantFollowCost: sumItem.AdMerchantFollowCost,
|
||||
AdMerchantFollow: sumItem.AdMerchantFollow,
|
||||
NetT0OrderCnt: sumItem.NetT0OrderCnt,
|
||||
NetT0Roi: sumItem.NetT0Roi,
|
||||
NetT0Gmv: sumItem.NetT0Gmv,
|
||||
PhotoName: sumItem.PhotoName,
|
||||
PhotoIdStr: sumItem.PhotoIdStr,
|
||||
PhotoId: sumItem.PhotoId,
|
||||
ModPriceSegment: sumItem.ModPriceSegment,
|
||||
AgeSegment: sumItem.AgeSegment,
|
||||
Province: sumItem.Province,
|
||||
Gender: sumItem.Gender,
|
||||
AdPhotoPlayedFiveRatio: sumItem.AdPhotoPlayedFiveRatio,
|
||||
AdPhotoPlayedThreeRatio: sumItem.AdPhotoPlayedThreeRatio,
|
||||
OrderSubmitRoi: sumItem.OrderSubmitRoi,
|
||||
OrderSubmitAmt: sumItem.OrderSubmitAmt,
|
||||
EventOrderSubmitCost: sumItem.EventOrderSubmitCost,
|
||||
EventOrderSubmit: sumItem.EventOrderSubmit,
|
||||
EventOrderPaidRoi: sumItem.EventOrderPaidRoi,
|
||||
EventAppInvoked: sumItem.EventAppInvoked,
|
||||
EventAddShoppingCart: sumItem.EventAddShoppingCart,
|
||||
ConversionNumCost: sumItem.ConversionNumCost,
|
||||
AdEffectivePlayNum: sumItem.AdEffectivePlayNum,
|
||||
AdItemClick: sumItem.AdItemClick,
|
||||
MerchantProductId: sumItem.MerchantProductId,
|
||||
CostTotal: sumItem.CostTotal,
|
||||
AdShow: sumItem.AdShow,
|
||||
AdShow1kCost: sumItem.AdShow1kCost,
|
||||
Impression: sumItem.Impression,
|
||||
PhotoClick: sumItem.PhotoClick,
|
||||
PhotoClickRatio: sumItem.PhotoClickRatio,
|
||||
Click: sumItem.Click,
|
||||
ActionbarClick: sumItem.ActionbarClick,
|
||||
ActionbarClickCost: sumItem.ActionbarClickCost,
|
||||
EspClickRatio: sumItem.EspClickRatio,
|
||||
ActionRatio: sumItem.ActionRatio,
|
||||
AdItemClickCount: sumItem.AdItemClickCount,
|
||||
EspLivePlayedSeconds: sumItem.EspLivePlayedSeconds,
|
||||
PlayedThreeSeconds: sumItem.PlayedThreeSeconds,
|
||||
Play3sRatio: sumItem.Play3sRatio,
|
||||
PlayedFiveSeconds: sumItem.PlayedFiveSeconds,
|
||||
Play5sRatio: sumItem.Play5sRatio,
|
||||
PlayedEnd: sumItem.PlayedEnd,
|
||||
PlayEndRatio: sumItem.PlayEndRatio,
|
||||
Share: sumItem.Share,
|
||||
Comment: sumItem.Comment,
|
||||
Likes: sumItem.Likes,
|
||||
Report: sumItem.Report,
|
||||
Block: sumItem.Block,
|
||||
ItemNegative: sumItem.ItemNegative,
|
||||
LiveShare: sumItem.LiveShare,
|
||||
LiveComment: sumItem.LiveComment,
|
||||
LiveReward: sumItem.LiveReward,
|
||||
EffectivePlayCount: sumItem.EffectivePlayCount,
|
||||
EffectivePlayRatio: sumItem.EffectivePlayRatio,
|
||||
ConversionNum: sumItem.ConversionNum,
|
||||
ConversionCostEsp: sumItem.ConversionCostEsp,
|
||||
Roi: sumItem.Roi,
|
||||
Gmv: sumItem.Gmv,
|
||||
T0Gmv: sumItem.T0Gmv,
|
||||
T1Gmv: sumItem.T1Gmv,
|
||||
T3Gmv: sumItem.T3Gmv,
|
||||
T7Gmv: sumItem.T7Gmv,
|
||||
T15Gmv: sumItem.T15Gmv,
|
||||
T30Gmv: sumItem.T30Gmv,
|
||||
T0Roi: sumItem.T0Roi,
|
||||
T1Roi: sumItem.T1Roi,
|
||||
T3Roi: sumItem.T3Roi,
|
||||
T7Roi: sumItem.T7Roi,
|
||||
T15Roi: sumItem.T15Roi,
|
||||
T30Roi: sumItem.T30Roi,
|
||||
PaiedOrder: sumItem.PaiedOrder,
|
||||
OrderRatio: sumItem.OrderRatio,
|
||||
T0OrderCnt: sumItem.T0OrderCnt,
|
||||
T0OrderCntCost: sumItem.T0OrderCntCost,
|
||||
T0OrderCntRatio: sumItem.T0OrderCntRatio,
|
||||
T1OrderCnt: sumItem.T1OrderCnt,
|
||||
T3OrderCnt: sumItem.T3OrderCnt,
|
||||
T7OrderCnt: sumItem.T7OrderCnt,
|
||||
T15OrderCnt: sumItem.T15OrderCnt,
|
||||
T30OrderCnt: sumItem.T30OrderCnt,
|
||||
MerchantRecoFans: sumItem.MerchantRecoFans,
|
||||
T1Retention: sumItem.T1Retention,
|
||||
T7Retention: sumItem.T7Retention,
|
||||
T15Retention: sumItem.T15Retention,
|
||||
T30Retention: sumItem.T30Retention,
|
||||
T1RetentionRatio: sumItem.T1RetentionRatio,
|
||||
T7RetentionRatio: sumItem.T7RetentionRatio,
|
||||
T15RetentionRatio: sumItem.T15RetentionRatio,
|
||||
T30RetentionRatio: sumItem.T30RetentionRatio,
|
||||
ReservationSuccess: sumItem.ReservationSuccess,
|
||||
ReservationCost: sumItem.ReservationCost,
|
||||
StandardLivePlayedStarted: sumItem.StandardLivePlayedStarted,
|
||||
AdLivePlayCnt: sumItem.AdLivePlayCnt,
|
||||
AdLivePlayCntCost: sumItem.AdLivePlayCntCost,
|
||||
LiveAudienceCost: sumItem.LiveAudienceCost,
|
||||
LiveEventGoodsView: sumItem.LiveEventGoodsView,
|
||||
GoodsClickRatio: sumItem.GoodsClickRatio,
|
||||
DirectAttrPlatNewBuyerCnt: sumItem.DirectAttrPlatNewBuyerCnt,
|
||||
T30AttrPlatTotalBuyerCnt: sumItem.T30AttrPlatTotalBuyerCnt,
|
||||
DirectAttrSellerNewBuyerCnt: sumItem.DirectAttrSellerNewBuyerCnt,
|
||||
T30AttrSellerTotalBuyerCnt: sumItem.T30AttrSellerTotalBuyerCnt,
|
||||
T7IndirectOrderAmt: sumItem.T7IndirectOrderAmt,
|
||||
T7IndirectOrderCnt: sumItem.T7IndirectOrderCnt,
|
||||
FansT0GmvPerFans: sumItem.FansT0GmvPerFans,
|
||||
FansT3GmvPerFans: sumItem.FansT3GmvPerFans,
|
||||
FansT7GmvPerFans: sumItem.FansT7GmvPerFans,
|
||||
FansT15GmvPerFans: sumItem.FansT15GmvPerFans,
|
||||
FansT30GmvPerFans: sumItem.FansT30GmvPerFans,
|
||||
RecoFansCost: sumItem.RecoFansCost,
|
||||
QcpxWhiteboxDirectOrderPaymentAmt: sumItem.QcpxWhiteboxDirectOrderPaymentAmt,
|
||||
QcpxWhiteboxDirectOrderCnt: sumItem.QcpxWhiteboxDirectOrderCnt,
|
||||
FansT0Gmv: sumItem.FansT0Gmv,
|
||||
FansT1Gmv: sumItem.FansT1Gmv,
|
||||
FansT7Gmv: sumItem.FansT7Gmv,
|
||||
FansT15Gmv: sumItem.FansT15Gmv,
|
||||
FansT30Gmv: sumItem.FansT30Gmv,
|
||||
FansT0Roi: sumItem.FansT0Roi,
|
||||
FansT1Roi: sumItem.FansT1Roi,
|
||||
FansT7Roi: sumItem.FansT7Roi,
|
||||
FansT15Roi: sumItem.FansT15Roi,
|
||||
FansT30Roi: sumItem.FansT30Roi,
|
||||
T0ShopNewBuyerOrderPaymentAmt: sumItem.T0ShopNewBuyerOrderPaymentAmt,
|
||||
T1ShopNewBuyerOrderPaymentAmt: sumItem.T1ShopNewBuyerOrderPaymentAmt,
|
||||
T3ShopNewBuyerOrderPaymentAmt: sumItem.T3ShopNewBuyerOrderPaymentAmt,
|
||||
T7ShopNewBuyerOrderPaymentAmt: sumItem.T7ShopNewBuyerOrderPaymentAmt,
|
||||
T15ShopNewBuyerOrderPaymentAmt: sumItem.T15ShopNewBuyerOrderPaymentAmt,
|
||||
T30ShopNewBuyerOrderPaymentAmt: sumItem.T30ShopNewBuyerOrderPaymentAmt,
|
||||
T0ShopNewBuyerOrderCnt: sumItem.T0ShopNewBuyerOrderCnt,
|
||||
T1ShopNewBuyerOrderCnt: sumItem.T1ShopNewBuyerOrderCnt,
|
||||
T3ShopNewBuyerOrderCnt: sumItem.T3ShopNewBuyerOrderCnt,
|
||||
T7ShopNewBuyerOrderCnt: sumItem.T7ShopNewBuyerOrderCnt,
|
||||
T15ShopNewBuyerOrderCnt: sumItem.T15ShopNewBuyerOrderCnt,
|
||||
T30ShopNewBuyerOrderCnt: sumItem.T30ShopNewBuyerOrderCnt,
|
||||
T1NewBuyerRepurchaseRatio: sumItem.T1NewBuyerRepurchaseRatio,
|
||||
T3NewBuyerRepurchaseRatio: sumItem.T3NewBuyerRepurchaseRatio,
|
||||
T7NewBuyerRepurchaseRatio: sumItem.T7NewBuyerRepurchaseRatio,
|
||||
T15NewBuyerRepurchaseRatio: sumItem.T15NewBuyerRepurchaseRatio,
|
||||
T30NewBuyerRepurchaseRatio: sumItem.T30NewBuyerRepurchaseRatio,
|
||||
T0ShopNewBuyerRoi: sumItem.T0ShopNewBuyerRoi,
|
||||
T1ShopNewBuyerRoi: sumItem.T1ShopNewBuyerRoi,
|
||||
T3ShopNewBuyerRoi: sumItem.T3ShopNewBuyerRoi,
|
||||
T7ShopNewBuyerRoi: sumItem.T7ShopNewBuyerRoi,
|
||||
T15ShopNewBuyerRoi: sumItem.T15ShopNewBuyerRoi,
|
||||
T30ShopNewBuyerRoi: sumItem.T30ShopNewBuyerRoi,
|
||||
CreateCardOrderCnt: sumItem.CreateCardOrderCnt,
|
||||
ForwardTsCreateCardOrderCnt: sumItem.ForwardTsCreateCardOrderCnt,
|
||||
CreateCardOrderCost: sumItem.CreateCardOrderCost,
|
||||
ForwardTsCreateCardOrderCost: sumItem.ForwardTsCreateCardOrderCost,
|
||||
ActivateCardOrderCnt: sumItem.ActivateCardOrderCnt,
|
||||
ForwardTsActivateCardOrderCnt: sumItem.ForwardTsActivateCardOrderCnt,
|
||||
ActivateCardOrderCost: sumItem.ActivateCardOrderCost,
|
||||
ForwardTsActivateCardOrderCost: sumItem.ForwardTsActivateCardOrderCost,
|
||||
CreateCardOrderRatio: sumItem.CreateCardOrderRatio,
|
||||
ForwardTsCreateCardOrderRatio: sumItem.ForwardTsCreateCardOrderRatio,
|
||||
ActivateCardOrderCntRatio: sumItem.ActivateCardOrderCntRatio,
|
||||
ForwardTsActivateCardOrderRatio: sumItem.ForwardTsActivateCardOrderRatio,
|
||||
LivePlayCnt: sumItem.LivePlayCnt,
|
||||
ItemEntranceClkCnt: sumItem.ItemEntranceClkCnt,
|
||||
ShowCnt: sumItem.ShowCnt,
|
||||
ReportDateStr: sumItem.ReportDateStr,
|
||||
CampaignId: sumItem.CampaignId,
|
||||
CampaignName: sumItem.CampaignName,
|
||||
UnitId: sumItem.UnitId,
|
||||
UnitName: sumItem.UnitName,
|
||||
CreativeId: sumItem.CreativeId,
|
||||
CreativeName: sumItem.CreativeName,
|
||||
CidActualRoiAfterSubsidy: sumItem.CidActualRoiAfterSubsidy,
|
||||
CidCouponAmount: sumItem.CidCouponAmount,
|
||||
CidCouponCallbackPaidRefundAmount: sumItem.CidCouponCallbackPaidRefundAmount,
|
||||
CidVoucherCost: sumItem.CidVoucherCost,
|
||||
}
|
||||
}
|
||||
68
sync/http_client.go
Normal file
68
sync/http_client.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type HttpClient struct {
|
||||
BaseURL string
|
||||
Timeout time.Duration
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
func NewHttpClient(baseURL string, timeout time.Duration) *HttpClient {
|
||||
if timeout == 0 {
|
||||
timeout = 30 * time.Second
|
||||
}
|
||||
return &HttpClient{
|
||||
BaseURL: baseURL,
|
||||
Timeout: timeout,
|
||||
HTTPClient: &http.Client{
|
||||
Timeout: timeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HttpClient) Post(ctx context.Context, url string, body interface{}) ([]byte, error) {
|
||||
jsonData, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化请求失败:%w", err)
|
||||
}
|
||||
|
||||
fullURL := url
|
||||
if c.BaseURL != "" && len(url) > 0 && url[0] != '/' {
|
||||
fullURL = c.BaseURL + url
|
||||
} else if c.BaseURL != "" {
|
||||
fullURL = c.BaseURL + url
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", fullURL, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建请求失败:%w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败:%w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取响应失败:%w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("HTTP 错误状态码:%d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
272
sync/mock_generator.go
Normal file
272
sync/mock_generator.go
Normal file
@@ -0,0 +1,272 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MockDataGenerator struct {
|
||||
rand *rand.Rand
|
||||
}
|
||||
|
||||
func NewMockDataGenerator() *MockDataGenerator {
|
||||
return &MockDataGenerator{
|
||||
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) GenerateCampaignReportRequest() *CampaignReportRequest {
|
||||
return &CampaignReportRequest{
|
||||
AdvertiserID: 10001,
|
||||
StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
EndTime: time.Now().UnixNano() / 1e6,
|
||||
SelectColumns: []string{"impression", "click", "cost", "t0GMV"},
|
||||
GroupType: 1,
|
||||
QueryVersion: 1,
|
||||
SelectParam: &CampaignSelectParam{
|
||||
CampaignIDs: []int64{1, 2, 3},
|
||||
},
|
||||
PageInfo: &PageInfo{
|
||||
CurrentPage: 1,
|
||||
PageSize: 20,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) GenerateCampaignReportResponse() *CampaignReportResponse {
|
||||
sumData := m.generateSumData()
|
||||
detailData := m.generateDetailData(5)
|
||||
|
||||
return &CampaignReportResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: &CampaignReportData{
|
||||
Sum: sumData,
|
||||
Detail: detailData,
|
||||
TotalCount: len(detailData),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) generateSumData() *CampaignReportSum {
|
||||
cost := m.randomFloat(1000, 10000)
|
||||
impression := m.randomInt64(10000, 100000)
|
||||
click := m.randomInt64(100, 1000)
|
||||
|
||||
return &CampaignReportSum{
|
||||
T0OrderPaymentAmt: "888.99",
|
||||
CreativeMaterialType: "视频素材类型",
|
||||
LiveName: "测试直播间",
|
||||
AuthorId: "123456",
|
||||
PicUrl: "http://example.com/pic.jpg",
|
||||
PicName: "图片名称",
|
||||
PicId: "pic_123",
|
||||
CoverUrl: "http://example.com/cover.jpg",
|
||||
CoverId: 4551122,
|
||||
ItemOrderConversionRatio: m.randomFloatPtr(0.01, 0.5),
|
||||
ItemCardClickRatio: m.randomFloatPtr(0.02, 0.3),
|
||||
ItemCardClkCnt: m.randomIntPtr(10, 100),
|
||||
LivePlayCntCost: m.randomFloatPtr(0.5, 5.0),
|
||||
AdMerchantFollowCost: m.randomFloatPtr(1.0, 10.0),
|
||||
AdMerchantFollow: m.randomIntPtr(50, 500),
|
||||
NetT0OrderCnt: m.randomIntPtr(10, 100),
|
||||
NetT0Roi: m.randomFloatPtr(1.5, 5.0),
|
||||
NetT0Gmv: m.randomFloatPtr(5000, 50000),
|
||||
PhotoName: "测试视频",
|
||||
PhotoIdStr: "video_123",
|
||||
PhotoId: "video_123",
|
||||
ModPriceSegment: "1000-2000",
|
||||
AgeSegment: "24-30",
|
||||
Province: "广东",
|
||||
Gender: "男",
|
||||
AdPhotoPlayedFiveRatio: m.randomFloatPtr(0.3, 0.8),
|
||||
AdPhotoPlayedThreeRatio: m.randomFloatPtr(0.5, 0.9),
|
||||
OrderSubmitRoi: m.randomFloatPtr(1.0, 3.0),
|
||||
OrderSubmitAmt: m.randomIntPtr(10, 100),
|
||||
EventOrderSubmitCost: m.randomFloatPtr(5.0, 20.0),
|
||||
EventOrderSubmit: m.randomIntPtr(5, 50),
|
||||
EventOrderPaidRoi: m.randomFloatPtr(0.5, 2.0),
|
||||
EventAppInvoked: m.randomIntPtr(100, 1000),
|
||||
EventAddShoppingCart: m.randomIntPtr(50, 500),
|
||||
ConversionNumCost: m.randomFloatPtr(10.0, 50.0),
|
||||
AdEffectivePlayNum: m.randomIntPtr(1000, 10000),
|
||||
AdItemClick: m.randomIntPtr(100, 1000),
|
||||
MerchantProductId: "product_123",
|
||||
CostTotal: &cost,
|
||||
AdShow: m.randomIntPtr(10000, 100000),
|
||||
AdShow1kCost: m.randomFloatPtr(5.0, 50.0),
|
||||
Impression: &impression,
|
||||
PhotoClick: m.randomIntPtr(100, 5000),
|
||||
PhotoClickRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
Click: &click,
|
||||
ActionbarClick: m.randomIntPtr(50, 500),
|
||||
ActionbarClickCost: m.randomFloatPtr(1.0, 10.0),
|
||||
EspClickRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
ActionRatio: m.randomFloatPtr(0.02, 0.2),
|
||||
AdItemClickCount: m.randomIntPtr(10, 100),
|
||||
EspLivePlayedSeconds: m.randomIntPtr(30, 300),
|
||||
PlayedThreeSeconds: m.randomIntPtr(5000, 50000),
|
||||
Play3sRatio: m.randomFloatPtr(0.3, 0.8),
|
||||
PlayedFiveSeconds: m.randomIntPtr(3000, 30000),
|
||||
Play5sRatio: m.randomFloatPtr(0.2, 0.6),
|
||||
PlayedEnd: m.randomIntPtr(1000, 10000),
|
||||
PlayEndRatio: m.randomFloatPtr(0.1, 0.4),
|
||||
Share: m.randomIntPtr(10, 100),
|
||||
Comment: m.randomIntPtr(20, 200),
|
||||
Likes: m.randomIntPtr(100, 1000),
|
||||
Report: m.randomIntPtr(1, 10),
|
||||
Block: m.randomIntPtr(1, 10),
|
||||
ItemNegative: m.randomIntPtr(5, 50),
|
||||
LiveShare: m.randomIntPtr(5, 50),
|
||||
LiveComment: m.randomIntPtr(10, 100),
|
||||
LiveReward: m.randomIntPtr(20, 200),
|
||||
EffectivePlayCount: m.randomIntPtr(1000, 10000),
|
||||
EffectivePlayRatio: m.randomFloatPtr(0.1, 0.5),
|
||||
ConversionNum: m.randomIntPtr(5, 50),
|
||||
ConversionCostEsp: m.randomFloatPtr(10.0, 50.0),
|
||||
Roi: m.randomFloatPtr(1.0, 3.0),
|
||||
Gmv: m.randomFloatPtr(1000, 10000),
|
||||
T0Gmv: m.randomFloatPtr(500, 5000),
|
||||
T1Gmv: m.randomFloatPtr(800, 8000),
|
||||
T3Gmv: m.randomFloatPtr(1200, 12000),
|
||||
T7Gmv: m.randomFloatPtr(2000, 20000),
|
||||
T15Gmv: m.randomFloatPtr(3000, 30000),
|
||||
T30Gmv: m.randomFloatPtr(5000, 50000),
|
||||
T0Roi: m.randomFloatPtr(0.5, 2.0),
|
||||
T1Roi: m.randomFloatPtr(0.8, 2.5),
|
||||
T3Roi: m.randomFloatPtr(1.0, 3.0),
|
||||
T7Roi: m.randomFloatPtr(1.5, 4.0),
|
||||
T15Roi: m.randomFloatPtr(2.0, 5.0),
|
||||
T30Roi: m.randomFloatPtr(2.5, 6.0),
|
||||
PaiedOrder: m.randomIntPtr(5, 50),
|
||||
OrderRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
T0OrderCnt: m.randomIntPtr(5, 50),
|
||||
T0OrderCntCost: m.randomFloatPtr(10.0, 100.0),
|
||||
T0OrderCntRatio: m.randomFloatPtr(0.5, 0.9),
|
||||
T1OrderCnt: m.randomIntPtr(10, 100),
|
||||
T3OrderCnt: m.randomIntPtr(20, 200),
|
||||
T7OrderCnt: m.randomIntPtr(30, 300),
|
||||
T15OrderCnt: m.randomIntPtr(40, 400),
|
||||
T30OrderCnt: m.randomIntPtr(50, 500),
|
||||
MerchantRecoFans: m.randomIntPtr(100, 1000),
|
||||
T1Retention: m.randomFloatPtr(0.3, 0.8),
|
||||
T7Retention: m.randomFloatPtr(0.2, 0.6),
|
||||
T15Retention: m.randomFloatPtr(0.15, 0.5),
|
||||
T30Retention: m.randomFloatPtr(0.1, 0.4),
|
||||
T1RetentionRatio: m.randomFloatPtr(0.3, 0.8),
|
||||
T7RetentionRatio: m.randomFloatPtr(0.2, 0.6),
|
||||
T15RetentionRatio: m.randomFloatPtr(0.15, 0.5),
|
||||
T30RetentionRatio: m.randomFloatPtr(0.1, 0.4),
|
||||
ReservationSuccess: m.randomIntPtr(10, 100),
|
||||
ReservationCost: m.randomFloatPtr(5.0, 50.0),
|
||||
StandardLivePlayedStarted: m.randomIntPtr(100, 1000),
|
||||
AdLivePlayCnt: m.randomIntPtr(50, 500),
|
||||
AdLivePlayCntCost: m.randomFloatPtr(1.0, 10.0),
|
||||
LiveAudienceCost: m.randomFloatPtr(0.5, 5.0),
|
||||
LiveEventGoodsView: m.randomIntPtr(100, 1000),
|
||||
GoodsClickRatio: m.randomFloatPtr(0.05, 0.3),
|
||||
DirectAttrPlatNewBuyerCnt: m.randomIntPtr(10, 100),
|
||||
T30AttrPlatTotalBuyerCnt: m.randomIntPtr(50, 500),
|
||||
DirectAttrSellerNewBuyerCnt: m.randomIntPtr(5, 50),
|
||||
T30AttrSellerTotalBuyerCnt: m.randomIntPtr(20, 200),
|
||||
T7IndirectOrderAmt: m.randomFloatPtr(500, 5000),
|
||||
T7IndirectOrderCnt: m.randomIntPtr(5, 50),
|
||||
FansT0GmvPerFans: m.randomFloatPtr(10.0, 100.0),
|
||||
FansT3GmvPerFans: m.randomFloatPtr(20.0, 200.0),
|
||||
FansT7GmvPerFans: m.randomFloatPtr(30.0, 300.0),
|
||||
FansT15GmvPerFans: m.randomFloatPtr(40.0, 400.0),
|
||||
FansT30GmvPerFans: m.randomFloatPtr(50.0, 500.0),
|
||||
RecoFansCost: m.randomFloatPtr(5.0, 50.0),
|
||||
QcpxWhiteboxDirectOrderPaymentAmt: m.randomFloatPtr(100, 1000),
|
||||
QcpxWhiteboxDirectOrderCnt: m.randomIntPtr(1, 10),
|
||||
FansT0Gmv: m.randomFloatPtr(100, 1000),
|
||||
FansT1Gmv: m.randomFloatPtr(200, 2000),
|
||||
FansT7Gmv: m.randomFloatPtr(300, 3000),
|
||||
FansT15Gmv: m.randomFloatPtr(400, 4000),
|
||||
FansT30Gmv: m.randomFloatPtr(500, 5000),
|
||||
FansT0Roi: m.randomFloatPtr(0.5, 2.0),
|
||||
FansT1Roi: m.randomFloatPtr(0.8, 2.5),
|
||||
FansT7Roi: m.randomFloatPtr(1.0, 3.0),
|
||||
FansT15Roi: m.randomFloatPtr(1.5, 4.0),
|
||||
FansT30Roi: m.randomFloatPtr(2.0, 5.0),
|
||||
T0ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(100, 1000),
|
||||
T1ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(200, 2000),
|
||||
T3ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(300, 3000),
|
||||
T7ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(400, 4000),
|
||||
T15ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(500, 5000),
|
||||
T30ShopNewBuyerOrderPaymentAmt: m.randomFloatPtr(600, 6000),
|
||||
T0ShopNewBuyerOrderCnt: m.randomIntPtr(1, 10),
|
||||
T1ShopNewBuyerOrderCnt: m.randomIntPtr(2, 20),
|
||||
T3ShopNewBuyerOrderCnt: m.randomIntPtr(3, 30),
|
||||
T7ShopNewBuyerOrderCnt: m.randomIntPtr(4, 40),
|
||||
T15ShopNewBuyerOrderCnt: m.randomIntPtr(5, 50),
|
||||
T30ShopNewBuyerOrderCnt: m.randomIntPtr(6, 60),
|
||||
T1NewBuyerRepurchaseRatio: m.randomFloatPtr(0.1, 0.5),
|
||||
T3NewBuyerRepurchaseRatio: m.randomFloatPtr(0.15, 0.55),
|
||||
T7NewBuyerRepurchaseRatio: m.randomFloatPtr(0.2, 0.6),
|
||||
T15NewBuyerRepurchaseRatio: m.randomFloatPtr(0.25, 0.65),
|
||||
T30NewBuyerRepurchaseRatio: m.randomFloatPtr(0.3, 0.7),
|
||||
T0ShopNewBuyerRoi: m.randomFloatPtr(0.5, 2.0),
|
||||
T1ShopNewBuyerRoi: m.randomFloatPtr(0.8, 2.5),
|
||||
T3ShopNewBuyerRoi: m.randomFloatPtr(1.0, 3.0),
|
||||
T7ShopNewBuyerRoi: m.randomFloatPtr(1.5, 4.0),
|
||||
T15ShopNewBuyerRoi: m.randomFloatPtr(2.0, 5.0),
|
||||
T30ShopNewBuyerRoi: m.randomFloatPtr(2.5, 6.0),
|
||||
CreateCardOrderCnt: m.randomIntPtr(1, 10),
|
||||
ForwardTsCreateCardOrderCnt: m.randomIntPtr(1, 10),
|
||||
CreateCardOrderCost: m.randomFloatPtr(10.0, 100.0),
|
||||
ForwardTsCreateCardOrderCost: m.randomFloatPtr(10.0, 100.0),
|
||||
ActivateCardOrderCnt: m.randomIntPtr(1, 10),
|
||||
ForwardTsActivateCardOrderCnt: m.randomIntPtr(1, 10),
|
||||
ActivateCardOrderCost: m.randomFloatPtr(10.0, 100.0),
|
||||
ForwardTsActivateCardOrderCost: m.randomFloatPtr(10.0, 100.0),
|
||||
CreateCardOrderRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
ForwardTsCreateCardOrderRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
ActivateCardOrderCntRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
ForwardTsActivateCardOrderRatio: m.randomFloatPtr(0.01, 0.1),
|
||||
LivePlayCnt: m.randomIntPtr(100, 1000),
|
||||
ItemEntranceClkCnt: m.randomIntPtr(50, 500),
|
||||
ShowCnt: m.randomIntPtr(1000, 10000),
|
||||
ReportDateStr: time.Now().Format("2006-01-02"),
|
||||
CampaignId: m.randomIntPtr(1, 100),
|
||||
CampaignName: "测试计划",
|
||||
UnitId: m.randomIntPtr(1, 50),
|
||||
UnitName: "测试单元",
|
||||
CreativeId: m.randomIntPtr(1, 20),
|
||||
CreativeName: "测试创意",
|
||||
CidActualRoiAfterSubsidy: m.randomFloatPtr(1.0, 3.0),
|
||||
CidCouponAmount: m.randomIntPtr(100, 1000),
|
||||
CidCouponCallbackPaidRefundAmount: m.randomIntPtr(50, 500),
|
||||
CidVoucherCost: m.randomFloatPtr(5.0, 50.0),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) generateDetailData(count int) []*CampaignReportItem {
|
||||
items := make([]*CampaignReportItem, count)
|
||||
for i := 0; i < count; i++ {
|
||||
items[i] = (*CampaignReportItem)(m.generateSumData())
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) randomInt(min, max int) int {
|
||||
return m.rand.Intn(max-min) + min
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) randomInt64(min, max int64) int64 {
|
||||
return m.rand.Int63n(max-min) + min
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) randomFloat(min, max float64) float64 {
|
||||
return m.rand.Float64()*(max-min) + min
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) randomIntPtr(min, max int) *int64 {
|
||||
v := int64(m.randomInt(min, max))
|
||||
return &v
|
||||
}
|
||||
|
||||
func (m *MockDataGenerator) randomFloatPtr(min, max float64) *float64 {
|
||||
v := m.randomFloat(min, max)
|
||||
return &v
|
||||
}
|
||||
51
sync/quick_sync.go
Normal file
51
sync/quick_sync.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func SyncCampaignReportWithMock(ctx context.Context) error {
|
||||
syncService := NewSyncService()
|
||||
|
||||
req := &CampaignReportRequest{
|
||||
AdvertiserID: 10001,
|
||||
StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
EndTime: time.Now().UnixNano() / 1e6,
|
||||
SelectColumns: []string{"impression", "click", "cost", "t0GMV"},
|
||||
GroupType: 1,
|
||||
QueryVersion: 1,
|
||||
SelectParam: &CampaignSelectParam{
|
||||
CampaignIDs: []int64{1, 2, 3},
|
||||
},
|
||||
PageInfo: &PageInfo{
|
||||
CurrentPage: 1,
|
||||
PageSize: 20,
|
||||
},
|
||||
}
|
||||
|
||||
result, err := syncService.SyncCampaignReport(ctx, req, true)
|
||||
if err != nil {
|
||||
logrus.Errorf("同步失败:%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Infof("同步成功 - 汇总 ID: %d, 明细数量:%d", result.SumID, result.DetailCount)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SyncCampaignReportWithRealAPI(ctx context.Context, req *CampaignReportRequest) error {
|
||||
syncService := NewSyncService()
|
||||
|
||||
result, err := syncService.SyncCampaignReport(ctx, req, false)
|
||||
if err != nil {
|
||||
logrus.Errorf("同步失败:%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Infof("同步成功 - 汇总 ID: %d, 明细数量:%d, 成功:%d, 失败:%d",
|
||||
result.SumID, result.DetailCount, result.DetailSuccessCount, result.DetailFailCount)
|
||||
return nil
|
||||
}
|
||||
268
sync/sync_service.go
Normal file
268
sync/sync_service.go
Normal file
@@ -0,0 +1,268 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
dto "cid/model/dto/copydata"
|
||||
"cid/service/copydata"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/beans"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type SyncService struct {
|
||||
httpClient *HttpClient
|
||||
converter *DataConverter
|
||||
mockGen *MockDataGenerator
|
||||
}
|
||||
|
||||
func NewSyncService() *SyncService {
|
||||
return &SyncService{
|
||||
httpClient: NewHttpClient("https://ad.e.kuaishou.com", 0),
|
||||
converter: NewDataConverter(),
|
||||
mockGen: NewMockDataGenerator(),
|
||||
}
|
||||
}
|
||||
|
||||
type SyncResult struct {
|
||||
SumSuccess bool `json:"sum_success"`
|
||||
SumID int64 `json:"sum_id"`
|
||||
DetailSuccess bool `json:"detail_success"`
|
||||
DetailCount int `json:"detail_count"`
|
||||
DetailSuccessCount int64 `json:"detail_success_count"`
|
||||
DetailFailCount int64 `json:"detail_fail_count"`
|
||||
Error error `json:"error"`
|
||||
}
|
||||
|
||||
func (s *SyncService) SyncCampaignReport(ctx context.Context, req *CampaignReportRequest, useMock bool) (*SyncResult, error) {
|
||||
result := &SyncResult{}
|
||||
|
||||
var responseData *CampaignReportResponse
|
||||
|
||||
if useMock {
|
||||
logrus.Info("使用 Mock 数据同步快手广告计划报表")
|
||||
responseData = s.mockGen.GenerateCampaignReportResponse()
|
||||
} else {
|
||||
logrus.Info("从真实 API 同步快手广告计划报表")
|
||||
respBytes, err := s.httpClient.Post(ctx, "/rest/openapi/gw/esp/report/campaignReport", req)
|
||||
if err != nil {
|
||||
result.Error = fmt.Errorf("调用 API 失败:%w", err)
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
responseData = &CampaignReportResponse{}
|
||||
if err := json.Unmarshal(respBytes, responseData); err != nil {
|
||||
result.Error = fmt.Errorf("解析响应失败:%w", err)
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
if responseData.Code != 0 {
|
||||
result.Error = fmt.Errorf("API 返回错误:code=%d, message=%s", responseData.Code, responseData.Message)
|
||||
return result, result.Error
|
||||
}
|
||||
}
|
||||
|
||||
if responseData.Data.Sum != nil {
|
||||
sumItem := s.converter.ConvertToSumItem(responseData.Data.Sum, "campaign_report")
|
||||
ctx = context.WithValue(ctx, "user", &beans.User{UserName: "admin"})
|
||||
|
||||
sumResult, saveErr := s.saveSumData(ctx, sumItem)
|
||||
if saveErr != nil {
|
||||
logrus.Errorf("保存汇总数据失败:%v", saveErr)
|
||||
result.Error = fmt.Errorf("保存汇总数据失败:%w", saveErr)
|
||||
} else {
|
||||
result.SumSuccess = true
|
||||
result.SumID = sumResult.Id
|
||||
logrus.Infof("成功保存汇总数据,ID=%d", sumResult.Id)
|
||||
}
|
||||
}
|
||||
|
||||
if len(responseData.Data.Detail) > 0 {
|
||||
detailItems := s.converter.ConvertToDetailItems(responseData.Data.Detail, "campaign_report")
|
||||
detailResult, saveErr := s.saveDetailData(ctx, detailItems)
|
||||
if saveErr != nil {
|
||||
logrus.Errorf("保存明细数据失败:%v", saveErr)
|
||||
result.Error = fmt.Errorf("保存明细数据失败:%w", saveErr)
|
||||
} else {
|
||||
result.DetailSuccess = true
|
||||
result.DetailCount = len(detailItems)
|
||||
result.DetailSuccessCount = detailResult.SuccessCount
|
||||
result.DetailFailCount = detailResult.FailCount
|
||||
logrus.Infof("成功保存明细数据,成功=%d, 失败=%d", detailResult.SuccessCount, detailResult.FailCount)
|
||||
}
|
||||
}
|
||||
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
// SyncCampaignReportWithPagination 带分页处理的同步方法(支持全量数据抽取)
|
||||
func (s *SyncService) SyncCampaignReportWithPagination(ctx context.Context, req *CampaignReportRequest, useMock bool, maxRetries int) (*SyncResult, error) {
|
||||
aggregatedResult := &SyncResult{
|
||||
SumSuccess: false,
|
||||
SumID: 0,
|
||||
}
|
||||
|
||||
allDetailItems := make([]*dto.CidAccountReportDetailItem, 0)
|
||||
totalCount := 0
|
||||
currentPage := 1
|
||||
pageSize := 100
|
||||
|
||||
if req.PageInfo == nil {
|
||||
req.PageInfo = &PageInfo{}
|
||||
}
|
||||
|
||||
for {
|
||||
logrus.Infof(">>> 正在同步第 %d 页数据...", currentPage)
|
||||
|
||||
req.PageInfo.CurrentPage = currentPage
|
||||
req.PageInfo.PageSize = pageSize
|
||||
|
||||
result, err := s.SyncWithRetry(ctx, req, useMock, maxRetries)
|
||||
if err != nil {
|
||||
logrus.Errorf("第 %d 页同步失败:%v", currentPage, err)
|
||||
return aggregatedResult, err
|
||||
}
|
||||
|
||||
if result.SumSuccess && aggregatedResult.SumID == 0 {
|
||||
aggregatedResult.SumSuccess = true
|
||||
aggregatedResult.SumID = result.SumID
|
||||
logrus.Infof("✓ 汇总数据已保存,ID=%d", result.SumID)
|
||||
}
|
||||
|
||||
if result.DetailSuccess && result.DetailCount > 0 {
|
||||
detailItems := s.extractDetailItems(req, useMock)
|
||||
if len(detailItems) > 0 {
|
||||
allDetailItems = append(allDetailItems, detailItems...)
|
||||
totalCount += len(detailItems)
|
||||
logrus.Infof("✓ 第 %d 页获取到 %d 条明细数据,累计 %d 条", currentPage, len(detailItems), totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
currentData := s.fetchCurrentData(req, useMock)
|
||||
if currentData != nil && currentData.TotalCount > 0 {
|
||||
totalPages := (currentData.TotalCount + pageSize - 1) / pageSize
|
||||
logrus.Infof("总记录数:%d, 总页数:%d, 当前页:%d/%d",
|
||||
currentData.TotalCount, totalPages, currentPage, totalPages)
|
||||
|
||||
if currentPage >= totalPages {
|
||||
logrus.Infof("✓ 已同步所有页面数据,共 %d 页,%d 条记录", totalPages, currentData.TotalCount)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if result.DetailCount < pageSize {
|
||||
logrus.Infof("✓ 当前页数据不足 %d 条,已到达最后一页", pageSize)
|
||||
break
|
||||
}
|
||||
|
||||
currentPage++
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
}
|
||||
|
||||
if len(allDetailItems) > 0 {
|
||||
logrus.Infof("开始批量保存 %d 条明细数据...", len(allDetailItems))
|
||||
detailResult, saveErr := s.saveDetailData(ctx, allDetailItems)
|
||||
if saveErr != nil {
|
||||
logrus.Errorf("批量保存明细数据失败:%v", saveErr)
|
||||
aggregatedResult.Error = fmt.Errorf("批量保存明细数据失败:%w", saveErr)
|
||||
} else {
|
||||
aggregatedResult.DetailSuccess = true
|
||||
aggregatedResult.DetailCount = len(allDetailItems)
|
||||
aggregatedResult.DetailSuccessCount = detailResult.SuccessCount
|
||||
aggregatedResult.DetailFailCount = detailResult.FailCount
|
||||
logrus.Infof("✓ 批量保存明细数据完成,成功=%d, 失败=%d",
|
||||
detailResult.SuccessCount, detailResult.FailCount)
|
||||
}
|
||||
} else {
|
||||
logrus.Info("没有明细数据需要保存")
|
||||
}
|
||||
|
||||
return aggregatedResult, aggregatedResult.Error
|
||||
}
|
||||
|
||||
func (s *SyncService) extractDetailItems(req *CampaignReportRequest, useMock bool) []*dto.CidAccountReportDetailItem {
|
||||
if useMock {
|
||||
responseData := s.mockGen.GenerateCampaignReportResponse()
|
||||
if responseData == nil || responseData.Data == nil || len(responseData.Data.Detail) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.converter.ConvertToDetailItems(responseData.Data.Detail, "campaign_report")
|
||||
}
|
||||
|
||||
respBytes, err := s.httpClient.Post(context.Background(), "/rest/openapi/gw/esp/report/campaignReport", req)
|
||||
if err != nil {
|
||||
logrus.Errorf("重新获取数据失败:%v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
responseData := &CampaignReportResponse{}
|
||||
if err := json.Unmarshal(respBytes, responseData); err != nil {
|
||||
logrus.Errorf("解析响应失败:%v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if responseData.Code != 0 || responseData.Data == nil || len(responseData.Data.Detail) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.converter.ConvertToDetailItems(responseData.Data.Detail, "campaign_report")
|
||||
}
|
||||
|
||||
func (s *SyncService) fetchCurrentData(req *CampaignReportRequest, useMock bool) *CampaignReportData {
|
||||
if useMock {
|
||||
responseData := s.mockGen.GenerateCampaignReportResponse()
|
||||
if responseData != nil && responseData.Data != nil {
|
||||
return responseData.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
respBytes, err := s.httpClient.Post(context.Background(), "/rest/openapi/gw/esp/report/campaignReport", req)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
responseData := &CampaignReportResponse{}
|
||||
if err := json.Unmarshal(respBytes, responseData); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if responseData.Code == 0 && responseData.Data != nil {
|
||||
return responseData.Data
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SyncService) saveSumData(ctx context.Context, item *dto.CidAccountReportSumItem) (*dto.CreateCidAccountReportSumRes, error) {
|
||||
return copydata.CidAccountReportDetail.CreateSum(ctx, item)
|
||||
}
|
||||
|
||||
func (s *SyncService) saveDetailData(ctx context.Context, items []*dto.CidAccountReportDetailItem) (*dto.BatchCreateCidAccountReportDetailRes, error) {
|
||||
req := &dto.BatchCreateCidAccountReportDetailReq{
|
||||
Items: items,
|
||||
}
|
||||
return copydata.CidAccountReportDetail.BatchCreate(ctx, req)
|
||||
}
|
||||
|
||||
func (s *SyncService) SyncWithRetry(ctx context.Context, req *CampaignReportRequest, useMock bool, maxRetries int) (*SyncResult, error) {
|
||||
var lastResult *SyncResult
|
||||
var lastErr error
|
||||
|
||||
for attempt := 0; attempt <= maxRetries; attempt++ {
|
||||
result, err := s.SyncCampaignReport(ctx, req, useMock)
|
||||
lastResult = result
|
||||
lastErr = err
|
||||
|
||||
if err == nil {
|
||||
logrus.Infof("同步成功,尝试次数:%d", attempt+1)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
logrus.Warnf("同步失败,第 %d 次重试,错误:%v", attempt+1, err)
|
||||
}
|
||||
|
||||
return lastResult, lastErr
|
||||
}
|
||||
139
sync/sync_test.go
Normal file
139
sync/sync_test.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
fmt.Println("=== 初始化测试环境 ===")
|
||||
ctx := gctx.New()
|
||||
|
||||
db := g.DB()
|
||||
if db != nil {
|
||||
_, err := db.Query(ctx, "SELECT 1")
|
||||
if err == nil {
|
||||
fmt.Println("✓ 数据库连接成功")
|
||||
} else {
|
||||
fmt.Printf("⚠️ 数据库连接失败:%v\n", err)
|
||||
fmt.Println("⚠️ 将跳过数据库相关测试")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("⚠️ 数据库未初始化")
|
||||
}
|
||||
fmt.Println("========================")
|
||||
}
|
||||
|
||||
func TestMockDataGeneration(t *testing.T) {
|
||||
mockGen := NewMockDataGenerator()
|
||||
|
||||
req := mockGen.GenerateCampaignReportRequest()
|
||||
if req == nil {
|
||||
t.Error("请求数据生成失败")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("✓ Mock 请求生成成功:AdvertiserID=%d\n", req.AdvertiserID)
|
||||
}
|
||||
|
||||
func TestDataConverter(t *testing.T) {
|
||||
converter := NewDataConverter()
|
||||
mockGen := NewMockDataGenerator()
|
||||
|
||||
responseData := mockGen.GenerateCampaignReportResponse()
|
||||
if responseData == nil || responseData.Data.Sum == nil {
|
||||
t.Fatal("Mock 数据生成失败")
|
||||
}
|
||||
|
||||
sumItem := converter.ConvertToSumItem(responseData.Data.Sum, "campaign_report")
|
||||
if sumItem == nil {
|
||||
t.Fatal("转换为汇总数据失败")
|
||||
}
|
||||
|
||||
if sumItem.CampaignName == "" {
|
||||
t.Error("计划名称为空")
|
||||
}
|
||||
|
||||
fmt.Printf("✓ 汇总数据转换成功:计划=%s\n", sumItem.CampaignName)
|
||||
|
||||
detailItems := converter.ConvertToDetailItems(responseData.Data.Detail, "campaign_report")
|
||||
if len(detailItems) == 0 {
|
||||
t.Fatal("转换为明细数据失败")
|
||||
}
|
||||
|
||||
fmt.Printf("✓ 明细数据转换成功:数量=%d\n", len(detailItems))
|
||||
}
|
||||
|
||||
func TestSyncCampaignReportWithDB(t *testing.T) {
|
||||
ctx := gctx.New()
|
||||
syncService := NewSyncService()
|
||||
|
||||
req := &CampaignReportRequest{
|
||||
AdvertiserID: 10001,
|
||||
StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
EndTime: time.Now().UnixNano() / 1e6,
|
||||
SelectColumns: []string{"impression", "click", "cost", "t0GMV"},
|
||||
GroupType: 1,
|
||||
QueryVersion: 1,
|
||||
}
|
||||
|
||||
result, err := syncService.SyncCampaignReport(ctx, req, true)
|
||||
if err != nil {
|
||||
t.Logf("同步失败(可能是数据库问题): %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("✓ 同步结果:汇总成功=%v, 汇总 ID=%d, 明细数量=%d\n",
|
||||
result.SumSuccess, result.SumID, result.DetailCount)
|
||||
}
|
||||
|
||||
//
|
||||
//// TestScheduledSyncTask 测试定时同步任务(每小时执行一次,全量分页抽取)
|
||||
//func TestScheduledSyncTask(t *testing.T) {
|
||||
// ctx := gctx.New()
|
||||
// syncService := NewSyncService()
|
||||
//
|
||||
// req := &CampaignReportRequest{
|
||||
// AdvertiserID: 10001,
|
||||
// StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
// EndTime: time.Now().UnixNano() / 1e6,
|
||||
// SelectColumns: []string{"impression", "click", "cost", "t0GMV"},
|
||||
// GroupType: 1,
|
||||
// QueryVersion: 1,
|
||||
// }
|
||||
//
|
||||
// logrus.Info("=== 开始执行定时同步任务 ===")
|
||||
// result, err := syncService.SyncCampaignReportWithPagination(ctx, req, true, 3)
|
||||
// if err != nil {
|
||||
// t.Logf("定时同步任务失败:%v", err)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// fmt.Printf("✓ 定时同步完成:\n")
|
||||
// fmt.Printf(" 汇总数据:成功=%v, ID=%d\n", result.SumSuccess, result.SumID)
|
||||
// fmt.Printf(" 明细数据:总数=%d, 成功=%d, 失败=%d\n",
|
||||
// result.DetailCount, result.DetailSuccessCount, result.DetailFailCount)
|
||||
//}
|
||||
|
||||
func BenchmarkSyncCampaignReport(b *testing.B) {
|
||||
ctx := gctx.New()
|
||||
syncService := NewSyncService()
|
||||
req := &CampaignReportRequest{
|
||||
AdvertiserID: 10001,
|
||||
StartTime: time.Now().AddDate(0, 0, -30).UnixNano() / 1e6,
|
||||
EndTime: time.Now().UnixNano() / 1e6,
|
||||
SelectColumns: []string{"impression", "click", "cost"},
|
||||
GroupType: 1,
|
||||
QueryVersion: 1,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = syncService.SyncCampaignReport(ctx, req, true)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user