123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302 |
- package search
- import (
- "context"
- "fmt"
- "strconv"
- "time"
- "go-common/app/interface/main/app-interface/conf"
- accdao "go-common/app/interface/main/app-interface/dao/account"
- arcdao "go-common/app/interface/main/app-interface/dao/archive"
- artdao "go-common/app/interface/main/app-interface/dao/article"
- bangumidao "go-common/app/interface/main/app-interface/dao/bangumi"
- bplusdao "go-common/app/interface/main/app-interface/dao/bplus"
- livedao "go-common/app/interface/main/app-interface/dao/live"
- resdao "go-common/app/interface/main/app-interface/dao/resource"
- srchdao "go-common/app/interface/main/app-interface/dao/search"
- tagdao "go-common/app/interface/main/app-interface/dao/tag"
- "go-common/app/interface/main/app-interface/model"
- "go-common/app/interface/main/app-interface/model/bangumi"
- "go-common/app/interface/main/app-interface/model/banner"
- "go-common/app/interface/main/app-interface/model/bplus"
- "go-common/app/interface/main/app-interface/model/live"
- "go-common/app/interface/main/app-interface/model/search"
- tagmdl "go-common/app/interface/main/app-interface/model/tag"
- article "go-common/app/interface/openplatform/article/model"
- account "go-common/app/service/main/account/model"
- "go-common/app/service/main/archive/api"
- resmdl "go-common/app/service/main/resource/model"
- seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- )
- // const for search
- const (
- _oldAndroid = 514000
- _oldIOS = 6090
- IPhoneSearchResourceID = 2447
- AndroidSearchResourceID = 2450
- IPadSearchResourceID = 2811
- )
- var (
- _emptyItem = []*search.Item{}
- _emptyResult = &search.Result{
- NavInfo: []*search.NavInfo{},
- Page: 0,
- Items: search.ResultItems{
- Season: _emptyItem,
- Upper: _emptyItem,
- Movie: _emptyItem,
- Archive: _emptyItem,
- LiveRoom: _emptyItem,
- LiveUser: _emptyItem,
- },
- }
- )
- // Service is search service
- type Service struct {
- c *conf.Config
- srchDao *srchdao.Dao
- accDao *accdao.Dao
- arcDao *arcdao.Dao
- liveDao *livedao.Dao
- artDao *artdao.Dao
- resDao *resdao.Dao
- tagDao *tagdao.Dao
- bangumiDao *bangumidao.Dao
- bplusDao *bplusdao.Dao
- // config
- seasonNum int
- movieNum int
- seasonShowMore int
- movieShowMore int
- upUserNum int
- uvLimit int
- userNum int
- userVideoLimit int
- biliUserNum int
- biliUserVideoLimit int
- iPadSearchBangumi int
- iPadSearchFt int
- }
- // New is search service initial func
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- c: c,
- srchDao: srchdao.New(c),
- accDao: accdao.New(c),
- liveDao: livedao.New(c),
- arcDao: arcdao.New(c),
- artDao: artdao.New(c),
- resDao: resdao.New(c),
- tagDao: tagdao.New(c),
- bangumiDao: bangumidao.New(c),
- bplusDao: bplusdao.New(c),
- seasonNum: c.Search.SeasonNum,
- movieNum: c.Search.MovieNum,
- seasonShowMore: c.Search.SeasonMore,
- movieShowMore: c.Search.MovieMore,
- upUserNum: c.Search.UpUserNum,
- uvLimit: c.Search.UVLimit,
- userNum: c.Search.UpUserNum,
- userVideoLimit: c.Search.UVLimit,
- biliUserNum: c.Search.BiliUserNum,
- biliUserVideoLimit: c.Search.BiliUserVideoLimit,
- iPadSearchBangumi: c.Search.IPadSearchBangumi,
- iPadSearchFt: c.Search.IPadSearchFt,
- }
- return
- }
- // Search get all type search data.
- 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) {
- const (
- _newIPhonePGC = 6500
- _newAndroidPGC = 519010
- _newIPhoneSearch = 6500
- _newAndroidSearch = 5215000
- _newAndroidBSearch = 591200
- )
- var (
- newPGC, flow, isNewTwitter bool
- avids []int64
- avm map[int64]*api.Arc
- owners []int64
- follows map[int64]bool
- roomIDs []int64
- lm map[int64]*live.RoomInfo
- seasonIDs []int64
- bangumis map[string]*bangumi.Card
- //tagSeasonIDs []int32
- tagBangumis map[int32]*seasongrpc.CardInfoProto
- tags []int64
- tagMyInfos []*tagmdl.Tag
- dynamicIDs []int64
- dynamicDetails map[int64]*bplus.Detail
- accInfos map[int64]*account.Info
- cooperation bool
- )
- // android 概念版 591205
- 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) {
- newPGC = true
- }
- // 处理一个ios概念版是 7140,是否需要过滤
- if (plat == model.PlatAndroid && build >= _newAndroidSearch) || (plat == model.PlatIPhone && build >= _newIPhoneSearch && build != 7140) || (plat == model.PlatAndroidB && build >= _newAndroidBSearch) || model.IsIPhoneB(plat) {
- flow = true
- }
- var (
- seasonNum int
- movieNum int
- )
- if (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) {
- seasonNum = s.iPadSearchBangumi
- movieNum = s.iPadSearchFt
- } else {
- seasonNum = s.seasonNum
- movieNum = s.movieNum
- }
- 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)
- if err != nil {
- log.Error("%+v", err)
- return
- }
- if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.NewTwitterAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.NewTwitterIOS) {
- isNewTwitter = true
- }
- if code == model.ForbidCode || code == model.NoResultCode {
- res = _emptyResult
- err = nil
- return
- }
- res = &search.Result{}
- res.Trackid = all.Trackid
- res.Page = all.Page
- res.Array = all.FlowPlaceholder
- res.Attribute = all.Attribute
- res.NavInfo = s.convertNav(all, plat, build, lang, old, newPGC)
- if len(all.FlowResult) != 0 {
- var item []*search.Item
- for _, v := range all.FlowResult {
- switch v.Type {
- case search.TypeUser, search.TypeBiliUser:
- owners = append(owners, v.User.Mid)
- for _, vr := range v.User.Res {
- avids = append(avids, vr.Aid)
- }
- roomIDs = append(roomIDs, v.User.RoomID)
- case search.TypeVideo:
- avids = append(avids, v.Video.ID)
- case search.TypeLive:
- roomIDs = append(roomIDs, v.Live.RoomID)
- case search.TypeMediaBangumi, search.TypeMediaFt:
- seasonIDs = append(seasonIDs, v.Media.SeasonID)
- case search.TypeStar:
- if v.Star.MID != 0 {
- owners = append(owners, v.Star.MID)
- }
- if v.Star.TagID != 0 {
- tags = append(tags, v.Star.TagID)
- }
- case search.TypeArticle:
- owners = append(owners, v.Article.Mid)
- case search.TypeChannel:
- tags = append(tags, v.Channel.TagID)
- if len(v.Channel.Values) > 0 {
- for _, vc := range v.Channel.Values {
- switch vc.Type {
- case search.TypeVideo:
- if vc.Video != nil {
- avids = append(avids, vc.Video.ID)
- }
- //case search.TypeLive:
- // if vc.Live != nil {
- // roomIDs = append(roomIDs, vc.Live.RoomID)
- // }
- //case search.TypeMediaBangumi, search.TypeMediaFt:
- // if vc.Media != nil {
- // tagSeasonIDs = append(tagSeasonIDs, int32(vc.Media.SeasonID))
- // }
- }
- }
- }
- case search.TypeTwitter:
- dynamicIDs = append(dynamicIDs, v.Twitter.ID)
- }
- }
- g, ctx := errgroup.WithContext(c)
- if len(owners) != 0 {
- if mid > 0 {
- g.Go(func() error {
- follows = s.accDao.Relations3(ctx, owners, mid)
- return nil
- })
- }
- g.Go(func() (err error) {
- if accInfos, err = s.accDao.Infos3(ctx, owners); err != nil {
- log.Error("%v", err)
- err = nil
- }
- return
- })
- }
- if len(avids) != 0 {
- g.Go(func() (err error) {
- if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(roomIDs) != 0 {
- g.Go(func() (err error) {
- if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(seasonIDs) != 0 {
- g.Go(func() (err error) {
- if bangumis, err = s.bangumiDao.Card(ctx, mid, seasonIDs); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- //if len(tagSeasonIDs) != 0 {
- // g.Go(func() (err error) {
- // if tagBangumis, err = s.bangumiDao.Cards(ctx, tagSeasonIDs); err != nil {
- // log.Error("%+v", err)
- // err = nil
- // }
- // return
- // })
- //}
- if len(tags) != 0 {
- g.Go(func() (err error) {
- if tagMyInfos, err = s.tagDao.TagInfos(ctx, tags, mid); err != nil {
- log.Error("%v \n", err)
- err = nil
- }
- return
- })
- }
- if len(dynamicIDs) != 0 {
- g.Go(func() (err error) {
- if dynamicDetails, err = s.bplusDao.DynamicDetails(ctx, dynamicIDs, "search"); err != nil {
- log.Error("%v \n", err)
- err = nil
- }
- return
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- if all.SuggestKeyword != "" && pn == 1 {
- i := &search.Item{Title: all.SuggestKeyword, Goto: model.GotoSuggestKeyWord, SugKeyWordType: 1}
- item = append(item, i)
- } else if all.CrrQuery != "" && pn == 1 {
- if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.QueryCorAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.QueryCorIOS) {
- i := &search.Item{Title: fmt.Sprintf("已匹配%q的搜索结果", all.CrrQuery), Goto: model.GotoSuggestKeyWord, SugKeyWordType: 2}
- item = append(item, i)
- }
- }
- for _, v := range all.FlowResult {
- i := &search.Item{TrackID: v.TrackID, LinkType: v.LinkType, Position: v.Position}
- switch v.Type {
- case search.TypeVideo:
- if (model.IsAndroid(plat) && build > s.c.SearchBuildLimit.CooperationAndroid) || (model.IsIPhone(plat) && build > s.c.SearchBuildLimit.CooperationIOS) {
- cooperation = true
- }
- i.FromVideo(v.Video, avm[v.Video.ID], cooperation)
- case search.TypeLive:
- i.FromLive(v.Live, lm[v.Live.RoomID])
- case search.TypeMediaBangumi:
- i.FromMedia(v.Media, "", model.GotoBangumi, bangumis)
- case search.TypeMediaFt:
- i.FromMedia(v.Media, "", model.GotoMovie, bangumis)
- case search.TypeArticle:
- i.FromArticle(v.Article, accInfos[v.Article.Mid])
- case search.TypeSpecial:
- i.FromOperate(v.Operate, model.GotoSpecial)
- case search.TypeBanner:
- i.FromOperate(v.Operate, model.GotoBanner)
- case search.TypeUser:
- if follows[v.User.Mid] {
- i.Attentions = 1
- }
- i.FromUser(v.User, avm, lm[v.User.RoomID])
- case search.TypeBiliUser:
- if follows[v.User.Mid] {
- i.Attentions = 1
- }
- i.FromUpUser(v.User, avm, lm[v.User.RoomID])
- case search.TypeSpecialS:
- i.FromOperate(v.Operate, model.GotoSpecialS)
- case search.TypeGame:
- i.FromGame(v.Game)
- case search.TypeQuery:
- i.Title = v.TypeName
- i.FromQuery(v.Query)
- case search.TypeComic:
- i.FromComic(v.Comic)
- case search.TypeConverge:
- var (
- aids, rids, artids []int64
- am map[int64]*api.Arc
- rm map[int64]*live.Room
- artm map[int64]*article.Meta
- )
- for _, c := range v.Operate.ContentList {
- switch c.Type {
- case 0:
- aids = append(aids, c.ID)
- case 1:
- rids = append(rids, c.ID)
- case 2:
- artids = append(artids, c.ID)
- }
- }
- g, ctx := errgroup.WithContext(c)
- if len(aids) != 0 {
- g.Go(func() (err error) {
- if am, err = s.arcDao.Archives2(ctx, aids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(rids) != 0 {
- g.Go(func() (err error) {
- if rm, err = s.liveDao.AppMRoom(ctx, rids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(artids) != 0 {
- g.Go(func() (err error) {
- if artm, err = s.artDao.Articles(ctx, artids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- continue
- }
- i.FromConverge(v.Operate, am, rm, artm)
- case search.TypeTwitter:
- i.FromTwitter(v.Twitter, dynamicDetails, s.c.SearchDynamicSwitch.IsUP, s.c.SearchDynamicSwitch.IsCount, isNewTwitter)
- case search.TypeStar:
- if v.Star.TagID != 0 {
- i.URIType = search.StarChannel
- for _, myInfo := range tagMyInfos {
- if myInfo != nil && myInfo.TagID == v.Star.TagID {
- i.IsAttention = myInfo.IsAtten
- break
- }
- }
- } else if v.Star.MID != 0 {
- i.URIType = search.StarSpace
- if follows[v.Star.MID] {
- i.IsAttention = 1
- }
- }
- i.FromStar(v.Star)
- case search.TypeTicket:
- i.FromTicket(v.Ticket)
- case search.TypeProduct:
- i.FromProduct(v.Product)
- case search.TypeSpecialerGuide:
- i.FromSpecialerGuide(v.SpecialerGuide)
- case search.TypeChannel:
- i.FromChannel(v.Channel, avm, tagBangumis, lm, tagMyInfos)
- }
- if i.Goto != "" {
- item = append(item, i)
- }
- }
- res.Item = item
- if plat == model.PlatAndroid && build < search.SearchEggInfoAndroid {
- return
- }
- if all.EggInfo != nil {
- res.EasterEgg = &search.EasterEgg{ID: all.EggInfo.Source, ShowCount: all.EggInfo.ShowCount}
- }
- return
- }
- var items []*search.Item
- if all.SuggestKeyword != "" && pn == 1 {
- res.Items.SuggestKeyWord = &search.Item{Title: all.SuggestKeyword, Goto: model.GotoSuggestKeyWord}
- }
- // archive
- for _, v := range all.Result.Video {
- avids = append(avids, v.ID)
- }
- if duration == "0" && order == "totalrank" && rid == 0 {
- for _, v := range all.Result.Movie {
- if v.Type == "movie" {
- avids = append(avids, v.Aid)
- }
- }
- }
- if pn == 1 {
- for _, v := range all.Result.User {
- for _, vr := range v.Res {
- avids = append(avids, vr.Aid)
- }
- }
- if old {
- for _, v := range all.Result.UpUser {
- for _, vr := range v.Res {
- avids = append(avids, vr.Aid)
- }
- owners = append(owners, v.Mid)
- roomIDs = append(roomIDs, v.RoomID)
- }
- } else {
- for _, v := range all.Result.BiliUser {
- for _, vr := range v.Res {
- avids = append(avids, vr.Aid)
- }
- owners = append(owners, v.Mid)
- roomIDs = append(roomIDs, v.RoomID)
- }
- }
- }
- if model.IsOverseas(plat) {
- for _, v := range all.Result.LiveRoom {
- roomIDs = append(roomIDs, v.RoomID)
- }
- for _, v := range all.Result.LiveUser {
- roomIDs = append(roomIDs, v.RoomID)
- }
- }
- g, ctx := errgroup.WithContext(c)
- if len(owners) != 0 {
- if mid > 0 {
- g.Go(func() error {
- follows = s.accDao.Relations3(ctx, owners, mid)
- return nil
- })
- }
- }
- if len(avids) != 0 {
- g.Go(func() (err error) {
- if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(roomIDs) != 0 {
- g.Go(func() (err error) {
- if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- if duration == "0" && order == "totalrank" && rid == 0 {
- var promptBangumi, promptFt string
- // season
- bangumi := all.Result.Bangumi
- items = make([]*search.Item, 0, len(bangumi))
- for _, v := range bangumi {
- si := &search.Item{}
- if (model.IsAndroid(plat) && build <= _oldAndroid) || (model.IsIPhone(plat) && build <= _oldIOS) {
- si.FromSeason(v, model.GotoBangumi)
- } else {
- si.FromSeason(v, model.GotoBangumiWeb)
- }
- items = append(items, si)
- }
- res.Items.Season = items
- // movie
- movie := all.Result.Movie
- items = make([]*search.Item, 0, len(movie))
- for _, v := range movie {
- si := &search.Item{}
- si.FromMovie(v, avm)
- items = append(items, si)
- }
- res.Items.Movie = items
- // season2
- mb := all.Result.MediaBangumi
- items = make([]*search.Item, 0, len(mb))
- for k, v := range mb {
- si := &search.Item{}
- if ((plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD)) && (k == len(mb)-1) && all.PageInfo.MediaBangumi.NumResults > s.iPadSearchBangumi {
- promptBangumi = fmt.Sprintf("查看全部番剧 ( %d ) >", all.PageInfo.MediaBangumi.NumResults)
- }
- si.FromMedia(v, promptBangumi, model.GotoBangumi, nil)
- items = append(items, si)
- }
- res.Items.Season2 = items
- // movie2
- mf := all.Result.MediaFt
- items = make([]*search.Item, 0, len(mf))
- for k, v := range mf {
- si := &search.Item{}
- if ((plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD)) && (k == len(mf)-1) && all.PageInfo.MediaFt.NumResults > s.iPadSearchFt {
- promptFt = fmt.Sprintf("查看全部影视 ( %d ) >", all.PageInfo.MediaFt.NumResults)
- }
- si.FromMedia(v, promptFt, model.GotoMovie, nil)
- si.Goto = model.GotoAv
- items = append(items, si)
- }
- res.Items.Movie2 = items
- }
- if pn == 1 {
- // upper + user
- var tmp []*search.User
- if old {
- tmp = all.Result.UpUser
- } else {
- tmp = all.Result.BiliUser
- }
- items = make([]*search.Item, 0, len(tmp)+len(all.Result.User))
- for _, v := range all.Result.User {
- si := &search.Item{}
- si.FromUser(v, avm, lm[v.RoomID])
- if follows[v.Mid] {
- si.Attentions = 1
- }
- items = append(items, si)
- }
- if len(items) == 0 {
- for _, v := range tmp {
- si := &search.Item{}
- si.FromUpUser(v, avm, lm[v.RoomID])
- if follows[v.Mid] {
- si.Attentions = 1
- }
- if old {
- si.IsUp = true
- }
- items = append(items, si)
- }
- }
- res.Items.Upper = items
- }
- items = make([]*search.Item, 0, len(all.Result.Video))
- for _, v := range all.Result.Video {
- si := &search.Item{}
- si.FromVideo(v, avm[v.ID], cooperation)
- items = append(items, si)
- }
- res.Items.Archive = items
- // live room
- if model.IsOverseas(plat) {
- items = make([]*search.Item, 0, len(all.Result.LiveRoom))
- for _, v := range all.Result.LiveRoom {
- si := &search.Item{}
- si.FromLive(v, lm[v.RoomID])
- items = append(items, si)
- }
- res.Items.LiveRoom = items
- // live user
- items = make([]*search.Item, 0, len(all.Result.LiveUser))
- for _, v := range all.Result.LiveUser {
- si := &search.Item{}
- si.FromLive(v, lm[v.RoomID])
- items = append(items, si)
- }
- res.Items.LiveUser = items
- }
- return
- }
- // SearchByType is tag bangumi movie upuser video search
- 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) {
- switch sType {
- case "season":
- if res, err = s.srchDao.Season(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, plat, build, pn, ps, now); err != nil {
- return
- }
- case "upper":
- 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 {
- return
- }
- case "movie":
- if !model.IsOverseas(plat) {
- if res, err = s.srchDao.MovieByType(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, plat, build, pn, ps, now); err != nil {
- return
- }
- }
- case "live_room", "live_user":
- if res, err = s.srchDao.LiveByType(c, mid, zoneid, keyword, mobiApp, device, platform, buvid, filtered, order, sType, plat, build, pn, ps, now); err != nil {
- return
- }
- case "article":
- 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 {
- return
- }
- case "season2":
- if (model.IsAndroid(plat) && build <= s.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIOS(plat) && build <= s.c.SearchBuildLimit.PGCHighLightIOS) {
- highlight = 0
- }
- if res, err = s.srchDao.Season2(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
- return
- }
- case "movie2":
- if !model.IsOverseas(plat) {
- if (model.IsAndroid(plat) && build <= s.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIOS(plat) && build <= s.c.SearchBuildLimit.PGCHighLightIOS) {
- highlight = 0
- }
- if res, err = s.srchDao.MovieByType2(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
- return
- }
- }
- case "tag":
- if res, err = s.channel(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps, highlight); err != nil {
- return
- }
- case "video":
- if res, err = s.srchDao.Video(c, mid, keyword, mobiApp, device, platform, buvid, highlight, build, pn, ps); err != nil {
- return
- }
- }
- if res == nil {
- res = &search.TypeSearch{Items: []*search.Item{}}
- }
- return
- }
- // SearchLive is search live
- 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) {
- if res, err = s.srchDao.Live(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps); err != nil {
- return
- }
- if res == nil {
- res = &search.TypeSearch{Items: []*search.Item{}}
- }
- return
- }
- // SearchLiveAll is search live
- 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) {
- var (
- g *errgroup.Group
- ctx context.Context
- uid int64
- owners []int64
- glorys []*live.Glory
- follows map[int64]bool
- userInfos map[int64]map[string]*live.Exp
- )
- if res, err = s.srchDao.LiveAll(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps); err != nil {
- return
- }
- if res.Master != nil {
- for _, item := range res.Master.Items {
- uid = item.Mid
- owners = append(owners, uid)
- break
- }
- }
- if len(owners) != 0 {
- g, ctx = errgroup.WithContext(c)
- if uid > 0 {
- g.Go(func() error {
- follows = s.accDao.Relations3(ctx, owners, mid)
- return nil
- })
- g.Go(func() error {
- glorys, _ = s.liveDao.Glory(ctx, uid)
- return nil
- })
- g.Go(func() error {
- userInfos, _ = s.liveDao.UserInfo(ctx, owners)
- return nil
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, m := range res.Master.Items {
- if follows[uid] {
- m.IsAttention = 1
- }
- m.Glory = &search.Glory{
- Title: "主播荣誉",
- Total: len(glorys),
- Items: make([]*search.Item, 0, len(glorys)),
- }
- if userInfo, ok := userInfos[m.Mid]; ok {
- if u, ok := userInfo["exp"]; ok {
- if u != nil || u.Master != nil {
- m.Level = u.Master.Level
- m.LevelColor = u.Master.Color
- }
- }
- }
- for _, glory := range glorys {
- if glory.GloryInfo != nil {
- item := &search.Item{
- Title: glory.GloryInfo.Name,
- Cover: glory.GloryInfo.Cover,
- }
- m.Glory.Items = append(m.Glory.Items, item)
- }
- }
- }
- }
- if res == nil {
- res = &search.TypeSearchLiveAll{Master: &search.TypeSearch{Items: []*search.Item{}}, Room: &search.TypeSearch{Items: []*search.Item{}}}
- }
- return
- }
- // channel search for channel
- 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) {
- var (
- g *errgroup.Group
- ctx context.Context
- tags []int64
- tagMyInfos []*tagmdl.Tag
- )
- if res, err = s.srchDao.Channel(c, mid, keyword, mobiApp, platform, buvid, device, order, sType, build, pn, ps, highlight); err != nil {
- return
- }
- if res == nil || len(res.Items) == 0 {
- return
- }
- tags = make([]int64, 0, len(res.Items))
- for _, item := range res.Items {
- tags = append(tags, item.ID)
- }
- if len(tags) != 0 {
- g, ctx = errgroup.WithContext(c)
- if mid > 0 {
- g.Go(func() error {
- tagMyInfos, _ = s.tagDao.TagInfos(ctx, tags, mid)
- return nil
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, item := range res.Items {
- for _, myInfo := range tagMyInfos {
- if myInfo != nil && myInfo.TagID == item.ID {
- item.IsAttention = myInfo.IsAtten
- break
- }
- }
- }
- }
- return
- }
- // upper search for upper
- 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) {
- var (
- g *errgroup.Group
- ctx context.Context
- owners []int64
- follows map[int64]bool
- )
- 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 {
- return
- }
- if res == nil || len(res.Items) == 0 {
- return
- }
- owners = make([]int64, 0, len(res.Items))
- for _, item := range res.Items {
- owners = append(owners, item.Mid)
- }
- if len(owners) != 0 {
- g, ctx = errgroup.WithContext(c)
- if mid > 0 {
- g.Go(func() error {
- follows = s.accDao.Relations3(ctx, owners, mid)
- return nil
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, item := range res.Items {
- if follows[item.Mid] {
- item.Attentions = 1
- }
- }
- }
- return
- }
- // article search for article
- 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) {
- 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 {
- log.Error("%+v", err)
- return
- }
- if res != nil && len(res.Items) > 0 {
- var mids []int64
- for _, v := range res.Items {
- mids = append(mids, v.Mid)
- }
- var infom map[int64]*account.Info
- if infom, err = s.accDao.Infos3(c, mids); err != nil {
- log.Error("%+v", err)
- err = nil
- return
- }
- for _, item := range res.Items {
- if info, ok := infom[item.Mid]; ok {
- item.Name = info.Name
- }
- }
- }
- return
- }
- // HotSearch is hot word search
- func (s *Service) HotSearch(c context.Context, buvid string, mid int64, build, limit int, mobiApp, device, platform string, now time.Time) (res *search.Hot) {
- var err error
- if res, err = s.srchDao.HotSearch(c, buvid, mid, build, limit, mobiApp, device, platform, now); err != nil {
- log.Error("%+v", err)
- }
- if res != nil {
- res.TrackID = res.SeID
- res.SeID = ""
- res.Code = 0
- } else {
- res = &search.Hot{}
- }
- return
- }
- // Suggest for search suggest
- func (s *Service) Suggest(c context.Context, mid int64, buvid, keyword string, build int, mobiApp, device string, now time.Time) (res *search.Suggestion) {
- var (
- suggest *search.Suggest
- err error
- )
- res = &search.Suggestion{}
- if suggest, err = s.srchDao.Suggest(c, mid, buvid, keyword, build, mobiApp, device, now); err != nil {
- log.Error("%+v", err)
- return
- }
- if suggest != nil {
- res.UpUser = suggest.Result.Accurate.UpUser
- res.Bangumi = suggest.Result.Accurate.Bangumi
- for _, v := range suggest.Result.Tag {
- res.Suggest = append(res.Suggest, v.Value)
- }
- res.TrackID = suggest.Stoken
- }
- return
- }
- // Suggest2 for search suggest
- func (s *Service) Suggest2(c context.Context, mid int64, platform, buvid, keyword string, build int, mobiApp string, now time.Time) (res *search.Suggestion2) {
- var (
- suggest *search.Suggest2
- err error
- avids []int64
- avm map[int64]*api.Arc
- roomIDs []int64
- lm map[int64]*live.RoomInfo
- )
- res = &search.Suggestion2{}
- if suggest, err = s.srchDao.Suggest2(c, mid, platform, buvid, keyword, build, mobiApp, now); err != nil {
- log.Error("%+v", err)
- return
- }
- if suggest.Result != nil {
- for _, v := range suggest.Result.Tag {
- if v.SpID == search.SuggestionJump {
- if v.Type == search.SuggestionAV {
- avids = append(avids, v.Ref)
- }
- if v.Type == search.SuggestionLive {
- roomIDs = append(roomIDs, v.Ref)
- }
- }
- }
- g, ctx := errgroup.WithContext(c)
- if len(avids) != 0 {
- g.Go(func() (err error) {
- if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(roomIDs) != 0 {
- g.Go(func() (err error) {
- if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, v := range suggest.Result.Tag {
- si := &search.Item{}
- si.FromSuggest2(v, avm, lm)
- res.List = append(res.List, si)
- }
- res.TrackID = suggest.Stoken
- }
- return
- }
- // Suggest3 for search suggest
- 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) {
- var (
- suggest *search.Suggest3
- err error
- avids []int64
- avm map[int64]*api.Arc
- roomIDs []int64
- lm map[int64]*live.RoomInfo
- )
- res = &search.SuggestionResult3{}
- if suggest, err = s.srchDao.Suggest3(c, mid, platform, buvid, keyword, device, build, highlight, mobiApp, now); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, v := range suggest.Result {
- if v.TermType == search.SuggestionJump {
- if v.SubType == search.SuggestionAV {
- avids = append(avids, v.Ref)
- }
- if v.SubType == search.SuggestionLive {
- roomIDs = append(roomIDs, v.Ref)
- }
- }
- }
- g, ctx := errgroup.WithContext(c)
- if len(avids) != 0 {
- g.Go(func() (err error) {
- if avm, err = s.arcDao.Archives2(ctx, avids); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if len(roomIDs) != 0 {
- g.Go(func() (err error) {
- if lm, err = s.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
- log.Error("%+v", err)
- err = nil
- }
- return
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("%+v", err)
- return
- }
- for _, v := range suggest.Result {
- si := &search.Item{}
- si.FromSuggest3(v, avm, lm)
- res.List = append(res.List, si)
- }
- res.TrackID = suggest.TrackID
- return
- }
- // User for search uer
- 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) {
- res = &search.UserResult{}
- user, err := s.srchDao.User(c, mid, keyword, mobiApp, device, platform, buvid, filtered, order, fromSource, highlight, build, userType, orderSort, pn, ps, now)
- if err != nil {
- log.Error("%+v", err)
- return
- }
- if len(user) == 0 {
- return
- }
- res.Items = make([]*search.Item, 0, len(user))
- for _, u := range user {
- res.Items = append(res.Items, &search.Item{Mid: u.Mid, Name: u.Name, Face: u.Pic})
- }
- return
- }
- // convertNav deal with old search pageinfo to new.
- func (s *Service) convertNav(all *search.Search, plat int8, build int, lang string, old, newPGC bool) (nis []*search.NavInfo) {
- const (
- _showHide = 0
- _oldAndroidArticle = 515009
- )
- var (
- season = "番剧"
- live = "直播"
- upper = "用户"
- movie = "影视"
- liveroom = "直播间"
- liveuser = "主播"
- article = "专栏"
- )
- if old {
- upper = "UP主"
- }
- if lang == model.Hant {
- season = "番劇"
- live = "直播"
- upper = "UP主"
- movie = "影視"
- liveroom = "直播间"
- liveuser = "主播"
- article = "專欄"
- }
- nis = make([]*search.NavInfo, 0, 4)
- // season
- if !newPGC && all.PageInfo.Bangumi != nil {
- var nav = &search.NavInfo{
- Name: season,
- Total: all.PageInfo.Bangumi.NumResults,
- Pages: all.PageInfo.Bangumi.Pages,
- Type: 1,
- }
- if all.PageInfo.Bangumi.NumResults > s.seasonNum {
- nav.Show = s.seasonShowMore
- } else {
- nav.Show = _showHide
- }
- nis = append(nis, nav)
- }
- // media season
- if newPGC && all.PageInfo.MediaBangumi != nil {
- var nav = &search.NavInfo{
- Name: season,
- Total: all.PageInfo.MediaBangumi.NumResults,
- Pages: all.PageInfo.MediaBangumi.Pages,
- Type: 7,
- }
- if all.PageInfo.MediaBangumi.NumResults > s.seasonNum {
- nav.Show = s.seasonShowMore
- } else {
- nav.Show = _showHide
- }
- nis = append(nis, nav)
- }
- // live
- 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) {
- if all.PageInfo.LiveAll != nil {
- var nav = &search.NavInfo{
- Name: live,
- Total: all.PageInfo.LiveAll.NumResults,
- Pages: all.PageInfo.LiveAll.Pages,
- Type: 4,
- }
- nis = append(nis, nav)
- }
- } else {
- if all.PageInfo.LiveRoom != nil {
- var nav = &search.NavInfo{
- Name: live,
- Total: all.PageInfo.LiveRoom.NumResults,
- Pages: all.PageInfo.LiveRoom.Pages,
- Type: 4,
- }
- nis = append(nis, nav)
- }
- }
- // upper
- if old {
- if all.PageInfo.UpUser != nil {
- var nav = &search.NavInfo{
- Name: upper,
- Total: all.PageInfo.UpUser.NumResults,
- Pages: all.PageInfo.UpUser.Pages,
- Type: 2,
- }
- nis = append(nis, nav)
- }
- } else {
- if all.PageInfo.BiliUser != nil {
- var nav = &search.NavInfo{
- Name: upper,
- Total: all.PageInfo.BiliUser.NumResults,
- Pages: all.PageInfo.BiliUser.Pages,
- Type: 2,
- }
- nis = append(nis, nav)
- }
- }
- // movie
- if !newPGC && all.PageInfo.Film != nil {
- var nav = &search.NavInfo{
- Name: movie,
- Total: all.PageInfo.Film.NumResults,
- Pages: all.PageInfo.Film.Pages,
- Type: 3,
- }
- if all.PageInfo.Movie != nil && all.PageInfo.Movie.NumResults > s.movieNum {
- nav.Show = s.movieShowMore
- } else {
- nav.Show = _showHide
- }
- nis = append(nis, nav)
- }
- // media movie
- if newPGC && all.PageInfo.MediaFt != nil {
- var nav = &search.NavInfo{
- Name: movie,
- Total: all.PageInfo.MediaFt.NumResults,
- Pages: all.PageInfo.MediaFt.Pages,
- Type: 8,
- }
- if all.PageInfo.MediaFt.NumResults > s.movieNum {
- nav.Show = s.movieShowMore
- } else {
- nav.Show = _showHide
- }
- nis = append(nis, nav)
- }
- if model.IsOverseas(plat) {
- // live room
- if all.PageInfo.LiveRoom != nil {
- var nav = &search.NavInfo{
- Name: liveroom,
- Total: all.PageInfo.LiveRoom.NumResults,
- Pages: all.PageInfo.LiveRoom.Pages,
- Type: 4,
- }
- nis = append(nis, nav)
- }
- if all.PageInfo.LiveUser != nil {
- var nav = &search.NavInfo{
- Name: liveuser,
- Total: all.PageInfo.LiveUser.NumResults,
- Pages: all.PageInfo.LiveUser.Pages,
- Type: 5,
- }
- nis = append(nis, nav)
- }
- } else {
- if all.PageInfo.Article != nil {
- if (model.IsIPhone(plat) && build > _oldIOS) || (model.IsAndroid(plat) && build > _oldAndroidArticle) || model.IsIPhoneB(plat) {
- var nav = &search.NavInfo{
- Name: article,
- Total: all.PageInfo.Article.NumResults,
- Pages: all.PageInfo.Article.Pages,
- Type: 6,
- }
- nis = append(nis, nav)
- }
- }
- }
- return
- }
- // RecommendNoResult search when no result
- func (s *Service) RecommendNoResult(c context.Context, platform, mobiApp, device, buvid, keyword string, build, pn, ps int, mid int64) (res *search.NoResultRcndResult, err error) {
- if res, err = s.srchDao.RecommendNoResult(c, platform, mobiApp, device, buvid, keyword, build, pn, ps, mid); err != nil {
- log.Error("%+v", err)
- }
- return
- }
- // Recommend search recommend
- func (s *Service) Recommend(c context.Context, mid int64, build, from, show int, buvid, platform, mobiApp, device string) (res *search.RecommendResult, err error) {
- if res, err = s.srchDao.Recommend(c, mid, build, from, show, buvid, platform, mobiApp, device); err != nil {
- log.Error("%+v", err)
- }
- return
- }
- // DefaultWords search for default words
- func (s *Service) DefaultWords(c context.Context, mid int64, build, from int, buvid, platform, mobiApp, device string) (res *search.DefaultWords, err error) {
- if res, err = s.srchDao.DefaultWords(c, mid, build, from, buvid, platform, mobiApp, device); err != nil {
- log.Error("%+v", err)
- }
- return
- }
- // Resource for rsource
- func (s *Service) Resource(c context.Context, mobiApp, device, network, buvid, adExtra string, build int, plat int8, mid int64) (res []*banner.Banner, err error) {
- var (
- bnsm map[int][]*resmdl.Banner
- resID int
- )
- if model.IsAndroid(plat) {
- resID = AndroidSearchResourceID
- } else if model.IsIPhone(plat) {
- resID = IPhoneSearchResourceID
- } else if model.IsIPad(plat) {
- resID = IPadSearchResourceID
- }
- if bnsm, err = s.resDao.Banner(c, mobiApp, device, network, "", buvid, adExtra, strconv.Itoa(resID), build, plat, mid); err != nil {
- return
- }
- // only one position
- for _, rb := range bnsm[resID] {
- b := &banner.Banner{}
- b.ChangeBanner(rb)
- res = append(res, b)
- break
- }
- return
- }
- // RecommendPre search at pre-page.
- func (s *Service) RecommendPre(c context.Context, platform, mobiApp, device, buvid string, build, ps int, mid int64) (res *search.RecommendPreResult, err error) {
- if res, err = s.srchDao.RecommendPre(c, platform, mobiApp, device, buvid, build, ps, mid); err != nil {
- log.Error("%+v", err)
- }
- return
- }
- // SearchEpisodes search PGC episodes
- func (s *Service) SearchEpisodes(c context.Context, mid, ssID int64) (res []*search.Item, err error) {
- var (
- seasonIDs []int64
- bangumis map[string]*bangumi.Card
- )
- seasonIDs = []int64{ssID}
- if bangumis, err = s.bangumiDao.Card(c, mid, seasonIDs); err != nil {
- log.Error("%+v", err)
- return
- }
- if bangumi, ok := bangumis[strconv.FormatInt(ssID, 10)]; ok {
- for _, v := range bangumi.Episodes {
- tmp := &search.Item{
- Param: strconv.Itoa(int(v.ID)),
- Index: v.Index,
- Badges: v.Badges,
- }
- tmp.URI = model.FillURI(model.GotoEP, tmp.Param, nil)
- res = append(res, tmp)
- }
- }
- return
- }
|