123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- package service
- import (
- "context"
- "fmt"
- "sort"
- "strconv"
- "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"
- "go-common/library/net/metadata"
- )
- var (
- _countLimit = 50
- _emptyVideos = []*model.Video{}
- _emptyHis = []*model.History{}
- _emptyHismap = make(map[int64]*model.History)
- )
- func (s *Service) key(aid int64, typ int8) string {
- if typ < model.TypeArticle {
- return strconv.FormatInt(aid, 10)
- }
- return fmt.Sprintf("%d_%d", aid, typ)
- }
- // AddHistories batch update history.
- // +wd:ignore
- func (s *Service) AddHistories(c context.Context, mid int64, typ int8, ip string, hs []*model.History) (err error) {
- var (
- ok bool
- his, h *model.History
- hm2 map[string]*model.History
- hmc, res map[int64]*model.History
- expire = time.Now().Unix() - 60*60*24*90
- )
- if len(hs) > _countLimit {
- return ecode.TargetNumberLimit
- }
- s.serviceAdds(mid, hs)
- if hm2, err = s.historyDao.Map(c, mid); err != nil {
- return
- }
- if typ < model.TypeArticle {
- if hmc, err = s.historyDao.CacheMap(c, mid); err != nil {
- return err
- }
- }
- res = make(map[int64]*model.History)
- for _, his = range hs {
- if his.Unix < expire {
- continue
- }
- if len(hm2) > 0 {
- if h, ok = hm2[s.key(his.Aid, his.TP)]; ok && his.Unix < h.Unix {
- continue
- }
- }
- if len(hmc) > 0 {
- if h, ok = hmc[his.Aid]; ok && his.Unix < h.Unix {
- continue
- }
- }
- // TODO comment && merge
- res[his.Aid] = his
- }
- if err = s.historyDao.AddMap(c, mid, res); err == nil {
- return
- }
- if typ < model.TypeArticle {
- s.historyDao.AddCacheMap(c, mid, res)
- }
- return nil
- }
- // AddHistory add hisotry progress into hbase.
- func (s *Service) AddHistory(c context.Context, mid, rtime int64, h *model.History) (err error) {
- if h.TP < model.TypeUnknown || h.TP > model.TypeComic {
- err = ecode.RequestErr
- return
- }
- if h.Aid == 0 {
- return ecode.RequestErr
- }
- if h.TP == model.TypeBangumi || h.TP == model.TypeMovie || h.TP == model.TypePGC {
- msg := playPro{
- Type: h.TP,
- SubType: h.STP,
- Mid: mid,
- Sid: h.Sid,
- Epid: h.Epid,
- Cid: h.Cid,
- Progress: h.Pro,
- IP: metadata.String(c, metadata.RemoteIP),
- Ts: h.Unix,
- RealTime: rtime,
- }
- s.addPlayPro(&msg)
- }
- // NOTE if login user to save history
- if mid == 0 {
- return
- }
- return s.addHistory(c, mid, h)
- }
- // Progress get view progress from cache/hbase.
- func (s *Service) Progress(c context.Context, mid int64, aids []int64) (res map[int64]*model.History, err error) {
- if mid == 0 {
- res = _emptyHismap
- return
- }
- if s.migration(mid) {
- res, err = s.servicePosition(c, mid, model.BusinessByTP(model.TypeUGC), aids)
- if err == nil {
- return
- }
- }
- if res, _, err = s.historyDao.Cache(c, mid, aids); err != nil {
- return
- } else if len(res) == 0 {
- res = _emptyHismap
- }
- return
- }
- // Position get view progress from cache/hbase.
- func (s *Service) Position(c context.Context, mid int64, aid int64, typ int8) (res *model.History, err error) {
- if mid == 0 {
- err = ecode.NothingFound
- return
- }
- if s.migration(mid) {
- var hm map[int64]*model.History
- hm, err = s.servicePosition(c, mid, model.BusinessByTP(typ), []int64{aid})
- if err == nil && hm != nil {
- if res = hm[aid]; res == nil {
- err = ecode.NothingFound
- }
- return
- }
- }
- if typ < model.TypeArticle {
- var hm map[int64]*model.History
- hm, _, err = s.historyDao.Cache(c, mid, []int64{aid})
- if err != nil {
- return
- }
- if len(hm) > 0 {
- if h, ok := hm[aid]; ok {
- res = h
- }
- }
- if res == nil {
- err = ecode.NothingFound
- }
- return
- }
- var mhis map[string]*model.History
- mhis, err = s.historyDao.Map(c, mid)
- if err != nil {
- return
- }
- if len(mhis) > 0 {
- key := fmt.Sprintf("%d_%d", aid, typ)
- if h, ok := mhis[key]; ok {
- res = h
- }
- }
- if res == nil {
- err = ecode.NothingFound
- }
- return
- }
- // addHistory add new history into set.
- func (s *Service) addHistory(c context.Context, mid int64, h *model.History) (err error) {
- var cmd int64
- // note: the type is video to increase experience of user .
- if h.TP < model.TypeArticle {
- s.historyDao.PushFirstQueue(c, mid, h.Aid, h.Unix)
- }
- if cmd, err = s.Shadow(c, mid); err != nil {
- return
- }
- if cmd == model.ShadowOn {
- return
- }
- h.Mid = mid
- s.serviceAdd(h)
- // note: the type is video to redis`cache .
- if h.TP >= model.TypeArticle {
- s.addProPub(h)
- if !s.conf.History.Pub {
- err = s.historyDao.Add(c, mid, h)
- }
- return
- }
- // NOTE first view
- if h.Pro < 30 && h.Pro != -1 {
- h.Pro = 0
- }
- // NOTE after 30s
- if err = s.historyDao.AddCache(c, mid, h); err != nil {
- return
- }
- s.addMerge(mid, h.Unix)
- return
- }
- // ClearHistory clear user's historys.
- func (s *Service) ClearHistory(c context.Context, mid int64, tps []int8) (err error) {
- s.serviceClear(mid, tps)
- if len(tps) == 0 {
- s.historyDao.ClearCache(c, mid)
- err = s.historyDao.Clear(c, mid)
- s.userActionLog(mid, model.HistoryClear)
- return
- }
- tpsMap := make(map[int8]bool)
- for _, tp := range tps {
- tpsMap[tp] = true
- }
- var (
- histories map[string]*model.History
- dels []*model.History
- chis map[int64]*model.History
- aids []int64
- )
- if histories, err = s.historyDao.Map(c, mid); err != nil {
- return
- }
- chis, _ = s.historyDao.CacheMap(c, mid)
- for _, v := range chis {
- histories[s.key(v.Aid, v.TP)] = v
- }
- logMap := make(map[int8]struct{})
- for _, h := range histories {
- oldType := h.TP
- h.ConvertType()
- if tpsMap[h.TP] {
- if (h.TP == model.TypeUGC) || (h.TP == model.TypePGC) {
- aids = append(aids, h.Aid)
- }
- h.TP = oldType
- dels = append(dels, h)
- logMap[oldType] = struct{}{}
- }
- }
- if len(dels) == 0 {
- return
- }
- if len(aids) > 0 {
- s.historyDao.DelCache(c, mid, aids)
- }
- if err = s.historyDao.Delete(c, mid, dels); err != nil {
- return
- }
- for k := range logMap {
- s.userActionLog(mid, fmt.Sprintf(model.HistoryClearTyp, model.BusinessByTP(k)))
- }
- return
- }
- // DelHistory delete user's history del archive .
- // +wd:ignore
- func (s *Service) DelHistory(ctx context.Context, mid int64, aids []int64, typ int8) (err error) {
- if err = s.serviceDels(ctx, mid, aids, typ); err != nil {
- return
- }
- if err = s.historyDao.DelAids(ctx, mid, aids); err != nil {
- return
- }
- if typ >= model.TypeArticle {
- return
- }
- return s.historyDao.DelCache(ctx, mid, aids)
- }
- // Videos get videos of user view history.
- // +wd:ignore
- func (s *Service) Videos(c context.Context, mid int64, pn, ps int, typ int8) (res []*model.Video, err error) {
- var (
- arc *arcmdl.View3
- ok bool
- arcs map[int64]*arcmdl.View3
- video *model.Video
- history []*model.History
- his *model.History
- aids, epids []int64
- aidFavs map[int64]bool
- epban map[int64]*model.Bangumi
- )
- res = _emptyVideos
- mOK := s.migration(mid)
- if mOK {
- businesses := []string{model.BusinessByTP(model.TypeUGC), model.BusinessByTP(model.TypePGC)}
- history, epids, err = s.servicePnPsCursor(c, mid, businesses, pn, ps)
- }
- if !mOK || err != nil {
- if history, epids, err = s.histories(c, mid, pn, ps, true); err != nil {
- return
- }
- }
- if len(history) == 0 {
- return
- }
- for _, his = range history {
- aids = append(aids, his.Aid)
- }
- if typ >= model.TypeArticle {
- // TODO Article info .
- return
- }
- // bangumi info
- if len(epids) > 0 {
- epban = s.bangumi(c, mid, epids)
- }
- // archive info
- arcAids := &arcmdl.ArgAids2{Aids: aids}
- if arcs, err = s.arcRPC.Views3(c, arcAids); err != nil {
- return
- } else if len(arcs) == 0 {
- return
- }
- // favorite info
- aidFavs = s.favoriteds(c, mid, aids)
- res = make([]*model.Video, 0, len(aids))
- for _, his = range history {
- if arc, ok = arcs[his.Aid]; !ok || arc.Archive3 == nil {
- continue
- }
- // NOTE all no pay
- arc.Rights.Movie = 0
- video = &model.Video{
- Archive3: arc.Archive3,
- ViewAt: his.Unix,
- DT: his.DT,
- STP: his.STP,
- TP: his.TP,
- Progress: his.Pro,
- Count: len(arc.Pages),
- }
- if aidFavs != nil {
- video.Favorite = aidFavs[his.Aid]
- }
- for n, p := range arc.Pages {
- if p.Cid == his.Cid {
- p.Page = int32(n + 1)
- video.Page = p
- break
- }
- }
- if video.TP == model.TypeBangumi || video.TP == model.TypeMovie || video.TP == model.TypePGC {
- if epban != nil {
- video.BangumiInfo = epban[his.Epid]
- }
- video.Count = 0
- }
- res = append(res, video)
- }
- return
- }
- // AVHistories return the user all av history.
- // +wd:ignore
- func (s *Service) AVHistories(c context.Context, mid int64) (hs []*model.History, err error) {
- if s.migration(mid) {
- businesses := []string{model.BusinessByTP(model.TypeUGC), model.BusinessByTP(model.TypePGC)}
- hs, _, err = s.servicePnPsCursor(c, mid, businesses, 1, s.conf.History.Max)
- if err == nil {
- return
- }
- }
- hs, _, err = s.histories(c, mid, 1, s.conf.History.Max, true)
- return
- }
- // Histories return the user all av history.
- func (s *Service) Histories(c context.Context, mid int64, typ int8, pn, ps int) (res []*model.Resource, err error) {
- var hs []*model.History
- mOK := s.migration(mid)
- if mOK {
- var businesses []string
- if typ > 0 {
- businesses = []string{model.BusinessByTP(typ)}
- }
- hs, _, err = s.servicePnPsCursor(c, mid, businesses, pn, ps)
- }
- if !mOK || err != nil {
- if typ >= model.TypeArticle {
- hs, err = s.platformHistories(c, mid, typ, pn, ps)
- } else {
- hs, _, err = s.histories(c, mid, pn, ps, false)
- }
- }
- if err != nil {
- return
- }
- if len(hs) == 0 {
- return
- }
- for _, h := range hs {
- h.ConvertType()
- r := &model.Resource{
- Mid: h.Mid,
- Oid: h.Aid,
- Sid: h.Sid,
- Epid: h.Epid,
- Cid: h.Cid,
- DT: h.DT,
- Pro: h.Pro,
- Unix: h.Unix,
- TP: h.TP,
- STP: h.STP,
- }
- res = append(res, r)
- }
- return
- }
- // histories get aids of user view history
- func (s *Service) histories(c context.Context, mid int64, pn, ps int, onlyAV bool) (his []*model.History, epids []int64, err error) {
- var (
- size int
- ok bool
- e, h *model.History
- mhis map[string]*model.History
- chis, ehis map[int64]*model.History
- dhis []*model.History
- start = (pn - 1) * ps
- end = start + ps - 1
- total = s.conf.History.Total
- )
- if mhis, err = s.historyDao.Map(c, mid); err != nil {
- err = nil
- mhis = make(map[string]*model.History)
- }
- chis, _ = s.historyDao.CacheMap(c, mid)
- for _, v := range chis {
- mhis[s.key(v.Aid, v.TP)] = v
- }
- if len(mhis) == 0 {
- his = _emptyHis
- return
- }
- ehis = make(map[int64]*model.History, len(mhis))
- for _, h = range mhis {
- if onlyAV && h.TP >= model.TypeArticle {
- continue
- }
- if (h.TP == model.TypeBangumi || h.TP == model.TypeMovie || h.TP == model.TypePGC) && h.Sid != 0 {
- if e, ok = ehis[h.Sid]; !ok || h.Unix > e.Unix {
- ehis[h.Sid] = h
- if e != nil {
- dhis = append(dhis, e)
- }
- }
- } else {
- his = append(his, h)
- }
- }
- for _, h = range ehis {
- if h.Epid != 0 {
- epids = append(epids, h.Epid)
- }
- his = append(his, h)
- }
- sort.Sort(model.Histories(his))
- if size = len(his); size > total {
- dhis = append(dhis, his[total:]...)
- s.delChan.Do(c, func(ctx context.Context) {
- s.historyDao.Delete(ctx, mid, dhis)
- })
- his = his[:total]
- size = total
- }
- switch {
- case size > start && size > end:
- his = his[start : end+1]
- case size > start && size <= end:
- his = his[start:]
- default:
- his = _emptyHis
- }
- return
- }
- // platformHistories get aids of user view history
- func (s *Service) platformHistories(c context.Context, mid int64, typ int8, pn, ps int) (his []*model.History, err error) {
- var (
- size int
- h *model.History
- mhis map[string]*model.History
- start = (pn - 1) * ps
- end = start + ps - 1
- total = s.conf.History.Total
- )
- if mhis, err = s.historyDao.Map(c, mid); err != nil {
- return
- }
- if len(mhis) == 0 {
- his = _emptyHis
- return
- }
- for _, h = range mhis {
- if typ != h.TP {
- continue
- }
- his = append(his, h)
- }
- sort.Sort(model.Histories(his))
- if size = len(his); size > total {
- his = his[:total]
- size = total
- }
- switch {
- case size > start && size > end:
- his = his[start : end+1]
- case size > start && size <= end:
- his = his[start:]
- default:
- his = _emptyHis
- }
- return
- }
- // HistoryType get aids of user view history
- // +wd:ignore
- func (s *Service) HistoryType(c context.Context, mid int64, typ int8, oids []int64, ip string) (his []*model.History, err error) {
- var (
- mhis map[string]*model.History
- )
- if s.migration(mid) {
- his, err = s.serviceHistoryType(c, mid, model.BusinessByTP(typ), oids)
- if err == nil {
- return
- }
- }
- if mhis, err = s.historyDao.Map(c, mid); err != nil {
- return
- }
- if len(mhis) == 0 {
- his = _emptyHis
- return
- }
- for _, oid := range oids {
- key := fmt.Sprintf("%d_%d", oid, typ)
- if h, ok := mhis[key]; ok && h != nil {
- his = append(his, h)
- }
- }
- return
- }
- // HistoryCursor return the user all av history.
- func (s *Service) HistoryCursor(c context.Context, mid, max, viewAt int64, ps int, tp int8, tps []int8, ip string) (res []*model.Resource, err error) {
- var hs []*model.History
- if s.migration(mid) {
- var businesses []string
- for _, b := range tps {
- businesses = append(businesses, model.BusinessByTP(b))
- }
- res, err = s.serviceHistoryCursor(c, mid, max, businesses, model.BusinessByTP(tp), viewAt, ps)
- if err == nil {
- return
- }
- }
- hs, err = s.historyCursor(c, mid, max, viewAt, ps, tp, tps, ip)
- if err != nil {
- return
- }
- if len(hs) == 0 {
- return
- }
- for _, h := range hs {
- r := &model.Resource{
- TP: h.TP,
- STP: h.STP,
- Mid: h.Mid,
- Oid: h.Aid,
- Sid: h.Sid,
- Epid: h.Epid,
- Cid: h.Cid,
- Business: h.Business,
- DT: h.DT,
- Pro: h.Pro,
- Unix: h.Unix,
- }
- res = append(res, r)
- }
- return
- }
- // historyCursor get aids of user view history.
- func (s *Service) historyCursor(c context.Context, mid, max, viewAt int64, ps int, tp int8, tps []int8, ip string) (his []*model.History, err error) {
- var (
- ok bool
- e, h *model.History
- mhis map[string]*model.History
- chis, ehis map[int64]*model.History
- dhis []*model.History
- total = s.conf.History.Total
- tpMap = make(map[int8]bool)
- )
- for _, tp := range tps {
- tpMap[tp] = true
- }
- if mhis, err = s.historyDao.Map(c, mid); err != nil {
- err = nil
- mhis = make(map[string]*model.History)
- }
- for k, v := range mhis {
- v.ConvertType()
- if (len(tps) > 0) && !tpMap[v.TP] {
- delete(mhis, k)
- }
- }
- chis, _ = s.historyDao.CacheMap(c, mid)
- for k, v := range chis {
- v.ConvertType()
- if (len(tps) > 0) && !tpMap[v.TP] {
- delete(chis, k)
- continue
- }
- mhis[s.key(v.Aid, v.TP)] = v
- }
- if len(mhis) == 0 {
- his = _emptyHis
- return
- }
- ehis = make(map[int64]*model.History, len(mhis))
- for _, h = range mhis {
- if (h.TP == model.TypePGC) && h.Sid != 0 {
- if e, ok = ehis[h.Sid]; !ok || h.Unix > e.Unix {
- ehis[h.Sid] = h
- if e != nil {
- dhis = append(dhis, e)
- }
- }
- } else {
- his = append(his, h)
- }
- }
- for _, h = range ehis {
- his = append(his, h)
- }
- sort.Sort(model.Histories(his))
- if len(his) > total {
- dhis = append(dhis, his[total:]...)
- s.delChan.Do(c, func(ctx context.Context) {
- s.historyDao.Delete(ctx, mid, dhis)
- })
- his = his[:total]
- }
- if viewAt != 0 || max != 0 && tp != 0 {
- for index, h := range his {
- if viewAt != 0 && h.Unix <= viewAt || h.Aid == max && h.TP == tp {
- index++
- if index+ps <= len(his) {
- return his[index : index+ps], nil
- }
- return his[index:], nil
- }
- }
- return _emptyHis, nil
- }
- if len(his) >= ps {
- return his[:ps], nil
- }
- return
- }
- // SetShadow set the user switch.
- // +wd:ignore
- func (s *Service) SetShadow(c context.Context, mid, value int64) (err error) {
- s.serviceHide(mid, value == model.ShadowOn)
- if err = s.historyDao.SetInfoShadow(c, mid, value); err != nil {
- return
- }
- return s.historyDao.SetShadowCache(c, mid, value)
- }
- // Delete .
- func (s *Service) Delete(ctx context.Context, mid int64, his []*model.History) (err error) {
- if err = s.serviceDel(ctx, mid, his); err != nil {
- return
- }
- if err = s.historyDao.Delete(ctx, mid, his); err != nil {
- return
- }
- var aids []int64
- for _, h := range his {
- if h.TP < model.TypeArticle {
- aids = append(aids, h.Aid)
- }
- }
- if len(aids) == 0 {
- return
- }
- return s.historyDao.DelCache(ctx, mid, aids)
- }
- // Shadow return the user switch by mid.
- // +wd:ignore
- func (s *Service) Shadow(c context.Context, mid int64) (value int64, err error) {
- var (
- ok bool
- cache = true
- )
- if s.migration(mid) {
- value, err = s.serviceHideState(c, mid)
- if err == nil {
- return
- }
- }
- if value, err = s.historyDao.ShadowCache(c, mid); err != nil {
- err = nil
- cache = false
- } else if value != model.ShadowUnknown {
- return
- }
- if value, err = s.historyDao.InfoShadow(c, mid); err != nil {
- ok = true
- }
- if cache {
- s.cache.Do(c, func(ctx context.Context) {
- s.historyDao.SetShadowCache(ctx, mid, value)
- if ok && value == model.ShadowOn {
- s.historyDao.SetInfoShadow(ctx, mid, value)
- }
- })
- }
- return
- }
- // FlushHistory flush to hbase from cache.
- func (s *Service) FlushHistory(c context.Context, mids []int64, stime int64) (err error) {
- var (
- aids, miss []int64
- res map[int64]*model.History
- limit = s.conf.History.Cache
- )
- for _, mid := range mids {
- if aids, err = s.historyDao.IndexCacheByTime(c, mid, stime); err != nil {
- log.Error("s.historyDao.IndexCacheByTime(%d,%v) error(%v)", mid, stime, err)
- err = nil
- continue
- }
- if len(aids) == 0 {
- continue
- }
- if res, miss, err = s.historyDao.Cache(c, mid, aids); err != nil {
- log.Error("historyDao.Cache(%d,%v) miss:%v error(%v)", mid, aids, miss, err)
- err = nil
- continue
- }
- // * typ < model.TypeArticle all can .
- if err = s.historyDao.AddMap(c, mid, res); err != nil {
- log.Error("historyDao.AddMap(%d,%+v) error(%v)", mid, res, err)
- err = nil
- }
- if err = s.historyDao.TrimCache(c, mid, limit); err != nil {
- log.Error("historyDao.TrimCache(%d,%d) error(%v)", mid, limit, err)
- err = nil
- }
- }
- return
- }
- func (s *Service) merge(hmap map[int64]int64) {
- var (
- size = int64(s.conf.History.Size)
- merges = make(map[int64][]*model.Merge, size)
- )
- for k, v := range hmap {
- merges[k%size] = append(merges[k%size], &model.Merge{Mid: k, Now: v})
- }
- for k, v := range merges {
- s.historyDao.Merge(context.TODO(), int64(k), v)
- }
- }
- func (s *Service) bangumi(c context.Context, mid int64, epids []int64) (bangumiMap map[int64]*model.Bangumi) {
- var n = 50
- bangumiMap = make(map[int64]*model.Bangumi, len(epids))
- for len(epids) > 0 {
- if n > len(epids) {
- n = len(epids)
- }
- epban, _ := s.historyDao.Bangumis(c, mid, epids[:n])
- epids = epids[n:]
- for k, v := range epban {
- bangumiMap[k] = v
- }
- }
- return
- }
- // ManagerHistory ManagerHistory.
- // +wd:ignore
- func (s *Service) ManagerHistory(c context.Context, onlyAV bool, mid int64) (his []*model.History, err error) {
- var (
- mhis map[string]*model.History
- chis, ehis map[int64]*model.History
- )
- if mhis, err = s.historyDao.Map(c, mid); err != nil {
- err = nil
- mhis = make(map[string]*model.History)
- }
- chis, _ = s.historyDao.CacheMap(c, mid)
- for _, v := range chis {
- mhis[s.key(v.Aid, v.TP)] = v
- }
- if len(mhis) == 0 {
- his = _emptyHis
- return
- }
- ehis = make(map[int64]*model.History, len(mhis))
- for _, h := range mhis {
- if onlyAV && h.TP >= model.TypeArticle {
- continue
- }
- if (h.TP == model.TypeBangumi || h.TP == model.TypeMovie || h.TP == model.TypePGC) && h.Sid != 0 {
- if e, ok := ehis[h.Sid]; !ok || h.Unix > e.Unix {
- ehis[h.Sid] = h
- }
- } else {
- his = append(his, h)
- }
- }
- for _, h := range ehis {
- his = append(his, h)
- }
- sort.Sort(model.Histories(his))
- return
- }
|