You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
6.1 KiB
253 lines
6.1 KiB
package bws |
|
|
|
import ( |
|
"context" |
|
"sort" |
|
"time" |
|
|
|
bwsmdl "go-common/app/interface/main/activity/model/bws" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
xtime "go-common/library/time" |
|
) |
|
|
|
func (s *Service) points(c context.Context, bid int64) (rs map[string][]*bwsmdl.Point, err error) { |
|
var ( |
|
points *bwsmdl.Points |
|
dp, game, clockin, egg []*bwsmdl.Point |
|
) |
|
if points, err = s.dao.Points(c, bid); err != nil || points == nil || len(points.Points) == 0 { |
|
log.Error("s.dao.Points error(%v)", err) |
|
err = ecode.ActivityPointFail |
|
return |
|
} |
|
for _, point := range points.Points { |
|
switch point.LockType { |
|
case _dpType: |
|
dp = append(dp, point) |
|
case _gameType: |
|
game = append(game, point) |
|
case _clockinType: |
|
clockin = append(clockin, point) |
|
case _eggType: |
|
egg = append(egg, point) |
|
} |
|
} |
|
rs = make(map[string][]*bwsmdl.Point, 4) |
|
if len(dp) == 0 { |
|
rs[_dp] = _emptPoints |
|
} else { |
|
rs[_dp] = dp |
|
} |
|
if len(game) == 0 { |
|
rs[_game] = _emptPoints |
|
} else { |
|
rs[_game] = game |
|
} |
|
if len(clockin) == 0 { |
|
rs[_clockin] = _emptPoints |
|
} else { |
|
rs[_clockin] = clockin |
|
} |
|
if len(egg) == 0 { |
|
rs[_egg] = _emptPoints |
|
} else { |
|
rs[_egg] = egg |
|
} |
|
return |
|
} |
|
|
|
// Points points list |
|
func (s *Service) Points(c context.Context, p *bwsmdl.ParamPoints) (rs map[string][]*bwsmdl.Point, err error) { |
|
var points map[string][]*bwsmdl.Point |
|
if points, err = s.points(c, p.Bid); err != nil { |
|
return |
|
} |
|
rs = make(map[string][]*bwsmdl.Point) |
|
switch p.Tp { |
|
case _allType: |
|
rs = points |
|
case _dpType: |
|
rs[_dp] = points[_dp] |
|
case _gameType: |
|
rs[_game] = points[_game] |
|
case _clockinType: |
|
rs[_clockin] = points[_clockin] |
|
case _eggType: |
|
rs[_egg] = points[_egg] |
|
} |
|
return |
|
} |
|
|
|
// Point point |
|
func (s *Service) Point(c context.Context, p *bwsmdl.ParamID) (rs *bwsmdl.Point, err error) { |
|
var ( |
|
points *bwsmdl.Points |
|
) |
|
if points, err = s.dao.Points(c, p.Bid); err != nil || points == nil || len(points.Points) == 0 { |
|
log.Error("s.dao.Points error(%v)", err) |
|
err = ecode.ActivityPointFail |
|
return |
|
} |
|
for _, point := range points.Points { |
|
if point.ID == p.ID { |
|
rs = point |
|
break |
|
} |
|
} |
|
if rs == nil { |
|
err = ecode.ActivityIDNotExists |
|
} |
|
return |
|
} |
|
|
|
// Unlock unlock point. |
|
func (s *Service) Unlock(c context.Context, owner int64, arg *bwsmdl.ParamUnlock) (err error) { |
|
var ( |
|
point *bwsmdl.Point |
|
userPoints []*bwsmdl.UserPointDetail |
|
userAchieves []*bwsmdl.UserAchieveDetail |
|
achieves *bwsmdl.Achievements |
|
unLockCnt, hp int64 |
|
addAchieve *bwsmdl.Achievement |
|
lockAchieves []*bwsmdl.Achievement |
|
) |
|
if arg.Key == "" { |
|
if arg.Key, err = s.midToKey(c, arg.Mid); err != nil { |
|
return |
|
} |
|
} |
|
if point, err = s.Point(c, &bwsmdl.ParamID{ID: arg.Pid, Bid: arg.Bid}); err != nil { |
|
return |
|
} |
|
if point.Ower != owner && !s.isAdmin(owner) { |
|
err = ecode.ActivityNotOwner |
|
return |
|
} |
|
if point.LockType == _gameType { |
|
if arg.GameResult != bwsmdl.GameResWin && arg.GameResult != bwsmdl.GameResFail { |
|
err = ecode.ActivityGameResult |
|
return |
|
} |
|
} |
|
if userPoints, err = s.userPoints(c, arg.Bid, arg.Key); err != nil { |
|
return |
|
} |
|
userPidMap := make(map[int64]int64, len(userPoints)) |
|
for _, v := range userPoints { |
|
if point.LockType != _gameType && v.Pid == point.ID { |
|
err = ecode.ActivityHasUnlock |
|
return |
|
} |
|
if _, ok := userPidMap[v.Pid]; !ok && v.LockType == point.LockType { |
|
if v.LockType == _gameType { |
|
if v.Points == v.Unlocked { |
|
unLockCnt++ |
|
userPidMap[v.Pid] = v.Pid |
|
} |
|
} else { |
|
unLockCnt++ |
|
userPidMap[v.Pid] = v.Pid |
|
} |
|
} |
|
hp += v.Points |
|
} |
|
lockPoint := point.Unlocked |
|
if point.LockType == _gameType && arg.GameResult == bwsmdl.GameResFail { |
|
lockPoint = point.LoseUnlocked |
|
} |
|
if hp+lockPoint < 0 { |
|
err = ecode.ActivityLackHp |
|
return |
|
} |
|
if userAchieves, err = s.userAchieves(c, arg.Bid, arg.Key); err != nil { |
|
return |
|
} |
|
if err = s.addUserPoint(c, arg.Bid, arg.Pid, lockPoint, arg.Key); err != nil { |
|
return |
|
} |
|
if achieves, err = s.dao.Achievements(c, arg.Bid); err != nil || len(achieves.Achievements) == 0 { |
|
log.Error("s.dao.Achievements error(%v)", err) |
|
err = ecode.ActivityAchieveFail |
|
return |
|
} |
|
for _, v := range achieves.Achievements { |
|
if point.LockType == v.LockType { |
|
lockAchieves = append(lockAchieves, v) |
|
} |
|
} |
|
if len(lockAchieves) > 0 { |
|
sort.Slice(lockAchieves, func(i, j int) bool { return lockAchieves[i].Unlock > lockAchieves[j].Unlock }) |
|
if point.LockType == _gameType { |
|
if arg.GameResult == bwsmdl.GameResWin { |
|
unLockCnt++ |
|
} |
|
} else { |
|
unLockCnt++ |
|
} |
|
for _, ach := range lockAchieves { |
|
if unLockCnt >= ach.Unlock { |
|
addAchieve = ach |
|
break |
|
} |
|
} |
|
} |
|
if addAchieve != nil { |
|
for _, v := range userAchieves { |
|
if v.Aid == addAchieve.ID { |
|
return |
|
} |
|
} |
|
s.addAchieve(c, arg.Mid, addAchieve, arg.Key) |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) userPoints(c context.Context, bid int64, key string) (res []*bwsmdl.UserPointDetail, err error) { |
|
var ( |
|
usPoints []*bwsmdl.UserPoint |
|
points *bwsmdl.Points |
|
) |
|
if usPoints, err = s.dao.UserPoints(c, bid, key); err != nil { |
|
err = ecode.ActivityUserPointFail |
|
return |
|
} |
|
if len(usPoints) == 0 { |
|
return |
|
} |
|
if points, err = s.dao.Points(c, bid); err != nil || points == nil || len(points.Points) == 0 { |
|
log.Error("s.dao.Points error(%v)", err) |
|
err = ecode.ActivityPointFail |
|
return |
|
} |
|
pointsMap := make(map[int64]*bwsmdl.Point, len(points.Points)) |
|
for _, v := range points.Points { |
|
pointsMap[v.ID] = v |
|
} |
|
for _, v := range usPoints { |
|
detail := &bwsmdl.UserPointDetail{UserPoint: v} |
|
if point, ok := pointsMap[v.Pid]; ok { |
|
detail.Name = point.Name |
|
detail.Icon = point.Icon |
|
detail.Fid = point.Fid |
|
detail.Image = point.Image |
|
detail.Unlocked = point.Unlocked |
|
detail.LockType = point.LockType |
|
detail.Dic = point.Dic |
|
detail.Rule = point.Rule |
|
detail.Bid = point.Bid |
|
} |
|
res = append(res, detail) |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) addUserPoint(c context.Context, bid, pid, points int64, key string) (err error) { |
|
var usPtID int64 |
|
if usPtID, err = s.dao.AddUserPoint(c, bid, pid, points, key); err != nil { |
|
err = ecode.ActivityUnlockFail |
|
return |
|
} |
|
err = s.dao.AppendUserPointsCache(c, bid, key, &bwsmdl.UserPoint{ID: usPtID, Pid: pid, Points: points, Ctime: xtime.Time(time.Now().Unix())}) |
|
return |
|
}
|
|
|