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.
289 lines
7.3 KiB
289 lines
7.3 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"time" |
|
|
|
"go-common/app/admin/main/up-rating/dao/global" |
|
"go-common/app/admin/main/up-rating/model" |
|
|
|
"go-common/library/log" |
|
"go-common/library/xstr" |
|
) |
|
|
|
var ( |
|
_layout = "2006-01-02" |
|
_segment = 10 |
|
) |
|
|
|
// StatisGraph get statistics graph data |
|
func (s *Service) StatisGraph(c context.Context, ctype int64, tagID string, Compare int) (data interface{}, err error) { |
|
totalScore, err := s.getTypeScore(c, ctype) |
|
if err != nil { |
|
log.Error("s.getTypeScore error(%v)", err) |
|
return |
|
} |
|
nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID) |
|
if err != nil { |
|
log.Error("s.GetRatingStatis error(%v)", err) |
|
return |
|
} |
|
last := now.AddDate(0, -1*Compare, 0) |
|
lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last)) |
|
if err != nil { |
|
log.Error("s.GetRatingStatis error(%v)", err) |
|
return |
|
} |
|
data = map[string]interface{}{ |
|
"xAxis": getSections(int(totalScore)), |
|
"this_month": statisSections(nowStatis, int(totalScore)), |
|
"compare": statisSections(lastStatis, int(totalScore)), |
|
} |
|
return |
|
} |
|
|
|
// StatisList get statistics list |
|
func (s *Service) StatisList(c context.Context, ctype int64, tagID string, Compare int) (list []*model.RatingStatis, err error) { |
|
list = make([]*model.RatingStatis, 0) |
|
totalScore, err := s.getTypeScore(c, ctype) |
|
if err != nil { |
|
log.Error("s.getTypeScore error(%v)", err) |
|
return |
|
} |
|
nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID) |
|
if err != nil { |
|
log.Error("s.GetRatingStatis error(%v)", err) |
|
return |
|
} |
|
last := now.AddDate(0, -1*Compare, 0) |
|
lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last)) |
|
if err != nil { |
|
log.Error("s.GetRatingStatis error(%v)", err) |
|
return |
|
} |
|
list = statisProportion(nowStatis, lastStatis, getSections(int(totalScore)), int(totalScore)) |
|
return |
|
} |
|
|
|
// StatisExport export statis |
|
func (s *Service) StatisExport(c context.Context, ctype int64, tagID string, Compare int) (res []byte, err error) { |
|
list, err := s.StatisList(c, ctype, tagID, Compare) |
|
if err != nil { |
|
log.Error("s.StatisList error(%v)", err) |
|
return |
|
} |
|
res, err = formatCSV(formatStatis(list, ctype)) |
|
if err != nil { |
|
log.Error("StatisExport formatCSV error(%v)", err) |
|
} |
|
return |
|
} |
|
|
|
func statisProportion(now, last []*model.RatingStatis, sections []string, totalScore int) (list []*model.RatingStatis) { |
|
var totalUps, lastTotalUps int64 |
|
list = make([]*model.RatingStatis, _segment) |
|
for i := 0; i < _segment; i++ { |
|
list[i] = &model.RatingStatis{ |
|
Tips: sections[i], |
|
} |
|
} |
|
offset := totalScore / _segment |
|
for _, s := range now { |
|
totalUps += s.Ups |
|
idx := int(s.Section) * 10 / offset |
|
if idx >= _segment { |
|
idx-- |
|
} |
|
|
|
list[idx].Ups += s.Ups |
|
list[idx].Score += s.Score |
|
list[idx].CreativityScore += s.CreativityScore |
|
list[idx].InfluenceScore += s.InfluenceScore |
|
list[idx].CreditScore += s.CreditScore |
|
list[idx].Fans += s.Fans |
|
list[idx].Avs += s.Avs |
|
list[idx].Coin += s.Coin |
|
list[idx].Play += s.Play |
|
} |
|
for _, s := range last { |
|
lastTotalUps += s.Ups |
|
idx := int(s.Section) * 10 / offset |
|
if idx >= _segment { |
|
idx-- |
|
} |
|
list[idx].Compare += s.Ups |
|
} |
|
for i := 0; i < len(list); i++ { |
|
if totalUps > 0 { |
|
list[i].Proportion = fmt.Sprintf("%.02f", float64(list[i].Ups*100)/float64(totalUps)) |
|
} |
|
if lastTotalUps > 0 { |
|
list[i].ComparePropor = fmt.Sprintf("%.02f", float64(list[i].Compare*100)/float64(lastTotalUps)) |
|
} |
|
if list[i].Ups > 0 { |
|
list[i].Score /= list[i].Ups |
|
list[i].CreativityScore /= list[i].Ups |
|
list[i].InfluenceScore /= list[i].Ups |
|
list[i].CreditScore /= list[i].Ups |
|
list[i].Fans /= list[i].Ups |
|
list[i].Avs /= list[i].Ups |
|
list[i].Coin /= list[i].Ups |
|
list[i].Play /= list[i].Ups |
|
} |
|
} |
|
return |
|
} |
|
|
|
func getSections(score int) (sections []string) { |
|
sections = make([]string, _segment) |
|
offset := score / _segment |
|
for i := 0; i < len(sections); i++ { |
|
sections[i] = fmt.Sprintf("%d-%d", i*offset, (i+1)*offset) |
|
} |
|
return sections |
|
} |
|
|
|
func statisSections(statis []*model.RatingStatis, totalScore int) (ups []int64) { |
|
ups = make([]int64, _segment) |
|
offset := totalScore / _segment |
|
for _, s := range statis { |
|
idx := int(s.Section) * 10 / offset |
|
if idx >= len(ups) { |
|
idx-- |
|
} |
|
ups[idx] += s.Ups |
|
} |
|
return |
|
} |
|
|
|
// GetLastRatingStatis get last rating statis |
|
func (s *Service) GetLastRatingStatis(c context.Context, ctype int64, tagID string) (statis []*model.RatingStatis, date time.Time, err error) { |
|
statis = make([]*model.RatingStatis, 0) |
|
times := 0 |
|
date = getStartMonthlyDate(time.Now()).AddDate(0, -1, 0) |
|
for times < 2 { |
|
statis, err = s.GetRatingStatis(c, ctype, tagID, date) |
|
if err != nil { |
|
return |
|
} |
|
if len(statis) > 0 { |
|
break |
|
} |
|
times++ |
|
date = date.AddDate(0, -1, 0) |
|
} |
|
if times == 2 && len(statis) == 0 { |
|
err = fmt.Errorf("get last statis error") |
|
return |
|
} |
|
return |
|
} |
|
|
|
// GetRatingStatis get rating statis |
|
func (s *Service) GetRatingStatis(c context.Context, ctype int64, tagID string, date time.Time) (statis []*model.RatingStatis, err error) { |
|
return s.dao.GetRatingStatis(c, ctype, date.Format(_layout), tagID) |
|
} |
|
|
|
func getStartMonthlyDate(date time.Time) time.Time { |
|
return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local) |
|
} |
|
|
|
// GetTrendAsc get trend asc |
|
func (s *Service) GetTrendAsc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) { |
|
q := query(ctype, tags, frl, mid) |
|
dsr := getStartMonthlyDate(date).Format(_layout) |
|
|
|
total, err = s.dao.AscTrendCount(c, dsr, q) |
|
if err != nil { |
|
return |
|
} |
|
|
|
q += fmt.Sprintf(" ORDER BY %s_diff DESC,id LIMIT %d,%d", ctype, offset, limit) |
|
ts, err = s.dao.GetTrendAsc(c, ctype, dsr, q) |
|
if err != nil { |
|
return |
|
} |
|
|
|
err = fillUpNames(c, ts) |
|
return |
|
} |
|
|
|
//GetTrendDesc get trend desc |
|
func (s *Service) GetTrendDesc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) { |
|
q := query(ctype, tags, frl, mid) |
|
dsr := getStartMonthlyDate(date).Format(_layout) |
|
|
|
total, err = s.dao.DescTrendCount(c, dsr, q) |
|
if err != nil { |
|
return |
|
} |
|
|
|
q += fmt.Sprintf(" ORDER BY %s_diff,id LIMIT %d,%d", ctype, offset, limit) |
|
ts, err = s.dao.GetTrendDesc(c, ctype, dsr, q) |
|
if err != nil { |
|
return |
|
} |
|
|
|
err = fillUpNames(c, ts) |
|
return |
|
} |
|
|
|
func fillUpNames(c context.Context, ts []*model.Trend) (err error) { |
|
var mids []int64 |
|
for _, trend := range ts { |
|
mids = append(mids, trend.MID) |
|
} |
|
if len(mids) == 0 { |
|
return |
|
} |
|
ns, err := global.Names(c, mids) |
|
if err != nil { |
|
return |
|
} |
|
for _, trend := range ts { |
|
trend.Nickname = ns[trend.MID] |
|
} |
|
return |
|
} |
|
|
|
func getSection(ctype string, frl int) (section int, typ int) { |
|
if ctype == "magnetic" { |
|
typ = 0 |
|
interval := 600 / 10 |
|
section = frl / interval |
|
} |
|
|
|
if ctype == "creativity" { |
|
typ = 1 |
|
interval := 200 / 10 |
|
section = frl / interval |
|
} |
|
|
|
if ctype == "influence" { |
|
typ = 2 |
|
interval := 200 / 10 |
|
section = frl / interval |
|
} |
|
|
|
if ctype == "credit" { |
|
typ = 3 |
|
interval := 200 / 10 |
|
section = frl / interval |
|
} |
|
return |
|
} |
|
|
|
func query(ctype string, tags []int64, frl int, mid int64) (q string) { |
|
if len(tags) > 0 { |
|
q += fmt.Sprintf(" AND tag_id IN (%s)", xstr.JoinInts(tags)) |
|
} |
|
section, typ := getSection(ctype, frl) |
|
q += fmt.Sprintf(" AND section=%d", section) |
|
q += fmt.Sprintf(" AND ctype=%d", typ) |
|
|
|
if mid > 0 { |
|
q += fmt.Sprintf(" AND mid=%d", mid) |
|
} |
|
return |
|
}
|
|
|