Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"achievement.go",
"bws.go",
"check.go",
"lottery.go",
"point.go",
],
importpath = "go-common/app/interface/main/activity/service/bws",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/activity/conf:go_default_library",
"//app/interface/main/activity/dao/bws:go_default_library",
"//app/interface/main/activity/model/bws:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//app/service/main/usersuit/rpc/client:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["bws_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/activity/conf:go_default_library",
"//app/interface/main/activity/model/bws:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,189 @@
package bws
import (
"context"
"time"
bwsmdl "go-common/app/interface/main/activity/model/bws"
suitmdl "go-common/app/service/main/usersuit/model"
"go-common/library/ecode"
"go-common/library/log"
xtime "go-common/library/time"
)
// Award achievement award
func (s *Service) Award(c context.Context, loginMid int64, p *bwsmdl.ParamAward) (err error) {
var (
userAchieves []*bwsmdl.UserAchieve
userAward int64 = -1
)
if _, ok := s.awardMids[loginMid]; !ok {
err = ecode.ActivityNotAwardAdmin
return
}
if p.Key == "" {
if p.Key, err = s.midToKey(c, p.Mid); err != nil {
return
}
}
if userAchieves, err = s.dao.UserAchieves(c, p.Bid, p.Key); err != nil {
err = ecode.ActivityAchieveFail
return
}
if len(userAchieves) == 0 {
err = ecode.ActivityNoAchieve
return
}
for _, v := range userAchieves {
if v.Aid == p.Aid {
userAward = v.Award
break
}
}
if userAward == -1 {
err = ecode.ActivityNoAchieve
return
} else if userAward == _noAward {
err = ecode.ActivityNoAward
return
} else if userAward == _awardAlready {
err = ecode.ActivityAwardAlready
return
}
if err = s.dao.Award(c, p.Key, p.Aid); err != nil {
log.Error("s.dao.Award key(%s) error(%v)", p.Key, err)
}
s.dao.DelCacheUserAchieves(c, p.Bid, p.Key)
return
}
// Achievements achievements list
func (s *Service) Achievements(c context.Context, p *bwsmdl.ParamID) (rs *bwsmdl.Achievements, err error) {
var mapCnt map[int64]int64
if rs, err = s.dao.Achievements(c, p.Bid); err != nil || rs == nil || len(rs.Achievements) == 0 {
log.Error("s.dao.Achievements error(%v)", err)
err = ecode.ActivityAchieveFail
return
}
if mapCnt, err = s.countAchieves(c, p.Bid, p.Day); err != nil || len(mapCnt) == 0 {
err = nil
return
}
for _, achieve := range rs.Achievements {
achieve.UserCount = mapCnt[achieve.ID]
}
return
}
func (s *Service) countAchieves(c context.Context, bid int64, day string) (rs map[int64]int64, err error) {
var countAchieves []*bwsmdl.CountAchieves
if day == "" {
day = today()
}
if countAchieves, err = s.dao.AchieveCounts(c, bid, day); err != nil {
log.Error("s.dao.RawCountAchieves error(%v)", err)
return
}
rs = make(map[int64]int64, len(countAchieves))
for _, countAchieve := range countAchieves {
rs[countAchieve.Aid] = countAchieve.Count
}
return
}
// Achievement Achievement
func (s *Service) Achievement(c context.Context, p *bwsmdl.ParamID) (rs *bwsmdl.Achievement, err error) {
var (
achieves *bwsmdl.Achievements
)
if achieves, err = s.dao.Achievements(c, p.Bid); err != nil || achieves == nil || len(achieves.Achievements) == 0 {
log.Error("s.dao.Achievements error(%v)", err)
err = ecode.ActivityAchieveFail
return
}
for _, Achievement := range achieves.Achievements {
if Achievement.ID == p.ID {
rs = Achievement
break
}
}
if rs == nil {
err = ecode.ActivityIDNotExists
}
return
}
func (s *Service) userAchieves(c context.Context, bid int64, key string) (res []*bwsmdl.UserAchieveDetail, err error) {
var (
usAchieves []*bwsmdl.UserAchieve
achieves *bwsmdl.Achievements
)
if usAchieves, err = s.dao.UserAchieves(c, bid, key); err != nil {
err = ecode.ActivityUserAchieveFail
return
}
if len(usAchieves) == 0 {
return
}
if achieves, err = s.dao.Achievements(c, bid); err != nil || achieves == nil || len(achieves.Achievements) == 0 {
err = ecode.ActivityAchieveFail
return
}
achievesMap := make(map[int64]*bwsmdl.Achievement, len(achieves.Achievements))
for _, v := range achieves.Achievements {
achievesMap[v.ID] = v
}
for _, v := range usAchieves {
detail := &bwsmdl.UserAchieveDetail{UserAchieve: v}
if achieve, ok := achievesMap[v.Aid]; ok {
detail.Name = achieve.Name
detail.Icon = achieve.Icon
detail.Dic = achieve.Dic
detail.LockType = achieve.LockType
detail.Unlock = achieve.Unlock
detail.Bid = achieve.Bid
detail.IconBig = achieve.IconBig
detail.IconActive = achieve.IconActive
detail.IconActiveBig = achieve.IconActiveBig
detail.SuitID = achieve.SuitID
}
res = append(res, detail)
}
return
}
func (s *Service) addAchieve(c context.Context, mid int64, achieve *bwsmdl.Achievement, key string) (err error) {
var uaID int64
if uaID, err = s.dao.AddUserAchieve(c, achieve.Bid, achieve.ID, achieve.Award, key); err != nil {
err = ecode.ActivityAddAchieveFail
return
}
if err = s.dao.AppendUserAchievesCache(c, achieve.Bid, key, &bwsmdl.UserAchieve{ID: uaID, Aid: achieve.ID, Award: achieve.Award, Ctime: xtime.Time(time.Now().Unix())}); err != nil {
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.IncrCacheAchieveCounts(c, achieve.Bid, achieve.ID, today())
var (
keyID int64
e error
)
if mid == 0 {
if mid, keyID, e = s.keyToMid(c, key); e != nil || mid == 0 {
log.Warn("Lottery keyID(%d) key(%s) error(%v)", keyID, key, e)
}
}
if mid > 0 {
if achieve.SuitID > 0 {
arg := &suitmdl.ArgGrantByMids{Mids: []int64{mid}, Pid: achieve.SuitID, Expire: s.c.Rule.BwsSuitExpire}
if e := s.suitRPC.GrantByMids(c, arg); e != nil {
log.Error("addAchieve s.suit.GrantByMids(%d,%d) error(%v)", mid, achieve.SuitID, e)
}
log.Warn("Suit mid(%d) suitID(%d)", mid, achieve.SuitID)
}
if _, ok := s.lotteryAids[achieve.ID]; ok {
s.dao.AddLotteryMidCache(c, achieve.ID, mid)
}
}
})
return
}

