Commit 406e236f authored by hujiebin's avatar hujiebin

Merge branch 'feature/user-detail' into 'master'

Feature/user detail

See merge request !8
parents 50c31efc 00996982
package country_e
import "git.hilo.cn/hilo-common/resource/mysql"
// 国家角色
type CountryMgrRole mysql.Type
const (
// 国家管理员
CountryMgrManager CountryMgrRole = 1
// 国家助理
CountryMgrAssistant CountryMgrRole = 2
)
// 角色权限
type ManagerPrivilegeItem mysql.Type
const (
// 重置用户头像
ManagerPrivilegeItemResetAvatar ManagerPrivilegeItem = 1
// 重置群组头像
ManagerPrivilegeItemResetFaceUrl ManagerPrivilegeItem = 2
// 删除广播
ManagerPrivilegeItemDeleteGlobalBroadcast ManagerPrivilegeItem = 3
)
package groupPower_e
import "git.hilo.cn/hilo-common/resource/mysql"
//国家势力状态
type GroupPowerStatus = mysql.Type
const (
//上架
GroupPowerUserHas GroupPowerStatus = 1
//未上架
GroupPowerUserNo GroupPowerStatus = 2
//解散
GroupPowerDissolve GroupPowerStatus = 3
)
//国家势力用户角色
type GroupPowerUserRole = mysql.Type
const (
// 普通用户
GroupPowerUserRoleUser GroupPowerUserRole = 1
// 势力主
GroupPowerUserRoleMgr GroupPowerUserRole = 2
// 管理员
GroupPowerUserRoleAdmin GroupPowerUserRole = 3
)
//国家势力日志操作类型
type GroupPowerUserLogType = mysql.Type
const (
//加入
GroupPowerUserLogTypeUserJoin GroupPowerUserLogType = 1
//用户自己离开
GroupPowerUserLogTypeUserLeave GroupPowerUserLogType = 2
//运营平台赋予管理者
GroupPowerUserLogTypeOwerJoin GroupPowerUserLogType = 3
//管理人让用户离开
GroupPowerUserLogTypeMgrLeave GroupPowerUserLogType = 4
//管理人解散
GroupPowerUserLogDissolve GroupPowerUserLogType = 5
)
type GroupPowerDiamondLogType = mysql.Type
const (
//群组原因加入
GroupPowerDiamondLogTypeByGroup GroupPowerDiamondLogType = 1
//群主原因加入
GroupPowerDiamondLogTypeByGroupOwer GroupPowerDiamondLogType = 2
)
type PowerSupportAwardState = uint
const (
PowerSuppportNo PowerSupportAwardState = 0 // 未达到要求
PowerSuppportAwarded PowerSupportAwardState = 1 // 已经领取
PowerSuppportWaiting PowerSupportAwardState = 2 // 待领取
)
package group_e
import "git.hilo.cn/hilo-common/resource/mysql"
type MsgStatusGroupUser = mysql.Type
const (
//正常: 灰点+震动
NormalMsgStatusGroupUser MsgStatusGroupUser = 0
//静音:灰点
MuteMsgStatusGroupUser MsgStatusGroupUser = 1
//免打扰:什么也没有
DoNotDisturbMsgStatusGroupUser MsgStatusGroupUser = 2
OverseaRoom = 1
LocalRoom = 2
)
// 公屏消息
type TypePublicScreenMsg = mysql.Type
const (
UserJoinPublicScreenMsg TypePublicScreenMsg = 1 // 加入群组
UserKickPublicScreenMsg TypePublicScreenMsg = 2 // 踢出房间
UserBannedPublicScreenMsg TypePublicScreenMsg = 3 // 拉黑用户
RoleAssignedPublicScreenMsg TypePublicScreenMsg = 4 // 添加角色
RoleRemovedPublicScreenMsg TypePublicScreenMsg = 5 // 移除角色
ClientSendMsgLocal TypePublicScreenMsg = 6 // 客户端占用
RollDiceMsg TypePublicScreenMsg = 7 // 掷骰子结果
GroupGiftMsg TypePublicScreenMsg = 8 //全服礼物
GroupSupportH5 TypePublicScreenMsg = 9 //群组支持H5
JumpMessage TypePublicScreenMsg = 10 // 可跳转的公屏消息
RocketAwardMsg TypePublicScreenMsg = 11 // 火箭获奖消息
LockyboxAwardMsg TypePublicScreenMsg = 12 // 幸运盒子公屏中奖
FruitMachineAwardMsg TypePublicScreenMsg = 13 // 水果机中奖
EnterRoomMsg TypePublicScreenMsg = 14 // 用户进入房间
)
// 信令消息(不显示公屏工,不记入消息历史,不影响未读数)
type TypeSignalMsg = mysql.Type
const (
GroupEditProfileSignal TypeSignalMsg = 1
GroupRoleChangeSignal TypeSignalMsg = 2
GroupMicChangeSignal TypeSignalMsg = 3 //保留
GroupMsgBannedSignal TypeSignalMsg = 4
GroupMemberRemoveSignal TypeSignalMsg = 5
GroupGiftSignal TypeSignalMsg = 6 //礼物
GroupMicInSignal TypeSignalMsg = 7
GroupMicOutSignal TypeSignalMsg = 8
GroupMicLockSignal TypeSignalMsg = 9
GroupMicUnLockSignal TypeSignalMsg = 10
GroupMicSpeechOpenSignal TypeSignalMsg = 11
GroupMicSpeechCloseSignal TypeSignalMsg = 12
GroupKickOut TypeSignalMsg = 13 //保留
GroupSocketMicOutSignal TypeSignalMsg = 14 //保留
GroupInviteMicInSignal TypeSignalMsg = 15 //邀请上麦保留
GroupInSignal TypeSignalMsg = 16 //进入房间,进房特效
GroupMicEmoji TypeSignalMsg = 17 //麦上表情
GroupLuckyWheel TypeSignalMsg = 18 //转盘的通知信令
GroupOutSignal TypeSignalMsg = 19 //离开房间
GroupRocketState TypeSignalMsg = 20 //火箭状态变化
GroupOnlineUser TypeSignalMsg = 21 //房间在线用户信息
GroupMicChange TypeSignalMsg = 22 //房间麦位上的变量
GroupMemberInvite TypeSignalMsg = 23 //房间-邀请用户成为会员
GroupRoleChange TypeSignalMsg = 24 //房间-用户群组身份变化
GroupClearScreen TypeSignalMsg = 25 //房间-清理公屏
GroupRoomGiftSignal TypeSignalMsg = 26 //全房间送礼物
)
//群组麦位数量类型
type GroupMicNumType = mysql.Type
const (
OneMicNumType GroupMicNumType = 5
TwoMicNumType GroupMicNumType = 10
ThreeMicNumType GroupMicNumType = 3
FourMicNumType GroupMicNumType = 4
SixMicNumType GroupMicNumType = 6
SevenMicNumType GroupMicNumType = 7
EightMicNumType GroupMicNumType = 8
NineMicNumType GroupMicNumType = 9
ElevenMicNumType GroupMicNumType = 11
TwelveMicNumType GroupMicNumType = 12
ThirteenMicNumType GroupMicNumType = 13
FourteenMicNumType GroupMicNumType = 14
FifteenMicNumType GroupMicNumType = 15
SixteenMicNumType GroupMicNumType = 16
SeventeenMicNumType GroupMicNumType = 17
EighteenMicNumType GroupMicNumType = 18
NineteenMicNumType GroupMicNumType = 19
TwentyMicNumType GroupMicNumType = 20
//5个麦位
FiveMicNumType GroupMicNumType = 1
//10个麦位
TenMicNumType GroupMicNumType = 2
//
SUPPORT_LEVEL_BOUNDARY_HOUR = 0
SUPPORT_LEVEL_PERIOD_DAY = 7
)
package user_e
import "git.hilo.cn/hilo-common/resource/mysql"
import (
"git.hilo.cn/hilo-common/resource/mysql"
)
type ThirdPartyType = mysql.Type
......@@ -12,6 +14,17 @@ const (
WeChat ThirdPartyType = 5
)
type CountType mysql.Type
const (
//我喜欢的数量
CountTypeLike CountType = 1
//我拉黑的数量
CountTypeBlock CountType = 2
//我被喜欢的次数
CountTypeLikeMe CountType = 3
)
type UserStatus mysql.Type
const (
......@@ -24,8 +37,33 @@ const (
type UserVipType = mysql.Type
const (
//
UserMan = 1
//
UserWomen = 2
//购买
UserVipTypeBuy UserVipType = 1
//赠送
UserVipTypeGive UserVipType = 2
)
type UserLikeOperateType = mysql.Type
const (
//增加喜欢
LikeAdd UserLikeOperateType = 1
//取消喜欢
LikeCancel UserLikeOperateType = 2
)
type UserLikeSceneType = mysql.Type
const (
Match UserLikeSceneType = 1
Video UserLikeSceneType = 2
)
type InteractionType = mysql.Type
const (
InteractPrivateGift InteractionType = 1
InteractVideo InteractionType = 2
)
package group_k
//在房间的人
const groupRoomLiving = "group_room_living"
func GetPrefixGroupRoomLiving() string {
return groupRoomLiving
}
......@@ -4,6 +4,8 @@ import (
"fmt"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/redis_key"
"strconv"
"strings"
)
const (
......@@ -28,3 +30,9 @@ func GetExternalIdToUidKey(externalId mysql.Str) string {
func GetCodeToUidKey(code mysql.Str) string {
return redis_key.ReplaceKey(UserCodeToUIdStr, code)
}
const syncTimHiloLock = "sync_tim_hilo_{userId}"
func GetKeySyncTimHilo(userId uint64) string {
return strings.Replace(syncTimHiloLock, "{userId}", strconv.FormatUint(userId, 10), -1)
}
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"
......@@ -101,6 +104,7 @@ type CvUserBase struct {
Headwear *headwear_cv.CvHeadwear `json:"headwear"` // 当前使用的头饰
Ride property_cv.CvProperty `json:"ride"` // 当前使用的座驾
Noble noble_cv.CvNoble `json:"noble"` // 当前的
GroupRole common.GroupRoleType `json:"groupRole"` // 在群组的角色
}
//批量获取用户基本信息
......@@ -156,7 +160,7 @@ func GetUserBases(userIds []mysql.ID, myUserId mysql.ID) ([]*CvUserBase, error)
return nil, err
}
superManagerMap, err := GetSuperManagerMap(userIds)
superManagerMap, err := user_m.GetSuperManagerMap(userIds)
if err != nil {
return nil, err
}
......@@ -223,6 +227,87 @@ func GetUserBases(userIds []mysql.ID, myUserId mysql.ID) ([]*CvUserBase, error)
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 {
......@@ -309,25 +394,6 @@ func GetPropertyAll(db *gorm.DB) (map[uint64]property_cv.CvProperty, error) {
return result, nil
}
func GetSuperManagerMap(userIds []uint64) (map[uint64]bool, error) {
if len(userIds) == 0 {
return map[uint64]bool{}, nil
}
var superManagers []user_m.SuperManager
if err := mysql.Db.Model(&user_m.SuperManager{}).Where("user_id in (?)", userIds).Find(&superManagers).Error; err != nil {
return nil, myerr.WrapErr(err)
}
//转换成map
rs := map[uint64]bool{}
for i, _ := range userIds {
rs[userIds[i]] = false
}
for i, _ := range superManagers {
rs[superManagers[i].UserId] = true
}
return rs, nil
}
func GetUserBaseMap(userIds []mysql.ID, myUserId mysql.ID) (map[mysql.ID]*CvUserBase, error) {
userBases, err := GetUserBases(userIds, myUserId)
if err != nil {
......@@ -355,3 +421,82 @@ type CvUserTiny struct {
//生日,如果是其它人用户信息,年龄则按照是否展示显示,如果是本人,年龄则按照是否存在展示
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:麦位特效
}
package country_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/country_e"
"hilo-user/myerr"
)
type CountryMgrUser struct {
mysql.Entity
Country string
UserId mysql.ID
Role country_e.CountryMgrRole
}
// 获取国家管理人员
func GetCountryMgr(model *domain.Model, userId mysql.ID) (*CountryMgrUser, error) {
cmu := new(CountryMgrUser)
if err := model.Db.WithContext(model.MyContext.Context).Where("user_id = ?", userId).First(&cmu).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return cmu, nil
}
// 更新国家管理人员
func (cmu *CountryMgrUser) UpdateCountryMgr(userId mysql.ID, role country_e.CountryMgrRole, country string) *CountryMgrUser {
cmu.UserId, cmu.Role, cmu.Country = userId, role, country
return cmu
}
// 删除国家管理人员
func (cmu *CountryMgrUser) DeleteCountryMgr() {
cmu.SetDel()
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/groupPower_e"
"hilo-user/domain/model/group_m"
"hilo-user/myerr"
)
type GroupPowerUser struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupPowerId mysql.ID
UserId mysql.ID
Role groupPower_e.GroupPowerUserRole
}
type GroupPower struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupUid mysql.Str
Name mysql.Str
Status groupPower_e.GroupPowerStatus
}
// 查询用户加入的国家势力ID及名称(势力绑定的群组的名称)
func GetUserGroupPower(model *domain.Model, userId uint64) (uint64, string, error) {
gpu, err := GetGroupPowerUserOrNil(model, userId)
if err != nil {
return 0, "", err
}
if gpu == nil || gpu.GroupPowerId == 0 {
return 0, "", nil
}
gp, err := GetGroupPowerOrErr(model, gpu.GroupPowerId)
if err != nil {
return 0, "", err
}
powerName := ""
if gp != nil && len(gp.GroupUid) > 0 {
gi, err := group_m.GetGroupInfo(model, gp.GroupUid)
if err != nil {
return 0, "", err
}
if gi != nil {
// 只要前15个字
s := []rune(gi.Name)
if len(s) <= 15 {
powerName = string(s)
} else {
powerName = string(s[0:15])
}
}
}
return gpu.GroupPowerId, powerName, nil
}
//获取用户所在的国家势力信息,不存在则为nil
func GetGroupPowerUserOrNil(model *domain.Model, userId mysql.ID) (*GroupPowerUser, error) {
groupPowerUser := GroupPowerUser{}
if err := model.Db.Where(&GroupPowerUser{
UserId: userId,
}).First(&groupPowerUser).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
groupPowerUser.Model = model
return &groupPowerUser, nil
}
func GetGroupPowerOrErr(model *domain.Model, id uint64) (*GroupPower, error) {
groupPower := GroupPower{}
if err := model.Db.Model(&GroupPower{}).First(&groupPower, id).Error; err != nil {
return nil, myerr.WrapErr(err)
}
groupPower.Model = model
return &groupPower, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/domain"
"gorm.io/gorm"
"hilo-user/_const/enum/group_e"
"hilo-user/myerr/bizerr"
"time"
)
type GroupInfo struct {
Id int64
ImGroupId string
TxGroupId string
Type uint16
Code string
OriginCode string
Owner uint64
Name string
Introduction string
Notification string
FaceUrl string
Country string
ChannelId string
Password string
EntryLevel uint32 // obsolete
MicOn bool
LoadHistory bool
ThemeId int16
MicNumType group_e.GroupMicNumType
TouristMic uint8 // 游客是否能上麦1是2否
TouristSendMsg uint8 // 游客是否能发消息1是2否
TouristSendPic uint8 // 游客是否能发图片1是2否
MemberFee uint64 // 加入会员需要黄钻数
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
func GetGroupInfo(model *domain.Model, groupId string) (*GroupInfo, error) {
if len(groupId) <= 0 {
return nil, bizerr.GroupNotFound
}
r := GroupInfo{}
err := model.Db.Where(&GroupInfo{ImGroupId: groupId}).First(&r).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, err
}
}
return &r, nil
}
func FindGroupByOwner(model *domain.Model, ownerId uint64) ([]GroupInfo, error) {
rows := make([]GroupInfo, 0)
err := model.Db.Where(&GroupInfo{Owner: ownerId}).Find(&rows).Error
if err != nil {
return nil, err
}
return rows, nil
}
func ToTxGroupId(model *domain.Model, imGroupId string) (string, error) {
if len(imGroupId) <= 0 {
return "", nil
}
gi, err := GetGroupInfo(model, imGroupId)
if err != nil {
return "", err
}
if gi == nil {
return "", bizerr.GroupNotFound
}
return gi.TxGroupId, nil
}
func ToImGroupId(model *domain.Model, txGroupId string) (string, error) {
if len(txGroupId) <= 0 {
return "", nil
}
gi, err := GetInfoByTxGroupId(model, txGroupId)
if err != nil {
return "", err
}
if gi == nil {
return "", bizerr.GroupNotFound
}
return gi.ImGroupId, nil
}
func GetInfoByTxGroupId(model *domain.Model, txGroupId string) (*GroupInfo, error) {
if len(txGroupId) <= 0 {
return nil, bizerr.GroupNotFound
}
r := GroupInfo{}
err := model.Db.Where(&GroupInfo{TxGroupId: txGroupId}).First(&r).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, err
}
}
return &r, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/_const/common"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
)
type GroupRoles struct {
mysql.Entity
UserId uint64
ImGroupId string
Role common.GroupRoleType
}
type GroupMember struct {
GroupId string
UserId uint64
}
func (gm *GroupMember) Find(db *gorm.DB) ([]GroupMember, error) {
rows := make([]GroupMember, 0)
if err := db.Where(gm).Order("created_time DESC").Find(&rows).Error; err != nil {
return nil, err
}
return rows, nil
}
func GetGroupRoleById(model *domain.Model, imGroupId string, userId uint64) (role common.GroupRoleType, err error) {
role = common.GROUP_VISITOR
roles, _, err := GetRolesInGroup(model, imGroupId)
if err != nil {
return
}
for u, r := range roles {
if u == userId {
role = r
return
}
}
isGroupMember, err := IsGroupMember(model.Db, imGroupId, userId)
if err != nil {
return
}
if isGroupMember {
role = common.GROUP_MEMBER
}
return
}
// 查询群组中所有有角色的成员,由级别高到低、创建时间由早到晚排列
func GetRolesInGroup(model *domain.Model, groupId string) (map[uint64]uint16, []uint64, error) {
data := make([]GroupRoles, 0)
err := model.Db.Where(&GroupRoles{ImGroupId: groupId}).Order("role DESC, created_time").Find(&data).Error
if err != nil {
return nil, nil, err
}
result := make(map[uint64]uint16, 0)
orders := make([]uint64, 0)
for _, i := range data {
orders = append(orders, i.UserId)
result[i.UserId] = i.Role
}
return result, orders, nil
}
func IsGroupMember(db *gorm.DB, groupId string, userId uint64) (bool, error) {
gm := GroupMember{
GroupId: groupId,
UserId: userId,
}
rows, err := gm.Find(db)
if err != nil {
return false, err
}
return len(rows) > 0, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/resource/redisCli"
"hilo-user/_const/redis_key/group_k"
"hilo-user/myerr"
"strconv"
"strings"
"time"
)
const expireMinute = 60 * 60 * 12
//获取在房间的用户 返回值:map,key:userId, value:groupUuid
func RoomLivingUserIdFilter(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]string, error) {
userIdSet := map[mysql.ID]struct{}{}
for i, _ := range userIds {
userIdSet[userIds[i]] = struct{}{}
}
key := group_k.GetPrefixGroupRoomLiving()
if err := ClearExpired(model, key, expireMinute); err != nil {
return nil, myerr.WrapErr(err)
}
groupUserIdstrs, err := redisCli.GetRedis().ZRange(model, key, 0, -1).Result()
if err != nil {
return nil, myerr.WrapErr(err)
}
resultUserSet := map[mysql.ID]string{}
for i, _ := range groupUserIdstrs {
tempGroupUid, userId := analysisMemberStr(groupUserIdstrs[i])
mylogrus.MyLog.Debugf("RoomLivingUserIdFilter, analysisMemberStr %s, %d", tempGroupUid, userId)
if _, flag := userIdSet[userId]; flag {
resultUserSet[userId] = tempGroupUid
}
}
return resultUserSet, nil
}
func ClearExpired(model *domain.Model, key string, expireSec int64) error {
return model.Redis.ZRemRangeByScore(model, key,
"0", strconv.FormatInt(time.Now().Unix()-expireSec, 10)).Err()
}
func analysisMemberStr(memberStr string) (string, uint64) {
strs := strings.Split(memberStr, "_")
groupUid := strs[0]
userId, err := strconv.ParseUint(strs[1], 10, 64)
if err != nil {
mylogrus.MyLog.Errorf("analysisMemberStr memberStr:%v err:%+v", memberStr, err)
}
return groupUid, userId
}
package tim_m
import (
"encoding/json"
"git.hilo.cn/hilo-common/sdk/tencentyun"
)
type TimHiloInfo struct {
IsVip bool `json:"isVip"`
IsPretty bool `json:"isPretty"`
Medals []uint32 `json:"medals"`
PowerName string `json:"powerName"` // 用户加入的国家势力的绑定群组的名称
NobleLevel uint16 `json:"nobleLevel"`
}
func FlushHiloInfo(extId string, isVip bool, isPrettyCode bool, medals []uint32, groupPowerName string, nobleLevel uint16) error {
info := TimHiloInfo{IsVip: isVip, IsPretty: isPrettyCode, Medals: medals, PowerName: groupPowerName, NobleLevel: nobleLevel}
buf, err := json.Marshal(info)
if err != nil {
return err
}
if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil {
return err
}
return nil
}
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/user_e"
)
//用户统计
type UserCount struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
Type user_e.CountType
Num mysql.Num
isAdd bool `gorm:"-"`
isReduce bool `gorm:"-"`
addReduceNum mysql.Num `gorm:"-"`
}
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/user_e"
"hilo-user/myerr"
)
//用户喜欢
type UserLike struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
LikeUserId mysql.ID
SceneType user_e.UserLikeSceneType
}
type UserLikeOperate struct {
mysql.Entity
UserId mysql.ID
LikeUserId mysql.ID
Type user_e.UserLikeOperateType
SceneType user_e.UserLikeSceneType
}
func AddUserLikeOperate(model *domain.Model, userId mysql.ID, likeUserId mysql.ID, t user_e.UserLikeOperateType, sceneType user_e.UserLikeSceneType) (mysql.ID, error) {
userLikeOperate := UserLikeOperate{
UserId: userId,
LikeUserId: likeUserId,
Type: t,
SceneType: sceneType,
}
if err := model.Db.Create(&userLikeOperate).Error; err != nil {
return 0, myerr.WrapErr(err)
} else {
return userLikeOperate.ID, nil
}
}
func initUserLike(model *domain.Model, userId mysql.ID) *UserLike {
return &UserLike{
Model: model,
UserId: userId,
}
}
/*func GetUserLike(model *domain.Model, userId mysql.ID, likeUserId mysql.ID) (*UserLike, error) {
var userLike UserLike
err := model.Db.Where(&UserLike{
UserId: userId,
LikeUserId: likeUserId,
}).First(&userLike).Error
if err == nil {
return &userLike, nil
} else if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}*/
//喜欢
func (userLike *UserLike) like(likeUserId mysql.ID, sceneType user_e.UserLikeSceneType) (*UserLike, mysql.ID, error) {
err := userLike.Db.Where(&UserLike{
UserId: userLike.UserId,
LikeUserId: likeUserId,
}).First(userLike).Error
//已经喜欢
if err == nil {
return nil, 0, myerr.NewWaring("已经标记喜欢")
} else if err == gorm.ErrRecordNotFound {
userLikeOperateId, err := AddUserLikeOperate(userLike.Model, userLike.UserId, likeUserId, user_e.LikeAdd, sceneType)
if err != nil {
return nil, 0, err
}
userLike.LikeUserId = likeUserId
userLike.SceneType = sceneType
return userLike, userLikeOperateId, nil
} else {
return nil, 0, myerr.WrapErr(err)
}
}
//取消喜欢
func (userLike *UserLike) likeCancel(likeUserId mysql.ID) (*UserLike, error) {
err := userLike.Db.Where(&UserLike{
UserId: userLike.UserId,
LikeUserId: likeUserId,
}).First(userLike).Error
//
if err == nil {
if _, err := AddUserLikeOperate(userLike.Model, userLike.UserId, likeUserId, user_e.LikeCancel, userLike.SceneType); err != nil {
return nil, err
}
userLike.SetDel()
return userLike, nil
} else if err == gorm.ErrRecordNotFound {
return nil, myerr.NewWaring("没有喜欢的记录")
} else {
return nil, myerr.WrapErr(err)
}
}
package user_m
import (
"git.hilo.cn/hilo-common/_const/common"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
"time"
)
type Relation struct {
// 永恒之心值
HeartValue uint32 `json:"heartValue"`
// 永恒之心的最大值(0代表没有永恒之心,即没有相互关注)
HeartValueMax uint32 `json:"heartValueMax"`
// 成长关系建立的时间(天数)
MeetDays uint `json:"meetDays"`
}
//用户成长关系
type UserRelation struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId_1 mysql.ID
UserId_2 mysql.ID
HeartValue uint32
}
// 查询成长关系
func GetRelation(model *domain.Model, userId1, userId2 mysql.ID) (Relation, error) {
result := Relation{0, 0, 0}
if userId1 == userId2 {
return result, nil
}
// 保证uid小的在前面
if userId1 > userId2 {
userId1, userId2 = userId2, userId1
}
rel := UserRelation{UserId_1: userId1, UserId_2: userId2, HeartValue: 0}
if err := model.DB().Model(&UserRelation{}).Where(&UserRelation{
UserId_1: userId1,
UserId_2: userId2,
}).First(&rel).Error; err != nil {
if err == gorm.ErrRecordNotFound {
// 没有成长关系的情况
return result, nil
} else {
return result, myerr.WrapErr(err)
}
}
result.HeartValueMax = common.HEART_VALUE_MAX
result.HeartValue = rel.HeartValue
if result.HeartValue > common.HEART_VALUE_MAX {
result.HeartValue = common.HEART_VALUE_MAX
}
d := uint(time.Since(rel.CreatedTime).Hours() / 24)
if d < 0 {
d = 0
}
result.MeetDays = d
return result, nil
}
// 批量查询成长关系
func BatchGetRelations(model *domain.Model, userId mysql.ID, others []mysql.ID) (map[mysql.ID]Relation, error) {
smaller := make([]mysql.ID, 0)
greater := make([]mysql.ID, 0)
for _, i := range others {
if i < userId {
smaller = append(smaller, i)
} else if i > userId {
greater = append(greater, i)
}
}
rows := make([]UserRelation, 0)
result := make(map[mysql.ID]Relation, 0)
var err error
if len(greater) > 0 {
if err = model.DB().Model(&UserRelation{}).Where("user_id_1 = ? AND user_id_2 IN ?", userId, greater).Find(&rows).Error; err != nil {
return result, err
}
}
for _, i := range rows {
if i.HeartValue > common.HEART_VALUE_MAX {
i.HeartValue = common.HEART_VALUE_MAX
}
d := uint(time.Since(i.CreatedTime).Hours() / 24)
if d < 0 {
d = 0
}
result[i.UserId_2] = Relation{HeartValue: i.HeartValue, HeartValueMax: common.HEART_VALUE_MAX, MeetDays: d}
}
rows = make([]UserRelation, 0)
if len(smaller) > 0 {
if err = model.DB().Model(&UserRelation{}).Where("user_id_1 IN ? AND user_id_2 = ?", smaller, userId).Find(&rows).Error; err != nil {
return result, err
}
}
for _, i := range rows {
if i.HeartValue > common.HEART_VALUE_MAX {
i.HeartValue = common.HEART_VALUE_MAX
}
d := uint(time.Since(i.CreatedTime).Hours() / 24)
if d < 0 {
d = 0
}
result[i.UserId_1] = Relation{HeartValue: i.HeartValue, HeartValueMax: common.HEART_VALUE_MAX, MeetDays: d}
}
// 补上没有成长关系的人
for _, u := range others {
if _, exists := result[u]; !exists {
result[u] = Relation{0, 0, 0}
}
}
return result, err
}
......@@ -65,15 +65,21 @@ func GetSuperManagerAll(model *domain.Model) ([]uint64, error) {
return userIds, nil
}
/*
func GetSuperManagerMap(model *domain.Model) (map[uint64]struct{}, error) {
userIds, err := GetSuperManagerAll(model)
if err != nil {
return nil, err
func GetSuperManagerMap(userIds []uint64) (map[uint64]bool, error) {
if len(userIds) == 0 {
return map[uint64]bool{}, nil
}
var superManagers []SuperManager
if err := mysql.Db.Model(&SuperManager{}).Where("user_id in (?)", userIds).Find(&superManagers).Error; err != nil {
return nil, myerr.WrapErr(err)
}
userIdMap := map[uint64]struct{}{}
//转换成map
rs := map[uint64]bool{}
for i, _ := range userIds {
userIdMap[userIds[i]] = struct{}{}
rs[userIds[i]] = false
}
return userIdMap, nil
}*/
for i, _ := range superManagers {
rs[superManagers[i].UserId] = true
}
return rs, nil
}
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"time"
)
type UserBindInfo struct {
UserId uint64 `json:"user_id"`
Phone string `json:"phone"`
PhoneCountry string `json:"phone_country"`
Pwd string `json:"pwd"`
AreaCode string `json:"area_code"`
Icon string `json:"icon"`
CreateAt time.Time `json:"create_at"`
UpdateAt time.Time `json:"update_at"`
}
func (*UserBindInfo) TableName() string {
return "user_bind_info"
}
type UserPhoneInfo struct {
Phone string `json:"phone"`
PhoneCountry string `json:"phoneCountry"`
AreaCode string `json:"areaCode"`
Icon string `json:"icon"`
}
// 获取用户手机号绑定信息
func GetUserBindInfoByUserId(model *domain.Model, userId uint64) (*UserBindInfo, error) {
res := new(UserBindInfo)
err := model.DB().Where(&UserBindInfo{UserId: userId}).First(&res).Error
if err != nil {
return nil, err
}
return res, nil
}
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"gorm.io/gorm"
"hilo-user/myerr"
)
type UserOauth struct {
UserId uint64 `json:"user_id"`
ThirdPartyId string `json:"third_party_id"`
ThirdPartyType int8 `json:"third_party_type"`
}
func (*UserOauth) TableName() string {
return "user_oauth"
}
// 根据id获取第三方登录信息
func GetUserOauthByUserId(model *domain.Model, userId uint64, thirdType uint8) ([]*UserOauth, error) {
res := make([]*UserOauth, 0)
db := model.DB().Where(&UserOauth{UserId: userId})
if thirdType > 0 {
db = db.Where(&UserOauth{ThirdPartyType: int8(thirdType)})
}
err := db.Find(&res).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return res, nil
}
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
)
type UserTradeUnion struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
MatchNotification mysql.OpenClose
AgentId mysql.ID
StarchatId mysql.ID
Avatar string
}
func GetUserTradeUnion(userId mysql.ID) (*UserTradeUnion, error) {
var userTradeUnion UserTradeUnion
if err := mysql.Db.Where(UserTradeUnion{
UserId: userId,
}).First(&userTradeUnion).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return &userTradeUnion, nil
}
type AgentMgr struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
AgentId mysql.ID
}
func IsAgent(userId uint64) bool {
data := AgentMgr{}
return mysql.Db.Where(&AgentMgr{UserId: userId}).First(&data).Error == nil
}
package visit_m
import "hilo-user/domain/model"
func (userVisit *UserVisit) Persistent() error {
return model.Persistent(userVisit.Db, userVisit)
}
package visit_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/myerr"
)
type UserVisit struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
VisitUserId mysql.ID
N mysql.Num
}
func GetVisitInstanceOrInit(model *domain.Model, userId mysql.ID, visitUserId mysql.ID) (*UserVisit, error) {
var userVisit UserVisit
if err := model.Db.Where(&UserVisit{
UserId: userId,
VisitUserId: visitUserId,
}).FirstOrInit(&userVisit, UserVisit{
UserId: userId,
VisitUserId: visitUserId,
N: 0,
}).Error; err != nil {
return nil, myerr.WrapErr(err)
}
userVisit.Model = model
return &userVisit, nil
}
func (userVisit *UserVisit) UserVisitAdd() *UserVisit {
userVisit.N = userVisit.N + 1
return userVisit
}
package cp_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"hilo-user/_const/enum/cp_e"
"hilo-user/cv/cp_cv"
"hilo-user/cv/user_cv"
"hilo-user/domain/model/cp_m"
"time"
)
type CpService struct {
svc *domain.Service
}
func NewCpService(myContext *mycontext.MyContext) *CpService {
svc := domain.CreateService(myContext)
return &CpService{svc}
}
// 获取用户cp信息
func (s *CpService) GetUserCp(userId uint64, lang string) (*user_cv.CvCp, error) {
var model = domain.CreateModelContext(s.svc.MyContext)
cpLevel := cp_e.CpLevel0
cpRelation, exists := cp_m.GetCpRelation(model, userId)
if !exists {
return nil, nil
}
var myPrivilegeList []user_cv.CvPrivilege
level := cp_m.GetCpLevel(model, cpRelation.Id)
if level.ExpireAt.Before(time.Now()) {
level.ExpireAt = time.Now().AddDate(0, 1, 0)
}
cpLevel = level.Level
cpUserId := cpRelation.UserId2
if cpUserId == userId {
cpUserId = cpRelation.UserId1
}
userPrivileges, err := cp_m.MGetUserSvipPrivilege(model, []uint64{userId})
if err != nil {
return nil, err
}
privilegeList := cp_cv.CopyCpLevelPrivilegeList(level.Level, "en")
for i, v := range privilegeList {
if v.CanSwitch {
privilegeList[i].UserSwitch = userPrivileges[userId][v.Type]
}
}
// 我的特权,有开关并且打开才返回
for _, v := range privilegeList {
if !v.CanSwitch {
myPrivilegeList = append(myPrivilegeList, user_cv.CvPrivilege{Type: v.Type})
} else if v.UserSwitch {
myPrivilegeList = append(myPrivilegeList, user_cv.CvPrivilege{Type: v.Type})
}
}
userBases, err := user_cv.GetUserBaseForCpMap([]uint64{cpUserId})
if err != nil {
return nil, err
}
// 返回值
title := cp_cv.GetTranslate(237, lang)
if msgId, ok := cp_e.CpLevelTitle[level.Level]; ok {
title = cp_cv.GetTranslate(msgId, lang)
}
var oldScore uint32
if oldCp, _ := cp_m.GetOldConnectCp(model, cpRelation.UserId1, cpRelation.UserId2); oldCp != nil {
oldScore = uint32(oldCp.Score)
}
response := &user_cv.CvCp{
CpUserInfo: userBases[cpUserId],
CpLevel: user_cv.CvCpLevel{
Level: cpLevel,
Points: oldScore + cp_m.SumCpPoints(model, cpRelation.Id), // 历史分数
Title: title,
},
MyPrivilegeList: myPrivilegeList,
CpDays: int(time.Now().Sub(cpRelation.CreatedTime).Hours()/24) + 1,
CreatedUnix: cpRelation.CreatedTime.Unix(),
}
return response, nil
}
package user_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/rpc"
"gorm.io/gorm"
"hilo-user/_const/enum/user_e"
"hilo-user/cv/headwear_cv"
"hilo-user/cv/medal_cv"
"hilo-user/cv/noble_cv"
"hilo-user/cv/property_cv"
"hilo-user/cv/user_cv"
"hilo-user/domain/model/country_m"
"hilo-user/domain/model/diamond_m"
"hilo-user/domain/model/groupPower_m"
"hilo-user/domain/model/group_m"
"hilo-user/domain/model/noble_m"
"hilo-user/domain/model/user_m"
"hilo-user/domain/model/visit_m"
"hilo-user/domain/service/cp_s"
"hilo-user/myerr"
)
type UserService struct {
svc *domain.Service
}
func NewUserService(myContext *mycontext.MyContext) *UserService {
svc := domain.CreateService(myContext)
return &UserService{svc}
}
//用户基本信息
func (s *UserService) GetUserDetail(userId mysql.ID, myUserId mysql.ID, lang string) (*user_cv.CvUserDetail, error) {
model := domain.CreateModelContext(s.svc.MyContext)
model.Log.Infof("GetUserDetail %d begin", userId)
var user user_m.User
var err error
if err = model.DB().First(&user, userId).Error; err != nil {
return nil, myerr.WrapErr(err)
}
//统计喜欢
var likeN int64
if err := model.DB().Model(&user_m.UserLike{}).Where(&user_m.UserLike{
UserId: myUserId,
LikeUserId: userId,
}).Count(&likeN).Error; err != nil {
return nil, myerr.WrapErr(err)
}
var likeMe int64
if err := model.DB().Model(&user_m.UserLike{}).Where(&user_m.UserLike{
UserId: userId,
LikeUserId: myUserId,
}).Count(&likeMe).Error; err != nil {
return nil, myerr.WrapErr(err)
}
rel := make(map[mysql.ID]user_m.Relation, 1)
rel[userId], _ = user_m.GetRelation(model, myUserId, userId)
var wealthUserScore user_m.MatchWealthUserScore
if err := model.DB().Model(&user_m.MatchWealthUserScore{}).Where(&user_m.MatchWealthUserScore{UserId: userId}).First(&wealthUserScore).Error; err != nil {
if err != nil {
if err == gorm.ErrRecordNotFound {
wealthUserScore = user_m.MatchWealthUserScore{
UserId: userId,
Score: 0,
Grade: 0,
}
} else {
return nil, myerr.WrapErr(err)
}
}
}
var charmUserScore user_m.MatchCharmUserScore
if err := model.DB().Model(&user_m.MatchCharmUserScore{}).Where(&user_m.MatchCharmUserScore{
UserId: userId,
}).First(&charmUserScore).Error; err != nil {
if err != nil {
if err == gorm.ErrRecordNotFound {
charmUserScore = user_m.MatchCharmUserScore{
UserId: userId,
Score: 0,
Grade: 0,
}
} else {
return nil, myerr.WrapErr(err)
}
}
}
var activityUserScore user_m.MatchActityUserScore
if err := model.DB().Model(&user_m.MatchActityUserScore{}).Where(&user_m.MatchActityUserScore{
UserId: userId,
}).First(&activityUserScore).Error; err != nil {
if err != nil {
if err == gorm.ErrRecordNotFound {
activityUserScore = user_m.MatchActityUserScore{
UserId: userId,
Score: 0,
Grade: 0,
}
} else {
return nil, myerr.WrapErr(err)
}
}
}
isVip, expireTime, err := user_m.IsVip(userId)
if err != nil {
return nil, myerr.WrapErr(err)
}
svip, err := rpc.GetUserSvip(model, userId)
if err != nil {
return nil, myerr.WrapErr(err)
}
headwear, err := headwear_cv.GetCvHeadwear(userId)
if err != nil {
return nil, err
}
medals := make(map[uint64][]uint32, 0)
medals[userId], err = user_m.GetUserMedalMerge(model.Log, mysql.Db, userId)
if err != nil {
return nil, err
}
medals, medalInfo, err := medal_cv.GetMedalInfoMap(mysql.Db, medals)
if err != nil {
return nil, err
}
rooms, err := group_m.RoomLivingUserIdFilter(model, []uint64{userId})
if err != nil {
return nil, err
}
// 2022-05-13 个人详情页:当用户在加锁的房间时,不显示进入房间的图标
if g, ok := rooms[userId]; ok {
gi, err := group_m.GetGroupInfo(model, g)
if err != nil {
return nil, err
}
if gi != nil && len(gi.Password) > 0 {
rooms[userId] = ""
}
}
cp, err := cp_s.NewCpService(s.svc.MyContext).GetUserCp(userId, lang)
if err != nil {
return nil, err
} else if cp != nil && cp.CpUserInfo != nil {
headwear.HeadwearIcon = *cp.CpUserInfo.Avatar
}
groupPowerId, groupPowerName, err := groupPower_m.GetUserGroupPower(model, userId)
if err != nil {
return nil, err
}
powers := map[mysql.ID]uint64{userId: groupPowerId}
powerNames := map[mysql.ID]string{userId: groupPowerName}
groupPower, _ := rpc.GetGroupPower(model, groupPowerId)
up := user_m.UserProperty{}
rides, err := up.BatchGet(mysql.Db, []uint64{userId})
if err != nil {
return nil, err
}
//rp := res_m.ResProperty{}
//properties, err := rp.GetAll(mysql.Db)
properties, err := property_cv.GetPropertyAll(mysql.Db)
if err != nil {
return nil, err
}
ride := property_cv.CvProperty{
Id: rides[user.ID],
PicUrl: properties[rides[user.ID]].PicUrl,
EffectUrl: properties[rides[user.ID]].EffectUrl,
SenderAvatar: properties[rides[user.ID]].SenderAvatar,
ReceiverAvatar: properties[rides[user.ID]].ReceiverAvatar,
Using: true,
}
noble, err := noble_m.FindActiveNoble(mysql.Db, userId)
if err != nil {
return nil, err
}
//判断是不是工会
userTradeUnion, err := user_m.GetUserTradeUnion(myUserId)
if err != nil {
return nil, err
}
superManagerMap, err := user_m.GetSuperManagerMap([]uint64{userId})
if err != nil {
return nil, err
}
// 群组信息
myGroups, err := group_m.FindGroupByOwner(model, userId)
if err != nil {
return nil, err
}
// 手机绑定信息
// 第三方账号绑定信息
phoneInfo := new(user_m.UserPhoneInfo)
var thirdList []int8
if userId == myUserId {
thirdList = make([]int8, 0, 5)
// 手机绑定信息
bindInfo, err := user_m.GetUserBindInfoByUserId(model, userId)
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
if bindInfo != nil {
if len(bindInfo.Phone) > 2 {
phoneInfo.Phone = bindInfo.Phone[:2] + "****" + bindInfo.Phone[len(bindInfo.Phone)-2:]
}
phoneInfo.PhoneCountry = bindInfo.PhoneCountry
phoneInfo.AreaCode = bindInfo.AreaCode
phoneInfo.Icon = bindInfo.Icon
thirdList = append(thirdList, 1)
}
// 第三方账号绑定信息
thirdInfoList, err := user_m.GetUserOauthByUserId(model, userId, 0)
if err != nil {
return nil, err
}
if thirdInfoList != nil {
for _, v := range thirdInfoList {
thirdList = append(thirdList, v.ThirdPartyType)
}
}
}
// 国家管理员
countryManager, err := country_m.GetCountryMgr(model, userId)
if err != nil {
return nil, err
}
var cvCountryManager *user_cv.CVCountryManager
if countryManager != nil {
cvCountryManager = &user_cv.CVCountryManager{
Country: countryManager.Country,
Role: countryManager.Role,
}
}
return userToDetailOne(model, &user, myUserId, userTradeUnion, likeN > 0, likeMe > 0,
rel, isVip, expireTime, svip, headwear, ride, wealthUserScore.Grade, charmUserScore.Grade,
activityUserScore.Grade, medals[userId], medalInfo[userId], rooms[userId], powers[userId], powerNames[userId], groupPower,
noble, superManagerMap[userId], myGroups, phoneInfo, thirdList, cvCountryManager, cp)
}
// 单用户版,简化参数
func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.UserTradeUnion, isLike bool, likeMe bool, hvMap map[mysql.ID]user_m.Relation,
isVip bool, vipExpireTime *int64, svip rpc.CvSvip, headwear *headwear_cv.CvHeadwear, ride property_cv.CvProperty, wealthGrade uint32, charmGrade uint32, activityGrade uint32,
medals []uint32, medalInfo []medal_cv.CvMedal, room string, power uint64, powerName string, groupPower rpc.CvGroupPowerInfo, noble *noble_m.UserNoble, isOfficialStaff bool,
myGroups []group_m.GroupInfo, phoneInfo *user_m.UserPhoneInfo, thirdList []int8, countryManager *user_cv.CVCountryManager, cp *user_cv.CvCp) (*user_cv.CvUserDetail, error) {
room, err := group_m.ToTxGroupId(model, room)
if err != nil {
model.Log.Warnf("ToTxGroupId failed for %s, err:%v", room, err)
room = ""
}
cvUserDetail := &user_cv.CvUserDetail{
CvUserBase: user_cv.CvUserBase{
Id: &user.ID,
Avatar: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), "", user.Avatar)),
DefaultAvatar: &user.DefaultAvatar,
ExternalId: StrToString(&user.ExternalId),
Nick: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), user.Code, user.Nick)),
Description: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), "", user.Description)),
Sex: TypeToUint8(&user.Sex),
Country: StrNil(user.Country),
CountryIcon: StrNil(user.CountryIcon),
Code: StrToString(&user.Code),
IsPrettyCode: user.IsPrettyCode(),
IsVip: isVip,
IsOfficialStaff: isOfficialStaff,
VipExpireTime: vipExpireTime,
Svip: svip,
MedalInfo: IfLogoutMedalInfo(IfLogout(user.LogoutTime), []medal_cv.CvMedal{}, medalInfo),
Headwear: IfLogoutHeadwear(IfLogout(user.LogoutTime), nil, headwear),
Ride: IfLogoutRide(IfLogout(user.LogoutTime), property_cv.CvProperty{}, ride),
},
IsPush: TypeToUint8(&user.IsPush),
IsLike: &isLike,
IsLikeMe: &likeMe,
WealthUserGrade: wealthGrade,
CharmUserGrade: charmGrade,
ActivityUserGrade: activityGrade,
CurrentRoom: room,
MyGroupPower: power,
MyGroupPowerName: powerName,
GroupPower: groupPower,
PhoneInfo: phoneInfo,
ThirdList: thirdList,
CountryManager: countryManager,
Cp: cp,
}
if noble != nil {
cvUserDetail.Noble = noble_cv.CvNoble{
Level: noble.Level,
EndTime: noble.EndTime.Unix(),
}
}
//本人,计算,喜欢统计,钻石数量
if user.ID == myUserId {
cvUserDetail.IsShowAge = TypeToUint8((*mysql.Type)(&user.IsShowAge))
cvUserDetail.Birthday = BirthdayToUint64(&user.Birthday)
//喜欢统计
var userCount user_m.UserCount
err := model.DB().Where(&user_m.UserCount{
UserId: myUserId,
Type: user_e.CountTypeLikeMe,
}).First(&userCount).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, myerr.WrapErr(err)
}
cvUserDetail.LikeCount = NumToUint32(&userCount.Num)
//我喜欢统计
var userILikeCount user_m.UserCount
err = mysql.Db.Where(&user_m.UserCount{
UserId: myUserId,
Type: user_e.CountTypeLike,
}).First(&userILikeCount).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, myerr.WrapErr(err)
}
cvUserDetail.ILikeCount = NumToUint32(&userILikeCount.Num)
//访问统计
var visitCount int64
err = mysql.Db.Model(&visit_m.UserVisit{}).Where(&visit_m.UserVisit{
VisitUserId: myUserId,
}).Count(&visitCount).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, myerr.WrapErr(err)
}
vc := uint32(visitCount)
cvUserDetail.VisitCount = NumToUint32((*mysql.Num)(&vc))
//钻石数量
cvDiamond, err := diamond_m.GetDiamondAccountByUserId(model, myUserId)
if err != nil {
return nil, err
}
cvUserDetail.DiamondNum = &cvDiamond.DiamondNum
cvUserDetail.PinkDiamondNum = &cvDiamond.PinkDiamondNum
isAgent := user_m.IsAgent(myUserId)
cvUserDetail.IsAgentMgr = &isAgent
} else {
//不是本人
if user.IsShowAge == mysql.OPEN {
cvUserDetail.Birthday = BirthdayToUint64(&user.Birthday)
}
}
if userTradeUnion == nil {
isTradeUnionFlag := false
cvUserDetail.IsTradeUnion = &isTradeUnionFlag
cvUserDetail.IsTradeUnionMatchNotification = nil
} else {
isTradeUnionFlag := true
cvUserDetail.IsTradeUnion = &isTradeUnionFlag
isTradeUnionMatchNotificationFlag := userTradeUnion.MatchNotification == mysql.OPEN
cvUserDetail.IsTradeUnionMatchNotification = &isTradeUnionMatchNotificationFlag
}
// 永恒之心的值
hv, ok := hvMap[user.ID]
if ok {
cvUserDetail.HeartValue = hv.HeartValue
cvUserDetail.HeartValueMax = hv.HeartValueMax
cvUserDetail.MeetDays = hv.MeetDays
} else {
cvUserDetail.HeartValueMax = 0
}
// 拥有的群组id
if len(myGroups) > 0 {
cvUserDetail.GroupId = myGroups[0].TxGroupId
}
return cvUserDetail, nil
}
package user_s
import (
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/cv/headwear_cv"
"hilo-user/cv/medal_cv"
"hilo-user/cv/property_cv"
"time"
)
//空字符串转成nil
func StrNil(msg string) *string {
if msg == "" {
return nil
}
return &msg
}
func TypeToUint8(t *mysql.Type) *uint8 {
if *t == 0 {
return nil
} else {
return (*uint8)(t)
}
}
func BirthdayToUint64(birthday *mysql.Timestamp) *uint64 {
if *birthday == 0 {
return nil
}
return (*uint64)(birthday)
}
func NumToUint32(num *mysql.Num) *uint32 {
return (*uint32)(num)
}
func TimeToUint64(t *time.Time) *uint64 {
a := uint64(t.Unix())
return &a
}
func StrToString(str *mysql.Str) *string {
return (*string)(str)
}
func IndexToUint16(i *mysql.Index) *uint16 {
return (*uint16)(i)
}
func IdToUint64(id *mysql.ID) *uint64 {
return (*uint64)(id)
}
func IfLogout(logoutTime int64) bool {
return logoutTime > 0 && time.Now().Unix() > logoutTime
}
func IfLogoutMedals(condition bool, trueVal, falseVal []uint32) []uint32 {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutMedalInfo(condition bool, trueVal, falseVal []medal_cv.CvMedal) []medal_cv.CvMedal {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutHeadwear(condition bool, trueVal, falseVal *headwear_cv.CvHeadwear) *headwear_cv.CvHeadwear {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutRide(condition bool, trueVal, falseVal property_cv.CvProperty) property_cv.CvProperty {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutStr(condition bool, trueVal, falseVal string) string {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutNick(condition bool, code string, nick string) string {
if condition {
return "Hilo No." + code
}
return nick
}
......@@ -28,6 +28,8 @@ func InitRouter() *gin.Engine {
{
user.GET("/nameplate", wrapper(user_r.UserNameplate))
user.GET("/bag/:resType", wrapper(user_r.UserBag))
user.GET("/detail", wrapper(user_r.UserDetail))
user.GET("/detail/:userExternalId", wrapper(user_r.UserDetailByExternalId))
}
cp := v2.Group("/cp")
{
......
package user_r
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/resource/redisCli"
"github.com/gin-gonic/gin"
"hilo-user/_const/redis_key/user_k"
"hilo-user/domain/model/group_m"
"hilo-user/domain/model/tim_m"
"hilo-user/domain/service/user_s"
"hilo-user/req"
"hilo-user/resp"
"time"
)
// @Tags 用户
// @Summary 获取用户详细信息
// @Param token header string true "token"
// @Param timestamp header string true "时间戳"
// @Param nonce header string true "随机数字"
// @Param signature header string true "sha1加密结果"
// @Param deviceType header string true "系统类型 ios android"
// @Param deviceVersion header string true "系统版本"
// @Success 200 {object} user_cv.CvUserDetail
// @Router /v1/user/detail [get]
func UserDetail(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
userId, lang, err := req.GetUserIdLang(c, myContext)
if err != nil {
return myContext, err
}
cvUserDetail, err := user_s.NewUserService(myContext).GetUserDetail(userId, userId, lang)
if err != nil {
return myContext, err
}
resp.ResponseOk(c, cvUserDetail)
return myContext, nil
}
// @Tags 用户
// @Summary 获取用户详细信息
// @Param token header string true "token"
// @Param timestamp header string true "时间戳"
// @Param nonce header string true "随机数字"
// @Param signature header string true "sha1加密结果"
// @Param deviceType header string true "系统类型 ios android"
// @Param deviceVersion header string true "系统版本"
// @Param userExternalId path string true "userExternalId"
// @Param groupId query string false "群组id,当传了该id,则返回该用户在该群组的身份"
// @Success 200 {object} user_cv.CvUserDetail
// @Router /v1/user/detail/{userExternalId} [get]
func UserDetailByExternalId(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
userId, lang, err := req.GetUserIdLang(c, myContext)
if err != nil {
return myContext, err
}
otherUserId, err := req.ToUserId(myContext, mysql.Str(c.Param("userExternalId")))
if err != nil {
return nil, err
}
model := domain.CreateModelContext(myContext)
imGroupId := c.Query("groupId")
if imGroupId != "" {
imGroupId, err = group_m.ToImGroupId(model, imGroupId)
if err != nil {
return myContext, err
}
}
cvUserDetail, err := user_s.NewUserService(myContext).GetUserDetail(otherUserId, userId, lang)
if err != nil {
return myContext, err
}
if imGroupId != "" {
cvUserDetail.GroupRole, err = group_m.GetGroupRoleById(model, imGroupId, otherUserId)
if err != nil {
return myContext, err
}
}
if cvUserDetail != nil {
// 检查是否需要同步
if n, err := redisCli.GetRedis().Exists(model, user_k.GetKeySyncTimHilo(userId)).Result(); err == nil {
if n == 0 {
// FIXME:转异步执行
err = tim_m.FlushHiloInfo(*cvUserDetail.ExternalId, cvUserDetail.IsVip, cvUserDetail.IsPrettyCode,
nil, cvUserDetail.MyGroupPowerName, cvUserDetail.Noble.Level)
if err == nil {
redisCli.GetRedis().Set(model, user_k.GetKeySyncTimHilo(userId), "1", time.Minute)
} else {
model.Log.Info("UserBaseByExternalId, FlushHiloInfo failed: ", err)
}
} else {
model.Log.Info("UserDetailByExternalId, no need to sync yet: ", userId)
}
} else {
model.Log.Info("UserDetailByExternalId, check KeySyncTimHilo failed", err)
}
}
resp.ResponseOk(c, cvUserDetail)
return myContext, nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment