package model import ( "context" "fmt" "git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) var _ StatisticsPvpModel = (*customStatisticsPvpModel)(nil) type ScoreType string const ( ScoreTypeDamage ScoreType = "damage" ScoreTypeGeneral = "general_count" ScoreTypeKillUnit = "kill_unit_count" ScoreTypeKillPlayer = "kill_player_count" ) type ( // StatisticsPvpModel is an interface to be customized, add more methods here, // and implement the added methods in customStatisticsPvpModel. StatisticsPvpModel interface { statisticsPvpModel Exists(ctx context.Context, userId int64) (bool, error) UpdateRecord(ctx context.Context, userId int64, props *UpdateRecordProps) error RecordPvp(ctx context.Context, winUids, lostUids []int64) error // FindGreaterByScore 找到比给定分数大的用户id以及具体分数 FindGreaterByScore(ctx context.Context, score int64, scoreType ScoreType) ([]UserAndScore, error) } UserAndScore struct { UserId int64 Score int64 } UpdateRecordProps struct { KillUnit bool // 是否击杀单位 DeKillUnit bool // 是否单位被击杀 KillPlayer bool // 是否击杀玩家 DeKillPlayer bool // 是否玩家被击杀 General bool // 是否拿到名将 DeGeneral bool // 是否名将罗马 FirstBlood bool // 是否拿到一血 DeFirstBlood bool // 是否被拿一血 Damage *int64 // 伤害 DeDamage *int64 // 被伤害 } customStatisticsPvpModel struct { *defaultStatisticsPvpModel } ) // NewStatisticsPvpModel returns a model for the database table. func NewStatisticsPvpModel(conn *gorm.DB) StatisticsPvpModel { return &customStatisticsPvpModel{ defaultStatisticsPvpModel: newStatisticsPvpModel(conn), } } func (m *customStatisticsPvpModel) Exists(ctx context.Context, userId int64) (bool, error) { var count int64 err := m.conn.WithContext(ctx).Model(&StatisticsPvp{}).Where("user_id = ?", userId).Count(&count).Error switch err { case nil: return count > 0, nil case gormc.ErrNotFound: return false, ErrNotFound default: return false, err } } func (m *customStatisticsPvpModel) UpdateRecord(ctx context.Context, userId int64, props *UpdateRecordProps) error { // 条件构建 db := m.conn.WithContext(ctx).Model(&StatisticsPvp{}).Where("user_id = ?", userId) data := make(map[string]interface{}) if props.Damage != nil { data["damage"] = gorm.Expr("damage + ?", *props.Damage) } if props.DeDamage != nil { data["de_damage"] = gorm.Expr("de_damage + ?", *props.DeDamage) } if props.KillUnit { data["kill_unit_count"] = gorm.Expr("kill_unit_count + 1") } if props.DeKillUnit { data["de_kill_unit_count"] = gorm.Expr("de_kill_unit_count + 1") } if props.KillPlayer { data["kill_player_count"] = gorm.Expr("kill_player_count + 1") } if props.DeKillPlayer { data["de_kill_player_count"] = gorm.Expr("de_kill_player_count + 1") } if props.General { data["general_count"] = gorm.Expr("general_count + 1") } if props.DeGeneral { data["de_general_count"] = gorm.Expr("de_general_count + 1") } if props.FirstBlood { data["first_blood_count"] = gorm.Expr("first_blood_count + 1") } if props.DeFirstBlood { data["de_first_blood_count"] = gorm.Expr("de_first_blood_count + 1") } return db.Updates(data).Error } func (m *customStatisticsPvpModel) RecordPvp(ctx context.Context, winUids, lostUids []int64) error { return m.conn.Transaction(func(tx *gorm.DB) error { err := tx.WithContext(ctx).Model(&StatisticsPvp{}). Where("user_id in (?)", winUids). Update("win_count", gorm.Expr("win_count + 1")). Error if err != nil { logx.Error("更新PvP胜场失败 %+v", err) } err = tx.WithContext(ctx).Model(&StatisticsPvp{}). Where("user_id in (?)", lostUids). Update("lost_count", gorm.Expr("lost_count + 1")). Error if err != nil { logx.Error("更新PvP败失败 %+v", err) } return err }) } func (m *customStatisticsPvpModel) FindGreaterByScore(ctx context.Context, score int64, scoreType ScoreType) ([]UserAndScore, error) { db := m.conn.WithContext(ctx) whereSql := fmt.Sprintf("%s.%s >= %d", m.table, scoreType, score) // 0 不入榜 if score == 0 { whereSql = fmt.Sprintf("%s.%s > %d", m.table, scoreType, score) } var result []UserAndScore err := db.Table(m.table). Select(fmt.Sprintf("%s.user_id, %s.%s AS score", m.table, m.table, scoreType)). Where(whereSql). Limit(MaxRankN).Find(&result).Error switch err { case nil: return result, nil case gormc.ErrNotFound: return nil, ErrNotFound default: return nil, err } }