301 lines
7.2 KiB
Go
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()
|
|
}
|
|
}
|