group_grade.go 6.31 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4 5
package groupPower_m

import (
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/resource/mysql"
6 7
	"git.hilo.cn/hilo-common/utils"
	"github.com/jinzhu/now"
hujiebin's avatar
hujiebin committed
8 9 10 11 12 13
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"hilo-group/_const/enum/groupPower_e"
	"time"
)

hujiebin's avatar
hujiebin committed
14
type GroupPowerDayExp struct {
hujiebin's avatar
hujiebin committed
15 16 17 18 19 20 21 22 23 24 25
	Date         string
	GroupPowerId mysql.ID
	Exp          int64
	CreatedTime  time.Time `gorm:"->"`
	UpdatedTime  time.Time `gorm:"->"`
}

type GroupPowerGrade struct {
	GroupPowerId mysql.ID
	Exp          int64
	Grade        groupPower_e.GroupPowerGrade
hujiebin's avatar
hujiebin committed
26
	ExpireAt     time.Time
hujiebin's avatar
hujiebin committed
27 28 29 30
	CreatedTime  time.Time `gorm:"->"`
	UpdatedTime  time.Time `gorm:"->"`
}

hujiebin's avatar
hujiebin committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44
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
hujiebin's avatar
hujiebin committed
45
	Minute       int
hujiebin's avatar
hujiebin committed
46 47 48 49
	CreatedTime  time.Time `gorm:"->"`
	UpdatedTime  time.Time `gorm:"->"`
}

hujiebin's avatar
hujiebin committed
50 51 52 53 54 55 56 57 58 59 60 61
// 增加家族经验
// 达到经验值之后升级
// 单进程同步执行,不考虑并发
func IncrGroupPowerExp(txModel *domain.Model, groupPowerId mysql.ID, exp int64) error {
	var err error
	defer func() {
		if err != nil {
			txModel.Log.Errorf("IncrGroupPowerExp fail,id:%v,exp:%v,err:%v", groupPowerId, exp, err)
		}
	}()
	// 增加家族经验-天
	date := time.Now().Format("2006-01-02")
hujiebin's avatar
hujiebin committed
62
	gpe := &GroupPowerDayExp{
hujiebin's avatar
hujiebin committed
63 64 65 66
		Date:         date,
		GroupPowerId: groupPowerId,
		Exp:          exp,
	}
hujiebin's avatar
hujiebin committed
67
	if err = txModel.DB().Model(GroupPowerDayExp{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "date"}, {Name: "group_power_id"}},
hujiebin's avatar
hujiebin committed
68 69 70 71 72 73 74 75 76
		DoUpdates: clause.Assignments(map[string]interface{}{
			"exp": gorm.Expr("exp + ?", gpe.Exp)})}).Create(gpe).Error; err != nil {
		return err
	}
	// 增加家族经验-总
	gpg := &GroupPowerGrade{
		GroupPowerId: groupPowerId,
		Exp:          exp,
		Grade:        0,
hujiebin's avatar
hujiebin committed
77
		ExpireAt:     time.Time{},
hujiebin's avatar
hujiebin committed
78 79 80 81 82 83 84 85 86 87 88 89 90
	}
	if err = txModel.DB().Model(GroupPowerGrade{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "group_power_id"}},
		DoUpdates: clause.Assignments(map[string]interface{}{
			"exp": gorm.Expr("exp + ?", gpg.Exp)})}).Create(gpg).Error; err != nil {
		return err
	}
	// 达到经验值之后升级
	latestGrade := new(GroupPowerGrade)
	if err = txModel.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", groupPowerId).First(latestGrade).Error; err != nil {
		return err
	}
	for grade := groupPower_e.GroupPowerGradeMax; grade >= groupPower_e.GroupPowerGrade0; grade-- {
		if latestGrade.Exp > groupPower_e.GroupPowerGradeExp[grade] {
91
			if latestGrade.Grade < grade { // 积分清零后,等级保持一段时间
92 93 94 95 96 97 98
				expireAt := now.EndOfMonth()
				expireAt = utils.AddDate(expireAt, 0, 1) // 等级有效期到下个月月底
				updateAttrs := map[string]interface{}{
					"grade":     grade,
					"expire_at": expireAt,
				}
				if err = txModel.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", latestGrade.GroupPowerId).UpdateColumns(updateAttrs).Error; err != nil {
hujiebin's avatar
hujiebin committed
99 100 101 102 103 104 105 106
					return err
				}
			}
			break
		}
	}
	return nil
}
hujiebin's avatar
hujiebin committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

// 获取势力用户上麦加经验记录
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

// 增加势力上麦经验
hujiebin's avatar
hujiebin committed
134
// 事务操作
hujiebin's avatar
hujiebin committed
135
func IncrGroupPowerExpOnMic(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error {
hujiebin's avatar
hujiebin committed
136 137 138 139 140
	return model.Transaction(func(model *domain.Model) error {
		// 获取用户上麦奖励历史
		onMicDetails, err := GetGroupPowerUserOnMicDetails(model, groupPowerId, userId)
		if err != nil {
			return err
hujiebin's avatar
hujiebin committed
141
		}
hujiebin's avatar
hujiebin committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155
		numDetails := len(onMicDetails)
		if numDetails >= MaxMinuteTimes {
			// 上麦经验贡献值最多1800,1分钟100
			return nil
		}
		onMic, err := GetGroupPowerOnMic(model, groupPowerId, userId)
		if err != nil {
			return err
		}
		onMicSeconds := time.Now().Unix() - joinMicTimestamp
		if onMic.LastCalTs == joinMicTimestamp {
			onMicSeconds = onMicSeconds - int64(numDetails*600) // 扣除之前加过的时间
		}
		var moreDetails []*GroupPowerOnMicDetail
hujiebin's avatar
hujiebin committed
156
		totalMinuteTimes := int((onMic.Seconds + onMicSeconds) / 600) // 今天实际能加经验次数
hujiebin's avatar
hujiebin committed
157 158 159 160
		if totalMinuteTimes >= MaxMinuteTimes {
			totalMinuteTimes = MaxMinuteTimes
		}
		if totalMinuteTimes > numDetails {
hujiebin's avatar
hujiebin committed
161 162
			// 续上上一次的时间,从numDetails开始
			for mt := numDetails + 1; mt <= totalMinuteTimes; mt++ {
hujiebin's avatar
hujiebin committed
163 164 165 166
				moreDetails = append(moreDetails, &GroupPowerOnMicDetail{
					Date:         time.Now().Format("2006-01-02"),
					GroupPowerId: groupPowerId,
					UserId:       userId,
hujiebin's avatar
hujiebin committed
167
					Minute:       mt * 10, // 转换分钟
hujiebin's avatar
hujiebin committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181
				})
			}
		}
		// 有更多麦上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); err != nil {
					return err
				}
hujiebin's avatar
hujiebin committed
182
			}
hujiebin's avatar
hujiebin committed
183 184 185
			// 更新micExp信息
			onMic.Seconds = onMic.Seconds + onMicSeconds
			onMic.LastCalTs = joinMicTimestamp
hujiebin's avatar
hujiebin committed
186 187 188 189 190 191 192 193
			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": joinMicTimestamp,
					},
				)}).
				Create(onMic).Error; err != nil {
hujiebin's avatar
hujiebin committed
194 195 196
				return err
			}
		}
hujiebin's avatar
hujiebin committed
197 198
		return nil
	})
hujiebin's avatar
hujiebin committed
199
}