View File

@@ -0,0 +1,331 @@
package bws
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/activity/conf"
"go-common/app/interface/main/activity/dao/bws"
bwsmdl "go-common/app/interface/main/activity/model/bws"
accapi "go-common/app/service/main/account/api"
suitmdl "go-common/app/service/main/usersuit/model"
suitrpc "go-common/app/service/main/usersuit/rpc/client"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/sync/pipeline/fanout"
)
const (
_accountBlocked = 1
_allType = 0
_dpType = 1
_gameType = 2
_clockinType = 3
_eggType = 4
_dp = "dp"
_game = "game"
_clockin = "clockin"
_egg = "egg"
_noAward = 0
_awardAlready = 2
_initLinkType = 5
)
var (
_emptPoints = make([]*bwsmdl.Point, 0)
_emptUserPoints = make([]*bwsmdl.UserPointDetail, 0)
_emptyUserAchieves = make([]*bwsmdl.UserAchieveDetail, 0)
)
// Service struct
type Service struct {
c *conf.Config
dao *bws.Dao
accClient accapi.AccountClient
suitRPC *suitrpc.Service2
// bws admin mids
allowMids map[int64]struct{}
awardMids map[int64]struct{}
lotteryMids map[int64]struct{}
lotteryAids map[int64]struct{}
cache *fanout.Fanout
}
// New Service
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: bws.New(c),
suitRPC: suitrpc.New(c.RPCClient2.Suit),
cache: fanout.New("cache", fanout.Worker(1), fanout.Buffer(1024)),
}
var err error
if s.accClient, err = accapi.NewClient(c.AccClient); err != nil {
panic(err)
}
s.initMids()
s.initLotteryAids()
return
}
func (s *Service) initMids() {
tmpMids := make(map[int64]struct{}, len(s.c.Rule.BwsMids))
tmpAward := make(map[int64]struct{}, len(s.c.Rule.BwsMids)+len(s.c.Rule.BwsAwardMids))
tmpLottery := make(map[int64]struct{}, len(s.c.Rule.BwsMids)+len(s.c.Rule.BwsLotteryMids))
for _, id := range s.c.Rule.BwsMids {
tmpMids[id] = struct{}{}
tmpAward[id] = struct{}{}
tmpLottery[id] = struct{}{}
}
for _, id := range s.c.Rule.BwsAwardMids {
tmpAward[id] = struct{}{}
}
for _, id := range s.c.Rule.BwsLotteryMids {
tmpLottery[id] = struct{}{}
}
s.allowMids = tmpMids
s.awardMids = tmpAward
s.lotteryMids = tmpLottery
}
func (s *Service) initLotteryAids() {
tmp := make(map[int64]struct{}, len(s.c.Rule.BwsLotteryAids))
for _, id := range s.c.Rule.BwsLotteryAids {
tmp[id] = struct{}{}
}
s.lotteryAids = tmp
}
// User user info.
func (s *Service) User(c context.Context, bid, mid int64, key string) (user *bwsmdl.User, err error) {
var (
hp, keyID int64
ac *accapi.CardReply
points, dps, games, clockins, eggs []*bwsmdl.UserPointDetail
achErr, pointErr error
)
if key == "" {
if key, err = s.midToKey(c, mid); err != nil {
return
}
} else {
if mid, keyID, err = s.keyToMid(c, key); err != nil {
return
}
}
user = new(bwsmdl.User)
if mid != 0 {
if ac, err = s.accCard(c, mid); err != nil {
log.Error("User s.accCard(%d) error(%v)", mid, err)
return
}
}
if ac != nil && ac.Card != nil {
user.User = &bwsmdl.UserInfo{
Mid: ac.Card.Mid,
Name: ac.Card.Name,
Face: ac.Card.Face,
Key: key,
}
} else {
user.User = &bwsmdl.UserInfo{
Name: strconv.FormatInt(keyID, 10),
Key: key,
}
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if user.Achievements, achErr = s.userAchieves(errCtx, bid, key); achErr != nil {
log.Error("User s.userAchieves(%d,%s) error(%v)", bid, key, achErr)
}
return nil
})
group.Go(func() error {
if points, pointErr = s.userPoints(errCtx, bid, key); pointErr != nil {
log.Error("User s.userPoints(%d,%s) error(%v)", bid, key, pointErr)
}
return nil
})
group.Wait()
if len(user.Achievements) == 0 {
user.Achievements = _emptyUserAchieves
}
user.Items = make(map[string][]*bwsmdl.UserPointDetail, 4)
gidMap := make(map[int64]int64, len(points))
for _, v := range points {
switch v.LockType {
case _dpType:
dps = append(dps, v)
case _gameType:
if v.Points == v.Unlocked {
if _, ok := gidMap[v.Pid]; !ok {
games = append(games, v)
}
gidMap[v.Pid] = v.Pid
}
case _clockinType:
clockins = append(clockins, v)
case _eggType:
eggs = append(eggs, v)
}
hp += v.Points
}
user.User.Hp = hp
if len(dps) == 0 {
user.Items[_dp] = _emptUserPoints
} else {
user.Items[_dp] = dps
}
if len(games) == 0 {
user.Items[_game] = _emptUserPoints
} else {
user.Items[_game] = games
}
if len(clockins) == 0 {
user.Items[_clockin] = _emptUserPoints
} else {
user.Items[_clockin] = clockins
}
if len(eggs) == 0 {
user.Items[_egg] = _emptUserPoints
} else {
user.Items[_egg] = eggs
}
return
}
func (s *Service) accCard(c context.Context, mid int64) (ac *accapi.CardReply, err error) {
var (
arg = &accapi.MidReq{Mid: mid}
)
if ac, err = s.accClient.Card3(c, arg); err != nil || ac == nil {
log.Error("s.accRPC.Card3(%d) error(%v)", mid, err)
err = ecode.AnswerAccCallErr
} else if ac.Card.Silence == _accountBlocked {
err = ecode.UserDisabled
}
return
}
// Binding binding by mid
func (s *Service) Binding(c context.Context, loginMid int64, p *bwsmdl.ParamBinding) (err error) {
var (
achieves *bwsmdl.Achievements
users *bwsmdl.Users
checkMid int64
)
if _, err = s.accCard(c, loginMid); err != nil {
log.Error("s.accCard(%d) error(%v)", loginMid, err)
return
}
if checkMid, _, err = s.keyToMid(c, p.Key); err != nil {
return
}
if checkMid != 0 {
err = ecode.ActivityKeyBindAlready
return
}
if users, err = s.dao.UsersMid(c, loginMid); err != nil {
err = ecode.ActivityKeyFail
return
}
if users != nil && users.Key != "" {
err = ecode.ActivityMidBindAlready
return
}
if err = s.dao.Binding(c, loginMid, p); err != nil {
log.Error("s.dao.Binding mid(%d) key(%s) error(%v)", loginMid, p.Key, err)
return
}
if s.c.Rule.NeedInitAchieve {
if achieves, err = s.dao.Achievements(c, p.Bid); err != nil {
log.Error("s.dao.Achievements error(%v)", err)
err = ecode.ActivityAchieveFail
return
}
if achieves == nil || len(achieves.Achievements) == 0 {
err = ecode.ActivityNoAchieve
return
}
for _, achieve := range achieves.Achievements {
if achieve.LockType == _initLinkType {
s.addAchieve(c, loginMid, achieve, p.Key)
break
}
}
var userAchieves []*bwsmdl.UserAchieveDetail
if userAchieves, err = s.userAchieves(c, p.Bid, p.Key); err != nil {
log.Error("Binding add suit key(%s) mid(%d) %+v", p.Key, loginMid, err)
err = nil
} else {
for _, v := range userAchieves {
if v.LockType == _initLinkType {
continue
}
if suitID := v.SuitID; suitID != 0 {
log.Warn("Binding suit mid(%d) suitID(%d) expire(%d)", loginMid, suitID, s.c.Rule.BwsSuitExpire)
s.cache.Do(c, func(c context.Context) {
arg := &suitmdl.ArgGrantByMids{Mids: []int64{loginMid}, Pid: suitID, Expire: s.c.Rule.BwsSuitExpire}
if e := s.suitRPC.GrantByMids(c, arg); e != nil {
log.Error("Binding s.suit.GrantByMids(%d,%d) error(%v)", loginMid, suitID, e)
}
})
}
if _, ok := s.lotteryAids[v.Aid]; ok {
lotteryAid := v.Aid
log.Warn("Binding lottery mid(%d) achieve id(%d) expire(%d)", loginMid, lotteryAid, s.c.Rule.BwsSuitExpire)
s.cache.Do(c, func(c context.Context) {
s.dao.AddLotteryMidCache(c, lotteryAid, loginMid)
})
}
}
}
}
s.dao.DelCacheUsersKey(c, p.Key)
s.dao.DelCacheUsersMid(c, loginMid)
return
}
func (s *Service) isAdmin(mid int64) bool {
if _, ok := s.allowMids[mid]; ok {
return true
}
return false
}
func (s *Service) midToKey(c context.Context, mid int64) (key string, err error) {
var users *bwsmdl.Users
if users, err = s.dao.UsersMid(c, mid); err != nil {
err = ecode.ActivityKeyFail
return
}
if users == nil || users.Key == "" {
err = ecode.ActivityNotBind
return
}
key = users.Key
return
}
func (s *Service) keyToMid(c context.Context, key string) (mid, keyID int64, err error) {
var users *bwsmdl.Users
if users, err = s.dao.UsersKey(c, key); err != nil {
err = ecode.ActivityKeyFail
return
}
if users == nil || users.Key == "" {
err = ecode.ActivityKeyNotExists
return
}
if users.Mid > 0 {
mid = users.Mid
}
keyID = users.ID
return
}
func today() string {
return time.Now().Format("20060102")
}

