Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/service:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"archive.go",
"article.go",
"fan.go",
"overview.go",
"service.go",
],
importpath = "go-common/app/interface/main/creative/service/data",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/dao/account:go_default_library",
"//app/interface/main/creative/dao/activity:go_default_library",
"//app/interface/main/creative/dao/archive:go_default_library",
"//app/interface/main/creative/dao/article:go_default_library",
"//app/interface/main/creative/dao/bfs:go_default_library",
"//app/interface/main/creative/dao/data:go_default_library",
"//app/interface/main/creative/dao/medal:go_default_library",
"//app/interface/main/creative/dao/tag:go_default_library",
"//app/interface/main/creative/model/archive:go_default_library",
"//app/interface/main/creative/model/data:go_default_library",
"//app/interface/main/creative/model/medal:go_default_library",
"//app/interface/main/creative/model/tag:go_default_library",
"//app/interface/main/creative/service:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,485 @@
package data
import (
"context"
"sort"
"sync"
"time"
"go-common/library/ecode"
"go-common/app/interface/main/creative/model/archive"
"go-common/app/interface/main/creative/model/data"
"go-common/app/service/main/archive/api"
"go-common/library/log"
"go-common/library/sync/errgroup"
"math"
)
var (
zeroSummary = map[string]int64{
"total": 0,
"inc": 0,
"play": 0,
"dm": 0,
"reply": 0,
"coin": 0,
"inter": 0,
"vv": 0,
"da": 0,
"re": 0,
"co": 0,
"fv": 0,
"sh": 0,
"lk": 0,
}
)
// UpFansAnalysisForApp get app fans analysis.
func (s *Service) UpFansAnalysisForApp(c context.Context, mid int64, ty int, ip string) (res *data.AppFan, err error) {
var (
g, ctx = errgroup.WithContext(c)
origin *data.AppFan
typeList map[string]int64
tagList []*data.Rank
viewerArea map[string]int64
viewerBase *data.ViewerBase
)
res = &data.AppFan{}
if origin, err = s.data.UpFansAnalysisForApp(c, mid, ty); err != nil {
log.Error("s.data.UpFansAnalysisForApp mid(%d)|ip(%s)|err(%v)", mid, ip, err)
return
}
if origin == nil {
return
}
if origin.Summary == nil {
origin.Summary = zeroSummary
}
log.Info("s.data.UpFansAnalysisForApp origin mid(%d)|origin(%+v)", mid, origin)
g.Go(func() (err error) {
total, ok := origin.Summary["total"]
inc, oki := origin.Summary["inc"]
if !ok || !oki {
return
}
pfl, err := s.acc.ProfileWithStat(ctx, mid)
if err != nil {
err = nil
log.Error("s.acc.ProfileWithStat mid(%d)|err(%v)", mid, err)
return
}
if pfl == nil {
log.Error("s.acc.ProfileWithStat mid(%d)|Follower(%+v) err(%v)", mid, pfl, err)
return
}
origin.Summary["total"] = pfl.Follower
origin.Summary["inc"] = inc + (pfl.Follower - total)
return
})
g.Go(func() (err error) {
if tys, tgs, err := s.fanTrend(ctx, mid); err == nil {
typeList = tys
tagList = tgs
}
return nil
})
g.Go(func() (err error) {
if va, err := s.fanViewerArea(ctx, mid); err == nil {
viewerArea = va
}
return nil
})
g.Go(func() (err error) {
if vb, err := s.fanViewerBase(ctx, mid); err == nil {
viewerBase = vb
}
return nil
})
g.Wait()
res.Summary = origin.Summary
res.TypeList = typeList
res.TagList = tagList
res.ViewerArea = viewerArea
res.ViewerBase = viewerBase
log.Info("UpFansAnalysisForApp mid(%d)|res(%+v)", mid, res)
return
}
//FanRankApp get app fans rank list.
func (s *Service) FanRankApp(c context.Context, mid int64, ty int, ip string) (res map[string][]*data.RankInfo, err error) {
var (
origin *data.AppFan
rkList map[string][]*data.RankInfo
)
if origin, err = s.data.UpFansAnalysisForApp(c, mid, ty); err != nil {
log.Error("s.data.UpFansAnalysisForApp mid(%d)|ip(%s)|err(%v)", mid, ip, err)
return
}
if origin == nil {
return
}
log.Info("s.UpFansRankApp origin mid(%d)|origin(%+v)", mid, origin)
if rkList, err = s.getTopList(c, mid, origin.RankMap, ip); err != nil {
log.Error("s.getTopList err(%v)", err)
}
if len(rkList) == 0 { //排行列表容错必须返回对应的key
rkList = make(map[string][]*data.RankInfo)
}
for _, key := range rankKeys {
if v, ok := rkList[key]; ok {
rkList[key] = v
} else {
rkList[key] = nil
}
}
res = rkList
log.Info("s.UpFansRankApp mid(%d)|res(%+v)|len[rkList](%d)", mid, res, len(rkList))
return
}
func (s *Service) fanTrend(c context.Context, mid int64) (tys map[string]int64, tags []*data.Rank, err error) {
var (
dt = getDate()
trend map[string]*data.ViewerTrend
)
if trend, err = s.viewerTrend(c, mid, dt); err != nil {
log.Error("fanTrend s.viewerTrend mid(%d)|err(%v)", mid, err)
return
}
if tr, ok := trend["fan"]; ok && tr != nil {
tys = tr.Ty
skeys := []int{2, 1, 4, 3, 6, 5, 8, 7, 10, 9}
for _, k := range skeys {
if v, ok := tr.Tag[k]; ok {
tg := &data.Rank{
Rank: k,
Name: v,
}
tags = append(tags, tg)
}
}
}
return
}
func (s *Service) fanViewerArea(c context.Context, mid int64) (res map[string]int64, err error) {
var (
origin map[string]map[string]int64
)
if origin, err = s.data.ViewerArea(c, mid, getDate()); err != nil {
log.Error("fanViewerBase s.data.ViewerArea mid(%d)|err(%v)", mid, err)
}
if len(origin) == 0 {
return
}
if v, ok := origin["fan"]; ok {
res = v
}
return
}
func (s *Service) fanViewerBase(c context.Context, mid int64) (res *data.ViewerBase, err error) {
var (
origin map[string]*data.ViewerBase
)
if origin, err = s.data.ViewerBase(c, mid, getDate()); err != nil {
log.Error("fanViewerBase s.data.ViewerArea mid(%d)|err(%v)", mid, err)
}
if len(origin) == 0 {
return
}
if v, ok := origin["fan"]; ok {
res = v
}
return
}
//OverView for app data overview.
func (s *Service) OverView(c context.Context, mid int64, ty int8, ip string) (res *data.AppOverView, err error) {
var (
g, ctx = errgroup.WithContext(c)
stat *data.Stat
allIncr []*data.ThirtyDay
singleArcInc []*data.ArcInc
)
g.Go(func() (err error) {
if stat, err = s.NewStat(ctx, mid, ip); err != nil {
err = nil
log.Error("OverView s.ThirtyDayArchive mid(%d)|err(%v)", mid, err)
}
return nil
})
g.Go(func() (err error) {
if allIncr, err = s.ThirtyDayArchive(ctx, mid, ty); err != nil {
err = nil
log.Error("OverView s.ThirtyDayArchive mid(%d)|err(%v)", mid, err)
}
if len(allIncr) >= 7 {
allIncr = allIncr[0:7]
}
return nil
})
g.Go(func() (err error) {
if prop, err := s.AppUpIncr(c, mid, ty, ip); err == nil && len(prop) > 0 {
if prop[len(prop)-1] != nil { //获取最后一天的数据
singleArcInc = prop[len(prop)-1].Arcs
}
}
return nil
})
g.Wait()
res = &data.AppOverView{
Stat: stat,
AllArcIncr: allIncr,
SingleArcInc: singleArcInc,
}
return
}
// ArchiveAnalyze get single archive data.
func (s *Service) ArchiveAnalyze(c context.Context, aid, mid int64, ip string) (stat *data.ArchiveData, err error) {
// check aid valid and owner
isWhite := false
for _, m := range s.c.Whitelist.DataMids {
if m == mid {
isWhite = true
break
}
}
a, re := s.arc.Archive(c, aid, ip)
if re != nil {
err = re
return
}
if a == nil {
err = ecode.AccessDenied
return
}
if !isWhite && a.Author.Mid != mid {
err = ecode.AccessDenied
return
}
stat, err = s.data.ArchiveStat(c, aid)
if err != nil {
log.Error("s.data.ArchiveStat aid(%d)|mid(%d)|error(%v)", aid, mid, err)
return
}
if stat == nil {
return
}
if stat.ArchiveStat.Play >= 100 {
stat.ArchiveAreas, err = s.data.ArchiveArea(c, aid)
}
log.Info("s.ArchiveAnalyze aid(%d)|mid(%d)|stat(%+v)", aid, mid, stat)
return
}
// VideoRetention get video quit data.
func (s *Service) VideoRetention(c context.Context, cid, mid int64, ip string) (res *data.VideoQuit, err error) {
var (
qs []int64
arc *api.Arc
video *archive.Video
isWhite bool
)
for _, m := range s.c.Whitelist.DataMids {
if m == mid {
isWhite = true
break
}
}
if video, err = s.arc.VideoByCid(c, int64(cid), ip); err != nil {
err = ecode.AccessDenied
return
}
if video == nil {
return
}
if arc, err = s.arc.Archive(c, video.Aid, ip); err == nil && !isWhite && arc.Author.Mid != mid {
err = ecode.AccessDenied
return
}
qs, err = s.data.VideoQuitPoints(c, cid)
res = &data.VideoQuit{
Point: appVideoQuit(qs),
Duration: sliceDuration(qs),
}
log.Info("s.VideoRetention cid(%d)|mid(%d)|quitPoints(%+v)|video(%+v)|res(%+v)", cid, mid, qs, video, res)
return
}
// >7 interval=(n/7四舍五入)
func appVideoQuit(qps []int64) []int64 {
cnt := len(qps) + 1
if cnt <= 7 {
return qps
}
nqps := make([]int64, 0)
interval := int64(math.Floor(float64(cnt)/7.0 + 0.5))
for i := 1; i < 8; i++ {
k := interval * int64(i)
if k > int64(cnt)-1 {
break
}
nqps = append(nqps, qps[k-1])
}
return nqps
}
func sliceDuration(qps []int64) (ds []int64) {
cnt := len(qps) + 1
if cnt <= 7 {
for i := 1; i < cnt; i++ {
ds = append(ds, int64(i)*30)
}
return
}
interval := int64(math.Floor(float64(cnt)/7.0 + 0.5))
for i := 1; i < 8; i++ {
k := interval * int64(i)
if k > int64(cnt)-1 {
break
}
ds = append(ds, (k)*30)
}
return
}
// AppVideoQuitPoints get app video quit data.
func (s *Service) AppVideoQuitPoints(c context.Context, cid, mid int64, ip string) (res []int64, err error) {
if res, err = s.VideoQuitPoints(c, cid, mid, ip); err != nil {
return
}
res = appVideoQuit(res)
return
}
// AppUpIncr for Play/Dm/Reply/Fav/Share/Elec/Coin incr.
func (s *Service) AppUpIncr(c context.Context, mid int64, ty int8, ip string) (res []*data.AppViewerIncr, err error) {
incr, err := s.UpIncr(c, mid, ty, ip)
if err != nil {
return
}
if len(incr) == 0 {
return
}
res = make([]*data.AppViewerIncr, 0, len(incr))
sortK := make([]string, 0, len(incr))
for k := range incr {
sortK = append(sortK, k)
}
sort.Strings(sortK)
for _, k := range sortK {
v, ok := incr[k]
if !ok {
continue
}
if v != nil {
av := &data.AppViewerIncr{}
tm, _ := time.Parse("20060102", k)
av.DateKey = tm.Unix()
av.Arcs = v.Arcs
av.TotalIncr = v.TotalIncr
trs := make([]*data.Rank, 0, len(v.TyRank))
for rk, rv := range v.TyRank {
tr := &data.Rank{}
tr.Name = rk
tr.Rank = rv
trs = append(trs, tr)
}
av.TyRank = trs
res = append(res, av)
}
}
return
}
// AppStat get app archive static data.
func (s *Service) AppStat(c context.Context, mid int64) (sts *data.AppStatList, err error) {
sts = &data.AppStatList{}
sts.Show = 1
if sts.Show == 0 {
return
}
var (
wg sync.WaitGroup
viewChan = make(chan *data.AppStat, 6)
fanChan = make(chan *data.AppStat, 6)
comChan = make(chan *data.AppStat, 6)
dmChan = make(chan *data.AppStat, 6)
)
for i := 0; i < 6; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
datekey := time.Now().AddDate(0, 0, -1-i).Add(-12 * time.Hour).Format("2006-01-02")
dt := time.Now().AddDate(0, 0, -1-i).Add(-12 * time.Hour).Format("20060102")
res, err := s.data.UpStat(c, mid, dt)
if err != nil {
log.Error("s.data.UpStat mid(%d)|err(%v)", mid, err)
return
}
if res == nil {
return
}
viewChan <- &data.AppStat{Date: datekey, Num: res.View}
fanChan <- &data.AppStat{Date: datekey, Num: res.Fans}
comChan <- &data.AppStat{Date: datekey, Num: res.Reply}
dmChan <- &data.AppStat{Date: datekey, Num: res.Dm}
}(i)
}
wg.Wait()
close(viewChan)
close(fanChan)
close(comChan)
close(dmChan)
for v := range viewChan {
sts.View = append(sts.View, v)
}
for v := range fanChan {
sts.Fans = append(sts.Fans, v)
}
for v := range comChan {
sts.Comment = append(sts.Comment, v)
}
for v := range dmChan {
sts.Danmu = append(sts.Danmu, v)
}
sort.Slice(sts.View, func(i, j int) bool {
return sts.View[i].Date > sts.View[j].Date
})
sort.Slice(sts.Fans, func(i, j int) bool {
return sts.Fans[i].Date > sts.Fans[j].Date
})
sort.Slice(sts.Comment, func(i, j int) bool {
return sts.Comment[i].Date > sts.Comment[j].Date
})
sort.Slice(sts.Danmu, func(i, j int) bool {
return sts.Danmu[i].Date > sts.Danmu[j].Date
})
// set increment num
for i := 0; i < len(sts.View)-1; i++ {
if sts.View[i].Num = sts.View[i].Num - sts.View[i+1].Num; sts.View[i].Num < 0 {
sts.View[i].Num = 0
}
if sts.Fans[i].Num = sts.Fans[i].Num - sts.Fans[i+1].Num; sts.Fans[i].Num < 0 {
sts.Fans[i].Num = 0
}
if sts.Comment[i].Num = sts.Comment[i].Num - sts.Comment[i+1].Num; sts.Comment[i].Num < 0 {
sts.Comment[i].Num = 0
}
if sts.Danmu[i].Num = sts.Danmu[i].Num - sts.Danmu[i+1].Num; sts.Danmu[i].Num < 0 {
sts.Danmu[i].Num = 0
}
}
// rm last element
if len(sts.View) > 0 {
sts.View = sts.View[:len(sts.View)-1]
sts.Fans = sts.Fans[:len(sts.Fans)-1]
sts.Comment = sts.Comment[:len(sts.Comment)-1]
sts.Danmu = sts.Danmu[:len(sts.Danmu)-1]
}
return
}

