|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ StatisticsPvpModel = (*customStatisticsPvpModel)(nil)
|
|
|
|
|
|
|
|
type ScoreType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
ScoreTypeDamage ScoreType = "damage"
|
|
|
|
ScoreTypeDeDamage = "de_damage"
|
|
|
|
ScoreTypeGeneral = "general_count"
|
|
|
|
ScoreTypeDeGeneral = "de_general_count"
|
|
|
|
ScoreTypeKillUnit = "kill_unit_count"
|
|
|
|
ScoreTypeDeKillUnit = "de_kill_unit_count"
|
|
|
|
ScoreTypeKillPlayer = "kill_player_count"
|
|
|
|
ScoreTypeDeKillPlayer = "de_kill_player_count"
|
|
|
|
ScoreTypeWin = "win_count"
|
|
|
|
ScoreTypeLost = "lost_count"
|
|
|
|
ScoreTypeFirstBlood = "first_blood_count"
|
|
|
|
ScoreTypeDeFirstBlood = "de_first_blood_count"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
// StatisticsPvpModel is an interface to be customized, add more methods here,
|
|
|
|
// and implement the added methods in customStatisticsPvpModel.
|
|
|
|
StatisticsPvpModel interface {
|
|
|
|
statisticsPvpModel
|
|
|
|
// Transaction 开启事务,传入方法即可
|
|
|
|
Transaction(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error
|
|
|
|
// InsertTx 插入事务
|
|
|
|
InsertTx(ctx context.Context, tx *gorm.DB, data *StatisticsPvp) error
|
|
|
|
// UpdateRecord 更新记录
|
|
|
|
UpdateRecord(ctx context.Context, tx *gorm.DB, userId int64, props *UpdateRecordProps) error
|
|
|
|
// FindGreaterByScore 找到比给定分数大的用户id以及具体分数
|
|
|
|
FindGreaterByScore(ctx context.Context, score int64, scoreType ScoreType, limit int) ([]UserAndScore, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
UserAndScore struct {
|
|
|
|
UserId int64
|
|
|
|
Score int64
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateRecordProps struct {
|
|
|
|
Damage *int64 // 伤害
|
|
|
|
DeDamage *int64 // 被伤害
|
|
|
|
KillUnitCount *int64 // 击杀单位数量
|
|
|
|
DeKillUnitCount *int64 // 被击杀单位被击杀
|
|
|
|
Win bool // 是否获胜
|
|
|
|
Lost bool // 是否战败
|
|
|
|
KillPlayer bool // 是否击杀玩家
|
|
|
|
DeKillPlayer bool // 是否玩家被击杀
|
|
|
|
General bool // 是否拿到名将
|
|
|
|
DeGeneral bool // 是否名将罗马
|
|
|
|
FirstBlood bool // 是否拿到一血
|
|
|
|
DeFirstBlood bool // 是否被拿一血
|
|
|
|
}
|
|
|
|
|
|
|
|
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) InsertTx(ctx context.Context, tx *gorm.DB, data *StatisticsPvp) error {
|
|
|
|
return withTx(ctx, m.conn, tx).Create(data).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customStatisticsPvpModel) Transaction(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error {
|
|
|
|
return withTx(ctx, m.conn, tx).Transaction(func(tx *gorm.DB) error {
|
|
|
|
return fn(tx)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customStatisticsPvpModel) UpdateRecord(ctx context.Context, tx *gorm.DB, userId int64, props *UpdateRecordProps) error {
|
|
|
|
// 条件构建
|
|
|
|
db := withTx(ctx, m.conn, tx)
|
|
|
|
db = db.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.KillUnitCount != nil {
|
|
|
|
data["kill_unit_count"] = gorm.Expr("kill_unit_count + ?", *props.KillUnitCount)
|
|
|
|
}
|
|
|
|
if props.DeKillUnitCount != nil {
|
|
|
|
data["de_kill_unit_count"] = gorm.Expr("de_kill_unit_count + ?", *props.DeKillUnitCount)
|
|
|
|
}
|
|
|
|
if props.Win {
|
|
|
|
data["win_count"] = gorm.Expr("win_count + 1")
|
|
|
|
}
|
|
|
|
if props.Lost {
|
|
|
|
data["lost_count"] = gorm.Expr("lost_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")
|
|
|
|
}
|
|
|
|
result := db.Updates(data)
|
|
|
|
if result.Error != nil {
|
|
|
|
return result.Error
|
|
|
|
}
|
|
|
|
if result.RowsAffected == 0 {
|
|
|
|
return ErrRowsAffectedZero
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customStatisticsPvpModel) FindGreaterByScore(ctx context.Context, score int64, scoreType ScoreType, limit int) ([]UserAndScore, error) {
|
|
|
|
db := m.conn.WithContext(ctx)
|
|
|
|
|
|
|
|
if limit > MaxRankN {
|
|
|
|
limit = MaxRankN
|
|
|
|
}
|
|
|
|
if limit <= 0 {
|
|
|
|
limit = MaxRankN
|
|
|
|
}
|
|
|
|
|
|
|
|
whereSql := fmt.Sprintf("%s.%s >= ?", m.table, scoreType)
|
|
|
|
// 0 不入榜
|
|
|
|
if score == 0 {
|
|
|
|
whereSql = fmt.Sprintf("%s.%s > ?", m.table, scoreType)
|
|
|
|
}
|
|
|
|
whereSql = fmt.Sprintf("%s AND user_id > 0", whereSql)
|
|
|
|
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, score).
|
|
|
|
Order(fmt.Sprintf("%s.%s desc", m.table, scoreType)).
|
|
|
|
Limit(limit).Find(&result).Error
|
|
|
|
switch err {
|
|
|
|
case nil:
|
|
|
|
return result, nil
|
|
|
|
case gormc.ErrNotFound:
|
|
|
|
return nil, ErrNotFound
|
|
|
|
default:
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|