luckyWheel.go 4.83 KB
package group_cv

import (
	"git.hilo.cn/hilo-common/domain"
	"gorm.io/gorm"
	"hilo-group/_const/enum/luckyWheel_e"
	"hilo-group/cv/user_cv"
	"hilo-group/domain/model/luckyWheel_m"
	"hilo-group/myerr/bizerr"
	"time"
)

type ResLuckyWheel struct {
	Id          uint   `json:"id"`
	EntranceFee uint32 `json:"entranceFee"`
}

func GetAllLuckyWheelConfig(db *gorm.DB) ([]ResLuckyWheel, error) {
	rows := make([]ResLuckyWheel, 0)
	if err := db.Model(&ResLuckyWheel{}).Order("id").Find(&rows).Error; err != nil {
		return nil, err
	}
	return rows, nil
}

func (rlw *ResLuckyWheel) GetLuckyWheelConfig(db *gorm.DB) error {
	return db.Where(rlw).First(rlw).Error
}

type LuckyWheelUserOption struct {
	UserId      uint64 `json:"-"`
	GroupId     string `json:"-"`
	LastId      uint   `json:"lastId"`      // 最后一次选择的配置ID
	SelfJoin    bool   `json:"selfJoin"`    // 自己是否加入
	AutoRestart bool   `json:"autoRestart"` // 是否重新开始新的一轮
}

func (uo *LuckyWheelUserOption) Get(db *gorm.DB) error {
	return db.Where(uo).First(uo).Error
}

type LuckyWheelSetting struct {
	Config []ResLuckyWheel `json:"config"` // 配置
	LuckyWheelUserOption
}

type LuckyWheelState struct {
	WheelId       uint64               `json:"wheelId"`       // 当前轮盘ID;=0时代表没有轮盘活动,其他参数都不用看了
	Status        uint8                `json:"status"`        // 轮盘状态
	EntranceFee   uint32               `json:"entranceFee"`   // 参与费用(钻石)
	Creator       string               `json:"creator"`       // 当前轮盘创建者(exteranlId)
	SeatNum       uint                 `json:"seatNum"`       // 轮盘位置数
	Participants  []user_cv.CvUserTiny `json:"participants"`  // 轮盘参与者信息
	TotalFee      uint32               `json:"totalFee"`      // 总参与金额
	PlayTimeStamp int64                `json:"playTimeStamp"` // 轮盘开始转动的时刻
	Sequence      []string             `json:"sequence"`      // 出局序列(用户externalId)
	LosersNum     int                  `json:"losersNum"`     // 出局人数,最多是N-1
	WinnerAmount  uint32               `json:"winnerAmount"`  // 胜利都得到的钻石数
}

func GetLuckWheelState(model *domain.Model, groupId string) (LuckyWheelState, error) {
	result := LuckyWheelState{}

	// FIXME: 先查redis,减少DB访问
	lw := luckyWheel_m.LuckyWheel{GroupId: groupId}
	err := lw.Get(model.Db)
	if err != nil && err != gorm.ErrRecordNotFound {
		return result, err
	}

	if err == gorm.ErrRecordNotFound {
		result.WheelId = 0
		result.Status = luckyWheel_e.NONE
	} else {
		uids := []uint64{lw.Creator}
		lws := luckyWheel_m.LuckyWheelSeat{WheelId: lw.ID}
		seats, err := lws.Get(model.Db)
		if err != nil && err != gorm.ErrRecordNotFound {
			return result, err
		}

		for _, i := range seats {
			uids = append(uids, i.UserId)
		}
		userMap, err := user_cv.GetUserTinyMap(uids)
		if err != nil {
			return result, err
		}

		result = LuckyWheelState{
			WheelId:       lw.ID,
			Status:        lw.Status,
			EntranceFee:   lw.EntranceFee,
			Creator:       userMap[lw.Creator].ExternalId,
			SeatNum:       luckyWheel_e.LUCKY_WHEEL_SEAT_NUM,
			PlayTimeStamp: lw.PlayTime.Unix(),
		}

		for _, i := range seats {
			result.Participants = append(result.Participants, userMap[i.UserId])
		}
		result.TotalFee = result.EntranceFee * uint32(len(result.Participants))

		if result.Status == luckyWheel_e.ROLLING || result.Status == luckyWheel_e.SHOWING {
			result.Sequence = make([]string, len(seats), len(seats))
			for _, e := range seats {
				if e.SeqId > 0 && e.SeqId <= uint(len(seats)) {
					result.Sequence[e.SeqId-1] = userMap[e.UserId].ExternalId
				} else {
					// FIXME:怎么办!?
				}
			}
			model.Log.Infof("Group %s, wheel %d, result: %v", groupId, lw.ID, result.Sequence)
		}
		if result.Status == luckyWheel_e.ROLLING {
			now := time.Now()
			if now.After(lw.PlayTime) {
				timeDiff := now.Unix() - lw.PlayTime.Unix()
				n := timeDiff / luckyWheel_e.LUCKY_WHEEL_ROLL_TIME
				if n >= int64(len(result.Participants))-2 {
					remain := timeDiff - luckyWheel_e.LUCKY_WHEEL_ROLL_TIME*n
					if remain >= luckyWheel_e.LUCKY_WHEEL_LAST_ROLL_TIME {
						n++
					}
				}
				result.LosersNum = int(n)
				if result.LosersNum >= len(result.Participants)-1 {
					result.LosersNum = len(result.Participants) - 1
				}
			}
			result.WinnerAmount, _ = luckyWheel_m.CalcDiamond(lw.EntranceFee, len(result.Participants))
		} else if result.Status == luckyWheel_e.SHOWING {
			result.LosersNum = len(result.Participants)
		}
		if result.Status == luckyWheel_e.SHOWING || result.Status == luckyWheel_e.RESTARTING {
			lwh := luckyWheel_m.LuckyWheelHistory{WheelId: lw.ID}
			err = lwh.Get(model.Db)
			if err == nil {
				result.WinnerAmount = lwh.WinnerAward
			} else if err != gorm.ErrRecordNotFound {
				return result, bizerr.IncorrectState
			}
		}
	}
	return result, nil
}