View File

@@ -0,0 +1,42 @@
package bws
import (
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/activity/conf"
"context"
"go-common/app/interface/main/activity/model/bws"
. "github.com/smartystreets/goconvey/convey"
)
var svf *Service
func WithService(f func(s *Service)) func() {
return func() {
dir, _ := filepath.Abs("../../cmd/activity-test.toml")
flag.Set("conf", dir)
conf.Init()
if svf == nil {
svf = New(conf.Conf)
}
time.Sleep(2 * time.Second)
f(svf)
}
}
func TestService_Binding(t *testing.T) {
Convey("test binding", t, WithService(func(s *Service) {
logMid := int64(1)
p := &bws.ParamBinding{
Bid: 1,
Key: "",
}
err := s.Binding(context.Background(), logMid, p)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,210 @@
package bws
import (
"context"
"encoding/json"
bwsmdl "go-common/app/interface/main/activity/model/bws"
"go-common/library/ecode"
"go-common/library/log"
)
// RedisInfo .
func (s *Service) RedisInfo(c context.Context, loginMid, mid int64, key, day, typ string, del int) (data json.RawMessage, err error) {
if !s.isAdmin(loginMid) {
err = ecode.ActivityNotAdmin
return
}
if key == "" {
if key, err = s.midToKey(c, mid); err != nil {
return
}
}
var (
bid int64 = 1
bs []byte
)
switch typ {
case "point":
if del == 1 {
err = s.dao.DelCachePoints(c, bid)
return
}
var points *bwsmdl.Points
if points, err = s.dao.CachePoints(c, bid); err != nil || points == nil || len(points.Points) == 0 {
log.Error("RedisInfo point error (%v)", err)
return
}
if bs, err = json.Marshal(points.Points); err != nil {
log.Error("RedisInfo point json error (%v)", err)
return
}
data = json.RawMessage(bs)
case "achieve":
if del == 1 {
err = s.dao.DelCacheAchievements(c, bid)
return
}
var achieves *bwsmdl.Achievements
if achieves, err = s.dao.CacheAchievements(c, bid); err != nil || achieves == nil || len(achieves.Achievements) == 0 {
log.Error("RedisInfo achieve error (%v)", err)
return
}
if bs, err = json.Marshal(achieves.Achievements); err != nil {
log.Error("RedisInfo achieve json error (%v)", err)
return
}
data = json.RawMessage(bs)
case "user_point":
if del == 1 {
err = s.dao.DelCacheUserPoints(c, bid, key)
return
}
var res []*bwsmdl.UserPoint
if res, err = s.dao.CacheUserPoints(c, bid, key); err != nil {
log.Error("RedisInfo user point key(%s) error (%v)", key, err)
return
}
if bs, err = json.Marshal(res); err != nil {
log.Error("RedisInfo user point json error (%v)", err)
return
}
data = json.RawMessage(bs)
case "user_achieve":
if del == 1 {
err = s.dao.DelCacheUserAchieves(c, bid, key)
return
}
var res []*bwsmdl.UserAchieve
if res, err = s.dao.CacheUserAchieves(c, bid, key); err != nil {
log.Error("RedisInfo user achieve key(%s) error (%v)", key, err)
return
}
if bs, err = json.Marshal(res); err != nil {
log.Error("RedisInfo user achieve json error (%v)", err)
return
}
data = json.RawMessage(bs)
case "achieve_cnt":
if day == "" {
day = today()
}
if del == 1 {
err = s.dao.DelCacheAchieveCounts(c, bid, day)
return
}
var res []*bwsmdl.CountAchieves
if res, err = s.dao.CacheAchieveCounts(c, bid, day); err != nil {
log.Error("RedisInfo achieve_cnt day(%s) error (%v)", day, err)
return
}
if bs, err = json.Marshal(res); err != nil {
log.Error("RedisInfo achieve_cnt json error (%v)", err)
return
}
data = json.RawMessage(bs)
case "achieve_cnt_db":
if day == "" {
day = today()
}
var res []*bwsmdl.CountAchieves
if res, err = s.dao.RawAchieveCounts(c, bid, day); err != nil {
log.Error("RedisInfo achieve_cnt_db day(%s) error (%v)", day, err)
return
}
if bs, err = json.Marshal(res); err != nil {
log.Error("RedisInfo achieve_cnt_db json error (%v)", err)
return
}
data = json.RawMessage(bs)
default:
err = ecode.RequestErr
}
return
}
// KeyInfo .
func (s *Service) KeyInfo(c context.Context, loginMid, keyID, mid int64, key, typ string, del int) (data json.RawMessage, err error) {
if !s.isAdmin(loginMid) {
err = ecode.ActivityNotAdmin
return
}
var (
bs []byte
)
switch typ {
case "id":
if keyID == 0 {
err = ecode.RequestErr
return
}
var user *bwsmdl.Users
if user, err = s.dao.UserByID(c, keyID); err != nil {
return
}
if bs, err = json.Marshal(user); err != nil {
return
}
data = json.RawMessage(bs)
case "mid":
if mid == 0 {
err = ecode.RequestErr
return
}
if del == 1 {
err = s.dao.DelCacheUsersMid(c, mid)
return
}
var res *bwsmdl.Users
if res, err = s.dao.CacheUsersMid(c, mid); err != nil {
return
}
if bs, err = json.Marshal(res); err != nil {
return
}
data = json.RawMessage(bs)
case "key":
if key == "" {
err = ecode.RequestErr
return
}
if del == 1 {
err = s.dao.DelCacheUsersKey(c, key)
return
}
var res *bwsmdl.Users
if res, err = s.dao.CacheUsersKey(c, key); err != nil {
return
}
if bs, err = json.Marshal(res); err != nil {
return
}
data = json.RawMessage(bs)
default:
err = ecode.RequestErr
}
return
}
// AdminInfo get admin info.
func (s *Service) AdminInfo(c context.Context, bid, mid int64) (data *bwsmdl.AdminInfo, err error) {
data = new(bwsmdl.AdminInfo)
if s.isAdmin(mid) {
data.IsAdmin = true
}
var points *bwsmdl.Points
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 _, v := range points.Points {
if v.Ower == mid {
data.Point = v
}
}
if data.Point == nil {
data.Point = struct{}{}
}
return
}

View File

@@ -0,0 +1,53 @@
package bws
import (
"context"
bwsmdl "go-common/app/interface/main/activity/model/bws"
accapi "go-common/app/service/main/account/api"
"go-common/library/ecode"
"go-common/library/log"
)
// Lottery get lottery account.
func (s *Service) Lottery(c context.Context, bid, loginMid, aid int64, day string) (data *bwsmdl.LotteryUser, err error) {
var (
mid int64
accData *accapi.InfoReply
)
if _, ok := s.lotteryMids[loginMid]; !ok {
err = ecode.ActivityNotLotteryAdmin
return
}
if _, ok := s.lotteryAids[aid]; !ok {
err = ecode.ActivityNotLotteryAchieve
return
}
if _, err = s.Achievement(c, &bwsmdl.ParamID{Bid: bid, ID: aid}); err != nil {
return
}
if mid, err = s.dao.CacheLotteryMid(c, aid, day); err != nil || mid == 0 {
err = ecode.ActivityLotteryFail
return
}
log.Warn("Lottery bid(%d) loginMid(%d) aid(%d) lotteryMid(%d)", bid, loginMid, aid, mid)
data = &bwsmdl.LotteryUser{Mid: mid}
if accData, err = s.accClient.Info3(c, &accapi.MidReq{Mid: mid}); err != nil {
log.Error("Lottery s.accRPC.Info3(%d) error(%v)", mid, err)
err = nil
return
}
if accData != nil && accData.Info != nil {
data = &bwsmdl.LotteryUser{Mid: mid, Name: accData.Info.Name, Face: accData.Info.Face}
}
return
}
// LotteryCheck .
func (s *Service) LotteryCheck(c context.Context, mid, aid int64, day string) (data []int64, err error) {
if !s.isAdmin(mid) {
err = ecode.ActivityNotAdmin
return
}
return s.dao.CacheLotteryMids(c, aid, day)
}

View File

@@ -0,0 +1,253 @@
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
}