mic.go 4.52 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3
package mic_m

import (
hujiebin's avatar
hujiebin committed
4
	"git.hilo.cn/hilo-common/_const/enum/timezone_e"
hujiebin's avatar
hujiebin committed
5 6 7 8 9
	"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"
JiebinHu's avatar
JiebinHu committed
10
	"hilo-group/_const/redis_key/mic_k"
hujiebin's avatar
hujiebin committed
11 12 13 14 15 16 17 18 19 20 21
	"time"
)

// 用户上麦
type UserOnMic struct {
	Date        string
	UserId      mysql.ID
	Seconds     mysql.Num
	LastCalTs   int64
	CreatedTime time.Time `gorm:"->"`
	UpdatedTime time.Time `gorm:"->"`
hujiebin's avatar
hujiebin committed
22
	Tz          timezone_e.Timezone
hujiebin's avatar
hujiebin committed
23 24 25 26
}

// 获取用户当日上麦
// 允许返回gorm.ErrRecordNotFound
hujiebin's avatar
hujiebin committed
27
func GetUserOnMic(model *domain.Model, userId mysql.ID, tz timezone_e.Timezone) (*UserOnMic, error) {
hujiebin's avatar
hujiebin committed
28
	res := new(UserOnMic)
chenweijian's avatar
chenweijian committed
29
	day := time.Now().In(timezone_e.TimezoneLocMap[tz]).Format("2006-01-02")
hujiebin's avatar
hujiebin committed
30
	if err := model.DB().Where("date = ? AND user_id = ? AND tz = ?", day, userId, tz).First(res).Error; err != nil {
hujiebin's avatar
hujiebin committed
31 32 33 34 35 36 37 38 39
		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 {
hujiebin's avatar
hujiebin committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
		for _, tz := range timezone_e.Timezones {
			omMic, err := GetUserOnMic(model, userId, tz)
			if err != nil && err != gorm.ErrRecordNotFound {
				return err
			}
			curTs := joinMicTimestamp
			nowTs := time.Now().Unix()
			day0Ts := utils.GetZeroTime(time.Now().In(timezone_e.TimezoneLocMap[tz])).Unix()
			if omMic != nil && joinMicTimestamp < omMic.LastCalTs { // 加入的时间比上次计算时间小
				curTs = omMic.LastCalTs
			}
			// 跨天
			if curTs < day0Ts {
				curTs = day0Ts
			}
			score := nowTs - curTs
			day := time.Now().In(timezone_e.TimezoneLocMap[tz]).Format("2006-01-02")
			onMicNew := &UserOnMic{
				Date:      day,
				UserId:    userId,
				Seconds:   mysql.Num(score),
				LastCalTs: nowTs,
				Tz:        tz,
			}
			if err := model.DB().Model(UserOnMic{}).Clauses(clause.OnConflict{
				Columns: []clause.Column{{Name: "date"}, {Name: "user_id"}, {Name: "tz"}},
				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
			}
hujiebin's avatar
hujiebin committed
74 75 76 77 78
		}
		return nil
	})
}

JiebinHu's avatar
JiebinHu committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
// 增加用户上麦时长
// 事务操作
func IncrUserOnMicV2(model *domain.Model, userId mysql.ID) error {
	for _, tz := range timezone_e.Timezones {
		day := time.Now().In(timezone_e.TimezoneLocMap[tz]).Format("2006-01-02")
		if err := model.DB().Model(UserOnMic{}).Clauses(clause.OnConflict{
			Columns: []clause.Column{{Name: "date"}, {Name: "user_id"}, {Name: "tz"}},
			DoUpdates: clause.Assignments(map[string]interface{}{
				"seconds": gorm.Expr("seconds + ?", 60),
			}),
		}).Create(&UserOnMic{
			Date:    day,
			UserId:  userId,
			Seconds: 60,
			Tz:      tz,
		}).Error; err != nil {
			model.Log.Errorf("IncrUserOnMic fail:%v", err)
			return err
		}
	}
	return nil
}

JiebinHu's avatar
JiebinHu committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
// 增加用户上麦时长
// Redis
func IncrUserOnMicV3(model *domain.Model, userId mysql.ID) error {
	for _, tz := range timezone_e.Timezones {
		day := time.Now().In(timezone_e.TimezoneLocMap[tz]).Format("2006-01-02")
		tzStr := "bj"
		if tz == timezone_e.TimezoneKSA {
			tzStr = "ksa"
		}
		tzKey := mic_k.GetUserOnMicKey(userId, tzStr, day)
		model.RedisCluster.IncrBy(model, tzKey, 60)
		model.RedisCluster.Expire(model, tzKey, time.Hour*24*30) // 30天上麦时长
	}
	return nil
}

hujiebin's avatar
hujiebin committed
118 119
// 批量获取用户上麦时长
// @return userId->seconds
hujiebin's avatar
hujiebin committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
func MGetUserOnMicSeconds(model *domain.Model, day string, tz timezone_e.Timezone, 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 tz = ? AND user_id in ?", day, tz, 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
}

// 批量获取用户上麦时长
// @return userId->seconds
func MGetUserOnMicSecondsRange(model *domain.Model, beginDate, endDate string, tz timezone_e.Timezone, userIds []uint64) (map[mysql.ID]mysql.Num, error) {
hujiebin's avatar
hujiebin committed
136 137
	var rows []UserOnMic
	res := make(map[mysql.ID]mysql.Num)
hujiebin's avatar
hujiebin committed
138
	if err := model.DB().Model(UserOnMic{}).Where("`date` >= ? AND `date` <= ? AND tz = ? AND user_id in ?", beginDate, endDate, tz, userIds).Find(&rows).Error; err != nil {
hujiebin's avatar
hujiebin committed
139 140 141 142
		model.Log.Errorf("MGetUserOnMic fail:%v", err)
		return res, err
	}
	for _, r := range rows {
hujiebin's avatar
hujiebin committed
143
		res[r.UserId] += r.Seconds
hujiebin's avatar
hujiebin committed
144 145 146
	}
	return res, nil
}