tab.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package feed
  2. import (
  3. "context"
  4. "sort"
  5. "time"
  6. "go-common/app/interface/main/app-card/model/card/bangumi"
  7. "go-common/app/interface/main/app-card/model/card/live"
  8. "go-common/app/interface/main/app-card/model/card/operate"
  9. "go-common/app/interface/main/app-feed/model"
  10. "go-common/app/interface/main/app-feed/model/feed"
  11. tag "go-common/app/interface/main/tag/model"
  12. article "go-common/app/interface/openplatform/article/model"
  13. "go-common/app/service/main/archive/model/archive"
  14. "go-common/library/log"
  15. "go-common/library/sync/errgroup"
  16. )
  17. func (s *Service) Menus(c context.Context, plat int8, build int, now time.Time) (menus []*operate.Menu) {
  18. memuCache := s.menuCache
  19. menus = make([]*operate.Menu, 0, len(memuCache))
  20. LOOP:
  21. for _, m := range memuCache {
  22. if vs, ok := m.Versions[plat]; ok {
  23. for _, v := range vs {
  24. if model.InvalidBuild(build, v.Build, v.Condition) {
  25. continue LOOP
  26. }
  27. }
  28. if m.Status == 1 && (m.STime == 0 || now.After(m.STime.Time())) && (m.ETime == 0 || now.Before(m.ETime.Time())) {
  29. if m.ID == s.c.Bnj.TabID {
  30. m.Img = s.c.Bnj.TabImg
  31. }
  32. menus = append(menus, m)
  33. }
  34. }
  35. }
  36. return
  37. }
  38. // Actives return actives
  39. func (s *Service) Actives(c context.Context, id, mid int64, now time.Time) (items []*feed.Item, cover string, isBnj bool, bnjDays int, err error) {
  40. if id == s.c.Bnj.TabID {
  41. isBnj = true
  42. nt := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
  43. bt, _ := time.Parse("2006-01-02", s.c.Bnj.BeginTime)
  44. bnjDays = int(bt.Sub(nt).Hours() / 24)
  45. if bnjDays < 0 {
  46. bnjDays = 0
  47. }
  48. }
  49. rs := s.tabCache[id]
  50. if items, err = s.dealTab(c, rs, mid, now); err != nil {
  51. log.Error("%+v", err)
  52. return
  53. }
  54. cover = s.coverCache[id]
  55. return
  56. }
  57. func (s *Service) dealTab(c context.Context, rs []*operate.Active, mid int64, now time.Time) (is []*feed.Item, err error) {
  58. if len(rs) == 0 {
  59. is = _emptyItem
  60. return
  61. }
  62. var (
  63. aids, tids, roomIDs, sids, metaIDs []int64
  64. am map[int64]*archive.ArchiveWithPlayer
  65. rm map[int64]*live.Room
  66. sm map[int64]*bangumi.Season
  67. metam map[int64]*article.Meta
  68. tagm map[int64]*tag.Tag
  69. )
  70. convergem := map[int64]*operate.Converge{}
  71. downloadm := map[int64]*operate.Download{}
  72. for _, r := range rs {
  73. switch r.Type {
  74. case model.GotoPlayer:
  75. if r.Pid != 0 {
  76. aids = append(aids, r.Pid)
  77. }
  78. case model.GotoPlayerLive:
  79. if r.Pid != 0 {
  80. roomIDs = append(roomIDs, r.Pid)
  81. }
  82. case model.GotoTabTagRcmd:
  83. if r.Pid != 0 {
  84. var taids []int64
  85. if taids, err = s.rcmd.TagTop(c, mid, r.Pid, r.Limit); err != nil {
  86. log.Error("%+v", err)
  87. err = nil
  88. continue
  89. }
  90. tids = append(tids, r.Pid)
  91. r.Items = make([]*operate.Active, 0, len(taids))
  92. for _, aid := range taids {
  93. item := &operate.Active{Pid: aid, Goto: model.GotoAv}
  94. r.Items = append(r.Items, item)
  95. aids = append(aids, aid)
  96. }
  97. }
  98. case model.GotoConverge:
  99. if card, ok := s.convergeCache[r.Pid]; ok {
  100. for _, item := range card.Items {
  101. switch item.Goto {
  102. case model.GotoAv:
  103. if item.Pid != 0 {
  104. aids = append(aids, item.Pid)
  105. }
  106. case model.GotoLive:
  107. if item.Pid != 0 {
  108. roomIDs = append(roomIDs, item.Pid)
  109. }
  110. case model.GotoArticle:
  111. if item.Pid != 0 {
  112. metaIDs = append(metaIDs, item.Pid)
  113. }
  114. }
  115. }
  116. convergem[r.Pid] = card
  117. }
  118. case model.GotoTabEntrance, model.GotoTabContentRcmd:
  119. for _, item := range r.Items {
  120. switch item.Goto {
  121. case model.GotoAv:
  122. if item.Pid != 0 {
  123. aids = append(aids, item.Pid)
  124. }
  125. case model.GotoLive:
  126. if item.Pid != 0 {
  127. roomIDs = append(roomIDs, item.Pid)
  128. }
  129. case model.GotoBangumi:
  130. if item.Pid != 0 {
  131. sids = append(sids, item.Pid)
  132. }
  133. case model.GotoGame:
  134. if card, ok := s.downloadCache[item.Pid]; ok {
  135. downloadm[item.Pid] = card
  136. }
  137. case model.GotoArticle:
  138. if item.Pid != 0 {
  139. metaIDs = append(metaIDs, item.Pid)
  140. }
  141. }
  142. }
  143. }
  144. }
  145. g, ctx := errgroup.WithContext(c)
  146. if len(tids) != 0 {
  147. g.Go(func() (err error) {
  148. if tagm, err = s.tg.InfoByIDs(c, 0, tids); err != nil {
  149. log.Error("%+v", err)
  150. err = nil
  151. }
  152. return
  153. })
  154. }
  155. if len(aids) != 0 {
  156. g.Go(func() (err error) {
  157. if am, err = s.ArchivesWithPlayer(ctx, aids, 0, "", 0, 0, 0, 0); err != nil {
  158. log.Error("%+v", err)
  159. err = nil
  160. }
  161. return
  162. })
  163. }
  164. if len(roomIDs) != 0 {
  165. g.Go(func() (err error) {
  166. if rm, err = s.lv.AppMRoom(ctx, roomIDs); err != nil {
  167. log.Error("%+v", err)
  168. err = nil
  169. }
  170. return
  171. })
  172. }
  173. if len(sids) != 0 {
  174. g.Go(func() (err error) {
  175. if sm, err = s.bgm.Seasons(ctx, sids, now); err != nil {
  176. log.Error("%+v", err)
  177. err = nil
  178. }
  179. return
  180. })
  181. }
  182. if len(metaIDs) != 0 {
  183. g.Go(func() (err error) {
  184. if metam, err = s.art.Articles(ctx, metaIDs); err != nil {
  185. log.Error("%+v", err)
  186. err = nil
  187. }
  188. return
  189. })
  190. }
  191. if err = g.Wait(); err != nil {
  192. log.Error("%+v", err)
  193. return
  194. }
  195. is = make([]*feed.Item, 0, len(rs))
  196. for _, r := range rs {
  197. i := &feed.Item{}
  198. switch r.Type {
  199. case model.GotoPlayer:
  200. if a, ok := am[r.Pid]; ok {
  201. i.FromPlayer(a)
  202. is = append(is, i)
  203. }
  204. case model.GotoPlayerLive:
  205. if room, ok := rm[r.Pid]; ok {
  206. i.FromPlayerLive(room)
  207. if i.Goto != "" {
  208. is = append(is, i)
  209. }
  210. }
  211. case model.GotoSpecial:
  212. if sc, ok := s.specialCache[r.Pid]; ok {
  213. i.FromSpecial(sc.ID, sc.Title, sc.Cover, sc.Desc, sc.ReValue, sc.ReType, sc.Badge, sc.Size)
  214. }
  215. if i.Goto != "" {
  216. is = append(is, i)
  217. }
  218. case model.GotoConverge:
  219. if cc, ok := convergem[r.Pid]; ok {
  220. i.FromConverge(cc, am, rm, metam)
  221. if i.Goto != "" {
  222. is = append(is, i)
  223. }
  224. }
  225. case model.GotoTabTagRcmd:
  226. i.FromTabTags(r, am, tagm)
  227. if i.Goto != "" {
  228. is = append(is, i)
  229. }
  230. case model.GotoTabEntrance, model.GotoTabContentRcmd:
  231. i.FromTabCards(r, am, downloadm, sm, rm, metam, s.specialCache)
  232. if i.Goto != "" {
  233. is = append(is, i)
  234. }
  235. case model.GotoBanner:
  236. i.FromTabBanner(r)
  237. if i.Goto != "" {
  238. is = append(is, i)
  239. }
  240. case model.GotoTabNews:
  241. i.FromNews(r)
  242. if i.Goto != "" {
  243. is = append(is, i)
  244. }
  245. }
  246. }
  247. if len(is) == 0 {
  248. is = _emptyItem
  249. }
  250. return
  251. }
  252. func (s *Service) loadTabCache() {
  253. c := context.TODO()
  254. menus, err := s.tab.Menus(c)
  255. if err != nil {
  256. log.Error("%+v", err)
  257. } else {
  258. s.menuCache = menus
  259. }
  260. acs, err := s.tab.Actives(c)
  261. if err != nil {
  262. log.Error("%+v", err)
  263. } else {
  264. s.tabCache, s.coverCache = mergeTab(acs)
  265. }
  266. }
  267. func mergeTab(acs []*operate.Active) (tabm map[int64][]*operate.Active, coverm map[int64]string) {
  268. coverm = make(map[int64]string, len(acs))
  269. parentm := make(map[int64]struct{}, len(acs))
  270. for _, ac := range acs {
  271. if ac.Type == model.GotoTabBackground {
  272. parentm[ac.ID] = struct{}{}
  273. coverm[ac.ID] = ac.Cover
  274. }
  275. }
  276. sort.Sort(operate.Actives(acs))
  277. tabm = make(map[int64][]*operate.Active, len(acs))
  278. for parentID := range parentm {
  279. for _, ac := range acs {
  280. if ac.ParentID == parentID {
  281. tabm[ac.ParentID] = append(tabm[ac.ParentID], ac)
  282. }
  283. }
  284. }
  285. return
  286. }
  287. func (s *Service) tabproc() {
  288. for {
  289. time.Sleep(time.Minute * 1)
  290. s.loadTabCache()
  291. }
  292. }