View File

@@ -0,0 +1,186 @@
package data
import (
"context"
"sort"
"sync"
"time"
"go-common/app/interface/main/creative/model/data"
"go-common/app/service/main/archive/api"
"go-common/library/log"
)
// UpPlaySourceAnalysis get play analysis.
func (s *Service) UpPlaySourceAnalysis(c context.Context, mid int64) (res *data.PlaySource, err error) {
if res, err = s.data.UpPlaySourceAnalysis(c, mid); err != nil {
log.Error("s.data.UpPlaySourceAnalysis err(%v)", err)
}
return
}
// reverse reverses a slice of ints in place.
func reverse(s []int64) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}
// UpArcPlayAnalysis get play list.
func (s *Service) UpArcPlayAnalysis(c context.Context, mid int64, cp int, ip string) (res *data.ArchivePlayList, err error) {
var (
originAIDs []int64
)
res = &data.ArchivePlayList{} //初始化返回值
dt := "0030" //最近30个稿件
originAIDs, err = s.data.UpArcQuery(c, mid, dt, cp)
if err != nil {
log.Error("s.data.UpArcQuery mid(%d)|err(%v)", err, mid)
return
}
log.Info("s.data.UpArcQuery originAIDs(%+v)|len(%d)|mid(%d)", originAIDs, len(originAIDs), mid)
reverse(originAIDs) //反转获取最近aid list.
aids := make([]int64, 0, 30)
aidsMap := make(map[int]int64)
sortK := make([]int, 0, 30)
for k, aid := range originAIDs { //取最近30个aid
aidsMap[k] = aid
sortK = append(sortK, k)
if len(sortK) == 30 {
break
}
}
sort.Slice(sortK, func(i, j int) bool { //30个aid索引从小到大排列
return sortK[i] < sortK[j]
})
for _, ak := range sortK {
if aid, ok := aidsMap[ak]; ok {
aids = append(aids, aid)
}
}
count := len(aids)
log.Info("s.data.UpArcQuery aids(%+v)|len(%d)|mid(%d)", aids, count, mid)
if count == 0 {
return
}
aps := make([]*data.ArchivePlay, 0, count)
apsMap := make(map[int64]*data.ArchivePlay, count)
var (
wg sync.WaitGroup
l sync.RWMutex
avm map[int64]*api.Arc
)
start := time.Now()
for _, aid := range aids { //并发获取aid对应的播放信息
wg.Add(1)
go func(aid int64) {
defer wg.Done()
start = time.Now()
var ap *data.ArchivePlay
if ap, err = s.data.UpArcPlayAnalysis(context.Background(), aid); err != nil {
log.Error("s.data.UpArcPlayAnalysis err(%v)", err)
}
elapsed := time.Since(start)
log.Info("s.data.UpArcPlayAnalysis ap(%+v) elapsed(%v)", ap, elapsed)
if ap != nil {
l.Lock()
apsMap[aid] = ap
l.Unlock()
}
}(aid)
}
wg.Add(1)
go func() {
defer wg.Done()
if avm, err = s.arc.Archives(c, aids, ip); err != nil {
log.Error("s.arc.Archives mid(%d)|aids(%+v)|ip(%s)|err(%v)", mid, aids, ip, err)
err = nil
}
}()
wg.Wait()
elapsed := time.Since(start)
log.Info("s.data.UpArcPlayAnalysis aids(%+v)|apsMap(%+v)|len(apsMap|%d)|len(avm|%d)|elapsed(%v)", apsMap, aids, len(avm), len(apsMap), elapsed)
for _, aid := range aids {
if ap, ok := apsMap[aid]; ok {
if av, ok := avm[aid]; ok && av != nil && ap != nil {
ap.Title = av.Title
}
aps = append(aps, ap)
}
}
sort.Slice(aps, func(i, j int) bool { //30个aid按创建时间从小到大排列
return aps[i].CTime < aps[j].CTime
})
res.ArcPlayList = aps
return
}
// ThirtyDayArchive for Play/Dm/Reply/Fav/Share/Elec/Coin for 30 days.
func (s *Service) ThirtyDayArchive(c context.Context, mid int64, ty int8) (res []*data.ThirtyDay, err error) {
tyStr, _ := data.IncrTy(ty)
if res, err = s.data.ThirtyDayArchiveCache(c, mid, tyStr); err != nil && len(res) != 0 {
log.Info("creatorDataArchive mid(%d) type(%d) cache hit", mid, ty)
return
}
if res, err = s.data.ThirtyDayArchive(c, mid, ty); len(res) != 0 {
timeSlice := make([]int64, 0, 30)
resMap := make(map[int64]int64)
for i := 30; i > 0; i-- { //从昨天往前推算30天生成30天对应的时间戳
var tm time.Time
dt := time.Now().AddDate(0, 0, -1-i).Add(-12 * time.Hour).Format("20060102")
tm, err = time.Parse("20060102", dt)
if err != nil {
log.Error("time.Parse error(%v)", err)
return
}
t := tm.Unix()
timeSlice = append(timeSlice, t)
}
for _, v := range res { //映射原始时间戳集合
resMap[v.DateKey] = v.DateKey
}
if len(res) < 30 { //如果当前的数据不够30条则补齐30条
for _, v := range timeSlice {
if _, ok := resMap[v]; !ok { //当前时间戳不在原始时间戳集合存在则使用生成的时间戳
td := &data.ThirtyDay{
DateKey: v,
}
res = append(res, td)
}
if len(res) == 30 { //添加到30条为止
break
}
}
log.Info("s.data.ThirtyDayArchive append mid(%d) type(%d) return data(%+v)", mid, ty, res)
}
tds := make([]*data.ThirtyDay, 0, 30)
skeys := make([]int64, 0, 30)
tdMap := make(map[int64]int64)
for _, v := range res {
if v != nil {
tdMap[v.DateKey] = v.TotalIncr //设置时间戳和动态数据的键值对
skeys = append(skeys, v.DateKey) //获取时间戳集合
}
}
sort.Slice(skeys, func(i, j int) bool { //对时间戳做降序排列
return skeys[i] > skeys[j]
})
for _, k := range skeys { //按照排序好的时间戳组装最终的返回数据
if v, ok := tdMap[k]; ok {
td := &data.ThirtyDay{}
td.DateKey = k
td.TotalIncr = v
tds = append(tds, td)
if len(tds) == 30 { //只取30条
break
}
}
}
log.Info("s.data.ThirtyDayArchive mid(%d) type(%d) cache miss res(%+v)", mid, ty, tds)
res = tds
s.data.AddCache(func() {
s.data.AddThirtyDayArchiveCache(context.Background(), mid, tyStr, tds)
})
}
return
}

