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" "hilo-group/_const/redis_key/mic_k" "hilo-group/domain/event/group_power_ev" "time" ) type GroupPowerDayExp struct { Date string GroupPowerId mysql.ID Exp mysql.Num CreatedTime time.Time `gorm:"->"` UpdatedTime time.Time `gorm:"->"` } type GroupPowerGrade struct { GroupPowerId mysql.ID Exp mysql.Num Grade groupPower_e.GroupPowerGrade ExpireAt time.Time CreatedTime time.Time `gorm:"->"` UpdatedTime time.Time `gorm:"->"` } type GroupPowerExpDetail struct { mysql.Entity GroupPowerId mysql.ID UserId mysql.ID Exp mysql.Num AddReduce mysql.AddReduce BefNum mysql.Num AftNum mysql.Num Remark string } // 增加家族经验 // 达到经验值之后升级 // 单进程同步执行,不考虑并发 func IncrGroupPowerExp(txModel *domain.Model, groupPowerId mysql.ID, exp mysql.Num, userId mysql.ID, remark string) 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 := new(GroupPowerGrade) // insert if err := txModel.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", groupPowerId).First(gpg).Error; err != nil { if err != gorm.ErrRecordNotFound { return err } // gorm.ErrRecordNotFound gpg = &GroupPowerGrade{ GroupPowerId: groupPowerId, Exp: exp, Grade: 0, ExpireAt: time.Time{}, } if err = txModel.DB().Create(gpg).Error; err != nil { return err } } else { // or update if err := txModel.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", groupPowerId). UpdateColumn("exp", gorm.Expr("exp + ?", exp)).Error; err != nil { return err } } //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 } // 记录明细 detail := &GroupPowerExpDetail{ GroupPowerId: groupPowerId, UserId: userId, Exp: exp, AddReduce: mysql.ADD, BefNum: latestGrade.Exp - exp, AftNum: latestGrade.Exp, Remark: remark, } if err = txModel.DB().Model(GroupPowerExpDetail{}).Create(detail).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 } // 升级发事件 _ = group_power_ev.PublishGroupPowerUpgrade(txModel, &group_power_ev.GroupPowerUpgradeEvent{ GroupPowerId: groupPowerId, }) } break } } return nil } // 增加势力上麦经验 // 事务操作 func IncrGroupPowerExpOnMic(model *domain.Model, groupPowerId, userId mysql.ID) error { key := mic_k.GetMicGroupPowerOnMic(userId) minutes, err := model.Redis.IncrBy(model, key, 1).Result() if err != nil { model.Log.Errorf("IncrGroupPowerExpOnMic fail:%v", err) return err } model.Redis.Expire(model, key, time.Hour*24) // ttl 一天 // 每日最多1800经验 = 18个10分钟 = 180分钟 if minutes > 180 { return nil } if minutes%10 == 0 { return IncrGroupPowerExp(model, groupPowerId, 100, userId, "上麦10分钟") } return nil } // 清理所有家族的经验 func ClearGroupPowerExp(model *domain.Model) error { var groupPowerGrades []*GroupPowerGrade if err := model.DB().Model(GroupPowerGrade{}).Where("exp > 0").Find(&groupPowerGrades).Error; err != nil { return err } return model.Transaction(func(model *domain.Model) error { for _, grade := range groupPowerGrades { if err := model.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", grade.GroupPowerId).UpdateColumn("exp", 0).Error; err != nil { return err } // 记录明细 detail := &GroupPowerExpDetail{ GroupPowerId: grade.GroupPowerId, UserId: 0, Exp: 0, AddReduce: mysql.SET, BefNum: grade.Exp, AftNum: 0, Remark: "每月清零", } if err := model.DB().Model(GroupPowerExpDetail{}).Create(detail).Error; err != nil { return err } } return nil }) } // 清理过期家族等级 func ClearGroupPowerGrade(model *domain.Model) error { var groupPowerGrades []*GroupPowerGrade if err := model.DB().Model(GroupPowerGrade{}).Where("expire_at < ?", time.Now()).Find(&groupPowerGrades).Error; err != nil { return err } return model.Transaction(func(model *domain.Model) error { for _, grade := range groupPowerGrades { updateAttrs := map[string]interface{}{ "grade": 0, "expire_at": time.Time{}, } if err := model.DB().Model(GroupPowerGrade{}).Where("group_power_id = ?", grade.GroupPowerId).Updates(updateAttrs).Error; err != nil { return err } } return nil }) } // 批量获取家族等级 func MGetGroupPowerGrade(model *domain.Model, groupPowerIds []mysql.ID) (map[mysql.ID]GroupPowerGrade, error) { var rows []GroupPowerGrade res := make(map[mysql.ID]GroupPowerGrade) if err := model.DB().Model(GroupPowerGrade{}).Where("group_power_id in ?", groupPowerIds).Find(&rows).Error; err != nil { model.Log.Errorf("MGetGroupPowerGrade fail:%v", err) return res, err } for i, v := range rows { res[v.GroupPowerId] = rows[i] } return res, nil }