mic.go 3.29 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 28
	res := new(UserOnMic)
	day := time.Now().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 78 79
		}
		return nil
	})
}

// 批量获取用户上麦时长
// @return userId->seconds
hujiebin's avatar
hujiebin committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
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
96 97
	var rows []UserOnMic
	res := make(map[mysql.ID]mysql.Num)
hujiebin's avatar
hujiebin committed
98
	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
99 100 101 102 103 104 105 106
		model.Log.Errorf("MGetUserOnMic fail:%v", err)
		return res, err
	}
	for _, r := range rows {
		res[r.UserId] = r.Seconds
	}
	return res, nil
}