View File

@@ -0,0 +1,87 @@
package data
import (
"context"
"sort"
"time"
"go-common/app/interface/main/creative/model/data"
artmdl "go-common/app/interface/openplatform/article/model"
"go-common/library/log"
)
// ThirtyDayArticle for 30 days.
func (s *Service) ThirtyDayArticle(c context.Context, mid int64, ip string) (res []*artmdl.ThirtyDayArticle, err error) {
if res, err = s.data.ThirtyDayArticleCache(c, mid); err != nil && len(res) != 0 {
return
}
if res, err = s.art.ThirtyDayArticle(c, mid, ip); err != nil && res != nil {
s.data.AddCache(func() {
s.data.AddThirtyDayArticleCache(context.Background(), mid, res)
})
}
return
}
//ArtThirtyDay for article.
func (s *Service) ArtThirtyDay(c context.Context, mid int64, ty byte) (res []*data.ArtTrend, err error) {
if res, err = s.data.ArtThirtyDay(c, mid, ty); err != nil {
log.Error("s.data.ArtThirtyDay mid(%d)|err(%v)", mid, err)
}
return
}
//ArtRank for article rank.
func (s *Service) ArtRank(c context.Context, mid int64, ty byte) (res *data.ArtRankList, err error) {
daytime := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour)
dt := daytime.Format("20060102")
var ar *data.ArtRankMap
if ar, err = s.data.ArtRank(c, mid, ty, dt); err != nil {
log.Error("s.data.ArtRank mid(%d)|err(%v)", mid, err)
return
}
if ar == nil {
log.Info("s.data.ArtRank mid(%d) article rank(%+v)", mid, ar)
return
}
sortK := make([]int, 0, len(ar.AIDs))
aids := make([]int64, 0, len(ar.AIDs))
for k, v := range ar.AIDs {
aids = append(aids, v)
sortK = append(sortK, k)
}
artMap, _ := s.art.ArticleMetas(c, aids, "")
if len(artMap) == 0 {
return
}
arts := make([]*data.ArtMeta, 0, len(artMap))
sort.Ints(sortK)
for _, k := range sortK {
if aid, ok := ar.AIDs[k]; ok {
if a, ok := artMap[aid]; ok {
art := &data.ArtMeta{}
art.AID = a.ID
art.Title = a.Title
art.PTime = a.PublishTime
if v, ok := ar.Incrs[k]; ok {
art.Incr = v
}
arts = append(arts, art)
}
}
}
res = &data.ArtRankList{Arts: arts}
return
}
//ArtReadAnalysis for article.
func (s *Service) ArtReadAnalysis(c context.Context, mid int64) (res *data.ArtRead, err error) {
if res, err = s.data.ReadAnalysis(c, mid); err != nil {
log.Error("s.data.ReadAnalysis mid(%d)|err(%v)", mid, err)
}
return
}

