go-common/app/interface/main/esports/service/favorite.go
2019-04-22 18:49:16 +08:00

376 lines
9.5 KiB
Go

package service
import (
"context"
"time"
"go-common/app/interface/main/esports/model"
favmdl "go-common/app/service/main/favorite/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
)
const (
_firstPs = 5
_firstAppPs = 50
_favDay = 15
)
var _empStime = make([]string, 0)
// AddFav add favorite contest.
func (s *Service) AddFav(c context.Context, mid, cid int64) (err error) {
var (
contest *model.Contest
mapC map[int64]*model.Contest
ip = metadata.String(c, metadata.RemoteIP)
)
if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
return
}
contest = mapC[cid]
if contest == nil || contest.ID == 0 {
err = ecode.EsportsContestNotExist
return
}
if contest.LiveRoom <= 0 {
err = ecode.EsportsContestFavNot
return
}
nowTime := time.Now().Unix()
if contest.Etime > 0 && nowTime >= contest.Etime {
err = ecode.EsportsContestEnd
return
}
if contest.Stime == 0 || nowTime >= contest.Stime {
err = ecode.EsportsContestStart
return
}
subDay := timeSub(contest.Stime)
if subDay > _favDay {
err = ecode.EsportsContestNotDay
return
}
arg := &favmdl.ArgAdd{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
if err = s.fav.Add(c, arg); err != nil {
log.Error("AddFav s.fav.Add(%+v) error(%v)", arg, err)
return
}
if err = s.dao.DelFavCoCache(c, mid); err != nil {
log.Error("AddFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
return
}
return
}
func timeSub(stime int64) int {
var (
nowTime, endTime time.Time
)
nowTime = time.Now()
endTime = time.Unix(stime, 0)
nowTime = time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, time.Local)
return int(endTime.Sub(nowTime).Hours() / 24)
}
// DelFav delete favorite contest.
func (s *Service) DelFav(c context.Context, mid, cid int64) (err error) {
var (
contest *model.Contest
mapC map[int64]*model.Contest
ip = metadata.String(c, metadata.RemoteIP)
)
if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
return
}
contest = mapC[cid]
if contest == nil || contest.ID == 0 {
err = ecode.EsportsContestNotExist
return
}
arg := &favmdl.ArgDel{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
if err = s.fav.Del(c, arg); err != nil {
log.Error("DelFav s.fav.Del(%+v) error(%v)", arg, err)
return
}
if err = s.dao.DelFavCoCache(c, mid); err != nil {
log.Error("DelFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
return
}
return
}
// ListFav list favorite contests.
func (s *Service) ListFav(c context.Context, mid, vmid int64, pn, ps int) (rs []*model.Contest, count int, err error) {
var (
isFirst bool
uid int64
favRes *favmdl.Favorites
cids []int64
ip = metadata.String(c, metadata.RemoteIP)
teams, seasons []*model.Filter
cData map[int64]*model.Contest
favContest []*model.Contest
group *errgroup.Group
contErr, teamErr, seasonErr error
)
if vmid > 0 {
uid = vmid
} else {
uid = mid
}
isFirst = pn == 1 && ps == _firstPs
if isFirst {
if rs, count, err = s.dao.FavCoCache(c, uid); err != nil {
err = nil
}
if len(rs) > 0 {
s.fmtContest(c, rs, mid)
return
}
}
arg := &favmdl.ArgFavs{Type: favmdl.TypeEsports, Mid: mid, Vmid: vmid, Fid: 0, Pn: pn, Ps: ps, RealIP: ip}
if favRes, err = s.fav.Favorites(c, arg); err != nil {
log.Error("ListFav s.fav.Favorites(%+v) error(%v)", arg, err)
return
}
count = favRes.Page.Count
if favRes == nil || len(favRes.List) == 0 || count == 0 {
rs = _emptContest
return
}
for _, fav := range favRes.List {
cids = append(cids, fav.Oid)
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
log.Error("s.dao.Contest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
for _, fav := range favRes.List {
if contest, ok := cData[fav.Oid]; ok {
favContest = append(favContest, contest)
}
}
rs = s.ContestInfo(c, cids, favContest, teams, seasons, mid)
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetFavCoCache(c, uid, rs, count)
})
}
return
}
// SeasonFav list favorite season.
func (s *Service) SeasonFav(c context.Context, mid int64, p *model.ParamSeason) (rs []*model.Season, count int, err error) {
var (
uid int64
elaContest []*model.ElaSub
mapSeasons map[int64]*model.Season
cids []int64
sids []int64
dbContests map[int64]*model.Contest
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
if elaContest, count, err = s.dao.SeasonFav(c, uid, p); err != nil {
log.Error("s.dao.StimeFav error(%v)", err)
return
}
for _, contest := range elaContest {
cids = append(cids, contest.Oid)
sids = append(sids, contest.Sid)
}
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.EpContests error(%v)", err)
return
}
} else {
rs = _emptSeason
return
}
if mapSeasons, err = s.dao.EpSeasons(c, sids); err != nil {
log.Error("s.dao.EpSeasons error(%v)", err)
return
}
ms := make(map[int64]struct{}, len(cids))
for _, contest := range elaContest {
if _, ok := ms[contest.Sid]; ok {
continue
}
// del over contest stime.
if contest, ok := dbContests[contest.Oid]; ok {
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
continue
}
}
ms[contest.Sid] = struct{}{}
if season, ok := mapSeasons[contest.Sid]; ok {
rs = append(rs, season)
}
}
if len(rs) == 0 {
rs = _emptSeason
}
return
}
// StimeFav list favorite contests stime.
func (s *Service) StimeFav(c context.Context, mid int64, p *model.ParamSeason) (rs []string, count int, err error) {
var (
uid int64
elaContest []*model.ElaSub
cids []int64
dbContests map[int64]*model.Contest
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
if elaContest, count, err = s.dao.StimeFav(c, uid, p); err != nil {
log.Error("s.dao.StimeFav error(%v)", err)
}
for _, contest := range elaContest {
cids = append(cids, contest.Oid)
}
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.EpContests error(%v)", err)
return
}
} else {
rs = _empStime
return
}
ms := make(map[string]struct{}, len(cids))
for _, contest := range elaContest {
tm := time.Unix(contest.Stime, 0)
stime := tm.Format("2006-01-02")
if _, ok := ms[stime]; ok {
continue
}
ms[stime] = struct{}{}
// del over contest stime.
if contest, ok := dbContests[contest.Oid]; ok {
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
continue
}
}
rs = append(rs, stime)
}
if len(rs) == 0 {
rs = _empStime
}
return
}
// ListAppFav list favorite contests.
func (s *Service) ListAppFav(c context.Context, mid int64, p *model.ParamFav) (rs []*model.Contest, count int, err error) {
var (
uid int64
cids []int64
isFirst bool
teams, seasons []*model.Filter
cData map[int64]*model.Contest
favContest []*model.Contest
group *errgroup.Group
contErr, teamErr, seasonErr error
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
isFirst = p.Pn == 1 && p.Ps == _firstAppPs && p.Stime == "" && p.Etime == "" && len(p.Sids) == 0 && p.Sort == 0
if isFirst {
if rs, count, err = s.dao.FavCoAppCache(c, uid); err != nil {
err = nil
}
if len(rs) > 0 {
s.fmtContest(c, rs, uid)
return
}
}
if cids, count, err = s.dao.SearchFav(c, uid, p); err != nil {
log.Error("s.dao.SearchFav error(%v)", err)
return
}
if len(cids) == 0 || count == 0 {
rs = _emptContest
return
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
log.Error("s.dao.Contest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
for _, cid := range cids {
if contest, ok := cData[cid]; ok {
favContest = append(favContest, contest)
}
}
rs = s.ContestInfo(c, cids, favContest, teams, seasons, uid)
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetAppFavCoCache(c, uid, rs, count)
})
}
return
}
func (s *Service) isFavs(c context.Context, mid int64, cids []int64) (res map[int64]bool, err error) {
if mid > 0 {
ip := metadata.String(c, metadata.RemoteIP)
if res, err = s.fav.IsFavs(c, &favmdl.ArgIsFavs{Type: favmdl.TypeEsports, Mid: mid, Oids: cids, RealIP: ip}); err != nil {
log.Error("s.fav.IsFavs(%d,%+v) error(%d)", mid, cids, err)
err = nil
}
}
return
}