123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- package service
- import (
- "context"
- "strconv"
- "strings"
- "go-common/app/interface/openplatform/article/model"
- "go-common/library/log"
- )
- var (
- _slideCount = 20
- _left = 0
- _right = 1
- )
- // var _slideRecommends = 2
- // ViewList .
- func (s *Service) ViewList(c context.Context, aid int64, buvid string, from string, ip string, build int, plat int8, mid int64) (pre int64, next int64) {
- var (
- cid int64
- res *model.Article
- err error
- arts = &model.ArticleViewList{From: from, Buvid: buvid, Plat: plat, Build: build, Mid: mid}
- )
- if res, err = s.Article(c, aid); err != nil {
- res = nil
- return
- }
- if res == nil {
- res = nil
- return
- }
- if strings.Contains(from, "_") {
- fs := strings.Split(from, "_")
- if len(fs) < 2 {
- return
- }
- cid, _ = strconv.ParseInt(fs[1], 10, 64)
- switch fs[0] {
- case "category":
- //分区 天马
- if cid == 0 {
- arts.From = "recommend"
- pre, next = s.listFromRecommends(c, aid, arts)
- // arts.From = "skyhorse"
- // pre, next = s.listFromSkyHorseEx(c, aid, cid, arts, int64(res.PublishTime), res.Author.Mid)
- } else {
- arts.From = "default"
- pre, next = s.listByAuthor(c, aid, res.Author.Mid, int64(res.PublishTime), arts)
- }
- case "rank":
- //排行榜
- pre, next = s.listFromRank(c, aid, cid, arts, ip)
- case "readlist":
- //文集
- pre, next = s.listFromReadList(c, aid, arts)
- default:
- //default
- arts.From = "default"
- pre, next = s.listByAuthor(c, aid, res.Author.Mid, int64(res.PublishTime), arts)
- }
- } else {
- switch from {
- // case "mainCard":
- // //天马
- // arts.From = "skyhorse"
- // pre, next = s.listFromSkyHorseEx(c, aid, 0, arts, int64(res.PublishTime), res.Author.Mid)
- case "favorite":
- // TODO
- pre, next = s.validFavsList(c, aid, arts, true)
- case "records":
- // TODO
- // pre, next = 0, 0
- // pre, next = s.historyCursor(c, aid, arts, true)
- case "readlist":
- //文集
- pre, next = s.listFromReadList(c, aid, arts)
- case "articleSlide":
- //滑动
- pre, next, arts = s.listFromCache(c, aid, arts.Buvid)
- default:
- //作者其他的文章
- arts.From = "default"
- pre, next = s.listByAuthor(c, aid, res.Author.Mid, int64(res.PublishTime), arts)
- }
- }
- s.dao.AddCacheListArtsId(c, buvid, arts)
- return
- }
- // func (s *Service) listFromSkyHorseEx(c context.Context, aid int64, cid int64, arts *model.ArticleViewList, pt int64, authorMid int64) (pre int64, next int64) {
- // pre, next = s.listFromSkyHorse(c, aid, cid, arts)
- // if pre == 0 && next == 0 {
- // arts.From = "default"
- // pre, next = s.listByAuthor(c, aid, authorMid, pt, arts)
- // }
- // return
- // }
- func (s *Service) listFromCache(c context.Context, aid int64, buvid string) (pre int64, next int64, arts *model.ArticleViewList) {
- var (
- res *model.Article
- err error
- position = -1
- )
- if arts, err = s.dao.CacheListArtsId(c, buvid); err != nil {
- log.Error("s.dao.CacheListArtsId, error(%+v)", err)
- return
- }
- if arts == nil || arts.Aids == nil {
- return
- }
- for i, id := range arts.Aids {
- if id == aid {
- position = i
- break
- }
- }
- if position == -1 {
- return
- }
- switch arts.From {
- case "recommend":
- if position == 0 {
- if len(arts.Aids) > 1 {
- next = arts.Aids[1]
- }
- pre = s.newRecommend(c, arts, _left)
- // pre = s.newSkyHorse(c, arts, _left)
- arts.Position = position
- return
- }
- if position == len(arts.Aids)-1 {
- if len(arts.Aids) > 1 {
- pre = arts.Aids[len(arts.Aids)-2]
- }
- next = s.newRecommend(c, arts, _right)
- // next = s.newSkyHorse(c, arts, _right)
- arts.Position = position
- return
- }
- case "default":
- if position == 0 || position == len(arts.Aids)-1 {
- if res, err = s.Article(c, aid); err != nil || res == nil {
- return
- }
- pre, next = s.listByAuthor(c, aid, res.Author.Mid, int64(res.PublishTime), arts)
- arts.Position = position
- return
- }
- next = arts.Aids[position-1]
- pre = arts.Aids[position+1]
- return
- case "records":
- return
- // if position == len(arts.Aids)-1 {
- // if position > 0 {
- // pre = arts.Aids[position-1]
- // }
- // _, next = s.historyCursor(c, aid, arts, false)
- // return
- // }
- case "favorite":
- if position == len(arts.Aids)-1 {
- if position > 0 {
- pre = arts.Aids[position-1]
- }
- _, next = s.validFavsList(c, aid, arts, false)
- return
- }
- }
- if position > 0 {
- pre = arts.Aids[position-1]
- }
- if position < len(arts.Aids)-1 {
- next = arts.Aids[position+1]
- }
- return
- }
- func (s *Service) listFromReadList(c context.Context, aid int64, arts *model.ArticleViewList) (pre int64, next int64) {
- var (
- listID int64
- list *model.List
- artsMetas []*model.ListArtMeta
- ok bool
- )
- lists, err := s.dao.ArtsList(c, []int64{aid})
- if err != nil {
- log.Error("s.dao.ArtsList, error(%+v)", err)
- return
- }
- if list, ok = lists[aid]; !ok {
- return
- }
- listID = list.ID
- if artsMetas, err = s.dao.ListArts(c, listID); err != nil {
- log.Error("s.dao.ListArts, error(%+v)", err)
- return
- }
- if artsMetas == nil {
- return
- }
- for i, art := range artsMetas {
- if art.ID == aid {
- arts.Position = i
- }
- arts.Aids = append(arts.Aids, art.ID)
- }
- if arts.Position > 0 {
- pre = artsMetas[arts.Position-1].ID
- }
- if arts.Position < len(artsMetas)-1 {
- next = artsMetas[arts.Position+1].ID
- }
- return
- }
- func (s *Service) listByAuthor(c context.Context, aid int64, mid int64, pt int64, arts *model.ArticleViewList) (pre int64, next int64) {
- var (
- beforeAids, afterAids, tmpAids []int64
- aidTimes [][2]int64
- exist bool
- j int
- err error
- metas map[int64]*model.Meta
- aids []int64
- addCache = true
- position = -1
- )
- if exist, err = s.dao.ExpireUpperCache(c, mid); err != nil {
- addCache = false
- err = nil
- } else if exist {
- if beforeAids, afterAids, err = s.dao.MoreArtsCaches(c, mid, int64(pt), _slideCount); err != nil {
- addCache = false
- exist = false
- }
- if len(beforeAids)+len(afterAids) == 0 {
- return
- }
- for i := len(beforeAids) - 1; i >= 0; i-- {
- tmpAids = append(tmpAids, beforeAids[i])
- }
- tmpAids = append(tmpAids, aid)
- tmpAids = append(tmpAids, afterAids...)
- } else {
- if aidTimes, err = s.dao.UpperPassed(c, mid); err != nil {
- log.Error("s.dao.UpperPassed, error(%+v)", err)
- return
- }
- if addCache {
- cache.Save(func() {
- s.dao.AddUpperCaches(context.TODO(), map[int64][][2]int64{mid: aidTimes})
- })
- }
- for i := len(aidTimes) - 1; i >= 0; i-- {
- aidTime := aidTimes[i]
- tmpAids = append(tmpAids, aidTime[0])
- }
- }
- if metas, err = s.ArticleMetas(c, tmpAids); err != nil {
- log.Error("s.ArticleMetas, error(%+v)", err)
- return
- }
- //过滤禁止显示的稿件
- filterNoDistributeArtsMap(metas)
- if len(metas) == 0 {
- return
- }
- for _, id := range tmpAids {
- if _, ok := metas[id]; !ok {
- continue
- }
- if id == aid {
- position = j
- }
- j++
- aids = append(aids, id)
- }
- if position == -1 {
- return
- }
- if position > 0 {
- next = aids[position-1]
- }
- if position < len(aids)-1 {
- pre = aids[position+1]
- }
- arts.Position = position
- arts.Aids = aids
- return
- }
- func (s *Service) listFromRank(c context.Context, aid int64, cid int64, arts *model.ArticleViewList, ip string) (pre int64, next int64) {
- var (
- exist bool
- err error
- aids []int64
- rank model.RankResp
- addCache = true
- position = -1
- )
- s.dao.DelCacheListArtsId(c, arts.Buvid)
- if !s.ranksMap[cid] {
- return
- }
- if exist, err = s.dao.ExpireRankCache(c, cid); err != nil {
- addCache = false
- err = nil
- }
- if exist {
- if rank, err = s.dao.RankCache(c, cid); err != nil {
- exist = false
- err = nil
- addCache = false
- }
- } else {
- if rank, err = s.dao.Rank(c, cid, ip); err != nil {
- if rank, err = s.dao.RankCache(c, cid); err != nil {
- log.Error("s.dao.RankCache, error(%+v)", err)
- return
- }
- } else {
- if addCache && len(rank.List) > 0 {
- cache.Save(func() {
- s.dao.AddRankCache(context.TODO(), cid, rank)
- })
- }
- }
- }
- if len(rank.List) == 0 {
- return
- }
- for i, a := range rank.List {
- aids = append(aids, a.Aid)
- if a.Aid == aid {
- position = i
- }
- }
- if position == -1 {
- return
- }
- arts.Position = position
- arts.Aids = aids
- if position > 0 {
- pre = aids[position-1]
- }
- if position < len(aids)-1 {
- next = aids[position+1]
- }
- return
- }
- // func (s *Service) listFromSkyHorse(c context.Context, aid int64, cid int64, arts *model.ArticleViewList) (pre int64, next int64) {
- // var (
- // beforeAids, afterAids, tmpAids, aids []int64
- // err error
- // position = -1
- // half = _slideRecommends / 2
- // )
- // if tmpAids, err = s.filterAidsFromSkyHorse(c, aid, arts, _slideRecommends); err != nil || len(tmpAids) == 0 {
- // return
- // }
- // if len(tmpAids) < half {
- // half = len(tmpAids) / 2
- // }
- // beforeAids = make([]int64, half)
- // afterAids = make([]int64, len(tmpAids)-half)
- // copy(beforeAids, tmpAids[:half])
- // copy(afterAids, tmpAids[half:])
- // position = half
- // aids = append([]int64{}, beforeAids...)
- // aids = append(aids, aid)
- // aids = append(aids, afterAids...)
- // arts.Position = position
- // arts.Aids = aids
- // if len(beforeAids) > 0 {
- // pre = beforeAids[len(beforeAids)-1]
- // }
- // if len(afterAids) > 0 {
- // next = afterAids[0]
- // }
- // return
- // }
- // func (s *Service) newSkyHorse(c context.Context, arts *model.ArticleViewList, side int) (aid int64) {
- // var (
- // aids []int64
- // err error
- // )
- // if aids, err = s.filterAidsFromSkyHorse(c, arts.Aids[arts.Position], arts, _slideRecommends/2); err != nil || len(aids) == 0 {
- // return
- // }
- // aids = uniqIDs(aids, arts.Aids)
- // if len(aids) == 0 {
- // return
- // }
- // if side == _left {
- // aid = aids[len(aids)-1]
- // arts.Aids = append(aids, arts.Aids...)
- // arts.Position += len(aids)
- // } else {
- // aid = aids[0]
- // arts.Aids = append(arts.Aids, aids...)
- // }
- // return
- // }
- // func (s *Service) filterAidsFromSkyHorse(c context.Context, aid int64, arts *model.ArticleViewList, size int) (aids []int64, err error) {
- // var (
- // tmpIds []int64
- // sky *model.SkyHorseResp
- // metas map[int64]*model.Meta
- // )
- // if sky, err = s.dao.SkyHorse(c, arts.Mid, arts.Build, arts.Buvid, arts.Plat, size); err != nil {
- // return
- // }
- // if len(sky.Data) == 0 {
- // return
- // }
- // for _, item := range sky.Data {
- // tmpIds = append(tmpIds, item.ID)
- // }
- // if metas, err = s.ArticleMetas(c, tmpIds); err != nil {
- // log.Error("s.ArticleMetas, error(%+v)", err)
- // return
- // }
- // //过滤禁止显示的稿件
- // filterNoDistributeArtsMap(metas)
- // filterNoRegionArts(metas)
- // if len(metas) == 0 {
- // return
- // }
- // for _, meta := range metas {
- // if meta.ID == aid {
- // continue
- // }
- // aids = append(aids, meta.ID)
- // }
- // return
- // }
- func (s *Service) validFavsList(c context.Context, aid int64, arts *model.ArticleViewList, ok bool) (pre int64, next int64) {
- arts.Position++
- var (
- favs []*model.Favorite
- err error
- page = &model.Page{Total: arts.Position*_slideCount + 1}
- )
- for ok && page.Total > arts.Position*_slideCount {
- if favs, page, err = s.Favs(c, arts.Mid, 0, arts.Position, _slideCount, ""); err != nil {
- return
- }
- for _, fav := range favs {
- if !fav.Valid {
- continue
- }
- arts.Aids = append(arts.Aids, fav.ID)
- }
- for i, id := range arts.Aids {
- if id != aid {
- continue
- }
- if i > 0 {
- pre = arts.Aids[i-1]
- }
- if i < len(arts.Aids)-1 {
- next = arts.Aids[i+1]
- ok = false
- }
- }
- arts.Position++
- }
- if next > 0 {
- return
- }
- ok = true
- for ok && page.Total > arts.Position*_slideCount {
- if favs, page, err = s.Favs(c, arts.Mid, 0, arts.Position, _slideCount, ""); err != nil {
- return
- }
- for _, fav := range favs {
- if !fav.Valid {
- continue
- }
- if next == 0 {
- next = fav.ID
- }
- ok = false
- arts.Aids = append(arts.Aids, fav.ID)
- }
- arts.Position++
- }
- return
- }
- // func (s *Service) historyCursor(c context.Context, aid int64, arts *model.ArticleViewList, ok bool) (pre int64, next int64) {
- // var (
- // res []*history.Resource
- // err error
- // viewAt = int64(arts.Position)
- // aids []int64
- // )
- // for ok {
- // arg := &history.ArgCursor{Mid: arts.Mid, Businesses: []string{"article", "article-list"}, Ps: _slideCount, ViewAt: viewAt}
- // if res, err = s.hisRPC.HistoryCursor(c, arg); err != nil || len(res) < 2 {
- // return
- // }
- // for _, r := range res {
- // viewAt = r.Unix
- // id := r.Oid
- // if r.TP == history.TypeCorpus {
- // id = r.Cid
- // }
- // aids = append(aids, id)
- // }
- // for i, id := range aids {
- // if id != aid {
- // continue
- // }
- // ok = false
- // if i > 0 {
- // pre = aids[i-1]
- // }
- // if i < len(aids)-1 {
- // next = aids[i+1]
- // }
- // }
- // arts.Aids = append(arts.Aids, aids...)
- // arts.Position = int(viewAt)
- // }
- // if next > 0 {
- // return
- // }
- // arg := &history.ArgCursor{Mid: arts.Mid, Businesses: []string{"article", "article-list"}, Ps: _slideCount, ViewAt: viewAt}
- // if res, err = s.hisRPC.HistoryCursor(c, arg); err != nil || len(res) == 0 {
- // return
- // }
- // for _, r := range res {
- // viewAt = r.Unix
- // id := r.Oid
- // if r.TP == history.TypeCorpus {
- // id = r.Cid
- // }
- // if next == 0 {
- // next = id
- // }
- // arts.Aids = append(arts.Aids, id)
- // }
- // arts.Position = int(viewAt)
- // return
- // }
- func (s *Service) listFromRecommends(c context.Context, aid int64, arts *model.ArticleViewList) (pre int64, next int64) {
- recommends := s.genRecommendArtFromPool(s.RecommendsMap[_recommendCategory], _slideCount)
- tmpAids, _ := s.dealRecommends(recommends)
- var aids []int64
- for _, id := range tmpAids {
- if id != aid {
- aids = append(aids, id)
- }
- }
- if len(aids) == 0 {
- return
- }
- if len(aids) == 1 {
- next = aids[0]
- arts.Aids = append([]int64{aid}, aids[0])
- return
- }
- half := len(aids) / 2
- beforeAids := make([]int64, half)
- afterAids := make([]int64, len(aids)-half)
- copy(beforeAids, aids[:half])
- copy(afterAids, aids[half:])
- aids = append([]int64{}, beforeAids...)
- aids = append(aids, aid)
- aids = append(aids, afterAids...)
- arts.Position = half
- arts.Aids = aids
- pre = arts.Aids[half-1]
- next = arts.Aids[half+1]
- return
- }
- func (s *Service) newRecommend(c context.Context, arts *model.ArticleViewList, side int) (res int64) {
- var (
- m = make(map[int64]bool)
- nids []int64
- )
- recommends := s.genRecommendArtFromPool(s.RecommendsMap[_recommendCategory], _slideCount)
- aids, _ := s.dealRecommends(recommends)
- if len(aids) == 0 {
- return
- }
- for _, aid := range arts.Aids {
- m[aid] = true
- }
- for _, aid := range aids {
- if !m[aid] {
- nids = append(nids, aid)
- }
- }
- if len(nids) == 0 {
- return
- }
- if side == _left {
- res = nids[len(nids)-1]
- arts.Aids = append(nids, arts.Aids...)
- }
- if side == _right {
- res = nids[0]
- arts.Aids = append(arts.Aids, nids...)
- }
- return
- }
|