View File

@@ -0,0 +1,143 @@
package data
import (
"context"
"sort"
"go-common/app/interface/main/creative/model/data"
"go-common/app/interface/main/creative/model/medal"
account "go-common/app/service/main/account/model"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
var (
rankKeys = []string{data.PlayDuration, data.VideoAct, data.DynamicAct}
)
// UpFansAnalysisForWeb get web fans data.
func (s *Service) UpFansAnalysisForWeb(c context.Context, mid int64, ip string) (res *data.WebFan, err error) {
var (
origin *data.WebFan
rkList map[string][]*data.RankInfo
mdlRank []*medal.FansRank
)
if origin, err = s.data.UpFansAnalysisForWeb(c, mid, data.Thirty); err != nil {
log.Error("s.data.UpFansAnalysisForWeb err(%v)", err)
return
}
if origin == nil {
return
}
group, ctx := errgroup.WithContext(c)
group.Go(func() (err error) {
if rkList, err = s.getTopList(ctx, mid, origin.RankMap, ip); err != nil {
log.Error("s.getTopList mid(%d)|err(%v)", mid, err)
err = nil
}
return
})
group.Go(func() (err error) {
if mdlRank, err = s.medal.Rank(ctx, mid); err != nil {
log.Error("s.medal.Rank mid(%d)|err(%v)", mid, err)
err = nil
}
return
})
group.Wait()
if len(rkList) == 0 {
log.Info("s.getTopList is empty rkList(%+v) ", rkList)
rkList = make(map[string][]*data.RankInfo)
}
for _, key := range rankKeys {
if v, ok := rkList[key]; ok {
rkList[key] = v
} else {
rkList[key] = nil
}
}
log.Info("s.getTopList rkList(%+v)|len(%d)", rkList, len(rkList))
res = &data.WebFan{
Summary: origin.Summary,
Source: origin.Source,
RankList: rkList,
RankMedal: map[string][]*medal.FansRank{
"medal": mdlRank,
},
}
return
}
// sort mid list and get uname/avatar info
func (s *Service) getTopList(c context.Context, mid int64, RankMap map[string]map[string]int32, ip string) (rkList map[string][]*data.RankInfo, err error) {
rkList = make(map[string][]*data.RankInfo)
for _, key := range rankKeys {
vd, ok := RankMap[key] //map playduration videoact dynamicact top10 mids.
if !ok {
continue
}
sortK := make([]string, 0, 10)
for key := range vd { //sort top mids by key, for example (dr2,dr1,dr3...)
sortK = append(sortK, key)
}
sort.Slice(sortK, func(i, j int) bool { //for example (dr1,dr2,dr3...)
return sortK[i] < sortK[j]
})
mids := make([]int64, 0, 10)
for _, k := range sortK { //get sort mids slice.
if mid, ok := vd[k]; ok {
mids = append(mids, int64(mid))
}
}
if len(mids) == 0 {
continue
}
var (
g, ctx = errgroup.WithContext(c)
users map[int64]*account.Info
followers map[int64]int
)
g.Go(func() error { //获取用户信息
if users, err = s.acc.Infos(ctx, mids, ip); err != nil {
log.Error("s.acc.Infos mid(%d)|mids(%v)|ip(%s)|err(%v)", mid, mids, ip, err)
}
return err
})
g.Go(func() error { //获取关注状态
if followers, err = s.acc.Relations2(ctx, mid, mids, ip); err != nil {
log.Error("s.acc.Relations mid(%d)|ip(%s)|err(%v)", mid, ip, err)
}
return err
})
if g.Wait() != nil {
return
}
rkInfos := make([]*data.RankInfo, 0, 10)
for _, m := range mids {
ri := &data.RankInfo{}
if v, ok := users[m]; ok { //get userinfo by sorted mids.
ri.MID = v.Mid
ri.Uname = v.Name
ri.Photo = v.Face
}
if fl, ok := followers[m]; ok { //get relation by sorted mids.
ri.Relation = fl
}
rkInfos = append(rkInfos, ri) //append top10 useinfo.
if len(rkInfos) == 10 {
break
}
}
rkList[key] = rkInfos //map playduration videoact dynamicact top10 userinfo.
}
log.Info("getTopList mid(%d)|rkList(%+v) ", mid, rkList)
return
}
//UpFansMedal for get fan medel count.
func (s *Service) UpFansMedal(c context.Context, mid int64) (fansMdl *data.UpFansMedal, err error) {
if fansMdl, err = s.data.UpFansMedal(c, mid); err != nil {
log.Error("s.data.UpFansMedal mid(%d)|err(%v)", mid, err)
}
return
}

View File

@@ -0,0 +1,354 @@
package data
import (
"context"
"sort"
"time"
"go-common/app/interface/main/creative/model/data"
"go-common/app/interface/main/creative/model/tag"
"go-common/library/ecode"
"go-common/library/log"
)
func beginningOfDay(t time.Time) time.Time {
d := time.Duration(-t.Hour()) * time.Hour
return t.Truncate(time.Hour).Add(d)
}
func getTuesday(now time.Time) time.Time {
t := beginningOfDay(now)
weekday := int(t.Weekday())
if weekday == 0 {
weekday = 7
}
d := time.Duration(-weekday+2) * 24 * time.Hour
return t.Truncate(time.Hour).Add(d)
}
func getSunday(now time.Time) time.Time {
t := beginningOfDay(now)
weekday := int(t.Weekday())
if weekday == 0 {
return t
}
d := time.Duration(7-weekday) * 24 * time.Hour
return t.Truncate(time.Hour).Add(d)
}
func getDate() (sd string) {
t := time.Now()
td := getTuesday(t).Add(12 * time.Hour)
if t.Before(td) { //当前时间在本周二12点之前则取上上周日的数据否则取上周日的数据
sd = getSunday(t.AddDate(0, 0, -14)).Format("20060102")
} else {
sd = getSunday(t.AddDate(0, 0, -7)).Format("20060102")
}
log.Info("current time (%s) tuesday (%s) sunday (%s)", t.Format("2006-01-02 15:04:05"), td, sd)
return
}
// NewStat get stat from hbase.
func (s *Service) NewStat(c context.Context, mid int64, ip string) (r *data.Stat, err error) {
hbaseDate1 := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
hbaseDate2 := time.Now().AddDate(0, 0, -2).Add(-12 * time.Hour).Format("20060102")
var r1, r2 *data.UpBaseStat
if r1, err = s.data.UpStat(c, mid, hbaseDate1); err != nil || r1 == nil {
log.Error("s.data.NewStat error(%v) mid(%d) r1(%v) ip(%s)", err, mid, r1, ip)
err = ecode.CreativeDataErr
return
}
if r2, err = s.data.UpStat(c, mid, hbaseDate2); err != nil || r2 == nil {
log.Error("s.data.NewStat error(%v) mid(%d) r2(%v) ip(%s)", err, mid, r2, ip)
err = ecode.CreativeDataErr
return
}
r = &data.Stat{}
if r1 != nil {
r.Play = r1.View
r.Dm = r1.Dm
r.Comment = r1.Reply
r.Fan = r1.Fans
r.Fav = r1.Fav
r.Like = r1.Like
r.Share = r1.Share
r.Coin = r1.Coin
r.Elec = r1.Elec
}
log.Info("s.data.UpStat hbaseDate1(%+v) mid(%d)", r1, mid)
if r2 != nil {
r.PlayLast = r2.View
r.DmLast = r2.Dm
r.CommentLast = r2.Reply
r.FanLast = r2.Fans
r.FavLast = r2.Fav
r.LikeLast = r2.Like
r.ShareLast = r2.Share
r.CoinLast = r2.Coin
r.ElecLast = r2.Elec
}
log.Info("s.data.UpStat hbaseDate2 (%+v) mid(%d)", r2, mid)
pfl, err := s.acc.ProfileWithStat(c, mid)
if err != nil {
return
}
r.Fan = int64(pfl.Follower)
return
}
// ViewerBase get up viewer base data.
func (s *Service) ViewerBase(c context.Context, mid int64) (res map[string]*data.ViewerBase, err error) {
dt := getDate()
// try cache
if res, _ = s.data.ViewerBaseCache(c, mid, dt); res != nil {
s.pCacheHit.Incr("viewer_base_cache")
return
}
// from data source
if res, err = s.data.ViewerBase(c, mid, dt); len(res) != 0 {
s.pCacheMiss.Incr("viewer_base_cache")
s.data.AddCache(func() {
s.data.AddViewerBaseCache(context.Background(), mid, dt, res)
})
}
return
}
// ViewerArea get up viewer area data.
func (s *Service) ViewerArea(c context.Context, mid int64) (res map[string]map[string]int64, err error) {
dt := getDate()
// try cache
if res, _ = s.data.ViewerAreaCache(c, mid, dt); res != nil {
s.pCacheHit.Incr("viewer_area_cache")
return
}
// from data source
if res, err = s.data.ViewerArea(c, mid, dt); len(res) != 0 {
s.pCacheMiss.Incr("viewer_area_cache")
s.data.AddCache(func() {
s.data.AddViewerAreaCache(context.Background(), mid, dt, res)
})
}
return
}
// CacheTrend get trend from mc.
func (s *Service) CacheTrend(c context.Context, mid int64) (res map[string]*data.ViewerTrend, err error) {
dt := getDate()
// try cache
if res, err = s.data.TrendCache(c, mid, dt); err != nil {
log.Error("trend s.data.TrendCache err(%v)", err)
return
}
if len(res) != 0 {
s.pCacheHit.Incr("trend_cache")
return
}
// from data source
if res, err = s.viewerTrend(c, mid, dt); err != nil {
return
}
s.pCacheMiss.Incr("trend_cache")
if len(res) != 0 {
s.data.AddCache(func() {
s.data.AddTrendCache(context.Background(), mid, dt, res)
})
}
return
}
// ViewerTrend get up viewer trend data.
func (s *Service) viewerTrend(c context.Context, mid int64, dt string) (res map[string]*data.ViewerTrend, err error) {
ut, err := s.data.ViewerTrend(c, mid, dt)
if err != nil || ut == nil {
log.Error("trend s.data.ViewerTrend err(%v)", err)
return
}
f := []string{"fan", "not_fan"}
skeys := make([]int, 0) //for tag sort.
tgs := make([]int64, 0) // for request tag name.
res = make(map[string]*data.ViewerTrend)
for _, fk := range f {
td := ut[fk]
vt := &data.ViewerTrend{}
if td == nil {
vt.Ty = nil
vt.Tag = nil
res[fk] = vt
continue
}
tg := make(map[int]string) //return tag map to user.
ty := make(map[string]int64) //return type map to user.
//deal type for type name.
if td.Ty != nil {
for k, v := range td.Ty {
ke := int16(k)
if t, ok := s.p.TypeMapCache[ke]; ok {
ty[t.Name] = v
}
}
} else {
ty = nil
}
// deal tag for tag name.
if td.Tag != nil {
for k, v := range td.Tag {
tgs = append(tgs, v)
skeys = append(skeys, k)
}
var tlist []*tag.Meta
if tlist, err = s.dtag.TagList(c, tgs); err != nil {
log.Error("trend s.dtag.TagList err(%v)", err)
}
tNameMap := make(map[int64]string)
for _, v := range tlist {
tNameMap[v.TagID] = v.TagName
}
for _, k := range skeys {
if _, ok := tNameMap[td.Tag[k]]; ok {
tg[k] = tNameMap[td.Tag[k]]
}
}
} else {
tg = nil
}
vt.Ty = ty
vt.Tag = tg
res[fk] = vt
}
return
}
// RelationFansDay get up viewer trend data.
func (s *Service) RelationFansDay(c context.Context, mid int64) (res map[string]map[string]int, err error) {
dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
// try cache
if res, _ = s.data.RelationFansDayCache(c, mid, dt); res != nil {
s.pCacheHit.Incr("relation_fans_day_cache")
return
}
// from data source
if res, err = s.data.RelationFansDay(c, mid); len(res) != 0 {
s.pCacheMiss.Incr("relation_fans_day_cache")
s.data.AddCache(func() {
s.data.AddRelationFansDayCache(context.Background(), mid, dt, res)
})
}
return
}
// RelationFansHistory get relation history data by month.
func (s *Service) RelationFansHistory(c context.Context, mid int64, month string) (res map[string]map[string]int, err error) {
if res, err = s.data.RelationFansHistory(c, mid, month); err != nil {
log.Error("s.data.RelationFansHistory err(%v)", err)
}
return
}
// RelationFansMonth get up viewer trend data.
func (s *Service) RelationFansMonth(c context.Context, mid int64) (res map[string]map[string]int, err error) {
dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
// try cache
if res, _ = s.data.RelationFansMonthCache(c, mid, dt); res != nil {
s.pCacheHit.Incr("relation_fans_month_cache")
return
}
// from data source
if res, err = s.data.RelationFansMonth(c, mid); len(res) != 0 {
s.pCacheMiss.Incr("relation_fans_month_cache")
s.data.AddCache(func() {
s.data.AddRelationFansMonthCache(context.Background(), mid, dt, res)
})
}
return
}
// ViewerActionHour get up viewer action hour data.
func (s *Service) ViewerActionHour(c context.Context, mid int64) (res map[string]*data.ViewerActionHour, err error) {
dt := getDate()
// try cache
if res, _ = s.data.ViewerActionHourCache(c, mid, dt); res != nil {
s.pCacheHit.Incr("viewer_action_hour_cache")
return
}
// from data source
if res, err = s.data.ViewerActionHour(c, mid, dt); len(res) != 0 {
s.data.AddCache(func() {
s.pCacheMiss.Incr("viewer_action_hour_cache")
s.data.AddViewerActionHourCache(context.Background(), mid, dt, res)
})
}
return
}
// UpIncr for Play/Dm/Reply/Fav/Share/Elec/Coin incr.
func (s *Service) UpIncr(c context.Context, mid int64, ty int8, ip string) (res map[string]*data.ViewerIncr, err error) {
tyStr, _ := data.IncrTy(ty)
res = make(map[string]*data.ViewerIncr)
daytime := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour)
datekey := daytime.Format("20060102")
dt := daytime.Format("20060102")
vic, _ := s.data.ViewerIncrCache(c, mid, tyStr, dt)
if vic != nil {
s.pCacheHit.Incr("viewer_incr_cache")
res[datekey] = vic
log.Info("s.data.ViewerIncrCache mid(%d) cache(%v) err(%v)", mid, vic, err)
return
}
incr, _ := s.data.UpIncr(c, mid, ty, dt)
if incr == nil {
res[datekey] = nil
log.Info("s.data.UpIncr mid(%d) incr(%v) err(%v)", incr, err)
return
}
tyRank := make(map[string]int) //return type map to user.
for k, v := range incr.Rank {
ke := int16(k)
if t, ok := s.p.TypeMapCache[ke]; ok {
tyRank[t.Name] = v
}
}
sortK := make([]int, 0, len(incr.TopAIDList))
aids := make([]int64, 0, len(incr.TopAIDList))
for k, v := range incr.TopAIDList {
aids = append(aids, v)
sortK = append(sortK, k)
}
avm, _ := s.p.BatchArchives(c, mid, aids, ip)
if len(avm) == 0 {
return
}
sort.Ints(sortK)
arcs := make([]*data.ArcInc, 0, len(avm))
for _, k := range sortK {
if aid, ok := incr.TopAIDList[k]; ok {
if av, ok := avm[aid]; ok {
al := &data.ArcInc{}
al.AID = av.Archive.Aid
al.PTime = av.Archive.PTime
al.Title = av.Archive.Title
al.DayTime = daytime.Unix()
if _, ok := incr.TopIncrList[k]; ok {
al.Incr = incr.TopIncrList[k]
}
arcs = append(arcs, al)
}
}
}
vi := &data.ViewerIncr{}
vi.Arcs = arcs
vi.TotalIncr = incr.Incr
if len(tyRank) == 0 {
vi.TyRank = nil
} else {
vi.TyRank = tyRank
}
res[datekey] = vi
// insert cache. NOTE: sync reason?
s.data.AddCache(func() {
s.pCacheMiss.Incr("viewer_incr_cache")
s.data.AddViewerIncrCache(context.Background(), mid, tyStr, dt, vi)
})
return
}

