Commit f3d1cdca authored by hujiebin's avatar hujiebin

Feature/on mic

parent cc2946f0
package groupPower_k
// groupPower等级
const (
GroupPowerGradeExpQueue = "group_power_grade_exp_queue"
)
func GetGroupPowerGradeExpQueue() string {
return GroupPowerGradeExpQueue
}
...@@ -10,9 +10,17 @@ import ( ...@@ -10,9 +10,17 @@ import (
const ( const (
MicPrefix = "mic:" MicPrefix = "mic:"
MicDayInvite = MicPrefix + "day:invite:${userId}:${date}" // string 自动被邀请上麦,1天一次,TTL:24H MicDayInvite = MicPrefix + "day:invite:${userId}:${date}" // string 自动被邀请上麦,1天一次,TTL:24H
MicGroupPowerOnMic = MicPrefix + "groupPower:${userId}:${date}" // 家族内群上麦分钟数
) )
func GetUserMicDayInvite(userId mysql.ID) string { func GetUserMicDayInvite(userId mysql.ID) string {
date := time.Now().Format("2006-01-02") date := time.Now().Format("2006-01-02")
return redis_key.ReplaceKey(MicDayInvite, fmt.Sprintf("%d", userId), date) return redis_key.ReplaceKey(MicDayInvite, fmt.Sprintf("%d", userId), date)
} }
// 家族内群上麦分钟数
func GetMicGroupPowerOnMic(userId uint64) string {
date := time.Now().Format("2006-01-02")
return redis_key.ReplaceKey(MicGroupPowerOnMic, fmt.Sprintf("%d", userId), date)
}
...@@ -19,7 +19,6 @@ func Init() { ...@@ -19,7 +19,6 @@ func Init() {
group_cron.GroupPowerExpClear() // 清理家族经验/等级 group_cron.GroupPowerExpClear() // 清理家族经验/等级
group_cron.GroupPowerMonthRankAct() group_cron.GroupPowerMonthRankAct()
//group_cron.GroupInEventInit() // 进房事件 //group_cron.GroupInEventInit() // 进房事件
group_cron.GroupPowerGradeExp() // 家族升级(上麦事件会用到) todo 待优化
group_cron.CreateGroup() // group_cron.CreateGroup() //
group_cron.CalcGroupSupport() // 群组扶持计算 group_cron.CalcGroupSupport() // 群组扶持计算
} }
package group_cron
import (
"git.hilo.cn/hilo-common/domain"
"hilo-group/domain/cache/groupPower_c"
"hilo-group/domain/model/groupPower_m"
)
func GroupPowerGradeExp() {
go func() {
for true {
model := domain.CreateModelNil()
if data := groupPower_c.BLPopGroupPowerGradeExp(model); data != nil {
if err := model.Transaction(func(model *domain.Model) error {
return groupPower_m.IncrGroupPowerExp(model, data.GroupPowerId, data.Exp, data.UserId, data.Remark)
}); err != nil {
model.Log.Errorf("IncrGroupPowerExp fail,data:%v-err:%v", data, err)
} else {
model.Log.Infof("IncrGroupPowerExp success,data:%v", data)
}
}
}
}()
}
package groupPower_c
import (
"encoding/json"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/go-redis/redis/v8"
"hilo-group/_const/redis_key/groupPower_k"
"time"
)
type GroupPowerGradeExp struct {
GroupPowerId mysql.ID
Exp mysql.Num
UserId mysql.ID
Remark string
Ts int64
}
// redis队列缓冲GroupPowerGradeExp升级内容
func QueueGroupPowerGradeExp(model *domain.Model, groupPowerId mysql.ID, exp mysql.Num, userId mysql.ID, remark string) error {
queue := groupPower_k.GetGroupPowerGradeExpQueue()
data := GroupPowerGradeExp{
GroupPowerId: groupPowerId,
Exp: exp,
UserId: userId,
Remark: remark,
Ts: time.Now().Unix(),
}
body, _ := json.Marshal(data)
return model.Redis.RPush(model, queue, string(body)).Err()
}
// redis弹出GroupPowerGradeExp升级内容
func BLPopGroupPowerGradeExp(model *domain.Model) *GroupPowerGradeExp {
var res *GroupPowerGradeExp
queue := groupPower_k.GetGroupPowerGradeExpQueue()
strs, err := model.Redis.BLPop(model, time.Second, queue).Result()
if err != nil {
if err != redis.Nil {
model.Log.Errorf("BLPopGroupPowerGradeExp fail:%v", err)
}
return nil
}
if len(strs) >= 2 {
content := strs[1]
res = new(GroupPowerGradeExp)
if err := json.Unmarshal([]byte(content), res); err != nil {
model.Log.Errorf("BLPopGroupPowerGradeExp json fail:%v", err)
return nil
}
return res
}
return nil
}
...@@ -8,7 +8,7 @@ import ( ...@@ -8,7 +8,7 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"hilo-group/_const/enum/groupPower_e" "hilo-group/_const/enum/groupPower_e"
"hilo-group/domain/cache/groupPower_c" "hilo-group/_const/redis_key/mic_k"
"hilo-group/domain/event/group_power_ev" "hilo-group/domain/event/group_power_ev"
"time" "time"
) )
...@@ -41,25 +41,6 @@ type GroupPowerExpDetail struct { ...@@ -41,25 +41,6 @@ type GroupPowerExpDetail struct {
Remark string Remark string
} }
type GroupPowerOnMic struct {
Date string
GroupPowerId mysql.ID
UserId mysql.ID
Seconds int64
LastCalTs int64
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
type GroupPowerOnMicDetail struct {
Date string
GroupPowerId mysql.ID
UserId mysql.ID
Minute int
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 增加家族经验 // 增加家族经验
// 达到经验值之后升级 // 达到经验值之后升级
// 单进程同步执行,不考虑并发 // 单进程同步执行,不考虑并发
...@@ -153,155 +134,70 @@ func IncrGroupPowerExp(txModel *domain.Model, groupPowerId mysql.ID, exp mysql.N ...@@ -153,155 +134,70 @@ func IncrGroupPowerExp(txModel *domain.Model, groupPowerId mysql.ID, exp mysql.N
return nil return nil
} }
// 获取势力用户上麦加经验记录
func GetGroupPowerUserOnMicDetails(model *domain.Model, groupPowerId, userId mysql.ID) ([]*GroupPowerOnMicDetail, error) {
var res []*GroupPowerOnMicDetail
date := time.Now().Format("2006-01-02")
if err := model.DB().Model(GroupPowerOnMicDetail{}).Where("date = ? AND group_power_id = ? AND user_id = ?", date, groupPowerId, userId).Find(&res).Error; err != nil {
return res, err
}
return res, nil
}
// 获取势力用户上麦记录
func GetGroupPowerOnMic(model *domain.Model, groupPowerId, userId mysql.ID) (*GroupPowerOnMic, error) {
gpom := new(GroupPowerOnMic)
date := time.Now().Format("2006-01-02")
if err := model.DB().Model(GroupPowerOnMic{}).Where("date = ? AND group_power_id = ? AND user_id = ?", date, groupPowerId, userId).First(gpom).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return &GroupPowerOnMic{Date: date, GroupPowerId: groupPowerId, UserId: userId}, nil
}
return nil, err
}
return gpom, nil
}
const MaxMinuteTimes = 18
// 增加势力上麦经验 // 增加势力上麦经验
// 事务操作 // 事务操作
func IncrGroupPowerExpOnMic(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error { func IncrGroupPowerExpOnMic(model *domain.Model, groupPowerId, userId mysql.ID) error {
return model.Transaction(func(model *domain.Model) error { key := mic_k.GetMicGroupPowerOnMic(userId)
// 获取用户上麦奖励历史 minutes, err := model.Redis.IncrBy(model, key, 1).Result()
onMicDetails, err := GetGroupPowerUserOnMicDetails(model, groupPowerId, userId) if err != nil {
if err != nil { model.Log.Errorf("IncrGroupPowerExpOnMic fail:%v", err)
return err return err
} }
numDetails := len(onMicDetails) model.Redis.Expire(model, key, time.Hour*24) // ttl 一天
if numDetails >= MaxMinuteTimes { // 每日最多1800经验 = 18个10分钟 = 180分钟
// 上麦经验贡献值最多1800,1分钟100 if minutes > 180 {
return nil
}
onMic, err := GetGroupPowerOnMic(model, groupPowerId, userId)
if err != nil {
return err
}
nowTs := time.Now().Unix()
curTs := joinMicTimestamp
day0Ts := utils.GetZeroTime(time.Now()).Unix()
if joinMicTimestamp < onMic.LastCalTs {
curTs = onMic.LastCalTs
}
// 跨天
if curTs < day0Ts {
curTs = day0Ts
}
onMicSeconds := nowTs - curTs
var moreDetails []*GroupPowerOnMicDetail
totalMinuteTimes := int((onMic.Seconds + onMicSeconds) / 600) // 今天实际能加经验次数
if totalMinuteTimes >= MaxMinuteTimes {
totalMinuteTimes = MaxMinuteTimes
}
if totalMinuteTimes > numDetails {
// 续上上一次的时间,从numDetails开始
for mt := numDetails + 1; mt <= totalMinuteTimes; mt++ {
moreDetails = append(moreDetails, &GroupPowerOnMicDetail{
Date: time.Now().Format("2006-01-02"),
GroupPowerId: groupPowerId,
UserId: userId,
Minute: mt * 10, // 转换分钟
})
}
}
// 有更多麦上10分钟,可以加经验
if len(moreDetails) > 0 {
for _, detail := range moreDetails {
// 添加明细,避免重复计算
if err := model.DB().Model(GroupPowerOnMicDetail{}).Create(detail).Error; err != nil {
return err
}
// 每10分钟增加100点经验
//if err := IncrGroupPowerExp(model, groupPowerId, 100, userId, "上麦10分钟"); err != nil {
if err := groupPower_c.QueueGroupPowerGradeExp(model, groupPowerId, 100, userId, "上麦10分钟"); err != nil {
return err
}
}
// 更新micExp信息
onMic.Seconds = onMic.Seconds + onMicSeconds
onMic.LastCalTs = nowTs
if err := model.DB().Model(GroupPowerOnMic{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "date"}, {Name: "group_power_id"}},
DoUpdates: clause.Assignments(
map[string]interface{}{
"seconds": onMic.Seconds,
"last_cal_ts": nowTs,
},
)}).
Create(onMic).Error; err != nil {
return err
}
}
return nil return nil
}) }
if minutes%10 == 0 {
return IncrGroupPowerExp(model, groupPowerId, 100, userId, "上麦10分钟")
}
return nil
} }
// 增加势力上麦时长-家族之星 // 增加势力上麦时长-家族之星
// 事务操作 // 事务操作
func IncrGroupPowerStarOnMicMonth(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error { func IncrGroupPowerStarOnMicMonth(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error {
return model.Transaction(func(model *domain.Model) error { // 月统计
// 月统计 star, err := GetGroupPowerMonthStar(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive)
star, err := GetGroupPowerMonthStar(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive) curTs := joinMicTimestamp
curTs := joinMicTimestamp nowTs := time.Now().Unix()
nowTs := time.Now().Unix() month0Ts := now.BeginningOfMonth().Unix()
month0Ts := now.BeginningOfMonth().Unix() if err != nil && err != gorm.ErrRecordNotFound {
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if star != nil && joinMicTimestamp < star.LastCalTs { // 加入的时间比上次计算时间小
curTs = star.LastCalTs
}
// 跨月
if curTs < month0Ts {
curTs = month0Ts
}
score := nowTs - curTs
err = IncrGroupPowerMonthStarScore(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive, mysql.Num(score), nowTs)
return err return err
}) }
if star != nil && joinMicTimestamp < star.LastCalTs { // 加入的时间比上次计算时间小
curTs = star.LastCalTs
}
// 跨月
if curTs < month0Ts {
curTs = month0Ts
}
score := nowTs - curTs
err = IncrGroupPowerMonthStarScore(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive, mysql.Num(score), nowTs)
return err
} }
// 增加势力上麦时长-家族之星 // 增加势力上麦时长-家族之星
// 事务操作 // 事务操作
func IncrGroupPowerStarOnMicDay(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error { func IncrGroupPowerStarOnMicDay(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error {
return model.Transaction(func(model *domain.Model) error { // 日统计
// 日统计 star, err := GetGroupPowerDayStar(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive)
star, err := GetGroupPowerDayStar(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive) curTs := joinMicTimestamp
curTs := joinMicTimestamp nowTs := time.Now().Unix()
nowTs := time.Now().Unix() day0Ts := now.BeginningOfDay().Unix()
day0Ts := now.BeginningOfDay().Unix() if err != nil && err != gorm.ErrRecordNotFound {
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if star != nil && joinMicTimestamp < star.LastCalTs { // 加入的时间比上次计算时间小
curTs = star.LastCalTs
}
// 跨天
if curTs < day0Ts {
curTs = day0Ts
}
score := nowTs - curTs
err = IncrGroupPowerDayStarScore(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive, mysql.Num(score), nowTs)
return err return err
}) }
if star != nil && joinMicTimestamp < star.LastCalTs { // 加入的时间比上次计算时间小
curTs = star.LastCalTs
}
// 跨天
if curTs < day0Ts {
curTs = day0Ts
}
score := nowTs - curTs
err = IncrGroupPowerDayStarScore(model, groupPowerId, userId, groupPower_e.GroupPowerStarTypeActive, mysql.Num(score), nowTs)
return err
} }
// 清理所有家族的经验 // 清理所有家族的经验
......
...@@ -317,7 +317,7 @@ func (s *GroupMicService) IncrGroupPowerOnMicExpAndTime(groupId string, userId u ...@@ -317,7 +317,7 @@ func (s *GroupMicService) IncrGroupPowerOnMicExpAndTime(groupId string, userId u
return nil return nil
} }
// 增加势力上麦经验 // 增加势力上麦经验
if err := groupPower_m.IncrGroupPowerExpOnMic(model, groupPowerId, userId, joinMicTimestamp); err != nil { if err := groupPower_m.IncrGroupPowerExpOnMic(model, groupPowerId, userId); err != nil {
model.Log.Errorf("IncrGroupPowerExpOnMic fail:%v", err) model.Log.Errorf("IncrGroupPowerExpOnMic fail:%v", err)
} }
// 增加势力上麦时长-月 // 增加势力上麦时长-月
......
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