You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
423 lines
8.5 KiB
Go
423 lines
8.5 KiB
Go
package campaignstat
|
|
|
|
import (
|
|
"joybuywork/internal/consts"
|
|
"joybuywork/internal/repository/dbcheck"
|
|
"joybuywork/internal/repository/finder"
|
|
"joybuywork/internal/repository/model"
|
|
"joybuywork/internal/repository/mtype"
|
|
"joybuywork/internal/utils/logic"
|
|
"joybuywork/internal/utils/verify"
|
|
pb "joybuywork/proto/go_proto/w_campaign_stat"
|
|
"joybuywork/proto/go_proto/workerr"
|
|
)
|
|
|
|
type TopTen struct {
|
|
logic.Logic
|
|
Req *pb.TopTenReq
|
|
Res *pb.TopTenRes
|
|
}
|
|
|
|
func (s *TopTen) Run() error {
|
|
return logic.Run(s)
|
|
}
|
|
|
|
func (s *TopTen) Exec() (err error) {
|
|
cpn, err := s.campaign()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return s.rank(cpn)
|
|
}
|
|
|
|
// 活动数据
|
|
func (s *TopTen) campaign() (cpn *model.FissionCampaign, err error) {
|
|
cpn, err = finder.Campaign(s.Ctx, s.Req.GetCampaignHashId())
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
if cpn == nil || cpn.IsDel == mtype.Yes {
|
|
return nil, workerr.NotFound("campaign not found")
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) rank(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionCampaignTicket
|
|
tickets, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID), m.Open.Eq(mtype.Yes)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
for _, ticket := range tickets {
|
|
switch ticket.Mark {
|
|
case mtype.FissionCampaignTicketFixed:
|
|
err = s._invite(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
case mtype.FissionCampaignTicketCustom:
|
|
err = s._event(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if s.Res.Invite == nil && verify.InArray[int64](cpn.FissionID, consts.IdReferral, consts.IdWinTogether) {
|
|
err = s._invite(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
switch cpn.FissionID {
|
|
case consts.IdGrow, consts.IdKeep:
|
|
err = s._grow(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
case consts.IdChop:
|
|
err = s._chop(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
case consts.IdSignIn:
|
|
err = s._sign(cpn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _invite(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionUserStat
|
|
|
|
list, err := m.WithContext(s.Ctx).
|
|
Where(m.CampaignID.Eq(cpn.ID), m.EffectiveNum.Gt(0)).
|
|
Order(m.EffectiveNum.Desc(), m.DirectNum.Desc(), m.ID).
|
|
Limit(10).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
|
|
var ids = make([]int64, 0, len(list))
|
|
for _, v := range list {
|
|
ids = append(ids, v.UserID)
|
|
}
|
|
|
|
userIdMap, err := s._getUserId(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var rank int32 = 1
|
|
s.Res.Invite = make([]*pb.TopTenRes_Invite, 0, len(list))
|
|
for _, v := range list {
|
|
s.Res.Invite = append(s.Res.Invite, &pb.TopTenRes_Invite{
|
|
Rank: rank,
|
|
UserId: userIdMap[v.UserID],
|
|
EffectNum: v.EffectiveNum,
|
|
InviteNum: v.DirectNum,
|
|
})
|
|
|
|
rank++
|
|
}
|
|
|
|
//裂变最深层级
|
|
furM := s.GetDao().FissionUser.SubTable(cpn.ID)
|
|
var maxDeep struct {
|
|
Deep int64 `json:"deep"`
|
|
}
|
|
err = furM.WithContext(s.Ctx).Select(furM.Deep.Max().As("deep")).Where(furM.CampaignID.Eq(cpn.ID)).Scan(&maxDeep)
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
return s.BE().MysqlError(err)
|
|
}
|
|
|
|
s.Res.MaxLv = maxDeep.Deep
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _event(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionUserStat
|
|
list, err := m.WithContext(s.Ctx).
|
|
Where(m.CampaignID.Eq(cpn.ID), m.TargetNum.Gt(0)).
|
|
Order(m.TargetNum.Desc(), m.ID).
|
|
Limit(10).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
|
|
var ids = make([]int64, 0, len(list))
|
|
for _, v := range list {
|
|
ids = append(ids, v.UserID)
|
|
}
|
|
|
|
userIdMap, err := s._getUserId(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
userCondMap, err := s._getUserConds(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var rank int32 = 1
|
|
s.Res.Event = make([]*pb.TopTenRes_Event, 0, len(list))
|
|
for _, v := range list {
|
|
s.Res.Event = append(s.Res.Event, &pb.TopTenRes_Event{
|
|
Rank: rank,
|
|
UserId: userIdMap[v.UserID],
|
|
Num: v.TargetNum,
|
|
Conds: userCondMap[v.UserID],
|
|
})
|
|
|
|
rank++
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _getUserId(campaignId int64, ids []int64) (data map[int64]string, err error) {
|
|
|
|
m := s.GetDao().FissionUser.SubTable(campaignId)
|
|
|
|
userList, err := m.WithContext(s.Ctx).Where(m.ID.In(ids...)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
data = make(map[int64]string, len(userList))
|
|
for _, v := range userList {
|
|
data[v.ID] = v.UserMark
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _getUserConds(cpnId int64, ids []int64) (data map[int64][]*pb.TopTenRes_Cond, err error) {
|
|
condM := s.GetDao().FissionCampaignCond
|
|
conds, err := condM.WithContext(s.Ctx).Where(condM.CampaignID.Eq(cpnId)).
|
|
Where(
|
|
condM.WithContext(s.Ctx).
|
|
Or(condM.IsDel.Eq(mtype.No)).
|
|
Or(condM.IsDel.Eq(mtype.Yes), condM.DelUse.Eq(mtype.Yes)),
|
|
).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
m := s.GetDao().FissionUserCond
|
|
list, err := m.WithContext(s.Ctx).Where(m.UserID.In(ids...)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
var userCondMap = make(map[int64]map[int64]int64)
|
|
for _, v := range list {
|
|
|
|
if _, ok := userCondMap[v.UserID]; !ok {
|
|
userCondMap[v.UserID] = map[int64]int64{
|
|
v.CondID: v.Num,
|
|
}
|
|
} else {
|
|
userCondMap[v.UserID][v.CondID] = v.Num
|
|
}
|
|
|
|
}
|
|
|
|
data = make(map[int64][]*pb.TopTenRes_Cond, len(ids))
|
|
for _, userId := range ids {
|
|
|
|
for _, cond := range conds {
|
|
one := &pb.TopTenRes_Cond{
|
|
Desc: cond.Desc,
|
|
Num: 0,
|
|
}
|
|
|
|
if uc, ok := userCondMap[userId]; ok {
|
|
one.Num = uc[cond.ID]
|
|
}
|
|
|
|
data[userId] = append(data[userId], one)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _grow(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionUserStat
|
|
|
|
list, err := m.WithContext(s.Ctx).
|
|
Where(m.CampaignID.Eq(cpn.ID), m.GrowRewardNum.Gt(0)).
|
|
Order(m.GrowRewardNum.Desc(), m.GrowNum.Desc(), m.ID).
|
|
Limit(10).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
|
|
var ids = make([]int64, 0, len(list))
|
|
for _, v := range list {
|
|
ids = append(ids, v.UserID)
|
|
}
|
|
|
|
userIdMap, err := s._getUserId(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var rank int32 = 1
|
|
for _, v := range list {
|
|
s.Res.Grow = append(s.Res.Grow, &pb.TopTenRes_Grow{
|
|
Rank: rank,
|
|
UserId: userIdMap[v.UserID],
|
|
GrowNum: v.GrowNum,
|
|
GrowRewardNum: v.GrowRewardNum,
|
|
})
|
|
rank++
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
type chopHelp struct {
|
|
UserId int64 `json:"user_id"`
|
|
Mark string `json:"mark"`
|
|
Num int64 `json:"num"`
|
|
}
|
|
|
|
func (s *TopTen) _chop(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionUserStat
|
|
|
|
list, err := m.WithContext(s.Ctx).
|
|
Where(m.CampaignID.Eq(cpn.ID), m.HelpNum.Gt(0)).
|
|
Order(m.HelpNum.Desc(), m.ID).
|
|
Limit(10).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
|
|
var ids = make([]int64, 0, len(list))
|
|
for _, v := range list {
|
|
ids = append(ids, v.UserID)
|
|
}
|
|
|
|
var helps []*chopHelp
|
|
helpM := s.GetDao().FissionChopHelp
|
|
err = helpM.WithContext(s.Ctx).
|
|
Select(helpM.ID.Count().As("num"), helpM.UserID, helpM.Mark).
|
|
Where(helpM.CampaignID.Eq(cpn.ID), helpM.UserID.In(ids...)).
|
|
Group(helpM.UserID, helpM.Mark).
|
|
Scan(&helps)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
var helpMap = make(map[int64][]*chopHelp, len(list))
|
|
for _, v := range helps {
|
|
helpMap[v.UserId] = append(helpMap[v.UserId], v)
|
|
}
|
|
|
|
userIdMap, err := s._getUserId(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var rank int32 = 1
|
|
for _, v := range list {
|
|
one := &pb.TopTenRes_Help{
|
|
Rank: rank,
|
|
UserId: userIdMap[v.UserID],
|
|
Num: v.HelpNum,
|
|
Detail: make([]*pb.TopTenRes_Detail, 0, len(helpMap[v.UserID])),
|
|
}
|
|
|
|
for _, help := range helpMap[v.UserID] {
|
|
|
|
one.Detail = append(one.Detail, &pb.TopTenRes_Detail{
|
|
Title: help.Mark,
|
|
Num: help.Num,
|
|
})
|
|
}
|
|
|
|
s.Res.Help = append(s.Res.Help, one)
|
|
rank++
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *TopTen) _sign(cpn *model.FissionCampaign) (err error) {
|
|
m := s.GetDao().FissionUserStat
|
|
|
|
list, err := m.WithContext(s.Ctx).
|
|
Where(m.CampaignID.Eq(cpn.ID), m.SignNum.Gt(0)).
|
|
Order(m.SignNum.Desc(), m.SignRewardNum.Desc(), m.ID).
|
|
Limit(10).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
|
|
var ids = make([]int64, 0, len(list))
|
|
for _, v := range list {
|
|
ids = append(ids, v.UserID)
|
|
}
|
|
|
|
userIdMap, err := s._getUserId(cpn.ID, ids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var rank int32 = 1
|
|
for _, v := range list {
|
|
s.Res.Sign = append(s.Res.Sign, &pb.TopTenRes_Sign{
|
|
Rank: rank,
|
|
UserId: userIdMap[v.UserID],
|
|
SignDay: v.SignNum,
|
|
SignRewardNum: v.SignRewardNum,
|
|
})
|
|
rank++
|
|
}
|
|
|
|
return
|
|
}
|