package groupPower_m import ( "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/mysql" "git.hilo.cn/hilo-common/utils" "github.com/jinzhu/now" "gorm.io/gorm" "gorm.io/gorm/clause" "hilo-group/_const/enum/groupPower_e" "time" ) type GroupPowerDayExp struct { 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 ExpireAt time.Time CreatedTime time.Time `gorm:"->"` UpdatedTime time.Time `gorm:"->"` } 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 Minute int CreatedTime time.Time `gorm:"->"` UpdatedTime time.Time `gorm:"->"` } // 增加家族经验 // 达到经验值之后升级 // 单进程同步执行,不考虑并发 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") gpe := &GroupPowerDayExp{ Date: date, GroupPowerId: groupPowerId, Exp: exp, } if err = txModel.DB().Model(GroupPowerDayExp{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "date"}, {Name: "group_power_id"}}, 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, ExpireAt: time.Time{}, } 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] { if latestGrade.Grade < grade { // 积分清零后,等级保持一段时间 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 { return err } } break } } return nil } // 获取势力用户上麦加经验记录 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 // 增加势力上麦经验 // 事务操作 func IncrGroupPowerExpOnMic(model *domain.Model, groupPowerId, userId mysql.ID, joinMicTimestamp int64) error { return model.Transaction(func(model *domain.Model) error { // 获取用户上麦奖励历史 onMicDetails, err := GetGroupPowerUserOnMicDetails(model, groupPowerId, userId) if err != nil { return err } 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 totalMinuteTimes := int((onMic.Seconds + onMicSeconds) / 600) // 今天实际能加经验次数 if totalMinuteTimes >= MaxMinuteTimes { totalMinuteTimes = MaxMinuteTimes } if totalMinuteTimes > numDetails { // 续上上一次的时间,从numDetails开始 for mt := numDetails + 1; mt <= totalMinuteTimes; mt++ { moreDetails = append(moreDetails, &GroupPowerOnMicDetail{ Date: time.Now().Format("2006-01-02"), GroupPowerId: groupPowerId, UserId: userId, Minute: mt * 10, // 转换分钟 }) } } // 有更多麦上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 } } // 更新micExp信息 onMic.Seconds = onMic.Seconds + onMicSeconds onMic.LastCalTs = joinMicTimestamp 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 { return err } } return nil }) }