go-common/app/admin/main/up/service/upcrmservice/up_rank.go
2019-04-22 18:49:16 +08:00

181 lines
4.5 KiB
Go

package upcrmservice
import (
"context"
"sort"
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/app/admin/main/up/util/mathutil"
"go-common/library/log"
xtime "go-common/library/time"
)
var (
//AllRankTyps all rank types
AllRankTyps = []int{
upcrmmodel.UpRankTypeFans30day1k,
upcrmmodel.UpRankTypeFans30day1w,
upcrmmodel.UpRankTypePlay30day1k,
upcrmmodel.UpRankTypePlay30day1w,
upcrmmodel.UpRankTypePlay30day10k,
upcrmmodel.UpRankTypeFans30dayIncreaseCount,
upcrmmodel.UpRankTypeFans30dayIncreasePercent,
}
)
type sortRankFunc func(p1, p2 *upcrmmodel.UpRankInfo) bool
type upRankSorter struct {
datas []*upcrmmodel.UpRankInfo
by sortRankFunc // Closure used in the Less method.
}
// Len is part of sort.Interface.
func (s *upRankSorter) Len() int {
return len(s.datas)
}
// Swap is part of sort.Interface.
func (s *upRankSorter) 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 *upRankSorter) Less(i, j int) bool {
return s.by(s.datas[i], s.datas[j])
}
func sortRankInfo(planets []*upcrmmodel.UpRankInfo, sortfunc sortRankFunc) {
ps := &upRankSorter{
datas: planets,
by: sortfunc, // The Sort method's receiver is the function (closure) that defines the sort order.
}
sort.Sort(ps)
}
func sortByValueAsc(p1, p2 *upcrmmodel.UpRankInfo) bool {
if p1.Value < p2.Value {
return true
}
if p1.Value == p2.Value {
return p1.Value2 < p2.Value2
}
return false
}
func sortByValueDesc(p1, p2 *upcrmmodel.UpRankInfo) bool {
if p1.Value > p2.Value {
return true
}
if p1.Value == p2.Value {
return p1.Value2 > p2.Value2
}
return false
}
// 从数据库中更新数据
func (s *Service) refreshUpRankDate(date time.Time) {
rankData, err := s.crmdb.QueryUpRankAll(date)
if err != nil {
log.Error("refresh from db fail, err=%+v", err)
return
}
var typeMap = map[int][]*upcrmmodel.UpRankInfo{}
var upInfoMap = map[int64]*upcrmmodel.InfoQueryResult{}
for _, v := range rankData {
var rankType = int(v.Type)
var rankInfo = &upcrmmodel.UpRankInfo{}
rankInfo.Mid = v.Mid
rankInfo.CopyFromUpRank(&v)
typeMap[rankType] = append(typeMap[rankType], rankInfo)
upInfoMap[v.Mid] = nil
}
log.Info("refresh from db, get for date=%v, len=%d", date, len(rankData))
// interestring code
var mids []int64
for k := range upInfoMap {
mids = append(mids, k)
}
// 查询并合并
var infoData, e = s.upBaseInfoQueryBatch(s.crmdb.QueryUpBaseInfoBatchByMid, mids...)
err = e
if err != nil {
log.Error("get from base info fail, err=%+v", err)
return
}
for _, v := range infoData {
upInfoMap[v.Mid] = v
}
for _, list := range typeMap {
for _, info := range list {
var data, _ = upInfoMap[info.Mid]
if data == nil {
continue
}
info.InfoQueryResult = *data
switch info.RankType {
case upcrmmodel.UpRankTypeFans30day1k,
upcrmmodel.UpRankTypeFans30day1w,
upcrmmodel.UpRankTypePlay30day1k,
upcrmmodel.UpRankTypePlay30day1w,
upcrmmodel.UpRankTypePlay30day10k,
upcrmmodel.UpRankTypeFans30dayIncreaseCount,
upcrmmodel.UpRankTypeFans30dayIncreasePercent:
info.CompleteTime = info.FirstUpTime + xtime.Time(info.Value)
}
}
}
// 排序
for k, list := range typeMap {
var sortFunc sortRankFunc = sortByValueAsc
switch k {
case upcrmmodel.UpRankTypeFans30dayIncreaseCount,
upcrmmodel.UpRankTypeFans30dayIncreasePercent:
sortFunc = sortByValueDesc
}
sortRankInfo(list, sortFunc)
for i, v := range list {
v.Rank = i + 1
}
log.Info("cache rank type=%d, len=%d, date=%v", k, len(list), date)
}
s.uprankCache = typeMap
s.lastCacheDate = date
}
//UpRankQueryList query up rank list
func (s *Service) UpRankQueryList(c context.Context, arg *upcrmmodel.UpRankQueryArgs) (result upcrmmodel.UpRankQueryResult, err error) {
if arg.Page == 0 {
arg.Page = 1
}
if arg.Size <= 0 || arg.Size > 50 {
arg.Size = 20
}
// 1.从内存中读数据
var rankList, ok = s.uprankCache[arg.Type]
if !ok || rankList == nil {
log.Warn("no available rank data in cache, type=%d", arg.Type)
return
}
var startIndex = (arg.Page - 1) * arg.Size
var endIndex = startIndex + arg.Size
var totalCount = len(rankList)
endIndex = mathutil.Min(endIndex, totalCount)
if startIndex < endIndex {
result.Result = rankList[startIndex:endIndex]
}
result.Date = xtime.Time(s.lastCacheDate.Unix())
result.TotalCount = totalCount
result.Size = arg.Size
result.Page = arg.Page
log.Info("get rank list for type=%d", arg.Type)
// 2.如果没有,从数据库中刷数据
return
}