2019-04-22 02:59:20 +00:00

301 lines
7.2 KiB
Go

package feed
import (
"context"
"sort"
"time"
"go-common/app/interface/main/app-card/model/card/bangumi"
"go-common/app/interface/main/app-card/model/card/live"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-feed/model"
"go-common/app/interface/main/app-feed/model/feed"
tag "go-common/app/interface/main/tag/model"
article "go-common/app/interface/openplatform/article/model"
"go-common/app/service/main/archive/model/archive"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
func (s *Service) Menus(c context.Context, plat int8, build int, now time.Time) (menus []*operate.Menu) {
memuCache := s.menuCache
menus = make([]*operate.Menu, 0, len(memuCache))
LOOP:
for _, m := range memuCache {
if vs, ok := m.Versions[plat]; ok {
for _, v := range vs {
if model.InvalidBuild(build, v.Build, v.Condition) {
continue LOOP
}
}
if m.Status == 1 && (m.STime == 0 || now.After(m.STime.Time())) && (m.ETime == 0 || now.Before(m.ETime.Time())) {
if m.ID == s.c.Bnj.TabID {
m.Img = s.c.Bnj.TabImg
}
menus = append(menus, m)
}
}
}
return
}
// Actives return actives
func (s *Service) Actives(c context.Context, id, mid int64, now time.Time) (items []*feed.Item, cover string, isBnj bool, bnjDays int, err error) {
if id == s.c.Bnj.TabID {
isBnj = true
nt := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
bt, _ := time.Parse("2006-01-02", s.c.Bnj.BeginTime)
bnjDays = int(bt.Sub(nt).Hours() / 24)
if bnjDays < 0 {
bnjDays = 0
}
}
rs := s.tabCache[id]
if items, err = s.dealTab(c, rs, mid, now); err != nil {
log.Error("%+v", err)
return
}
cover = s.coverCache[id]
return
}
func (s *Service) dealTab(c context.Context, rs []*operate.Active, mid int64, now time.Time) (is []*feed.Item, err error) {
if len(rs) == 0 {
is = _emptyItem
return
}
var (
aids, tids, roomIDs, sids, metaIDs []int64
am map[int64]*archive.ArchiveWithPlayer
rm map[int64]*live.Room
sm map[int64]*bangumi.Season
metam map[int64]*article.Meta
tagm map[int64]*tag.Tag
)
convergem := map[int64]*operate.Converge{}
downloadm := map[int64]*operate.Download{}
for _, r := range rs {
switch r.Type {
case model.GotoPlayer:
if r.Pid != 0 {
aids = append(aids, r.Pid)
}
case model.GotoPlayerLive:
if r.Pid != 0 {
roomIDs = append(roomIDs, r.Pid)
}
case model.GotoTabTagRcmd:
if r.Pid != 0 {
var taids []int64
if taids, err = s.rcmd.TagTop(c, mid, r.Pid, r.Limit); err != nil {
log.Error("%+v", err)
err = nil
continue
}
tids = append(tids, r.Pid)
r.Items = make([]*operate.Active, 0, len(taids))
for _, aid := range taids {
item := &operate.Active{Pid: aid, Goto: model.GotoAv}
r.Items = append(r.Items, item)
aids = append(aids, aid)
}
}
case model.GotoConverge:
if card, ok := s.convergeCache[r.Pid]; ok {
for _, item := range card.Items {
switch item.Goto {
case model.GotoAv:
if item.Pid != 0 {
aids = append(aids, item.Pid)
}
case model.GotoLive:
if item.Pid != 0 {
roomIDs = append(roomIDs, item.Pid)
}
case model.GotoArticle:
if item.Pid != 0 {
metaIDs = append(metaIDs, item.Pid)
}
}
}
convergem[r.Pid] = card
}
case model.GotoTabEntrance, model.GotoTabContentRcmd:
for _, item := range r.Items {
switch item.Goto {
case model.GotoAv:
if item.Pid != 0 {
aids = append(aids, item.Pid)
}
case model.GotoLive:
if item.Pid != 0 {
roomIDs = append(roomIDs, item.Pid)
}
case model.GotoBangumi:
if item.Pid != 0 {
sids = append(sids, item.Pid)
}
case model.GotoGame:
if card, ok := s.downloadCache[item.Pid]; ok {
downloadm[item.Pid] = card
}
case model.GotoArticle:
if item.Pid != 0 {
metaIDs = append(metaIDs, item.Pid)
}
}
}
}
}
g, ctx := errgroup.WithContext(c)
if len(tids) != 0 {
g.Go(func() (err error) {
if tagm, err = s.tg.InfoByIDs(c, 0, tids); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(aids) != 0 {
g.Go(func() (err error) {
if am, err = s.ArchivesWithPlayer(ctx, aids, 0, "", 0, 0, 0, 0); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(roomIDs) != 0 {
g.Go(func() (err error) {
if rm, err = s.lv.AppMRoom(ctx, roomIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(sids) != 0 {
g.Go(func() (err error) {
if sm, err = s.bgm.Seasons(ctx, sids, now); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(metaIDs) != 0 {
g.Go(func() (err error) {
if metam, err = s.art.Articles(ctx, metaIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
is = make([]*feed.Item, 0, len(rs))
for _, r := range rs {
i := &feed.Item{}
switch r.Type {
case model.GotoPlayer:
if a, ok := am[r.Pid]; ok {
i.FromPlayer(a)
is = append(is, i)
}
case model.GotoPlayerLive:
if room, ok := rm[r.Pid]; ok {
i.FromPlayerLive(room)
if i.Goto != "" {
is = append(is, i)
}
}
case model.GotoSpecial:
if sc, ok := s.specialCache[r.Pid]; ok {
i.FromSpecial(sc.ID, sc.Title, sc.Cover, sc.Desc, sc.ReValue, sc.ReType, sc.Badge, sc.Size)
}
if i.Goto != "" {
is = append(is, i)
}
case model.GotoConverge:
if cc, ok := convergem[r.Pid]; ok {
i.FromConverge(cc, am, rm, metam)
if i.Goto != "" {
is = append(is, i)
}
}
case model.GotoTabTagRcmd:
i.FromTabTags(r, am, tagm)
if i.Goto != "" {
is = append(is, i)
}
case model.GotoTabEntrance, model.GotoTabContentRcmd:
i.FromTabCards(r, am, downloadm, sm, rm, metam, s.specialCache)
if i.Goto != "" {
is = append(is, i)
}
case model.GotoBanner:
i.FromTabBanner(r)
if i.Goto != "" {
is = append(is, i)
}
case model.GotoTabNews:
i.FromNews(r)
if i.Goto != "" {
is = append(is, i)
}
}
}
if len(is) == 0 {
is = _emptyItem
}
return
}
func (s *Service) loadTabCache() {
c := context.TODO()
menus, err := s.tab.Menus(c)
if err != nil {
log.Error("%+v", err)
} else {
s.menuCache = menus
}
acs, err := s.tab.Actives(c)
if err != nil {
log.Error("%+v", err)
} else {
s.tabCache, s.coverCache = mergeTab(acs)
}
}
func mergeTab(acs []*operate.Active) (tabm map[int64][]*operate.Active, coverm map[int64]string) {
coverm = make(map[int64]string, len(acs))
parentm := make(map[int64]struct{}, len(acs))
for _, ac := range acs {
if ac.Type == model.GotoTabBackground {
parentm[ac.ID] = struct{}{}
coverm[ac.ID] = ac.Cover
}
}
sort.Sort(operate.Actives(acs))
tabm = make(map[int64][]*operate.Active, len(acs))
for parentID := range parentm {
for _, ac := range acs {
if ac.ParentID == parentID {
tabm[ac.ParentID] = append(tabm[ac.ParentID], ac)
}
}
}
return
}
func (s *Service) tabproc() {
for {
time.Sleep(time.Minute * 1)
s.loadTabCache()
}
}