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.
180 lines
4.5 KiB
180 lines
4.5 KiB
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 |
|
}
|
|
|