luckyWheel.go 4.83 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
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
}