mic.go 2.35 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 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 73 74 75 76 77 78 79 80 81 82 83 84 85
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 {
	Day         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("day = ? 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{
			Day:     day,
			UserId:  userId,
			Seconds: mysql.Num(score),
		}
		if err := model.DB().Model(UserOnMic{}).Clauses(clause.OnConflict{
			Columns: []clause.Column{{Name: "day"}, {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("`day`= ? 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
}