mic.go 4 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 10 11 12 13 14 15 16 17 18 19 20
	"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:"->"`
hujiebin's avatar
hujiebin committed
21
	Tz          timezone_e.Timezone
hujiebin's avatar
hujiebin committed
22 23 24 25
}

// 获取用户当日上麦
// 允许返回gorm.ErrRecordNotFound
hujiebin's avatar
hujiebin committed
26
func GetUserOnMic(model *domain.Model, userId mysql.ID, tz timezone_e.Timezone) (*UserOnMic, error) {
hujiebin's avatar
hujiebin committed
27
	res := new(UserOnMic)
chenweijian's avatar
chenweijian committed
28
	day := time.Now().In(timezone_e.TimezoneLocMap[tz]).Format("2006-01-02")
hujiebin's avatar
hujiebin committed
29
	if err := model.DB().Where("date = ? AND user_id = ? AND tz = ?", day, userId, tz).First(res).Error; err != nil {
hujiebin's avatar
hujiebin committed
30 31 32 33 34 35 36 37 38
		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
39 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
		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
73 74 75 76 77
		}
		return nil
	})
}

JiebinHu's avatar
JiebinHu committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// 增加用户上麦时长
// 事务操作
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
}

hujiebin's avatar
hujiebin committed
101 102
// 批量获取用户上麦时长
// @return userId->seconds
hujiebin's avatar
hujiebin committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
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
119 120
	var rows []UserOnMic
	res := make(map[mysql.ID]mysql.Num)
hujiebin's avatar
hujiebin committed
121
	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
122 123 124 125
		model.Log.Errorf("MGetUserOnMic fail:%v", err)
		return res, err
	}
	for _, r := range rows {
hujiebin's avatar
hujiebin committed
126
		res[r.UserId] += r.Seconds
hujiebin's avatar
hujiebin committed
127 128 129
	}
	return res, nil
}