diff --git a/internal/api/group.go b/internal/api/group.go index c165f8aab..da645ea15 100644 --- a/internal/api/group.go +++ b/internal/api/group.go @@ -114,3 +114,7 @@ func (o *GroupApi) GetJoinedSuperGroupList(c *gin.Context) { func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) { a2r.Call(group.GroupClient.GetSuperGroupsInfo, o.Client, c) } + +func (o *GroupApi) GroupCreateCount(c *gin.Context) { + a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c) +} diff --git a/internal/api/route.go b/internal/api/route.go index f6cfe29aa..6c5c264e2 100644 --- a/internal/api/route.go +++ b/internal/api/route.go @@ -154,6 +154,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive { statisticsGroup.POST("/user/register", u.UserRegisterCount) statisticsGroup.POST("/user/active", m.GetActiveUser) + statisticsGroup.POST("/group/create", g.GroupCreateCount) } return r } diff --git a/internal/rpc/group/statistics.go b/internal/rpc/group/statistics.go new file mode 100644 index 000000000..c6664b4df --- /dev/null +++ b/internal/rpc/group/statistics.go @@ -0,0 +1,28 @@ +package group + +import ( + "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" + "time" +) + +func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCreateCountReq) (*group.GroupCreateCountResp, error) { + if req.Start > req.End { + return nil, errs.ErrArgs.Wrap("start > end") + } + total, err := s.GroupDatabase.CountTotal(ctx, nil) + if err != nil { + return nil, err + } + start := time.UnixMilli(req.Start) + before, err := s.GroupDatabase.CountTotal(ctx, &start) + if err != nil { + return nil, err + } + count, err := s.GroupDatabase.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End)) + if err != nil { + return nil, err + } + return &group.GroupCreateCountResp{Total: total, Before: before, Count: count}, nil +} diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 19ae3e87e..54289e623 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -3,6 +3,7 @@ package controller import ( "context" "fmt" + "time" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" @@ -57,6 +58,11 @@ type GroupDatabase interface { DeleteSuperGroup(ctx context.Context, groupID string) error DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error + + // 获取群总数 + CountTotal(ctx context.Context, before *time.Time) (count int64, err error) + // 获取范围内群增量 + CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) } func NewGroupDatabase( @@ -419,3 +425,11 @@ func (g *groupDatabase) CreateSuperGroupMember(ctx context.Context, groupID stri } return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx) } + +func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { + return g.groupDB.CountTotal(ctx, before) +} + +func (g *groupDatabase) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { + return g.groupDB.CountRangeEverydayTotal(ctx, start, end) +} diff --git a/pkg/common/db/relation/group_model.go b/pkg/common/db/relation/group_model.go index 39feb5d7a..f3e1aec2f 100644 --- a/pkg/common/db/relation/group_model.go +++ b/pkg/common/db/relation/group_model.go @@ -4,8 +4,10 @@ import ( "context" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/ormutil" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "gorm.io/gorm" + "time" ) var _ relation.GroupModelInterface = (*GroupGorm)(nil) @@ -50,3 +52,30 @@ func (g *GroupGorm) Search(ctx context.Context, keyword string, pageNumber, show func (g *GroupGorm) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) { return groupIDs, utils.Wrap(g.DB.Model(&relation.GroupModel{}).Where("group_type = ? ", groupType).Pluck("group_id", &groupIDs).Error, "") } + +func (g *GroupGorm) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { + db := g.db(ctx).Model(&relation.GroupModel{}) + if before != nil { + db = db.Where("create_time < ?", before) + } + if err := db.Count(&count).Error; err != nil { + return 0, err + } + return count, nil +} + +func (g *GroupGorm) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { + var res []struct { + Date time.Time `gorm:"column:date"` + Count int64 `gorm:"column:count"` + } + err := g.db(ctx).Model(&relation.GroupModel{}).Select("DATE(create_time) AS date, count(1) AS count").Where("create_time >= ? and create_time < ?", start, end).Group("date").Find(&res).Error + if err != nil { + return nil, errs.Wrap(err) + } + v := make(map[string]int64) + for _, r := range res { + v[r.Date.Format("2006-01-02")] = r.Count + } + return v, nil +} diff --git a/pkg/common/db/table/relation/group.go b/pkg/common/db/table/relation/group.go index c011699ae..289ba02cb 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/db/table/relation/group.go @@ -40,4 +40,8 @@ type GroupModelInterface interface { Take(ctx context.Context, groupID string) (group *GroupModel, err error) Search(ctx context.Context, keyword string, pageNumber, showNumber int32) (total uint32, groups []*GroupModel, err error) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) + // 获取群总数 + CountTotal(ctx context.Context, before *time.Time) (count int64, err error) + // 获取范围内群增量 + CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) } diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 86d53e279..369c6d1c7 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -14,7 +14,7 @@ type UserModel struct { Nickname string `gorm:"column:name;size:255"` FaceURL string `gorm:"column:face_url;size:255"` Ex string `gorm:"column:ex;size:1024"` - CreateTime time.Time `gorm:"column:create_time;index:create_time; autoCreateTime"` + CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` AppMangerLevel int32 `gorm:"column:app_manger_level;default:18"` GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt"` } diff --git a/pkg/proto/group/group.proto b/pkg/proto/group/group.proto index 432da16db..9ae7f2c6a 100644 --- a/pkg/proto/group/group.proto +++ b/pkg/proto/group/group.proto @@ -318,6 +318,17 @@ message GetGroupMemberCacheResp { sdkws.GroupMemberFullInfo member = 1; } +message GroupCreateCountReq { + int64 start = 1; + int64 end = 2; +} + +message GroupCreateCountResp { + int64 total = 1; + int64 before = 2; + map count = 3; +} + service group{ //创建群 rpc createGroup(CreateGroupReq) returns(CreateGroupResp); @@ -380,6 +391,8 @@ service group{ rpc GetGroupInfoCache(GetGroupInfoCacheReq) returns (GetGroupInfoCacheResp); rpc GetGroupMemberCache(GetGroupMemberCacheReq) returns (GetGroupMemberCacheResp); + + rpc GroupCreateCount(GroupCreateCountReq) returns (GroupCreateCountResp); }