You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.8 KiB
183 lines
4.8 KiB
package mcndao |
|
|
|
import ( |
|
"context" |
|
"sort" |
|
"time" |
|
|
|
"go-common/app/interface/main/mcn/conf" |
|
"go-common/app/interface/main/mcn/dao/cache" |
|
"go-common/app/interface/main/mcn/dao/global" |
|
"go-common/app/interface/main/mcn/model/mcnmodel" |
|
"go-common/library/log" |
|
|
|
"github.com/bluele/gcache" |
|
) |
|
|
|
// RecommendPoolCache . |
|
type RecommendPoolCache struct { |
|
// map[tid] list |
|
UpTidMap map[int16][]*mcnmodel.McnGetRecommendPoolInfo |
|
TidTypeList []*mcnmodel.TidnameInfo |
|
} |
|
|
|
func (r *RecommendPoolCache) add(v *mcnmodel.McnGetRecommendPoolInfo) { |
|
if v == nil { |
|
return |
|
} |
|
if r.UpTidMap == nil { |
|
r.UpTidMap = make(map[int16][]*mcnmodel.McnGetRecommendPoolInfo) |
|
} |
|
|
|
r.UpTidMap[v.ActiveTid] = append(r.UpTidMap[v.ActiveTid], v) |
|
if v.ActiveTid != 0 { |
|
// 加入到全部分类中 |
|
r.UpTidMap[0] = append(r.UpTidMap[0], v) |
|
} |
|
} |
|
|
|
//RecommendSortFunc sort func |
|
type RecommendSortFunc func(p1, p2 *mcnmodel.McnGetRecommendPoolInfo) bool |
|
|
|
//RecommendDataSorter data sorter |
|
type RecommendDataSorter struct { |
|
Datas []*mcnmodel.McnGetRecommendPoolInfo |
|
By RecommendSortFunc // Closure used in the Less method. |
|
} |
|
|
|
// Len is part of sort.Interface. |
|
func (s *RecommendDataSorter) Len() int { |
|
return len(s.Datas) |
|
} |
|
|
|
// Swap is part of sort.Interface. |
|
func (s *RecommendDataSorter) Swap(i, j int) { |
|
s.Datas[i], s.Datas[j] = s.Datas[j], s.Datas[i] |
|
} |
|
|
|
// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter. |
|
func (s *RecommendDataSorter) Less(i, j int) bool { |
|
return s.By(s.Datas[i], s.Datas[j]) |
|
} |
|
|
|
// RecommendSortByFansDesc . |
|
func RecommendSortByFansDesc(p1, p2 *mcnmodel.McnGetRecommendPoolInfo) bool { |
|
return p1.FansCount > p2.FansCount |
|
} |
|
|
|
// RecommendSortByFansAsc . |
|
func RecommendSortByFansAsc(p1, p2 *mcnmodel.McnGetRecommendPoolInfo) bool { |
|
return p1.FansCount < p2.FansCount |
|
} |
|
|
|
// RecommendSortByMonthFansDesc . |
|
func RecommendSortByMonthFansDesc(p1, p2 *mcnmodel.McnGetRecommendPoolInfo) bool { |
|
return p1.FansCountIncreaseMonth > p2.FansCountIncreaseMonth |
|
} |
|
|
|
// RecommendSortByArchiveCountDesc . |
|
func RecommendSortByArchiveCountDesc(p1, p2 *mcnmodel.McnGetRecommendPoolInfo) bool { |
|
return p1.ArchiveCount > p2.ArchiveCount |
|
} |
|
|
|
type loadRecommandFunc func() (res *RecommendPoolCache, err error) |
|
|
|
func cacheKeyRecommend(int64) string { |
|
return "recommend" |
|
} |
|
|
|
//rawGetRecommendPool get recommend pool |
|
func (d *Dao) rawGetRecommendPool() (res []*mcnmodel.McnGetRecommendPoolInfo, err error) { |
|
var dbresult []*mcnmodel.McnUpRecommendPool |
|
err = d.mcndb.Where("state=?", mcnmodel.MCNUPRecommendStateOn).Find(&dbresult).Error |
|
if err != nil { |
|
log.Error("fail to get recommend pool, err=%s", err) |
|
return |
|
} |
|
|
|
for _, v := range dbresult { |
|
var info = &mcnmodel.McnGetRecommendPoolInfo{} |
|
info.Copy(v) |
|
res = append(res, info) |
|
} |
|
return |
|
} |
|
|
|
func (d *Dao) loadRecommendPool() (res *RecommendPoolCache, err error) { |
|
recommendInfos, err := d.rawGetRecommendPool() |
|
if err != nil { |
|
log.Error("get recommend fail, err=%s", err) |
|
return |
|
} |
|
|
|
var midMap = make(map[int64]struct{}) |
|
// 获取mid列表 |
|
for _, v := range recommendInfos { |
|
midMap[v.UpMid] = struct{}{} |
|
} |
|
|
|
var mids []int64 |
|
for k := range midMap { |
|
mids = append(mids, k) |
|
} |
|
|
|
// 获取账号信息,头像 |
|
accInfos, err := global.GetInfos(context.Background(), mids) |
|
if err != nil || accInfos == nil { |
|
log.Warn("get infos fail, err=%s", err) |
|
} |
|
|
|
var tidUnique = newTidNameUnique() |
|
res = new(RecommendPoolCache) |
|
for _, v := range recommendInfos { |
|
if account, ok := accInfos[v.UpMid]; ok { |
|
v.UpName = account.Name |
|
} |
|
v.TidName = cache.GetTidName(int64(v.ActiveTid)) |
|
// 这里DataTypeAccumulate只是用来记录一下 |
|
tidUnique.addTid(v.ActiveTid, v.TidName, mcnmodel.DataTypeAccumulate) |
|
res.add(v) |
|
} |
|
res.TidTypeList = tidUnique.getList(mcnmodel.DataTypeAccumulate) |
|
|
|
// 进行默认排序,按照粉丝数,降序 |
|
for k := range res.UpTidMap { |
|
sort.Sort(&RecommendDataSorter{Datas: res.UpTidMap[k], By: RecommendSortByFansDesc}) |
|
} |
|
return |
|
} |
|
|
|
func (d *Dao) getRecommendCache(keyCalc keyFunc, load loadRecommandFunc) (result *RecommendPoolCache, err error) { |
|
var key = keyCalc(0) |
|
v, err := d.localcache.Get(key) |
|
if err != nil { |
|
if err == gcache.KeyNotFoundError { |
|
// load cache |
|
v, err = load() |
|
if err != nil { |
|
log.Error("load cache error, key=%s. err=%s", key, err) |
|
return |
|
} |
|
|
|
d.localcache.SetWithExpire(key, v, time.Duration(conf.Conf.RankCache.RecommendPoolExpireTime)) |
|
} else { |
|
log.Error("get from gcache err, key=%s, err=%s", key, err) |
|
return |
|
} |
|
} |
|
if v == nil { |
|
return |
|
} |
|
result, _ = v.(*RecommendPoolCache) |
|
return |
|
} |
|
|
|
//GetRecommendPool get recommend pool |
|
func (d *Dao) GetRecommendPool() (res *RecommendPoolCache, err error) { |
|
res, err = d.getRecommendCache(cacheKeyRecommend, d.loadRecommendPool) |
|
if err != nil { |
|
log.Error("fail to get recommend pool, err=%s", err) |
|
return |
|
} |
|
return |
|
}
|
|
|