From a5ad059610f0a0e3f4069edc939bb2f36d4b0098 Mon Sep 17 00:00:00 2001 From: hujiebin Date: Mon, 29 May 2023 14:05:21 +0800 Subject: [PATCH] feat:cp_cv --- _const/enum/res_e/enum.go | 43 +--- cv/cp_cv/rank.go | 11 + cv/headwear_cv/headwear.go | 148 ++++++++++++++ cv/medal_cv/medal.go | 60 ++++++ cv/noble_cv/noble.go | 89 ++++++++ cv/property_cv/property.go | 302 ++++++++++++++++++++++++++++ cv/user_cv/user.go | 300 ++++++++++++++++++++++++++- cv/user_cv/utils.go | 100 +++++++++ domain/model/res_m/country.go | 2 +- domain/model/res_m/headwear.go | 12 ++ domain/model/res_m/medal.go | 38 ++++ domain/model/res_m/property.go | 149 ++++++++++++++ domain/model/res_m/resMultiText.go | 2 +- domain/model/user_m/medal.go | 12 ++ domain/model/user_m/property.go | 30 ++- domain/model/user_m/superManager.go | 79 ++++++++ domain/model/user_m/vip.go | 21 ++ go.mod | 2 + go.sum | 88 ++++++++ myerr/bizerr/bizCode.go | 2 + route/cp_r/rank.go | 30 ++- 21 files changed, 1473 insertions(+), 47 deletions(-) create mode 100644 cv/cp_cv/rank.go create mode 100644 cv/headwear_cv/headwear.go create mode 100644 cv/medal_cv/medal.go create mode 100644 cv/noble_cv/noble.go create mode 100644 cv/property_cv/property.go create mode 100644 cv/user_cv/utils.go create mode 100644 domain/model/res_m/property.go create mode 100644 domain/model/user_m/superManager.go diff --git a/_const/enum/res_e/enum.go b/_const/enum/res_e/enum.go index ef2d565..f7bc65d 100755 --- a/_const/enum/res_e/enum.go +++ b/_const/enum/res_e/enum.go @@ -5,55 +5,16 @@ import "git.hilo.cn/hilo-common/resource/mysql" type MsgIdType = uint const ( - DEFAULT_LANG = "en" + DefaultLang = "en" ) type ResMedalType = mysql.Type - -const ( - Wealth ResMedalType = 1 - Charm ResMedalType = 2 - LoveForAll ResMedalType = 3 - StartForAll ResMedalType = 4 - MoonForAll ResMedalType = 5 - MarryMe ResMedalType = 6 - RoomRocket ResMedalType = 7 - Actity ResMedalType = 8 - FruitKing ResMedalType = 9 - BoxKing ResMedalType = 10 - Helicopter ResMedalType = 11 - Roadster ResMedalType = 12 - Watermelon ResMedalType = 13 - Kiss ResMedalType = 14 - Love ResMedalType = 15 - Chick ResMedalType = 16 - SportsCar ResMedalType = 17 - Rocket ResMedalType = 18 - Tower ResMedalType = 19 - Eagle ResMedalType = 20 - Lion ResMedalType = 21 - Vacation ResMedalType = 22 - RomanticNight ResMedalType = 23 - SweetCouple ResMedalType = 24 - Castle ResMedalType = 25 - WeddingCar ResMedalType = 26 - VideoChat ResMedalType = 27 -) - type ResMedalScope = mysql.Type - -const ( - //私有,只能时管理人发放 - Private ResMedalScope = 1 - //公有,自己获取 - Public ResMedalScope = 2 -) - type ResNameplateType = mysql.Type type ResNameplateObtainType = mysql.Type type ResNameplateScope = mysql.Type - type ResUserBag = mysql.Type +type ResPropertyAvatarType = mysql.Type const ( ResUserBagGift ResUserBag = 1 // 背包道具-礼物 diff --git a/cv/cp_cv/rank.go b/cv/cp_cv/rank.go new file mode 100644 index 0000000..df4a94a --- /dev/null +++ b/cv/cp_cv/rank.go @@ -0,0 +1,11 @@ +package cp_cv + +import "hilo-user/cv/user_cv" + +type CvCp struct { + CpId uint64 `json:"cpId"` // cpId + User1 *user_cv.CvUserBase `json:"user1"` // user1 + User2 *user_cv.CvUserBase `json:"user2"` // user2 + Score uint32 `json:"score"` // 分值 + Ranking int `json:"ranking"` // 排名 +} diff --git a/cv/headwear_cv/headwear.go b/cv/headwear_cv/headwear.go new file mode 100644 index 0000000..c009846 --- /dev/null +++ b/cv/headwear_cv/headwear.go @@ -0,0 +1,148 @@ +package headwear_cv + +import ( + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/_const/enum/headwear_e" + "hilo-user/domain/model/res_m" + "hilo-user/domain/model/user_m" + "hilo-user/myerr" + "strconv" + "time" +) + +type CvHeadwear struct { + Id uint64 `json:"id"` + Using bool `json:"using"` + PicUrl mysql.Str `json:"picUrl"` + EffectUrl mysql.Str `json:"effectUrl"` + TimeLeft int64 `json:"timeLeft"` // 离到期还有多少秒(过期则是负数) +} + +type CvHeadwearDiamond struct { + Id uint64 `json:"id"` + PicUrl string `json:"picUrl"` + EffectUrl string `json:"effectUrl"` + DiamondNum uint32 `json:"diamondNum"` + Second uint32 `json:"second"` + Days string `json:"days"` +} + +func GetCvHeadwearDiamond(pageSize int, pageIndex int) ([]CvHeadwearDiamond, error) { + headwearDiamonds := []CvHeadwearDiamond{} + if err := mysql.Db.Raw("SELECT d.id, r.pic_url, r.effect_url, d.`second`, d.diamond_num from res_headwear r, res_headwear_diamond d where r.id = d.res_headwear_id and d.`status` = ? ORDER BY d.diamond_num asc LIMIT ?, ?", mysql.USER, (pageIndex-1)*pageSize, pageSize).Scan(&headwearDiamonds).Error; err != nil { + return nil, myerr.WrapErr(err) + } + for i, _ := range headwearDiamonds { + headwearDiamonds[i].Days = strconv.FormatUint(uint64(headwearDiamonds[i].Second/(24*60*60)), 10) + } + return headwearDiamonds, nil +} + +func GetHeadwearList(db *gorm.DB, userId uint64) ([]CvHeadwear, error) { + rows := make([]user_m.UserHeadwear, 0) + if err := db.Where(&user_m.UserHeadwear{ + UserId: userId, + }).Where("end_time >= ?", time.Now()).Order("`using` DESC, updated_time DESC").Find(&rows).Error; err != nil { + return nil, err + } + resHwMap, err := res_m.GetResHeadwearMap(db) + if err != nil { + return nil, myerr.WrapErr(err) + } + + result := make([]CvHeadwear, 0) + now := time.Now() + hasUsing := false + for _, i := range rows { + // TODO: 没过期并且有设置using的,才算是,因为写入方不维护using状态的更新 + isUsing := i.Using == headwear_e.YesUsing && i.EndTime.After(now) + result = append(result, CvHeadwear{ + Id: i.HeadwearId, + PicUrl: resHwMap[i.HeadwearId].PicUrl, + EffectUrl: resHwMap[i.HeadwearId].EffectUrl, + Using: isUsing, + TimeLeft: i.EndTime.Unix() - now.Unix(), + }) + if isUsing { + hasUsing = true + } + } + // 如果没有一个using,则找第一个没过期的充当 + if ! hasUsing { + for i, e := range result { + if e.TimeLeft > 0 { + result[i].Using = true + break + } + } + } + + return result, nil +} + +func GetCvHeadwear(userId uint64) (*CvHeadwear, error) { + userHeadwear := user_m.UserHeadwear{} + if err := mysql.Db.Model(&user_m.UserHeadwear{}).Where(&user_m.UserHeadwear{ + UserId: userId, + }).Where("end_time >= ?", time.Now()).Order("`using` DESC, updated_time DESC").First(&userHeadwear).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } else { + return nil, myerr.WrapErr(err) + } + } + resHeadwear := res_m.ResHeadwear{} + if err := mysql.Db.Model(&res_m.ResHeadwear{}).First(&resHeadwear, userHeadwear.HeadwearId).Error; err != nil { + return nil, myerr.WrapErr(err) + } + return &CvHeadwear{ + Id: userHeadwear.HeadwearId, + PicUrl: resHeadwear.PicUrl, + EffectUrl: resHeadwear.EffectUrl, + Using: userHeadwear.Using == headwear_e.YesUsing, + }, nil +} + +func BatchGetCvHeadwears(userIds []uint64) (map[uint64]CvHeadwear, error) { + if len(userIds) == 0 { + return map[uint64]CvHeadwear{}, nil + } + rows := make([]user_m.UserHeadwear, 0) + //asc 进行覆盖,保证了updated_time 最大的是最后的输出 + if err := mysql.Db.Where("user_id IN ?", userIds).Where("end_time >= ?", time.Now()). + Order("`using` ASC, updated_time ASC").Find(&rows).Error; err != nil { + return nil, err + } + // + resHeadwearIds := make([]uint64, 0, len(rows)) + for i, _ := range rows { + resHeadwearIds = append(resHeadwearIds, rows[i].HeadwearId) + } + //获取头饰资源,然后转换成map结构 + resHeadwearMap := map[uint64]res_m.ResHeadwear{} + resHeadwears := []res_m.ResHeadwear{} + if err := mysql.Db.Where("id IN ?", resHeadwearIds).Find(&resHeadwears).Error; err != nil { + return nil, err + } + for i, _ := range resHeadwears { + resHeadwearMap[resHeadwears[i].ID] = resHeadwears[i] + } + + result := make(map[uint64]CvHeadwear, 0) + for _, r := range rows { + headwear, flag := resHeadwearMap[r.HeadwearId] + if flag { + result[r.UserId] = CvHeadwear{ + Id: headwear.ID, + PicUrl: headwear.PicUrl, + EffectUrl: headwear.EffectUrl, + Using: r.Using == headwear_e.YesUsing, + } + } + + } + return result, nil + +} + diff --git a/cv/medal_cv/medal.go b/cv/medal_cv/medal.go new file mode 100644 index 0000000..dca4988 --- /dev/null +++ b/cv/medal_cv/medal.go @@ -0,0 +1,60 @@ +package medal_cv + +import ( + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/domain/model/res_m" + "sort" +) + +type CvMedal struct { + Id uint32 `json:"id"` + PicUrl mysql.Str `json:"picUrl"` + EffectUrl mysql.Str `json:"effectUrl"` +} + +type ReturnGroupMedal struct { + PicUrl string `json:"picUrl"` + SvgaUrl string `json:"svgaUrl"` +} + +type PicElement struct { + PicUrl string `json:"picUrl"` + SvgaUrl string `json:"svgaUrl"` +} + +func GetMedalInfoMap(db *gorm.DB, medals map[uint64][]uint32) (map[uint64][]uint32, map[uint64][]CvMedal, error) { + resMedals, err := res_m.MedalGetAllMap(db) + if err != nil { + return nil, nil, err + } + + medalIds := make(map[uint64][]uint32) + medalMap := make(map[uint64][]CvMedal, 0) + + // 只选择合法的勋章 + for u, i := range medals { + medalIds[u] = make([]uint32, 0) + medalMap[u] = make([]CvMedal, 0) + + for _, j := range i { + if e, ok := resMedals[j]; ok { + medalIds[u] = append(medalIds[u], j) + medalMap[u] = append(medalMap[u], CvMedal{ + Id: j, + PicUrl: e.PicUrl, + EffectUrl: e.SvgaUrl, + }) + } + } + // 按照勋章排序 + sort.Slice(medalIds[u], func(i, j int) bool { + return resMedals[medalIds[u][i]].Sort < resMedals[medalIds[u][j]].Sort + }) + + sort.Slice(medalMap[u], func(i, j int) bool { + return resMedals[medalMap[u][i].Id].Sort < resMedals[medalMap[u][j].Id].Sort + }) + } + return medalIds, medalMap, nil +} diff --git a/cv/noble_cv/noble.go b/cv/noble_cv/noble.go new file mode 100644 index 0000000..39166ce --- /dev/null +++ b/cv/noble_cv/noble.go @@ -0,0 +1,89 @@ +package noble_cv + +import ( + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/domain/model/noble_m" + "hilo-user/myerr" + "time" +) + +type NobleConfig struct { + Level uint16 `json:"level"` // 贵族等级 + PurchasePrice uint32 `json:"purchasePrice"` // 购买价格 + RenewalPrice uint32 `json:"renewalPrice"` // 续费价格 + Duration uint16 `json:"duration"` // 有效期(天) + PicUrl string `json:"picUrl"` // 大图url + DailyGold uint `json:"dailyGold"` // 每日登录领取的金币 + RideId uint64 `json:"rideId"` // 赠送的勋章ID + HeaddressId uint64 `json:"headdressId"` // 赠送的头饰ID + Privileges []int `json:"privileges"` // 权益列表 +} + +type NobleInfo struct { + Level uint16 `json:"level"` // 等级 + EndTime int64 `json:"endTime"` // 截止时间 + RemainTime int64 `json:"remainTime"` // 还有多久(秒)过期,可以是负数 + Price uint32 `json:"price"` // 购买或续费价格 +} + +type CvNoble struct { + Level uint16 `json:"level"` + EndTime int64 `json:"endTime"` +} + +func GetCvNoble(userId uint64) (CvNoble, error) { + userNoble := noble_m.UserNoble{} + if err := mysql.Db.Model(&noble_m.UserNoble{}).Where(&noble_m.UserNoble{ + UserId: userId, + }).Where("end_time > ?", time.Now()).Order("level desc").First(&userNoble).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return CvNoble{ + Level: 0, + EndTime: 0, + }, nil + } else { + return CvNoble{ + Level: 0, + EndTime: 0, + }, myerr.WrapErr(err) + } + } else { + return CvNoble{ + Level: userNoble.Level, + EndTime: userNoble.EndTime.Unix(), + }, nil + } +} + +func GetCvNobles(userIds []uint64) (map[uint64]CvNoble, error) { + if len(userIds) == 0 { + return map[uint64]CvNoble{}, nil + } + var userNobles []noble_m.UserNoble + if err := mysql.Db.Model(&noble_m.UserNoble{}).Where("user_id in (?)", userIds).Where("end_time > ?", time.Now()).Order("level asc").Find(&userNobles).Error; err != nil { + return nil, err + } + + userNobleMap := map[uint64]noble_m.UserNoble{} + for i, _ := range userNobles { + userNobleMap[userNobles[i].UserId] = userNobles[i] + } + + result := map[uint64]CvNoble{} + for _, r := range userIds { + userNoble, flag := userNobleMap[r] + if flag { + result[r] = CvNoble{ + Level: userNoble.Level, + EndTime: userNoble.EndTime.Unix(), + } + } else { + result[r] = CvNoble{ + Level: 0, + EndTime: 0, + } + } + } + return result, nil +} diff --git a/cv/property_cv/property.go b/cv/property_cv/property.go new file mode 100644 index 0000000..c6af321 --- /dev/null +++ b/cv/property_cv/property.go @@ -0,0 +1,302 @@ +package property_cv + +import ( + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/_const/enum/headwear_e" + "hilo-user/domain/model/res_m" + "hilo-user/domain/model/user_m" + "hilo-user/myerr" + "strconv" + "time" +) + +type CvProperty struct { + Id uint64 `json:"id"` + PicUrl mysql.Str `json:"picUrl"` + EffectUrl mysql.Str `json:"effectUrl"` + Using bool `json:"using"` + TimeLeft int64 `json:"timeLeft"` // 离到期还有多少秒(过期则是负数) + SenderAvatar string `json:"senderAvatar"` + ReceiverAvatar string `json:"receiverAvatar"` +} + +type CvPropertyDiamond struct { + Id uint64 `json:"id"` + PicUrl string `json:"picUrl"` + EffectUrl string `json:"effectUrl"` + DiamondNum uint32 `json:"diamondNum"` + Second uint32 `json:"second"` + Days string `json:"days"` +} + +func GetCvPropertyDiamond(pageSize int, pageIndex int) ([]CvPropertyDiamond, error) { + propertyDiamonds := []CvPropertyDiamond{} + if err := mysql.Db.Raw("select d.id, r.pic_url, r.effect_url, d.`second`, d.diamond_num from res_property r, res_property_diamond d where r.id = d.res_property_id and d.`status` = ? ORDER BY d.diamond_num ASC LIMIT ?, ?", mysql.USER, (pageIndex-1)*pageSize, pageSize).Scan(&propertyDiamonds).Error; err != nil { + return nil, myerr.WrapErr(err) + } + for i, _ := range propertyDiamonds { + propertyDiamonds[i].Days = strconv.FormatUint(uint64(propertyDiamonds[i].Second/(24*60*60)), 10) + } + return propertyDiamonds, nil +} + +func GetPropertyById(resPropertyId mysql.ID) (CvProperty, error) { + resProperty := res_m.ResProperty{} + if err := mysql.Db.Model(&res_m.ResProperty{}).First(&resProperty, resPropertyId).Error; err != nil { + return CvProperty{}, err + } + + //获取座驾头像 + propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db) + if err != nil { + return CvProperty{}, err + } + + userIds := []uint64{} + for _, value := range propertieAvatarMap { + if value.SendUserId > 0 { + userIds = append(userIds, value.SendUserId) + } + if value.ReceiverUserId > 0 { + userIds = append(userIds, value.ReceiverUserId) + } + } + //获取用户信息 + users := []user_m.User{} + if err := mysql.Db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil { + return CvProperty{}, myerr.WrapErr(err) + } + userAvatarMap := map[mysql.ID]string{} + for _, r := range users { + userAvatarMap[r.ID] = r.Avatar + } + var senderAvatar string = "" + var receiverAvatar string = "" + + if propertieAvatar, flag := propertieAvatarMap[resProperty.ID]; flag { + if propertieAvatar.SendUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag { + senderAvatar = avatar + } + } + if propertieAvatar.ReceiverUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag { + receiverAvatar = avatar + } + } + } + return CvProperty{ + Id: resProperty.ID, + PicUrl: resProperty.PicUrl, + EffectUrl: resProperty.EffectUrl, + SenderAvatar: senderAvatar, + ReceiverAvatar: receiverAvatar, + }, nil +} + +func GetPropertyAll(db *gorm.DB) (map[uint64]CvProperty, error) { + rp := res_m.ResProperty{} + properties, err := rp.GetAll(mysql.Db) + if err != nil { + return nil, err + } + + //获取座驾头像 + propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db) + + userIds := []uint64{} + for _, value := range propertieAvatarMap { + 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]CvProperty{} + for _, r := range properties { + + var senderAvatar string = "" + var receiverAvatar string = "" + if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag { + if propertieAvatar.SendUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag { + senderAvatar = avatar + } + } + if propertieAvatar.ReceiverUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag { + receiverAvatar = avatar + } + } + } + + result[r.ID] = CvProperty{ + Id: r.ID, + PicUrl: r.PicUrl, + EffectUrl: r.EffectUrl, + SenderAvatar: senderAvatar, + ReceiverAvatar: receiverAvatar, + } + } + return result, nil +} + +func GetPropertyList(db *gorm.DB, userId uint64) ([]CvProperty, error) { + rows := make([]user_m.UserProperty, 0) + if err := db.Where(&user_m.UserProperty{ + UserId: userId, + }).Order("`using` DESC, updated_time DESC").Find(&rows).Error; err != nil { + return nil, err + } + rp := res_m.ResProperty{} + properties, err := rp.GetAll(mysql.Db) + if err != nil { + return nil, err + } + + //获取座驾头像 + propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db) + + userIds := []uint64{} + for _, value := range propertieAvatarMap { + 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 := make([]CvProperty, 0) + now := time.Now() + hasUsing := false + for _, i := range rows { + // TODO: 没过期并且有设置using的,才算是,因为写入方不维护using状态的更新 + isUsing := i.Using == headwear_e.YesUsing && i.EndTime.After(now) + var senderAvatar string = "" + var receiverAvatar string = "" + if propertieAvatar, flag := propertieAvatarMap[i.PropertyId]; flag { + if propertieAvatar.SendUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag { + senderAvatar = avatar + } + } + if propertieAvatar.ReceiverUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag { + receiverAvatar = avatar + } + } + } + result = append(result, CvProperty{ + Id: i.PropertyId, + PicUrl: properties[i.PropertyId].PicUrl, + EffectUrl: properties[i.PropertyId].EffectUrl, + Using: isUsing, + TimeLeft: i.EndTime.Unix() - now.Unix(), + SenderAvatar: senderAvatar, + ReceiverAvatar: receiverAvatar, + }) + if isUsing { + hasUsing = true + } + } + // 如果没有一个using,则找第一个没过期的充当 + if !hasUsing { + for i, e := range result { + if e.TimeLeft > 0 { + result[i].Using = true + break + } + } + } + return result, nil +} + +type PropertyExt struct { + Id uint64 + PicUrl mysql.Str + EffectUrl mysql.Str + Using bool + TimeLeft int64 // 离到期还有多少秒(过期则是负数) + SenderAvatar string + ReceiverAvatar string +} + +func GetExtendedProperty(db *gorm.DB) (map[uint64]PropertyExt, error) { + rp := res_m.ResProperty{} + properties, err := rp.GetAll(mysql.Db) + if err != nil { + return nil, err + } + + //获取座驾头像 + propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db) + + userIds := []uint64{} + for _, value := range propertieAvatarMap { + 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]PropertyExt{} + for _, r := range properties { + + var senderAvatar string = "" + var receiverAvatar string = "" + if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag { + if propertieAvatar.SendUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag { + senderAvatar = avatar + } + } + if propertieAvatar.ReceiverUserId > 0 { + if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag { + receiverAvatar = avatar + } + } + } + + result[r.ID] = PropertyExt{ + Id: r.ID, + PicUrl: r.PicUrl, + EffectUrl: r.EffectUrl, + SenderAvatar: senderAvatar, + ReceiverAvatar: receiverAvatar, + } + } + return result, nil +} diff --git a/cv/user_cv/user.go b/cv/user_cv/user.go index 38885db..1859632 100644 --- a/cv/user_cv/user.go +++ b/cv/user_cv/user.go @@ -1,6 +1,20 @@ package user_cv -import "hilo-user/domain/model/user_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/rpc" + "gorm.io/gorm" + "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"` @@ -27,3 +41,287 @@ func UserToTiny(user user_m.User) UserTiny { 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"` // 当前的 +} + +//批量获取用户基本信息 +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 { + 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 := 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 +} + +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 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 { + 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 +} diff --git a/cv/user_cv/utils.go b/cv/user_cv/utils.go new file mode 100644 index 0000000..827e24e --- /dev/null +++ b/cv/user_cv/utils.go @@ -0,0 +1,100 @@ +package user_cv + +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 IsInStringList(str string, list []string) bool { + for _, v := range list { + if str == v { + return true + } + } + return false +} + +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 +} +func IfLogout(logoutTime int64) bool { + return logoutTime > 0 && time.Now().Unix() > logoutTime +} + +func IfLogoutMedalInfo(condition bool, trueVal, falseVal []medal_cv.CvMedal) []medal_cv.CvMedal { + 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 IfLogoutHeadwear(condition bool, trueVal, falseVal *headwear_cv.CvHeadwear) *headwear_cv.CvHeadwear { + if condition { + return trueVal + } + return falseVal +} diff --git a/domain/model/res_m/country.go b/domain/model/res_m/country.go index 988b0fd..2bc12ec 100755 --- a/domain/model/res_m/country.go +++ b/domain/model/res_m/country.go @@ -191,7 +191,7 @@ func GetLangeByCountry(db *gorm.DB, country mysql.Str) (string, error) { if err == nil { return r.Lang, nil } else if err == gorm.ErrRecordNotFound { - return res_e.DEFAULT_LANG, nil + return res_e.DefaultLang, nil } else { return "", myerr.WrapErr(err) } diff --git a/domain/model/res_m/headwear.go b/domain/model/res_m/headwear.go index 3c02f09..39c662e 100644 --- a/domain/model/res_m/headwear.go +++ b/domain/model/res_m/headwear.go @@ -123,3 +123,15 @@ func CheckHeadwearValidById(model *domain.Model, id mysql.ID) (bool, error) { return true, nil } } + +func GetResHeadwearMap(db *gorm.DB) (map[uint64]ResHeadwear, error) { + rows := make([]ResHeadwear, 0) + if err := db.Model(&ResHeadwear{}).Find(&rows).Error; err != nil { + return nil, err + } + result := make(map[uint64]ResHeadwear, 0) + for _, i := range rows { + result[i.ID] = i + } + return result, nil +} \ No newline at end of file diff --git a/domain/model/res_m/medal.go b/domain/model/res_m/medal.go index fe7a16b..fd377e1 100755 --- a/domain/model/res_m/medal.go +++ b/domain/model/res_m/medal.go @@ -2,8 +2,10 @@ package res_m import ( "git.hilo.cn/hilo-common/resource/mysql" + "github.com/bluele/gcache" "gorm.io/gorm" "hilo-user/_const/enum/res_e" + "time" ) type ResMedal struct { @@ -41,3 +43,39 @@ func GetUserMedalLevelMap(db *gorm.DB) (map[uint64]uint8, map[uint8][]uint64, er } return medalTypes, result, nil } + +var medalCache = gcache.New(1000).LRU().Build() +var medalMapCache = gcache.New(1).LRU().Build() + +const medalKey = "MEDAL" + +// pprof看到内存分配很多 +// 加上15min lru +func MedalGetAll(db *gorm.DB) ([]ResMedal, error) { + if data, err := medalCache.Get(medalKey); err == nil { + return data.([]ResMedal), nil + } + rows := make([]ResMedal, 0) + err := db.Find(&rows).Error + if err != nil { + return nil, err + } + _ = medalCache.SetWithExpire(medalKey, rows, time.Minute*15) + return rows, nil +} + +func MedalGetAllMap(db *gorm.DB) (map[uint32]ResMedal, error) { + if data, err := medalMapCache.Get(medalKey); err == nil { + return data.(map[uint32]ResMedal), nil + } + rows, err := MedalGetAll(db) + if err != nil { + return nil, err + } + result := make(map[uint32]ResMedal, 0) + for _, i := range rows { + result[uint32(i.ID)] = i + } + _ = medalMapCache.SetWithExpire(medalKey, result, time.Minute*15) + return result, nil +} diff --git a/domain/model/res_m/property.go b/domain/model/res_m/property.go new file mode 100644 index 0000000..d390314 --- /dev/null +++ b/domain/model/res_m/property.go @@ -0,0 +1,149 @@ +package res_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/_const/enum/res_e" + "hilo-user/myerr" + "hilo-user/myerr/bizerr" +) + +type ResProperty struct { + mysql.Entity + *domain.Model `gorm:"-"` + Name mysql.Str + PicUrl mysql.Str + EffectUrl mysql.Str +} + +type ResPropertyDiamond struct { + mysql.Entity + *domain.Model `gorm:"-"` + ResPropertyId mysql.ID + DiamondNum mysql.Num + Second mysql.Num + Status mysql.UserYesNo +} + +type ResPropertyAvatar struct { + mysql.Entity + *domain.Model `gorm:"-"` + ResPropertyId mysql.ID + Type res_e.ResPropertyAvatarType + SendUserId mysql.ID + ReceiverUserId mysql.ID +} + +func InitResPropertyDiamond(model *domain.Model, resPropertyId mysql.ID, diamondNum mysql.Num, second mysql.Num) *ResPropertyDiamond { + return &ResPropertyDiamond{ + Model: model, + ResPropertyId: resPropertyId, + DiamondNum: diamondNum, + Second: second, + Status: mysql.NOUSER, + } +} + +//id获取头饰,不存在则抛异常 +func GetPropertyById(model *domain.Model, id mysql.ID) (*ResProperty, error) { + resProperty := ResProperty{} + if err := model.Db.Model(&ResProperty{}).First(&resProperty, id).Error; err != nil { + return nil, myerr.WrapErr(err) + } else { + resProperty.Model = model + return &resProperty, nil + } +} + +func GetResPropertyDiamond(model *domain.Model, resPropertyDiamondId mysql.ID) (*ResPropertyDiamond, error) { + resPropertyDiamond := ResPropertyDiamond{} + if err := model.Db.Model(&ResPropertyDiamond{}).First(&resPropertyDiamond, resPropertyDiamondId).Error; err != nil { + return nil, myerr.WrapErr(err) + } + if resPropertyDiamond.Status == mysql.NOUSER { + return nil, bizerr.ResPropertyDiamondNoUse + } + return &resPropertyDiamond, nil +} + +func GetResPropertyDiamondByPropertyIdOrNil(model *domain.Model, resPropertyId mysql.ID) (*ResPropertyDiamond, error) { + resPropertyDiamond := ResPropertyDiamond{} + if err := model.Db.Model(&ResPropertyDiamond{}).Where(&ResPropertyDiamond{ + ResPropertyId: resPropertyId, + }).First(&resPropertyDiamond).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } else { + return nil, myerr.WrapErr(err) + } + } + resPropertyDiamond.Model = model + return &resPropertyDiamond, nil +} + +//设置成未使用 +func (resPropertyDiamond *ResPropertyDiamond) SetUser() *ResPropertyDiamond { + resPropertyDiamond.Status = mysql.USER + return resPropertyDiamond +} + +//设置成未使用 +func (resPropertyDiamond *ResPropertyDiamond) SetNoUser() *ResPropertyDiamond { + resPropertyDiamond.Status = mysql.NOUSER + return resPropertyDiamond +} + +func (resPropertyDiamond *ResPropertyDiamond) SetDiamondNum(diamondNum uint32) *ResPropertyDiamond { + resPropertyDiamond.DiamondNum = diamondNum + return resPropertyDiamond +} + +func (resPropertyDiamond *ResPropertyDiamond) SetSecond(second uint32) *ResPropertyDiamond { + resPropertyDiamond.Second = second + return resPropertyDiamond +} + +func AddProperty(model *domain.Model, p *ResProperty) error { + return model.Db.Create(p).Error +} + +func EditProperty(model *domain.Model, propertyId uint64, name, picUrl, effectUrl string) error { + activityConfig := ResProperty{Entity: mysql.Entity{ID: propertyId}} + err := model.Db.First(&activityConfig).Error + if err != nil { + return err + } + activityConfig.Name = name + activityConfig.PicUrl = picUrl + activityConfig.EffectUrl = effectUrl + return model.Db.Save(&activityConfig).Error +} + +func (p *ResProperty) Get(db *gorm.DB) error { + return db.Where(p).First(p).Error +} + +func (p *ResProperty) GetAll(db *gorm.DB) (map[uint64]ResProperty, error) { + rows := make([]ResProperty, 0) + if err := db.Where(p).Find(&rows).Error; err != nil { + return nil, err + } + result := make(map[uint64]ResProperty, 0) + for _, i := range rows { + result[i.ID] = i + } + return result, nil +} + +func (p *ResPropertyAvatar) GetAll(db *gorm.DB) (map[uint64]ResPropertyAvatar, error) { + rows := make([]ResPropertyAvatar, 0) + if err := db.Where(p).Find(&rows).Error; err != nil { + return nil, myerr.WrapErr(err) + } + result := make(map[uint64]ResPropertyAvatar, 0) + for _, i := range rows { + result[i.ResPropertyId] = i + } + return result, nil +} diff --git a/domain/model/res_m/resMultiText.go b/domain/model/res_m/resMultiText.go index 59e2ded..e2f4312 100755 --- a/domain/model/res_m/resMultiText.go +++ b/domain/model/res_m/resMultiText.go @@ -27,7 +27,7 @@ func GetResMultiTextBy(db *gorm.DB, msgId uint, Language mysql.Str) (*ResMultiTe if err == gorm.ErrRecordNotFound { if err := db.Where(&ResMultiText{ MsgId: msgId, - Language: res_e.DEFAULT_LANG, + Language: res_e.DefaultLang, }).First(&r).Error; err != nil { return nil, myerr.WrapErr(err) } diff --git a/domain/model/user_m/medal.go b/domain/model/user_m/medal.go index aa0184a..9712bb4 100755 --- a/domain/model/user_m/medal.go +++ b/domain/model/user_m/medal.go @@ -89,3 +89,15 @@ func GetUserMedal(db *gorm.DB, userId mysql.ID) ([]uint32, error) { } return result, nil } + +func BatchGetUserMedalMerge(logger *logrus.Entry, db *gorm.DB, userIds []mysql.ID) (map[uint64][]uint32, error) { + result := make(map[uint64][]uint32, 0) + for _, u := range userIds { + a, err := GetUserMedalMerge(logger, db, u) + if err != nil { + return nil, err + } + result[u] = a + } + return result, nil +} diff --git a/domain/model/user_m/property.go b/domain/model/user_m/property.go index 17a0325..c5a80cf 100644 --- a/domain/model/user_m/property.go +++ b/domain/model/user_m/property.go @@ -108,4 +108,32 @@ type UserPropertyLog struct { Type property_e.UserPropertyLogType AddSecond *mysql.Num UpdateEndTime *time.Time -} \ No newline at end of file +} + +func (userProperty *UserProperty) BatchGet(db *gorm.DB, userIds []uint64) (map[uint64]uint64, error) { + rows := make([]UserProperty, 0) + if err := db.Model(userProperty). + Where("end_time > NOW() AND user_id IN ?", userIds).Order("id DESC").Find(&rows).Error; err != nil { + return nil, err + } + result := make(map[uint64]uint64, 0) + tmp := make(map[uint64]uint64, 0) + for _, i := range rows { + if _, ok := result[i.UserId]; !ok { + if i.Using == property_e.YesUsing { + // using = true且id最大,就确定是当前使用的 + result[i.UserId] = i.PropertyId + } else if _, ok := tmp[i.UserId]; !ok { + // using = false且id最大,先记下,因为不知道还有没有using=true的 + tmp[i.UserId] = i.PropertyId + } + } + } + for k, v := range tmp { + // result中没有的,就采用tmp保存的 + if _, ok := result[k]; !ok { + result[k] = v + } + } + return result, nil +} diff --git a/domain/model/user_m/superManager.go b/domain/model/user_m/superManager.go new file mode 100644 index 0000000..12e4483 --- /dev/null +++ b/domain/model/user_m/superManager.go @@ -0,0 +1,79 @@ +package user_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/myerr" + "strings" +) + +type SuperManager struct { + mysql.Entity + *domain.Model `gorm:"-"` + UserId mysql.ID + IsAll bool + Countries string +} + +func IsSuperManager(model *domain.Model, userId mysql.ID) (bool, error) { + var n int64 + if err := model.Db.Model(&SuperManager{}).Where(&SuperManager{ + UserId: userId, + }).Count(&n).Error; err != nil { + return false, myerr.WrapErr(err) + } + return n > 0, nil +} + +// 对某人是否有超管权限 +func IsSuperManagerV2(model *domain.Model, userId, targetUserId mysql.ID) (bool, error) { + var man SuperManager + if err := model.Db.Model(&SuperManager{}).Where(&SuperManager{ + UserId: userId, + }).First(&man).Error; err != nil { + if err != gorm.ErrRecordNotFound { + model.Log.Errorf("IsSuperManagerV2 fail:%v", err) + } + return false, nil + } + if man.IsAll { + return true, nil + } + targetUser, err := GetUser(model, targetUserId) + if err != nil { + return false, err + } + countries := strings.Split(man.Countries, ",") + for _, c := range countries { + if c == targetUser.Country { + return true, nil + } + } + return false, nil +} + +func GetSuperManagerAll(model *domain.Model) ([]uint64, error) { + var superManagers []SuperManager + if err := model.Db.Model(&SuperManager{}).Find(&superManagers).Error; err != nil { + return nil, myerr.WrapErr(err) + } + userIds := make([]uint64, 0, len(superManagers)) + for i, _ := range superManagers { + userIds = append(userIds, superManagers[i].UserId) + } + return userIds, nil +} + +/* +func GetSuperManagerMap(model *domain.Model) (map[uint64]struct{}, error) { + userIds, err := GetSuperManagerAll(model) + if err != nil { + return nil, err + } + userIdMap := map[uint64]struct{}{} + for i, _ := range userIds { + userIdMap[userIds[i]] = struct{}{} + } + return userIdMap, nil +}*/ diff --git a/domain/model/user_m/vip.go b/domain/model/user_m/vip.go index 1b469a4..2274d56 100755 --- a/domain/model/user_m/vip.go +++ b/domain/model/user_m/vip.go @@ -43,3 +43,24 @@ func GetVip(db *gorm.DB, userId uint64) (*UserVip, error) { } return nil, nil } + +func BatchGetVips(userIds []uint64) (map[uint64]*int64, error) { + rows := make([]UserVip, 0) + err := mysql.Db.Where("user_id IN ?", userIds).Find(&rows).Error + if err != nil { + return nil, err + } + + result := make(map[uint64]*int64, 0) + for _, i := range userIds { + result[i] = nil + } + now := time.Now() + for _, i := range rows { + if i.ExpireAt.After(now) { + ts := i.ExpireAt.Unix() + result[i.UserId] = &ts + } + } + return result, nil +} diff --git a/go.mod b/go.mod index 1c2ca0b..09851b8 100644 --- a/go.mod +++ b/go.mod @@ -70,6 +70,8 @@ require ( golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/text v0.3.6 // indirect golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 // indirect + google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect + google.golang.org/grpc v1.42.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 1c180d3..71c73f3 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -10,6 +12,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1274 h1:u48e7I7h/BY5uDP8xiIFNaUkdTVk7hjj/Sucg8FrxNU= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1274/go.mod h1:9CMdKNL3ynIGPpfTcdwTvIm8SGuAZYYC4jFVSSvE1YQ= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -18,8 +21,17 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -28,6 +40,12 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -73,17 +91,35 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.7.0 h1:tGs8Oep67r8CcA2Ycmb/8BLBcJ70St44mF2X10a/qPg= github.com/hashicorp/consul/api v1.7.0/go.mod h1:1NSuaUUkFaJzMasbfq/11wKYWSR67Xn6r2DXKhuDNFg= github.com/hashicorp/consul/sdk v0.6.0 h1:FfhMEkwvQl57CildXJyGHnwGGM4HMODGyfjGwNM1Vdw= @@ -200,10 +236,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= @@ -220,6 +258,7 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= @@ -237,14 +276,24 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -253,11 +302,17 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -272,6 +327,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= @@ -282,7 +338,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -291,6 +351,31 @@ golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= @@ -306,6 +391,7 @@ gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -316,3 +402,5 @@ gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/myerr/bizerr/bizCode.go b/myerr/bizerr/bizCode.go index ba8f1c9..326be31 100755 --- a/myerr/bizerr/bizCode.go +++ b/myerr/bizerr/bizCode.go @@ -19,4 +19,6 @@ var ( DiamondNoEnough = myerr.NewBusinessCode(4000, "Insufficient diamonds", myerr.BusinessData{}) DiamondFrequency = myerr.NewBusinessCode(4001, "Diamond operation frequency too high", myerr.BusinessData{}) DiamondAccountFrozen = myerr.NewBusinessCode(4004, "Diamond Account Frozen", myerr.BusinessData{}) + + ResPropertyDiamondNoUse = myerr.NewBusinessCode(5004, "Property can not buy", myerr.BusinessData{}) //头饰不能买 ) diff --git a/route/cp_r/rank.go b/route/cp_r/rank.go index e0c5608..64183f4 100644 --- a/route/cp_r/rank.go +++ b/route/cp_r/rank.go @@ -3,8 +3,11 @@ package cp_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" "github.com/jinzhu/now" + "hilo-user/cv/cp_cv" + "hilo-user/cv/user_cv" "hilo-user/domain/model/cp_m" "hilo-user/myerr/bizerr" "hilo-user/req" @@ -19,10 +22,14 @@ import ( // @Param pageIndex query int true "偏移值 默认:1" default(1) // @Param pageSize query int true "请求数量 默认:10" default(10) // @Param queryType path string true "类型:day/week/month" -// @Success 200 +// @Success 200 {object} []cp_cv.CvCp // @Router /v2/cp/rank/{queryType} [get] func CpRank(c *gin.Context) (*mycontext.MyContext, error) { myCtx := mycontext.CreateMyContext(c.Keys) + userId, err := req.GetUserId(c) + if err != nil { + return myCtx, err + } pageReq := new(req.PageReqBase) if err := c.ShouldBindQuery(pageReq); err != nil { return myCtx, err @@ -48,6 +55,25 @@ func CpRank(c *gin.Context) (*mycontext.MyContext, error) { offset, limit := (pageReq.PageIndex-1)*pageReq.PageSize, pageReq.PageSize model := domain.CreateModelContext(myCtx) ranks := cp_m.PageCpDayRank(model, beginDate, endDate, offset, limit) - resp.ResponsePageBaseOk(c, ranks, pageReq.PageIndex+1, len(ranks) < pageReq.PageSize) + var response []cp_cv.CvCp + var userIds []mysql.ID + for _, rank := range ranks { + userIds = append(userIds, rank.UserId1) + userIds = append(userIds, rank.UserId2) + } + userBase, err := user_cv.GetUserBaseMap(userIds, userId) + if err != nil { + return myCtx, err + } + for i, rank := range ranks { + response = append(response, cp_cv.CvCp{ + CpId: rank.CpId, + User1: userBase[rank.UserId1], + User2: userBase[rank.UserId2], + Score: rank.Score, + Ranking: i + 1 + offset, + }) + } + resp.ResponsePageBaseOk(c, response, pageReq.PageIndex+1, len(ranks) < pageReq.PageSize) return myCtx, nil } -- 2.22.0