diff --git a/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index 7c702a57..c8c65540 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -1579,6 +1579,42 @@ func (m *Mongo) GetMomentListByIds(ctx *gin.Context, momentIds []int64) ([]*dbst return list, err } +func (m *Mongo) GetMomentCountByTimeSpanGroupByMid(ctx *gin.Context, st, et int64) ([]*dbstruct.MomentStatInfo, error) { + + results := make([]*dbstruct.MomentStatInfo, 0) + + col := m.getColMoment() + matchClause := bson.D{{ + Key: "$match", Value: bson.M{ + "$and": []bson.M{ + {"ct": bson.M{"$gte": st}}, + {"ct": bson.M{"$lte": et}}, + }, + "del_flag": 0, + }, + }} + + groupClause := bson.D{ + {Key: "$group", Value: bson.D{ + {Key: "_id", Value: "$mid"}, + {Key: "count", Value: bson.M{ + "$sum": 1, + }}, + }, + }, + } + + pipeline := qmgo.Pipeline{matchClause, groupClause} + + err := col.Aggregate(ctx, pipeline).All(&results) + if err != nil { + logger.Error("err : %v", err) + return make([]*dbstruct.MomentStatInfo, 0), err + } + + return results, err +} + // 查私有动态接口 func (m *Mongo) GetMomentListByMid(ctx *gin.Context, req *momentproto.OpListByMidReq) ([]*dbstruct.Moment, error) { list := make([]*dbstruct.Moment, 0) @@ -4326,6 +4362,42 @@ func (m *Mongo) HeadZoneMomentByIds(ctx *gin.Context, ids []int64, opType int64) return err } +func (m *Mongo) GetZoneMomentCountByTimeSpanGroupByMid(ctx *gin.Context, st, et int64) ([]*dbstruct.ZoneMomentStatInfo, error) { + + results := make([]*dbstruct.ZoneMomentStatInfo, 0) + + col := m.getColZoneMoment() + matchClause := bson.D{{ + Key: "$match", Value: bson.M{ + "$and": []bson.M{ + {"ct": bson.M{"$gte": st}}, + {"ct": bson.M{"$lte": et}}, + }, + "del_flag": 0, + }, + }} + + groupClause := bson.D{ + {Key: "$group", Value: bson.D{ + {Key: "_id", Value: "$mid"}, + {Key: "count", Value: bson.M{ + "$sum": 1, + }}, + }, + }, + } + + pipeline := qmgo.Pipeline{matchClause, groupClause} + + err := col.Aggregate(ctx, pipeline).All(&results) + if err != nil { + logger.Error("err : %v", err) + return make([]*dbstruct.ZoneMomentStatInfo, 0), err + } + + return results, err +} + // 点赞相关 func (m *Mongo) CreateZoneMomentThumbsUp(ctx *gin.Context, zonemomentthumbsup *dbstruct.ZoneMomentThumbsUp) error { col := m.getColZoneMomentThumbsUp() diff --git a/app/mix/dao/mysql.go b/app/mix/dao/mysql.go index fc2d1f26..60355773 100644 --- a/app/mix/dao/mysql.go +++ b/app/mix/dao/mysql.go @@ -1225,3 +1225,22 @@ func (m *Mysql) GetTotalFinishIncome(ctx *gin.Context, tx *sqlx.Tx, mid int64, o } return tmp.Dias, nil } + +// 根据时间段统计各主播消费总额 +func (m *Mysql) GetIncomeByTimeSpanGroupByMid(ctx *gin.Context, tx *sqlx.Tx, st, et int64) ([]*dbstruct.StreamerProfit, error) { + var sql strings.Builder + var err error + sql.WriteString(fmt.Sprintf("select uid as mid, sum(pay_amount) as amount from %s", TableOrder)) + sql.WriteString(fmt.Sprintf(" where ct >=%d and ct<=%d and product_id in(?,?,?,?,?,?) and order_status = 1 group by uid", st, et)) + list := make([]*dbstruct.StreamerProfit, 0) + if tx != nil { + err = tx.SelectContext(ctx, &list, sql.String(), dbstruct.ProductIdH5ZoneMoment, dbstruct.ProductIdH5ZoneAdmission, dbstruct.ProductIdH5ZoneIronfanship, dbstruct.ProductIdH5ZoneSuperfanship, dbstruct.ProductIdContactWechat, dbstruct.ProductIdH5ContactWechat) + } else { + db := m.getDBVas() + err = db.SelectContext(ctx, &list, sql.String(), dbstruct.ProductIdH5ZoneMoment, dbstruct.ProductIdH5ZoneAdmission, dbstruct.ProductIdH5ZoneIronfanship, dbstruct.ProductIdH5ZoneSuperfanship, dbstruct.ProductIdContactWechat, dbstruct.ProductIdH5ContactWechat) + } + if err != nil { + return make([]*dbstruct.StreamerProfit, 0), err + } + return list, nil +} diff --git a/app/mix/dao/mysql_zone.go b/app/mix/dao/mysql_zone.go index 46c73318..5b6bda1b 100644 --- a/app/mix/dao/mysql_zone.go +++ b/app/mix/dao/mysql_zone.go @@ -556,3 +556,21 @@ func (m *Mysql) GetLastHourZoneRefund(ctx *gin.Context, tx *sqlx.Tx, st, et int6 } return } + +// 获取时段内空间进入人数 +func (m *Mysql) GetLastHourZoneAdmissionInfo(ctx *gin.Context, tx *sqlx.Tx, st, et int64) (list []*dbstruct.ZoneAdmissionInfo, err error) { + var sql strings.Builder + sql.WriteString(fmt.Sprintf("select uid as mid, count(1) as num from %s", TableOrder)) + sql.WriteString(fmt.Sprintf(" where ct >=%d and ct<=%d and product_id in(?,?) and order_status = 1 group by uid", st, et)) + list = make([]*dbstruct.ZoneAdmissionInfo, 0) + if tx != nil { + err = tx.SelectContext(ctx, &list, sql.String(), dbstruct.ProductIdH5ZoneAdmission, dbstruct.ProductIdH5ZoneSuperfanship) + } else { + db := m.getDBVas() + err = db.SelectContext(ctx, &list, sql.String(), dbstruct.ProductIdH5ZoneAdmission, dbstruct.ProductIdH5ZoneSuperfanship) + } + if err != nil { + return + } + return +} diff --git a/app/mix/service/streamer_recomm_service.go b/app/mix/service/streamer_recomm_service.go index 9c78c18b..f02296e1 100644 --- a/app/mix/service/streamer_recomm_service.go +++ b/app/mix/service/streamer_recomm_service.go @@ -1,6 +1,31 @@ package service +import ( + "service/dbstruct" + "service/library/logger" + + "github.com/gin-gonic/gin" +) + +type StreamerScore struct { + Mid int64 + ZoneMomentCountInThreeDays int64 + ZoneMomentCountInAMonth int64 + IncomeInAWeek int64 + NewZoneMemberCountInThreeDays int64 + NewZoneMemberCountInAMonth int64 + MomentCountInThreeDays int64 + RefundRate float64 + Score int64 +} + type StreamerRecommService struct { + RecvZoneMomentStatInfo func(ctx *gin.Context, st, et int64) ([]*dbstruct.ZoneMomentStatInfo, error) + RecvMomentStatInfo func(ctx *gin.Context, st, et int64) ([]*dbstruct.MomentStatInfo, error) + RecvStreamerProfit func(ctx *gin.Context, st, et int64) ([]*dbstruct.StreamerProfit, error) + RecvZoneAdmissionInfo func(ctx *gin.Context, st, et int64) ([]*dbstruct.ZoneAdmissionInfo, error) + + scores map[int64]*StreamerScore } // 启动跑批 @@ -9,21 +34,189 @@ func (s *StreamerRecommService) RunBatch() { } // 取数 -func (s *StreamerRecommService) RecvMsg() { +func (s *StreamerRecommService) recvMsg(ctx *gin.Context, nt int64) (err error) { + beforeThreeDays := nt - int64(259200) + beforeAWeek := nt - int64(604800) + beforeAMonth := nt - int64(2592000) + + // 三日内空间动态总数 + err = s.recvZoneMomentStatInfoInThreeDays(ctx, beforeThreeDays, nt) + if err != nil { + logger.Error("recvZoneMomentStatInfoInThreeDays fail, err: %v", err) + return + } + + // 三十日内空间动态总数 + err = s.recvZoneMomentStatInfoInAMonth(ctx, beforeAMonth, nt) + if err != nil { + logger.Error("recvZoneMomentStatInfoInAMonth fail, err: %v", err) + return + } + + // 七日内消费金额 + err = s.recvStreamerProfit(ctx, beforeAWeek, nt) + if err != nil { + logger.Error("recvStreamerProfit fail, err: %v", err) + return + } + + // 三日内新增成员数 + err = s.recvZoneAdmissionInfoInThreeDays(ctx, beforeThreeDays, nt) + if err != nil { + logger.Error("recvZoneAdmissionInfoInThreeDays fail, err: %v", err) + return + } + + // 三十日内新增成员数 + err = s.recvZoneAdmissionInfoInAMonth(ctx, beforeAMonth, nt) + if err != nil { + logger.Error("recvZoneAdmissionInfoInAMonth fail, err: %v", err) + return + } + + // 三日内新增广场动态总数 + err = s.recvMomentStatInfoInThreeDays(ctx, beforeThreeDays, nt) + if err != nil { + logger.Error("recvMomentStatInfoInThreeDays fail, err: %v", err) + return + } + + return } // 运算 -func (s *ScriptsService) Score() { +func (s *ScriptsService) score() { } // 转存 -func (s *ScriptsService) Save() { +func (s *ScriptsService) save() { } // 推送 -func (s *ScriptsService) Push() { +func (s *ScriptsService) push() { } + +// 取数 +func (s *StreamerRecommService) recvZoneMomentStatInfoInThreeDays(ctx *gin.Context, st, et int64) (err error) { + + zoneMomentStatInfoList, err := s.RecvZoneMomentStatInfo(ctx, st, et) + if err != nil { + logger.Error("RecvZoneMomentStatInfo in three days fail, err: %v", err) + return + } + + for _, zmsi := range zoneMomentStatInfoList { + _, ok := s.scores[zmsi.GetMid()] + if !ok { + s.scores[zmsi.GetMid()] = &StreamerScore{ + Mid: zmsi.GetMid(), + } + } + s.scores[zmsi.GetMid()].ZoneMomentCountInThreeDays = zmsi.GetCount() + } + return +} + +func (s *StreamerRecommService) recvZoneMomentStatInfoInAMonth(ctx *gin.Context, st, et int64) (err error) { + + zoneMomentStatInfoList, err := s.RecvZoneMomentStatInfo(ctx, st, et) + if err != nil { + logger.Error("RecvZoneMomentStatInfo in three days fail, err: %v", err) + return + } + + for _, zmsi := range zoneMomentStatInfoList { + _, ok := s.scores[zmsi.GetMid()] + if !ok { + s.scores[zmsi.GetMid()] = &StreamerScore{ + Mid: zmsi.GetMid(), + } + } + s.scores[zmsi.GetMid()].ZoneMomentCountInAMonth = zmsi.GetCount() + } + return +} + +func (s *StreamerRecommService) recvStreamerProfit(ctx *gin.Context, st, et int64) (err error) { + + streamerProfitList, err := s.RecvStreamerProfit(ctx, st, et) + if err != nil { + logger.Error("RecvStreamerProfit fail, err: %v", err) + return + } + + for _, sp := range streamerProfitList { + _, ok := s.scores[sp.GetMid()] + if !ok { + s.scores[sp.GetMid()] = &StreamerScore{ + Mid: sp.GetMid(), + } + } + s.scores[sp.GetMid()].IncomeInAWeek = sp.GetAmount() + } + return +} + +func (s *StreamerRecommService) recvZoneAdmissionInfoInThreeDays(ctx *gin.Context, st, et int64) (err error) { + + zoneAdmissionInfoList, err := s.RecvZoneAdmissionInfo(ctx, st, et) + if err != nil { + logger.Error("RecvZoneAdmissionInfo in three days fail, err: %v", err) + return + } + + for _, zai := range zoneAdmissionInfoList { + _, ok := s.scores[zai.GetMid()] + if !ok { + s.scores[zai.GetMid()] = &StreamerScore{ + Mid: zai.GetMid(), + } + } + s.scores[zai.GetMid()].NewZoneMemberCountInThreeDays = zai.GetNum() + } + return +} + +func (s *StreamerRecommService) recvZoneAdmissionInfoInAMonth(ctx *gin.Context, st, et int64) (err error) { + + zoneAdmissionInfoList, err := s.RecvZoneAdmissionInfo(ctx, st, et) + if err != nil { + logger.Error("RecvZoneAdmissionInfo in three days fail, err: %v", err) + return + } + + for _, zai := range zoneAdmissionInfoList { + _, ok := s.scores[zai.GetMid()] + if !ok { + s.scores[zai.GetMid()] = &StreamerScore{ + Mid: zai.GetMid(), + } + } + s.scores[zai.GetMid()].NewZoneMemberCountInAMonth = zai.GetNum() + } + return +} + +func (s *StreamerRecommService) recvMomentStatInfoInThreeDays(ctx *gin.Context, st, et int64) (err error) { + + momentStatInfoList, err := s.RecvMomentStatInfo(ctx, st, et) + if err != nil { + logger.Error("RecvMomentStatInfo in three days fail, err: %v", err) + return + } + + for _, msi := range momentStatInfoList { + _, ok := s.scores[msi.GetMid()] + if !ok { + s.scores[msi.GetMid()] = &StreamerScore{ + Mid: msi.GetMid(), + } + } + s.scores[msi.GetMid()].MomentCountInThreeDays = msi.GetCount() + } + return +} diff --git a/dbstruct/moment.go b/dbstruct/moment.go index 5a04b086..76a9773f 100644 --- a/dbstruct/moment.go +++ b/dbstruct/moment.go @@ -38,3 +38,22 @@ func (p *Moment) GetId() int64 { } return 0 } + +type MomentStatInfo struct { + Mid *int64 `json:"id" bson:"_id"` // mid + Count *int64 `json:"count" bson:"count"` // count +} + +func (p *MomentStatInfo) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} + +func (p *MomentStatInfo) GetCount() int64 { + if p != nil && p.Count != nil { + return *p.Count + } + return 0 +} diff --git a/dbstruct/vas_mysql.go b/dbstruct/vas_mysql.go index 3396d907..9c8877a2 100644 --- a/dbstruct/vas_mysql.go +++ b/dbstruct/vas_mysql.go @@ -1423,3 +1423,42 @@ func (p *ZoneProfit) GetNum() int64 { } return 0 } + +// 时段收入信息 +type StreamerProfit struct { + Mid *int64 `json:"mid" db:"mid"` // 用户id + Amount *int64 `json:"amount" db:"amount"` // 支付总金额 +} + +func (p *StreamerProfit) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} +func (p *StreamerProfit) GetAmount() int64 { + if p != nil && p.Amount != nil { + return *p.Amount + } + return 0 +} + +// 时段空间入场信息 +type ZoneAdmissionInfo struct { + Mid *int64 `json:"mid" db:"mid"` // 用户id + Num *int64 `json:"num" db:"num"` // 支付总人数 +} + +func (p *ZoneAdmissionInfo) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} + +func (p *ZoneAdmissionInfo) GetNum() int64 { + if p != nil && p.Num != nil { + return *p.Num + } + return 0 +} diff --git a/dbstruct/zonemoment.go b/dbstruct/zonemoment.go index 428b172a..ce9d7da6 100644 --- a/dbstruct/zonemoment.go +++ b/dbstruct/zonemoment.go @@ -117,3 +117,22 @@ func (p *ZoneMoment) GetPaidText() string { } return "" } + +type ZoneMomentStatInfo struct { + Mid *int64 `json:"id" bson:"_id"` // mid + Count *int64 `json:"count" bson:"count"` // count +} + +func (p *ZoneMomentStatInfo) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} + +func (p *ZoneMomentStatInfo) GetCount() int64 { + if p != nil && p.Count != nil { + return *p.Count + } + return 0 +}