View File

@@ -0,0 +1,240 @@
package data
import (
"context"
"strings"
"go-common/app/interface/main/creative/conf"
"go-common/app/interface/main/creative/dao/account"
"go-common/app/interface/main/creative/dao/activity"
"go-common/app/interface/main/creative/dao/archive"
"go-common/app/interface/main/creative/dao/article"
"go-common/app/interface/main/creative/dao/bfs"
"go-common/app/interface/main/creative/dao/data"
"go-common/app/interface/main/creative/dao/medal"
"go-common/app/interface/main/creative/dao/tag"
arcMdl "go-common/app/interface/main/creative/model/archive"
dataMdl "go-common/app/interface/main/creative/model/data"
"go-common/app/interface/main/creative/service"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/stat/prom"
)
//Service struct
type Service struct {
c *conf.Config
data *data.Dao
acc *account.Dao
arc *archive.Dao
art *article.Dao
dtag *tag.Dao
dbfs *bfs.Dao
medal *medal.Dao
act *activity.Dao
p *service.Public
pCacheHit *prom.Prom
pCacheMiss *prom.Prom
}
//New get service
func New(c *conf.Config, rpcdaos *service.RPCDaos, p *service.Public) *Service {
s := &Service{
c: c,
data: data.New(c),
acc: rpcdaos.Acc,
arc: rpcdaos.Arc,
art: rpcdaos.Art,
dtag: tag.New(c),
dbfs: bfs.New(c),
medal: medal.New(c),
act: activity.New(c),
p: p,
pCacheHit: prom.CacheHit,
pCacheMiss: prom.CacheMiss,
}
return s
}
// Stat get stat.
func (s *Service) Stat(c context.Context, mid int64, ip string) (r *dataMdl.Stat, err error) {
if r, err = s.data.Stat(c, ip, mid); err != nil {
return
}
pfl, err := s.acc.ProfileWithStat(c, mid)
if err != nil {
return
}
r.Fan = int64(pfl.Follower)
return
}
// Tags get predict tag.
func (s *Service) Tags(c context.Context, mid int64, tid uint16, title, filename, desc, cover string, tagFrom int8) (res *dataMdl.Tags, err error) {
res = &dataMdl.Tags{
Tags: make([]string, 0),
}
var ctags []*dataMdl.CheckedTag
ctags, err = s.TagsWithChecked(c, mid, tid, title, filename, desc, cover, tagFrom)
if len(ctags) > 0 {
for _, t := range ctags {
res.Tags = append(res.Tags, t.Tag)
}
}
return
}
// TagsWithChecked get predict tag with checked mark.
func (s *Service) TagsWithChecked(c context.Context, mid int64, tid uint16, title, filename, desc, cover string, tagFrom int8) (retTags []*dataMdl.CheckedTag, err error) {
retTags = make([]*dataMdl.CheckedTag, 0)
var checkedTags []*dataMdl.CheckedTag
if checkedTags, err = s.data.TagsWithChecked(c, mid, tid, title, filename, desc, cover, tagFrom); err != nil {
log.Error("s.data.TagsWithChecked error(%v)", err)
err = nil
}
// no recommend tag, return
if len(checkedTags) == 0 {
return
}
actTagsMap := make(map[string]int64)
acts, _ := s.act.Activities(c)
// no acts, no filter and return
if len(acts) == 0 {
retTags = checkedTags
return
}
// filter act tags
for _, act := range acts {
tagsSlice := strings.Split(act.Tags, ",")
if len(tagsSlice) > 0 {
for _, tag := range tagsSlice {
actTagsMap[tag] = act.ID
}
}
actTagsMap[act.Name] = act.ID
}
for _, checkedTag := range checkedTags {
if _, ok := actTagsMap[checkedTag.Tag]; !ok {
retTags = append(retTags, checkedTag)
}
}
return
}
// VideoQuitPoints get video quit data.
func (s *Service) VideoQuitPoints(c context.Context, cid, mid int64, ip string) (res []int64, err error) {
// check cid owner
isWhite := false
for _, m := range s.c.Whitelist.DataMids {
if m == mid {
isWhite = true
break
}
}
if !isWhite {
var video *arcMdl.Video
if video, err = s.arc.VideoByCid(c, int64(cid), ip); err != nil {
err = ecode.AccessDenied
return
}
if arc, errr := s.arc.Archive(c, video.Aid, ip); errr == nil {
if arc.Author.Mid != mid {
err = ecode.AccessDenied
return
}
}
}
res, err = s.data.VideoQuitPoints(c, cid)
return
}
// ArchiveStat get video quit data.
func (s *Service) ArchiveStat(c context.Context, aid, mid int64, ip string) (stat *dataMdl.ArchiveData, err error) {
// check aid valid and owner
isWhite := false
for _, m := range s.c.Whitelist.DataMids {
if m == mid {
isWhite = true
break
}
}
if !isWhite {
a, re := s.arc.Archive(c, aid, ip)
if re != nil {
err = re
return
}
if a == nil {
log.Warn("arc not exist")
err = ecode.AccessDenied
return
}
if a.Author.Mid != mid {
log.Warn("owner mid(%d) and viewer mid(%d) are different ", a.Author.Mid, mid)
err = ecode.AccessDenied
return
}
}
if stat, err = s.data.ArchiveStat(c, aid); err != nil {
return
}
if stat == nil {
return
}
if stat.ArchiveStat != nil && stat.ArchiveStat.Play >= 100 {
if stat.ArchiveAreas, err = s.data.ArchiveArea(c, aid); err != nil {
log.Error(" s.data.ArchiveArea aid(%d)|mid(%d), err(%+v)", aid, mid, err)
return
}
}
//获取播放数据
if stat.ArchivePlay, err = s.data.UpArcPlayAnalysis(c, aid); err != nil {
log.Error(" s.data.UpArcPlayAnalysis aid(%d)|mid(%d), err(%+v)", aid, mid, err)
return
}
return
}
// Covers get covers from ai
func (s *Service) Covers(c context.Context, mid int64, fns []string, ip string) (cvs []string, err error) {
if cvs, err = s.data.RecommendCovers(c, mid, fns); err != nil {
log.Error("s.data.RecommendCovers err(%v)", mid, err)
return
}
return
}
// Ping service
func (s *Service) Ping(c context.Context) (err error) {
if err = s.data.Ping(c); err != nil {
log.Error("s.data.Dao.PingDb err(%v)", err)
}
return
}
// Close dao
func (s *Service) Close() {
s.data.Close()
}
// IsWhite check white.
func (s *Service) IsWhite(mid int64) (isWhite bool) {
for _, m := range s.c.Whitelist.DataMids {
if m == mid {
isWhite = true
break
}
}
return
}
// IsForbidVideoup fn.
func (s *Service) IsForbidVideoup(mid int64) (isForbid bool) {
for _, m := range s.c.Whitelist.ForbidVideoupMids {
if m == mid {
isForbid = true
break
}
}
return
}

