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.
300 lines
7.2 KiB
300 lines
7.2 KiB
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() |
|
} |
|
}
|
|
|