search.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. package search
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. "go-common/app/interface/main/app-interface/conf"
  8. accdao "go-common/app/interface/main/app-interface/dao/account"
  9. arcdao "go-common/app/interface/main/app-interface/dao/archive"
  10. artdao "go-common/app/interface/main/app-interface/dao/article"
  11. bangumidao "go-common/app/interface/main/app-interface/dao/bangumi"
  12. bplusdao "go-common/app/interface/main/app-interface/dao/bplus"
  13. livedao "go-common/app/interface/main/app-interface/dao/live"
  14. resdao "go-common/app/interface/main/app-interface/dao/resource"
  15. srchdao "go-common/app/interface/main/app-interface/dao/search"
  16. tagdao "go-common/app/interface/main/app-interface/dao/tag"
  17. "go-common/app/interface/main/app-interface/model"
  18. "go-common/app/interface/main/app-interface/model/bangumi"
  19. "go-common/app/interface/main/app-interface/model/banner"
  20. "go-common/app/interface/main/app-interface/model/bplus"
  21. "go-common/app/interface/main/app-interface/model/live"
  22. "go-common/app/interface/main/app-interface/model/search"
  23. tagmdl "go-common/app/interface/main/app-interface/model/tag"
  24. article "go-common/app/interface/openplatform/article/model"
  25. account "go-common/app/service/main/account/model"
  26. "go-common/app/service/main/archive/api"
  27. resmdl "go-common/app/service/main/resource/model"
  28. seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
  29. "go-common/library/log"
  30. "go-common/library/sync/errgroup"
  31. )
  32. // const for search
  33. const (
  34. _oldAndroid = 514000
  35. _oldIOS = 6090
  36. IPhoneSearchResourceID = 2447
  37. AndroidSearchResourceID = 2450
  38. IPadSearchResourceID = 2811
  39. )
  40. var (
  41. _emptyItem = []*search.Item{}
  42. _emptyResult = &search.Result{
  43. NavInfo: []*search.NavInfo{},
  44. Page: 0,
  45. Items: search.ResultItems{
  46. Season: _emptyItem,
  47. Upper: _emptyItem,
  48. Movie: _emptyItem,
  49. Archive: _emptyItem,
  50. LiveRoom: _emptyItem,
  51. LiveUser: _emptyItem,
  52. },
  53. }
  54. )
  55. // Service is search service
  56. type Service struct {
  57. c *conf.Config
  58. srchDao *srchdao.Dao
  59. accDao *accdao.Dao
  60. arcDao *arcdao.Dao
  61. liveDao *livedao.Dao
  62. artDao *artdao.Dao
  63. resDao *resdao.Dao
  64. tagDao *tagdao.Dao
  65. bangumiDao *bangumidao.Dao
  66. bplusDao *bplusdao.Dao
  67. // config
  68. seasonNum int
  69. movieNum int
  70. seasonShowMore int
  71. movieShowMore int
  72. upUserNum int
  73. uvLimit int
  74. userNum int
  75. userVideoLimit int
  76. biliUserNum int
  77. biliUserVideoLimit int
  78. iPadSearchBangumi int
  79. iPadSearchFt int
  80. }
  81. // New is search service initial func
  82. func New(c *conf.Config) (s *Service) {
  83. s = &Service{
  84. c: c,
  85. srchDao: srchdao.New(c),
  86. accDao: accdao.New(c),
  87. liveDao: livedao.New(c),
  88. arcDao: arcdao.New(c),
  89. artDao: artdao.New(c),
  90. resDao: resdao.New(c),
  91. tagDao: tagdao.New(c),
  92. bangumiDao: bangumidao.New(c),
  93. bplusDao: bplusdao.New(c),
  94. seasonNum: c.Search.SeasonNum,
  95. movieNum: c.Search.MovieNum,
  96. seasonShowMore: c.Search.SeasonMore,
  97. movieShowMore: c.Search.MovieMore,
  98. upUserNum: c.Search.UpUserNum,
  99. uvLimit: c.Search.UVLimit,
  100. userNum: c.Search.UpUserNum,
  101. userVideoLimit: c.Search.UVLimit,
  102. biliUserNum: c.Search.BiliUserNum,
  103. biliUserVideoLimit: c.Search.BiliUserVideoLimit,
  104. iPadSearchBangumi: c.Search.IPadSearchBangumi,
  105. iPadSearchFt: c.Search.IPadSearchFt,
  106. }
  107. return
  108. }
  109. // Search get all type search data.
  110. func (s *Service) Search(c context.Context, mid, zoneid int64, mobiApp, device, platform, buvid, keyword, duration, order, filtered, lang, fromSource, recommend, parent string, plat int8, rid, highlight, build, pn, ps, isQuery int, old bool, now time.Time) (res *search.Result, err error) {
  111. const (
  112. _newIPhonePGC = 6500
  113. _newAndroidPGC = 519010
  114. _newIPhoneSearch = 6500
  115. _newAndroidSearch = 5215000
  116. _newAndroidBSearch = 591200
  117. )
  118. var (
  119. newPGC, flow, isNewTwitter bool
  120. avids []int64
  121. avm map[int64]*api.Arc
  122. owners []int64
  123. follows map[int64]bool
  124. roomIDs []int64
  125. lm map[int64]*live.RoomInfo
  126. seasonIDs []int64
  127. bangumis map[string]*bangumi.Card
  128. //tagSeasonIDs []int32
  129. tagBangumis map[int32]*seasongrpc.CardInfoProto
  130. tags []int64
  131. tagMyInfos []*tagmdl.Tag
  132. dynamicIDs []int64
  133. dynamicDetails map[int64]*bplus.Detail
  134. accInfos map[int64]*account.Info
  135. cooperation bool
  136. )
  137. // android 概念版 591205
  138. if (plat == model.PlatAndroid && build >= _newAndroidPGC && build != 591205) || (plat == model.PlatIPhone && build >= _newIPhonePGC && build != 7140) || (plat == model.PlatAndroidB && build >= _newAndroidBSearch) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
  139. newPGC = true
  140. }
  141. // 处理一个ios概念版是 7140,是否需要过滤
  142. if (plat == model.PlatAndroid && build >= _newAndroidSearch) || (plat == model.PlatIPhone && build >= _newIPhoneSearch && build != 7140) || (plat == model.PlatAndroidB && build >= _newAndroidBSearch) || model.IsIPhoneB(plat) {
  143. flow = true
  144. }
  145. var (
  146. seasonNum int
  147. movieNum int
  148. )
  149. if (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) {
  150. seasonNum = s.iPadSearchBangumi
  151. movieNum = s.iPadSearchFt
  152. } else {
  153. seasonNum = s.seasonNum
  154. movieNum = s.movieNum
  155. }
  156. all, code, err := s.srchDao.Search(c, mid, zoneid, mobiApp, device, platform, buvid, keyword, duration, order, filtered, fromSource, recommend, parent, plat, seasonNum, movieNum, s.upUserNum, s.uvLimit, s.userNum, s.userVideoLimit, s.biliUserNum, s.biliUserVideoLimit, rid, highlight, build, pn, ps, isQuery, old, now, newPGC, flow)
  157. if err != nil {
  158. log.Error("%+v", err)
  159. return
  160. }
  161. if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.NewTwitterAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.NewTwitterIOS) {
  162. isNewTwitter = true
  163. }
  164. if code == model.ForbidCode || code == model.NoResultCode {
  165. res = _emptyResult
  166. err = nil
  167. return
  168. }
  169. res = &search.Result{}
  170. res.Trackid = all.Trackid
  171. res.Page = all.Page
  172. res.Array = all.FlowPlaceholder
  173. res.Attribute = all.Attribute
  174. res.NavInfo = s.convertNav(all, plat, build, lang, old, newPGC)
  175. if len(all.FlowResult) != 0 {
  176. var item []*search.Item
  177. for _, v := range all.FlowResult {
  178. switch v.Type {
  179. case search.TypeUser, search.TypeBiliUser:
  180. owners = append(owners, v.User.Mid)
  181. for _, vr := range v.User.Res {
  182. avids = append(avids, vr.Aid)
  183. }
  184. roomIDs = append(roomIDs, v.User.RoomID)
  185. case search.TypeVideo:
  186. avids = append(avids, v.Video.ID)
  187. case search.TypeLive:
  188. roomIDs = append(roomIDs, v.Live.RoomID)
  189. case search.TypeMediaBangumi, search.TypeMediaFt:
  190. seasonIDs = append(seasonIDs, v.Media.SeasonID)
  191. case search.TypeStar:
  192. if v.Star.MID != 0 {
  193. owners = append(owners, v.Star.MID)
  194. }
  195. if v.Star.TagID != 0 {
  196. tags = append(tags, v.Star.TagID)
  197. }
  198. case search.TypeArticle:
  199. owners = append(owners, v.Article.Mid)
  200. case search.TypeChannel:
  201. tags = append(tags, v.Channel.TagID)
  202. if len(v.Channel.Values) > 0 {
  203. for _, vc := range v.Channel.Values {
  204. switch vc.Type {
  205. case search.TypeVideo:
  206. if vc.Video != nil {
  207. avids = append(avids, vc.Video.ID)
  208. }
  209. //case search.TypeLive:
  210. // if vc.Live != nil {
  211. // roomIDs = append(roomIDs, vc.Live.RoomID)
  212. // }
  213. //case search.TypeMediaBangumi, search.TypeMediaFt:
  214. // if vc.Media != nil {
  215. // tagSeasonIDs = append(tagSeasonIDs, int32(vc.Media.SeasonID))
  216. // }
  217. }
  218. }
  219. }
  220. case search.TypeTwitter:
  221. dynamicIDs = append(dynamicIDs, v.Twitter.ID)
  222. }
  223. }
  224. g, ctx := errgroup.WithContext(c)
  225. if len(owners) != 0 {
  226. if mid > 0 {
  227. g.Go(func() error {
  228. follows = s.accDao.Relations3(ctx, owners, mid)
  229. return nil
  230. })
  231. }
  232. g.Go(func() (err error) {
  233. if accInfos, err = s.accDao.Infos3(ctx, owners); err != nil {
  234. log.Error("%v", err)
  235. err = nil
  236. }
  237. return
  238. })
  239. }
  240. if len(avids) != 0 {
  241. g.Go(func() (err error) {
  242. if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
  243. log.Error("%+v", err)
  244. err = nil
  245. }
  246. return
  247. })
  248. }
  249. if len(roomIDs) != 0 {
  250. g.Go(func() (err error) {
  251. if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
  252. log.Error("%+v", err)
  253. err = nil
  254. }
  255. return
  256. })
  257. }
  258. if len(seasonIDs) != 0 {
  259. g.Go(func() (err error) {
  260. if bangumis, err = s.bangumiDao.Card(ctx, mid, seasonIDs); err != nil {
  261. log.Error("%+v", err)
  262. err = nil
  263. }
  264. return
  265. })
  266. }
  267. //if len(tagSeasonIDs) != 0 {
  268. // g.Go(func() (err error) {
  269. // if tagBangumis, err = s.bangumiDao.Cards(ctx, tagSeasonIDs); err != nil {
  270. // log.Error("%+v", err)
  271. // err = nil
  272. // }
  273. // return
  274. // })
  275. //}
  276. if len(tags) != 0 {
  277. g.Go(func() (err error) {
  278. if tagMyInfos, err = s.tagDao.TagInfos(ctx, tags, mid); err != nil {
  279. log.Error("%v \n", err)
  280. err = nil
  281. }
  282. return
  283. })
  284. }
  285. if len(dynamicIDs) != 0 {
  286. g.Go(func() (err error) {
  287. if dynamicDetails, err = s.bplusDao.DynamicDetails(ctx, dynamicIDs, "search"); err != nil {
  288. log.Error("%v \n", err)
  289. err = nil
  290. }
  291. return
  292. })
  293. }
  294. if err = g.Wait(); err != nil {
  295. log.Error("%+v", err)
  296. return
  297. }
  298. if all.SuggestKeyword != "" && pn == 1 {
  299. i := &search.Item{Title: all.SuggestKeyword, Goto: model.GotoSuggestKeyWord, SugKeyWordType: 1}
  300. item = append(item, i)
  301. } else if all.CrrQuery != "" && pn == 1 {
  302. if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.QueryCorAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.QueryCorIOS) {
  303. i := &search.Item{Title: fmt.Sprintf("已匹配%q的搜索结果", all.CrrQuery), Goto: model.GotoSuggestKeyWord, SugKeyWordType: 2}
  304. item = append(item, i)
  305. }
  306. }
  307. for _, v := range all.FlowResult {
  308. i := &search.Item{TrackID: v.TrackID, LinkType: v.LinkType, Position: v.Position}
  309. switch v.Type {
  310. case search.TypeVideo:
  311. if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.CooperationAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.CooperationIOS) {
  312. cooperation = true
  313. }
  314. i.FromVideo(v.Video, avm[v.Video.ID], cooperation)
  315. case search.TypeLive:
  316. i.FromLive(v.Live, lm[v.Live.RoomID])
  317. case search.TypeMediaBangumi:
  318. i.FromMedia(v.Media, "", model.GotoBangumi, bangumis)
  319. case search.TypeMediaFt:
  320. i.FromMedia(v.Media, "", model.GotoMovie, bangumis)
  321. case search.TypeArticle:
  322. i.FromArticle(v.Article, accInfos[v.Article.Mid])
  323. case search.TypeSpecial:
  324. i.FromOperate(v.Operate, model.GotoSpecial)
  325. case search.TypeBanner:
  326. i.FromOperate(v.Operate, model.GotoBanner)
  327. case search.TypeUser:
  328. if follows[v.User.Mid] {
  329. i.Attentions = 1
  330. }
  331. i.FromUser(v.User, avm, lm[v.User.RoomID])
  332. case search.TypeBiliUser:
  333. if follows[v.User.Mid] {
  334. i.Attentions = 1
  335. }
  336. i.FromUpUser(v.User, avm, lm[v.User.RoomID])
  337. case search.TypeSpecialS:
  338. i.FromOperate(v.Operate, model.GotoSpecialS)
  339. case search.TypeGame:
  340. i.FromGame(v.Game)
  341. case search.TypeQuery:
  342. i.Title = v.TypeName
  343. i.FromQuery(v.Query)
  344. case search.TypeComic:
  345. i.FromComic(v.Comic)
  346. case search.TypeConverge:
  347. var (
  348. aids, rids, artids []int64
  349. am map[int64]*api.Arc
  350. rm map[int64]*live.Room
  351. artm map[int64]*article.Meta
  352. )
  353. for _, c := range v.Operate.ContentList {
  354. switch c.Type {
  355. case 0:
  356. aids = append(aids, c.ID)
  357. case 1:
  358. rids = append(rids, c.ID)
  359. case 2:
  360. artids = append(artids, c.ID)
  361. }
  362. }
  363. g, ctx := errgroup.WithContext(c)
  364. if len(aids) != 0 {
  365. g.Go(func() (err error) {
  366. if am, err = s.arcDao.Archives2(ctx, aids); err != nil {
  367. log.Error("%+v", err)
  368. err = nil
  369. }
  370. return
  371. })
  372. }
  373. if len(rids) != 0 {
  374. g.Go(func() (err error) {
  375. if rm, err = s.liveDao.AppMRoom(ctx, rids); err != nil {
  376. log.Error("%+v", err)
  377. err = nil
  378. }
  379. return
  380. })
  381. }
  382. if len(artids) != 0 {
  383. g.Go(func() (err error) {
  384. if artm, err = s.artDao.Articles(ctx, artids); err != nil {
  385. log.Error("%+v", err)
  386. err = nil
  387. }
  388. return
  389. })
  390. }
  391. if err = g.Wait(); err != nil {
  392. log.Error("%+v", err)
  393. continue
  394. }
  395. i.FromConverge(v.Operate, am, rm, artm)
  396. case search.TypeTwitter:
  397. i.FromTwitter(v.Twitter, dynamicDetails, s.c.SearchDynamicSwitch.IsUP, s.c.SearchDynamicSwitch.IsCount, isNewTwitter)
  398. case search.TypeStar:
  399. if v.Star.TagID != 0 {
  400. i.URIType = search.StarChannel
  401. for _, myInfo := range tagMyInfos {
  402. if myInfo != nil && myInfo.TagID == v.Star.TagID {
  403. i.IsAttention = myInfo.IsAtten
  404. break
  405. }
  406. }
  407. } else if v.Star.MID != 0 {
  408. i.URIType = search.StarSpace
  409. if follows[v.Star.MID] {
  410. i.IsAttention = 1
  411. }
  412. }
  413. i.FromStar(v.Star)
  414. case search.TypeTicket:
  415. i.FromTicket(v.Ticket)
  416. case search.TypeProduct:
  417. i.FromProduct(v.Product)
  418. case search.TypeSpecialerGuide:
  419. i.FromSpecialerGuide(v.SpecialerGuide)
  420. case search.TypeChannel:
  421. i.FromChannel(v.Channel, avm, tagBangumis, lm, tagMyInfos)
  422. }
  423. if i.Goto != "" {
  424. item = append(item, i)
  425. }
  426. }
  427. res.Item = item
  428. if plat == model.PlatAndroid && build < search.SearchEggInfoAndroid {
  429. return
  430. }
  431. if all.EggInfo != nil {
  432. res.EasterEgg = &search.EasterEgg{ID: all.EggInfo.Source, ShowCount: all.EggInfo.ShowCount}
  433. }
  434. return
  435. }
  436. var items []*search.Item
  437. if all.SuggestKeyword != "" && pn == 1 {
  438. res.Items.SuggestKeyWord = &search.Item{Title: all.SuggestKeyword, Goto: model.GotoSuggestKeyWord}
  439. }
  440. // archive
  441. for _, v := range all.Result.Video {
  442. avids = append(avids, v.ID)
  443. }
  444. if duration == "0" && order == "totalrank" && rid == 0 {
  445. for _, v := range all.Result.Movie {
  446. if v.Type == "movie" {
  447. avids = append(avids, v.Aid)
  448. }
  449. }
  450. }
  451. if pn == 1 {
  452. for _, v := range all.Result.User {
  453. for _, vr := range v.Res {
  454. avids = append(avids, vr.Aid)
  455. }
  456. }
  457. if old {
  458. for _, v := range all.Result.UpUser {
  459. for _, vr := range v.Res {
  460. avids = append(avids, vr.Aid)
  461. }
  462. owners = append(owners, v.Mid)
  463. roomIDs = append(roomIDs, v.RoomID)
  464. }
  465. } else {
  466. for _, v := range all.Result.BiliUser {
  467. for _, vr := range v.Res {
  468. avids = append(avids, vr.Aid)
  469. }
  470. owners = append(owners, v.Mid)
  471. roomIDs = append(roomIDs, v.RoomID)
  472. }
  473. }
  474. }
  475. if model.IsOverseas(plat) {
  476. for _, v := range all.Result.LiveRoom {
  477. roomIDs = append(roomIDs, v.RoomID)
  478. }
  479. for _, v := range all.Result.LiveUser {
  480. roomIDs = append(roomIDs, v.RoomID)
  481. }
  482. }
  483. g, ctx := errgroup.WithContext(c)
  484. if len(owners) != 0 {
  485. if mid > 0 {
  486. g.Go(func() error {
  487. follows = s.accDao.Relations3(ctx, owners, mid)
  488. return nil
  489. })
  490. }
  491. }
  492. if len(avids) != 0 {
  493. g.Go(func() (err error) {
  494. if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
  495. log.Error("%+v", err)
  496. err = nil
  497. }
  498. return
  499. })
  500. }
  501. if len(roomIDs) != 0 {
  502. g.Go(func() (err error) {
  503. if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
  504. log.Error("%+v", err)
  505. err = nil
  506. }
  507. return
  508. })
  509. }
  510. if err = g.Wait(); err != nil {
  511. log.Error("%+v", err)
  512. return
  513. }
  514. if duration == "0" && order == "totalrank" && rid == 0 {
  515. var promptBangumi, promptFt string
  516. // season
  517. bangumi := all.Result.Bangumi
  518. items = make([]*search.Item, 0, len(bangumi))
  519. for _, v := range bangumi {
  520. si := &search.Item{}
  521. if (model.IsAndroid(plat) && build <= _oldAndroid) || (model.IsIPhone(plat) && build <= _oldIOS) {
  522. si.FromSeason(v, model.GotoBangumi)
  523. } else {
  524. si.FromSeason(v, model.GotoBangumiWeb)
  525. }
  526. items = append(items, si)
  527. }
  528. res.Items.Season = items
  529. // movie
  530. movie := all.Result.Movie
  531. items = make([]*search.Item, 0, len(movie))
  532. for _, v := range movie {
  533. si := &search.Item{}
  534. si.FromMovie(v, avm)
  535. items = append(items, si)
  536. }
  537. res.Items.Movie = items
  538. // season2
  539. mb := all.Result.MediaBangumi
  540. items = make([]*search.Item, 0, len(mb))
  541. for k, v := range mb {
  542. si := &search.Item{}
  543. if ((plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD)) && (k == len(mb)-1) && all.PageInfo.MediaBangumi.NumResults > s.iPadSearchBangumi {
  544. promptBangumi = fmt.Sprintf("查看全部番剧 ( %d ) >", all.PageInfo.MediaBangumi.NumResults)
  545. }
  546. si.FromMedia(v, promptBangumi, model.GotoBangumi, nil)
  547. items = append(items, si)
  548. }
  549. res.Items.Season2 = items
  550. // movie2
  551. mf := all.Result.MediaFt
  552. items = make([]*search.Item, 0, len(mf))
  553. for k, v := range mf {
  554. si := &search.Item{}
  555. if ((plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD)) && (k == len(mf)-1) && all.PageInfo.MediaFt.NumResults > s.iPadSearchFt {
  556. promptFt = fmt.Sprintf("查看全部影视 ( %d ) >", all.PageInfo.MediaFt.NumResults)
  557. }
  558. si.FromMedia(v, promptFt, model.GotoMovie, nil)
  559. si.Goto = model.GotoAv
  560. items = append(items, si)
  561. }
  562. res.Items.Movie2 = items
  563. }
  564. if pn == 1 {
  565. // upper + user
  566. var tmp []*search.User
  567. if old {
  568. tmp = all.Result.UpUser
  569. } else {
  570. tmp = all.Result.BiliUser
  571. }
  572. items = make([]*search.Item, 0, len(tmp)+len(all.Result.User))
  573. for _, v := range all.Result.User {
  574. si := &search.Item{}
  575. si.FromUser(v, avm, lm[v.RoomID])
  576. if follows[v.Mid] {
  577. si.Attentions = 1
  578. }
  579. items = append(items, si)
  580. }
  581. if len(items) == 0 {
  582. for _, v := range tmp {
  583. si := &search.Item{}
  584. si.FromUpUser(v, avm, lm[v.RoomID])
  585. if follows[v.Mid] {
  586. si.Attentions = 1
  587. }
  588. if old {
  589. si.IsUp = true
  590. }
  591. items = append(items, si)
  592. }
  593. }
  594. res.Items.Upper = items
  595. }
  596. items = make([]*search.Item, 0, len(all.Result.Video))
  597. for _, v := range all.Result.Video {
  598. si := &search.Item{}
  599. si.FromVideo(v, avm[v.ID], cooperation)
  600. items = append(items, si)
  601. }
  602. res.Items.Archive = items
  603. // live room
  604. if model.IsOverseas(plat) {
  605. items = make([]*search.Item, 0, len(all.Result.LiveRoom))
  606. for _, v := range all.Result.LiveRoom {
  607. si := &search.Item{}
  608. si.FromLive(v, lm[v.RoomID])
  609. items = append(items, si)
  610. }
  611. res.Items.LiveRoom = items
  612. // live user
  613. items = make([]*search.Item, 0, len(all.Result.LiveUser))
  614. for _, v := range all.Result.LiveUser {
  615. si := &search.Item{}
  616. si.FromLive(v, lm[v.RoomID])
  617. items = append(items, si)
  618. }
  619. res.Items.LiveUser = items
  620. }
  621. return
  622. }
  623. // SearchByType is tag bangumi movie upuser video search
  624. func (s *Service) SearchByType(c context.Context, mid, zoneid int64, mobiApp, device, platform, buvid, sType, keyword, filtered, order string, plat int8, build, highlight, categoryID, userType, orderSort, pn, ps int, old bool, now time.Time) (res *search.TypeSearch, err error) {
  625. switch sType {
  626. case "season":
  627. if res, err = s.srchDao.Season(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, plat, build, pn, ps, now); err != nil {
  628. return
  629. }
  630. case "upper":
  631. if res, err = s.upper(c, mid, keyword, mobiApp, device, platform, buvid, filtered, order, s.biliUserVideoLimit, highlight, build, userType, orderSort, pn, ps, old, now); err != nil {
  632. return
  633. }
  634. case "movie":
  635. if !model.IsOverseas(plat) {
  636. if res, err = s.srchDao.MovieByType(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, plat, build, pn, ps, now); err != nil {
  637. return
  638. }
  639. }
  640. case "live_room", "live_user":
  641. if res, err = s.srchDao.LiveByType(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, order, sType, plat, build, pn, ps, now); err != nil {
  642. return
  643. }
  644. case "article":
  645. if res, err = s.article(c, mid, zoneid, highlight, keyword, mobiApp, device, platform, buvid, filtered, order, sType, plat, categoryID, build, pn, ps, now); err != nil {
  646. return
  647. }
  648. case "season2":
  649. if (model.IsAndroid(plat) && build <= s.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIOS(plat) && build <= s.c.SearchBuildLimit.PGCHighLightIOS) {
  650. highlight = 0
  651. }
  652. if res, err = s.srchDao.Season2(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
  653. return
  654. }
  655. case "movie2":
  656. if !model.IsOverseas(plat) {
  657. if (model.IsAndroid(plat) && build <= s.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIOS(plat) && build <= s.c.SearchBuildLimit.PGCHighLightIOS) {
  658. highlight = 0
  659. }
  660. if res, err = s.srchDao.MovieByType2(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
  661. return
  662. }
  663. }
  664. case "tag":
  665. if res, err = s.channel(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps, highlight); err != nil {
  666. return
  667. }
  668. case "video":
  669. if res, err = s.srchDao.Video(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
  670. return
  671. }
  672. }
  673. if res == nil {
  674. res = &search.TypeSearch{Items: []*search.Item{}}
  675. }
  676. return
  677. }
  678. // SearchLive is search live
  679. func (s *Service) SearchLive(c context.Context, mid int64, mobiApp, platform, buvid, device, sType, keyword, order string, build, pn, ps int) (res *search.TypeSearch, err error) {
  680. if res, err = s.srchDao.Live(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps); err != nil {
  681. return
  682. }
  683. if res == nil {
  684. res = &search.TypeSearch{Items: []*search.Item{}}
  685. }
  686. return
  687. }
  688. // SearchLiveAll is search live
  689. func (s *Service) SearchLiveAll(c context.Context, mid int64, mobiApp, platform, buvid, device, sType, keyword, order string, build, pn, ps int) (res *search.TypeSearchLiveAll, err error) {
  690. var (
  691. g *errgroup.Group
  692. ctx context.Context
  693. uid int64
  694. owners []int64
  695. glorys []*live.Glory
  696. follows map[int64]bool
  697. userInfos map[int64]map[string]*live.Exp
  698. )
  699. if res, err = s.srchDao.LiveAll(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps); err != nil {
  700. return
  701. }
  702. if res.Master != nil {
  703. for _, item := range res.Master.Items {
  704. uid = item.Mid
  705. owners = append(owners, uid)
  706. break
  707. }
  708. }
  709. if len(owners) != 0 {
  710. g, ctx = errgroup.WithContext(c)
  711. if uid > 0 {
  712. g.Go(func() error {
  713. follows = s.accDao.Relations3(ctx, owners, mid)
  714. return nil
  715. })
  716. g.Go(func() error {
  717. glorys, _ = s.liveDao.Glory(ctx, uid)
  718. return nil
  719. })
  720. g.Go(func() error {
  721. userInfos, _ = s.liveDao.UserInfo(ctx, owners)
  722. return nil
  723. })
  724. }
  725. if err = g.Wait(); err != nil {
  726. log.Error("%+v", err)
  727. return
  728. }
  729. for _, m := range res.Master.Items {
  730. if follows[uid] {
  731. m.IsAttention = 1
  732. }
  733. m.Glory = &search.Glory{
  734. Title: "主播荣誉",
  735. Total: len(glorys),
  736. Items: make([]*search.Item, 0, len(glorys)),
  737. }
  738. if userInfo, ok := userInfos[m.Mid]; ok {
  739. if u, ok := userInfo["exp"]; ok {
  740. if u != nil || u.Master != nil {
  741. m.Level = u.Master.Level
  742. m.LevelColor = u.Master.Color
  743. }
  744. }
  745. }
  746. for _, glory := range glorys {
  747. if glory.GloryInfo != nil {
  748. item := &search.Item{
  749. Title: glory.GloryInfo.Name,
  750. Cover: glory.GloryInfo.Cover,
  751. }
  752. m.Glory.Items = append(m.Glory.Items, item)
  753. }
  754. }
  755. }
  756. }
  757. if res == nil {
  758. res = &search.TypeSearchLiveAll{Master: &search.TypeSearch{Items: []*search.Item{}}, Room: &search.TypeSearch{Items: []*search.Item{}}}
  759. }
  760. return
  761. }
  762. // channel search for channel
  763. func (s *Service) channel(c context.Context, mid int64, keyword, mobiApp, platform, buvid, device, order, sType string, build, pn, ps, highlight int) (res *search.TypeSearch, err error) {
  764. var (
  765. g *errgroup.Group
  766. ctx context.Context
  767. tags []int64
  768. tagMyInfos []*tagmdl.Tag
  769. )
  770. if res, err = s.srchDao.Channel(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps, highlight); err != nil {
  771. return
  772. }
  773. if res == nil || len(res.Items) == 0 {
  774. return
  775. }
  776. tags = make([]int64, 0, len(res.Items))
  777. for _, item := range res.Items {
  778. tags = append(tags, item.ID)
  779. }
  780. if len(tags) != 0 {
  781. g, ctx = errgroup.WithContext(c)
  782. if mid > 0 {
  783. g.Go(func() error {
  784. tagMyInfos, _ = s.tagDao.TagInfos(ctx, tags, mid)
  785. return nil
  786. })
  787. }
  788. if err = g.Wait(); err != nil {
  789. log.Error("%+v", err)
  790. return
  791. }
  792. for _, item := range res.Items {
  793. for _, myInfo := range tagMyInfos {
  794. if myInfo != nil && myInfo.TagID == item.ID {
  795. item.IsAttention = myInfo.IsAtten
  796. break
  797. }
  798. }
  799. }
  800. }
  801. return
  802. }
  803. // upper search for upper
  804. func (s *Service) upper(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid, filtered, order string, biliUserVL, highlight, build, userType, orderSort, pn, ps int, old bool, now time.Time) (res *search.TypeSearch, err error) {
  805. var (
  806. g *errgroup.Group
  807. ctx context.Context
  808. owners []int64
  809. follows map[int64]bool
  810. )
  811. if res, err = s.srchDao.Upper(c, mid, keyword, mobiApp, device, platform, buvid, filtered, order, biliUserVL, highlight, build, userType, orderSort, pn, ps, old, now); err != nil {
  812. return
  813. }
  814. if res == nil || len(res.Items) == 0 {
  815. return
  816. }
  817. owners = make([]int64, 0, len(res.Items))
  818. for _, item := range res.Items {
  819. owners = append(owners, item.Mid)
  820. }
  821. if len(owners) != 0 {
  822. g, ctx = errgroup.WithContext(c)
  823. if mid > 0 {
  824. g.Go(func() error {
  825. follows = s.accDao.Relations3(ctx, owners, mid)
  826. return nil
  827. })
  828. }
  829. if err = g.Wait(); err != nil {
  830. log.Error("%+v", err)
  831. return
  832. }
  833. for _, item := range res.Items {
  834. if follows[item.Mid] {
  835. item.Attentions = 1
  836. }
  837. }
  838. }
  839. return
  840. }
  841. // article search for article
  842. func (s *Service) article(c context.Context, mid, zoneid int64, highlight int, keyword, mobiApp, device, platform, buvid, filtered, order, sType string, plat int8, categoryID, build, pn, ps int, now time.Time) (res *search.TypeSearch, err error) {
  843. if res, err = s.srchDao.ArticleByType(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, order, sType, plat, categoryID, build, highlight, pn, ps, now); err != nil {
  844. log.Error("%+v", err)
  845. return
  846. }
  847. if res != nil && len(res.Items) > 0 {
  848. var mids []int64
  849. for _, v := range res.Items {
  850. mids = append(mids, v.Mid)
  851. }
  852. var infom map[int64]*account.Info
  853. if infom, err = s.accDao.Infos3(c, mids); err != nil {
  854. log.Error("%+v", err)
  855. err = nil
  856. return
  857. }
  858. for _, item := range res.Items {
  859. if info, ok := infom[item.Mid]; ok {
  860. item.Name = info.Name
  861. }
  862. }
  863. }
  864. return
  865. }
  866. // HotSearch is hot word search
  867. func (s *Service) HotSearch(c context.Context, buvid string, mid int64, build, limit int, mobiApp, device, platform string, now time.Time) (res *search.Hot) {
  868. var err error
  869. if res, err = s.srchDao.HotSearch(c, buvid, mid, build, limit, mobiApp, device, platform, now); err != nil {
  870. log.Error("%+v", err)
  871. }
  872. if res != nil {
  873. res.TrackID = res.SeID
  874. res.SeID = ""
  875. res.Code = 0
  876. } else {
  877. res = &search.Hot{}
  878. }
  879. return
  880. }
  881. // Suggest for search suggest
  882. func (s *Service) Suggest(c context.Context, mid int64, buvid, keyword string, build int, mobiApp, device string, now time.Time) (res *search.Suggestion) {
  883. var (
  884. suggest *search.Suggest
  885. err error
  886. )
  887. res = &search.Suggestion{}
  888. if suggest, err = s.srchDao.Suggest(c, mid, buvid, keyword, build, mobiApp, device, now); err != nil {
  889. log.Error("%+v", err)
  890. return
  891. }
  892. if suggest != nil {
  893. res.UpUser = suggest.Result.Accurate.UpUser
  894. res.Bangumi = suggest.Result.Accurate.Bangumi
  895. for _, v := range suggest.Result.Tag {
  896. res.Suggest = append(res.Suggest, v.Value)
  897. }
  898. res.TrackID = suggest.Stoken
  899. }
  900. return
  901. }
  902. // Suggest2 for search suggest
  903. func (s *Service) Suggest2(c context.Context, mid int64, platform, buvid, keyword string, build int, mobiApp string, now time.Time) (res *search.Suggestion2) {
  904. var (
  905. suggest *search.Suggest2
  906. err error
  907. avids []int64
  908. avm map[int64]*api.Arc
  909. roomIDs []int64
  910. lm map[int64]*live.RoomInfo
  911. )
  912. res = &search.Suggestion2{}
  913. if suggest, err = s.srchDao.Suggest2(c, mid, platform, buvid, keyword, build, mobiApp, now); err != nil {
  914. log.Error("%+v", err)
  915. return
  916. }
  917. if suggest.Result != nil {
  918. for _, v := range suggest.Result.Tag {
  919. if v.SpID == search.SuggestionJump {
  920. if v.Type == search.SuggestionAV {
  921. avids = append(avids, v.Ref)
  922. }
  923. if v.Type == search.SuggestionLive {
  924. roomIDs = append(roomIDs, v.Ref)
  925. }
  926. }
  927. }
  928. g, ctx := errgroup.WithContext(c)
  929. if len(avids) != 0 {
  930. g.Go(func() (err error) {
  931. if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
  932. log.Error("%+v", err)
  933. err = nil
  934. }
  935. return
  936. })
  937. }
  938. if len(roomIDs) != 0 {
  939. g.Go(func() (err error) {
  940. if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
  941. log.Error("%+v", err)
  942. err = nil
  943. }
  944. return
  945. })
  946. }
  947. if err = g.Wait(); err != nil {
  948. log.Error("%+v", err)
  949. return
  950. }
  951. for _, v := range suggest.Result.Tag {
  952. si := &search.Item{}
  953. si.FromSuggest2(v, avm, lm)
  954. res.List = append(res.List, si)
  955. }
  956. res.TrackID = suggest.Stoken
  957. }
  958. return
  959. }
  960. // Suggest3 for search suggest
  961. func (s *Service) Suggest3(c context.Context, mid int64, platform, buvid, keyword, device string, build, highlight int, mobiApp string, now time.Time) (res *search.SuggestionResult3) {
  962. var (
  963. suggest *search.Suggest3
  964. err error
  965. avids []int64
  966. avm map[int64]*api.Arc
  967. roomIDs []int64
  968. lm map[int64]*live.RoomInfo
  969. )
  970. res = &search.SuggestionResult3{}
  971. if suggest, err = s.srchDao.Suggest3(c, mid, platform, buvid, keyword, device, build, highlight, mobiApp, now); err != nil {
  972. log.Error("%+v", err)
  973. return
  974. }
  975. for _, v := range suggest.Result {
  976. if v.TermType == search.SuggestionJump {
  977. if v.SubType == search.SuggestionAV {
  978. avids = append(avids, v.Ref)
  979. }
  980. if v.SubType == search.SuggestionLive {
  981. roomIDs = append(roomIDs, v.Ref)
  982. }
  983. }
  984. }
  985. g, ctx := errgroup.WithContext(c)
  986. if len(avids) != 0 {
  987. g.Go(func() (err error) {
  988. if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
  989. log.Error("%+v", err)
  990. err = nil
  991. }
  992. return
  993. })
  994. }
  995. if len(roomIDs) != 0 {
  996. g.Go(func() (err error) {
  997. if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
  998. log.Error("%+v", err)
  999. err = nil
  1000. }
  1001. return
  1002. })
  1003. }
  1004. if err = g.Wait(); err != nil {
  1005. log.Error("%+v", err)
  1006. return
  1007. }
  1008. for _, v := range suggest.Result {
  1009. si := &search.Item{}
  1010. si.FromSuggest3(v, avm, lm)
  1011. res.List = append(res.List, si)
  1012. }
  1013. res.TrackID = suggest.TrackID
  1014. return
  1015. }
  1016. // User for search uer
  1017. func (s *Service) User(c context.Context, mid int64, buvid, mobiApp, device, platform, keyword, filtered, order, fromSource string, highlight, build, userType, orderSort, pn, ps int, now time.Time) (res *search.UserResult) {
  1018. res = &search.UserResult{}
  1019. user, err := s.srchDao.User(c, mid, keyword, mobiApp, device, platform, buvid, filtered, order, fromSource, highlight, build, userType, orderSort, pn, ps, now)
  1020. if err != nil {
  1021. log.Error("%+v", err)
  1022. return
  1023. }
  1024. if len(user) == 0 {
  1025. return
  1026. }
  1027. res.Items = make([]*search.Item, 0, len(user))
  1028. for _, u := range user {
  1029. res.Items = append(res.Items, &search.Item{Mid: u.Mid, Name: u.Name, Face: u.Pic})
  1030. }
  1031. return
  1032. }
  1033. // convertNav deal with old search pageinfo to new.
  1034. func (s *Service) convertNav(all *search.Search, plat int8, build int, lang string, old, newPGC bool) (nis []*search.NavInfo) {
  1035. const (
  1036. _showHide = 0
  1037. _oldAndroidArticle = 515009
  1038. )
  1039. var (
  1040. season = "番剧"
  1041. live = "直播"
  1042. upper = "用户"
  1043. movie = "影视"
  1044. liveroom = "直播间"
  1045. liveuser = "主播"
  1046. article = "专栏"
  1047. )
  1048. if old {
  1049. upper = "UP主"
  1050. }
  1051. if lang == model.Hant {
  1052. season = "番劇"
  1053. live = "直播"
  1054. upper = "UP主"
  1055. movie = "影視"
  1056. liveroom = "直播间"
  1057. liveuser = "主播"
  1058. article = "專欄"
  1059. }
  1060. nis = make([]*search.NavInfo, 0, 4)
  1061. // season
  1062. if !newPGC && all.PageInfo.Bangumi != nil {
  1063. var nav = &search.NavInfo{
  1064. Name: season,
  1065. Total: all.PageInfo.Bangumi.NumResults,
  1066. Pages: all.PageInfo.Bangumi.Pages,
  1067. Type: 1,
  1068. }
  1069. if all.PageInfo.Bangumi.NumResults > s.seasonNum {
  1070. nav.Show = s.seasonShowMore
  1071. } else {
  1072. nav.Show = _showHide
  1073. }
  1074. nis = append(nis, nav)
  1075. }
  1076. // media season
  1077. if newPGC && all.PageInfo.MediaBangumi != nil {
  1078. var nav = &search.NavInfo{
  1079. Name: season,
  1080. Total: all.PageInfo.MediaBangumi.NumResults,
  1081. Pages: all.PageInfo.MediaBangumi.Pages,
  1082. Type: 7,
  1083. }
  1084. if all.PageInfo.MediaBangumi.NumResults > s.seasonNum {
  1085. nav.Show = s.seasonShowMore
  1086. } else {
  1087. nav.Show = _showHide
  1088. }
  1089. nis = append(nis, nav)
  1090. }
  1091. // live
  1092. if (model.IsAndroid(plat) && build > search.SearchLiveAllAndroid) || (model.IsIPhone(plat) && build > search.SearchLiveAllIOS) || ((plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD)) || model.IsIPhoneB(plat) {
  1093. if all.PageInfo.LiveAll != nil {
  1094. var nav = &search.NavInfo{
  1095. Name: live,
  1096. Total: all.PageInfo.LiveAll.NumResults,
  1097. Pages: all.PageInfo.LiveAll.Pages,
  1098. Type: 4,
  1099. }
  1100. nis = append(nis, nav)
  1101. }
  1102. } else {
  1103. if all.PageInfo.LiveRoom != nil {
  1104. var nav = &search.NavInfo{
  1105. Name: live,
  1106. Total: all.PageInfo.LiveRoom.NumResults,
  1107. Pages: all.PageInfo.LiveRoom.Pages,
  1108. Type: 4,
  1109. }
  1110. nis = append(nis, nav)
  1111. }
  1112. }
  1113. // upper
  1114. if old {
  1115. if all.PageInfo.UpUser != nil {
  1116. var nav = &search.NavInfo{
  1117. Name: upper,
  1118. Total: all.PageInfo.UpUser.NumResults,
  1119. Pages: all.PageInfo.UpUser.Pages,
  1120. Type: 2,
  1121. }
  1122. nis = append(nis, nav)
  1123. }
  1124. } else {
  1125. if all.PageInfo.BiliUser != nil {
  1126. var nav = &search.NavInfo{
  1127. Name: upper,
  1128. Total: all.PageInfo.BiliUser.NumResults,
  1129. Pages: all.PageInfo.BiliUser.Pages,
  1130. Type: 2,
  1131. }
  1132. nis = append(nis, nav)
  1133. }
  1134. }
  1135. // movie
  1136. if !newPGC && all.PageInfo.Film != nil {
  1137. var nav = &search.NavInfo{
  1138. Name: movie,
  1139. Total: all.PageInfo.Film.NumResults,
  1140. Pages: all.PageInfo.Film.Pages,
  1141. Type: 3,
  1142. }
  1143. if all.PageInfo.Movie != nil && all.PageInfo.Movie.NumResults > s.movieNum {
  1144. nav.Show = s.movieShowMore
  1145. } else {
  1146. nav.Show = _showHide
  1147. }
  1148. nis = append(nis, nav)
  1149. }
  1150. // media movie
  1151. if newPGC && all.PageInfo.MediaFt != nil {
  1152. var nav = &search.NavInfo{
  1153. Name: movie,
  1154. Total: all.PageInfo.MediaFt.NumResults,
  1155. Pages: all.PageInfo.MediaFt.Pages,
  1156. Type: 8,
  1157. }
  1158. if all.PageInfo.MediaFt.NumResults > s.movieNum {
  1159. nav.Show = s.movieShowMore
  1160. } else {
  1161. nav.Show = _showHide
  1162. }
  1163. nis = append(nis, nav)
  1164. }
  1165. if model.IsOverseas(plat) {
  1166. // live room
  1167. if all.PageInfo.LiveRoom != nil {
  1168. var nav = &search.NavInfo{
  1169. Name: liveroom,
  1170. Total: all.PageInfo.LiveRoom.NumResults,
  1171. Pages: all.PageInfo.LiveRoom.Pages,
  1172. Type: 4,
  1173. }
  1174. nis = append(nis, nav)
  1175. }
  1176. if all.PageInfo.LiveUser != nil {
  1177. var nav = &search.NavInfo{
  1178. Name: liveuser,
  1179. Total: all.PageInfo.LiveUser.NumResults,
  1180. Pages: all.PageInfo.LiveUser.Pages,
  1181. Type: 5,
  1182. }
  1183. nis = append(nis, nav)
  1184. }
  1185. } else {
  1186. if all.PageInfo.Article != nil {
  1187. if (model.IsIPhone(plat) && build > _oldIOS) || (model.IsAndroid(plat) && build > _oldAndroidArticle) || model.IsIPhoneB(plat) {
  1188. var nav = &search.NavInfo{
  1189. Name: article,
  1190. Total: all.PageInfo.Article.NumResults,
  1191. Pages: all.PageInfo.Article.Pages,
  1192. Type: 6,
  1193. }
  1194. nis = append(nis, nav)
  1195. }
  1196. }
  1197. }
  1198. return
  1199. }
  1200. // RecommendNoResult search when no result
  1201. func (s *Service) RecommendNoResult(c context.Context, platform, mobiApp, device, buvid, keyword string, build, pn, ps int, mid int64) (res *search.NoResultRcndResult, err error) {
  1202. if res, err = s.srchDao.RecommendNoResult(c, platform, mobiApp, device, buvid, keyword, build, pn, ps, mid); err != nil {
  1203. log.Error("%+v", err)
  1204. }
  1205. return
  1206. }
  1207. // Recommend search recommend
  1208. func (s *Service) Recommend(c context.Context, mid int64, build, from, show int, buvid, platform, mobiApp, device string) (res *search.RecommendResult, err error) {
  1209. if res, err = s.srchDao.Recommend(c, mid, build, from, show, buvid, platform, mobiApp, device); err != nil {
  1210. log.Error("%+v", err)
  1211. }
  1212. return
  1213. }
  1214. // DefaultWords search for default words
  1215. func (s *Service) DefaultWords(c context.Context, mid int64, build, from int, buvid, platform, mobiApp, device string) (res *search.DefaultWords, err error) {
  1216. if res, err = s.srchDao.DefaultWords(c, mid, build, from, buvid, platform, mobiApp, device); err != nil {
  1217. log.Error("%+v", err)
  1218. }
  1219. return
  1220. }
  1221. // Resource for rsource
  1222. func (s *Service) Resource(c context.Context, mobiApp, device, network, buvid, adExtra string, build int, plat int8, mid int64) (res []*banner.Banner, err error) {
  1223. var (
  1224. bnsm map[int][]*resmdl.Banner
  1225. resID int
  1226. )
  1227. if model.IsAndroid(plat) {
  1228. resID = AndroidSearchResourceID
  1229. } else if model.IsIPhone(plat) {
  1230. resID = IPhoneSearchResourceID
  1231. } else if model.IsIPad(plat) {
  1232. resID = IPadSearchResourceID
  1233. }
  1234. if bnsm, err = s.resDao.Banner(c, mobiApp, device, network, "", buvid, adExtra, strconv.Itoa(resID), build, plat, mid); err != nil {
  1235. return
  1236. }
  1237. // only one position
  1238. for _, rb := range bnsm[resID] {
  1239. b := &banner.Banner{}
  1240. b.ChangeBanner(rb)
  1241. res = append(res, b)
  1242. break
  1243. }
  1244. return
  1245. }
  1246. // RecommendPre search at pre-page.
  1247. func (s *Service) RecommendPre(c context.Context, platform, mobiApp, device, buvid string, build, ps int, mid int64) (res *search.RecommendPreResult, err error) {
  1248. if res, err = s.srchDao.RecommendPre(c, platform, mobiApp, device, buvid, build, ps, mid); err != nil {
  1249. log.Error("%+v", err)
  1250. }
  1251. return
  1252. }
  1253. // SearchEpisodes search PGC episodes
  1254. func (s *Service) SearchEpisodes(c context.Context, mid, ssID int64) (res []*search.Item, err error) {
  1255. var (
  1256. seasonIDs []int64
  1257. bangumis map[string]*bangumi.Card
  1258. )
  1259. seasonIDs = []int64{ssID}
  1260. if bangumis, err = s.bangumiDao.Card(c, mid, seasonIDs); err != nil {
  1261. log.Error("%+v", err)
  1262. return
  1263. }
  1264. if bangumi, ok := bangumis[strconv.FormatInt(ssID, 10)]; ok {
  1265. for _, v := range bangumi.Episodes {
  1266. tmp := &search.Item{
  1267. Param: strconv.Itoa(int(v.ID)),
  1268. Index: v.Index,
  1269. Badges: v.Badges,
  1270. }
  1271. tmp.URI = model.FillURI(model.GotoEP, tmp.Param, nil)
  1272. res = append(res, tmp)
  1273. }
  1274. }
  1275. return
  1276. }