123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- package service
- import (
- "context"
- "sort"
- "go-common/app/interface/openplatform/article/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- )
- var (
- _blankList = &model.List{ID: -1}
- _blankArtList = int64(-1)
- _blankListArts = []*model.ListArtMeta{&model.ListArtMeta{ID: -1}}
- )
- func (s *Service) rawListArticles(c context.Context, listID int64) (res []*model.ListArtMeta, err error) {
- if listID <= 0 {
- return
- }
- arts, err := s.dao.CreativeListArticles(c, listID)
- if err != nil {
- return
- }
- var ids []int64
- for _, art := range arts {
- ids = append(ids, art.ID)
- }
- metas, err := s.dao.CreativeArticles(c, ids)
- if err != nil {
- return
- }
- for _, id := range ids {
- if metas[id] != nil {
- res = append(res, metas[id])
- }
- }
- return
- }
- // List .
- func (s *Service) List(c context.Context, id int64) (res *model.List, err error) {
- res, err = s.dao.List(c, id)
- res.FillDefaultImage(s.c.Article.ListDefaultImage)
- return
- }
- // ListArticles get list passed articles
- func (s *Service) ListArticles(c context.Context, id, mid int64) (res *model.ListArticles, err error) {
- if id <= 0 {
- return
- }
- res = &model.ListArticles{}
- res.List, err = s.List(c, id)
- if err != nil {
- return
- }
- if res.List == nil {
- err = ecode.NothingFound
- return
- }
- var lastID int64
- group := &errgroup.Group{}
- group.Go(func() (err error) {
- arts, err := s.dao.ListArts(c, id)
- if err != nil {
- return
- }
- for _, a := range arts {
- if a.IsNormal() {
- res.Articles = append(res.Articles, a)
- }
- }
- return
- })
- group.Go(func() (err error) {
- res.Author, err = s.author(c, res.List.Mid)
- return
- })
- group.Go(func() (err error) {
- res.List.Read, err = s.dao.CacheListReadCount(c, id)
- return
- })
- group.Go(func() (err error) {
- if mid > 0 {
- res.Attention, _ = s.isAttention(c, mid, res.List.Mid)
- }
- return
- })
- group.Go(func() (err error) {
- if mid == 0 {
- return
- }
- lastID, _ = s.historyPosition(c, mid, res.List.ID)
- return
- })
- err = group.Wait()
- if res.Articles == nil {
- res.Articles = []*model.ListArtMeta{}
- }
- res.List.ArticlesCount = int64(len(res.Articles))
- res.Last.Strong()
- if lastID == 0 {
- return
- }
- for _, a := range res.Articles {
- if a.ID == lastID {
- res.Last = *a
- break
- }
- }
- return
- }
- // WebListArticles .
- func (s *Service) WebListArticles(c context.Context, id, mid int64) (res *model.WebListArticles, err error) {
- arts, err := s.ListArticles(c, id, mid)
- res = &model.WebListArticles{Attention: arts.Attention, Author: arts.Author, List: arts.List, Last: arts.Last}
- var ids []int64
- for _, a := range arts.Articles {
- ids = append(ids, a.ID)
- }
- var stats map[int64]*model.Stats
- var states map[int64]int8
- group, ctx := errgroup.WithContext(c)
- group.Go(func() (err error) {
- if len(ids) == 0 {
- return
- }
- stats, _ = s.stats(ctx, ids)
- return
- })
- group.Go(func() (err error) {
- if mid == 0 || len(ids) == 0 {
- return
- }
- states, _ = s.HadLikesByMid(ctx, mid, ids)
- return
- })
- group.Wait()
- for _, a := range arts.Articles {
- art := &model.FullListArtMeta{ListArtMeta: a}
- if s.categoriesMap[art.Category.ID] != nil {
- art.Category = s.categoriesMap[art.Category.ID]
- art.Categories = s.categoryParents[art.Category.ID]
- }
- s := stats[art.ID]
- if s != nil {
- art.Stats = *s
- }
- if states != nil {
- art.LikeState = states[art.ID]
- }
- res.Articles = append(res.Articles, art)
- }
- return
- }
- // RebuildListCache rebuild list cache
- func (s *Service) rebuildArticleListCache(c context.Context, aid int64) (listID int64, err error) {
- s.deleteArtsListCache(c, aid)
- lists, _ := s.dao.RawArtsListID(c, []int64{aid})
- listID = lists[aid]
- if listID > 0 {
- err = s.dao.SetArticleListCache(c, listID, []*model.ListArtMeta{&model.ListArtMeta{ID: aid}})
- }
- return
- }
- // RebuildListCache rebuild list cache
- func (s *Service) RebuildListCache(c context.Context, id int64) (err error) {
- err = s.updateListCache(c, id)
- if err != nil {
- return
- }
- arts, err := s.dao.RawListArts(c, id)
- if err != nil {
- return
- }
- if err = s.updateListArtsCache(c, id, arts); err != nil {
- return
- }
- if err = s.updateArtListCache(c, id, arts); err != nil {
- return
- }
- list, err := s.dao.RawList(c, id)
- if err != nil {
- return
- }
- if list == nil {
- err = ecode.NothingFound
- return
- }
- if err = s.dao.RebuildUpListsCache(c, list.Mid); err != nil {
- return
- }
- if err = s.dao.RebuildListReadCountCache(c, id); err != nil {
- return
- }
- return
- }
- func (s *Service) updateListCache(c context.Context, id int64) (err error) {
- list, err := s.dao.RawList(c, id)
- if err != nil {
- return
- }
- err = s.dao.AddCacheList(c, id, list)
- return
- }
- func (s *Service) updateListArtsCache(c context.Context, id int64, arts []*model.ListArtMeta) (err error) {
- if arts == nil {
- arts, err = s.dao.RawListArts(c, id)
- if err != nil {
- return
- }
- }
- if len(arts) == 0 {
- err = s.deleteListArtsCache(c, id)
- return
- }
- err = s.dao.AddCacheListArts(c, id, arts)
- return
- }
- func (s *Service) updateArtListCache(c context.Context, id int64, arts []*model.ListArtMeta) (err error) {
- if arts == nil {
- arts, err = s.dao.RawListArts(c, id)
- if err != nil {
- return
- }
- }
- err = s.dao.SetArticleListCache(c, id, arts)
- return
- }
- func (s *Service) deleteListArtsCache(c context.Context, listID int64) (err error) {
- err = s.dao.AddCacheListArts(c, listID, _blankListArts)
- return
- }
- func (s *Service) deleteListCache(c context.Context, listID int64) (err error) {
- l := map[int64]*model.List{listID: _blankList}
- err = s.dao.AddCacheLists(c, l)
- return
- }
- func (s *Service) deleteArtsListCache(c context.Context, ids ...int64) (err error) {
- if len(ids) == 0 {
- return
- }
- m := make(map[int64]int64)
- for _, id := range ids {
- m[id] = _blankArtList
- }
- if err = s.dao.AddCacheArtsListID(c, m); err != nil {
- log.Errorv(c, log.KV("log", "deleteArtsListCache"), log.KV("err", err), log.KV("arg", ids))
- }
- return
- }
- // ListInfo list info
- func (s *Service) ListInfo(c context.Context, aid int64) (res *model.ListInfo, err error) {
- lists, err := s.dao.ArtsList(c, []int64{aid})
- if err != nil {
- return
- }
- list := lists[aid]
- if list == nil {
- err = ecode.NothingFound
- return
- }
- res = &model.ListInfo{List: list}
- var articles []*model.ListArtMeta
- arts, err := s.dao.ListArts(c, list.ID)
- if err != nil {
- return
- }
- for _, a := range arts {
- if a.IsNormal() {
- articles = append(articles, a)
- }
- }
- res.Total = len(articles)
- for i, l := range articles {
- if l.ID == aid {
- res.Now = i
- if i-1 >= 0 {
- res.Last = articles[i-1]
- }
- if (i + 1) < len(articles) {
- res.Next = articles[i+1]
- }
- break
- }
- }
- res.List.FillDefaultImage(s.c.Article.ListDefaultImage)
- res.List.Read, err = s.dao.CacheListReadCount(c, list.ID)
- return
- }
- // Lists .
- func (s *Service) Lists(c context.Context, keys []int64) (res map[int64]*model.List, err error) {
- res, err = s.dao.Lists(c, keys)
- for _, l := range res {
- l.FillDefaultImage(s.c.Article.ListDefaultImage)
- }
- return
- }
- // UpLists .
- func (s *Service) UpLists(c context.Context, mid int64, sortType int8) (res model.UpLists, err error) {
- lists, err := s.dao.UpLists(c, mid)
- if err != nil {
- return
- }
- lmap, err := s.Lists(c, lists)
- if err != nil {
- return
- }
- arts, err := s.dao.ListsArts(c, lists)
- if err != nil {
- return
- }
- counts, err := s.dao.CacheListsReadCount(c, lists)
- for _, l := range lists {
- if lmap[l] != nil {
- list := lmap[l]
- if arts[l] != nil {
- list.ArticlesCount = int64(len(arts[l]))
- }
- list.Read = counts[l]
- res.Lists = append(res.Lists, list)
- }
- }
- if sortType == model.ListSortView {
- sort.Slice(res.Lists, func(i, j int) bool { return res.Lists[i].Read > res.Lists[j].Read })
- } else {
- sort.Slice(res.Lists, func(i, j int) bool { return res.Lists[i].PublishTime > res.Lists[j].PublishTime })
- }
- res.Total = len(res.Lists)
- return
- }
- // rebuildAllListReadCount .
- func (s *Service) rebuildAllListReadCount(c context.Context) error {
- i := 0
- for {
- lists, err := s.dao.RawAllListsEx(c, i, 1000)
- if err != nil {
- log.Errorv(c, log.KV("RebuildAllReadCount err", err))
- return err
- }
- if lists == nil {
- return nil
- }
- for _, list := range lists {
- err = s.dao.RebuildListReadCountCache(c, list.ID)
- if err != nil {
- log.Errorv(c, log.KV("RebuildAllReadCount err", err), log.KV("id", list.ID))
- } else {
- log.Infov(c, log.KV("RebuildAllReadCount", list.ID))
- }
- }
- i += 1000
- }
- }
- // RebuildAllListReadCount .
- func (s *Service) RebuildAllListReadCount(c context.Context) {
- go s.rebuildAllListReadCount(context.TODO())
- }
- // UpArtMetasAndLists .
- func (s *Service) UpArtMetasAndLists(c context.Context, mid int64, pn int, ps int, sortType int) (res model.UpArtMetasLists, err error) {
- metas, err := s.UpArticleMetas(c, mid, pn, ps, sortType)
- if err != nil {
- return
- }
- res.UpArtMetas = metas
- res.UpLists, err = s.UpLists(c, mid, model.ListSortPtime)
- if res.UpArtMetas == nil {
- res.UpArtMetas = &model.UpArtMetas{}
- }
- if res.UpArtMetas.Articles == nil {
- res.UpArtMetas.Articles = []*model.Meta{}
- }
- if res.UpLists.Lists == nil {
- res.UpLists.Lists = []*model.List{}
- }
- return
- }
|