View File

@@ -0,0 +1,154 @@
package data
import (
"context"
"flag"
"go-common/app/interface/main/creative/conf"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/creative/service"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
p *service.Public
)
func init() {
dir, _ := filepath.Abs("../../cmd/creative.toml")
flag.Set("conf", dir)
conf.Init()
rpcdaos := service.NewRPCDaos(conf.Conf)
p = service.New(conf.Conf, rpcdaos)
s = New(conf.Conf, rpcdaos, p)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
Reset(func() {})
f(s)
}
}
var (
c = context.TODO()
MID = int64(27515256)
ty = int8(1)
ip = "127.0.0.1"
dt = "20180301"
)
func Test_AppStat(t *testing.T) {
Convey("AppStat", t, WithService(func(s *Service) {
Convey("AppStat", func() {
res, err := s.AppStat(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_ViewerBase(t *testing.T) {
Convey("ViewerBase", t, WithService(func(s *Service) {
Convey("ViewerBase", func() {
res, err := s.ViewerBase(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_ViewerArea(t *testing.T) {
Convey("ViewerArea", t, WithService(func(s *Service) {
Convey("ViewerArea", func() {
res, err := s.ViewerArea(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_CacheTrend(t *testing.T) {
Convey("CacheTrend", t, WithService(func(s *Service) {
Convey("CacheTrend", func() {
res, err := s.CacheTrend(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_RelationFansHistory(t *testing.T) {
Convey("RelationFansHistory", t, WithService(func(s *Service) {
Convey("RelationFansHistory", func() {
res, err := s.RelationFansHistory(c, MID, dt)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_RelationFansMonth(t *testing.T) {
Convey("RelationFansMonth", t, WithService(func(s *Service) {
Convey("RelationFansMonth", func() {
res, err := s.RelationFansMonth(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_ViewerActionHour(t *testing.T) {
Convey("ViewerActionHour", t, WithService(func(s *Service) {
Convey("ViewerActionHour", func() {
res, err := s.ViewerActionHour(c, MID)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_UpIncr(t *testing.T) {
Convey("UpIncr", t, WithService(func(s *Service) {
Convey("UpIncr", func() {
res, err := s.UpIncr(c, MID, ty, ip)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_AppUpIncr(t *testing.T) {
Convey("AppUpIncr", t, WithService(func(s *Service) {
Convey("AppUpIncr", func() {
res, err := s.AppUpIncr(c, MID, ty, ip)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_ThirtyDayArchive(t *testing.T) {
Convey("ThirtyDayArchive", t, WithService(func(s *Service) {
Convey("ThirtyDayArchive", func() {
res, err := s.ThirtyDayArchive(c, MID, ty)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}
func Test_ThirtyDayArticle(t *testing.T) {
Convey("ThirtyDayArticle", t, WithService(func(s *Service) {
Convey("ThirtyDayArticle", func() {
res, err := s.ThirtyDayArticle(c, MID, ip)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}))
}