index.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. package channel
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. cdm "go-common/app/interface/main/app-card/model"
  8. "go-common/app/interface/main/app-card/model/card/audio"
  9. "go-common/app/interface/main/app-card/model/card/bangumi"
  10. "go-common/app/interface/main/app-card/model/card/live"
  11. "go-common/app/interface/main/app-card/model/card/operate"
  12. shopping "go-common/app/interface/main/app-card/model/card/show"
  13. "go-common/app/interface/main/app-channel/model"
  14. "go-common/app/interface/main/app-channel/model/activity"
  15. "go-common/app/interface/main/app-channel/model/card"
  16. "go-common/app/interface/main/app-channel/model/feed"
  17. bustag "go-common/app/interface/main/tag/model"
  18. tag "go-common/app/interface/main/tag/model"
  19. article "go-common/app/interface/openplatform/article/model"
  20. account "go-common/app/service/main/account/model"
  21. "go-common/app/service/main/archive/model/archive"
  22. relation "go-common/app/service/main/relation/model"
  23. episodegrpc "go-common/app/service/openplatform/pgc-season/api/grpc/episode/v1"
  24. "go-common/library/log"
  25. "go-common/library/sync/errgroup"
  26. )
  27. var (
  28. _emptyItem = []*feed.Item{}
  29. )
  30. // Index channel index
  31. func (s *Service) Index(c context.Context, mid, channelID, idx int64, plat int8, mobiApp, device, buvid, channelName string, build, loginEvent, displayID, qn, fnver, fnval int, pull bool, now time.Time) (res *feed.Show, err error) {
  32. var (
  33. aids []int64
  34. requestCnt = 10
  35. isIpad = plat == model.PlatIPad
  36. topic *feed.Item
  37. item []*feed.Item
  38. channelResource *tag.ChannelResource
  39. topChannel, isRec int
  40. )
  41. if isIpad {
  42. requestCnt = 20
  43. }
  44. if channelID > 0 {
  45. channelName = ""
  46. }
  47. g, ctx := errgroup.WithContext(c)
  48. g.Go(func() (err error) {
  49. if channelResource, err = s.tg.Resources(ctx, plat, channelID, mid, channelName, buvid, build, requestCnt, loginEvent, displayID); err != nil {
  50. log.Error("index s.tg.Resources error(%v)", err)
  51. return
  52. }
  53. if channelResource != nil {
  54. aids = channelResource.Oids
  55. if channelResource.Failover {
  56. isRec = 0
  57. } else {
  58. isRec = 1
  59. }
  60. if channelResource.IsChannel {
  61. topChannel = 1
  62. } else {
  63. topChannel = 0
  64. }
  65. }
  66. return
  67. })
  68. g.Go(func() (err error) {
  69. var t *tag.ChannelDetail
  70. if t, err = s.tg.ChannelDetail(c, mid, channelID, channelName, s.isOverseas(plat)); err != nil {
  71. log.Error("s.tag.ChannelDetail(%d, %d, %s) error(%v)", mid, channelID, channelName, err)
  72. return
  73. }
  74. channelID = t.Tag.ID
  75. channelName = t.Tag.Name
  76. return
  77. })
  78. if err = g.Wait(); err != nil {
  79. if (mobiApp == "iphone" && build > 8050) || (mobiApp == "android" && build > 5305000) {
  80. log.Error("%+v", err)
  81. res = &feed.Show{
  82. Feed: _emptyItem,
  83. }
  84. return
  85. }
  86. err = nil
  87. }
  88. if loginEvent == 1 || loginEvent == 2 {
  89. if cards, ok := s.cardCache[channelID]; ok {
  90. topic, item, err = s.dealItem(c, mid, idx, channelID, plat, build, qn, fnver, fnval, mobiApp, buvid, pull, now, cards, aids)
  91. } else {
  92. item, err = s.feedItem(c, plat, aids, mobiApp, qn, fnver, fnval, build)
  93. }
  94. } else {
  95. item, err = s.feedItem(c, plat, aids, mobiApp, qn, fnver, fnval, build)
  96. }
  97. res = &feed.Show{
  98. Topic: topic,
  99. Feed: item,
  100. }
  101. //infoc
  102. infoc := &feedInfoc{
  103. mobiApp: mobiApp,
  104. device: device,
  105. build: strconv.Itoa(build),
  106. now: now.Format("2006-01-02 15:04:05"),
  107. pull: strconv.FormatBool(pull),
  108. loginEvent: strconv.Itoa(loginEvent),
  109. channelID: strconv.FormatInt(channelID, 10),
  110. channelName: channelName,
  111. mid: strconv.FormatInt(mid, 10),
  112. buvid: buvid,
  113. displayID: strconv.Itoa(displayID),
  114. feed: res,
  115. isRec: strconv.Itoa(isRec),
  116. topChannel: strconv.Itoa(topChannel),
  117. ServerCode: "0",
  118. }
  119. s.infoc(infoc)
  120. return
  121. }
  122. // dealItem
  123. func (s *Service) dealItem(c context.Context, mid, idx, channelID int64, plat int8, build, qn, fnver, fnval int, mobiApp, buvid string, pull bool, now time.Time, cards []*card.Card, listAID []int64) (top *feed.Item, is []*feed.Item, err error) {
  124. if len(cards) == 0 {
  125. is = _emptyItem
  126. return
  127. }
  128. var (
  129. aids, sids, roomIDs, metaIDs, shopIDs, audioIDs []int64
  130. upIDs, tids, avUpIDs, rmUpIDs, mtUpIDs []int64
  131. seasonIDs []int32
  132. am map[int64]*archive.ArchiveWithPlayer
  133. tagm map[int64]*bustag.Tag
  134. follows map[int64]bool
  135. rm map[int64]*live.Room
  136. sm map[int64]*bangumi.Season
  137. actIDs, topIDs []int64
  138. actm, topm map[int64]*activity.Activity
  139. atm map[int64]*article.Meta
  140. scm map[int64]*shopping.Shopping
  141. aum map[int64]*audio.Audio
  142. infocard map[int64]*account.Card
  143. upStatm map[int64]*relation.Stat
  144. cardAids = map[int64]struct{}{}
  145. channelCards []*card.Card
  146. seasonCards map[int32]*episodegrpc.EpisodeCardsProto
  147. // key
  148. _initCardPlatKey = "card_platkey_%d_%d"
  149. _fTypeOperation = "operation"
  150. _fTypeRecommend = "recommend"
  151. )
  152. convergem := map[int64]*operate.Converge{}
  153. downloadm := map[int64]*operate.Download{}
  154. liveUpm := map[int64][]*live.Card{}
  155. followm := map[int64]*operate.Follow{}
  156. LOOP:
  157. for _, c := range cards {
  158. key := fmt.Sprintf(_initCardPlatKey, plat, c.ID)
  159. if cardPlat, ok := s.cardPlatCache[key]; ok {
  160. for _, l := range cardPlat {
  161. if model.InvalidBuild(build, l.Build, l.Condition) {
  162. continue LOOP
  163. }
  164. }
  165. } else {
  166. continue LOOP
  167. }
  168. channelCards = append(channelCards, c)
  169. switch c.Type {
  170. case model.GotoAv, model.GotoPlayer, model.GotoUpRcmdAv:
  171. if c.Value != 0 {
  172. aids = append(aids, c.Value)
  173. cardAids[c.Value] = struct{}{}
  174. }
  175. case model.GotoLive, model.GotoPlayerLive:
  176. if c.Value != 0 {
  177. roomIDs = append(roomIDs, c.Value)
  178. }
  179. case model.GotoBangumi:
  180. if c.Value != 0 {
  181. sids = append(sids, c.Value)
  182. }
  183. case model.GotoPGC:
  184. if c.Value != 0 {
  185. seasonIDs = append(seasonIDs, int32(c.Value))
  186. }
  187. case model.GotoActivity:
  188. if c.Value != 0 {
  189. actIDs = append(actIDs, c.Value)
  190. }
  191. case model.GotoTopic:
  192. if c.Value != 0 {
  193. topIDs = append(topIDs, c.Value)
  194. }
  195. case model.GotoConverge:
  196. if card, ok := s.convergeCardCache[c.Value]; ok {
  197. for _, item := range card.Items {
  198. switch item.Goto {
  199. case model.GotoAv:
  200. if item.Pid != 0 {
  201. aids = append(aids, item.Pid)
  202. }
  203. case model.GotoLive:
  204. if item.Pid != 0 {
  205. roomIDs = append(roomIDs, item.Pid)
  206. }
  207. case model.GotoArticle:
  208. if item.Pid != 0 {
  209. metaIDs = append(metaIDs, item.Pid)
  210. }
  211. }
  212. }
  213. convergem[c.Value] = card
  214. }
  215. case model.GotoGameDownload, model.GotoGameDownloadS:
  216. if card, ok := s.gameDownloadCache[c.Value]; ok {
  217. downloadm[c.Value] = card
  218. }
  219. case model.GotoArticle, model.GotoArticleS:
  220. if c.Value != 0 {
  221. metaIDs = append(metaIDs, c.Value)
  222. }
  223. case model.GotoShoppingS:
  224. if c.Value != 0 {
  225. shopIDs = append(shopIDs, c.Value)
  226. }
  227. case model.GotoAudio:
  228. if c.Value != 0 {
  229. audioIDs = append(audioIDs, c.Value)
  230. }
  231. case model.GotoLiveUpRcmd:
  232. if c.Value != 0 {
  233. if cs, ok := s.liveCardCache[c.Value]; ok {
  234. for _, c := range cs {
  235. upIDs = append(upIDs, c.UID)
  236. }
  237. }
  238. }
  239. case model.GotoSubscribe:
  240. if c.Value != 0 {
  241. if card, ok := s.upCardCache[c.Value]; ok {
  242. for _, item := range card.Items {
  243. switch item.Goto {
  244. case cdm.GotoMid:
  245. if item.Pid != 0 {
  246. upIDs = append(upIDs, item.Pid)
  247. }
  248. case cdm.GotoTag:
  249. if item.Pid != 0 {
  250. tids = append(tids, item.Pid)
  251. }
  252. }
  253. }
  254. followm[c.Value] = card
  255. }
  256. }
  257. case model.GotoChannelRcmd:
  258. if c.Value != 0 {
  259. if card, ok := s.upCardCache[c.Value]; ok {
  260. if card.Pid != 0 {
  261. aids = append(aids, card.Pid)
  262. }
  263. if card.Tid != 0 {
  264. tids = append(tids, card.Tid)
  265. }
  266. followm[c.Value] = card
  267. }
  268. }
  269. }
  270. }
  271. if len(listAID) != 0 {
  272. aids = append(aids, listAID...)
  273. }
  274. g, ctx := errgroup.WithContext(c)
  275. if len(aids) != 0 {
  276. g.Go(func() (err error) {
  277. if am, err = s.ArchivesWithPlayer(ctx, aids, qn, mobiApp, fnver, fnval, build); err != nil {
  278. return
  279. }
  280. for _, a := range am {
  281. avUpIDs = append(avUpIDs, a.Author.Mid)
  282. }
  283. return
  284. })
  285. }
  286. if len(tids) != 0 {
  287. g.Go(func() (err error) {
  288. if tagm, err = s.tg.InfoByIDs(ctx, mid, tids); err != nil {
  289. log.Error("%+v", err)
  290. err = nil
  291. }
  292. return
  293. })
  294. }
  295. if len(roomIDs) != 0 {
  296. g.Go(func() (err error) {
  297. if rm, err = s.lv.AppMRoom(ctx, roomIDs); err != nil {
  298. log.Error("%+v", err)
  299. err = nil
  300. }
  301. for _, r := range rm {
  302. rmUpIDs = append(rmUpIDs, r.UID)
  303. }
  304. return
  305. })
  306. }
  307. if len(sids) != 0 {
  308. g.Go(func() (err error) {
  309. if sm, err = s.bgm.Seasons(ctx, sids, now); err != nil {
  310. log.Error("%+v", err)
  311. err = nil
  312. }
  313. return
  314. })
  315. }
  316. if len(seasonIDs) != 0 {
  317. g.Go(func() (err error) {
  318. if seasonCards, err = s.bgm.EpidsCardsInfoReply(ctx, seasonIDs); err != nil {
  319. log.Error("%+v", err)
  320. err = nil
  321. }
  322. return
  323. })
  324. }
  325. if len(metaIDs) != 0 {
  326. g.Go(func() (err error) {
  327. if atm, err = s.art.Articles(ctx, metaIDs); err != nil {
  328. log.Error("%+v", err)
  329. err = nil
  330. }
  331. for _, at := range atm {
  332. if at.Author != nil {
  333. mtUpIDs = append(mtUpIDs, at.Author.Mid)
  334. }
  335. }
  336. return
  337. })
  338. }
  339. if len(shopIDs) != 0 {
  340. g.Go(func() (err error) {
  341. if scm, err = s.sp.Card(ctx, shopIDs); err != nil {
  342. log.Error("%+v", err)
  343. err = nil
  344. }
  345. return
  346. })
  347. }
  348. if len(audioIDs) != 0 {
  349. g.Go(func() (err error) {
  350. if aum, err = s.audio.Audios(ctx, audioIDs); err != nil {
  351. log.Error("%+v", err)
  352. err = nil
  353. }
  354. return
  355. })
  356. }
  357. if len(actIDs) != 0 {
  358. g.Go(func() (err error) {
  359. if actm, err = s.act.Activitys(ctx, actIDs); err != nil {
  360. log.Error("%+v", err)
  361. err = nil
  362. }
  363. return
  364. })
  365. }
  366. if len(topIDs) != 0 {
  367. g.Go(func() (err error) {
  368. if topm, err = s.act.Activitys(ctx, topIDs); err != nil {
  369. log.Error("%+v", err)
  370. err = nil
  371. }
  372. return
  373. })
  374. }
  375. if err = g.Wait(); err != nil {
  376. log.Error("%+v", err)
  377. return
  378. }
  379. upIDs = append(upIDs, avUpIDs...)
  380. upIDs = append(upIDs, rmUpIDs...)
  381. upIDs = append(upIDs, mtUpIDs...)
  382. g, ctx = errgroup.WithContext(c)
  383. if len(upIDs) != 0 {
  384. g.Go(func() (err error) {
  385. if infocard, err = s.acc.Cards3(ctx, upIDs); err != nil {
  386. log.Error("%+v", err)
  387. err = nil
  388. }
  389. return
  390. })
  391. g.Go(func() (err error) {
  392. if upStatm, err = s.rel.Stats(ctx, upIDs); err != nil {
  393. log.Error("%+v", err)
  394. err = nil
  395. }
  396. return
  397. })
  398. if mid != 0 {
  399. g.Go(func() error {
  400. follows = s.acc.Relations3(ctx, upIDs, mid)
  401. return nil
  402. })
  403. }
  404. }
  405. if err = g.Wait(); err != nil {
  406. log.Error("%+v", err)
  407. return
  408. }
  409. for _, c := range channelCards {
  410. i := &feed.Item{}
  411. i.Pos = c.Pos
  412. i.FromType = _fTypeOperation
  413. switch c.Type {
  414. case model.GotoAv, model.GotoUpRcmdAv:
  415. a := am[c.Value]
  416. isOsea := model.IsOverseas(plat)
  417. if a != nil && a.IsNormal() && (!isOsea || (isOsea && a.AttrVal(archive.AttrBitOverseaLock) == 0)) {
  418. i.FromPlayerAv(a)
  419. i.FromDislikeReason()
  420. i.FromRcmdReason(c)
  421. if follows[i.Mid] {
  422. i.IsAtten = 1
  423. if i.RcmdReason != nil && i.RcmdReason.Content == "已关注" {
  424. i.RcmdReason.Content = ""
  425. }
  426. }
  427. //for GotoUpRcmdAv
  428. i.Goto = c.Type
  429. is = append(is, i)
  430. }
  431. case model.GotoLive:
  432. if r, ok := rm[c.Value]; ok {
  433. i.FromLive(r)
  434. if card, ok := infocard[i.Mid]; ok {
  435. if card.Official.Role != 0 {
  436. i.Official = &feed.OfficialInfo{Role: card.Official.Role, Title: card.Official.Title, Desc: card.Official.Desc}
  437. }
  438. }
  439. if stat, ok := upStatm[i.Mid]; ok {
  440. i.Fans = stat.Follower
  441. }
  442. if follows[i.Mid] {
  443. i.IsAtten = 1
  444. }
  445. if i.Goto != "" {
  446. is = append(is, i)
  447. }
  448. }
  449. case model.GotoBangumi:
  450. if s, ok := sm[c.Value]; ok {
  451. i.FromSeason(s)
  452. is = append(is, i)
  453. }
  454. case model.GotoPGC:
  455. if s, ok := seasonCards[int32(c.Value)]; ok {
  456. i.FromPGCSeason(s)
  457. is = append(is, i)
  458. }
  459. case model.GotoActivity:
  460. if act, ok := actm[c.Value]; ok && act.H5Cover != "" && act.H5URL != "" {
  461. i.FromActivity(act, now)
  462. if i.Goto != "" {
  463. is = append(is, i)
  464. }
  465. }
  466. case model.GotoTopic:
  467. if top, ok := topm[c.Value]; ok && top.H5Cover != "" && top.H5URL != "" {
  468. i.FromTopic(top)
  469. is = append(is, i)
  470. }
  471. case model.GotoSpecial:
  472. if sc, ok := s.specialCardCache[c.Value]; ok {
  473. i.FromSpecial(sc.ID, sc.Title, sc.Cover, sc.Desc, sc.ReValue, sc.ReType, sc.Badge, sc.Size)
  474. }
  475. if i.Goto != "" {
  476. is = append(is, i)
  477. }
  478. case model.GotoSpecialS:
  479. if sc, ok := s.specialCardCache[c.Value]; ok {
  480. i.FromSpecialS(sc.ID, sc.Title, sc.Cover, sc.Desc, sc.ReValue, sc.ReType, sc.Badge)
  481. }
  482. if i.Goto != "" {
  483. is = append(is, i)
  484. }
  485. case model.GotoTopstick:
  486. if sc, ok := s.specialCardCache[c.Value]; ok {
  487. i.FromTopstick(sc.ID, sc.Title, sc.Cover, sc.Desc, sc.ReValue, sc.ReType)
  488. top = i
  489. }
  490. case model.GotoConverge:
  491. if cc, ok := convergem[c.Value]; ok {
  492. i.FromConverge(cc, am, rm, atm)
  493. if i.Goto != "" {
  494. is = append(is, i)
  495. }
  496. }
  497. case model.GotoGameDownload:
  498. if gd, ok := downloadm[c.Value]; ok {
  499. i.FromGameDownload(gd, plat, build)
  500. if i.Goto != "" {
  501. is = append(is, i)
  502. }
  503. }
  504. case model.GotoGameDownloadS:
  505. if gd, ok := downloadm[c.Value]; ok {
  506. i.FromGameDownloadS(gd, plat, build)
  507. if i.Goto != "" {
  508. is = append(is, i)
  509. }
  510. }
  511. case model.GotoArticle:
  512. if m, ok := atm[c.Value]; ok {
  513. i.FromArticle(m)
  514. if card, ok := infocard[i.Mid]; ok {
  515. if card.Official.Role != 0 {
  516. i.Official = &feed.OfficialInfo{Role: card.Official.Role, Title: card.Official.Title, Desc: card.Official.Desc}
  517. }
  518. }
  519. if i.Goto != "" {
  520. is = append(is, i)
  521. }
  522. }
  523. case model.GotoArticleS:
  524. if m, ok := atm[c.Value]; ok {
  525. i.FromArticleS(m)
  526. if card, ok := infocard[i.Mid]; ok {
  527. if card.Official.Role != 0 {
  528. i.Official = &feed.OfficialInfo{Role: card.Official.Role, Title: card.Official.Title, Desc: card.Official.Desc}
  529. }
  530. }
  531. if i.Goto != "" {
  532. is = append(is, i)
  533. }
  534. }
  535. case model.GotoShoppingS:
  536. if c, ok := scm[c.Value]; ok {
  537. i.FromShoppingS(c)
  538. if i.Goto != "" {
  539. is = append(is, i)
  540. }
  541. }
  542. case model.GotoAudio:
  543. if au, ok := aum[c.Value]; ok {
  544. i.FromAudio(au)
  545. is = append(is, i)
  546. }
  547. case model.GotoPlayer:
  548. if a, ok := am[c.Value]; ok {
  549. i.FromPlayer(a)
  550. if i.Goto != "" {
  551. if follows[i.Mid] {
  552. i.IsAtten = 1
  553. }
  554. if card, ok := infocard[i.Mid]; ok {
  555. if card.Official.Role != 0 {
  556. i.Official = &feed.OfficialInfo{Role: card.Official.Role, Title: card.Official.Title, Desc: card.Official.Desc}
  557. }
  558. }
  559. i.FromDislikeReason()
  560. is = append(is, i)
  561. }
  562. }
  563. case model.GotoPlayerLive:
  564. if r, ok := rm[c.Value]; ok {
  565. i.FromPlayerLive(r)
  566. if i.Goto != "" {
  567. if follows[i.Mid] {
  568. i.IsAtten = 1
  569. }
  570. if card, ok := infocard[i.Mid]; ok {
  571. if card.Official.Role != 0 {
  572. i.Official = &feed.OfficialInfo{Role: card.Official.Role, Title: card.Official.Title, Desc: card.Official.Desc}
  573. }
  574. }
  575. if stat, ok := upStatm[i.Mid]; ok {
  576. i.Fans = stat.Follower
  577. }
  578. is = append(is, i)
  579. }
  580. }
  581. case model.GotoSubscribe:
  582. if c, ok := followm[c.Value]; ok {
  583. i.FromSubscribe(c, infocard, follows, upStatm, tagm)
  584. is = append(is, i)
  585. }
  586. case model.GotoChannelRcmd:
  587. if c, ok := followm[c.Value]; ok {
  588. i.FromChannelRcmd(c, am, tagm)
  589. is = append(is, i)
  590. }
  591. case model.GotoLiveUpRcmd:
  592. if l, ok := liveUpm[c.Value]; ok {
  593. i.FromLiveUpRcmd(c.Value, l, infocard)
  594. is = append(is, i)
  595. }
  596. }
  597. }
  598. if len(listAID) > 0 {
  599. isOsea := model.IsOverseas(plat)
  600. for _, aid := range listAID {
  601. if _, ok := cardAids[aid]; ok {
  602. continue
  603. }
  604. i := &feed.Item{}
  605. a := am[aid]
  606. if a != nil && a.IsNormal() && (!isOsea || (isOsea && a.AttrVal(archive.AttrBitOverseaLock) == 0)) {
  607. i.FromType = _fTypeRecommend
  608. i.FromPlayerAv(a)
  609. i.FromDislikeReason()
  610. //for GotoUpRcmdAv
  611. i.Goto = model.GotoAv
  612. is = append(is, i)
  613. }
  614. }
  615. }
  616. rl := len(is)
  617. if rl == 0 {
  618. is = _emptyItem
  619. return
  620. }
  621. if idx == 0 {
  622. idx = now.Unix()
  623. }
  624. for i, r := range is {
  625. if pull {
  626. r.Idx = idx + int64(rl-i)
  627. } else {
  628. r.Idx = idx - int64(i+1)
  629. }
  630. }
  631. return
  632. }
  633. func (s *Service) feedItem(c context.Context, plat int8, cids []int64, mobiApp string, qn, fnver, fnval, build int) (is []*feed.Item, err error) {
  634. var (
  635. channelids map[int64]*archive.ArchiveWithPlayer
  636. _fTypeRecommend = "recommend"
  637. )
  638. if len(cids) == 0 {
  639. is = _emptyItem
  640. return
  641. }
  642. if channelids, err = s.ArchivesWithPlayer(c, cids, qn, mobiApp, fnver, fnval, build); err != nil {
  643. return
  644. }
  645. if len(channelids) > 0 {
  646. isOsea := model.IsOverseas(plat)
  647. for _, aid := range cids {
  648. i := &feed.Item{}
  649. i.FromType = _fTypeRecommend
  650. a := channelids[aid]
  651. if a != nil && a.IsNormal() && (!isOsea || (isOsea && a.AttrVal(archive.AttrBitOverseaLock) == 0)) {
  652. i.FromPlayerAv(a)
  653. i.FromDislikeReason()
  654. i.Goto = model.GotoAv
  655. is = append(is, i)
  656. }
  657. }
  658. }
  659. return
  660. }