支持实验数据拉取

This commit is contained in:
2025-10-16 10:09:20 +08:00
parent d7ab7b5156
commit df62e4fae6
5 changed files with 771 additions and 89 deletions

384
cmd.pb.go
View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.8 // protoc-gen-go v1.36.9
// protoc v5.29.4 // protoc v5.29.4
// source: cmd.proto // source: cmd.proto
@@ -157,6 +157,7 @@ const (
ErrorCode_DATA_ERROR ErrorCode = 201 // 数据错误 ErrorCode_DATA_ERROR ErrorCode = 201 // 数据错误
ErrorCode_CMD_ERROR ErrorCode = 202 // 命令行执行错误 ErrorCode_CMD_ERROR ErrorCode = 202 // 命令行执行错误
ErrorCode_API_ERROR ErrorCode = 301 // 调用内部API错误 ErrorCode_API_ERROR ErrorCode = 301 // 调用内部API错误
ErrorCode_TARGET_ERROR ErrorCode = 401 // Target参数错误
) )
// Enum value maps for ErrorCode. // Enum value maps for ErrorCode.
@@ -188,6 +189,7 @@ var (
201: "DATA_ERROR", 201: "DATA_ERROR",
202: "CMD_ERROR", 202: "CMD_ERROR",
301: "API_ERROR", 301: "API_ERROR",
401: "TARGET_ERROR",
} }
ErrorCode_value = map[string]int32{ ErrorCode_value = map[string]int32{
"SUCC": 0, "SUCC": 0,
@@ -216,6 +218,7 @@ var (
"DATA_ERROR": 201, "DATA_ERROR": 201,
"CMD_ERROR": 202, "CMD_ERROR": 202,
"API_ERROR": 301, "API_ERROR": 301,
"TARGET_ERROR": 401,
} }
) )
@@ -1046,8 +1049,6 @@ type Bytes struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Bytes []byte `protobuf:"bytes,1,opt,name=bytes,proto3" json:"bytes,omitempty"` // 写入的byte Bytes []byte `protobuf:"bytes,1,opt,name=bytes,proto3" json:"bytes,omitempty"` // 写入的byte
Index_1 uint64 `protobuf:"varint,2,opt,name=index_1,json=index1,proto3" json:"index_1,omitempty"` // 写入byte的索引值(0..63) Index_1 uint64 `protobuf:"varint,2,opt,name=index_1,json=index1,proto3" json:"index_1,omitempty"` // 写入byte的索引值(0..63)
// Deprecated: Marked as deprecated in cmd.proto.
Index_2 uint64 `protobuf:"varint,3,opt,name=index_2,json=index2,proto3" json:"index_2,omitempty"` // **已弃用 写入byte的索引值(64..127)
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -1096,14 +1097,6 @@ func (x *Bytes) GetIndex_1() uint64 {
return 0 return 0
} }
// Deprecated: Marked as deprecated in cmd.proto.
func (x *Bytes) GetIndex_2() uint64 {
if x != nil {
return x.Index_2
}
return 0
}
// Uint32s 写入uint32区域 // Uint32s 写入uint32区域
type Uint32S struct { type Uint32S struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@@ -2094,8 +2087,24 @@ func (*ExpList) Descriptor() ([]byte, []int) {
} }
// ExpGet 获取实验报表 // ExpGet 获取实验报表
// select base_fields, {EXT_FIELDS}
// where day between {WHERE_BEGIN_DAY} and {WHERE_END_DAY}
//
// and expid in {WHERE_EXP_ID}
// and target = {WHERE_TARGET}
// and advertiser_id in {WHERE_ADVERTISER_ID}
//
// group by {GROUP_BY}
type ExpGet struct { type ExpGet struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
ExtFields []string `protobuf:"bytes,1,rep,name=ext_fields,json=extFields,proto3" json:"ext_fields,omitempty"` // 扩展字段(除基础字段必然输出外,其余字段需在这里填写,也可以使用*输出全部扩展字段)
WhereBeginDay uint64 `protobuf:"varint,10,opt,name=where_begin_day,json=whereBeginDay,proto3" json:"where_begin_day,omitempty"` // 起始日期
WhereEndDay uint64 `protobuf:"varint,11,opt,name=where_end_day,json=whereEndDay,proto3" json:"where_end_day,omitempty"` // 结束日期
WhereExpId []uint32 `protobuf:"varint,12,rep,packed,name=where_exp_id,json=whereExpId,proto3" json:"where_exp_id,omitempty"` // 实验ID(1-10)
WhereTarget string `protobuf:"bytes,13,opt,name=where_target,json=whereTarget,proto3" json:"where_target,omitempty"` // 策略ID
WhereAdvertiserId []uint64 `protobuf:"varint,14,rep,packed,name=where_advertiser_id,json=whereAdvertiserId,proto3" json:"where_advertiser_id,omitempty"` // 广告主ID
GroupBy []string `protobuf:"bytes,20,rep,name=group_by,json=groupBy,proto3" json:"group_by,omitempty"` // 当前支持广告主ID(advertiser_id)
TotalFlag uint32 `protobuf:"varint,30,opt,name=TotalFlag,proto3" json:"TotalFlag,omitempty"` // 是否汇总
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -2130,6 +2139,62 @@ func (*ExpGet) Descriptor() ([]byte, []int) {
return file_cmd_proto_rawDescGZIP(), []int{24} return file_cmd_proto_rawDescGZIP(), []int{24}
} }
func (x *ExpGet) GetExtFields() []string {
if x != nil {
return x.ExtFields
}
return nil
}
func (x *ExpGet) GetWhereBeginDay() uint64 {
if x != nil {
return x.WhereBeginDay
}
return 0
}
func (x *ExpGet) GetWhereEndDay() uint64 {
if x != nil {
return x.WhereEndDay
}
return 0
}
func (x *ExpGet) GetWhereExpId() []uint32 {
if x != nil {
return x.WhereExpId
}
return nil
}
func (x *ExpGet) GetWhereTarget() string {
if x != nil {
return x.WhereTarget
}
return ""
}
func (x *ExpGet) GetWhereAdvertiserId() []uint64 {
if x != nil {
return x.WhereAdvertiserId
}
return nil
}
func (x *ExpGet) GetGroupBy() []string {
if x != nil {
return x.GroupBy
}
return nil
}
func (x *ExpGet) GetTotalFlag() uint32 {
if x != nil {
return x.TotalFlag
}
return 0
}
// SaasRes 命令返回 // SaasRes 命令返回
type SaasRes struct { type SaasRes struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@@ -3351,6 +3416,7 @@ func (x *ExpBucket) GetPercent() uint32 {
// ExpGetRes 实验报表返回 // ExpGetRes 实验报表返回
type ExpGetRes struct { type ExpGetRes struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Expdata []*ExpData `protobuf:"bytes,1,rep,name=expdata,proto3" json:"expdata,omitempty"` // 实验数据
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -3385,6 +3451,213 @@ func (*ExpGetRes) Descriptor() ([]byte, []int) {
return file_cmd_proto_rawDescGZIP(), []int{42} return file_cmd_proto_rawDescGZIP(), []int{42}
} }
func (x *ExpGetRes) GetExpdata() []*ExpData {
if x != nil {
return x.Expdata
}
return nil
}
type ExpData struct {
state protoimpl.MessageState `protogen:"open.v1"`
Time uint64 `protobuf:"varint,1,opt,name=time,proto3" json:"time,omitempty"` // 日期
ExpId uint32 `protobuf:"varint,2,opt,name=ExpId,proto3" json:"ExpId,omitempty"` // 实验ID
BaseFields *ExpBaseFields `protobuf:"bytes,3,opt,name=base_fields,json=baseFields,proto3" json:"base_fields,omitempty"` // 基础字段
ExtFields map[string]float64 `protobuf:"bytes,4,rep,name=ext_fields,json=extFields,proto3" json:"ext_fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"` // 扩展字段
Group map[string]uint64 `protobuf:"bytes,5,rep,name=group,proto3" json:"group,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` // 分组
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ExpData) Reset() {
*x = ExpData{}
mi := &file_cmd_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ExpData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExpData) ProtoMessage() {}
func (x *ExpData) ProtoReflect() protoreflect.Message {
mi := &file_cmd_proto_msgTypes[43]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExpData.ProtoReflect.Descriptor instead.
func (*ExpData) Descriptor() ([]byte, []int) {
return file_cmd_proto_rawDescGZIP(), []int{43}
}
func (x *ExpData) GetTime() uint64 {
if x != nil {
return x.Time
}
return 0
}
func (x *ExpData) GetExpId() uint32 {
if x != nil {
return x.ExpId
}
return 0
}
func (x *ExpData) GetBaseFields() *ExpBaseFields {
if x != nil {
return x.BaseFields
}
return nil
}
func (x *ExpData) GetExtFields() map[string]float64 {
if x != nil {
return x.ExtFields
}
return nil
}
func (x *ExpData) GetGroup() map[string]uint64 {
if x != nil {
return x.Group
}
return nil
}
type ExpBaseFields struct {
state protoimpl.MessageState `protogen:"open.v1"`
Cost float64 `protobuf:"fixed64,1,opt,name=cost,proto3" json:"cost,omitempty"` // 花费
Exposure int64 `protobuf:"varint,2,opt,name=exposure,proto3" json:"exposure,omitempty"` // 曝光量
Click int64 `protobuf:"varint,3,opt,name=click,proto3" json:"click,omitempty"` // 点击量
Cpm float64 `protobuf:"fixed64,4,opt,name=cpm,proto3" json:"cpm,omitempty"` // 单次曝光成本
Cpc float64 `protobuf:"fixed64,5,opt,name=cpc,proto3" json:"cpc,omitempty"` // 单次点击成本
Cpa float64 `protobuf:"fixed64,6,opt,name=cpa,proto3" json:"cpa,omitempty"` // 单次转化成本
Ctr float64 `protobuf:"fixed64,7,opt,name=ctr,proto3" json:"ctr,omitempty"` // 点击率
Cvr float64 `protobuf:"fixed64,8,opt,name=cvr,proto3" json:"cvr,omitempty"` // 浅层转化率
CvrSecond float64 `protobuf:"fixed64,9,opt,name=cvr_second,json=cvrSecond,proto3" json:"cvr_second,omitempty"` // 深层转化率
Conversion int64 `protobuf:"varint,10,opt,name=conversion,proto3" json:"conversion,omitempty"` // 浅层转化量
ConversionSecond int64 `protobuf:"varint,11,opt,name=conversion_second,json=conversionSecond,proto3" json:"conversion_second,omitempty"` // 深层转化量
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ExpBaseFields) Reset() {
*x = ExpBaseFields{}
mi := &file_cmd_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ExpBaseFields) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExpBaseFields) ProtoMessage() {}
func (x *ExpBaseFields) ProtoReflect() protoreflect.Message {
mi := &file_cmd_proto_msgTypes[44]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExpBaseFields.ProtoReflect.Descriptor instead.
func (*ExpBaseFields) Descriptor() ([]byte, []int) {
return file_cmd_proto_rawDescGZIP(), []int{44}
}
func (x *ExpBaseFields) GetCost() float64 {
if x != nil {
return x.Cost
}
return 0
}
func (x *ExpBaseFields) GetExposure() int64 {
if x != nil {
return x.Exposure
}
return 0
}
func (x *ExpBaseFields) GetClick() int64 {
if x != nil {
return x.Click
}
return 0
}
func (x *ExpBaseFields) GetCpm() float64 {
if x != nil {
return x.Cpm
}
return 0
}
func (x *ExpBaseFields) GetCpc() float64 {
if x != nil {
return x.Cpc
}
return 0
}
func (x *ExpBaseFields) GetCpa() float64 {
if x != nil {
return x.Cpa
}
return 0
}
func (x *ExpBaseFields) GetCtr() float64 {
if x != nil {
return x.Ctr
}
return 0
}
func (x *ExpBaseFields) GetCvr() float64 {
if x != nil {
return x.Cvr
}
return 0
}
func (x *ExpBaseFields) GetCvrSecond() float64 {
if x != nil {
return x.CvrSecond
}
return 0
}
func (x *ExpBaseFields) GetConversion() int64 {
if x != nil {
return x.Conversion
}
return 0
}
func (x *ExpBaseFields) GetConversionSecond() int64 {
if x != nil {
return x.ConversionSecond
}
return 0
}
var File_cmd_proto protoreflect.FileDescriptor var File_cmd_proto protoreflect.FileDescriptor
const file_cmd_proto_rawDesc = "" + const file_cmd_proto_rawDesc = "" +
@@ -3433,11 +3706,10 @@ const file_cmd_proto_rawDesc = "" +
"\vwrite_bytes\x18\x02 \x01(\v2\x0e.saasapi.BytesR\n" + "\vwrite_bytes\x18\x02 \x01(\v2\x0e.saasapi.BytesR\n" +
"writeBytes\x125\n" + "writeBytes\x125\n" +
"\rwrite_uint32s\x18\x03 \x01(\v2\x10.saasapi.Uint32sR\fwriteUint32s\x12O\n" + "\rwrite_uint32s\x18\x03 \x01(\v2\x10.saasapi.Uint32sR\fwriteUint32s\x12O\n" +
"\x17write_flags_with_expire\x18\x04 \x01(\v2\x18.saasapi.FlagsWithExpireR\x14writeFlagsWithExpire\"S\n" + "\x17write_flags_with_expire\x18\x04 \x01(\v2\x18.saasapi.FlagsWithExpireR\x14writeFlagsWithExpire\"6\n" +
"\x05Bytes\x12\x14\n" + "\x05Bytes\x12\x14\n" +
"\x05bytes\x18\x01 \x01(\fR\x05bytes\x12\x17\n" + "\x05bytes\x18\x01 \x01(\fR\x05bytes\x12\x17\n" +
"\aindex_1\x18\x02 \x01(\x04R\x06index1\x12\x1b\n" + "\aindex_1\x18\x02 \x01(\x04R\x06index1\"<\n" +
"\aindex_2\x18\x03 \x01(\x04B\x02\x18\x01R\x06index2\"<\n" +
"\aUint32s\x12\x18\n" + "\aUint32s\x12\x18\n" +
"\auint32s\x18\x01 \x03(\rR\auint32s\x12\x17\n" + "\auint32s\x18\x01 \x03(\rR\auint32s\x12\x17\n" +
"\aindex_1\x18\x02 \x01(\x04R\x06index1\"o\n" + "\aindex_1\x18\x02 \x01(\x04R\x06index1\"o\n" +
@@ -3515,8 +3787,19 @@ const file_cmd_proto_rawDesc = "" +
"\rserver_openid\x18\x04 \x01(\tR\fserverOpenid\x12\x1b\n" + "\rserver_openid\x18\x04 \x01(\tR\fserverOpenid\x12\x1b\n" +
"\x02os\x18\x05 \x01(\x0e2\v.saasapi.OSR\x02os\"\x0e\n" + "\x02os\x18\x05 \x01(\x0e2\v.saasapi.OSR\x02os\"\x0e\n" +
"\fScriptUpdate\"\t\n" + "\fScriptUpdate\"\t\n" +
"\aExpList\"\b\n" + "\aExpList\"\xa1\x02\n" +
"\x06ExpGet\"\xa9\a\n" + "\x06ExpGet\x12\x1d\n" +
"\n" +
"ext_fields\x18\x01 \x03(\tR\textFields\x12&\n" +
"\x0fwhere_begin_day\x18\n" +
" \x01(\x04R\rwhereBeginDay\x12\"\n" +
"\rwhere_end_day\x18\v \x01(\x04R\vwhereEndDay\x12 \n" +
"\fwhere_exp_id\x18\f \x03(\rR\n" +
"whereExpId\x12!\n" +
"\fwhere_target\x18\r \x01(\tR\vwhereTarget\x12.\n" +
"\x13where_advertiser_id\x18\x0e \x03(\x04R\x11whereAdvertiserId\x12\x19\n" +
"\bgroup_by\x18\x14 \x03(\tR\agroupBy\x12\x1c\n" +
"\tTotalFlag\x18\x1e \x01(\rR\tTotalFlag\"\xa9\a\n" +
"\aSaasRes\x12&\n" + "\aSaasRes\x12&\n" +
"\x04code\x18\x01 \x01(\x0e2\x12.saasapi.ErrorCodeR\x04code\x12\x16\n" + "\x04code\x18\x01 \x01(\x0e2\x12.saasapi.ErrorCodeR\x04code\x12\x16\n" +
"\x06status\x18\x02 \x01(\tR\x06status\x12-\n" + "\x06status\x18\x02 \x01(\tR\x06status\x12-\n" +
@@ -3605,8 +3888,40 @@ const file_cmd_proto_rawDesc = "" +
"\tExpBucket\x12\x1b\n" + "\tExpBucket\x12\x1b\n" +
"\tbucket_id\x18\x01 \x01(\rR\bbucketId\x12\x1a\n" + "\tbucket_id\x18\x01 \x01(\rR\bbucketId\x12\x1a\n" +
"\tpt_exp_id\x18\x02 \x01(\rR\aptExpId\x12\x18\n" + "\tpt_exp_id\x18\x02 \x01(\rR\aptExpId\x12\x18\n" +
"\apercent\x18\x03 \x01(\rR\apercent\"\v\n" + "\apercent\x18\x03 \x01(\rR\apercent\"7\n" +
"\tExpGetRes*=\n" + "\tExpGetRes\x12*\n" +
"\aexpdata\x18\x01 \x03(\v2\x10.saasapi.ExpDataR\aexpdata\"\xd7\x02\n" +
"\aExpData\x12\x12\n" +
"\x04time\x18\x01 \x01(\x04R\x04time\x12\x14\n" +
"\x05ExpId\x18\x02 \x01(\rR\x05ExpId\x127\n" +
"\vbase_fields\x18\x03 \x01(\v2\x16.saasapi.ExpBaseFieldsR\n" +
"baseFields\x12>\n" +
"\n" +
"ext_fields\x18\x04 \x03(\v2\x1f.saasapi.ExpData.ExtFieldsEntryR\textFields\x121\n" +
"\x05group\x18\x05 \x03(\v2\x1b.saasapi.ExpData.GroupEntryR\x05group\x1a<\n" +
"\x0eExtFieldsEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x02 \x01(\x01R\x05value:\x028\x01\x1a8\n" +
"\n" +
"GroupEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x02 \x01(\x04R\x05value:\x028\x01\"\x9b\x02\n" +
"\rExpBaseFields\x12\x12\n" +
"\x04cost\x18\x01 \x01(\x01R\x04cost\x12\x1a\n" +
"\bexposure\x18\x02 \x01(\x03R\bexposure\x12\x14\n" +
"\x05click\x18\x03 \x01(\x03R\x05click\x12\x10\n" +
"\x03cpm\x18\x04 \x01(\x01R\x03cpm\x12\x10\n" +
"\x03cpc\x18\x05 \x01(\x01R\x03cpc\x12\x10\n" +
"\x03cpa\x18\x06 \x01(\x01R\x03cpa\x12\x10\n" +
"\x03ctr\x18\a \x01(\x01R\x03ctr\x12\x10\n" +
"\x03cvr\x18\b \x01(\x01R\x03cvr\x12\x1d\n" +
"\n" +
"cvr_second\x18\t \x01(\x01R\tcvrSecond\x12\x1e\n" +
"\n" +
"conversion\x18\n" +
" \x01(\x03R\n" +
"conversion\x12+\n" +
"\x11conversion_second\x18\v \x01(\x03R\x10conversionSecond*=\n" +
"\bBindType\x12\x13\n" + "\bBindType\x12\x13\n" +
"\x0fUnknownBindType\x10\x00\x12\r\n" + "\x0fUnknownBindType\x10\x00\x12\r\n" +
"\tAdgroupId\x10\x01\x12\r\n" + "\tAdgroupId\x10\x01\x12\r\n" +
@@ -3617,7 +3932,7 @@ const file_cmd_proto_rawDesc = "" +
"\x03ADQ\x10\x02\x12\x06\n" + "\x03ADQ\x10\x02\x12\x06\n" +
"\x02MP\x10\x03\x12\n" + "\x02MP\x10\x03\x12\n" +
"\n" + "\n" +
"\x06MktApi\x10\x04*\xfa\x03\n" + "\x06MktApi\x10\x04*\x8d\x04\n" +
"\tErrorCode\x12\b\n" + "\tErrorCode\x12\b\n" +
"\x04SUCC\x10\x00\x12\x13\n" + "\x04SUCC\x10\x00\x12\x13\n" +
"\x0fINVALID_ACCOUNT\x10e\x12\x15\n" + "\x0fINVALID_ACCOUNT\x10e\x12\x15\n" +
@@ -3646,7 +3961,8 @@ const file_cmd_proto_rawDesc = "" +
"\n" + "\n" +
"DATA_ERROR\x10\xc9\x01\x12\x0e\n" + "DATA_ERROR\x10\xc9\x01\x12\x0e\n" +
"\tCMD_ERROR\x10\xca\x01\x12\x0e\n" + "\tCMD_ERROR\x10\xca\x01\x12\x0e\n" +
"\tAPI_ERROR\x10\xad\x02*\x16\n" + "\tAPI_ERROR\x10\xad\x02\x12\x11\n" +
"\fTARGET_ERROR\x10\x91\x03*\x16\n" +
"\fCmdErrorCode\x12\x06\n" + "\fCmdErrorCode\x12\x06\n" +
"\x02OK\x10\x00*^\n" + "\x02OK\x10\x00*^\n" +
"\n" + "\n" +
@@ -3683,7 +3999,7 @@ func file_cmd_proto_rawDescGZIP() []byte {
} }
var file_cmd_proto_enumTypes = make([]protoimpl.EnumInfo, 7) var file_cmd_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
var file_cmd_proto_msgTypes = make([]protoimpl.MessageInfo, 44) var file_cmd_proto_msgTypes = make([]protoimpl.MessageInfo, 48)
var file_cmd_proto_goTypes = []any{ var file_cmd_proto_goTypes = []any{
(BindType)(0), // 0: saasapi.BindType (BindType)(0), // 0: saasapi.BindType
(BindSourceType)(0), // 1: saasapi.BindSourceType (BindSourceType)(0), // 1: saasapi.BindSourceType
@@ -3735,7 +4051,11 @@ var file_cmd_proto_goTypes = []any{
(*ExpListRes)(nil), // 47: saasapi.ExpListRes (*ExpListRes)(nil), // 47: saasapi.ExpListRes
(*ExpBucket)(nil), // 48: saasapi.ExpBucket (*ExpBucket)(nil), // 48: saasapi.ExpBucket
(*ExpGetRes)(nil), // 49: saasapi.ExpGetRes (*ExpGetRes)(nil), // 49: saasapi.ExpGetRes
nil, // 50: saasapi.TargetListRes.TargetListEntry (*ExpData)(nil), // 50: saasapi.ExpData
(*ExpBaseFields)(nil), // 51: saasapi.ExpBaseFields
nil, // 52: saasapi.TargetListRes.TargetListEntry
nil, // 53: saasapi.ExpData.ExtFieldsEntry
nil, // 54: saasapi.ExpData.GroupEntry
} }
var file_cmd_proto_depIdxs = []int32{ var file_cmd_proto_depIdxs = []int32{
8, // 0: saasapi.SaasReq.info:type_name -> saasapi.Info 8, // 0: saasapi.SaasReq.info:type_name -> saasapi.Info
@@ -3791,19 +4111,23 @@ var file_cmd_proto_depIdxs = []int32{
3, // 50: saasapi.ValueItem.cmd_code:type_name -> saasapi.CmdErrorCode 3, // 50: saasapi.ValueItem.cmd_code:type_name -> saasapi.CmdErrorCode
16, // 51: saasapi.ValueItem.flags_with_expire:type_name -> saasapi.FlagWithExpire 16, // 51: saasapi.ValueItem.flags_with_expire:type_name -> saasapi.FlagWithExpire
18, // 52: saasapi.TaskListRes.tasks:type_name -> saasapi.Task 18, // 52: saasapi.TaskListRes.tasks:type_name -> saasapi.Task
50, // 53: saasapi.TargetListRes.target_list:type_name -> saasapi.TargetListRes.TargetListEntry 52, // 53: saasapi.TargetListRes.target_list:type_name -> saasapi.TargetListRes.TargetListEntry
41, // 54: saasapi.Binds.binds:type_name -> saasapi.Bind 41, // 54: saasapi.Binds.binds:type_name -> saasapi.Bind
0, // 55: saasapi.Bind.bind_type:type_name -> saasapi.BindType 0, // 55: saasapi.Bind.bind_type:type_name -> saasapi.BindType
1, // 56: saasapi.Bind.bind_source:type_name -> saasapi.BindSourceType 1, // 56: saasapi.Bind.bind_source:type_name -> saasapi.BindSourceType
44, // 57: saasapi.BindSetRes.errors:type_name -> saasapi.BindError 44, // 57: saasapi.BindSetRes.errors:type_name -> saasapi.BindError
44, // 58: saasapi.BindDeleteRes.errors:type_name -> saasapi.BindError 44, // 58: saasapi.BindDeleteRes.errors:type_name -> saasapi.BindError
48, // 59: saasapi.ExpListRes.buckets:type_name -> saasapi.ExpBucket 48, // 59: saasapi.ExpListRes.buckets:type_name -> saasapi.ExpBucket
40, // 60: saasapi.TargetListRes.TargetListEntry.value:type_name -> saasapi.Binds 50, // 60: saasapi.ExpGetRes.expdata:type_name -> saasapi.ExpData
61, // [61:61] is the sub-list for method output_type 51, // 61: saasapi.ExpData.base_fields:type_name -> saasapi.ExpBaseFields
61, // [61:61] is the sub-list for method input_type 53, // 62: saasapi.ExpData.ext_fields:type_name -> saasapi.ExpData.ExtFieldsEntry
61, // [61:61] is the sub-list for extension type_name 54, // 63: saasapi.ExpData.group:type_name -> saasapi.ExpData.GroupEntry
61, // [61:61] is the sub-list for extension extendee 40, // 64: saasapi.TargetListRes.TargetListEntry.value:type_name -> saasapi.Binds
0, // [0:61] is the sub-list for field type_name 65, // [65:65] is the sub-list for method output_type
65, // [65:65] is the sub-list for method input_type
65, // [65:65] is the sub-list for extension type_name
65, // [65:65] is the sub-list for extension extendee
0, // [0:65] is the sub-list for field type_name
} }
func init() { file_cmd_proto_init() } func init() { file_cmd_proto_init() }
@@ -3852,7 +4176,7 @@ func file_cmd_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_cmd_proto_rawDesc), len(file_cmd_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_cmd_proto_rawDesc), len(file_cmd_proto_rawDesc)),
NumEnums: 7, NumEnums: 7,
NumMessages: 44, NumMessages: 48,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

155
cmd.proto
View File

@@ -189,8 +189,21 @@ message ExpList {
} }
// ExpGet 获取实验报表 // ExpGet 获取实验报表
// select base_fields, {EXT_FIELDS}
// where day between {WHERE_BEGIN_DAY} and {WHERE_END_DAY}
// and expid in {WHERE_EXP_ID}
// and target = {WHERE_TARGET}
// and advertiser_id in {WHERE_ADVERTISER_ID}
// group by {GROUP_BY}
message ExpGet { message ExpGet {
repeated string ext_fields = 1; // 扩展字段(除基础字段必然输出外,其余字段需在这里填写,也可以使用*输出全部扩展字段)
uint64 where_begin_day = 10; // 起始日期
uint64 where_end_day = 11; // 结束日期
repeated uint32 where_exp_id = 12; // 实验ID(1-10)
string where_target = 13; // 策略ID
repeated uint64 where_advertiser_id = 14; // 广告主ID
repeated string group_by = 20; // 当前支持广告主ID(advertiser_id)
uint32 TotalFlag = 30; // 是否汇总
} }
// SaasRes 命令返回 // SaasRes 命令返回
@@ -346,9 +359,145 @@ message ExpBucket {
// ExpGetRes 实验报表返回 // ExpGetRes 实验报表返回
message ExpGetRes { message ExpGetRes {
repeated ExpData expdata = 1; // 实验数据
} }
message ExpData {
uint64 time = 1; // 日期
uint32 ExpId = 2; // 实验ID
ExpBaseFields base_fields = 3; // 基础字段
map <string, double> ext_fields = 4; // 扩展字段
map<string, uint64> group = 5; // 分组
}
message ExpBaseFields {
double cost = 1; // 花费
int64 exposure = 2; // 曝光量
int64 click = 3; // 点击量
double cpm = 4; // 单次曝光成本
double cpc = 5; // 单次点击成本
double cpa = 6; // 单次转化成本
double ctr = 7; // 点击率
double cvr = 8; // 浅层转化率
double cvr_second = 9; // 深层转化率
int64 conversion = 10; // 浅层转化量
int64 conversion_second = 11; // 深层转化量
}
/*
type RtaResExpGetRecord struct {
Time int32 `json:"time"` // 时间
ExpId int64 `json:"exp_id"` // 实验ID
GroupInfo map[string]uint64 `json:"group_info"` // GroupBy信息
Cost float64 `json:"cost"` // 消耗(元)
Exposure int64 `json:"exposure"` // 曝光量(次)
Click int64 `json:"click"` // 点击量(次)
Cpm float64 `json:"cpm"` // 单次曝光成本处理时要转换成CPM方便理解这字段定义真的一言难尽
Cpc float64 `json:"cpc"` // 单次点击成本
Ctr float64 `json:"ctr"` // 点击率
Conversion int64 `json:"conversion"` // 浅层转化数
ConversionSecond int64 `json:"conversion_second"` // 深层转化数
Cvr float64 `json:"cvr"` // 浅层转化率
CvrSecond float64 `json:"cvr_second"` // 深层转化率
Og6 float64 `json:"og_6"` // 优化目标-关注
Og7 float64 `json:"og_7"` // 优化目标-点击
Og10 float64 `json:"og_10"` // 优化目标-跳转按钮点击
Og105 float64 `json:"og_105"` // 优化目标- 注册(App)
Og106 int64 `json:"og_106"` // 优化目标-次日留存
Og108 int64 `json:"og_108"` // 优化目标-完成购买数量
Og112 int64 `json:"og_112"` // 优化目标-快应用加桌面
Og114 int64 `json:"og_114"` // 优化目标-小游戏创角
Og115 int64 `json:"og_115"` // 优化目标-游戏授权
Og119 float64 `json:"og_119"` // 优化目标-授信
Og120 int64 `json:"og_120"` // 优化目标-提现
Og121 float64 `json:"og_121"` // 优化目标-广告变现
Og202 int64 `json:"og_202"` // 优化目标-商品收藏
Og204 float64 `json:"og_204"` // 优化目标-下单
Og205 float64 `json:"og_205"` // 优化目标-付费
Og301 float64 `json:"og_301"` // 优化目标-关键页面访问
Og302 int64 `json:"og_302"` // 优化目标-H5注册
Og307 int64 `json:"og_307"` // 优化目标-领券
Og315 int64 `json:"og_315"` // 优化目标-浏览量
Og316 int64 `json:"og_316"` // 优化目标-阅读文章
Og318 int64 `json:"og_318"` // 优化目标-预授信
Og403 int64 `json:"og_403"` // 优化目标-电话拨打
Og405 float64 `json:"og_405"` // 优化目标-表单预约
Og406 int64 `json:"og_406"` // 优化目标-完件
Og409 float64 `json:"og_409"` // 优化目标-有效线索
Og412 int64 `json:"og_412"` // 优化目标-加企微客户
Og413 int64 `json:"og_413"` // 优化目标-选课
Og418 int64 `json:"og_418"` // 优化目标-外链点击
Og419 int64 `json:"og_419"` // 优化目标-购券
Og421 int64 `json:"og_421"` // 优化目标-加群
Og501 int64 `json:"og_501"` // 优化目标-打开公众号
Og503 int64 `json:"og_503"` // 优化目标-关注后点击菜单栏
Og10000 int64 `json:"og_10000"` // 优化目标-综合线索收集
Og10004 int64 `json:"og_10004"` // 优化目标-首次购买会员
Og10006 int64 `json:"og_10006"` // 优化目标-微信流量预约
Og10007 int64 `json:"og_10007"` // 优化目标-首次下单
Og10008 int64 `json:"og_10008"` // 优化目标-点赞
Og10009 int64 `json:"og_10009"` // 优化目标-咨询留资
Og10601 int64 `json:"og_10601"` // 优化目标-次留
Og10801 float64 `json:"og_10801"` // 优化目标-首次付费
Bo6 int64 `json:"bo_6"` // 推广目标-公众号关注数
Bo7 int64 `json:"bo_7"` // 推广目标-公众号内下单人数
Bo23 int64 `json:"bo_23"` // 推广目标-关键页面访问数
Bo25 int64 `json:"bo_25"` // 推广目标-公众号注册数
Bo26 int64 `json:"bo_26"` // 推广目标-公众号发消息数
Bo41 int64 `json:"bo_41"` // 推广目标-公众号付费人数
ConversionCost101 float64 `json:"101_conversion_cost"` // 下单单价
Amount204 float64 `json:"204_amount"` // 下单金额
Roi204 float64 `json:"204_roi"` // 下单ROI
Roi204fd float64 `json:"204_roi_fd"` // 首日下单ROI(T+1更新)
Roi204tw float64 `json:"204_roi_tw"` // 3日下单ROI
Roi204ow float64 `json:"204_roi_ow"` // 7日下单ROI
Roi204td float64 `json:"204_roi_td"` // 15日下单ROI
Roi204om float64 `json:"204_roi_om"` // 30日下单ROI
OrderCost float64 `json:"order_cost"` // 下单成本
OrderCount int64 `json:"order_count"` // 下单数
Roi float64 `json:"roi"` // ROI
MdMgPurchaseUv int64 `json:"md_mg_purchase_uv"` // 小游戏首次付费人数
MdMgPurchaseVal1 int64 `json:"md_mg_purchase_val1"` // 小游戏首日付费金额(广告主回传)(分)
MdMgPurchaseVal int64 `json:"md_mg_purchase_val"` // 小游戏付费金额(分)
WeAppRegUv int64 `json:"weapp_reg_uv"` // 小游戏注册人数
ActiveCount int64 `json:"active_count"` // 激活数
InstallCount int64 `json:"install_count"` // 安装数
Count107 int64 `json:"107_count"` // 加入购物车数
AtCount402 int64 `json:"402_at_count"` // 开口数
SendGoodsCount int64 `json:"send_goods_count"` // 发货数(次)
Sign int64 `json:"sign"` // 签收数(次)
AtRate409405 float64 `json:"409_405_at_rate"` // 表单有效率
AtCost409 float64 `json:"409_at_cost"` // 有效销售线索成本
AtCount409 int64 `json:"409_at_count"` // 有效销售线索数
AtCost415 float64 `json:"415_at_cost"` // 试驾成本
AtCount415 int64 `json:"415_at_count"` // 试驾数
AtCost405 float64 `json:"405_at_cost"` // 表单预约成本(元)
AtCount405 int64 `json:"405_at_count"` // 表单预约数
AtCost108 float64 `json:"108_at_cost"` // 完成购买成本(元)
AtCount108 int64 `json:"108_at_count"` // 完成购买数
AogAction119 int64 `json:"119_aog_action"` // 授信数
AogAction406 int64 `json:"406_aog_action"` // 完件数
CvrClick119 float64 `json:"119_cvr_click"` // 点击授信率
CvrClick406 float64 `json:"406_cvr_click"` // 点击完件率
FinanceCreditPcvrAfterCaliBias float64 `json:"finance_credit_pcvr_after_cali_bias"` // pcvrbias金融pdcvr修正后授信(校正后)
FinanceCreditPcvrBeforeCaliBias float64 `json:"finance_credit_pcvr_before_cali_bias"` // pcvrbias金融pdcvr修正后授信(校正前)
FinanceApplyOrginalPcvrBias float64 `json:"finance_apply_original_pcvr_bias"` // 原始pcvrbias金融pdcvr完件)
IndustryFinanceApplyPcvrBias float64 `json:"industry_finance_apply_pcvr_bias"` // pcvrbias(金融pdcvr完件)
ActiveCost float64 `json:"active_cost"` // 激活成本
ActiveRegisterRate float64 `json:"active_register_rate"` // 激活注册率
MdActiPurVal float64 `json:"md_acti_pur_val"` // 付费金额(激活口径)
MdActiPurValFdRoi float64 `json:"md_acti_pur_val_fd_roi"` // 首日付费金额(激活口径)
MdPurVal3 float64 `json:"md_pur_val_3"` // 3日付费金额(激活口径)
MdPurVal3Roi float64 `json:"md_pur_val_3_roi"` // 3日ROI(激活口径)
MdPurVal7 float64 `json:"md_pur_val_7"` // 7日付费金额(激活口径)
MdPurVal7Roi float64 `json:"md_pur_val_7_roi"` // 7日ROI(激活口径)
MdPurVal14 float64 `json:"md_pur_val_14"` // 14日付费金额(激活口径)
MdPurVal14Roi float64 `json:"md_pur_val_14_roi"` // 14日ROI(激活口径)
MdPurVal30 float64 `json:"md_pur_val_30"` // 30日付费金额(激活口径)
MdPurVal30Roi float64 `json:"md_pur_val_30_roi"` // 30日ROI(激活口径)
}
*/
// ErrorCode 返回码 // ErrorCode 返回码
enum ErrorCode { enum ErrorCode {
SUCC = 0; // 成功 SUCC = 0; // 成功
@@ -382,6 +531,8 @@ enum ErrorCode {
CMD_ERROR = 202; // 命令行执行错误 CMD_ERROR = 202; // 命令行执行错误
API_ERROR = 301; // 调用内部API错误 API_ERROR = 301; // 调用内部API错误
TARGET_ERROR = 401; // Target参数错误
} }
enum CmdErrorCode { enum CmdErrorCode {

View File

@@ -1,5 +1,180 @@
package main package main
import (
"flag"
"fmt"
"net/http"
"os"
"slices"
"strconv"
"strings"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type getExpParams struct {
saasHttp *saashttp.SaasClient
expIDs []uint32
beginDay uint64
endDay uint64
target string
advertiserIDs []uint64
groupBy []string
totalFlag bool
extFields []string
}
func RunExpGet(args ...string) error { func RunExpGet(args ...string) error {
fs := flag.NewFlagSet("get", flag.ExitOnError)
cfgFile := paramConfig(fs)
beginDay := paramWhereBeginDay(fs)
endDay := paramWhereEndDay(fs)
expIDs := paramWhereExpIds(fs)
target := paramWhereTarget(fs)
advertiserIDs := paramWhereAdvertiserId(fs)
groupBy := paramGroupBy(fs)
totalFlag := paramTotalFlag(fs)
extFields := paramExtFields(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
expIDsNumSlice := []uint32{}
if *expIDs != "" {
expIDsSlice := strings.Split(*expIDs, ",")
for _, id := range expIDsSlice {
idNum, err := strconv.ParseUint(id, 10, 32)
if err != nil {
fmt.Fprintln(os.Stderr, "expid parse error", "err", err)
return err
}
if idNum == 0 || idNum > 10 {
fmt.Fprintln(os.Stderr, "expid range error")
return nil
}
expIDsNumSlice = append(expIDsNumSlice, uint32(idNum))
}
}
if *beginDay < 20250101 || *beginDay > 21001231 || *endDay < 20250101 || *endDay > 21001231 {
fmt.Fprintln(os.Stderr, "begin/end day error")
return nil
}
if *target == "" {
fmt.Fprintln(os.Stderr, "target error")
return nil
}
uidNumSlice := []uint64{}
if *advertiserIDs != "" {
uidSlice := strings.Split(*advertiserIDs, ",")
for _, id := range uidSlice {
idNum, err := strconv.ParseUint(id, 10, 64)
if err != nil {
fmt.Fprintln(os.Stderr, "advertiser id parse error", "err", err)
return err
}
if idNum == 0 {
fmt.Fprintln(os.Stderr, "advertiser id error")
return nil
}
uidNumSlice = append(uidNumSlice, idNum)
}
}
groupBySlice := []string{}
if *groupBy != "" {
validGroupBy := map[string]bool{"advertiser_id": true, "user_weight_factor": true}
groupBySlice := strings.Split(*groupBy, ",")
for _, group := range groupBySlice {
if !validGroupBy[group] {
fmt.Fprintln(os.Stderr, "group by error", "group", group)
return nil
}
}
}
extFieldsSlice := []string{}
if *extFields != "" {
extFieldsSlice = strings.Split(*extFields, ",")
if slices.Contains(extFieldsSlice, "") {
fmt.Fprintln(os.Stderr, "ext field error")
return nil
}
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
getExpParams := getExpParams{
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
expIDs: expIDsNumSlice,
beginDay: *beginDay,
endDay: *endDay,
target: *target,
advertiserIDs: uidNumSlice,
groupBy: groupBySlice,
totalFlag: *totalFlag,
extFields: extFieldsSlice,
}
return doExpGet(getExpParams)
}
func doExpGet(getExpParams getExpParams) error {
totalFlag := uint32(0)
if getExpParams.totalFlag {
totalFlag = 1
}
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_ExpGet{
ExpGet: &saasapi.ExpGet{
WhereExpId: getExpParams.expIDs,
WhereBeginDay: getExpParams.beginDay,
WhereEndDay: getExpParams.endDay,
WhereTarget: getExpParams.target,
WhereAdvertiserId: getExpParams.advertiserIDs,
GroupBy: getExpParams.groupBy,
TotalFlag: totalFlag,
ExtFields: getExpParams.extFields,
},
},
}
res, err := getExpParams.saasHttp.ExpGet(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit GetExp error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "get exp failed", "code", res.Code, "status", res.Status)
return nil
}
getExpRes := res.GetExpGetRes()
fmt.Printf("exp res: %v\n", protojson.Format(getExpRes))
return nil return nil
} }

View File

@@ -117,6 +117,38 @@ func paramOS(fs *flag.FlagSet) *uint {
return fs.Uint("os", 2, "1=iOS, 2=Android, default=2") return fs.Uint("os", 2, "1=iOS, 2=Android, default=2")
} }
func paramWhereBeginDay(fs *flag.FlagSet) *uint64 {
return fs.Uint64("beginday", 0, "Begin day")
}
func paramWhereEndDay(fs *flag.FlagSet) *uint64 {
return fs.Uint64("endday", 0, "End day")
}
func paramWhereExpIds(fs *flag.FlagSet) *string {
return fs.String("expids", "", "Exp IDs. Use commas to separate multiple IDs. empty is all")
}
func paramWhereTarget(fs *flag.FlagSet) *string {
return fs.String("target", "", "Target ID")
}
func paramWhereAdvertiserId(fs *flag.FlagSet) *string {
return fs.String("uid", "", "Advertiser IDs. Use commas to separate multiple IDs.")
}
func paramGroupBy(fs *flag.FlagSet) *string {
return fs.String("groupby", "", "Group by. Use commas to separate multiple fields. empty is none")
}
func paramExtFields(fs *flag.FlagSet) *string {
return fs.String("extfields", "", "Ext fields. Use commas to separate multiple fields. * is all")
}
func paramTotalFlag(fs *flag.FlagSet) *bool {
return fs.Bool("total", false, "Total flag")
}
// ParseByteSize 解析字节大小字符串为字节数 // ParseByteSize 解析字节大小字符串为字节数
func ParseByteSize(sizeStr string) (uint64, error) { func ParseByteSize(sizeStr string) (uint64, error) {
sizeStr = strings.TrimSpace(sizeStr) sizeStr = strings.TrimSpace(sizeStr)