Commit 3566534b authored by hujiebin's avatar hujiebin

Feature/3.5

parent 8a1cdc0b
...@@ -3,7 +3,7 @@ package country_e ...@@ -3,7 +3,7 @@ package country_e
import "git.hilo.cn/hilo-common/resource/mysql" import "git.hilo.cn/hilo-common/resource/mysql"
// 国家角色 // 国家角色
type CountryMgrRole mysql.Type type CountryMgrRole uint8
const ( const (
// 国家管理员 // 国家管理员
......
...@@ -22,6 +22,17 @@ const ( ...@@ -22,6 +22,17 @@ const (
GroupPowerUserRoleUser GroupPowerUserRole = 1 GroupPowerUserRoleUser GroupPowerUserRole = 1
//势力主 //势力主
GroupPowerUserRoleMgr GroupPowerUserRole = 2 GroupPowerUserRoleMgr GroupPowerUserRole = 2
//势力管理员
GroupPowerUserRoleAdmin GroupPowerUserRole = 3
)
//国家势力排行榜类型
type GroupPowerRankType = mysql.Type
const (
GroupPowerRankTypeFamous GroupPowerRankType = 1
GroupPowerRankTypeActive GroupPowerRankType = 2
GroupPowerRankTypeCharm GroupPowerRankType = 3
) )
//国家势力日志操作类型 //国家势力日志操作类型
......
package groupPower_e
import "git.hilo.cn/hilo-common/resource/mysql"
type GroupPowerGrade int
const (
GroupPowerGrade0 GroupPowerGrade = 0 // 青铜
GroupPowerGrade1 GroupPowerGrade = 1 // 白银
GroupPowerGrade2 GroupPowerGrade = 2 // 黄金
GroupPowerGrade3 GroupPowerGrade = 3 // 黑金
GroupPowerGradeMax = GroupPowerGrade3
)
var (
GroupPowerGradeExp = map[GroupPowerGrade]mysql.Num{
GroupPowerGrade0: 0,
GroupPowerGrade1: 2500000,
GroupPowerGrade2: 15000000,
GroupPowerGrade3: 60000000,
}
)
type GroupPowerPrivilege int
const (
GroupPowerPrivilegeMemberNum GroupPowerPrivilege = 1 // 成员数
GroupPowerPrivilegeMgrNum GroupPowerPrivilege = 2 // 管理员数
GroupPowerPrivilegeNameplate GroupPowerPrivilege = 3 // 家族铭牌
GroupPowerPrivilegeMedal GroupPowerPrivilege = 4 // 家族徽章装饰
GroupPowerPrivilegeNameplateEdit GroupPowerPrivilege = 5 // 编辑铭牌
GroupPowerPrivilegeNameplateHeadwear GroupPowerPrivilege = 6 // 家族头饰
)
package groupPower_e
type GroupPowerStarType int
const (
GroupPowerStarTypeFamous GroupPowerStarType = 1 // 送礼
GroupPowerStarTypeActive GroupPowerStarType = 2 // 活跃
GroupPowerStarTypeCharm GroupPowerStarType = 3 // 收礼
)
func IsGroupPowerStarType(t GroupPowerStarType) bool {
if t != GroupPowerStarTypeFamous && t != GroupPowerStarTypeActive && t != GroupPowerStarTypeCharm {
return false
}
return true
}
...@@ -131,6 +131,8 @@ const ( ...@@ -131,6 +131,8 @@ const (
NewUserRegisterPush2 = 45 // 邀请朋友来Hilo,最高获得100,000钻石奖励! NewUserRegisterPush2 = 45 // 邀请朋友来Hilo,最高获得100,000钻石奖励!
NewUserRegisterPush3 = 46 // 举办首个活动,领取10,000钻石和35%奖杯奖励! NewUserRegisterPush3 = 46 // 举办首个活动,领取10,000钻石和35%奖杯奖励!
ActFruitPutRankAward = 47 // 水果机投入排行榜提醒领奖 ActFruitPutRankAward = 47 // 水果机投入排行榜提醒领奖
GroupPowerUpgrade = 48 // 家族升级
GroupPowerExpireNotice = 49 // 家族等级即将过期(每月20日)
) )
type MsgSysUserType = mysql.Type type MsgSysUserType = mysql.Type
......
package common
type MsgIdType = uint
type OnlineStatusType = uint
type GroupRoleType = uint16
type AddGroupResultType = uint
const (
APP_KICKOFF_TIME = "2020-12-19"
DEFAULT_LANG = "en"
DEFAULT_COUNTRY = "KSA"
DEFAULT_NICK = "Hilo No.%s"
DEFAULT_DESCRIPTION = "Welcome to Hilo"
DEFAULT_GROUP_NAME = "Hilo Group NO.%s"
DefaultAvatarMan = "hilo/manager/ea48b62d54a24a709de3c38702c89995.png"
DefaultAvatarWoman = "hilo/manager/ea48b62d54a24a709de3c38702c89995.png"
// 用户视频最低要求时长
BASIC_VIDEO_TIME = 1
// 公会用户视频最低要求时长
GUILD_USER_VIDEO_TIME = 15
STATUS_IN_USE = 1
STATUS_UNUSED = 2
// 公会用户是否打开通知
GuildUserNotifyOn = 1
GuildUserNotifyOff = 2
// 平台
PlatformIOS = 1
PlatformGOOGLE = 2
PlatformEggPlant = 3 // 通过starchat回调的茄子充值
PlatformCheckout = 4
// 加、减
DIRECTION_ADD = 1
DIRECTION_REDUCE = 2
// 操作类型
//发送礼物
OPERATE_TYPE_SENDGIFT = 1
//匹配条件
OPERATE_TYPE_MATCHCONDITION = 2
//建立融云会话
OPERATE_TYPE_SESSIONPAY = 3
//购买钻石
OPERATE_TYPE_BUYDIAMOND = 4
//接受礼物
OPERATE_TYPE_RECEIVEGIFT = 5
//注册
OPERATE_TYPE_REGISTER = 6
//平台赠送
OPERATE_TYPE_MGRSEND = 8
MATCH_CONFIRM_SUCCESS = 1
MATCH_CONFIRM_FAIL = 2
MATCH_CONFIRM_TEMP = 3
ACCEPT_MATCH_CONFIRM = 1
REFUSE_MATCH_CONFIRM = 2
// 视频通话是否达标
VIDEO_EFFECTIVE_YES = 1
VIDEO_EFFECTIVE_NO = 2
// 最大用户相册数
USER_PHOTO_MAX = 9
// 上下架状态
SWITCH_ON = 1
SWITH_OFF = 0
// 群组角色
GROUP_VISITOR GroupRoleType = 0 // 游客
GROUP_MEMBER GroupRoleType = 1 // 成员
GROUP_ADMIN GroupRoleType = 10 // 管理员
GROUP_MANAGER GroupRoleType = 50 // 经理
GROUP_OWNER GroupRoleType = 100 // owner
ROOM_PASSWORD_LENGTH = 4
CREATE_GROUP_MAX_ATTEMPT = 10
// 在线状态
IM_STATUS_OFF_LINE OnlineStatusType = 0
IM_STATUS_PUSH_ON_LINE OnlineStatusType = 1
IM_STATUS_ON_LINE OnlineStatusType = 2
MSG_ID_GROUP_NAME MsgIdType = 101
MSG_ID_GROUP_INTRODUCTION MsgIdType = 102
MSG_ID_GROUP_NOTIFICATION MsgIdType = 103
MSG_ID_GROUP_WELCOME MsgIdType = 104
MSG_ID_GROUP_INVITE MsgIdType = 105
MSG_ID_GROUP_LEAVE_POWER MsgIdType = 106
MSG_ID_ALL_GROUP_ROCKET MsgIdType = 107
MSG_ID_ROOM_MEADAL MsgIdType = 108
MSG_ID_VIDEO_PUSH_TITITLE MsgIdType = 109
MSG_ID_VIDEO_PUSH_CONTENT MsgIdType = 110
MSG_ID_REPEAT_ACCOUNT MsgIdType = 111
MSG_ID_USER_TRANSFER MsgIdType = 114
MSG_ID_NO_POWER_TO_SVIP6 MsgIdType = 115 // 不能对svip6做某些动作
// ps:116-138 在hilo-finance定义了!
MSG_ID_NOT_FAMILY_MEMBER MsgIdType = 165 // 非家族成员
MSG_ID_DEALER_CAN_NOT_SOLE MsgIdType = 166 // 此用户已有家族代理,不能出售钻石
MSG_ID_BUY_FROM_FAMILY MsgIdType = 167 // 请向本家族代理购买钻石
MSG_ID_NEED_JOIN_FAMILY MsgIdType = 168 // 请加入代理的家族后进行购买
ADD_GROUP_FAILED AddGroupResultType = 0
ADD_GROUP_DONE AddGroupResultType = 1
ADD_GROUP_DUPLICATE AddGroupResultType = 2
ADD_GROUP_PENDING AddGroupResultType = 3
SETTING_OFFICIAL = 1
SETTING_CUSTOMIZED = 2
)
var USER_QPS_DEFAULT_MAX int64 = 15
var HEART_VALUE_MAX uint32 = 2000
var BUILDBOARD_SMALL_SIZE = 30
var BUILDBOARD_SIZE = 50
var GROUP_CREATE_LIMIT = 1
var GROUP_NAME_LENGTH_LIMIT = 30
var GROUP_INTRODUCTION_LENGTH_LIMIT = 500
var GROUP_NOTIFICATION_LENGTH_LIMIT = 150
var MAX_BEAUTIFUL_CODE_LENGTH = 8
var GROUP_DEFAULT_CODE_LENGTH uint16 = 8
var GROUP_DEFAULT_JOIN_LIMIT uint = 200
var GROUP_VIP_JOIN_LIMIT uint = 500
var GROUP_NOBLE4_JOIN_LIMIT uint = 1000
var GROUP_MANAGER_LIMIT uint = 30
var GROUP_ADMIN_LIMIT uint = 50
var GROUP_ROLE_VIEW_LIMIT = 10
var GROUP_ROLE_PERSONAL_VIEW_LIMIT = 5
var GROUP_RECOMMEND_SIZE = 5
var IM_INVALID_USER = "@TLS#NOT_FOUND"
// TIM相关常量
const (
SYNC_TO_SENDER = 1
NOSYNC_TO_SENDER = 2
TAG_PROFILE_IM_LEVEL = "Tag_Profile_IM_Level"
TAG_PROFILE_IM_NICK = "Tag_Profile_IM_Nick"
TAG_PROFILE_IM_IMAGE = "Tag_Profile_IM_Image"
TAG_PROFILE_IM_HILO = "Tag_Profile_Custom_Hilo"
)
// 群组内游戏相关
const (
GROUP_DICE_NUM_DEFAULT = 5
GROUP_DICE_NUM_MAX = 5
)
var PAY_TEST_USERS = []uint64{11, 21, 41, 71, 151, 251, 291, 881, 1041, 4411, 951, 24091}
var ROCKET_STAGE_NUM uint16 = 3
var ROCKET_STAGE_CHANGE_THRESHOLD = 10
var ROCKET_SHOW_DURATION = 10
// RocketAwardType
const (
ROCKET_AWARD_GUEST_DIAMOND = 0 // 观众分到小额钻石
ROCKET_AWARD_PROPERTY = 1 // TOP6抽到的座驾
ROCKET_AWARD_HEADDRESS = 2 // TOP6抽到的头饰
ROCKET_AWARD_DIAMOND = 3 // TOP6抽到的钻石
)
const DefaultMinimalVersionAndroid = 100
const DefaultMinimalVersionIOS = 100
const DefaultMsgParallelSize = 20
const OldGroupNamePrefix = "@TGS#"
const NewGroupNamePrefix = "HTGS#"
const OverseaGroupNamePrefix = NewGroupNamePrefix + "a"
const (
SendSmsCodeIpMaxHourTimes = 20
SendSmsCodeImeiMaxHourTimes = 10
SendSmsCodePhoneMaxHourTimes = 5
SendSmsCodeUserMaxHourTimes = 3
SendSmsCodeLen = 6 // 验证码长度
SendSmsCodeMaxCheckTimes = 3 // 验证码最大校验次数
SendSmsCodeNoUserIdMaxHourTimes = 1000 // 没有传userId调用发短信,5分钟最大次数
CallbackCheckoutPaySucceed = "payment_captured" // checkout回调支付成功
// ranking
RankingDay = "day"
RankingWeek = "week"
RankingMonth = "month"
RankingAll = "all"
// ranking module
RankingModulePinkDiamond = "pinkDiamond"
// giftwall 礼物墙
GiftWallInitNum = 15000 // 礼物墙初始化数量
GiftWallInitOnceSetNum = 500 // 礼物墙初始化,一次插入的数量
GiftWallStartReduceNum = 20000 // 礼物墙触发清理逻辑数量
GiftWallReduceNum = 3000 // 礼物墙触发清理逻辑,清理的数量
)
package common
import (
"git.hilo.cn/hilo-common/resource/config"
"strings"
)
// 去除slice中的重复元素
func UniqueSliceUInt64(sliceIn []uint64) []uint64 {
sliceOut := make([]uint64, 0, len(sliceIn))
m := make(map[uint64]struct{}, len(sliceIn))
for _, i := range sliceIn {
if _, ok := m[i]; !ok {
m[i] = struct{}{}
sliceOut = append(sliceOut, i)
}
}
return sliceOut
}
// 补全url,区分处理oss和aws两种情况
func MakeFullUrl(url string) string {
if strings.HasPrefix(url, config.GetConfigOss().OSS_CDN) || strings.HasPrefix(url, config.GetConfigAws().AWS_CDN) {
return url
} else if strings.HasPrefix(url, "nextvideo/") {
return config.GetConfigOss().OSS_CDN + url
} else if strings.HasPrefix(url, config.GetConfigAws().AWS_DIR) {
return config.GetConfigAws().AWS_CDN + url
} else {
return url
}
}
func PageNext(total int64, pageIndex, pageSize int) (int, bool) {
var nextIdx int
var hasNext bool
if total >= int64(pageIndex+pageSize) {
hasNext = true
nextIdx = pageIndex + pageSize
}
return nextIdx, hasNext
}
package utime
import (
"github.com/jinzhu/now"
"time"
)
const (
Day = 86400
Layout = "2006-01-02 15:04:05"
LayoutDay = "2006-01-02"
LayoutDay2 = "20060102"
LayoutMonth = "2006-01"
LayoutMinute = "2006-01-02 15:04"
)
// 获取时间所在周的第一天(周一) 00:00:00,和最后一天(周日)23:59:59
func WeekStartEnd(date time.Time) (start, end time.Time) {
w := 0
week := date.Weekday()
if week == time.Sunday {
w = 7
} else {
w = int(week)
}
startTmp := date.AddDate(0, 0, -w+1)
endTmp := date.AddDate(0, 0, 7-w)
start = time.Date(startTmp.Year(), startTmp.Month(), startTmp.Day(), 0, 0, 0, 0, startTmp.Location())
end = time.Date(endTmp.Year(), endTmp.Month(), endTmp.Day(), 23, 59, 59, 999, endTmp.Location())
return
}
// 当天开始结束
func DayStartEnd(date time.Time) (start, end time.Time) {
start = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
end = time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 999, date.Location())
return
}
// 获取时间所在月的第一天(1号) 00:00:00,和最后一天23:59:59
func MonthStartEnd(date time.Time) (start, end time.Time) {
start = time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location())
lastDay := now.New(start).EndOfMonth().Day()
end = time.Date(date.Year(), date.Month(), lastDay, 23, 59, 59, 999999999, date.Location())
return
}
// 增加年/月
// 因为golang原生的Time.AddDate增加月份的时候有bug
func AddDate(t time.Time, years int, months int) time.Time {
year, month, day := t.Date()
hour, min, sec := t.Clock()
// firstDayOfMonthAfterAddDate: years 年,months 月后的 那个月份的1号
firstDayOfMonthAfterAddDate := time.Date(year+years, month+time.Month(months), 1,
hour, min, sec, t.Nanosecond(), t.Location())
// firstDayOfMonthAfterAddDate 月份的最后一天
lastDay := now.New(firstDayOfMonthAfterAddDate).EndOfMonth().Day()
// 如果 t 的天 > lastDay,则设置为lastDay
// 如:t 为 2020-03-31 12:00:00 +0800,增加1个月,为4月31号
// 但是4月没有31号,则设置为4月最后一天lastDay(30号)
if day > lastDay {
day = lastDay
}
return time.Date(year+years, month+time.Month(months), day,
hour, min, sec, t.Nanosecond(), t.Location())
}
...@@ -3,6 +3,8 @@ package cron ...@@ -3,6 +3,8 @@ package cron
import ( import (
"git.hilo.cn/hilo-common/resource/config" "git.hilo.cn/hilo-common/resource/config"
"hilo-group/cron/gift_cron" "hilo-group/cron/gift_cron"
"hilo-group/cron/group_cron"
"hilo-group/cron/mic_cron"
) )
func Init() { func Init() {
...@@ -11,4 +13,6 @@ func Init() { ...@@ -11,4 +13,6 @@ func Init() {
} }
gift_cron.SendGiftEventInit() // 礼物消息 gift_cron.SendGiftEventInit() // 礼物消息
gift_cron.GiftRemark() // 礼物消息补偿 gift_cron.GiftRemark() // 礼物消息补偿
mic_cron.OnMicCheck() // 检查上麦
group_cron.GroupPowerExpClear() // 清理家族经验/等级
} }
package group_cron
import (
"git.hilo.cn/hilo-common/domain"
"github.com/robfig/cron"
"hilo-group/domain/event/group_power_ev"
"hilo-group/domain/model/groupPower_m"
)
// 清理家族经验和等级
func GroupPowerExpClear() {
c := cron.New()
// 每月1号0:00经验值清零
spec := "0 0 0 1 * ?"
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
if err := groupPower_m.ClearGroupPowerExp(model); err != nil {
model.Log.Errorf("ClearGroupPowerExp fail:%v", err)
}
})
// 每分钟清理过期家族等级
spec = "0 * * * * ?"
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
if err := groupPower_m.ClearGroupPowerGrade(model); err != nil {
model.Log.Errorf("ClearGroupPowerGrade fail:%v", err)
}
})
// 每月20号发家族即将过期通知
spec = "0 0 0 20 * ?"
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
_ = group_power_ev.PublishGroupPowerExpireNotice(model, &group_power_ev.GroupPowerExpireNoticeEvent{})
})
c.Start()
}
package mic_cron
import (
"git.hilo.cn/hilo-common/domain"
"github.com/robfig/cron"
"hilo-group/domain/event/mic_ev"
"hilo-group/domain/model/group_m"
)
func OnMicCheck() {
c := cron.New()
//一分钟执行一次
spec := "0 */1 * * * ?"
_ = c.AddFunc(spec, func() {
//获取麦上的所有人
var model = domain.CreateModelNil()
groupIds, err := group_m.GetMicHasInGroups()
if err != nil {
model.Log.Errorf("cron micIn GetMicHasInGroups err:%v", err)
return
}
for _, groupId := range groupIds {
//遍历每个麦位
for i := 1; i <= 30; i++ {
micUser, err := group_m.GetMicUser(model, groupId, i)
if err != nil {
model.Log.Errorf("cron micIn group_m.GetMicUser err:%v", err)
}
if micUser != nil {
if err := mic_ev.PublishOnMicEvent(model, &mic_ev.OnMicEvent{
GroupUuid: micUser.GroupUuid,
I: micUser.I,
ExternalId: micUser.ExternalId,
UserId: micUser.UserId,
Forbid: micUser.Forbid,
Timestamp: micUser.Timestamp,
}); err != nil {
model.Log.Errorf("PublishOnMicEvent fail:%v", err)
}
}
}
}
})
c.Start()
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/utils" "git.hilo.cn/hilo-common/utils"
"hilo-group/_const/enum/game_e" "hilo-group/_const/enum/game_e"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/_const/enum/group_e" "hilo-group/_const/enum/group_e"
"hilo-group/_const/enum/online_e" "hilo-group/_const/enum/online_e"
"hilo-group/cv/billboard_cv" "hilo-group/cv/billboard_cv"
...@@ -43,7 +44,7 @@ type GroupBasicInfo struct { ...@@ -43,7 +44,7 @@ type GroupBasicInfo struct {
//1:5人 2:10人 //1:5人 2:10人
MicNumType int `json:"micNumType"` MicNumType int `json:"micNumType"`
// N天内的进入用户数量(重复进入去重,实时) // N天内的进入用户数量(重复进入去重,实时)
GroupInUserDuration int64 `json:"groupInUserDuration"` GroupInUserDuration int64 `json:"groupInUserDuration"` // 群热度
GroupMedals []medal_cv.PicElement `json:"groupMedals"` // 群勋章 GroupMedals []medal_cv.PicElement `json:"groupMedals"` // 群勋章
TouristMic uint8 `json:"touristMic"` // 游客是否能上麦 TouristMic uint8 `json:"touristMic"` // 游客是否能上麦
TouristSendMsg uint8 `json:"touristSendMsg"` // 游客是否能发言 TouristSendMsg uint8 `json:"touristSendMsg"` // 游客是否能发言
...@@ -60,6 +61,13 @@ type MemberListInfo struct { ...@@ -60,6 +61,13 @@ type MemberListInfo struct {
// AppMemberDefinedData": [ // 群成员自定义字段 【暂时不用】 // AppMemberDefinedData": [ // 群成员自定义字段 【暂时不用】
} }
type GroupPower struct {
Id uint64 `json:"id"` // 群主所在的势力ID
Name string `json:"name"` // 群主所在的势力的名称
Nameplate string `json:"nameplate"` // 势力铭牌
Grade groupPower_e.GroupPowerGrade `json:"grade"` // 等级
}
type GroupInfo struct { type GroupInfo struct {
GroupBasicInfo GroupBasicInfo
...@@ -68,6 +76,8 @@ type GroupInfo struct { ...@@ -68,6 +76,8 @@ type GroupInfo struct {
HasOnMic bool `json:"hasOnMic"` // 房间麦上是否有人 HasOnMic bool `json:"hasOnMic"` // 房间麦上是否有人
GroupPowerId uint64 `json:"groupPowerId"` // 群主所在的势力ID GroupPowerId uint64 `json:"groupPowerId"` // 群主所在的势力ID
GroupPowerName string `json:"groupPowerName"` // 群主所在的势力的名称 GroupPowerName string `json:"groupPowerName"` // 群主所在的势力的名称
GroupPowerNameplate string `json:"groupPowerNameplate"` // 势力铭牌
GroupPower GroupPower `json:"groupPower"` // 势力信息
// "AppDefinedData": 群组维度的自定义字段 【暂时不用】 // "AppDefinedData": 群组维度的自定义字段 【暂时不用】
MemberList []MemberListInfo MemberList []MemberListInfo
...@@ -312,7 +322,7 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [ ...@@ -312,7 +322,7 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [
for _, i := range groupIds { for _, i := range groupIds {
owners = append(owners, groupInfo[i].Owner) owners = append(owners, groupInfo[i].Owner)
} }
powerIds, powerNames, err := group_power_cv.BatchGetGroupPower(model.Db, owners) powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
...@@ -391,6 +401,13 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [ ...@@ -391,6 +401,13 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [
HasOnMic: len(micUsers) > 0, HasOnMic: len(micUsers) > 0,
GroupPowerId: powerIds[g.Owner], GroupPowerId: powerIds[g.Owner],
GroupPowerName: powerNames[g.Owner], GroupPowerName: powerNames[g.Owner],
GroupPowerNameplate: powerNameplates[g.Owner],
GroupPower: GroupPower{
Id: powerIds[g.Owner],
Name: powerNames[g.Owner],
Nameplate: powerNameplates[g.Owner],
Grade: powerGrades[g.Owner],
},
}, },
MicUsers: micUsers, MicUsers: micUsers,
RoomUserCount: uint(roomCount[i]), RoomUserCount: uint(roomCount[i]),
...@@ -404,6 +421,175 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [ ...@@ -404,6 +421,175 @@ func BuildJoinedGroupInfo(myService *domain.Service, myUserId uint64, groupIds [
return result, len(groupInfo), nil return result, len(groupInfo), nil
} }
func BuildPopularGroupInfo(model *domain.Model, myUserId uint64, groupInfo []*group_m.GroupInfo) ([]*PopularGroupInfo, error) {
groupIds := make([]string, 0, len(groupInfo))
for _, v := range groupInfo {
groupIds = append(groupIds, v.ImGroupId)
}
// roomMicUserMap不影响排序
roomMicUserMap, err := group_m.BatchGetAllMicUser(model, groupIds)
if err != nil {
return nil, err
}
uids := make([]uint64, 0)
micUsersMap := make(map[string][]uint64, 0)
for _, v := range groupInfo {
micUsersMap[v.ImGroupId] = make([]uint64, 0)
if len(v.Password) <= 0 {
// 密码群不显示麦上头像
u := roomMicUserMap[v.ImGroupId]
if len(u) >= 4 {
micUsersMap[v.ImGroupId] = u[0:4]
} else if len(u) > 0 {
micUsersMap[v.ImGroupId] = u
}
uids = append(uids, micUsersMap[v.ImGroupId]...)
}
}
uids = utils.UniqueSliceUInt64(uids)
userTiny, err := user_cv.GetUserTinyMap(uids)
if err != nil {
return nil, err
}
roomCount, err := group_m.BatchGetRoomCount(model, groupIds)
if err != nil {
return nil, err
}
countryInfo, err := res_c.GetCountryIconMap(model)
if err != nil {
return nil, err
}
supportLevels, err := group_s.NewGroupService(model.MyContext).GetWeekMaxSupportLevelMap()
if err != nil {
return nil, err
}
visitCount, err := group_m.BatchGetRoomVisitCount(model.Log, groupIds)
if err != nil {
return nil, err
}
roomEnterTime, err := room_c.GetUserRoomVisit(myUserId)
if err != nil {
return nil, err
}
model.Log.Infof("BuildPopularGroupInfo, roomEnterTime: %v", roomEnterTime)
// 排序优先级V8.0版本
sort.Slice(groupIds, func(i, j int) bool {
gi := groupIds[i]
gj := groupIds[j]
return roomEnterTime[gi] > roomEnterTime[gj] ||
roomEnterTime[gi] == roomEnterTime[gj] && visitCount[gj] > visitCount[gj] ||
roomEnterTime[gi] == roomEnterTime[gj] && visitCount[gj] == visitCount[gj] && i >= j
})
result := make([]*PopularGroupInfo, 0)
owners := make([]uint64, 0)
for _, v := range groupInfo {
owners = append(owners, v.Owner)
}
powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil {
return nil, err
}
groupMedals, err := group_m.BatchGetMedals(model.Db, groupIds)
if err != nil {
return nil, err
}
resMedal, err := res_m.MedalGetAllMap(model.Db)
if err != nil {
return nil, err
}
rr := rocket_m.RocketResult{}
maxStageMap, err := rr.GetMaxStage(model.Db, groupIds)
if err != nil {
return nil, err
}
// 正在进行的游戏
games := game_m.GetNotEndGamesMap(model)
for _, v := range groupInfo {
g := v
i := v.ImGroupId
micUsers := make([]user_cv.CvUserTiny, 0)
for _, j := range micUsersMap[i] {
micUsers = append(micUsers, userTiny[j])
}
var maxStage *uint16 = nil
if s, ok := maxStageMap[i]; ok {
maxStage = &s
}
medals := make([]medal_cv.PicElement, 0)
if m, ok := groupMedals[i]; ok {
for _, j := range m {
mId := uint32(j)
if e, ok := resMedal[mId]; ok {
medals = append(medals, medal_cv.PicElement{
PicUrl: e.PicUrl,
})
}
}
}
// 补上房间流水勋章
var pe *medal_cv.PicElement
_, pe, err = medal_cv.GetGroupConsumeMedal(model, i)
if err != nil {
model.Log.Infof("BuildPopularGroupInfo: GetGroupConsumeMedal: %s", err.Error())
} else if pe != nil {
medals = append(medals, medal_cv.PicElement{PicUrl: pe.PicUrl})
}
var password *string = nil
if len(g.Password) > 0 && g.Owner != myUserId {
emptyStr := ""
password = &emptyStr
}
result = append(result, &PopularGroupInfo{
GroupInfo: GroupInfo{
GroupBasicInfo: GroupBasicInfo{
GroupId: g.TxGroupId,
Name: g.Name,
Notification: g.Notification,
Introduction: g.Introduction,
FaceUrl: g.FaceUrl,
Code: g.Code,
CountryIcon: countryInfo[g.Country],
Password: password,
SupportLevel: supportLevels[i],
GroupInUserDuration: visitCount[i],
MicNumType: int(g.MicNumType),
GroupMedals: medals,
},
HasOnMic: len(micUsers) > 0,
GroupPowerId: powerIds[g.Owner],
GroupPowerName: powerNames[g.Owner],
GroupPowerNameplate: powerNameplates[g.Owner],
GroupPower: GroupPower{
Id: powerIds[g.Owner],
Name: powerNames[g.Owner],
Nameplate: powerNameplates[g.Owner],
Grade: powerGrades[g.Owner],
},
},
MicUsers: micUsers,
RoomUserCount: uint(roomCount[i]),
MaxStage: maxStage,
GameTypes: games[g.TxGroupId],
})
}
return result, nil
}
//检查群组中是否有有人在麦上,返回存在的Set[imGroupId] //检查群组中是否有有人在麦上,返回存在的Set[imGroupId]
func CheckMicHasUserByGroup(groupIds []string) (map[string]struct{}, error) { func CheckMicHasUserByGroup(groupIds []string) (map[string]struct{}, error) {
groupMap := map[string]struct{}{} groupMap := map[string]struct{}{}
......
...@@ -16,6 +16,7 @@ import ( ...@@ -16,6 +16,7 @@ import (
"hilo-group/cv/user_cv" "hilo-group/cv/user_cv"
"hilo-group/domain/model/groupPower_m" "hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/group_m" "hilo-group/domain/model/group_m"
"hilo-group/domain/model/user_m"
"hilo-group/myerr" "hilo-group/myerr"
"sort" "sort"
"strconv" "strconv"
...@@ -232,28 +233,37 @@ func GetCvGroupPowerUsers(groupPowerId uint64) ([]mysql.ID, error) { ...@@ -232,28 +233,37 @@ func GetCvGroupPowerUsers(groupPowerId uint64) ([]mysql.ID, error) {
return usreIds, nil return usreIds, nil
} }
func BatchGetGroupPower(db *gorm.DB, userIds []uint64) (map[uint64]uint64, map[uint64]string, error) { // return userId->powerId userId->powerName userId->powerNameplate
func BatchGetGroupPower(db *gorm.DB, userIds []uint64) (map[uint64]uint64, map[uint64]string, map[uint64]string, map[uint64]groupPower_e.GroupPowerGrade, error) {
if len(userIds) <= 0 { if len(userIds) <= 0 {
return nil, nil, nil return nil, nil, nil, nil, nil
} }
groupPowers, err := groupPower_m.GetGroupPowerMap(db, userIds) groupPowers, err := groupPower_m.GetGroupPowerMap(db, userIds)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, nil, err
} }
gpIds := make([]uint64, 0) gpIds := make([]uint64, 0)
for _, i := range groupPowers { for _, i := range groupPowers {
gpIds = append(gpIds, i) gpIds = append(gpIds, i)
} }
powerNames, err := groupPower_m.GetGroupPowerNames(db, gpIds) powerNames, powerNameplates, err := groupPower_m.GetGroupPowerNames(db, gpIds)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, nil, err
}
groupPowerGrade, err := groupPower_m.MGetGroupPowerGrade(domain.CreateModelNil(), gpIds)
if err != nil {
return nil, nil, nil, nil, err
} }
groupPowerNames := make(map[mysql.ID]string, 0) groupPowerNames := make(map[mysql.ID]string, 0)
groupPowerNameplates := make(map[mysql.ID]string, 0)
groupPowerGrades := make(map[mysql.ID]groupPower_e.GroupPowerGrade, 0)
for i, g := range groupPowers { for i, g := range groupPowers {
groupPowerNames[i] = powerNames[g] groupPowerNames[i] = powerNames[g]
groupPowerNameplates[i] = powerNameplates[g]
groupPowerGrades[i] = groupPowerGrade[g].Grade
} }
return groupPowers, groupPowerNames, nil return groupPowers, groupPowerNames, groupPowerNameplates, groupPowerGrades, nil
} }
//获取国家势力的所有用户数量 //获取国家势力的所有用户数量
...@@ -639,3 +649,55 @@ func GetAllPowerDiamond(period string) (map[string]string, error) { ...@@ -639,3 +649,55 @@ func GetAllPowerDiamond(period string) (map[string]string, error) {
key := redis_key.GetPrefixGroupPowerDiamond(period) key := redis_key.GetPrefixGroupPowerDiamond(period)
return redisCli.GetRedis().HGetAll(context.Background(), key).Result() return redisCli.GetRedis().HGetAll(context.Background(), key).Result()
} }
type GroupPowerInfo struct {
Info *GroupPower `json:"info"`
Members []*GroupPowerUser `json:"members"`
Stars []*GroupPowerStar `json:"stars,omitempty"`
}
type GroupPower struct {
Id uint64 `json:"id"`
Name string `json:"name"`
Nameplate string `json:"nameplate"` // 铭牌
Declaration string `json:"declaration"` // 宣言
Icon string `json:"icon"` // 头像
Grade mysql.Num `json:"grade" gorm:"-"` // 等级
Exp mysql.Num `json:"exp" gorm:"-"` // 当前经验值
NextExp mysql.Num `json:"nextExp" gorm:"-"` // 升到下一级需要的经验值
GradeName mysql.Str `json:"gradeName"` // 等级称号
GradeMedal mysql.Str `json:"gradeMedal"` // 等级勋章图片
MemberNum mysql.Num `json:"memberNum" gorm:"-"` // 当前人数
MemberMax mysql.Num `json:"memberMax" gorm:"-"` // 最大人数
Role int `json:"role" gorm:"-"` // 我在此家族中的角色 0.路人 1.成员 2.家族长 3.管理员
IsApply bool `json:"isApply" gorm:"-"` // 最大人数
}
type GroupPowerUser struct {
User *user_m.UserTiny `json:"user"`
Role groupPower_e.GroupPowerUserRole `json:"role"`
}
type GroupPowerStar struct {
User user_cv.CvUserTiny `json:"user"`
RankingType groupPower_e.GroupPowerRankType `json:"rankingType"`
}
type FamilyMemberDetail struct {
User user_cv.CvUserExtend `json:"user"`
Role groupPower_e.GroupPowerUserRole `json:"role"`
}
type FamilyApplyList struct {
User *user_m.UserTiny `json:"user"`
Time int64 `json:"time"`
Status int8 `json:"status"` // 0未操作,1已接受,2.已拒绝
MgrName string `json:"mgrName"` // 管理员名称
}
type FamilyQuitList struct {
User *user_m.UserTiny `json:"user"`
Time int64 `json:"time"`
QuitType int8 `json:"quitType"` // 1.主动退出 2.被踢出
MgrName string `json:"mgrName"` // 管理员名称
}
package group_power_cv
import (
"hilo-group/_const/enum/groupPower_e"
"hilo-group/cv/user_cv"
)
// 家族信息
type CvGroupPowerInfo struct {
CvGroupPowerBase `json:",inline"`
CvGroupPowerMember `json:",inline"`
CvGroupPowerGrade `json:",inline"`
}
// 家族基本信息
type CvGroupPowerBase struct {
Id uint64 `json:"id"` // 家族id
Icon string `json:"icon"` // 家族图片
Name string `json:"name"` // 家族名
Nameplate string `json:"nameplate"` // 铭牌
}
// 家族成员
type CvGroupPowerMember struct {
MemberNum uint32 `json:"memberNum"` // 当前成员数
MemberMax uint32 `json:"memberMax"` // 成员上限
}
// 家族等级
type CvGroupPowerGrade struct {
Grade groupPower_e.GroupPowerGrade `json:"grade"` // 等级 0:青铜 1:白银 2:黄金 3:黑金
Exp uint32 `json:"exp"` // 经验值
NextExp uint32 `json:"nextExp,omitempty"` // 下个等级所需经验值
ExpireAt string `json:"expireAt,omitempty"` // 有效期
}
// 家族榜单
type CvGroupPowerRank struct {
MyGroupPower *CvGroupPowerRankData `json:"myGroupPower,omitempty"` // 我的家族排名
Items []CvGroupPowerRankData `json:"items"` // 列表
}
type CvGroupPowerRankData struct {
CvGroupPowerBase `json:",inline"`
CvGroupPowerGrade `json:",inline"`
Rank int `json:"rank"` // 排名
}
// 家族之星
type CvGroupPowerStarData struct {
User user_cv.CvUserTiny `json:"user"`
Score uint32 `json:"score"` // 对应分值
}
// 资源等级
type CvResGrade struct {
Grade groupPower_e.GroupPowerGrade `json:"grade"` // 等级
Icon string `json:"icon"` // 等级icon
BigIcon string `json:"bigIcon"` // 等级大图标
}
// 特权信息
type CvPrivilege struct {
Type groupPower_e.GroupPowerPrivilege `json:"type"` // 特权id 1:成员数 2:管理员数 3:家族铭牌 4:家族徽章装饰 5:编辑铭牌 6:家族头饰
Num int `json:"num"` // 数目
}
// 家族等级页
type CvGroupPowerGradeDetail struct {
GroupPowerBase CvGroupPowerBase `json:"groupPowerBase"` // 家族基本信息
GroupPowerGrade CvGroupPowerGrade `json:"groupPowerGrade"` // 家族等级信息
ResGradeList []CvResGrade `json:"resGradeList"` // 资源等级列表,青铜、白银、黄金、黑金
PrivilegeList []CvPrivilege `json:"privilegeList"` // 等级特权
IsMember bool `json:"isMember"` // 是否家族成员
}
var CvResGradeList = []CvResGrade{
{groupPower_e.GroupPowerGrade0, "青铜icon", "青铜bigIcon"}, // todo
{groupPower_e.GroupPowerGrade1, "白银icon", "白银bigIcon"}, // todo
{groupPower_e.GroupPowerGrade2, "黄金icon", "黄金bigIcon"}, // todo
{groupPower_e.GroupPowerGrade3, "黑金icon", "黑金bigIcon"}, // todo
}
var GroupPowerGradePrivilegeNum = map[groupPower_e.GroupPowerGrade][]CvPrivilege{
groupPower_e.GroupPowerGrade0: {
{groupPower_e.GroupPowerPrivilegeMemberNum, 300},
{groupPower_e.GroupPowerPrivilegeMgrNum, 10},
{groupPower_e.GroupPowerPrivilegeNameplate, 1},
{groupPower_e.GroupPowerPrivilegeMedal, 1},
},
groupPower_e.GroupPowerGrade1: {
{groupPower_e.GroupPowerPrivilegeMemberNum, 500},
{groupPower_e.GroupPowerPrivilegeMgrNum, 15},
{groupPower_e.GroupPowerPrivilegeNameplate, 1},
{groupPower_e.GroupPowerPrivilegeMedal, 1},
{groupPower_e.GroupPowerPrivilegeNameplateEdit, 1},
},
groupPower_e.GroupPowerGrade2: {
{groupPower_e.GroupPowerPrivilegeMemberNum, 800},
{groupPower_e.GroupPowerPrivilegeMgrNum, 20},
{groupPower_e.GroupPowerPrivilegeNameplate, 1},
{groupPower_e.GroupPowerPrivilegeMedal, 1},
{groupPower_e.GroupPowerPrivilegeNameplateEdit, 1},
{groupPower_e.GroupPowerPrivilegeNameplateHeadwear, 1},
},
groupPower_e.GroupPowerGrade3: {
{groupPower_e.GroupPowerPrivilegeMemberNum, 1200},
{groupPower_e.GroupPowerPrivilegeMgrNum, 25},
{groupPower_e.GroupPowerPrivilegeNameplate, 1},
{groupPower_e.GroupPowerPrivilegeMedal, 1},
{groupPower_e.GroupPowerPrivilegeNameplateEdit, 1},
{groupPower_e.GroupPowerPrivilegeNameplateHeadwear, 1},
},
}
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"git.hilo.cn/hilo-common/rpc" "git.hilo.cn/hilo-common/rpc"
. "git.hilo.cn/hilo-common/utils" . "git.hilo.cn/hilo-common/utils"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/_const/enum/group_e" "hilo-group/_const/enum/group_e"
"hilo-group/_const/enum/user_e" "hilo-group/_const/enum/user_e"
"hilo-group/cv/country_cv" "hilo-group/cv/country_cv"
...@@ -61,12 +62,20 @@ type CvUserDetail struct { ...@@ -61,12 +62,20 @@ type CvUserDetail struct {
CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”) CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”)
MyGroupPower uint64 `json:"myGroupPower"` // 当前用户所在势力 MyGroupPower uint64 `json:"myGroupPower"` // 当前用户所在势力
MyGroupPowerName string `json:"myGroupPowerName"` // 当前用户所在势力绑定群组的名称 MyGroupPowerName string `json:"myGroupPowerName"` // 当前用户所在势力绑定群组的名称
GroupPower GroupPower `json:"groupPower"` // 当前用户势力信息
GroupId string `json:"groupId"` // 当前用户拥有的群组id(产品叫“群组”),如果没有则为空,拥有多个,返回第一个 GroupId string `json:"groupId"` // 当前用户拥有的群组id(产品叫“群组”),如果没有则为空,拥有多个,返回第一个
PhoneInfo *user_m.UserPhoneInfo `json:"phoneInfo"` // 用户绑定的手机信息 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) ThirdList []int8 `json:"thirdList"` // 用户绑定的第三方平台列表;类型 1:phone, 2:google, 3:facebook 4:apple 5:wechat" Enums(1,2,3,4,5)
CountryManager *country_cv.CVCountryManager `json:"countryManager,omitempty"` // 国家管理员 CountryManager *country_cv.CVCountryManager `json:"countryManager,omitempty"` // 国家管理员
} }
type GroupPower struct {
Id uint64 `json:"id"` // 群主所在的势力ID
Name string `json:"name"` // 群主所在的势力的名称
Nameplate string `json:"nameplate"` // 势力铭牌
Grade groupPower_e.GroupPowerGrade `json:"grade"` // 等级
}
type CvUserTiny struct { type CvUserTiny struct {
Id uint64 `json:"id,omitempty"` Id uint64 `json:"id,omitempty"`
ExternalId string `json:"externalId"` ExternalId string `json:"externalId"`
...@@ -290,6 +299,7 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID ...@@ -290,6 +299,7 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID
} }
model.Log.Infof("getUserDetails: %+v", rooms) model.Log.Infof("getUserDetails: %+v", rooms)
// userId->groupPowerId
groupPowers, err := groupPower_m.GetGroupPowerMap(mysql.Db, userIds) groupPowers, err := groupPower_m.GetGroupPowerMap(mysql.Db, userIds)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -299,13 +309,25 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID ...@@ -299,13 +309,25 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID
for _, i := range groupPowers { for _, i := range groupPowers {
gpIds = append(gpIds, i) gpIds = append(gpIds, i)
} }
powerNames, err := groupPower_m.GetGroupPowerNames(mysql.Db, gpIds) powerNames, _, err := groupPower_m.GetGroupPowerNames(mysql.Db, gpIds)
if err != nil {
return nil, err
}
groupPowerInfoMap, err := groupPower_m.MGetGroupPowerInfoMap(model, gpIds)
if err != nil {
return nil, err
}
groupPowerGradeMap, err := groupPower_m.MGetGroupPowerGrade(model, gpIds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
groupPowerNames := make(map[mysql.ID]string, 0) groupPowerNames := make(map[mysql.ID]string, 0)
for i, g := range groupPowers { groupPowerInfos := make(map[mysql.ID]groupPower_m.GroupPowerInfo)
groupPowerNames[i] = powerNames[g] groupPowerGrades := make(map[mysql.ID]groupPower_m.GroupPowerGrade)
for uid, gid := range groupPowers {
groupPowerNames[uid] = powerNames[gid]
groupPowerInfos[uid] = groupPowerInfoMap[gid]
groupPowerGrades[uid] = groupPowerGradeMap[gid]
} }
up := user_m.UserProperty{} up := user_m.UserProperty{}
...@@ -350,7 +372,7 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID ...@@ -350,7 +372,7 @@ func getUserDetails(model *domain.Model, users []*user_m.User, myUserId mysql.ID
cvUserDetail, err := userToDetail(users[i], myUserId, userTradeUnion, likeMap, likeMeMap, rels, cvUserDetail, err := userToDetail(users[i], myUserId, userTradeUnion, likeMap, likeMeMap, rels,
vips[users[i].ID] != nil, vips[users[i].ID], svips[users[i].ID], headwear, ride, vips[users[i].ID] != nil, vips[users[i].ID], svips[users[i].ID], headwear, ride,
wealthGradeMap, charmGradeMap, activeGradeMap, medals, medalInfo, rooms, groupPowers, groupPowerNames, nobles, superManagerMap) wealthGradeMap, charmGradeMap, activeGradeMap, medals, medalInfo, rooms, groupPowers, groupPowerNames, groupPowerInfos, groupPowerGrades, nobles, superManagerMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -370,7 +392,7 @@ func userToDetail(user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.U ...@@ -370,7 +392,7 @@ func userToDetail(user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.U
likeMeMap map[mysql.ID]bool, hvMap map[mysql.ID]Relation, isVip bool, vipExpireTime *int64, svip rpc.CvSvip, headwear *headwear_cv.CvHeadwear, ride property_cv.CvProperty, likeMeMap map[mysql.ID]bool, hvMap map[mysql.ID]Relation, isVip bool, vipExpireTime *int64, svip rpc.CvSvip, headwear *headwear_cv.CvHeadwear, ride property_cv.CvProperty,
wealthGradeMap map[mysql.ID]uint32, charmGradeMap map[mysql.ID]uint32, actityGradeMap map[mysql.ID]uint32, wealthGradeMap map[mysql.ID]uint32, charmGradeMap map[mysql.ID]uint32, actityGradeMap map[mysql.ID]uint32,
medals map[uint64][]uint32, medalInfo map[uint64][]medal_cv.CvMedal, rooms map[mysql.ID]string, medals map[uint64][]uint32, medalInfo map[uint64][]medal_cv.CvMedal, rooms map[mysql.ID]string,
powers map[mysql.ID]uint64, powerNames map[mysql.ID]string, nobles map[mysql.ID]noble_m.UserNoble, superManagerMap map[uint64]bool) (*CvUserDetail, error) { powers map[mysql.ID]uint64, powerNames map[mysql.ID]string, groupPowerInfos map[mysql.ID]groupPower_m.GroupPowerInfo, powerGrades map[mysql.ID]groupPower_m.GroupPowerGrade, nobles map[mysql.ID]noble_m.UserNoble, superManagerMap map[uint64]bool) (*CvUserDetail, error) {
cvUserDetail := &CvUserDetail{ cvUserDetail := &CvUserDetail{
CvUserBase: CvUserBase{ CvUserBase: CvUserBase{
Id: &user.ID, Id: &user.ID,
...@@ -510,6 +532,12 @@ func userToDetail(user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.U ...@@ -510,6 +532,12 @@ func userToDetail(user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.U
cvUserDetail.CurrentRoom = rooms[user.ID] cvUserDetail.CurrentRoom = rooms[user.ID]
cvUserDetail.MyGroupPower = powers[user.ID] cvUserDetail.MyGroupPower = powers[user.ID]
cvUserDetail.MyGroupPowerName = powerNames[user.ID] cvUserDetail.MyGroupPowerName = powerNames[user.ID]
cvUserDetail.GroupPower = GroupPower{
Id: groupPowerInfos[user.ID].ID,
Name: groupPowerInfos[user.ID].Name,
Nameplate: groupPowerInfos[user.ID].Nameplate,
Grade: powerGrades[user.ID].Grade,
}
if n, ok := nobles[user.ID]; ok && n.Level > 0 { if n, ok := nobles[user.ID]; ok && n.Level > 0 {
cvUserDetail.Noble = noble_cv.CvNoble{ cvUserDetail.Noble = noble_cv.CvNoble{
Level: n.Level, Level: n.Level,
...@@ -670,6 +698,8 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv ...@@ -670,6 +698,8 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv
} }
powers := map[mysql.ID]uint64{userId: groupPowerId} powers := map[mysql.ID]uint64{userId: groupPowerId}
powerNames := map[mysql.ID]string{userId: groupPowerName} powerNames := map[mysql.ID]string{userId: groupPowerName}
groupPowerInfos, err := groupPower_m.MGetGroupPowerInfoMap(model, []mysql.ID{groupPowerId})
groupPowerGrades, err := groupPower_m.MGetGroupPowerGrade(model, []mysql.ID{groupPowerId})
up := user_m.UserProperty{} up := user_m.UserProperty{}
rides, err := up.BatchGet(mysql.Db, []uint64{userId}) rides, err := up.BatchGet(mysql.Db, []uint64{userId})
...@@ -759,14 +789,14 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv ...@@ -759,14 +789,14 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv
return userToDetailOne(model, &user, myUserId, userTradeUnion, likeN > 0, likeMe > 0, return userToDetailOne(model, &user, myUserId, userTradeUnion, likeN > 0, likeMe > 0,
rel, isVip, expireTime, svip, headwear, ride, wealthUserScore.Grade, charmUserScore.Grade, rel, isVip, expireTime, svip, headwear, ride, wealthUserScore.Grade, charmUserScore.Grade,
activityUserScore.Grade, medals[userId], medalInfo[userId], rooms[userId], powers[userId], powerNames[userId], activityUserScore.Grade, medals[userId], medalInfo[userId], rooms[userId], powers[userId], powerNames[userId], groupPowerInfos[groupPowerId].Nameplate, groupPowerGrades[groupPowerId],
noble, superManagerMap[userId], myGroups, phoneInfo, thirdList, cvCountryManager) noble, superManagerMap[userId], myGroups, phoneInfo, thirdList, cvCountryManager)
} }
// 单用户版,简化参数 // 单用户版,简化参数
func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.UserTradeUnion, isLike bool, likeMe bool, hvMap map[mysql.ID]Relation, func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.UserTradeUnion, isLike bool, likeMe bool, hvMap map[mysql.ID]Relation,
isVip bool, vipExpireTime *int64, svip rpc.CvSvip, headwear *headwear_cv.CvHeadwear, ride property_cv.CvProperty, wealthGrade uint32, charmGrade uint32, activityGrade uint32, 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, noble *noble_m.UserNoble, isOfficialStaff bool, medals []uint32, medalInfo []medal_cv.CvMedal, room string, power uint64, powerName string, powerNameplate string, grade groupPower_m.GroupPowerGrade, noble *noble_m.UserNoble, isOfficialStaff bool,
myGroups []group_m.GroupInfo, phoneInfo *user_m.UserPhoneInfo, thirdList []int8, countryManager *country_cv.CVCountryManager) (*CvUserDetail, error) { myGroups []group_m.GroupInfo, phoneInfo *user_m.UserPhoneInfo, thirdList []int8, countryManager *country_cv.CVCountryManager) (*CvUserDetail, error) {
room, err := group_m.ToTxGroupId(model, room) room, err := group_m.ToTxGroupId(model, room)
...@@ -806,6 +836,12 @@ func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, ...@@ -806,6 +836,12 @@ func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID,
CurrentRoom: room, CurrentRoom: room,
MyGroupPower: power, MyGroupPower: power,
MyGroupPowerName: powerName, MyGroupPowerName: powerName,
GroupPower: GroupPower{
Id: power,
Name: powerName,
Nameplate: powerNameplate,
Grade: grade.Grade,
},
PhoneInfo: phoneInfo, PhoneInfo: phoneInfo,
ThirdList: thirdList, ThirdList: thirdList,
CountryManager: countryManager, CountryManager: countryManager,
......
...@@ -6,10 +6,12 @@ import ( ...@@ -6,10 +6,12 @@ import (
redisV8 "github.com/go-redis/redis/v8" redisV8 "github.com/go-redis/redis/v8"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"hilo-group/_const/redis_key/user_k" "hilo-group/_const/redis_key/user_k"
"hilo-group/common"
"hilo-group/domain/cache" "hilo-group/domain/cache"
"hilo-group/domain/model/user_m" "hilo-group/domain/model/user_m"
"hilo-group/myerr" "hilo-group/myerr"
"hilo-group/myerr/bizerr" "hilo-group/myerr/bizerr"
"time"
) )
// 获取用户简要信息 // 获取用户简要信息
...@@ -96,10 +98,11 @@ func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) { ...@@ -96,10 +98,11 @@ func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) {
// 顺手缓存code->userId // 顺手缓存code->userId
// param user: 已经在上层获取的db User结构 // param user: 已经在上层获取的db User结构
func cacheUserTiny(model *domain.Model, user *user_m.User) error { func cacheUserTiny(model *domain.Model, user *user_m.User) error {
userTiny := new(user_m.UserTiny) userTiny := ToUserTinyBy(user)
if err := copier.Copy(userTiny, user); err != nil { //userTiny := new(user_m.UserTiny)
return err //if err := copier.Copy(userTiny, user); err != nil {
} // return err
//}
// cache externalId->userId // cache externalId->userId
if err := model.Redis.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil { if err := model.Redis.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
return err return err
...@@ -113,3 +116,89 @@ func cacheUserTiny(model *domain.Model, user *user_m.User) error { ...@@ -113,3 +116,89 @@ func cacheUserTiny(model *domain.Model, user *user_m.User) error {
} }
return nil return nil
} }
// 获取用户简要信息
// param userIds 用户id列表
func GetUserTinyMap(model *domain.Model, userIds []mysql.ID, isDefAvatar bool) (map[mysql.ID]*user_m.UserTiny, error) {
redisNoIds := make([]mysql.ID, 0)
res := make(map[mysql.ID]*user_m.UserTiny)
for _, id := range userIds {
userTiny := new(user_m.UserTiny)
key := user_k.GetUserTinyKey(id)
err := cache.GetJSON(model, key, userTiny)
if err != nil && err != redisV8.Nil {
return nil, err
}
if err == redisV8.Nil {
redisNoIds = append(redisNoIds, id)
} else if userTiny.ID > 0 {
res[id] = userTiny
}
}
// 从db中读
users, err := user_m.GetUsers(model, redisNoIds)
if err != nil {
return nil, err
}
for _, u := range users {
userTiny := ToUserTinyBy(u)
err = cacheUserTiny(model, u)
if err != nil {
return nil, err
}
res[userTiny.ID] = userTiny
}
if isDefAvatar {
for _, v := range res {
if len(v.Avatar) <= 0 {
if v.Sex == mysql.MAN {
v.Avatar = common.MakeFullUrl(common.DefaultAvatarMan)
} else if v.Sex == mysql.WOMAN {
v.Avatar = common.MakeFullUrl(common.DefaultAvatarWoman)
}
}
}
}
return res, nil
}
func ToUserTinyBy(user *user_m.User) *user_m.UserTiny {
return &user_m.UserTiny{
ID: user.ID,
Avatar: IfLogoutStr(IfLogout(user.LogoutTime), "", user.Avatar),
ExternalId: user.ExternalId,
Nick: IfLogoutNick(IfLogout(user.LogoutTime), user.Code, user.Nick),
Sex: user.Sex,
Code: user.Code,
Country: user.Country,
CountryIcon: user.CountryIcon,
IsPrettyCode: user.IsPrettyCode(),
IsLogout: IfLogout(user.LogoutTime),
Birthday: BirthdayToUint64(&user.Birthday),
}
}
func IfLogout(logoutTime int64) bool {
return logoutTime > 0 && time.Now().Unix() > logoutTime
}
func BirthdayToUint64(birthday *mysql.Timestamp) *uint64 {
if *birthday == 0 {
return nil
}
return (*uint64)(birthday)
}
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
}
package group_power_ev
import (
"git.hilo.cn/hilo-common/domain"
)
//注册监听
var groupPowerExpireNoticeListen = new(domain.EventBase)
type GroupPowerExpireNoticeEvent struct {
}
//添加领域事件,在每个领域模型中init中添加,因为这是静态业务,非动态的。
func AddGroupPowerExpireNoticeSync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventSync(groupPowerExpireNoticeListen, callback)
}
//加入到异步操作中
func AddGroupPowerExpireNoticeAsync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventAsync(groupPowerExpireNoticeListen, callback)
}
//领域事件发布
func PublishGroupPowerExpireNotice(model *domain.Model, event interface{}) error {
return domain.PublishEvent(groupPowerExpireNoticeListen, model, event)
}
package group_power_ev
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
)
//注册监听
var groupPowerUpgradeListen = new(domain.EventBase)
type GroupPowerUpgradeEvent struct {
GroupPowerId mysql.ID
}
//添加领域事件,在每个领域模型中init中添加,因为这是静态业务,非动态的。
func AddGroupPowerUpgradeSync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventSync(groupPowerUpgradeListen, callback)
}
//加入到异步操作中
func AddGroupPowerUpgradeAsync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventAsync(groupPowerUpgradeListen, callback)
}
//领域事件发布
func PublishGroupPowerUpgrade(model *domain.Model, event interface{}) error {
return domain.PublishEvent(groupPowerUpgradeListen, model, event)
}
package mic_ev
import (
"git.hilo.cn/hilo-common/domain"
)
var onMicListen = new(domain.EventBase)
// 在麦上事件
type OnMicEvent struct {
GroupUuid string // 群组uuid
I int // 麦位
ExternalId string // 麦中的人
UserId uint64 // 麦中的人
Forbid bool // 静音 true:静音,false:没有静音
Timestamp int64 // 上麦的的时间戳
}
func AddOnMicEventSync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventSync(onMicListen, callback)
}
func AddOnMicEventAsync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventAsync(onMicListen, callback)
}
func PublishOnMicEvent(model *domain.Model, event interface{}) error {
return domain.PublishEvent(onMicListen, model, event)
}
package diamond_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-group/common"
"hilo-group/myerr"
)
type DiamondDealer struct {
mysql.Entity
UserId uint64
Diamond uint32
Wechat string
Whatsapp string
Contact string
Status int
HasInvite int
IsFamilyAgent int8
}
func (dealer *DiamondDealer) Save(db *gorm.DB) error {
if dealer.ID > 0 {
db = db.Omit("diamond", "status")
} else {
dealer.Status = common.SWITCH_ON
}
return db.Save(dealer).Error
}
func (dealer *DiamondDealer) Get(db *gorm.DB) error {
return db.Where(dealer).First(dealer).Error
}
func IsDiamondDealer(db *gorm.DB, userId uint64) (bool, error) {
dd := DiamondDealer{UserId: userId, Status: common.SWITCH_ON}
if err := dd.Get(db); err != nil {
if err == gorm.ErrRecordNotFound {
return false, nil
} else {
return false, err
}
}
return true, nil
}
// 是否是家族代理
func IsFamilyDiamondDealer(db *gorm.DB, userId uint64) (bool, error) {
dd := DiamondDealer{UserId: userId, Status: common.SWITCH_ON, IsFamilyAgent: 1}
if err := dd.Get(db); err != nil {
if err == gorm.ErrRecordNotFound {
return false, nil
} else {
return false, err
}
}
return true, nil
}
func GetDiamondDealer(db *gorm.DB, userId uint64) (*DiamondDealer, error) {
dd := &DiamondDealer{UserId: userId, Status: common.SWITCH_ON}
if err := dd.Get(db); err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return dd, nil
}
func (dealer *DiamondDealer) GetAll(db *gorm.DB, status *uint8) ([]DiamondDealer, error) {
rows := make([]DiamondDealer, 0)
if status == nil {
if err := db.Where(dealer).Find(&rows).Error; err != nil {
return nil, err
}
} else if err := db.Where(dealer).Where("status = ?", *status).Find(&rows).Error; err != nil {
return nil, err
}
return rows, nil
}
func (dealer *DiamondDealer) Remove(db *gorm.DB) (int64, error) {
result := db.Where(dealer).Delete(&DiamondDealer{})
return result.RowsAffected, result.Error
}
func (dealer *DiamondDealer) SafeReduceDiamond(db *gorm.DB, diamond uint32) (int64, error) {
result := db.Model(&DiamondDealer{}).Where(dealer).Where("diamond >= ?", diamond).UpdateColumn("diamond", gorm.Expr("diamond - ?", diamond))
return result.RowsAffected, result.Error
}
func (dealer *DiamondDealer) AddDiamond(db *gorm.DB, diamond uint32) (int64, error) {
result := db.Model(&DiamondDealer{}).Where(dealer).Where("status = ?", common.SWITCH_ON).UpdateColumn("diamond", gorm.Expr("diamond + ?", diamond))
return result.RowsAffected, result.Error
}
func (dealer *DiamondDealer) SetStatus(db *gorm.DB, status uint8) error {
return db.Model(&DiamondDealer{}).Where(dealer).Update("status", status).Error
}
type DealerTransferDetail struct {
mysql.Entity
DealerId uint64
ReceiverId uint64
Diamond uint32
Dollar uint
}
func (dtd *DealerTransferDetail) Create(db *gorm.DB) error {
return db.Create(dtd).Error
}
func (dfd *DealerTransferDetail) Find(db *gorm.DB, offset, limit int) ([]DealerTransferDetail, error) {
rows := make([]DealerTransferDetail, 0)
if err := db.Where(dfd).Order("created_time DESC").Offset(offset).Limit(limit).Find(&rows).Error; err != nil {
return nil, err
}
return rows, nil
}
func (dfd *DealerTransferDetail) CountByDealer(db *gorm.DB, dealerIds []uint64) (map[uint64]uint, error) {
type summary struct {
DealerId uint64
C uint
}
rows := make([]summary, 0)
if err := db.Model(&DealerTransferDetail{}).Where("dealer_id IN ?", dealerIds).
Select("dealer_id, COUNT(0) AS c").Group("dealer_id").Find(&rows).Error; err != nil {
return nil, err
}
result := make(map[uint64]uint, 0)
for _, i := range rows {
result[i.DealerId] = i.C
}
return result, nil
}
func (dfd *DealerTransferDetail) Sum(db *gorm.DB) (uint, uint32, uint, error) {
type summary struct {
C uint
Diamond uint32
Dollar uint
}
s := summary{}
if err := db.Model(&DealerTransferDetail{}).Where(dfd).
Select("COUNT(0) AS c, SUM(diamond) AS diamond, SUM(dollar) AS dollar").First(&s).Error; err != nil {
return 0, 0, 0, err
}
return s.C, s.Diamond, s.Dollar, nil
}
type DealerChargeDetail struct {
mysql.Entity
DealerId uint64
MgrId uint64
Diamond uint32
Dollar uint
PaymentMethod string
Type uint8
Money float32 `json:"money"` // 支付的货币数值
Currency string `json:"currency"` // 支付货币
GoodsId string `json:"goodsId"` // 充值钻石套餐id/商品id
}
func (dcd *DealerChargeDetail) Create(db *gorm.DB) error {
return db.Create(dcd).Error
}
type DealerCountry struct {
DealerId uint64
Country string
}
func (dc *DealerCountry) Find(db *gorm.DB) ([]DealerCountry, error) {
rows := make([]DealerCountry, 0)
if err := db.Where(dc).Find(&rows).Error; err != nil {
return nil, err
}
return rows, nil
}
func (dc *DealerCountry) Delete(db *gorm.DB) error {
return db.Where(dc).Delete(&DealerCountry{}).Error
}
func (dc *DealerCountry) BatchInsert(db *gorm.DB, dealerId uint64, countries []string) error {
rows := make([]DealerCountry, 0)
for _, i := range countries {
rows = append(rows, DealerCountry{
DealerId: dealerId,
Country: i,
})
}
return db.Create(&rows).Error
}
// 活动排行榜黑名单 获取所有已经上架代理币商的群组id
func GetAllValidActivityBlackImGroupIds(model *domain.Model) []mysql.Str {
//return []mysql.Str{"HTGS#a88745892", "@TGS#3UW6RFSIX"}
var imGroupIds []mysql.Str
subQuery := model.Db.WithContext(model).Model(DiamondDealer{}).Where("status = 1").Select("user_id")
if err := model.Db.WithContext(model).Table("group_info").Select("im_group_id").Where("owner in (?)", subQuery).Scan(&imGroupIds).Error; err != nil {
mylogrus.MyLog.Errorf("GetAllValidActivityBlackImGroupIds fail:%v", err)
}
imGroupIds = append(imGroupIds, "HTGS#a88745892", "@TGS#3UW6RFSIX")
return imGroupIds
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/common"
"hilo-group/common/utime"
"hilo-group/myerr"
"hilo-group/myerr/bizerr"
"time"
)
//type GroupPowerGrade struct {
// GroupPowerId uint64 `json:"group_power_id"`
// Exp int64 `json:"exp"`
// Grade int32 `json:"grade"`
// ExpireAt time.Time `json:"expire_at"`
//}
type GroupPowerQuitLog struct {
Id uint64 `json:"id"`
UserId uint64 `json:"user_id"`
MgrId uint64 `json:"mgr_id"`
CreatedTime time.Time `json:"created_time"`
GroupPowerId uint64 `json:"group_power_id"`
}
func (this *GroupPower) Get(model *domain.Model) (*GroupPower, error) {
group := new(GroupPower)
err := model.Db.Where(this).First(&group).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
return nil, err
}
grade := new(GroupPowerGrade)
err = model.Db.Model(&GroupPowerGrade{}).Where("group_power_id=? and expire_at > ?", this.ID, time.Now().Format(utime.Layout)).First(&grade).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
if grade.GroupPowerId > 0 {
group.Grade = mysql.Num(grade.Grade)
group.Exp = mysql.Num(grade.Exp)
group.NextExp = mysql.Num(grade.Exp)
}
return group, nil
}
func (gpu *GroupPowerUser) GetBy(model *domain.Model, pageSize, pageIndex int) ([]*GroupPowerUser, int64, int, bool, error) {
rows := make([]*GroupPowerUser, 0)
db := model.Db.Model(GroupPowerUser{}).Where(gpu).Order("field(`role`, 2, 3, 1)")
var count int64
err := db.Count(&count).Error
if err != nil {
return nil, 0, 0, false, err
}
err = db.Limit(pageSize).Offset(pageIndex).Find(&rows).Error
if err != nil {
return nil, 0, 0, false, err
}
nextPageIndex, hasNextPage := common.PageNext(count, pageIndex, pageSize)
return rows, count, nextPageIndex, hasNextPage, nil
}
func (gpu *GroupPowerUser) GetGroupPowerUser(model *domain.Model) (*GroupPowerUser, error) {
rows := make([]*GroupPowerUser, 0)
err := model.Db.Where(gpu).Find(&rows).Error
if err != nil {
return nil, err
}
if len(rows) == 0 {
return nil, nil
}
return rows[0], nil
}
func (gpu *GroupPowerUser) Create(db *gorm.DB) error {
return db.Create(gpu).Error
}
func QuitFamily(model *domain.Model, userId, mgrId, familyId uint64) error {
err := model.Db.Exec("delete from group_power_user where group_power_id = ? and user_id = ?", familyId, userId).Error
if err != nil {
return err
}
// log
log := &GroupPowerQuitLog{UserId: userId, MgrId: mgrId, GroupPowerId: familyId, CreatedTime: time.Now()}
return model.Db.Create(log).Error
}
func GroupPowerQuitList(model *domain.Model, familyId uint64, pageSize, pageIndex int) ([]*GroupPowerQuitLog, int, bool, error) {
rows := make([]*GroupPowerQuitLog, 0)
db := model.Db.Model(GroupPowerQuitLog{}).Where("group_power_id = ?", familyId).Order("created_time desc")
var count int64
err := db.Count(&count).Error
if err != nil {
return nil, 0, false, err
}
err = db.Limit(pageSize).Offset(pageIndex).Find(&rows).Error
if err != nil {
return nil, 0, false, err
}
nextIdx, hasNext := common.PageNext(count, pageIndex, pageSize)
return rows, nextIdx, hasNext, nil
}
func UpdateFamilyAdmin(model *domain.Model, userId, familyId uint64, role groupPower_e.GroupPowerUserRole) error {
err := model.Db.Exec("update group_power_user set role = ? where group_power_id = ? and user_id = ?", role, familyId, userId).Error
if err != nil {
return err
}
return nil
}
func UpdateFamily(model *domain.Model, familyId uint64, name, nameplate, declaration, icon string) error {
if familyId == 0 || (name == "" && nameplate == "" && declaration == "" && icon == "") {
return nil
}
db := model.Db.Model(GroupPower{})
updateMap := make(map[string]interface{})
if name != "" {
updateMap["name"] = name
}
if nameplate != "" {
updateMap["nameplate"] = nameplate
db = db.Where("not exists (select id from group_power where nameplate = ?)", nameplate)
}
if declaration != "" {
updateMap["declaration"] = declaration
}
if icon != "" {
updateMap["icon"] = icon
}
result := db.Where("id = ?", familyId).Updates(updateMap).Limit(1)
if result.Error != nil {
return myerr.WrapErr(result.Error)
}
if result.RowsAffected <= 0 {
return myerr.WrapErr(bizerr.GroupPowerHaveChangeInfo)
}
return nil
}
func IsExistsNameplate(model *domain.Model, nameplate string) bool {
var count int64
err := model.Db.Model(GroupPower{}).Where("nameplate = ?", nameplate).Count(&count).Error
if err != nil {
model.Log.Errorf("IsExistsNameplate err:%v, nameplate:%s", err, nameplate)
return false
}
if count > 0 {
return true
}
return false
}
...@@ -26,6 +26,14 @@ type GroupPower struct { ...@@ -26,6 +26,14 @@ type GroupPower struct {
GroupUid mysql.Str GroupUid mysql.Str
Name mysql.Str Name mysql.Str
Status groupPower_e.GroupPowerStatus Status groupPower_e.GroupPowerStatus
Nameplate mysql.Str // 铭牌
Declaration mysql.Str // 宣言
Icon mysql.Str // 头像
Grade mysql.Num `gorm:"-"` // 等级
Exp mysql.Num `gorm:"-"` // 当前经验值
NextExp mysql.Num `gorm:"-"` // 升到下一级需要的经验值
GradeName mysql.Str // 等级称号
GradeMedal mysql.Str // 等级勋章图片
} }
type GroupPowerUser struct { type GroupPowerUser struct {
...@@ -334,6 +342,34 @@ func GetGroupPowerByGroupOrNil(model *domain.Model, groupUid string) (*GroupPowe ...@@ -334,6 +342,34 @@ func GetGroupPowerByGroupOrNil(model *domain.Model, groupUid string) (*GroupPowe
return &groupPower, nil return &groupPower, nil
} }
// 某个势力的势力主是否是代理
func IsGroupPowerHasMgrDealer(model *domain.Model, groupId mysql.ID) (bool, error) {
var num int64
if err := model.Db.Raw("select count(1) from (select * from diamond_dealer where user_id in "+
"(select user_id from group_power_user where group_power_id = ? and role = ?)) a", groupId, groupPower_e.GroupPowerUserRoleMgr).
Scan(&num).Error; err != nil {
return false, myerr.WrapErr(err)
}
if num > 0 {
return true, nil
}
return false, nil
}
// 某个家族是否有家族代理
func IsGroupPowerHasFamilyAgent(model *domain.Model, groupId mysql.ID) (bool, error) {
var num int64
if err := model.Db.Raw("select count(1) from diamond_dealer where status=1 and is_family_agent=1 and user_id in "+
"(select user_id from group_power_user where group_power_id = ?)", groupId).
Scan(&num).Error; err != nil {
return false, myerr.WrapErr(err)
}
if num > 0 {
return true, nil
}
return false, nil
}
func GetGroupPowerMap(db *gorm.DB, userIds []mysql.ID) (map[mysql.ID]uint64, error) { func GetGroupPowerMap(db *gorm.DB, userIds []mysql.ID) (map[mysql.ID]uint64, error) {
rows := make([]GroupPowerUser, 0) rows := make([]GroupPowerUser, 0)
if len(userIds) > 0 { if len(userIds) > 0 {
...@@ -348,47 +384,28 @@ func GetGroupPowerMap(db *gorm.DB, userIds []mysql.ID) (map[mysql.ID]uint64, err ...@@ -348,47 +384,28 @@ func GetGroupPowerMap(db *gorm.DB, userIds []mysql.ID) (map[mysql.ID]uint64, err
return result, nil return result, nil
} }
func GetGroupPowerNames(db *gorm.DB, ids []mysql.ID) (map[mysql.ID]string, error) { // return
func GetGroupPowerNames(db *gorm.DB, ids []mysql.ID) (map[mysql.ID]string, map[mysql.ID]string, error) {
type record struct { type record struct {
Id mysql.ID Id mysql.ID
Name string Name string
Nameplate string
} }
rows := make([]record, 0) rows := make([]record, 0)
result := make(map[mysql.ID]string, 0)
result2 := make(map[mysql.ID]string, 0)
if len(ids) > 0 { if len(ids) > 0 {
if err := db.Model(&GroupPower{}).Select("p.id, i.name"). if err := db.Model(&GroupPower{}).Select("p.id, i.name,p.nameplate").
Joins("AS p INNER JOIN group_info AS i ON p.group_uid = i.im_group_id"). Joins("AS p INNER JOIN group_info AS i ON p.group_uid = i.im_group_id").
Where("p.id IN ?", ids).Find(&rows).Error; err != nil { Where("p.id IN ?", ids).Find(&rows).Error; err != nil {
return nil, err return result, result2, err
} }
} }
result := make(map[mysql.ID]string, 0)
for _, i := range rows { for _, i := range rows {
result[i.Id] = i.Name result[i.Id] = i.Name
result2[i.Id] = i.Nameplate
} }
return result, nil return result, result2, nil
}
type GroupPowerInfo struct {
PowerId mysql.ID
Owner mysql.ID
Name string
}
func BatchGetGroupPower(db *gorm.DB, ids []mysql.ID) (map[mysql.ID]GroupPowerInfo, error) {
rows := make([]GroupPowerInfo, 0)
if len(ids) > 0 {
if err := db.Model(&GroupPower{}).Select("p.id AS power_id, u.user_id AS owner, p.name").
Joins("AS p INNER JOIN group_power_user AS u ON p.id = u.group_power_id").
Where("p.id IN ? AND p.status = ? AND role = ?", ids, groupPower_e.GroupPowerUserHas, groupPower_e.GroupPowerUserRoleMgr).
Find(&rows).Error; err != nil {
return nil, err
}
}
result := make(map[mysql.ID]GroupPowerInfo, 0)
for _, i := range rows {
result[i.PowerId] = i
}
return result, nil
} }
func GetGroupPower(model *domain.Model, id mysql.ID) (*GroupPower, error) { func GetGroupPower(model *domain.Model, id mysql.ID) (*GroupPower, error) {
...@@ -648,3 +665,36 @@ func GetUserGroupPower(model *domain.Model, userId uint64) (uint64, string, erro ...@@ -648,3 +665,36 @@ func GetUserGroupPower(model *domain.Model, userId uint64) (uint64, string, erro
} }
return gpu.GroupPowerId, powerName, nil return gpu.GroupPowerId, powerName, nil
} }
// 获取势力下的所有群组
func GetGroupPowerGroups(model *domain.Model, groupPowerId mysql.ID) ([]*group_m.GroupInfo, error) {
var res []*group_m.GroupInfo
var ownerIds []mysql.ID
if err := model.DB().Model(GroupPowerUser{}).Select("user_id").Where("group_power_id = ?", groupPowerId).Scan(&ownerIds).Error; err != nil {
model.Log.Errorf("GetGroupPowerGroups fail:%v", err)
return nil, err
}
if len(ownerIds) <= 0 {
return res, nil
}
if err := model.DB().Model(group_m.GroupInfo{}).Where("owner in ?", ownerIds).Find(&res).Error; err != nil {
model.Log.Errorf("GetGroupPowerGroups fail:%v", err)
return nil, err
}
return res, nil
}
// 批量获取势力用户
// return userId->GroupPowerUser
func BatchGetGroupPowerUser(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]GroupPowerUser, error) {
var rows []GroupPowerUser
res := make(map[mysql.ID]GroupPowerUser)
if err := model.Db.Model(GroupPowerUser{}).Where("user_id in ?", userIds).Find(&rows).Error; err != nil {
model.Log.Errorf("BatchGetGroupPowerUser fail:%v", err)
return res, err
}
for i, v := range rows {
res[v.UserId] = rows[i]
}
return res, nil
}
This diff is collapsed.
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-group/_const/enum/groupPower_e"
)
type GroupPowerInfo struct {
mysql.Entity
GroupUid string
Name string
Nameplate string
Declaration string
Icon string
Status int
}
func (GroupPowerInfo) TableName() string {
return "group_power"
}
// 批量获取家族信息
func MGetGroupPowerInfoMap(model *domain.Model, groupPowerIds []mysql.ID) (map[mysql.ID]GroupPowerInfo, error) {
var rows []GroupPowerInfo
res := make(map[mysql.ID]GroupPowerInfo)
if err := model.DB().Model(GroupPowerInfo{}).Where("id in ?", groupPowerIds).Find(&rows).Error; err != nil {
model.Log.Errorf("MGetGroupPowerInfo fail:%v", err)
return res, err
}
for i, v := range rows {
res[v.ID] = rows[i]
}
return res, nil
}
// 批量获取家族成员
func MGetGroupPowerUsers(model *domain.Model, groupPowerIds []mysql.ID) (map[mysql.ID][]*GroupPowerUser, error) {
var users []*GroupPowerUser
res := make(map[mysql.ID][]*GroupPowerUser)
if err := model.DB().Model(GroupPowerUser{}).Where("group_power_id in ?", groupPowerIds).Find(&users).Error; err != nil {
model.Log.Errorf("MGetGroupPowerUsers fail:%v", err)
return res, err
}
for i, v := range users {
res[v.GroupPowerId] = append(res[v.GroupPowerId], users[i])
}
return res, nil
}
// 获取家族成员
func GetGroupPowerUser(model *domain.Model, groupPowerId mysql.ID) ([]*GroupPowerUser, error) {
m, err := MGetGroupPowerUsers(model, []mysql.ID{groupPowerId})
if err != nil {
return nil, err
}
return m[groupPowerId], nil
}
// 获取所有家族的主
func GetAllGroupPowerOwners(model *domain.Model) ([]mysql.ID, error) {
var userIds []mysql.ID
if err := model.DB().Model(GroupPowerUser{}).Select("user_id").
Where("role = ?", groupPower_e.GroupPowerUserRoleMgr).Find(&userIds).Error; err != nil {
model.Log.Errorf("GetAllGroupPowerOwners fail:%v", err)
return userIds, err
}
return userIds, nil
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"gorm.io/gorm"
"hilo-group/common"
"hilo-group/myerr"
"hilo-group/myerr/bizerr"
"time"
)
type GroupPowerApplyJoin struct {
Id uint64 `json:"id"`
UserId uint64 `json:"user_id"`
GroupPowerId uint64 `json:"group_power_id"`
CreatedTime time.Time `json:"created_time"`
UpdatedTime time.Time `json:"updated_time"`
IsAccept int8 `json:"is_accept"`
MgrId uint64 `json:"mgr_id"`
}
func InsertGroupPowerApplyJoin(model *domain.Model, userId, familyId uint64) error {
sql := "insert into group_power_apply_join(user_id,group_power_id,is_accept) " +
"select ?, ?, ? where not exists (select id from group_power_apply_join where user_id=? and group_power_id=? and is_accept=0)"
result := model.Db.Exec(sql, userId, familyId, 0, userId, familyId)
if result.Error != nil {
return myerr.WrapErr(result.Error)
}
if result.RowsAffected <= 0 {
return myerr.WrapErr(bizerr.GroupPowerHaveAlreadyApply)
}
return nil
}
func GetGroupPowerApplyJoin(model *domain.Model, userId, familyId uint64, isAccept int) (*GroupPowerApplyJoin, error) {
res := new(GroupPowerApplyJoin)
db := model.Db.Where(GroupPowerApplyJoin{UserId: userId, GroupPowerId: familyId})
if isAccept != -1 {
db = db.Where("is_accept=?", isAccept)
}
err := db.First(&res).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return res, nil
}
func OptGroupPowerApplyJoinById(model *domain.Model, id, mgrId uint64, optType int) error {
err := model.Db.Exec("update group_power_apply_join set is_accept = ?, mgr_id = ? where id=? and is_accept = 0", optType, mgrId, id).Error
if err != nil {
return myerr.WrapErr(err)
}
return nil
}
func AcceptGroupPowerApplyJoin(model *domain.Model, userId, familyId uint64) error {
err := model.Db.Exec("update group_power_apply_join set is_accept = 1 where user_id=? and group_power_id=?", userId, familyId).Error
if err != nil {
return myerr.WrapErr(err)
}
return nil
}
func OptGroupPowerApplyList(model *domain.Model, familyId uint64, pageSize, pageIndex int) ([]*GroupPowerApplyJoin, int, bool, error) {
rows := make([]*GroupPowerApplyJoin, 0)
db := model.Db.Model(GroupPowerApplyJoin{}).Where("group_power_id = ?", familyId).Order("is_accept, created_time desc")
var count int64
err := db.Count(&count).Error
if err != nil {
return nil, 0, false, err
}
err = db.Limit(pageSize).Offset(pageIndex).Find(&rows).Error
if err != nil {
return nil, 0, false, err
}
nextIdx, hasNext := common.PageNext(count, pageIndex, pageSize)
return rows, nextIdx, hasNext, nil
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-group/myerr"
"time"
)
type GroupPowerInviteJoin struct {
Id uint64 `json:"id"`
UserId uint64 `json:"user_id"`
GroupPowerId uint64 `json:"group_power_id"`
CreatedTime time.Time `json:"created_time"`
UpdatedTime time.Time `json:"updated_time"`
InviteUserId uint64 `json:"invite_user_id"`
IsAccept int8 `json:"is_accept"`
}
func InsertGroupPowerInviteJoin(userId, inviteUserId, familyId uint64) error {
nowTime := time.Now()
sql := "insert into group_power_invite_join(user_id,invite_user_id,group_power_id,is_accept,created_time,updated_time) " +
"value(?,?,?,?,?,?) on duplicate key update is_accept=?,created_time=?,updated_time=?"
err := mysql.Db.Exec(sql, userId, inviteUserId, familyId, 0, nowTime, nowTime, 0, nowTime, nowTime).Error
if err != nil {
return myerr.WrapErr(err)
}
return nil
}
func GetGroupPowerInviteJoin(userId, familyId uint64) (*GroupPowerInviteJoin, error) {
res := new(GroupPowerInviteJoin)
err := mysql.Db.Where(GroupPowerInviteJoin{UserId: userId, GroupPowerId: familyId}).Where("is_accept=0").First(&res).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return res, nil
}
func AcceptGroupPowerInviteJoin(userId, familyId uint64) error {
err := mysql.Db.Exec("update group_power_invite_join set is_accept = 1 where user_id=? and group_power_id=?", userId, familyId).Error
if err != nil {
return myerr.WrapErr(err)
}
return nil
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
)
type GroupPowerExpRank struct {
GroupPowerId mysql.ID
Exp mysql.Num
Rank int
}
// 获取家族经验排行榜
// param limit: 排行榜人数
func GetGroupPowerExpRank(model *domain.Model, beginDate, endDate string, limit int) ([]GroupPowerExpRank, error) {
var res []GroupPowerExpRank
if err := model.DB().Table("group_power_day_exp").Select("group_power_id,SUM(exp) as exp").
Where("date BETWEEN ? AND ?", beginDate, endDate).Group("group_power_id").Order("exp DESC").Limit(limit).Find(&res).Error; err != nil {
model.Log.Errorf("GetGroupPowerExpRank fail:%v", err)
return res, err
}
for i := range res {
res[i].Rank = i + 1
}
return res, nil
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"hilo-group/_const/enum/groupPower_e"
"time"
)
// 家族之星
type GroupPowerMonthStar struct {
Month string
GroupPowerId mysql.ID
UserId mysql.ID
Type groupPower_e.GroupPowerStarType
Score mysql.Num
LastCalTs int64
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 增加家族之星分数
func IncrGroupPowerMonthStarScore(model *domain.Model, groupPowerId, userId mysql.ID, _type groupPower_e.GroupPowerStarType, score mysql.Num, lastCalTs int64) error {
month := time.Now().Format("200601")
star := &GroupPowerMonthStar{
Month: month,
GroupPowerId: groupPowerId,
UserId: userId,
Type: _type,
Score: score,
LastCalTs: lastCalTs,
}
if err := model.DB().Model(GroupPowerMonthStar{}).Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "month"}, {Name: "group_power_id"}, {Name: "user_id"}, {Name: "type"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"score": gorm.Expr("score + ?", star.Score),
"last_cal_ts": lastCalTs,
}),
}).Create(star).Error; err != nil {
model.Log.Errorf("IncrGroupPowerMonthStarScore fail:%v", err)
return err
}
return nil
}
// 获取家族之星分数
// 允许返回gorm.ErrRecordNotFound
func GetGroupPowerMonthStar(model *domain.Model, groupPowerId, userId mysql.ID, _type groupPower_e.GroupPowerStarType) (*GroupPowerMonthStar, error) {
res := new(GroupPowerMonthStar)
month := time.Now().Format("200601")
if err := model.DB().Where("month = ? AND group_power_id = ? AND user_id = ? AND `type` = ?", month, groupPowerId, userId, _type).First(res).Error; err != nil {
return nil, err
}
return res, nil
}
// 获取家族之星排行
func GetGroupPowerMonthStarRank(model *domain.Model, groupPowerId mysql.ID, _type groupPower_e.GroupPowerStarType, offset, limit int) ([]*GroupPowerMonthStar, error) {
var res []*GroupPowerMonthStar
month := time.Now().Format("200601")
if err := model.DB().Model(GroupPowerMonthStar{}).Where("month = ? AND group_power_id = ? AND `type` = ?", month, groupPowerId, _type).
Order("score desc").Offset(offset).Limit(limit).Find(&res).Error; err != nil {
model.Log.Errorf("GetGroupPowerMonthStarRank fail:%v", err)
return res, err
}
return res, nil
}
// 获取家族之星三个排行榜的各自第一名
func GetGroupPowerMonthStartTop1(model *domain.Model, groupPowerId mysql.ID) ([]*GroupPowerMonthStar, error) {
var res []*GroupPowerMonthStar
r1, err := GetGroupPowerMonthStarRank(model, groupPowerId, groupPower_e.GroupPowerStarTypeFamous, 0, 1)
if err != nil {
return res, err
}
r2, err := GetGroupPowerMonthStarRank(model, groupPowerId, groupPower_e.GroupPowerStarTypeActive, 0, 1)
if err != nil {
return res, err
}
r3, err := GetGroupPowerMonthStarRank(model, groupPowerId, groupPower_e.GroupPowerStarTypeCharm, 0, 1)
if err != nil {
return res, err
}
res = append(res, r1...)
res = append(res, r2...)
res = append(res, r3...)
return res, nil
}
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/bluele/gcache" "github.com/bluele/gcache"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-group/_const/enum/group_e" "hilo-group/_const/enum/group_e"
"hilo-group/common"
"hilo-group/myerr" "hilo-group/myerr"
"hilo-group/myerr/bizerr" "hilo-group/myerr/bizerr"
"math/rand" "math/rand"
...@@ -515,29 +516,18 @@ func GetLatestGroupInfos(model *domain.Model, limit, lastId int, groupIds []stri ...@@ -515,29 +516,18 @@ func GetLatestGroupInfos(model *domain.Model, limit, lastId int, groupIds []stri
return return
} }
//func init() { func GetFamilyRooms(model *domain.Model, familyId uint64, pageSize, pageIndex int) ([]*GroupInfo, int, bool, error) {
// // 初始化官方群组 rows := make([]*GroupInfo, 0)
// strGroupIds := strings.Split(config.GetConfigApp().OFFICIAL_GROUP, ",") db := model.Db.Model(GroupInfo{}).Where("owner in (select user_id from group_power_user where group_power_id=? order by field(`role`, 2, 3, 1))", familyId)
// for _, i := range strGroupIds { var count int64
// if len(i) > 0 { err := db.Count(&count).Error
// officialGroup = append(officialGroup, i) if err != nil {
// } return nil, 0, false, err
// } }
// mylogrus.MyLog.Info("Official groups: ", officialGroup) err = db.Limit(pageSize).Offset(pageIndex).Find(&rows).Error
// if err != nil {
// event.AddUserInfoUpdate(func(model *domain.Model, e interface{}) error { return nil, 0, false, err
// event := e.(*event.UserInfoUpdateEvent) }
// if event.Country == nil { nextIdx, hasNext := common.PageNext(count, pageIndex, pageSize)
// return nil return rows, nextIdx, hasNext, nil
// } else { }
// // v2.3需求:同步更新群组country
// model.Log.Infof("Receive userInfoUpdate: user %d, country %s", event.UserId, *event.Country)
// return UpdateCountryByOwner(model, *event.Country, event.UserId)
// }
// })
// event.AddMgrUserCountryUpdateAsync(func(model *domain.Model, event *event.MgrUserCountryUpdateEvent) error {
// // v2.3需求:同步更新群组country
// model.Log.Infof("Receive MgrUserCountryUpdate: user %d, from %s to %s", event.UserId, event.OldCountry, event.NewCountry)
// return UpdateCountryByOwner(model, event.NewCountry, event.UserId)
// })
//}
package mic_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/utils"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"time"
)
// 用户上麦
type UserOnMic struct {
Date string
UserId mysql.ID
Seconds mysql.Num
LastCalTs int64
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 获取用户当日上麦
// 允许返回gorm.ErrRecordNotFound
func GetUserOnMic(model *domain.Model, userId mysql.ID) (*UserOnMic, error) {
res := new(UserOnMic)
day := time.Now().Format("2006-01-02")
if err := model.DB().Where("date = ? AND user_id = ?", day, userId).First(res).Error; err != nil {
return nil, err
}
return res, nil
}
// 增加用户上麦时长
// 事务操作
func IncrUserOnMic(model *domain.Model, userId mysql.ID, joinMicTimestamp int64) error {
return model.Transaction(func(model *domain.Model) error {
omMic, err := GetUserOnMic(model, userId)
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
curTs := joinMicTimestamp
nowTs := time.Now().Unix()
day0Ts := utils.GetZeroTime(time.Now()).Unix()
if omMic != nil && joinMicTimestamp < omMic.LastCalTs { // 加入的时间比上次计算时间小
curTs = omMic.LastCalTs
}
// 跨天
if curTs < day0Ts {
curTs = day0Ts
}
score := nowTs - curTs
day := time.Now().Format("2006-01-02")
onMicNew := &UserOnMic{
Date: day,
UserId: userId,
Seconds: mysql.Num(score),
LastCalTs: nowTs,
}
if err := model.DB().Model(UserOnMic{}).Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "date"}, {Name: "user_id"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"seconds": gorm.Expr("seconds + ?", onMicNew.Seconds),
"last_cal_ts": nowTs,
}),
}).Create(onMicNew).Error; err != nil {
model.Log.Errorf("IncrUserOnMic fail:%v", err)
return err
}
return nil
})
}
// 批量获取用户上麦时长
// @return userId->seconds
func MGetUserOnMicSeconds(model *domain.Model, day string, userIds []uint64) (map[mysql.ID]mysql.Num, error) {
var rows []UserOnMic
res := make(map[mysql.ID]mysql.Num)
if err := model.DB().Model(UserOnMic{}).Where("`date`= ? AND user_id in ?", day, userIds).Find(&rows).Error; err != nil {
model.Log.Errorf("MGetUserOnMic fail:%v", err)
return res, err
}
for _, r := range rows {
res[r.UserId] = r.Seconds
}
return res, nil
}
...@@ -118,3 +118,12 @@ func BatchGetUserByExtIds(model *domain.Model, extIds []string) ([]User, error) ...@@ -118,3 +118,12 @@ func BatchGetUserByExtIds(model *domain.Model, extIds []string) ([]User, error)
} }
return users, nil return users, nil
} }
//获取用户
func GetUsers(model *domain.Model, ids []mysql.ID) ([]*User, error) {
res := make([]*User, 0)
if err := model.Db.WithContext(model.Context).Where("id in (?)", ids).Find(&res).Error; err != nil {
return nil, myerr.WrapErr(err)
}
return res, nil
}
package diamond_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-group/common"
"hilo-group/domain/model/diamond_m"
"hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/res_m"
"hilo-group/myerr"
"hilo-group/myerr/bizerr"
)
type DiamondService struct {
svc *domain.Service
}
func NewDiamondService(myContext *mycontext.MyContext) *DiamondService {
svc := domain.CreateService(myContext)
return &DiamondService{svc}
}
// 币商转账钻石-家族限制检查
func (this *DiamondService) CheckDealerTransferFamilyLimit(dealerId, userId uint64, lang string) error {
model := domain.CreateModelContext(this.svc.MyContext)
// 代理、用户是否加入了家族
dealerFamily, err := groupPower_m.GetGroupPowerUserOrNil(model, dealerId)
if err != nil {
return err
}
// 代理是否是家族代理
isFamilyAgent, err := diamond_m.IsFamilyDiamondDealer(mysql.Db, dealerId)
if err != nil {
return err
}
userFamily, err := groupPower_m.GetGroupPowerUserOrNil(model, userId)
if err != nil {
return err
}
// 用户的家族是否有家族代理
var userHasFamilyAgent bool
if userFamily != nil {
userHasFamilyAgent, err = groupPower_m.IsGroupPowerHasFamilyAgent(model, userFamily.GroupPowerId)
if err != nil {
return err
}
}
if dealerFamily != nil && dealerFamily.GroupPowerId > 0 { // 代理加入了家族
if isFamilyAgent && (userFamily == nil || userFamily.GroupPowerId != dealerFamily.GroupPowerId) { // 是家族代理:只能向本家族成员转移钻石,如果向非家族成员转移钻石,则提示“非家族成员”
return myerr.WrapErr(res_m.GetErrByLanguage(model.Db, common.MSG_ID_NOT_FAMILY_MEMBER, lang, bizerr.GroupPowerDealerNotMember))
}
if !isFamilyAgent && userHasFamilyAgent { // 不是家族代理:如果用户加入了家族,且家族中有家族代理,那么也不能,“此用户已有家族代理,不能出售钻石”
return myerr.WrapErr(res_m.GetErrByLanguage(model.Db, common.MSG_ID_DEALER_CAN_NOT_SOLE, lang, bizerr.GroupPowerDealerCanNotSole))
}
} else { // 代理没有加入家族的
// 普通代理:不能向已经加入家族的成员(并且家族有家族代理)转移钻石,如果转移则提示“此用户已有家族代理,不能出售钻石”
if userHasFamilyAgent {
return myerr.WrapErr(res_m.GetErrByLanguage(model.Db, common.MSG_ID_DEALER_CAN_NOT_SOLE, lang, bizerr.GroupPowerDealerCanNotSole))
}
}
return nil
}
...@@ -3,20 +3,25 @@ package event_s ...@@ -3,20 +3,25 @@ package event_s
import ( import (
"encoding/json" "encoding/json"
"git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/rpc" "git.hilo.cn/hilo-common/rpc"
"git.hilo.cn/hilo-common/sdk/tencentyun" "git.hilo.cn/hilo-common/sdk/tencentyun"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/_const/enum/group_e" "hilo-group/_const/enum/group_e"
"hilo-group/_const/enum/msg_e" "hilo-group/_const/enum/msg_e"
"hilo-group/_const/enum/task_e" "hilo-group/_const/enum/task_e"
"hilo-group/domain/event/gift_ev" "hilo-group/domain/event/gift_ev"
"hilo-group/domain/event/group_ev" "hilo-group/domain/event/group_ev"
"hilo-group/domain/event/group_power_ev" "hilo-group/domain/event/group_power_ev"
"hilo-group/domain/event/mic_ev"
"hilo-group/domain/model/diamond_m" "hilo-group/domain/model/diamond_m"
"hilo-group/domain/model/groupPower_m" "hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/group_m" "hilo-group/domain/model/group_m"
"hilo-group/domain/model/mic_m"
"hilo-group/domain/model/msg_m" "hilo-group/domain/model/msg_m"
"hilo-group/domain/model/task_m" "hilo-group/domain/model/task_m"
"hilo-group/domain/model/user_m" "hilo-group/domain/model/user_m"
"hilo-group/domain/service/group_mic_s"
"hilo-group/myerr" "hilo-group/myerr"
"strconv" "strconv"
"time" "time"
...@@ -28,7 +33,8 @@ func EventInit() { ...@@ -28,7 +33,8 @@ func EventInit() {
GroupEvents() GroupEvents()
GroupImMass() GroupImMass()
GroupTheme() GroupTheme()
SendGift() SendGift() // 送礼事件
OnMic() // 在麦上事件
} }
func GroupSupportEvents() { func GroupSupportEvents() {
...@@ -101,7 +107,7 @@ func GroupSupportEvents() { ...@@ -101,7 +107,7 @@ func GroupSupportEvents() {
} }
func GroupPowerEvents() { func GroupPowerEvents() {
//加入势力 // 加入势力
group_power_ev.AddGroupPowerJoinAsync(func(model *domain.Model, e interface{}) error { group_power_ev.AddGroupPowerJoinAsync(func(model *domain.Model, e interface{}) error {
event, ok := e.(*group_power_ev.GroupPowerJoinEvent) event, ok := e.(*group_power_ev.GroupPowerJoinEvent)
if !ok { if !ok {
...@@ -129,7 +135,7 @@ func GroupPowerEvents() { ...@@ -129,7 +135,7 @@ func GroupPowerEvents() {
msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType) msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType)
return nil return nil
}) })
//离开势力 // 离开势力
group_power_ev.AddGroupPowerLeaveAsync(func(model *domain.Model, e interface{}) error { group_power_ev.AddGroupPowerLeaveAsync(func(model *domain.Model, e interface{}) error {
event, ok := e.(*group_power_ev.GroupPowerLeaveEvent) event, ok := e.(*group_power_ev.GroupPowerLeaveEvent)
if !ok { if !ok {
...@@ -157,6 +163,57 @@ func GroupPowerEvents() { ...@@ -157,6 +163,57 @@ func GroupPowerEvents() {
msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType) msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType)
return nil return nil
}) })
// 势力升级
group_power_ev.AddGroupPowerUpgradeAsync(func(model *domain.Model, e interface{}) error {
event, ok := e.(*group_power_ev.GroupPowerUpgradeEvent)
if !ok {
model.Log.Errorf("AddGroupPowerUpgradeAsync event type err")
return nil
}
model.Log.Infof("msg AddGroupPowerUpgradeAsync GroupPowerId:%v", event.GroupPowerId)
users, err := groupPower_m.GetGroupPowerUser(model, event.GroupPowerId)
if err != nil {
return err
}
var userIds []mysql.ID
for _, u := range users {
userIds = append(userIds, u.UserId)
}
userMaps, err := user_m.GetUserMapByIds(model, userIds)
if err != nil {
return err
}
for uid, u := range userMaps {
if err := msg_m.NewUserRecord(model, uid, msg_e.GroupPowerUpgrade, "", 0, "", "", "", "", "").Persistent(); err != nil {
model.Log.Errorf("msg AddGroupPowerLeaveAsync NewUserRecord err:%v", err)
return nil
}
msg_m.SendEmasMsgAssistant(model, u.ExternalId, u.DeviceType)
}
return nil
})
// 势力等级即将过期
group_power_ev.AddGroupPowerExpireNoticeAsync(func(model *domain.Model, e interface{}) error {
model.Log.Infof("msg AddGroupPowerExpireNoticeAsync")
powerOwners, err := groupPower_m.GetAllGroupPowerOwners(model)
if err != nil {
model.Log.Errorf("AddGroupPowerExpireNoticeAsync fail:%v", err)
return err
}
userMaps, err := user_m.GetUserMapByIds(model, powerOwners)
if err != nil {
return err
}
for uid, u := range userMaps {
if err := msg_m.NewUserRecord(model, uid, msg_e.GroupPowerExpireNotice, "", 0, "", "", "", "", "").Persistent(); err != nil {
model.Log.Errorf("msg AddGroupPowerExpireNoticeAsync NewUserRecord err:%v", err)
return nil
}
msg_m.SendEmasMsgAssistant(model, u.ExternalId, u.DeviceType)
}
return nil
})
} }
func GroupEvents() { func GroupEvents() {
...@@ -397,14 +454,86 @@ func FlushHiloInfo(extId string, isVip bool, isPrettyCode bool, medals []uint32, ...@@ -397,14 +454,86 @@ func FlushHiloInfo(extId string, isVip bool, isPrettyCode bool, medals []uint32,
} }
func SendGift() { func SendGift() {
// 送礼事件-火箭 // 送礼事件-势力经验
gift_ev.AddSendGiftEventAsync(func(model *domain.Model, event interface{}) error { gift_ev.AddSendGiftEventSync(func(model *domain.Model, event interface{}) error {
sendGiftEvent, ok := event.(*gift_ev.SendGiftEvent) sendGiftEvent, ok := event.(*gift_ev.SendGiftEvent)
if !ok { if !ok {
model.Log.Errorf("AddSendGiftEventAsync event type err") model.Log.Errorf("AddSendGiftEventAsync event type err")
return nil return nil
} }
model.Log.Infof("AddSendGiftEventAsync %+v", sendGiftEvent) model.Log.Infof("AddSendGiftEventAsync %+v", sendGiftEvent)
exist, groupPowerId, err := groupPower_m.CheckGroupPowerUser(model, sendGiftEvent.SendUserId)
if err != nil {
model.Log.Infof("CheckGroupPowerUser fail %+v", err)
return err
}
if exist {
exp := sendGiftEvent.GiftN * mysql.Num(len(sendGiftEvent.ReceiveUserIds)) * sendGiftEvent.ResGift.DiamondNum
return groupPower_m.IncrGroupPowerExp(model, groupPowerId, exp, sendGiftEvent.SendUserId, "送礼")
}
return nil
})
// 家族之星-送礼/收礼
gift_ev.AddSendGiftEventAsync(func(model *domain.Model, event interface{}) error {
sendGiftEvent, ok := event.(*gift_ev.SendGiftEvent)
if !ok {
model.Log.Errorf("AddSendGiftEventAsync event type err")
return nil
}
var userIds = []mysql.ID{sendGiftEvent.SendUserId}
userIds = append(userIds, sendGiftEvent.ReceiveUserIds...)
groupPowers, err := groupPower_m.BatchGetGroupPowerUser(model, userIds)
if err != nil {
model.Log.Errorf("AddSendGiftEventAsync fail:%v", err)
return err
}
// 送礼加分
if data, ok := groupPowers[sendGiftEvent.SendUserId]; ok {
diamonds := sendGiftEvent.GiftN * sendGiftEvent.ResGift.DiamondNum * mysql.Num(len(sendGiftEvent.ReceiveUserIds))
if err := groupPower_m.IncrGroupPowerMonthStarScore(model, data.GroupPowerId, data.UserId, groupPower_e.GroupPowerStarTypeFamous, diamonds, 0); err != nil {
model.Log.Errorf("IncrGroupPowerMonthStarScore famous fail:%v", err)
}
}
// 收礼加分
for _, userId := range sendGiftEvent.ReceiveUserIds {
if data, ok := groupPowers[userId]; ok {
diamonds := sendGiftEvent.GiftN * sendGiftEvent.ResGift.DiamondNum
if err := groupPower_m.IncrGroupPowerMonthStarScore(model, data.GroupPowerId, data.UserId, groupPower_e.GroupPowerStarTypeCharm, diamonds, 0); err != nil {
model.Log.Errorf("IncrGroupPowerMonthStarScore charm fail:%v", err)
}
}
}
return nil
})
}
func OnMic() {
// 上麦经验/上麦时长
mic_ev.AddOnMicEventAsync(func(model *domain.Model, e interface{}) error {
event, ok := e.(*mic_ev.OnMicEvent)
if !ok {
model.Log.Errorf("AddOnMicEventSync event type err")
return nil
}
if err := group_mic_s.NewGroupPowerService(model.MyContext).IncrGroupPowerOnMicExpAndTime(event.GroupUuid, event.UserId, event.Timestamp); err != nil {
model.Log.Errorf("cron micIn GroupPowerOnMicExp err:%v", err)
} else {
model.Log.Infof("cron micIn GroupPowerOnMicExp success, groupId:%v, userId:%v", event.GroupUuid, event.UserId)
}
return nil
})
// 用户上麦时长
mic_ev.AddOnMicEventAsync(func(model *domain.Model, e interface{}) error {
event, ok := e.(*mic_ev.OnMicEvent)
if !ok {
model.Log.Errorf("AddOnMicEventSync event type err")
return nil
}
if err := mic_m.IncrUserOnMic(model, event.UserId, event.Timestamp); err != nil {
model.Log.Errorf("cron micIn IncrUserOnMic err:%v", err)
} else {
model.Log.Infof("cron micIn IncrUserOnMic success,userId:%v", event.UserId)
}
return nil return nil
}) })
} }
...@@ -57,7 +57,7 @@ func (s *GiftSendEventService) Consume() error { ...@@ -57,7 +57,7 @@ func (s *GiftSendEventService) Consume() error {
return nil return nil
} }
if err := gift_ev.PublishSendGiftEvent(model, sendGiftEvent); err != nil { if err := gift_ev.PublishSendGiftEvent(model, sendGiftEvent); err != nil {
model.Log.Errorf("PublishSendGiftEvent fail,event:%v,err:%v", cpEvent, err) model.Log.Errorf("PublishSendGiftEvent fail,event:%v,err:%v", string(cpEvent.Payload), err)
return err return err
} }
// 标记已经处理 // 标记已经处理
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"hilo-group/_const/enum/group_e" "hilo-group/_const/enum/group_e"
"hilo-group/_const/redis_key" "hilo-group/_const/redis_key"
"hilo-group/domain/event/group_ev" "hilo-group/domain/event/group_ev"
"hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/group_m" "hilo-group/domain/model/group_m"
"hilo-group/domain/service/signal_s" "hilo-group/domain/service/signal_s"
"hilo-group/myerr" "hilo-group/myerr"
...@@ -287,3 +288,39 @@ func (s *GroupMicService) GroupIMMassByMgr(groupId string, userId uint64, extern ...@@ -287,3 +288,39 @@ func (s *GroupMicService) GroupIMMassByMgr(groupId string, userId uint64, extern
}) })
}) })
} }
// 增加势力上麦经验/时长
func (s *GroupMicService) IncrGroupPowerOnMicExpAndTime(groupId string, userId uint64, joinMicTimestamp int64) error {
var model = domain.CreateModelContext(s.svc.MyContext)
exists, groupPowerId, err := groupPower_m.CheckGroupPowerUser(model, userId)
if err != nil {
return err
}
if !exists {
return nil
}
// 获取势力下所有群组
groups, err := groupPower_m.GetGroupPowerGroups(model, groupPowerId)
if err != nil {
return err
}
inGroup := false
for _, group := range groups {
if group.ImGroupId == groupId {
inGroup = true
break
}
}
if !inGroup {
return nil
}
// 增加势力上麦经验
if err := groupPower_m.IncrGroupPowerExpOnMic(model, groupPowerId, userId, joinMicTimestamp); err != nil {
model.Log.Errorf("IncrGroupPowerExpOnMic fail:%v", err)
}
// 增加势力上麦时长
if err := groupPower_m.IncrGroupPowerStarOnMic(model, groupPowerId, userId, joinMicTimestamp); err != nil {
model.Log.Errorf("IncrGroupPowerOnMicTime fail:%v", err)
}
return nil
}
...@@ -20,6 +20,13 @@ require ( ...@@ -20,6 +20,13 @@ require (
gorm.io/gorm v1.23.8 gorm.io/gorm v1.23.8
) )
require (
github.com/jinzhu/now v1.1.5
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/robfig/cron v1.2.0
github.com/spf13/cast v1.5.0
)
require ( require (
github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src v0.0.0-20200910100525-12b7f1b63a6a // indirect github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src v0.0.0-20200910100525-12b7f1b63a6a // indirect
github.com/KyleBanks/depth v1.2.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect
...@@ -57,7 +64,7 @@ require ( ...@@ -57,7 +64,7 @@ require (
github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.2.0 // indirect github.com/go-playground/validator/v10 v10.2.0 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/golang/protobuf v1.5.0 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/hashicorp/consul/api v1.7.0 // indirect github.com/hashicorp/consul/api v1.7.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
github.com/hashicorp/go-hclog v0.12.0 // indirect github.com/hashicorp/go-hclog v0.12.0 // indirect
...@@ -67,10 +74,8 @@ require ( ...@@ -67,10 +74,8 @@ require (
github.com/hashicorp/golang-lru v0.5.0 // indirect github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/hashicorp/serf v0.9.3 // indirect github.com/hashicorp/serf v0.9.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joho/godotenv v1.3.0 // indirect github.com/joho/godotenv v1.3.0 // indirect
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/json-iterator/go v1.1.9 // indirect github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect github.com/leodido/go-urn v1.2.0 // indirect
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
...@@ -83,8 +88,6 @@ require ( ...@@ -83,8 +88,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.479 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.479 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ims v1.0.479 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ims v1.0.479 // indirect
github.com/tencentyun/tls-sig-api-v2-golang v1.0.0 // indirect github.com/tencentyun/tls-sig-api-v2-golang v1.0.0 // indirect
...@@ -92,7 +95,7 @@ require ( ...@@ -92,7 +95,7 @@ require (
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
golang.org/x/text v0.3.6 // indirect golang.org/x/text v0.3.6 // indirect
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 // indirect golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/grpc v1.42.0 // indirect google.golang.org/grpc v1.42.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
......
This diff is collapsed.
...@@ -59,12 +59,12 @@ TX_OVERSEA_APP_ID=40000066 ...@@ -59,12 +59,12 @@ TX_OVERSEA_APP_ID=40000066
TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c
[EMAS] [EMAS]
REGION_ID=cn-hangzhou REGION_ID=cn-hangzhou
ACCESS_KEY_ID=LTAI4FhNPzxdzD4w6bHirL9Z ACCESS_KEY_ID=LTAIdQZv5H1kNZp5
ACCESS_KEY_SECRET=OQvUJpXDrjGi3g1F2aHiAIFWIvLdbP ACCESS_KEY_SECRET=UnwY0ClDkqBMLwPx3OJJiLYyk9xYLO
ANDROID_APP_KEY=30250713 ANDROID_APP_KEY=30250713
ANDROID_APP_SECRET=cae7b9a9d3e54577d2c3b60bf6d23047 ANDROID_APP_SECRET=cae7b9a9d3e54577d2c3b60bf6d23047
IOS_APP_KEY=30240346 IOS_APP_KEY=30790728
IOS_APP_SECRET=57f33ab9ca6a957a8c659f2b0b6d1205 IOS_APP_SECRET=4fd69ca084c67d4b5a8d15452f0af26a
APNS=DEV APNS=DEV
[AGORA] [AGORA]
APP_ID=fc3e087f701b4f788099e1924c3cc7b0 APP_ID=fc3e087f701b4f788099e1924c3cc7b0
......
...@@ -77,6 +77,20 @@ var ( ...@@ -77,6 +77,20 @@ var (
GroupPowerNotExist = myerr.NewBusinessCode(15004, "国家势力不存在", myerr.BusinessData{}) // 国家势力不存在 GroupPowerNotExist = myerr.NewBusinessCode(15004, "国家势力不存在", myerr.BusinessData{}) // 国家势力不存在
GroupPowerNoOwner = myerr.NewBusinessCode(15005, "power owner not exits or unique", myerr.BusinessData{}) // 国家势力主不存在或不唯一 GroupPowerNoOwner = myerr.NewBusinessCode(15005, "power owner not exits or unique", myerr.BusinessData{}) // 国家势力主不存在或不唯一
GroupPowerStayTooShort = myerr.NewBusinessCode(15006, "You joined this power not more than 10 days ago", myerr.BusinessData{}) // 加入国家势力不超过10天 GroupPowerStayTooShort = myerr.NewBusinessCode(15006, "You joined this power not more than 10 days ago", myerr.BusinessData{}) // 加入国家势力不超过10天
GroupPowerDealerNotMember = myerr.NewBusinessCode(15007, "Not family member", myerr.BusinessData{}) // 代理转账失败-非家族成员
GroupPowerDealerCanNotSole = myerr.NewBusinessCode(15008, "This user already has a family agent and cannot sell diamonds", myerr.BusinessData{}) // 代理转账失败-此用户已有家族代理,不能出售钻石
GroupPowerDealerCanNotBuy = myerr.NewBusinessCode(15009, "Buy diamonds from your family agent", myerr.BusinessData{}) // 请向本家族代理购买钻石
GroupPowerDealerNeedJoin = myerr.NewBusinessCode(15010, "Please join the agent's family to purchase", myerr.BusinessData{}) // 请加入代理的家族后进行购买
GroupPowerHaveNoJoin = myerr.NewBusinessCode(15011, "You have no joined power", myerr.BusinessData{}) // 还未加入国家势力
GroupPowerHaveNoPower = myerr.NewBusinessCode(15012, "You have no power", myerr.BusinessData{}) // 没有权限
GroupPowerHaveNoApply = myerr.NewBusinessCode(15013, "User have no apply", myerr.BusinessData{}) // 没有找到申请
GroupPowerHaveAlreadyApply = myerr.NewBusinessCode(15014, "Already applied", myerr.BusinessData{}) // 已经申请过
GroupPowerHaveAlreadyChange = myerr.NewBusinessCode(15015, "Already changed", myerr.BusinessData{}) // 已经改变了
GroupPowerHaveChangeInfo = myerr.NewBusinessCode(15016, "Setting failed", myerr.BusinessData{}) // 修改失败
GroupPowerHaveTooLong = myerr.NewBusinessCode(15017, "too long", myerr.BusinessData{}) // 长度太长
GroupPowerCannotRepeated = myerr.NewBusinessCode(15018, "Cannot be repeated", myerr.BusinessData{}) // 不能重复
GroupPowerCannotQuit = myerr.NewBusinessCode(15019, "Cannot quit", myerr.BusinessData{}) // 不能退出
GroupPowerUserHaveNoJoin = myerr.NewBusinessCode(15020, "User have no joined power", myerr.BusinessData{}) // 还未加入国家势力
TaskHasAward = myerr.NewBusinessCode(19001, "task has award", myerr.BusinessData{}) TaskHasAward = myerr.NewBusinessCode(19001, "task has award", myerr.BusinessData{})
......
ALTER TABLE hilo.group_power ADD nameplate varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' NOT NULL COMMENT '家族铭牌';
ALTER TABLE hilo.group_power ADD declaration varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' NOT NULL COMMENT '家族宣言';
ALTER TABLE hilo.group_power ADD icon varchar(200) DEFAULT '' NOT NULL COMMENT '家族头像';
update hilo.group_power set nameplate = id;
CREATE UNIQUE INDEX nameplate_IDX USING BTREE ON hilo.group_power (nameplate);
CREATE TABLE `group_power_invite_join` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`user_id` bigint unsigned NOT NULL COMMENT '被邀请者id',
`group_power_id` bigint unsigned NOT NULL,
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`invite_user_id` bigint unsigned NOT NULL COMMENT '邀请者id',
`is_accept` tinyint NOT NULL DEFAULT '0' COMMENT '是否已经接受邀请',
PRIMARY KEY (`id`),
UNIQUE KEY `user_group` (`user_id`,`group_power_id`),
KEY `group_power_id` (`group_power_id`),
KEY `invite_user_id` (`invite_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请加入家族';
CREATE TABLE `group_power_apply_join` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`user_id` bigint unsigned NOT NULL COMMENT '申请者id',
`group_power_id` bigint unsigned NOT NULL,
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_accept` tinyint NOT NULL DEFAULT '0' COMMENT '是否已经接受',
`mgr_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '审核的管理员id',
PRIMARY KEY (`id`),
KEY `group_power_id` (`group_power_id`),
KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='申请加入家族';
CREATE TABLE `group_power_quit_log` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`user_id` bigint unsigned NOT NULL COMMENT '用户id',
`mgr_id` bigint unsigned NOT NULL COMMENT '操作人id',
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`group_power_id` bigint unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`) USING BTREE,
KEY `created_time` (`created_time`) USING BTREE,
KEY `mgr_id` (`mgr_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
\ No newline at end of file
package charge_r
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"github.com/gin-gonic/gin"
"hilo-group/domain/cache/user_c"
"hilo-group/domain/service/diamond_s"
"hilo-group/req"
"hilo-group/resp"
)
// @Tags 充值
// @Summary 是否可以分享充值链接
// @Param externalId query string true "分享对象的external id"
// @Success 200
// @Router /v1/charge/share [get]
func CanShareChargeLink(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
userId, lang, err := req.GetUserIdLang(c, myContext)
if err != nil {
return myContext, err
}
extId := c.Query("externalId")
model := domain.CreateModelContext(myContext)
toUser, err := user_c.GetUserByExternalId(model, extId)
if err != nil {
return myContext, err
}
// 家族限制检查
if err = diamond_s.NewDiamondService(myContext).CheckDealerTransferFamilyLimit(userId, toUser.ID, lang); err != nil {
myContext.Log.Errorf("CanShareChargeLink err:%v", err)
return myContext, err
}
resp.ResponseOk(c, nil)
return myContext, nil
}
This diff is collapsed.
package group_power_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/utils"
"github.com/gin-gonic/gin"
"github.com/jinzhu/now"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/cv/group_power_cv"
"hilo-group/cv/user_cv"
"hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/user_m"
"hilo-group/myerr/bizerr"
"hilo-group/req"
"hilo-group/resp"
"strconv"
"time"
)
// @Tags 国家势力
// @Summary 家族榜单
// @Param token header string true "token"
// @Param nonce header string true "随机数字"
// @Param period path string true "榜单周期 day:日 week:周 month:月"
// @Success 200 {object} group_power_cv.CvGroupPowerRank
// @Router /v1/groupPower/rank/{period} [get]
func GroupPowerRank(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
userId, err := req.GetUserId(c)
if err != nil {
return myContext, err
}
period := c.Param("period")
if period != "day" && period != "week" && period != "month" {
return myContext, bizerr.InvalidParameter
}
var beginDate, endDate string
switch period {
case "day":
beginDate, endDate = time.Now().Format("2006-01-02"), time.Now().Format("2006-01-02")
case "week":
beginDate, endDate = utils.GetMonday(time.Now()).Format("2006-01-02"), utils.GetMonday(time.Now()).AddDate(0, 0, 6).Format("2006-01-02")
case "month":
beginDate, endDate = now.BeginningOfMonth().Format("2006-01-02"), now.EndOfMonth().Format("2006-01-02")
}
var model = domain.CreateModelContext(myContext)
rank, err := groupPower_m.GetGroupPowerExpRank(model, beginDate, endDate, 30)
if err != nil {
return myContext, err
}
var ids []mysql.ID
for _, g := range rank {
ids = append(ids, g.GroupPowerId)
}
response := group_power_cv.CvGroupPowerRank{}
myGroupPower, err := groupPower_m.GetGroupPowerUserOrNil(model, userId)
if err != nil {
return myContext, err
}
if myGroupPower != nil {
ids = append(ids, myGroupPower.GroupPowerId)
}
grades, err := groupPower_m.MGetGroupPowerGrade(model, ids)
if err != nil {
return myContext, err
}
groupPowers, err := groupPower_m.MGetGroupPowerInfoMap(model, ids)
if err != nil {
return myContext, err
}
for _, v := range rank {
if myGroupPower != nil && v.GroupPowerId == myGroupPower.GroupPowerId && myGroupPower.Role == groupPower_e.GroupPowerUserRoleMgr {
response.MyGroupPower = &group_power_cv.CvGroupPowerRankData{
CvGroupPowerBase: group_power_cv.CvGroupPowerBase{
Id: myGroupPower.GroupPowerId,
Icon: groupPowers[myGroupPower.GroupPowerId].Icon,
Name: groupPowers[myGroupPower.GroupPowerId].Name,
Nameplate: groupPowers[myGroupPower.GroupPowerId].Nameplate,
},
CvGroupPowerGrade: group_power_cv.CvGroupPowerGrade{
Grade: grades[myGroupPower.GroupPowerId].Grade,
Exp: v.Exp,
},
Rank: v.Rank,
}
}
response.Items = append(response.Items, group_power_cv.CvGroupPowerRankData{
CvGroupPowerBase: group_power_cv.CvGroupPowerBase{
Id: v.GroupPowerId,
Icon: groupPowers[v.GroupPowerId].Icon,
Name: groupPowers[v.GroupPowerId].Name,
Nameplate: groupPowers[v.GroupPowerId].Nameplate,
},
CvGroupPowerGrade: group_power_cv.CvGroupPowerGrade{
Grade: grades[v.GroupPowerId].Grade,
Exp: v.Exp,
},
Rank: v.Rank,
})
}
if response.MyGroupPower != nil && response.MyGroupPower.Rank == 0 {
response.MyGroupPower.Rank = 31 // 客户端统一显示30+
}
resp.ResponseOk(c, response)
return myContext, nil
}
type GroupPowerStarReq struct {
GroupPowerId mysql.ID `form:"groupPowerId" binding:"required"`
Type groupPower_e.GroupPowerStarType `form:"type" binding:"required"`
PageSize int `form:"pageSize"`
PageIndex int `form:"pageIndex"`
}
// @Tags 国家势力
// @Summary 家族之星
// @Param token header string true "token"
// @Param nonce header string true "随机数字"
// @Param groupPowerId query int true "家族id"
// @Param type query integer true "类型 1:送礼 2:活跃 3:收礼物"
// @Param pageSize query int false "分页大小 默认:30" default(30)
// @Param pageIndex query int false "第几个分页,从1开始 默认:1" default(1)
// @Success 200 {object} []group_power_cv.CvGroupPowerStarData
// @Router /v1/groupPower/star [get]
func GroupPowerStar(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
param := new(GroupPowerStarReq)
if err := c.ShouldBindQuery(param); err != nil {
return myContext, err
}
if param.PageIndex <= 0 {
param.PageIndex = 1
}
if param.PageSize <= 0 {
param.PageSize = 30
}
var model = domain.CreateModelContext(myContext)
offset, limit := (param.PageIndex-1)*param.PageSize, param.PageSize
rank, err := groupPower_m.GetGroupPowerMonthStarRank(model, param.GroupPowerId, param.Type, offset, limit)
if err != nil {
return myContext, err
}
var response []group_power_cv.CvGroupPowerStarData
var userIds []mysql.ID
for _, row := range rank {
userIds = append(userIds, row.UserId)
}
users, err := user_m.GetUserMapByIds(model, userIds)
for _, row := range rank {
user := users[row.UserId]
response = append(response, group_power_cv.CvGroupPowerStarData{
User: user_cv.CvUserTiny{
Id: user.ID,
ExternalId: user.ExternalId,
Code: user.Code,
Nick: user.Nick,
Avatar: user.Avatar,
},
Score: row.Score,
})
}
resp.ResponsePageBaseOk(c, response, 0, false)
return myContext, nil
}
// @Tags 国家势力
// @Summary 家族等级页
// @Param token header string true "token"
// @Param nonce header string true "随机数字"
// @Param groupPowerId query int true "家族id"
// @Success 200 {object} group_power_cv.CvGroupPowerGradeDetail
// @Router /v1/h5/groupPower/grade/detail [get]
func GroupPowerGradeDetail(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys)
userId, err := req.GetUserId(c)
if err != nil {
return myContext, err
}
groupPowerId, err := strconv.ParseUint(c.Query("groupPowerId"), 10, 16)
if err != nil || groupPowerId <= 0 {
return myContext, bizerr.InvalidParameter
}
var model = domain.CreateModelContext(myContext)
groupPowerInfo, err := groupPower_m.MGetGroupPowerInfoMap(model, []mysql.ID{groupPowerId})
if err != nil {
return myContext, err
}
gradeM, err := groupPower_m.MGetGroupPowerGrade(model, []mysql.ID{groupPowerId})
if err != nil {
return myContext, err
}
groupPower, ok := groupPowerInfo[groupPowerId]
if !ok {
return myContext, bizerr.GroupNotFound
}
grade := gradeM[groupPowerId]
nextExp := mysql.Num(0)
if grade.Grade != groupPower_e.GroupPowerGradeMax {
nextExp = groupPower_e.GroupPowerGradeExp[grade.Grade+1]
}
expireAt := ""
if grade.ExpireAt.After(time.Now()) {
expireAt = grade.ExpireAt.Format("2006-01-02")
}
isMember := false
if exits, _, err := groupPower_m.CheckGroupPowerUser(model, userId); err != nil {
return myContext, err
} else if exits {
isMember = true
}
response := group_power_cv.CvGroupPowerGradeDetail{
GroupPowerBase: group_power_cv.CvGroupPowerBase{
Id: groupPower.ID,
Icon: groupPower.Icon,
Name: groupPower.Name,
Nameplate: groupPower.Nameplate,
},
GroupPowerGrade: group_power_cv.CvGroupPowerGrade{
Grade: grade.Grade,
Exp: grade.Exp,
NextExp: nextExp,
ExpireAt: expireAt,
},
ResGradeList: group_power_cv.CvResGradeList,
PrivilegeList: group_power_cv.GroupPowerGradePrivilegeNum[grade.Grade],
IsMember: isMember,
}
resp.ResponseOk(c, response)
return myContext, nil
}
package group_power_r
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/gin-gonic/gin"
"hilo-group/_const/enum/groupPower_e"
"hilo-group/_const/enum/msg_e"
"hilo-group/cv/group_power_cv"
"hilo-group/domain/model/groupPower_m"
"hilo-group/domain/model/msg_m"
"hilo-group/domain/model/user_m"
"hilo-group/resp"
)
type MGetGroupPowerReq struct {
Ids []mysql.ID `form:"ids" binding:"required"`
}
// @Tags 国家势力-内部
// @Summary 批量获取国家势力信息
// @Param ids query string true "用户id,如:ids=1&ids=2&ids=3"
// @Success 200 {object} map[mysql.ID]group_power_cv.CvGroupPowerInfo
// @Router /inner/groupPower/infos [get]
func MGetGroupPowers(c *gin.Context) (*mycontext.MyContext, error) {
myCtx := mycontext.CreateMyContext(c.Keys)
var model = domain.CreateModelContext(myCtx)
var req MGetGroupPowerReq
if err := c.ShouldBindQuery(&req); err != nil {
return myCtx, err
}
groupPowers, err := groupPower_m.MGetGroupPowerInfoMap(model, req.Ids)
if err != nil {
return myCtx, err
}
groupPowerUsers, err := groupPower_m.MGetGroupPowerUsers(model, req.Ids)
if err != nil {
return myCtx, err
}
groupPowerGrade, err := groupPower_m.MGetGroupPowerGrade(model, req.Ids)
if err != nil {
return myCtx, err
}
response := make(map[mysql.ID]group_power_cv.CvGroupPowerInfo)
for groupPowerId, info := range groupPowers {
// 成员上限
var memberMax mysql.Num
grade := groupPowerGrade[groupPowerId].Grade
if grade >= groupPower_e.GroupPowerGrade0 && grade <= groupPower_e.GroupPowerGradeMax {
memberMax = mysql.Num(group_power_cv.GroupPowerGradePrivilegeNum[groupPowerGrade[groupPowerId].Grade][0].Num)
}
memberNum := mysql.Num(len(groupPowerUsers[groupPowerId]))
if memberNum > memberMax {
memberMax = memberNum
}
response[groupPowerId] = group_power_cv.CvGroupPowerInfo{
CvGroupPowerBase: group_power_cv.CvGroupPowerBase{
Id: groupPowerId,
Icon: info.Icon,
Name: info.Name,
Nameplate: info.Nameplate,
},
CvGroupPowerMember: group_power_cv.CvGroupPowerMember{
MemberNum: memberNum,
MemberMax: memberMax,
},
CvGroupPowerGrade: group_power_cv.CvGroupPowerGrade{
Grade: grade,
Exp: groupPowerGrade[groupPowerId].Exp,
},
}
}
resp.ResponseOk(c, response)
return myCtx, nil
}
func Test(c *gin.Context) (*mycontext.MyContext, error) {
var model = domain.CreateModelNil()
if err := msg_m.NewUserRecord(model, 4522, msg_e.GroupPowerUserJoin, "frozen", 4522, "", "", "", "", "").Persistent(); err != nil {
return nil, err
}
mgrUser, _ := user_m.GetUser(model, 4522)
err := msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType)
if err != nil {
return nil, err
}
//err := emas.SendIosMsgAll("全部消息测试")
//if err != nil {
// return nil, err
//}
return nil, nil
}
...@@ -133,7 +133,7 @@ func GetTheirGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -133,7 +133,7 @@ func GetTheirGroups(c *gin.Context) (*mycontext.MyContext, error) {
} }
model.Log.Info("GetTheirGroups: theirRoles - ", theirRoles) model.Log.Info("GetTheirGroups: theirRoles - ", theirRoles)
powerIds, powerNames, err := group_power_cv.BatchGetGroupPower(model.Db, owners) powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil { if err != nil {
return myContext, err return myContext, err
} }
...@@ -275,6 +275,13 @@ func GetTheirGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -275,6 +275,13 @@ func GetTheirGroups(c *gin.Context) (*mycontext.MyContext, error) {
//HasOnMic: onMicScore[i.GroupId] != 0, //HasOnMic: onMicScore[i.GroupId] != 0,
GroupPowerId: powerIds[gi.Owner], GroupPowerId: powerIds[gi.Owner],
GroupPowerName: powerNames[gi.Owner], GroupPowerName: powerNames[gi.Owner],
GroupPowerNameplate: powerNameplates[gi.Owner],
GroupPower: group_cv.GroupPower{
Id: powerIds[gi.Owner],
Name: powerNames[gi.Owner],
Nameplate: powerNameplates[gi.Owner],
Grade: powerGrades[gi.Owner],
},
}, },
MicUsers: micUsers, MicUsers: micUsers,
RoomUserCount: uint(roomCount[i.GroupId]), RoomUserCount: uint(roomCount[i.GroupId]),
...@@ -362,7 +369,7 @@ func PluginReady(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -362,7 +369,7 @@ func PluginReady(c *gin.Context) (*mycontext.MyContext, error) {
// @Param token header string true "token" // @Param token header string true "token"
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId path string true "群ID" // @Param groupId path string true "群ID"
// @Success 200 {object} cv.RoomInfo // @Success 200 {object} group_cv.RoomInfo
// @Router /v1/imGroup/roomInfo/{groupId} [get] // @Router /v1/imGroup/roomInfo/{groupId} [get]
func GetRoomInfo(c *gin.Context) (*mycontext.MyContext, error) { func GetRoomInfo(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
...@@ -1195,7 +1202,7 @@ func GroupMedalAll(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -1195,7 +1202,7 @@ func GroupMedalAll(c *gin.Context) (*mycontext.MyContext, error) {
// @Param token header string true "token" // @Param token header string true "token"
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId query string false "群ID" // @Param groupId query string false "群ID"
// @Success 200 {object} cv.RoomMedalInfo // @Success 200 {object} group_cv.RoomMedalInfo
// @Router /v1/imGroup/medal/room [get] // @Router /v1/imGroup/medal/room [get]
func GetRoomMedal(c *gin.Context) (*mycontext.MyContext, error) { func GetRoomMedal(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
......
...@@ -246,7 +246,7 @@ func GetPopularGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -246,7 +246,7 @@ func GetPopularGroups(c *gin.Context) (*mycontext.MyContext, error) {
groupIds = append(groupIds, i.ImGroupId) groupIds = append(groupIds, i.ImGroupId)
owners = append(owners, i.Owner) owners = append(owners, i.Owner)
} }
powerIds, powerNames, err := group_power_cv.BatchGetGroupPower(model.Db, owners) powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil { if err != nil {
return myContext, err return myContext, err
} }
...@@ -341,6 +341,13 @@ func GetPopularGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -341,6 +341,13 @@ func GetPopularGroups(c *gin.Context) (*mycontext.MyContext, error) {
HasOnMic: true, HasOnMic: true,
GroupPowerId: powerIds[i.Owner], GroupPowerId: powerIds[i.Owner],
GroupPowerName: powerNames[i.Owner], GroupPowerName: powerNames[i.Owner],
GroupPowerNameplate: powerNameplates[i.Owner],
GroupPower: group_cv.GroupPower{
Id: powerIds[i.Owner],
Name: powerNames[i.Owner],
Nameplate: powerNameplates[i.Owner],
Grade: powerGrades[i.Owner],
},
}, },
MicUsers: micUsers, MicUsers: micUsers,
RoomUserCount: uint(roomCount[i.ImGroupId]), RoomUserCount: uint(roomCount[i.ImGroupId]),
...@@ -468,7 +475,7 @@ func GetLatestGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -468,7 +475,7 @@ func GetLatestGroups(c *gin.Context) (*mycontext.MyContext, error) {
for _, group := range groupInfos { for _, group := range groupInfos {
owners = append(owners, group.Owner) owners = append(owners, group.Owner)
} }
powerIds, powerNames, err := group_power_cv.BatchGetGroupPower(model.Db, owners) powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil { if err != nil {
return myContext, err return myContext, err
} }
...@@ -558,6 +565,13 @@ func GetLatestGroups(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -558,6 +565,13 @@ func GetLatestGroups(c *gin.Context) (*mycontext.MyContext, error) {
HasOnMic: true, HasOnMic: true,
GroupPowerId: powerIds[group.Owner], GroupPowerId: powerIds[group.Owner],
GroupPowerName: powerNames[group.Owner], GroupPowerName: powerNames[group.Owner],
GroupPowerNameplate: powerNameplates[group.Owner],
GroupPower: group_cv.GroupPower{
Id: powerIds[group.Owner],
Name: powerNames[group.Owner],
Nameplate: powerNameplates[group.Owner],
Grade: powerGrades[group.Owner],
},
}, },
MicUsers: micUsers, MicUsers: micUsers,
RoomUserCount: uint(roomCount[group.ImGroupId]), RoomUserCount: uint(roomCount[group.ImGroupId]),
...@@ -1150,7 +1164,7 @@ func buildRoleMembers(model *domain.Model, groupId string, userId uint64) ([]gro ...@@ -1150,7 +1164,7 @@ func buildRoleMembers(model *domain.Model, groupId string, userId uint64) ([]gro
// @Param countryShortName query string true "国家缩写" // @Param countryShortName query string true "国家缩写"
// @Param pageSize query int true "分页大小 默认:10" default(10) // @Param pageSize query int true "分页大小 默认:10" default(10)
// @Param pageIndex query int true "第几个分页,从1开始 默认:1" default(1) // @Param pageIndex query int true "第几个分页,从1开始 默认:1" default(1)
// @Success 200 {object} cv.PopularGroupInfo // @Success 200 {object} group_cv.PopularGroupInfo
// @Router /v1/imGroup/country [get] // @Router /v1/imGroup/country [get]
func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) { func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
...@@ -1289,7 +1303,7 @@ func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -1289,7 +1303,7 @@ func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) {
groupIds = append(groupIds, i.ImGroupId) groupIds = append(groupIds, i.ImGroupId)
owners = append(owners, i.Owner) owners = append(owners, i.Owner)
} }
powerIds, powerNames, err := group_power_cv.BatchGetGroupPower(model.Db, owners) powerIds, powerNames, powerNameplates, powerGrades, err := group_power_cv.BatchGetGroupPower(model.Db, owners)
if err != nil { if err != nil {
return myContext, err return myContext, err
} }
...@@ -1372,6 +1386,13 @@ func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -1372,6 +1386,13 @@ func GetGroupByCountry(c *gin.Context) (*mycontext.MyContext, error) {
HasOnMic: micGroupNum[i.ImGroupId] > 0, HasOnMic: micGroupNum[i.ImGroupId] > 0,
GroupPowerId: powerIds[i.Owner], GroupPowerId: powerIds[i.Owner],
GroupPowerName: powerNames[i.Owner], GroupPowerName: powerNames[i.Owner],
GroupPowerNameplate: powerNameplates[i.Owner],
GroupPower: group_cv.GroupPower{
Id: powerIds[i.Owner],
Name: powerNames[i.Owner],
Nameplate: powerNameplates[i.Owner],
Grade: powerGrades[i.Owner],
},
}, },
MicUsers: []user_cv.CvUserTiny{}, MicUsers: []user_cv.CvUserTiny{},
RoomUserCount: uint(roomCount[i.ImGroupId]), RoomUserCount: uint(roomCount[i.ImGroupId]),
...@@ -1436,7 +1457,7 @@ func getCandidatesByCountry(model *domain.Model, bannedGroups map[string]uint64, ...@@ -1436,7 +1457,7 @@ func getCandidatesByCountry(model *domain.Model, bannedGroups map[string]uint64,
// @Param signature header string true "sha1加密结果" // @Param signature header string true "sha1加密结果"
// @Param deviceType header string true "系统类型 ios android" // @Param deviceType header string true "系统类型 ios android"
// @Param deviceVersion header string true "系统版本" // @Param deviceVersion header string true "系统版本"
// @Success 200 {object} cv.CvCountry // @Success 200 {object} group_cv.CvCountry
// @Router /v1/imGroup/country/prior [get] // @Router /v1/imGroup/country/prior [get]
func GroupountryPrior(c *gin.Context) (*mycontext.MyContext, error) { func GroupountryPrior(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
......
...@@ -921,7 +921,7 @@ func GroupMicMute(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -921,7 +921,7 @@ func GroupMicMute(c *gin.Context) (*mycontext.MyContext, error) {
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId formData string true "群ID" // @Param groupId formData string true "群ID"
// @Param content formData string true "内容" // @Param content formData string true "内容"
// @Success 200 {object} cv.CvDiamond // @Success 200 {object} diamond_cv.CvDiamond
// @Router /v1/imGroup/mic/mass [post] // @Router /v1/imGroup/mic/mass [post]
func GroupMicMass(c *gin.Context) (*mycontext.MyContext, error) { func GroupMicMass(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
...@@ -960,7 +960,7 @@ func GroupMicMass(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -960,7 +960,7 @@ func GroupMicMass(c *gin.Context) (*mycontext.MyContext, error) {
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId formData string true "群ID" // @Param groupId formData string true "群ID"
// @Param content formData string true "内容" // @Param content formData string true "内容"
// @Success 200 {object} cv.CvDiamond // @Success 200 {object} diamond_cv.CvDiamond
// @Router /v1/imGroup/mgr/mass [post] // @Router /v1/imGroup/mgr/mass [post]
func GroupMgrMass(c *gin.Context) (*mycontext.MyContext, error) { func GroupMgrMass(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
......
...@@ -67,7 +67,7 @@ func GetSupportPage(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -67,7 +67,7 @@ func GetSupportPage(c *gin.Context) (*mycontext.MyContext, error) {
// @Param token header string true "token" // @Param token header string true "token"
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId query string false "群ID" // @Param groupId query string false "群ID"
// @Success 200 {object} cv.SupportPageDetail // @Success 200 {object} group_cv.SupportPageDetail
// @Router /v1/imGroup/support/detail [get] // @Router /v1/imGroup/support/detail [get]
func GetSupportDetail(c *gin.Context) (*mycontext.MyContext, error) { func GetSupportDetail(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
...@@ -256,7 +256,7 @@ func TryAddSupporter(c *gin.Context) (*mycontext.MyContext, error) { ...@@ -256,7 +256,7 @@ func TryAddSupporter(c *gin.Context) (*mycontext.MyContext, error) {
// @Param nonce header string true "随机数字" // @Param nonce header string true "随机数字"
// @Param groupId path string true "群ID" // @Param groupId path string true "群ID"
// @Param supporters formData string false "群支持者的externalId,用逗号分隔" // @Param supporters formData string false "群支持者的externalId,用逗号分隔"
// @Success 200 {object} cv.AwardResult // @Success 200 {object} group_cv.AwardResult
// @Router /v1/imGroup/support/award/{groupId} [post] // @Router /v1/imGroup/support/award/{groupId} [post]
func TakeSupportAward(c *gin.Context) (*mycontext.MyContext, error) { func TakeSupportAward(c *gin.Context) (*mycontext.MyContext, error) {
myContext := mycontext.CreateMyContext(c.Keys) myContext := mycontext.CreateMyContext(c.Keys)
......
package mic_r
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/gin-gonic/gin"
"hilo-group/domain/model/mic_m"
"hilo-group/resp"
)
type MGetUserOnMicSecondsReq struct {
Day string `form:"day" binding:"required"`
Ids []mysql.ID `form:"ids" binding:"required"`
}
// @Tags 麦位-内部
// @Summary 批量获取用户天上麦时长
// @Param day query string true "天 格式2006-001-02"
// @Param ids query string true "用户id,如:ids=1&ids=2&ids=3"
// @Success 200 {object} map[uint64]uint32
// @Router /inner/mic/onMicSeconds [get]
func MGetUserOnMicSeconds(c *gin.Context) (*mycontext.MyContext, error) {
myCtx := mycontext.CreateMyContext(c.Keys)
var model = domain.CreateModelContext(myCtx)
var req MGetUserOnMicSecondsReq
if err := c.ShouldBindQuery(&req); err != nil {
return myCtx, err
}
onMic, err := mic_m.MGetUserOnMicSeconds(model, req.Day, req.Ids)
if err != nil {
return myCtx, err
}
response := onMic
resp.ResponseOk(c, response)
return myCtx, nil
}
...@@ -9,8 +9,10 @@ import ( ...@@ -9,8 +9,10 @@ import (
"hilo-group/_const/enum/mgr_e" "hilo-group/_const/enum/mgr_e"
_ "hilo-group/docs" _ "hilo-group/docs"
"hilo-group/domain/model/mgr_m" "hilo-group/domain/model/mgr_m"
"hilo-group/route/charge_r"
"hilo-group/route/group_power_r" "hilo-group/route/group_power_r"
"hilo-group/route/group_r" "hilo-group/route/group_r"
"hilo-group/route/mic_r"
) )
func InitRouter() *gin.Engine { func InitRouter() *gin.Engine {
...@@ -125,7 +127,40 @@ func InitRouter() *gin.Engine { ...@@ -125,7 +127,40 @@ func InitRouter() *gin.Engine {
groupPower.GET("/team", wrapper(group_power_r.GroupPowerTeam)) groupPower.GET("/team", wrapper(group_power_r.GroupPowerTeam))
groupPower.GET("/billboard/week", wrapper(group_power_r.GroupPowerBillboardWeek)) groupPower.GET("/billboard/week", wrapper(group_power_r.GroupPowerBillboardWeek))
groupPower.GET("/billboard/owner/week", wrapper(group_power_r.GroupPowerBillboardOwnerWeek)) groupPower.GET("/billboard/owner/week", wrapper(group_power_r.GroupPowerBillboardOwnerWeek))
groupPower.GET("/info", wrapper(group_power_r.GroupPowerInfo))
groupPower.GET("/rooms", wrapper(group_power_r.GroupPowerRooms))
groupPower.GET("/members", wrapper(group_power_r.GroupPowerMembers))
groupPower.POST("/apply", wrapper(group_power_r.GroupPowerApplyJoin))
groupPower.POST("/apply/pass", wrapper(group_power_r.GroupPowerApplyPass))
groupPower.GET("/apply/list", wrapper(group_power_r.GroupPowerApplyList))
groupPower.POST("/quit", wrapper(group_power_r.GroupPowerQuit))
groupPower.GET("/quit/list", wrapper(group_power_r.GroupPowerQuitList))
groupPower.POST("/admin", wrapper(group_power_r.GroupPowerSetAdmin))
groupPower.GET("/rank/:period", wrapper(group_power_r.GroupPowerRank))
groupPower.GET("/star", wrapper(group_power_r.GroupPowerStar))
groupPower.POST("/info/set", wrapper(group_power_r.GroupPowerSetInfo))
} }
h5GroupPower := v1.Group("/h5/groupPower")
{
h5GroupPower.GET("/grade/detail", wrapper(group_power_r.GroupPowerGradeDetail))
}
charge := v1.Group("/charge")
{
charge.GET("/share", wrapper(charge_r.CanShareChargeLink))
}
// 内部接口
inner := r.Group("/inner")
innerGroupPower := inner.Group("/groupPower")
{
innerGroupPower.GET("/infos", wrapper(group_power_r.MGetGroupPowers))
}
innerMic := inner.Group("/mic")
{
innerMic.GET("/onMicSeconds", wrapper(mic_r.MGetUserOnMicSeconds))
}
r.GET("/test", wrapper(group_power_r.Test))
return r return r
} }
......
MODE=local
package test
import (
"git.hilo.cn/hilo-common/domain"
"hilo-group/domain/model/groupPower_m"
"testing"
)
func TestGetAllGroupPowerOwner(t *testing.T) {
owners, err := groupPower_m.GetAllGroupPowerOwners(domain.CreateModelNil())
println(owners, err)
}
[DATABASE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=240h
[GAMEJWT]
SECRET=hilo1632
ISSUER_CLIENT=hiloClient
ISSUER_SERVER=hiloServer
EXPIRE=240h
[APP]
MASTER=false
BIZ_SECRET=biz
WEB_SECRET=webHilo1258
OPERATION_SECRET=operation1258236
SUPERUSER=2701,2831
OFFICIAL_STAFF=2701,2831
OFFICIAL_GROUP=@TGS#3NC2ATRHS,@TGS#33W3KNLHK
MINIMAL_VERSION_ANDROID=212
MINIMAL_VERSION_IOS=100
MODERATE=AWS
[OSS]
OSS_ACCESS_KEY_ID=LTAIxdazV2pCuV3T
OSS_ACCESS_KEY_SECRET=zuAnreAXQ6vlAKnvvmolFLfb1N5w5S
OSS_ROLE_ARN=acs:ram::1509841556585969:role/aliyunosstokengeneratorrole
OSS_END_POINT=http://oss-accelerate.aliyuncs.com
OSS_BUCKET=starvoice
OSS_CDN=https://oss.chathot.me/
OSS_EXPIRED_TIME=3600
OSS_STS_POINT=me-east-1
OSS_STS=sts-faceline-demo
OSS_STS_AES=484194d4d0f968a7
[AWS]
AWS_BUCKET=starchat
AWS_CDN=https://image.whoisamy.shop/
AWS_DIR=hilo/
CONFIDENCE=80
[RONGYUN]
RONG_CLOUD_APP_KEY=pvxdm17jpe9tr
RONG_CLOUD_APP_SECRET=rI4giiKWaBS4
RONG_CLOUD_URL=https://api-sg01.ronghub.com
[TENCENTYUN]
TENCENTYUN_APP_ID=1400548270
TENCENTYUN_KEY=321bd60f73096b059c7350f1cd97d51028850b34fa58c5c0d26bb4a19e783de8
TX_OVERSEA_APP_ID=40000066
TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c
[EMAS]
REGION_ID=cn-hangzhou
ACCESS_KEY_ID=LTAI4FhNPzxdzD4w6bHirL9Z
ACCESS_KEY_SECRET=OQvUJpXDrjGi3g1F2aHiAIFWIvLdbP
ANDROID_APP_KEY=30250713
ANDROID_APP_SECRET=cae7b9a9d3e54577d2c3b60bf6d23047
IOS_APP_KEY=30240346
IOS_APP_SECRET=57f33ab9ca6a957a8c659f2b0b6d1205
APNS=DEV
[AGORA]
APP_ID=fc3e087f701b4f788099e1924c3cc7b0
APP_CERTIFICATE=ff29c100a613433db82324e8411eabc8
CUSTOMER_KEY=6b132c0ff7164560a2bc53fda06ea85a
CUSTOMER_SECRET=eedad2cd16d24834990d5450ace9f1ce
CALLBACK_SECRET=n_ZizS_N8
[CHECKOUT]
AUTHORIZATION=sk_test_9b5e771c-5a3f-4a8d-a4da-31b19bd43d83
URL=https://api.sandbox.checkout.com/hosted-payments
H5=http://test.chathot.me/action/hiloHtml/22_05_30_recharge/topup.html
HILO_SECRET_KEY=sk_test_dfbaa3b6-135d-4376-9996-2089b7d8a086
[MATCH]
MATCH_FREE_TIME=60
MATCH_FREE_TIME_VIP=300
MATCH_ADD_TIME_FREE=90
MATCH_AGORA_TIME=30
MATCH_CYCLE=8
MATCH_USER_EXPIRES=480
MATCH_SUCCESS_WAIT_DURATION=10
MATCH_SUCCESS_SINGLE_WAIT_TIME_IN_SEC=12
MATCH_SUCCESS_DUAL_WAIT_TIME_IN_SEC=15
[ONLINE]
ONLINE_CYCLE=600
ONLINE_USER_EXPIRES=259200
[VIDEO]
VIDEO_DAILY_FREE_NUM=20
VIDEO_FREE_TIME=60
VIDEO_FREE_TIME_VIP=300
VIDEO_ADD_TIME_FREE=60
VIDEO_AGORA_TIME=30
VIDEO_MINUTE_NORMAL=1000
VIDEO_MINUTE_UNION=2000
[SESSION]
SESSION_DAILY_FREE_NUM=50
[BEAN]
DIAMOND_BEAN_RATE=90
[H5]
USER_LEVEL=http://test.chathot.me/action/activityhtml/hiloUserLevel/index.html
GROUP_SUPPORT=http://test.chathot.me/action/activityhtml/21_12_06/page.html
LUCKY_WHEEL=https://h5.whoisamy.shop/action/activityhtml/21_12_30/page.html
NOBLE_BUY_IOS=https://h5.whoisamy.shop/action/hiloHtml/lxt_h5/page.html
[GROUPIM]
MSG_SORT_EXPIRE=43200
MSG_SORT_SNAP=300
[GRADE]
CHARM_SPEED_VIP=15
ACTITY_SPEED_VIP=15
WEALTH_SPEED_VIP=15
[LIKE]
I_LIKE_NUM=30
I_LIKE_NUM_VIP=100
I_LIKE_NUM_NOBLE=1000
[APPLEPAY]
PASSWORD=38702750a05c4cb09c9d6ca646835634
[REGISTER]
IMEI_TOTAL=3
IMEI_OAUTH=2
ACCOUNT_IP=100
ACCOUNT_IP_DURATION=21600
[BANNER]
GIFT_BANNER_LEVEL1=100
GIFT_BANNER_LEVEL2=2000
GIFT_BANNER_LEVEL3=5000
[DIAMOND]
DAILY_LOGIN_IMEI_LIMIT=200
DAILY_LOGIN_IP_LIMIT=5
PRIVATE_GIFT_RETURN=1440
NEW_USER_INVITE_AWARD=5000
[LUCKY_WHEEL]
MINIMAL_PARTICIPANT=2
WAIT_TIMELONG=10
WINNER_DIAMOND_BANNER=100
[GROUP_CUSTOM_THEME]
PIC_LIMIT=5
DAY=10
[GIFT]
WALL_DIAMOND=10
[DAILY]
LOGIN_COMMON=5
LOGIN_VIP=300
[DAILY]
LOGIN_COMMON=5
LOGIN_VIP=300
[FRUIT_TYCOON]
POOL_RATIO=20
WATERMELON_RATIO=70
[ACTIVITY]
COUNTRY_STAR_POOL_RATIO=20
COUNTRY_STAR_ORDINARY_RATIO=20
[PAYER_MAX]
URL=https://pay-gate-uat.payermax.com/aggregate-pay-gate/api/gateway
KEY=d50d149a883b8bb6
MERCHANT_ID=SP11018326
BIZ_TYPE=CUSTOMIZE
VERSION=2.3
FRONT_CALLBACK_URL=https://www.hiloconn.com
SHOW_RESULT=1
EXPIRE_TIME=1800
LANGUAGE=en
[SUD]
API_LIST=https://sim-asc.sudden.ltd
[URL]
BIZ_HTTP=https://test.apiv1.faceline.live
\ No newline at end of file
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