package user_cv import ( "git.hilo.cn/hilo-common/_const/common" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/mylogrus" "git.hilo.cn/hilo-common/resource/mysql" "git.hilo.cn/hilo-common/rpc" "gorm.io/gorm" "hilo-user/_const/enum/country_e" "hilo-user/_const/enum/cp_e" "hilo-user/cv/headwear_cv" "hilo-user/cv/medal_cv" "hilo-user/cv/noble_cv" "hilo-user/cv/property_cv" "hilo-user/domain/model/noble_m" "hilo-user/domain/model/res_m" "hilo-user/domain/model/user_m" "hilo-user/myerr" ) type UserTiny struct { Id uint64 `json:"id,omitempty"` ExternalId string `json:"externalId"` Avatar string `json:"avatar"` Nick string `json:"nick"` Sex uint8 `json:"sex"` Code string `json:"code"` Country string `json:"country"` CountryIcon string `json:"countryIcon"` IsPrettyCode bool `json:"isPrettyCode"` // 是否靓号 } func UserToTiny(user user_m.User) *UserTiny { return &UserTiny{ Id: user.ID, ExternalId: user.ExternalId, Avatar: user.Avatar, Nick: user.Nick, Sex: user.Sex, Code: user.Code, Country: user.Country, CountryIcon: user.CountryIcon, IsPrettyCode: user.IsPrettyCode(), } } func UserTinyToCvTiny(user *user_m.UserTiny) *UserTiny { return &UserTiny{ Id: user.ID, ExternalId: user.ExternalId, Avatar: user.Avatar, Nick: user.Nick, Sex: user.Sex, Code: user.Code, Country: user.Country, CountryIcon: user.CountryIcon, IsPrettyCode: user.IsPrettyCode, } } //用户基本信息 type CvUserBase struct { //不会有返回值 Id *mysql.ID `json:"id,omitempty"` //头像,不存在为nil Avatar *string `json:"avatar"` //是否默认头像 true:是 false:不是 DefaultAvatar *bool `json:"defaultAvatar"` //用户对外ID ExternalId *string `json:"externalId"` //昵称,不存在为nil Nick *string `json:"nick"` //签名,不存在为nil Description *string `json:"description"` //性别 1:男 2:女,不存在为nil Sex *uint8 `json:"sex"` //国家,不存在为nil Country *string `json:"country"` //国旗图标,不存在为nil CountryIcon *string `json:"countryIcon"` //邀请码 Code *string `json:"code"` IsPrettyCode bool `json:"isPrettyCode"` // 是否靓号 IsLogout bool `json:"isLogout"` //是否注销 //生日,如果是其它人用户信息,年龄则按照是否展示显示,如果是本人,年龄则按照是否存在展示 Birthday *uint64 `json:"birthday"` //是否展示年龄, 是本人才有数据,看其他用户均为nil IsShowAge *uint8 `json:"isShowAge"` //是否工会成员, 只有是自己查自己,这个才有值,其它全为nil, 20220329 数据开放:原因:产品1对1视频聊天中,公会用户视频需要送礼物。改为: 全部人可以知道是否是公会用户。 IsTradeUnion *bool `json:"isTradeUnion"` //是否代理管理员, 只有自己查自己的时候才有值,其他情况为nil IsAgentMgr *bool `json:"isAgentMgr"` //工会成员,是否开启了,匹配通知,只有 isTradeUnion值为true,这里才有值, IsTradeUnionMatchNotification *bool `json:"isTradeUnionMatchNotification"` //是否VIP用户 IsVip bool `json:"isVip"` //是否是官方人员 IsOfficialStaff bool `json:"isOfficialStaff"` //VIP用户过期时间(只有自己查询自己,才返回) VipExpireTime *int64 `json:"vipExpireTime"` Svip rpc.CvSvip `json:"svip"` // svip结构,等级+权限 MedalInfo []medal_cv.CvMedal `json:"medalInfo"` // 勋章列表 Headwear *headwear_cv.CvHeadwear `json:"headwear"` // 当前使用的头饰 Ride property_cv.CvProperty `json:"ride"` // 当前使用的座驾 Noble noble_cv.CvNoble `json:"noble"` // 当前的 GroupRole common.GroupRoleType `json:"groupRole"` // 在群组的角色 } //批量获取用户基本信息 func GetUserBases(userIds []mysql.ID, myUserId mysql.ID) ([]*CvUserBase, error) { if len(userIds) == 0 { return []*CvUserBase{}, nil } var users []user_m.User if err := mysql.Db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil { return nil, myerr.WrapErr(err) } vips, err := user_m.BatchGetVips(userIds) if err != nil { return nil, myerr.WrapErr(err) } svips, err := rpc.MGetUserSvip(domain.CreateModelNil(), userIds) if err != nil { mylogrus.MyLog.Errorf("MGetUserSvip fail:%v", err) //return nil, myerr.WrapErr(err) } headwearMap, err := headwear_cv.BatchGetCvHeadwears(userIds) if err != nil { return nil, err } logger := mylogrus.MyLog.WithField("func", "GetUserBases") medals, err := user_m.BatchGetUserMedalMerge(logger, mysql.Db, userIds) if err != nil { return nil, err } medals, medalInfo, err := getMedalInfoMap(mysql.Db, medals) if err != nil { return nil, err } up := user_m.UserProperty{} rides, err := up.BatchGet(mysql.Db, userIds) if err != nil { return nil, err } //rp := res_m.ResProperty{} //properties, err := rp.GetAll(mysql.Db) properties, err := GetPropertyAll(mysql.Db) if err != nil { return nil, err } nobles, err := noble_m.BatchGetActiveNoble(domain.CreateModelNil(), userIds) if err != nil { return nil, err } superManagerMap, err := user_m.GetSuperManagerMap(userIds) if err != nil { return nil, err } cvUserBases := []*CvUserBase{} for i := 0; i < len(users); i++ { user := users[i] invisible := IfLogout(user.LogoutTime) invisibleAvatar := "" invisibleNick := user.Code //for _, p := range svips[user.ID].Privileges { // if p.Type == 17 && p.UserSwitch { // 神秘人特权 // invisible = true // invisibleAvatar, invisibleNick = rpc.ReplaceSvipAvatarNick(invisibleAvatar, invisibleNick, svips[user.ID].Privileges) // } //} cvUserBase := &CvUserBase{ Id: &user.ID, Avatar: StrNil(IfLogoutStr(invisible, invisibleAvatar, user.Avatar)), DefaultAvatar: &user.DefaultAvatar, ExternalId: StrToString(&user.ExternalId), Nick: StrNil(IfLogoutNick(invisible, invisibleNick, user.Nick)), Description: StrNil(IfLogoutStr(invisible, "", user.Description)), Sex: TypeToUint8(&user.Sex), Country: StrNil(user.Country), CountryIcon: StrNil(user.CountryIcon), Code: StrToString(&user.Code), IsPrettyCode: user.IsPrettyCode(), IsVip: vips[user.ID] != nil, IsOfficialStaff: superManagerMap[user.ID], MedalInfo: IfLogoutMedalInfo(invisible, []medal_cv.CvMedal{}, medalInfo[user.ID]), Ride: IfLogoutRide(IfLogout(user.LogoutTime), property_cv.CvProperty{}, property_cv.CvProperty{ Id: rides[user.ID], PicUrl: properties[rides[user.ID]].PicUrl, EffectUrl: properties[rides[user.ID]].EffectUrl, Using: true, SenderAvatar: properties[rides[user.ID]].SenderAvatar, ReceiverAvatar: properties[rides[user.ID]].ReceiverAvatar, }), Noble: noble_cv.CvNoble{ Level: nobles[user.ID].Level, EndTime: nobles[user.ID].EndTime.Unix(), }, } if cvUserBase.Noble.Level <= 0 { cvUserBase.Noble.EndTime = 0 } // if headwear, flag := headwearMap[user.ID]; flag { cvUserBase.Headwear = IfLogoutHeadwear(IfLogout(user.LogoutTime), nil, &headwear) } if user.ID == myUserId { cvUserBase.VipExpireTime = vips[user.ID] cvUserBase.IsShowAge = TypeToUint8(&user.IsShowAge) cvUserBase.Birthday = BirthdayToUint64(&user.Birthday) } else if user.IsShowAge == mysql.OPEN { cvUserBase.Birthday = BirthdayToUint64(&user.Birthday) } cvUserBase.Svip = svips[user.ID] cvUserBases = append(cvUserBases, cvUserBase) } return cvUserBases, nil } // 获取cp另一半基本信息 func GetUserBaseForCpMap(userIds []mysql.ID) (map[mysql.ID]*CvUserBase, error) { var res = make(map[mysql.ID]*CvUserBase) users, err := GetUserBasesForCp(userIds) if err != nil { return nil, err } for i, v := range users { if v.Id != nil { res[*v.Id] = users[i] } } return res, nil } // 批量获取cp另一半基本信息 func GetUserBasesForCp(userIds []mysql.ID) ([]*CvUserBase, error) { if len(userIds) == 0 { return []*CvUserBase{}, nil } var users []user_m.User if err := mysql.Db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil { return nil, myerr.WrapErr(err) } vips, err := user_m.BatchGetVips(userIds) if err != nil { return nil, myerr.WrapErr(err) } svips, err := rpc.MGetUserSvip(domain.CreateModelNil(), userIds) if err != nil { mylogrus.MyLog.Errorf("MGetUserSvip fail:%v", err) } headwearMap, err := headwear_cv.BatchGetCvHeadwears(userIds) if err != nil { return nil, err } nobles, err := noble_m.BatchGetActiveNoble(domain.CreateModelNil(), userIds) if err != nil { return nil, err } var cvUserBases []*CvUserBase for i := 0; i < len(users); i++ { user := users[i] invisible := IfLogout(user.LogoutTime) invisibleAvatar := "" invisibleNick := user.Code cvUserBase := &CvUserBase{ Id: &user.ID, Avatar: StrNil(IfLogoutStr(invisible, invisibleAvatar, user.Avatar)), DefaultAvatar: &user.DefaultAvatar, ExternalId: StrToString(&user.ExternalId), Nick: StrNil(IfLogoutNick(invisible, invisibleNick, user.Nick)), Description: StrNil(IfLogoutStr(invisible, "", user.Description)), Sex: TypeToUint8(&user.Sex), Country: StrNil(user.Country), CountryIcon: StrNil(user.CountryIcon), Code: StrToString(&user.Code), IsPrettyCode: user.IsPrettyCode(), IsVip: vips[user.ID] != nil, Noble: noble_cv.CvNoble{ Level: nobles[user.ID].Level, EndTime: nobles[user.ID].EndTime.Unix(), }, } if cvUserBase.Noble.Level <= 0 { cvUserBase.Noble.EndTime = 0 } // if headwear, flag := headwearMap[user.ID]; flag { cvUserBase.Headwear = IfLogoutHeadwear(IfLogout(user.LogoutTime), nil, &headwear) } cvUserBase.Svip = svips[user.ID] cvUserBases = append(cvUserBases, cvUserBase) } return cvUserBases, nil } func getMedalInfoMap(db *gorm.DB, medals map[uint64][]uint32) (map[uint64][]uint32, map[uint64][]medal_cv.CvMedal, error) { resMedals, err := res_m.MedalGetAllMap(db) if err != nil { return nil, nil, err } medalIds := make(map[uint64][]uint32) medalMap := make(map[uint64][]medal_cv.CvMedal, 0) // 只选择合法的勋章 for u, i := range medals { medalIds[u] = make([]uint32, 0) medalMap[u] = make([]medal_cv.CvMedal, 0) for _, j := range i { if e, ok := resMedals[j]; ok { medalIds[u] = append(medalIds[u], j) medalMap[u] = append(medalMap[u], medal_cv.CvMedal{ Id: j, PicUrl: e.PicUrl, EffectUrl: e.SvgaUrl, }) } } } return medalIds, medalMap, nil } func GetPropertyAll(db *gorm.DB) (map[uint64]property_cv.CvProperty, error) { rp := res_m.ResProperty{} properties, err := rp.GetAll(mysql.Db) if err != nil { return nil, err } //获取座驾头像 propertyAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db) var userIds []uint64 for _, value := range propertyAvatarMap { if value.SendUserId > 0 { userIds = append(userIds, value.SendUserId) } if value.ReceiverUserId > 0 { userIds = append(userIds, value.ReceiverUserId) } } //获取用户信息 users := []user_m.User{} if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil { return nil, myerr.WrapErr(err) } userAvatarMap := map[mysql.ID]string{} for _, r := range users { userAvatarMap[r.ID] = r.Avatar } result := map[uint64]property_cv.CvProperty{} for _, r := range properties { var senderAvatar string = "" var receiverAvatar string = "" if propertyAvatar, flag := propertyAvatarMap[r.ID]; flag { if propertyAvatar.SendUserId > 0 { if avatar, flag := userAvatarMap[propertyAvatar.SendUserId]; flag { senderAvatar = avatar } } if propertyAvatar.ReceiverUserId > 0 { if avatar, flag := userAvatarMap[propertyAvatar.ReceiverUserId]; flag { receiverAvatar = avatar } } } result[r.ID] = property_cv.CvProperty{ Id: r.ID, PicUrl: r.PicUrl, EffectUrl: r.EffectUrl, SenderAvatar: senderAvatar, ReceiverAvatar: receiverAvatar, } } return result, nil } func GetUserBaseMap(userIds []mysql.ID, myUserId mysql.ID) (map[mysql.ID]*CvUserBase, error) { userBases, err := GetUserBases(userIds, myUserId) if err != nil { return nil, err } //转换成map mapIdUser := map[mysql.ID]*CvUserBase{} for i := 0; i < len(userBases); i++ { mapIdUser[*userBases[i].Id] = userBases[i] } return mapIdUser, nil } type CvUserTiny struct { Id uint64 `json:"id,omitempty"` ExternalId string `json:"externalId"` Avatar string `json:"avatar"` Nick string `json:"nick"` Sex uint8 `json:"sex"` Code string `json:"code"` Country string `json:"country"` CountryIcon string `json:"countryIcon"` IsPrettyCode bool `json:"isPrettyCode"` // 是否靓号 IsLogout bool `json:"isLogout"` //是否注销 true:已经注销, false:没有注销 //生日,如果是其它人用户信息,年龄则按照是否展示显示,如果是本人,年龄则按照是否存在展示 Birthday *uint64 `json:"birthday"` } //用户详细信息 type CvUserDetail struct { CvUserBase //统计:我喜欢多少人 ILikeCount *uint32 `json:"iLikeCount"` //统计:多少人喜欢你, (本才才有数据,不是本人,数据为nil) LikeCount *uint32 `json:"likeCount"` //统计:多少人访问你 VisitCount *uint32 `json:"visitCount"` //消息提醒, 1:开启,2:关闭 IsPush *uint8 `json:"isPush"` //钻石数量(本人才有数据,不是本人,数据为nil) DiamondNum *uint32 `json:"diamondNum"` //粉钻数量(本人才有数据,不是本人,数据为nil) PinkDiamondNum *uint32 `json:"pinkDiamondNum"` //是否喜欢(本人没有数据,//20210205 已废弃nil,产品说:可以自己喜欢自己) IsLike *bool `json:"isLike"` //ID //ID *mysql.ID `json:"id,omitempty"` //是否工会成员, 只有是自己查自己,这个才有值,其它全为nil //IsTradeUnion *bool `json:"isTradeUnion"` //工会成员,是否开启了,匹配通知,只有 isTradeUnion值为true,这里才有值, //IsTradeUnionMatchNotification *bool `json:"isTradeUnionMatchNotification"` //是否可以免费通话,自己本人没有数据 //IsVideoFreeCan *bool `json:"isVideoCanFree"` //别人是否喜欢我,自己本人没有数据 (20210205 已废弃nil,产品说:可以自己喜欢自己) IsLikeMe *bool `json:"isLikeMe"` HeartValue uint32 `json:"heartValue"` // 与我之间永恒之心的值 HeartValueMax uint32 `json:"heartValueMax"` // 与我之间永恒之心的最大值(0代表没有永恒之心,即没有相互关注) MeetDays uint `json:"meetDays"` // 成长关系建立的时间(天数) WealthUserGrade uint32 `json:"wealthUserGrade"` //财富等级 CharmUserGrade uint32 `json:"charmUserGrade"` //魅力等级 ActivityUserGrade uint32 `json:"activityUserGrade"` //活跃等级 CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”) MyGroupPower uint64 `json:"myGroupPower"` // 当前用户所在势力 MyGroupPowerName string `json:"myGroupPowerName"` // 当前用户所在势力绑定群组的名称 GroupPower rpc.CvGroupPowerInfo `json:"groupPower"` // 家族 GroupId string `json:"groupId"` // 当前用户拥有的群组id(产品叫“群组”),如果没有则为空,拥有多个,返回第一个 PhoneInfo *user_m.UserPhoneInfo `json:"phoneInfo"` // 用户绑定的手机信息 ThirdList []int8 `json:"thirdList"` // 用户绑定的第三方平台列表;类型 1:phone, 2:google, 3:facebook 4:apple 5:wechat" Enums(1,2,3,4,5) CountryManager *CVCountryManager `json:"countryManager,omitempty"` // 国家管理员 Cp *CvCp `json:"cp,omitempty"` // cp信息 } // cv国家管理人员 type CVCountryManager struct { Country string `json:"country"` // 国家name Role country_e.CountryMgrRole `json:"role" swaggertype:"integer"` // 角色 1:国家管理员 2:国家助理 } // cp信息 type CvCp struct { CpUserInfo *CvUserBase `json:"cpUserInfo"` // cp用户信息 CpLevel CvCpLevel `json:"cpLevel"` // cp等级 MyPrivilegeList []CvPrivilege `json:"myPrivilegeList"` // 等级特权 CreatedUnix int64 `json:"createdUnix"` // cp创建时间 CpDays int `json:"cpDays"` // cp天数 } // cp关系 type CvCpRelation struct { CpId uint64 `json:"cpId"` UserId uint64 `json:"userId"` CpUserId uint64 `json:"cpUserId"` CpUserAvatar string `json:"cpUserAvatar,omitempty"` } // cp等级 type CvCpLevel struct { Level cp_e.CpLevel `json:"level"` // 等级 0:无称号 1:恋爱CP 2:甜蜜CP 3:忠诚CP 4:炽热CP 5:荣耀CP Points uint32 `json:"points"` // CP值 Title string `json:"title,omitempty"` // 称号翻译 } // 特权信息 type CvPrivilege struct { Type cp_e.CpPrivilege `json:"type"` // 特权id 1:空间 2:横幅 3:等级勋章 4:证书 5:进场特效 6:头像头饰 7:动态资料卡 8:麦位特效 }