123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- package service
- import (
- "context"
- "sort"
- "time"
- "go-common/app/interface/main/history/model"
- arcmdl "go-common/app/service/main/archive/model/archive"
- "go-common/library/ecode"
- "go-common/library/log"
- )
- const maxToView = 100
- var (
- _empToView = []*model.ToView{}
- _empArcToView = []*model.ArcToView{}
- _empWebArcToView = []*model.WebArcToView{}
- )
- // AddToView add the user a toview item.
- // +wd:ignore
- func (s *Service) AddToView(c context.Context, mid, aid int64, ip string) (err error) {
- var (
- ok bool
- count int
- arc *arcmdl.View3
- now = time.Now().Unix()
- )
- arcAid := &arcmdl.ArgAid2{Aid: aid}
- if arc, err = s.arcRPC.View3(c, arcAid); err != nil {
- return
- }
- if arc == nil {
- return
- }
- if arc.Rights.UGCPay == 1 {
- return ecode.ToViewPayUGC
- }
- if ok, err = s.toviewDao.Expire(c, mid); err != nil {
- return
- }
- if ok {
- if count, err = s.toviewDao.CntCache(c, mid); err != nil {
- return
- }
- } else {
- if _, count, err = s.toView(c, mid, 1, maxToView, ip); err != nil {
- return
- }
- }
- if count >= maxToView {
- err = ecode.ToViewOverMax
- return
- }
- if err = s.toviewDao.Add(c, mid, aid, now); err != nil {
- return
- }
- s.toviewCache.Do(c, func(ctx context.Context) {
- if errCache := s.toviewDao.AddCache(ctx, mid, aid, now); errCache != nil {
- log.Warn("s.toviewDao.AddCache(%d,%d,%d) err:%v", mid, aid, now, errCache)
- }
- })
- return
- }
- // AddMultiToView add toview items to user.
- // +wd:ignore
- func (s *Service) AddMultiToView(c context.Context, mid int64, aids []int64, ip string) (err error) {
- var (
- ok bool
- count int
- expectedAids []int64
- arcs map[int64]*arcmdl.View3
- viewMap map[int64]*model.ToView
- views []*model.ToView
- now = time.Now().Unix()
- )
- arcAids := &arcmdl.ArgAids2{Aids: aids}
- if arcs, err = s.arcRPC.Views3(c, arcAids); err != nil {
- return
- } else if len(arcs) == 0 {
- return
- }
- for _, v := range arcs {
- if v.Rights.UGCPay == 1 {
- return ecode.ToViewPayUGC
- }
- }
- if ok, err = s.toviewDao.Expire(c, mid); err != nil {
- return
- }
- if ok {
- if viewMap, err = s.toviewDao.CacheMap(c, mid); err != nil {
- return
- }
- } else {
- var list []*model.ToView
- list, _, err = s.toView(c, mid, 1, maxToView, ip)
- if err != nil {
- return
- }
- viewMap = make(map[int64]*model.ToView)
- for _, v := range list {
- if v == nil {
- continue
- }
- viewMap[v.Aid] = v
- }
- }
- count = len(viewMap)
- if count >= maxToView {
- err = ecode.ToViewOverMax
- return
- }
- expectedLen := maxToView - count
- for _, aid := range aids {
- if _, exist := viewMap[aid]; !exist {
- expectedAids = append(expectedAids, aid)
- expectedLen--
- if expectedLen == 0 {
- break
- }
- }
- }
- if err = s.toviewDao.Adds(c, mid, expectedAids, now); err != nil {
- return
- }
- if ok {
- s.toviewCache.Do(c, func(ctx context.Context) {
- for _, aid := range expectedAids {
- views = append(views, &model.ToView{Aid: aid, Unix: now})
- }
- if errCache := s.toviewDao.AddCacheList(ctx, mid, views); errCache != nil {
- log.Warn("s.toviewDao.AddCacheList(%d,%v) err:%v", mid, views, errCache)
- }
- })
- }
- return
- }
- // RemainingToView add toview items to user.
- // +wd:ignore
- func (s *Service) RemainingToView(c context.Context, mid int64, ip string) (remaining int, err error) {
- var (
- count int
- )
- if _, count, err = s.toView(c, mid, 1, maxToView, ip); err != nil {
- return
- }
- remaining = maxToView - count
- return
- }
- // ClearToView clear the user toview items.
- // +wd:ignore
- func (s *Service) ClearToView(c context.Context, mid int64) (err error) {
- if err = s.toviewDao.ClearCache(c, mid); err != nil {
- return
- }
- s.userActionLog(mid, model.ToviewClear)
- return s.toviewDao.Clear(c, mid)
- }
- // DelToView delete the user to videos.
- // +wd:ignore
- func (s *Service) DelToView(c context.Context, mid int64, aids []int64, viewed bool, ip string) (err error) {
- var (
- delAids []int64
- list []*model.ToView
- rhs, hs map[int64]*model.History
- rs *model.History
- )
- // viewed del all viewed
- if viewed {
- if list, _, err = s.toView(c, mid, 1, maxToView, ip); err != nil {
- return
- }
- for _, l := range list {
- aids = append(aids, l.Aid)
- }
- if len(aids) == 0 {
- return
- }
- if hs, err = s.historyDao.AidsMap(c, mid, aids); err != nil {
- return
- }
- rhs, _ = s.historyDao.CacheMap(c, mid)
- for _, rs = range rhs {
- hs[rs.Aid] = rs
- }
- for k, v := range hs {
- if v.Pro >= 30 || v.Pro == -1 {
- delAids = append(delAids, k)
- }
- }
- if len(delAids) == 0 {
- return
- }
- if err = s.toviewDao.Del(c, mid, delAids); err != nil {
- return
- }
- s.toviewCache.Do(c, func(ctx context.Context) {
- s.toviewDao.DelCaches(ctx, mid, delAids)
- })
- return
- }
- if err = s.toviewDao.Del(c, mid, aids); err != nil {
- return
- }
- s.toviewCache.Do(c, func(ctx context.Context) {
- s.toviewDao.DelCaches(ctx, mid, aids)
- })
- return
- }
- // WebToView get videos of user view history.
- // +wd:ignore
- func (s *Service) WebToView(c context.Context, mid int64, pn, ps int, ip string) (res []*model.WebArcToView, count int, err error) {
- var (
- ok bool
- aids, epids []int64
- avs map[int64]*arcmdl.View3
- views []*model.ToView
- v *model.ToView
- hm map[int64]*model.History
- av *arcmdl.View3
- epban = make(map[int64]*model.Bangumi)
- seasonMap = make(map[int64]*model.BangumiSeason)
- )
- if views, count, err = s.toView(c, mid, pn, ps, ip); err != nil {
- return
- }
- if len(views) == 0 {
- return
- }
- for _, v = range views {
- if v != nil {
- aids = append(aids, v.Aid)
- }
- }
- argAids := &arcmdl.ArgAids2{Aids: aids}
- if avs, err = s.arcRPC.Views3(c, argAids); err != nil {
- log.Error("s.arcRPC.Views3(arcAids:(%v), arcs) error(%v)", aids, err)
- return
- }
- if len(avs) == 0 {
- return
- }
- seasonMap, epids = s.season(c, mid, aids, ip)
- // bangumi info
- if len(epids) > 0 {
- epban = s.bangumi(c, mid, epids)
- }
- if hm, err = s.toViewPro(c, mid, aids); err != nil {
- err = nil
- }
- res = make([]*model.WebArcToView, 0, len(aids))
- for _, v = range views {
- if v == nil {
- count--
- continue
- }
- // NOTE compat android
- if av, ok = avs[v.Aid]; !ok || av == nil {
- count--
- continue
- }
- // NOTE all no pay
- av.Rights.Movie = 0
- at := &model.WebArcToView{View3: av}
- at.AddTime = v.Unix
- if hm[v.Aid] != nil {
- at.Cid = hm[v.Aid].Cid
- at.Progress = hm[v.Aid].Pro
- }
- if season, ok := seasonMap[v.Aid]; ok && season != nil {
- if bangumi, ok := epban[season.Epid]; ok && bangumi != nil {
- at.BangumiInfo = bangumi
- }
- }
- res = append(res, at)
- }
- if len(res) == 0 {
- res = _empWebArcToView
- }
- return
- }
- // ToView get videos of user view history.
- // +wd:ignore
- func (s *Service) ToView(c context.Context, mid int64, pn, ps int, ip string) (res []*model.ArcToView, count int, err error) {
- var (
- ok bool
- aids []int64
- avs map[int64]*arcmdl.View3
- views []*model.ToView
- v *model.ToView
- hm map[int64]*model.History
- av *arcmdl.View3
- )
- res = _empArcToView
- if views, count, err = s.toView(c, mid, pn, ps, ip); err != nil {
- return
- }
- if len(views) == 0 {
- return
- }
- for _, v = range views {
- if v != nil {
- aids = append(aids, v.Aid)
- }
- }
- argAids := &arcmdl.ArgAids2{Aids: aids}
- if avs, err = s.arcRPC.Views3(c, argAids); err != nil {
- log.Error("s.arcRPC.Views3(%v) error(%v)", aids, err)
- return
- }
- if len(avs) == 0 {
- return
- }
- if hm, err = s.toViewPro(c, mid, aids); err != nil {
- err = nil
- }
- res = make([]*model.ArcToView, 0, len(aids))
- for _, v = range views {
- if v == nil {
- count--
- continue
- }
- // NOTE compat android
- if av, ok = avs[v.Aid]; !ok || av.Archive3 == nil {
- count--
- continue
- }
- // NOTE all no pay
- av.Rights.Movie = 0
- at := &model.ArcToView{
- Archive3: av.Archive3,
- Count: len(av.Pages),
- }
- at.AddTime = v.Unix
- // get cid and progress
- if hm[v.Aid] != nil {
- at.Cid = hm[v.Aid].Cid
- at.Progress = hm[v.Aid].Pro
- }
- for n, p := range av.Pages {
- if p.Cid == at.Cid {
- p.Page = int32(n + 1)
- at.Page = p
- break
- }
- }
- res = append(res, at)
- }
- return
- }
- // toView return ToSee of After the paging data.
- func (s *Service) toView(c context.Context, mid int64, pn, ps int, ip string) (res []*model.ToView, count int, err error) {
- var (
- ok bool
- start = (pn - 1) * ps
- end = start + ps - 1
- )
- if ok, err = s.toviewDao.Expire(c, mid); err != nil {
- return
- }
- if ok {
- if end > maxToView {
- end = maxToView
- }
- if res, err = s.toviewDao.Cache(c, mid, start, end); err != nil {
- return
- }
- count, err = s.toviewDao.CntCache(c, mid)
- if count > maxToView {
- count = maxToView
- }
- return
- }
- var views []*model.ToView
- var viewMap = make(map[int64]*model.ToView)
- if viewMap, err = s.toviewDao.MapInfo(c, mid, nil); err != nil {
- return
- }
- if len(viewMap) == 0 {
- res = _empToView
- return
- }
- for _, v := range viewMap {
- views = append(views, v)
- }
- sort.Sort(model.ToViews(views))
- if count = len(views); count > maxToView {
- count = maxToView
- views = views[:count]
- }
- switch {
- case count > start && count > end:
- res = views[start : end+1]
- case count > start && count <= end:
- res = views[start:]
- default:
- res = _empToView
- }
- s.toviewCache.Do(c, func(ctx context.Context) {
- if errCache := s.toviewDao.AddCacheList(ctx, mid, views); errCache != nil {
- log.Warn("s.toviewDao.AddCacheList(%d,%v) err:%v", mid, views, errCache)
- }
- })
- return
- }
- func (s *Service) toViewPro(c context.Context, mid int64, aids []int64) (res map[int64]*model.History, err error) {
- var (
- miss []int64
- hm map[int64]*model.History
- )
- if res, miss, err = s.historyDao.Cache(c, mid, aids); err != nil {
- err = nil
- } else if len(res) == len(aids) {
- return
- }
- if len(res) == 0 {
- res = make(map[int64]*model.History)
- miss = aids
- }
- if hm, err = s.historyDao.AidsMap(c, mid, miss); err != nil {
- err = nil
- }
- for k, v := range hm {
- res[k] = v
- }
- return
- }
- func (s *Service) season(c context.Context, mid int64, aids []int64, ip string) (seasonMap map[int64]*model.BangumiSeason, epids []int64) {
- var (
- n = 50
- seasonM = make(map[int64]*model.BangumiSeason, n)
- )
- seasonMap = make(map[int64]*model.BangumiSeason, n)
- for len(aids) > 0 {
- if n > len(aids) {
- n = len(aids)
- }
- seasonM, _ = s.historyDao.BangumisByAids(c, mid, aids[:n], ip)
- aids = aids[n:]
- for k, v := range seasonM {
- epids = append(epids, v.Epid)
- seasonMap[k] = v
- }
- }
- return
- }
- // ManagerToView manager get mid toview list.
- // +wd:ignore
- func (s *Service) ManagerToView(c context.Context, mid int64, ip string) ([]*model.ToView, error) {
- return s.toviewDao.ListInfo(c, mid, nil)
- }
|