diff --git a/cv/user_cv/user.go b/cv/user_cv/user.go index 6e09de77dc321ee9a5bb0d8b90751cb0ac04299f..82e053d1963ad14ed7b1d33f16bc7cfdb50e3a26 100644 --- a/cv/user_cv/user.go +++ b/cv/user_cv/user.go @@ -29,6 +29,7 @@ type UserTiny struct { Country string `json:"country"` CountryIcon string `json:"countryIcon"` IsPrettyCode bool `json:"isPrettyCode"` // 是否靓号 + Birthday uint64 `json:"birthday"` } func UserToTiny(user user_m.User) *UserTiny { @@ -42,6 +43,7 @@ func UserToTiny(user user_m.User) *UserTiny { Country: user.Country, CountryIcon: user.CountryIcon, IsPrettyCode: user.IsPrettyCode(), + Birthday: user.Birthday, } } @@ -82,7 +84,8 @@ type CvUserBase struct { //邀请码 Code *string `json:"code"` IsPrettyCode bool `json:"isPrettyCode"` // 是否靓号 - IsLogout bool `json:"isLogout"` //是否注销 + IsNew bool `json:"isNew"` // 是否新用户 + IsLogout bool `json:"isLogout"` // 是否注销 //生日,如果是其它人用户信息,年龄则按照是否展示显示,如果是本人,年龄则按照是否存在展示 Birthday *uint64 `json:"birthday"` //是否展示年龄, 是本人才有数据,看其他用户均为nil @@ -199,6 +202,7 @@ func GetUserBases(userIds []mysql.ID, myUserId mysql.ID) ([]*CvUserBase, error) CountryIcon: StrNil(user.CountryIcon), Code: StrToString(&user.Code), IsPrettyCode: user.IsPrettyCode(), + IsNew: user.IsNew(), IsVip: vips[user.ID] != nil, IsOfficialStaff: superManagerMap[user.ID], Medals: IfLogoutMedals(IfLogout(user.LogoutTime), []uint32{}, medals[user.ID]), @@ -299,6 +303,7 @@ func GetUserBasesForCp(userIds []mysql.ID) ([]*CvUserBase, error) { CountryIcon: StrNil(user.CountryIcon), Code: StrToString(&user.Code), IsPrettyCode: user.IsPrettyCode(), + IsNew: user.IsNew(), IsVip: vips[user.ID] != nil, Noble: noble_cv.CvNoble{ Level: nobles[user.ID].Level, diff --git a/domain/model/group_m/groupInfo.go b/domain/model/group_m/groupInfo.go index cf0c798f65bc05fc9f09b0dde281b63e293f265e..13441e62eb47ffd5265415b563762cc26a14b8c6 100644 --- a/domain/model/group_m/groupInfo.go +++ b/domain/model/group_m/groupInfo.go @@ -76,6 +76,18 @@ func ToTxGroupId(model *domain.Model, imGroupId string) (string, error) { return gi.TxGroupId, nil } +func ToTxGroupIdMap(model *domain.Model, imGroupIds []string) (map[string]string, error) { + var res = make(map[string]string) + var rows []GroupInfo + if err := model.DB().Model(GroupInfo{}).Where("im_group_id in ?", imGroupIds).Find(&rows).Error; err != nil { + return res, err + } + for _, v := range rows { + res[v.ImGroupId] = v.TxGroupId + } + return res, nil +} + func ToImGroupId(model *domain.Model, txGroupId string) (string, error) { if len(txGroupId) <= 0 { return "", nil diff --git a/domain/model/recommend_m/gift.go b/domain/model/recommend_m/gift.go new file mode 100644 index 0000000000000000000000000000000000000000..0ca4f3f91e99fde119f11188a2bf1eeb3c9f5566 --- /dev/null +++ b/domain/model/recommend_m/gift.go @@ -0,0 +1,34 @@ +package recommend_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "github.com/bluele/gcache" + "time" +) + +// 推荐用户送礼 +type recommendUserGift struct { + SendUserId mysql.ID + SendUserDiamond mysql.Num +} + +var recommendUserGiftKey = "recommendUserGiftKey" +var recommendUserGiftCache = gcache.New(1).LRU().Build() + +// 推荐最近送礼的50人,最近12小时赠送礼物大于100k的用户 +// 先lru cache,后db +// ttl: 5min +func GetPastTop50SendGiftUsers(model *domain.Model) []recommendUserGift { + if data, err := recommendUserGiftCache.Get(recommendUserGiftKey); err == nil { + return data.([]recommendUserGift) + } + var res []recommendUserGift + if err := model.DB().Table("gift_operate").Select("send_user_id,SUM(send_user_diamond) send_user_diamond"). + Where("created_time >= ?", time.Now().Add(-time.Hour*12)).Group("send_user_id"). + Having("send_user_diamond > 100000").Order("send_user_diamond DESC").Limit(34).Find(&res).Error; err != nil { + model.Log.Errorf("GetPastTop50SendGiftUsers fail:%v", err) + } + recommendUserGiftCache.SetWithExpire(recommendUserGiftKey, res, time.Minute*5) + return res +} diff --git a/domain/model/user_m/user.go b/domain/model/user_m/user.go index a9863ca6b8fb8f8a37d1fb5c88534eb9ac64b101..afdf3179554aff45671b7cae63df6b8b2914dd86 100755 --- a/domain/model/user_m/user.go +++ b/domain/model/user_m/user.go @@ -52,6 +52,11 @@ func (u User) IsPrettyCode() bool { return u.Code != u.OriginCode } +// 七天内注册 +func (u User) IsNew() bool { + return time.Now().Sub(u.CreatedTime).Hours() < 24*7 +} + //获取用户 func GetUser(model *domain.Model, id mysql.ID) (*User, error) { var user User diff --git a/domain/service/user_s/user.go b/domain/service/user_s/user.go index de797c426c033239e7d75d418e94481f67b4c48e..fd67094d0a8f575b0af1f98a7677347600ea7ffe 100644 --- a/domain/service/user_s/user.go +++ b/domain/service/user_s/user.go @@ -285,6 +285,7 @@ func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, CountryIcon: StrNil(user.CountryIcon), Code: StrToString(&user.Code), IsPrettyCode: user.IsPrettyCode(), + IsNew: user.IsNew(), IsVip: isVip, IsOfficialStaff: isOfficialStaff, VipExpireTime: vipExpireTime, diff --git a/route/recommend_r/gift.go b/route/recommend_r/gift.go new file mode 100644 index 0000000000000000000000000000000000000000..0258156b6a331fea9de9d831692a60ee1fb55fbe --- /dev/null +++ b/route/recommend_r/gift.go @@ -0,0 +1,62 @@ +package recommend_r + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/mycontext" + "git.hilo.cn/hilo-common/resource/mysql" + "github.com/gin-gonic/gin" + "hilo-user/cv/user_cv" + "hilo-user/domain/model/group_m" + "hilo-user/domain/model/recommend_m" + "hilo-user/domain/model/user_m" + "hilo-user/resp" +) + +type RecommendUser struct { + User *user_cv.UserTiny `json:"user"` + CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”) +} + +// @Tags 用户推荐 +// @Summary 推荐最近送礼的50人,最近12小时赠送礼物大于100k的用户 +// @Param token header string true "token" +// @Success 200 {object} []RecommendUser +// @Router /v1/recommend/user/gift [get] +func UserRecommendGift(c *gin.Context) (*mycontext.MyContext, error) { + myContext := mycontext.CreateMyContext(c.Keys) + model := domain.CreateModelContext(myContext) + // 获取推荐 + recommendUser := recommend_m.GetPastTop50SendGiftUsers(model) + var response = make([]RecommendUser, 0) + if len(recommendUser) <= 0 { + resp.ResponseOk(c, response) + return myContext, nil + } + var userIds []mysql.ID + for _, v := range recommendUser { + userIds = append(userIds, v.SendUserId) + } + users, err := user_m.GetUserMapByIds(model, userIds) + if err != nil { + return myContext, err + } + rooms, err := group_m.RoomLivingUserIdFilter(model, userIds) + if err != nil { + return nil, err + } else if len(rooms) > 0 { + // to txGroupIds + var imGroupIds []string + for _, imGroupId := range rooms { + imGroupIds = append(imGroupIds, imGroupId) + } + txGroupIdsMap, _ := group_m.ToTxGroupIdMap(model, imGroupIds) + for uid, room := range rooms { + rooms[uid] = txGroupIdsMap[room] + } + } + for _, v := range recommendUser { + response = append(response, RecommendUser{user_cv.UserToTiny(users[v.SendUserId]), rooms[v.SendUserId]}) + } + resp.ResponseOk(c, response) + return myContext, nil +} diff --git a/route/router.go b/route/router.go old mode 100755 new mode 100644 index fb2d73520190b9401a6509e7563c8354b0e2456a..81cfcb81908701fe13f28b7e193e0d4114387659 --- a/route/router.go +++ b/route/router.go @@ -13,6 +13,7 @@ import ( "hilo-user/resp" "hilo-user/route/cp_r" "hilo-user/route/invite_r" + "hilo-user/route/recommend_r" "hilo-user/route/user_r" ) @@ -53,6 +54,11 @@ func InitRouter() *gin.Engine { //cp.GET("/relation/detail", wrapper(cp_r.CpDetailPage)) cp.GET("/im/check", wrapper(cp_r.CheckCpImExpire)) } + recommend := v1.Group("recommend") + { + recommend.GET("/user/gift", wrapper(recommend_r.UserRecommendGift)) + } + userV2 := v2.Group("/user") { userV2.POST("/invite/apply", wrapper(invite_r.InviteApply))