feat(statistic): add event.proto and statistic.proto with 7 RPCs + 2 event RPCs
This commit is contained in:
parent
3707125549
commit
4212914057
236
backend/pkg/proto/event/event.pb.go
Normal file
236
backend/pkg/proto/event/event.pb.go
Normal file
@ -0,0 +1,236 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.34.0
|
||||
// source: event.proto
|
||||
|
||||
package event
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// 单条事件
|
||||
type Event struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
EventId string `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` // 事件 ID(UUID,客户端生成,用于去重)
|
||||
UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 用户 ID
|
||||
StarId int64 `protobuf:"varint,3,opt,name=star_id,json=starId,proto3" json:"star_id,omitempty"` // 顶粉星城 ID
|
||||
EventType string `protobuf:"bytes,4,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` // 事件类型(如 "asset.like", "exhibition.start")
|
||||
OccurredAt int64 `protobuf:"varint,5,opt,name=occurred_at,json=occurredAt,proto3" json:"occurred_at,omitempty"` // 事件发生时间(ms timestamp)
|
||||
ReceivedAt int64 `protobuf:"varint,6,opt,name=received_at,json=receivedAt,proto3" json:"received_at,omitempty"` // 服务端接收时间(ms,服务端填充)
|
||||
Properties map[string]string `protobuf:"bytes,7,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // 自定义属性(扁平 key-value)
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Event) Reset() {
|
||||
*x = Event{}
|
||||
mi := &file_event_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Event) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Event) ProtoMessage() {}
|
||||
|
||||
func (x *Event) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_event_proto_msgTypes[0]
|
||||
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 Event.ProtoReflect.Descriptor instead.
|
||||
func (*Event) Descriptor() ([]byte, []int) {
|
||||
return file_event_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Event) GetEventId() string {
|
||||
if x != nil {
|
||||
return x.EventId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Event) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Event) GetStarId() int64 {
|
||||
if x != nil {
|
||||
return x.StarId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Event) GetEventType() string {
|
||||
if x != nil {
|
||||
return x.EventType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Event) GetOccurredAt() int64 {
|
||||
if x != nil {
|
||||
return x.OccurredAt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Event) GetReceivedAt() int64 {
|
||||
if x != nil {
|
||||
return x.ReceivedAt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Event) GetProperties() map[string]string {
|
||||
if x != nil {
|
||||
return x.Properties
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 批量事件请求
|
||||
type BatchEventRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Events []*Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *BatchEventRequest) Reset() {
|
||||
*x = BatchEventRequest{}
|
||||
mi := &file_event_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *BatchEventRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BatchEventRequest) ProtoMessage() {}
|
||||
|
||||
func (x *BatchEventRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_event_proto_msgTypes[1]
|
||||
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 BatchEventRequest.ProtoReflect.Descriptor instead.
|
||||
func (*BatchEventRequest) Descriptor() ([]byte, []int) {
|
||||
return file_event_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *BatchEventRequest) GetEvents() []*Event {
|
||||
if x != nil {
|
||||
return x.Events
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_event_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_event_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vevent.proto\x12\rtopfans.event\"\xba\x02\n" +
|
||||
"\x05Event\x12\x19\n" +
|
||||
"\bevent_id\x18\x01 \x01(\tR\aeventId\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\x03R\x06userId\x12\x17\n" +
|
||||
"\astar_id\x18\x03 \x01(\x03R\x06starId\x12\x1d\n" +
|
||||
"\n" +
|
||||
"event_type\x18\x04 \x01(\tR\teventType\x12\x1f\n" +
|
||||
"\voccurred_at\x18\x05 \x01(\x03R\n" +
|
||||
"occurredAt\x12\x1f\n" +
|
||||
"\vreceived_at\x18\x06 \x01(\x03R\n" +
|
||||
"receivedAt\x12D\n" +
|
||||
"\n" +
|
||||
"properties\x18\a \x03(\v2$.topfans.event.Event.PropertiesEntryR\n" +
|
||||
"properties\x1a=\n" +
|
||||
"\x0fPropertiesEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"A\n" +
|
||||
"\x11BatchEventRequest\x12,\n" +
|
||||
"\x06events\x18\x01 \x03(\v2\x14.topfans.event.EventR\x06eventsB2Z0github.com/topfans/backend/pkg/proto/event;eventb\x06proto3"
|
||||
|
||||
var (
|
||||
file_event_proto_rawDescOnce sync.Once
|
||||
file_event_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_event_proto_rawDescGZIP() []byte {
|
||||
file_event_proto_rawDescOnce.Do(func() {
|
||||
file_event_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_event_proto_rawDesc), len(file_event_proto_rawDesc)))
|
||||
})
|
||||
return file_event_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_event_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_event_proto_goTypes = []any{
|
||||
(*Event)(nil), // 0: topfans.event.Event
|
||||
(*BatchEventRequest)(nil), // 1: topfans.event.BatchEventRequest
|
||||
nil, // 2: topfans.event.Event.PropertiesEntry
|
||||
}
|
||||
var file_event_proto_depIdxs = []int32{
|
||||
2, // 0: topfans.event.Event.properties:type_name -> topfans.event.Event.PropertiesEntry
|
||||
0, // 1: topfans.event.BatchEventRequest.events:type_name -> topfans.event.Event
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_event_proto_init() }
|
||||
func file_event_proto_init() {
|
||||
if File_event_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_event_proto_rawDesc), len(file_event_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_event_proto_goTypes,
|
||||
DependencyIndexes: file_event_proto_depIdxs,
|
||||
MessageInfos: file_event_proto_msgTypes,
|
||||
}.Build()
|
||||
File_event_proto = out.File
|
||||
file_event_proto_goTypes = nil
|
||||
file_event_proto_depIdxs = nil
|
||||
}
|
||||
1510
backend/pkg/proto/statistic/statistic.pb.go
Normal file
1510
backend/pkg/proto/statistic/statistic.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
339
backend/pkg/proto/statistic/statistic.triple.go
Normal file
339
backend/pkg/proto/statistic/statistic.triple.go
Normal file
@ -0,0 +1,339 @@
|
||||
// Code generated by protoc-gen-triple. DO NOT EDIT.
|
||||
//
|
||||
// Source: statistic.proto
|
||||
package statistic
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
import (
|
||||
"dubbo.apache.org/dubbo-go/v3"
|
||||
"dubbo.apache.org/dubbo-go/v3/client"
|
||||
"dubbo.apache.org/dubbo-go/v3/common"
|
||||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||
"dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
|
||||
"dubbo.apache.org/dubbo-go/v3/server"
|
||||
event "github.com/topfans/backend/pkg/proto/event"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the Triple package
|
||||
// are compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of Triple newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of Triple or updating the Triple
|
||||
// version compiled into your binary.
|
||||
const _ = triple_protocol.IsAtLeastVersion0_1_0
|
||||
|
||||
const (
|
||||
// StatisticServiceName is the fully-qualified name of the StatisticService service.
|
||||
StatisticServiceName = "topfans.statistic.StatisticService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// StatisticServiceGetTodayOverviewProcedure is the fully-qualified name of the StatisticService's GetTodayOverview RPC.
|
||||
StatisticServiceGetTodayOverviewProcedure = "/topfans.statistic.StatisticService/GetTodayOverview"
|
||||
// StatisticServiceGet7DayIncomeCurveProcedure is the fully-qualified name of the StatisticService's Get7DayIncomeCurve RPC.
|
||||
StatisticServiceGet7DayIncomeCurveProcedure = "/topfans.statistic.StatisticService/Get7DayIncomeCurve"
|
||||
// StatisticServiceGetExhibitionIncomeSummaryProcedure is the fully-qualified name of the StatisticService's GetExhibitionIncomeSummary RPC.
|
||||
StatisticServiceGetExhibitionIncomeSummaryProcedure = "/topfans.statistic.StatisticService/GetExhibitionIncomeSummary"
|
||||
// StatisticServiceGetLikeIncomeByLevelProcedure is the fully-qualified name of the StatisticService's GetLikeIncomeByLevel RPC.
|
||||
StatisticServiceGetLikeIncomeByLevelProcedure = "/topfans.statistic.StatisticService/GetLikeIncomeByLevel"
|
||||
// StatisticServiceGetTopAssetsByEarningProcedure is the fully-qualified name of the StatisticService's GetTopAssetsByEarning RPC.
|
||||
StatisticServiceGetTopAssetsByEarningProcedure = "/topfans.statistic.StatisticService/GetTopAssetsByEarning"
|
||||
// StatisticServiceGetAssetLevelDistributionProcedure is the fully-qualified name of the StatisticService's GetAssetLevelDistribution RPC.
|
||||
StatisticServiceGetAssetLevelDistributionProcedure = "/topfans.statistic.StatisticService/GetAssetLevelDistribution"
|
||||
// StatisticServiceGetAssetUpgradeProgressProcedure is the fully-qualified name of the StatisticService's GetAssetUpgradeProgress RPC.
|
||||
StatisticServiceGetAssetUpgradeProgressProcedure = "/topfans.statistic.StatisticService/GetAssetUpgradeProgress"
|
||||
// StatisticServiceTrackEventProcedure is the fully-qualified name of the StatisticService's TrackEvent RPC.
|
||||
StatisticServiceTrackEventProcedure = "/topfans.statistic.StatisticService/TrackEvent"
|
||||
// StatisticServiceBatchTrackEventProcedure is the fully-qualified name of the StatisticService's BatchTrackEvent RPC.
|
||||
StatisticServiceBatchTrackEventProcedure = "/topfans.statistic.StatisticService/BatchTrackEvent"
|
||||
)
|
||||
|
||||
var (
|
||||
_ StatisticService = (*StatisticServiceImpl)(nil)
|
||||
)
|
||||
|
||||
// StatisticService is a client for the topfans.statistic.StatisticService service.
|
||||
type StatisticService interface {
|
||||
GetTodayOverview(ctx context.Context, req *GetTodayOverviewRequest, opts ...client.CallOption) (*GetTodayOverviewResponse, error)
|
||||
Get7DayIncomeCurve(ctx context.Context, req *Get7DayIncomeCurveRequest, opts ...client.CallOption) (*Get7DayIncomeCurveResponse, error)
|
||||
GetExhibitionIncomeSummary(ctx context.Context, req *GetExhibitionIncomeSummaryRequest, opts ...client.CallOption) (*GetExhibitionIncomeSummaryResponse, error)
|
||||
GetLikeIncomeByLevel(ctx context.Context, req *GetLikeIncomeByLevelRequest, opts ...client.CallOption) (*GetLikeIncomeByLevelResponse, error)
|
||||
GetTopAssetsByEarning(ctx context.Context, req *GetTopAssetsByEarningRequest, opts ...client.CallOption) (*GetTopAssetsByEarningResponse, error)
|
||||
GetAssetLevelDistribution(ctx context.Context, req *GetAssetLevelDistributionRequest, opts ...client.CallOption) (*GetAssetLevelDistributionResponse, error)
|
||||
GetAssetUpgradeProgress(ctx context.Context, req *GetAssetUpgradeProgressRequest, opts ...client.CallOption) (*GetAssetUpgradeProgressResponse, error)
|
||||
TrackEvent(ctx context.Context, req *event.Event, opts ...client.CallOption) (*TrackEventResponse, error)
|
||||
BatchTrackEvent(ctx context.Context, req *event.BatchEventRequest, opts ...client.CallOption) (*TrackEventResponse, error)
|
||||
}
|
||||
|
||||
// NewStatisticService constructs a client for the statistic.StatisticService service.
|
||||
func NewStatisticService(cli *client.Client, opts ...client.ReferenceOption) (StatisticService, error) {
|
||||
conn, err := cli.DialWithInfo("topfans.statistic.StatisticService", &StatisticService_ClientInfo, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &StatisticServiceImpl{
|
||||
conn: conn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func SetConsumerStatisticService(srv common.RPCService) {
|
||||
dubbo.SetConsumerServiceWithInfo(srv, &StatisticService_ClientInfo)
|
||||
}
|
||||
|
||||
// StatisticServiceImpl implements StatisticService.
|
||||
type StatisticServiceImpl struct {
|
||||
conn *client.Connection
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetTodayOverview(ctx context.Context, req *GetTodayOverviewRequest, opts ...client.CallOption) (*GetTodayOverviewResponse, error) {
|
||||
resp := new(GetTodayOverviewResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetTodayOverview", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) Get7DayIncomeCurve(ctx context.Context, req *Get7DayIncomeCurveRequest, opts ...client.CallOption) (*Get7DayIncomeCurveResponse, error) {
|
||||
resp := new(Get7DayIncomeCurveResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "Get7DayIncomeCurve", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetExhibitionIncomeSummary(ctx context.Context, req *GetExhibitionIncomeSummaryRequest, opts ...client.CallOption) (*GetExhibitionIncomeSummaryResponse, error) {
|
||||
resp := new(GetExhibitionIncomeSummaryResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetExhibitionIncomeSummary", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetLikeIncomeByLevel(ctx context.Context, req *GetLikeIncomeByLevelRequest, opts ...client.CallOption) (*GetLikeIncomeByLevelResponse, error) {
|
||||
resp := new(GetLikeIncomeByLevelResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetLikeIncomeByLevel", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetTopAssetsByEarning(ctx context.Context, req *GetTopAssetsByEarningRequest, opts ...client.CallOption) (*GetTopAssetsByEarningResponse, error) {
|
||||
resp := new(GetTopAssetsByEarningResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetTopAssetsByEarning", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetAssetLevelDistribution(ctx context.Context, req *GetAssetLevelDistributionRequest, opts ...client.CallOption) (*GetAssetLevelDistributionResponse, error) {
|
||||
resp := new(GetAssetLevelDistributionResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetAssetLevelDistribution", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) GetAssetUpgradeProgress(ctx context.Context, req *GetAssetUpgradeProgressRequest, opts ...client.CallOption) (*GetAssetUpgradeProgressResponse, error) {
|
||||
resp := new(GetAssetUpgradeProgressResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetAssetUpgradeProgress", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) TrackEvent(ctx context.Context, req *event.Event, opts ...client.CallOption) (*TrackEventResponse, error) {
|
||||
resp := new(TrackEventResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "TrackEvent", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *StatisticServiceImpl) BatchTrackEvent(ctx context.Context, req *event.BatchEventRequest, opts ...client.CallOption) (*TrackEventResponse, error) {
|
||||
resp := new(TrackEventResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "BatchTrackEvent", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var StatisticService_ClientInfo = client.ClientInfo{
|
||||
InterfaceName: "topfans.statistic.StatisticService",
|
||||
MethodNames: []string{"GetTodayOverview", "Get7DayIncomeCurve", "GetExhibitionIncomeSummary", "GetLikeIncomeByLevel", "GetTopAssetsByEarning", "GetAssetLevelDistribution", "GetAssetUpgradeProgress", "TrackEvent", "BatchTrackEvent"},
|
||||
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
|
||||
dubboCli := dubboCliRaw.(*StatisticServiceImpl)
|
||||
dubboCli.conn = conn
|
||||
},
|
||||
}
|
||||
|
||||
// StatisticServiceHandler is an implementation of the topfans.statistic.StatisticService service.
|
||||
type StatisticServiceHandler interface {
|
||||
GetTodayOverview(context.Context, *GetTodayOverviewRequest) (*GetTodayOverviewResponse, error)
|
||||
Get7DayIncomeCurve(context.Context, *Get7DayIncomeCurveRequest) (*Get7DayIncomeCurveResponse, error)
|
||||
GetExhibitionIncomeSummary(context.Context, *GetExhibitionIncomeSummaryRequest) (*GetExhibitionIncomeSummaryResponse, error)
|
||||
GetLikeIncomeByLevel(context.Context, *GetLikeIncomeByLevelRequest) (*GetLikeIncomeByLevelResponse, error)
|
||||
GetTopAssetsByEarning(context.Context, *GetTopAssetsByEarningRequest) (*GetTopAssetsByEarningResponse, error)
|
||||
GetAssetLevelDistribution(context.Context, *GetAssetLevelDistributionRequest) (*GetAssetLevelDistributionResponse, error)
|
||||
GetAssetUpgradeProgress(context.Context, *GetAssetUpgradeProgressRequest) (*GetAssetUpgradeProgressResponse, error)
|
||||
TrackEvent(context.Context, *event.Event) (*TrackEventResponse, error)
|
||||
BatchTrackEvent(context.Context, *event.BatchEventRequest) (*TrackEventResponse, error)
|
||||
}
|
||||
|
||||
func RegisterStatisticServiceHandler(srv *server.Server, hdlr StatisticServiceHandler, opts ...server.ServiceOption) error {
|
||||
return srv.Register(hdlr, &StatisticService_ServiceInfo, opts...)
|
||||
}
|
||||
|
||||
func SetProviderStatisticService(srv common.RPCService) {
|
||||
dubbo.SetProviderServiceWithInfo(srv, &StatisticService_ServiceInfo)
|
||||
}
|
||||
|
||||
var StatisticService_ServiceInfo = server.ServiceInfo{
|
||||
InterfaceName: "topfans.statistic.StatisticService",
|
||||
ServiceType: (*StatisticServiceHandler)(nil),
|
||||
Methods: []server.MethodInfo{
|
||||
{
|
||||
Name: "GetTodayOverview",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetTodayOverviewRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetTodayOverviewRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetTodayOverview(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Get7DayIncomeCurve",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(Get7DayIncomeCurveRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*Get7DayIncomeCurveRequest)
|
||||
res, err := handler.(StatisticServiceHandler).Get7DayIncomeCurve(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetExhibitionIncomeSummary",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetExhibitionIncomeSummaryRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetExhibitionIncomeSummaryRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetExhibitionIncomeSummary(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetLikeIncomeByLevel",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetLikeIncomeByLevelRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetLikeIncomeByLevelRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetLikeIncomeByLevel(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetTopAssetsByEarning",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetTopAssetsByEarningRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetTopAssetsByEarningRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetTopAssetsByEarning(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetAssetLevelDistribution",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetAssetLevelDistributionRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetAssetLevelDistributionRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetAssetLevelDistribution(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetAssetUpgradeProgress",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(GetAssetUpgradeProgressRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*GetAssetUpgradeProgressRequest)
|
||||
res, err := handler.(StatisticServiceHandler).GetAssetUpgradeProgress(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "TrackEvent",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(event.Event)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*event.Event)
|
||||
res, err := handler.(StatisticServiceHandler).TrackEvent(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "BatchTrackEvent",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(event.BatchEventRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*event.BatchEventRequest)
|
||||
res, err := handler.(StatisticServiceHandler).BatchTrackEvent(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
25
backend/proto/event.proto
Normal file
25
backend/proto/event.proto
Normal file
@ -0,0 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package topfans.event;
|
||||
|
||||
option go_package = "github.com/topfans/backend/pkg/proto/event;event";
|
||||
|
||||
// ==================== 通用事件 ====================
|
||||
// 独立 proto 文件,跨服务复用。其他服务(如 socialService、assetService 等)
|
||||
// 可以只引用 event.proto 而不必引用 statistic.proto,避免循环依赖。
|
||||
|
||||
// 单条事件
|
||||
message Event {
|
||||
string event_id = 1; // 事件 ID(UUID,客户端生成,用于去重)
|
||||
int64 user_id = 2; // 用户 ID
|
||||
int64 star_id = 3; // 顶粉星城 ID
|
||||
string event_type = 4; // 事件类型(如 "asset.like", "exhibition.start")
|
||||
int64 occurred_at = 5; // 事件发生时间(ms timestamp)
|
||||
int64 received_at = 6; // 服务端接收时间(ms,服务端填充)
|
||||
map<string, string> properties = 7; // 自定义属性(扁平 key-value)
|
||||
}
|
||||
|
||||
// 批量事件请求
|
||||
message BatchEventRequest {
|
||||
repeated Event events = 1;
|
||||
}
|
||||
146
backend/proto/statistic.proto
Normal file
146
backend/proto/statistic.proto
Normal file
@ -0,0 +1,146 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package topfans.statistic;
|
||||
|
||||
option go_package = "github.com/topfans/backend/pkg/proto/statistic;statistic";
|
||||
|
||||
import "proto/event.proto";
|
||||
|
||||
// ==================== StatisticService ====================
|
||||
// 看板 7 RPC(经 gateway 暴露给前端)+ 事件采集 2 RPC(内部)。
|
||||
// Go 侧由 mobile_provider.go / internal_provider.go 两个文件实现同名服务。
|
||||
|
||||
service StatisticService {
|
||||
// ============ 看板 7 RPC(经 gateway 暴露) ============
|
||||
rpc GetTodayOverview(GetTodayOverviewRequest) returns (GetTodayOverviewResponse);
|
||||
rpc Get7DayIncomeCurve(Get7DayIncomeCurveRequest) returns (Get7DayIncomeCurveResponse);
|
||||
rpc GetExhibitionIncomeSummary(GetExhibitionIncomeSummaryRequest) returns (GetExhibitionIncomeSummaryResponse);
|
||||
rpc GetLikeIncomeByLevel(GetLikeIncomeByLevelRequest) returns (GetLikeIncomeByLevelResponse);
|
||||
rpc GetTopAssetsByEarning(GetTopAssetsByEarningRequest) returns (GetTopAssetsByEarningResponse);
|
||||
rpc GetAssetLevelDistribution(GetAssetLevelDistributionRequest) returns (GetAssetLevelDistributionResponse);
|
||||
rpc GetAssetUpgradeProgress(GetAssetUpgradeProgressRequest) returns (GetAssetUpgradeProgressResponse);
|
||||
|
||||
// ============ 事件采集(内部 RPC) ============
|
||||
rpc TrackEvent(topfans.event.Event) returns (TrackEventResponse);
|
||||
rpc BatchTrackEvent(topfans.event.BatchEventRequest) returns (TrackEventResponse);
|
||||
}
|
||||
|
||||
// ====== 1. 今日概览 ======
|
||||
message GetTodayOverviewRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message GetTodayOverviewResponse {
|
||||
int64 crystal_balance = 1;
|
||||
int64 today_income = 2;
|
||||
int32 week_rank = 3; // 本期完整实现
|
||||
int32 week_total_users = 4; // 用于"击败 X%"展示
|
||||
}
|
||||
|
||||
// ====== 2. 七日收益曲线 ======
|
||||
message Get7DayIncomeCurveRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message DailyIncomePoint {
|
||||
string date = 1; // "YYYY-MM-DD"
|
||||
int64 income = 2;
|
||||
bool is_today = 3;
|
||||
bool is_peak = 4;
|
||||
}
|
||||
message Get7DayIncomeCurveResponse {
|
||||
repeated DailyIncomePoint points = 1;
|
||||
int64 total_income = 2;
|
||||
int64 avg_income = 3;
|
||||
}
|
||||
|
||||
// ====== 3. 展出收益中心 ======
|
||||
message GetExhibitionIncomeSummaryRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message TopExhibitionItem {
|
||||
int64 asset_id = 1;
|
||||
string asset_name = 2;
|
||||
string asset_thumb = 3;
|
||||
string duration_7d = 4; // 7 天累计展示时长("D:HH:MM:SS")
|
||||
int64 earnings_7d = 5;
|
||||
int32 avg_earnings = 6;
|
||||
}
|
||||
message GetExhibitionIncomeSummaryResponse {
|
||||
int32 exhibiting_count = 1; // 当前在展藏品数
|
||||
int32 starbook_count = 2; // 星图册数
|
||||
string total_duration = 3; // 累计展示时长
|
||||
int64 total_earnings = 4; // 累计收益
|
||||
repeated TopExhibitionItem top5 = 5;
|
||||
}
|
||||
|
||||
// ====== 4. 点赞收益按等级 ======
|
||||
message GetLikeIncomeByLevelRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message LikeIncomeLevelItem {
|
||||
string level = 1; // 藏品等级(N/R/SR/SSR/UR)
|
||||
int32 asset_count = 2;
|
||||
int64 total_income = 3;
|
||||
string thumb = 4; // 等级代表缩略图
|
||||
}
|
||||
message GetLikeIncomeByLevelResponse {
|
||||
int64 total_like_count = 1;
|
||||
int64 total_income = 2;
|
||||
repeated LikeIncomeLevelItem levels = 3;
|
||||
}
|
||||
|
||||
// ====== 5. 藏品 TOP5(按收益) ======
|
||||
message GetTopAssetsByEarningRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message TopAssetItem {
|
||||
int64 asset_id = 1;
|
||||
string asset_name = 2;
|
||||
string asset_thumb = 3;
|
||||
int64 total_earnings = 4;
|
||||
int32 rank = 5;
|
||||
}
|
||||
message GetTopAssetsByEarningResponse {
|
||||
repeated TopAssetItem items = 1;
|
||||
}
|
||||
|
||||
// ====== 6. 藏品等级分布 ======
|
||||
message GetAssetLevelDistributionRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message AssetLevelItem {
|
||||
string level = 1; // 藏品等级
|
||||
int32 count = 2; // 当前持有该等级的藏品数
|
||||
int32 total = 3; // 累计(历史)该等级藏品数
|
||||
}
|
||||
message GetAssetLevelDistributionResponse {
|
||||
repeated AssetLevelItem items = 1;
|
||||
}
|
||||
|
||||
// ====== 7. 升级进度 ======
|
||||
message GetAssetUpgradeProgressRequest {
|
||||
int64 star_id = 1;
|
||||
}
|
||||
message UpcomingLevelUpItem {
|
||||
int64 asset_id = 1;
|
||||
string asset_name = 2;
|
||||
string asset_thumb = 3;
|
||||
int32 like_progress = 4; // 0-100 进度
|
||||
int32 duration_progress = 5; // 0-100 进度
|
||||
}
|
||||
message RecentLevelUpItem {
|
||||
int64 asset_id = 1;
|
||||
string asset_name = 2;
|
||||
string asset_thumb = 3;
|
||||
string new_level = 4;
|
||||
int64 upgrade_time = 5; // ms timestamp
|
||||
}
|
||||
message GetAssetUpgradeProgressResponse {
|
||||
repeated UpcomingLevelUpItem upcoming = 1;
|
||||
repeated RecentLevelUpItem recent = 2;
|
||||
}
|
||||
|
||||
// ====== 事件采集响应 ======
|
||||
message TrackEventResponse {
|
||||
int32 accepted = 1; // 成功接收并进入 channel 的事件数
|
||||
int32 rejected = 2; // 被拒收的事件数(格式错误、限流等)
|
||||
}
|
||||
@ -67,7 +67,7 @@ move_triple_files() {
|
||||
|
||||
# 预先创建目标目录
|
||||
echo "📁 创建目标目录..."
|
||||
for name in common user social asset gallery ranking activity task starbook ai_chat; do
|
||||
for name in common user social asset gallery ranking activity task starbook ai_chat event statistic; do
|
||||
mkdir -p "pkg/proto/$name"
|
||||
done
|
||||
echo ""
|
||||
@ -208,6 +208,75 @@ move_triple_files "topfans/backend/pkg/proto/ai_chat" "pkg/proto/ai_chat"
|
||||
echo "✅ ai_chat.proto 编译完成"
|
||||
echo ""
|
||||
|
||||
# 编译 event.proto(仅生成 pb.go;event.proto 没有 service,生成 triple.go 会导致未使用 import 编译失败)
|
||||
echo "📦 编译 event.proto ..."
|
||||
protoc --proto_path=proto \
|
||||
--proto_path=. \
|
||||
--go_out=pkg/proto/event \
|
||||
--go_opt=paths=source_relative \
|
||||
event.proto
|
||||
|
||||
echo "✅ event.proto 编译完成"
|
||||
echo ""
|
||||
|
||||
# 编译 statistic.proto
|
||||
echo "📦 编译 statistic.proto ..."
|
||||
protoc --proto_path=proto \
|
||||
--proto_path=. \
|
||||
--go_out=pkg/proto/statistic \
|
||||
--go_opt=paths=source_relative \
|
||||
--go-triple_out=pkg/proto/statistic \
|
||||
--go-triple_opt=paths=source_relative \
|
||||
statistic.proto
|
||||
move_triple_files "topfans/backend/pkg/proto/statistic" "pkg/proto/statistic"
|
||||
|
||||
# 后处理:protoc-gen-go-triple v3.0.0 在跨包类型作 RPC 参数时丢包前缀。
|
||||
# statistic.proto 引用了 event.Event / event.BatchEventRequest,
|
||||
# triple 生成器把它们当作 statistic 包内类型(new(Event) / *Event),
|
||||
# 而未导入 event 包,导致编译失败。这里补回 event 包导入和类型前缀。
|
||||
TRIPLE_FILE="pkg/proto/statistic/statistic.triple.go"
|
||||
if [ -f "$TRIPLE_FILE" ]; then
|
||||
if ! grep -q 'github.com/topfans/backend/pkg/proto/event"' "$TRIPLE_FILE"; then
|
||||
# 在第二个 import 块(dubbo 块)的最末 import 行后追加 event 包导入
|
||||
# 用 awk 顺序扫描,找到第二个 "import (" 之后第一个 ")" 之前的最后一行
|
||||
python3 -c "
|
||||
import re, sys
|
||||
with open('$TRIPLE_FILE', 'r') as f:
|
||||
src = f.read()
|
||||
# 找所有 import 块,定位第二个 import ( ... )
|
||||
pattern = re.compile(r'(import\s*\([^)]*\))', re.MULTILINE)
|
||||
blocks = list(pattern.finditer(src))
|
||||
if len(blocks) >= 2:
|
||||
second = blocks[1]
|
||||
block_text = second.group(1)
|
||||
if 'pkg/proto/event' not in block_text:
|
||||
new_block = block_text[:-1].rstrip() + '\n\tevent \"github.com/topfans/backend/pkg/proto/event\"\n)'
|
||||
src = src[:second.start()] + new_block + src[second.end():]
|
||||
with open('$TRIPLE_FILE', 'w') as f:
|
||||
f.write(src)
|
||||
"
|
||||
# 把 RPC 方法签名 / new() / 类型断言中的裸 Event / BatchEventRequest 加上 event. 前缀
|
||||
# 注意:BSD sed(macOS)不支持 \b,改用 ([,)]) 等显式边界
|
||||
sed -i '' \
|
||||
-e 's/\*Event\([,)]\)/\*event.Event\1/g' \
|
||||
-e 's/\*Event$/&XXX/g' \
|
||||
-e 's/\*Event[^a-zA-Z._)/]/\*event.Event\&/g' \
|
||||
-e 's/new(Event)/new(event.Event)/g' \
|
||||
-e 's/\*BatchEventRequest\([,)]\)/\*event.BatchEventRequest\1/g' \
|
||||
-e 's/new(BatchEventRequest)/new(event.BatchEventRequest)/g' \
|
||||
"$TRIPLE_FILE"
|
||||
# 修复 args[0].(*Event) 类型断言 — 用单独的 sed 处理方括号
|
||||
sed -i '' \
|
||||
-e 's/(\*Event)/(\*event.Event)/g' \
|
||||
-e 's/(\*BatchEventRequest)/(\*event.BatchEventRequest)/g' \
|
||||
"$TRIPLE_FILE"
|
||||
echo " ✅ statistic.triple.go 已修复跨包类型引用(protoc-gen-go-triple v3.0.0 bug)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ statistic.proto 编译完成"
|
||||
echo ""
|
||||
|
||||
# 清理可能存在的冗余目录和文件
|
||||
echo "🔄 清理冗余文件..."
|
||||
|
||||
@ -218,7 +287,7 @@ if [ -d "github.com" ]; then
|
||||
fi
|
||||
|
||||
# 删除 proto 目录下的生成文件(如果存在)
|
||||
for name in common user social asset gallery ranking activity task starbook ai_chat; do
|
||||
for name in common user social asset gallery ranking activity task starbook ai_chat event statistic; do
|
||||
if [ -f "proto/$name.pb.go" ]; then
|
||||
rm "proto/$name.pb.go"
|
||||
echo " ✅ proto/$name.pb.go 已清理"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user