package followser import ( "91porn-server/app/appg" "91porn-server/app/service/vidhelpser" "91porn-server/common/log" "91porn-server/common/services/follow" "91porn-server/common/stderr" topser "91porn-server/common/top" "91porn-server/common/top/weektop" "91porn-server/models/commod" "91porn-server/models/v/followmod" "91porn-server/models/v/usermod" "91porn-server/models/v/vidmod" "errors" "fmt" goredis "github.com/go-redis/redis" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" "strconv" "time" ) func encodeUserBase(uids []uint64, uInfo []*usermod.BaseInfoVip, mModel map[uint64]followmod.FollowModel, mFollow map[uint64]bool) []*followmod.BaseInfo { var infos []*followmod.BaseInfo mInfo := make(map[uint64]usermod.BaseInfoVip) for _, u := range uInfo { if u == nil { continue } mInfo[u.UID] = *u } for _, u := range uids { bi := followmod.BaseInfo{ UID: u, Name: mInfo[u].Name, Gender: mInfo[u].Gender, Portrait: mInfo[u].Portrait, HasLocked: mInfo[u].HasLocked, HasBanned: mInfo[u].HasBanned, VipLevel: mInfo[u].VipLevel, IsVip: mInfo[u].IsVip, HasFollow: true, Via: mModel[u].Via, Fans: mInfo[u].Fans, Summary: mInfo[u].Summary, CreatedAt: mModel[u].CreatedAt, SuperUser: mInfo[u].SuperUser, Awards: mInfo[u].Awards, TotalWorks: mInfo[u].TotalWorks, } infos = append(infos, &bi) } return infos } // GetHisFollowList 获取他关注列表 func GetHisFollowList(uid, oid uint64, page int, size int) (code stderr.Code, data interface{}) { uids, mModel, hasNext, err := followmod.GetFollowList(oid, page, size, false) if err != nil { return stderr.ErrDbQueryError, nil } uInfos, err := usermod.GetUsersBaseInfoWithVip(uids) if err != nil { return stderr.ErrDbQueryError, nil } mFollow, err := followmod.IsFollowedByUsers(uid, uids) if err != nil { return stderr.ErrDbQueryError, nil } datas := encodeUserBase(uids, uInfos, mModel, mFollow) data = followmod.ListResp{List: datas, HasNext: hasNext} return stderr.Success, data } // GetFollowList 获取关注列表 func GetFollowList(uid uint64, page int, size int, isShort bool) (code stderr.Code, data interface{}) { uids, mModel, hasNext, err := followmod.GetFollowList(uid, page, size, isShort) if err != nil { return stderr.ErrDbQueryError, nil } uInfos, err := usermod.GetUsersBaseInfoWithVip(uids) if err != nil { return stderr.ErrDbQueryError, nil } mFollow, err := followmod.IsFollowedByUsers(uid, uids) if err != nil { return stderr.ErrDbQueryError, nil } datas := encodeUserBase(uids, uInfos, mModel, mFollow) data = followmod.ListResp{List: datas, HasNext: hasNext} return stderr.Success, data } // GetHisFansList 获取他的粉丝列表 func GetHisFansList(uid, oid uint64, page int, size int) (code stderr.Code, data interface{}) { uids, mModel, hasNext, err := followmod.GetFansList(oid, page, size) if err != nil { return stderr.ErrDbQueryError, nil } uInfos, err := usermod.GetUsersBaseInfoWithVip(uids) if err != nil { return stderr.ErrDbQueryError, nil } mFollow, err := followmod.IsFollowUsers(uid, uids) if err != nil { return stderr.ErrDbQueryError, nil } datas := encodeUserBase(uids, uInfos, mModel, mFollow) data = followmod.ListResp{List: datas, HasNext: hasNext} return stderr.Success, data } // GetFansList 获取粉丝列表 func GetFansList(uid uint64, page int, size int) (code stderr.Code, data interface{}) { uids, mModel, hasNext, err := followmod.GetFansList(uid, page, size) if err != nil { return stderr.ErrDbQueryError, nil } uInfos, err := usermod.GetUsersBaseInfoWithVip(uids) if err != nil { return stderr.ErrDbQueryError, nil } mFollow, err := followmod.IsFollowUsers(uid, uids) if err != nil { return stderr.ErrDbQueryError, nil } datas := encodeUserBase(uids, uInfos, mModel, mFollow) data = followmod.ListResp{List: datas, HasNext: hasNext} return stderr.Success, data } // GetDynamicsList 获取关注用户动态 func GetDynamicsList(uid uint64, req followmod.AppDynamicsListReq) (data followmod.DynamicsResp, code stderr.Code) { // 处理用户关注消息状态 _ = follow.CancelTip(uid) var infos []*vidmod.VideoModel // 获取官方帖子 //vid, err := vidmod.FindOneByUid(bson.M{"publisherID": 100000, "newsType": "COVER", "status": 1}) //if err != nil { // return stderr.ErrDbQueryError, nil //} // //if vid != nil && !vid.ID.IsZero() { // infos = append(infos, vid) //} uids, err := followmod.GetTotalFollowList(uid) if err != nil { return data, stderr.ErrDbQueryError } if len(uids) == 0 { //if len(infos) > 0 { // list := vidhelpser.EncodeVideoInfo(uid, infos) // data = followmod.DynamicsResp{VInfos: list, List: list, TotalPages: 1, HasNext: false} //} else { //data = followmod.DynamicsResp{VInfos: nil, List: nil, HasNext: false, TotalPages: 0} //} return data, stderr.Success } filter := bson.M{ "publisherID": bson.M{"$in": uids}, "newsType": vidmod.SHORT, // 默认短视频 "status": vidmod.CheckPass, } if req.NewsType != "" { filter["newsType"] = req.NewsType } sort := bson.D{{Key: "reviewAt", Value: -1}} opt := options.Find().SetSkip(req.Skip64()).SetLimit(req.Limit64()).SetSort(sort) videos, hasNext, err := vidmod.FindList(filter, opt) if err != nil { return data, stderr.ErrDbQueryError } if len(videos) == 0 { //if len(infos) > 0 { // list := vidhelpser.EncodeVideoInfo(uid, infos) // data = followmod.DynamicsResp{VInfos: list, List: list, TotalPages: 1, HasNext: false} //} else { //data = followmod.DynamicsResp{VInfos: nil, List: nil, HasNext: false, TotalPages: 0} //} return data, stderr.Success } infos = append(infos, videos...) list := vidhelpser.EncodeVideoInfo(uid, infos) data = followmod.DynamicsResp{VInfos: list, List: list, TotalPages: 0, HasNext: hasNext} return data, stderr.Success } // 短视频-获取关注用户和作品,若无关注,则获取推荐用户及作品 type ( GetFollowUpUsersWithShortReq struct { commod.Page ShowType int `json:"showType" form:"showType"` //0:优先获取已关注没有则获取推荐 1:已关注 2:推荐 } GetFollowUpUsersWithShortRep struct { RecoUsers []*RecoUser `json:"recoUsers"` // 官方推荐(没有关注用户则使用此数据) //FollowUsers []*UserInfo `json:"followUsers"` // 已关注的博主列表 List []*vidmod.VideoInfo `json:"list"` // 已关注的博主发布的视频列表 ShowType int `json:"showType"` // 1:已关注 2:推荐 HasNext bool `json:"hasNext"` // 是否有下一页 } UserInfo struct { Uid uint64 `json:"uid" bson:"uid"` //UID Gender string `json:"gender" bson:"gender"` //性别 Name string `json:"name" bson:"name"` //姓名 Portrait string `json:"portrait" bson:"portrait"` //头像 Fans int64 `json:"fans" bson:"fans"` //粉丝数 Summary string `json:"summary" bson:"summary"` //简介 OfficialCert bool `json:"officialCert" bson:"officialCert"` //是否官方认证 IsFollow bool `json:"isFollow"` //是否关注 TotalWorks int64 `json:"totalWorks" bson:"totalWorks"` // 总作品数 } RecoUser struct { UserInfo UserInfo `json:"userInfo"` // 用户信息 List []*vidmod.VideoBase `json:"list"` // 用户发布的视频信息 } ) // GetFollowUpUserListWithShort 获取用户关注的UP主短视频 或 短视频推荐UP主以及UP主发布的短视频 func (req *GetFollowUpUsersWithShortReq) GetFollowUpUserListWithShort(uid uint64) (data GetFollowUpUsersWithShortRep, code stderr.Code) { if req.ShowType <= 1 { data, code = req.GetFollowUpUserListAndShortVideo(uid) if code != stderr.Success || data.ShowType == 1 { return data, code } } // 短视频推荐 data, code = req.getRecoUserByShortVideo() return data, stderr.Success } // GetFollowUpUserListAndShortVideo 获取关注用户和用户下的短视频 func (req *GetFollowUpUsersWithShortReq) GetFollowUpUserListAndShortVideo(uid uint64) (data GetFollowUpUsersWithShortRep, code stderr.Code) { // 已关注的用户列表不需要展示 var uids []uint64 uids, err := followmod.GetTotalFollowListLimit(uid, 30) if err != nil { return data, stderr.ErrDbQueryError } if len(uids) == 0 { return data, stderr.Success } //users, err := usermod.FindUsersMapByUID(uids) //if err != nil { // return data, stderr.Failure //} // //if len(users) == 0 { // return data, stderr.Success //} // //for _, user := range users { // data.FollowUsers = append(data.FollowUsers, &UserInfo{ // Uid: user.UID, // Gender: user.Gender, // Name: user.Name, // Portrait: user.Portrait, // Fans: user.Fans, // OfficialCert: user.OfficialCert, // IsFollow: true, // Summary: user.Summary, // TotalWorks: user.TotalWorks, // }) //} cond := bson.M{"newsType": vidmod.SHORT, "publisherID": bson.M{"$in": uids}, "status": vidmod.CheckPass} // 下层函数已经设置过滤status sort := bson.D{{Key: "reviewAt", Value: -1}} videos, hasNext, err := vidmod.FindList(cond, options.Find().SetSort(sort).SetLimit(req.Limit64()).SetSkip(req.Skip64())) if err != nil { return data, stderr.Failure } list := vidhelpser.EncodeVideoInfo(uid, videos) data.List = list data.HasNext = hasNext data.ShowType = 1 // 当前是关注用户 return data, stderr.Success } // getRecoUserByShortVideo 获取推荐用户 func (req *GetFollowUpUsersWithShortReq) getRecoUserByShortVideo() (data GetFollowUpUsersWithShortRep, code stderr.Code) { req.PageSize = 6 // 短视频推荐每页固定条数 key := fmt.Sprintf("recoUserAndShortVideo:%d_%d", req.PageSize, req.PageNumber) err := appg.Redis.GetWithJson2Any(key, &data) if err == nil { return data, stderr.Success } if !errors.Is(err, goredis.Nil) { log.Warn("GetFollowUpUserPublishVideosReq.getRecoVideoList error", log.E(err)) } defer func() { _ = appg.Redis.SetWithAny2Json(key, data, time.Minute*5) }() recoUsers, _, hasNext := weektop.GetTopByPage(topser.TypeRecommendUser, req.Limit64(), req.Limit64()+1) if len(recoUsers) > int(req.Limit64()) { recoUsers = recoUsers[:req.Limit64()] hasNext = true } if len(recoUsers) == 0 { return data, stderr.Success } var ( dataMap = map[uint64]*RecoUser{} uids []uint64 ) for _, v := range recoUsers { uid, e := strconv.ParseUint(v, 10, 64) if e != nil { continue } uids = append(uids, uid) } users, err := usermod.FindUsersByUID(uids) if err != nil { return data, stderr.Failure } uids = uids[:0] for _, user := range users { recoUser := &RecoUser{ UserInfo: UserInfo{ Uid: user.UID, Gender: user.Gender, Name: user.Name, Portrait: user.Portrait, Fans: user.Fans, Summary: user.Summary, OfficialCert: user.OfficialCert, TotalWorks: user.TotalWorks, }, } dataMap[user.UID] = recoUser // 获取用户的视频 filterTmp := bson.M{"newsType": vidmod.SP, "publisherID": user.UID, "status": vidmod.CheckPass} optTmp := options.Find().SetSort(bson.D{{"reviewAt", -1}}).SetLimit(6) list, _, err := vidmod.FindList(filterTmp, optTmp) if err != nil { return data, stderr.Failure } for _, model := range list { baseVid := vidhelpser.ToVideoBaseInfo(model, nil, 0) recoUser.List = append(recoUser.List, baseVid) } data.RecoUsers = append(data.RecoUsers, recoUser) } data.HasNext = hasNext data.ShowType = 2 // 当前是推荐用户 return data, stderr.Success }