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.
293 lines
7.3 KiB
293 lines
7.3 KiB
package statistics |
|
|
|
import ( |
|
"fmt" |
|
"server/call" |
|
"server/common" |
|
"server/db" |
|
"server/modules/backend/app" |
|
"server/modules/backend/models" |
|
"server/modules/backend/util" |
|
"server/modules/backend/values" |
|
utils "server/util" |
|
"sync" |
|
"time" |
|
|
|
"github.com/gin-gonic/gin" |
|
"github.com/liangdas/mqant/log" |
|
"github.com/olivere/elastic/v7" |
|
) |
|
|
|
type OutputDataReq struct { |
|
Start string `json:"Start" binding:"required"` |
|
End string `json:"End" binding:"required"` |
|
Page int `json:"Page" binding:"required"` |
|
Num int `json:"Num" binding:"required"` |
|
Channel int `json:"Channel"` |
|
} |
|
|
|
type OutputDataResp struct { |
|
Titles []string |
|
Count int64 |
|
AllData []OneOutputData |
|
Total OneOutputData |
|
} |
|
|
|
type OneOutputData struct { |
|
Date string |
|
Time int64 |
|
Data map[string]string |
|
} |
|
|
|
// OutputData 获取产出统计 |
|
func OutputData(c *gin.Context) { |
|
a := app.NewApp(c) |
|
defer func() { |
|
a.Response() |
|
}() |
|
req := new(OutputDataReq) |
|
if !a.S(req) { |
|
return |
|
} |
|
log.Debug("OutputDataReq:%+v", req) |
|
if req.Page < 1 { |
|
a.Code = values.CodeParam |
|
return |
|
} |
|
resp := &OutputDataResp{} |
|
for i := common.CurrencyEventZero + 1; i < common.CurrencyEventAll; i++ { |
|
if i == common.CurrencyEventMailDraw || i == common.CurrencyEventBindPhone || i == common.CurrencyEventActivityAppSpin { |
|
continue |
|
} |
|
resp.Titles = append(resp.Titles, common.GetCurrencyTypeName(i)) |
|
} |
|
a.Data = resp |
|
var oneDay int64 = 24 * 60 * 60 |
|
|
|
su, eu := util.GetQueryUnix(req.Start, req.End) |
|
if req.Num > 60 { |
|
a.Code = values.CodeParam |
|
return |
|
} |
|
resp.Count = (eu - su) / oneDay |
|
|
|
start := eu - int64(req.Page-1)*int64(req.Num)*oneDay |
|
end := start - int64(req.Num)*oneDay |
|
if end < su { |
|
end = su |
|
} |
|
count := (start - end) / oneDay |
|
group := new(sync.WaitGroup) |
|
group.Add(int(count)) |
|
resp.AllData = make([]OneOutputData, count) |
|
resp.Total = OneOutputData{ |
|
Data: models.GetOutputData(su, eu, req.Channel, 0), |
|
} |
|
step := 0 |
|
for i := start - oneDay; i >= end; i -= oneDay { |
|
tmp := step |
|
t := i |
|
utils.Go(func() { |
|
resp.AllData[tmp] = OneOutputData{ |
|
Date: time.Unix(t, 0).Format("20060102"), |
|
Time: t, |
|
Data: models.GetOutputData(t, t+oneDay, req.Channel, 0)} |
|
|
|
group.Done() |
|
}) |
|
step++ |
|
} |
|
group.Wait() |
|
} |
|
|
|
// func GetOutputData(su, eu int64, cid int) map[string]string { |
|
// ret := map[string]string{} |
|
// q := elastic.NewBoolQuery() |
|
// q.Filter(elastic.NewRangeQuery("time").Gte(su)) |
|
// q.Filter(elastic.NewRangeQuery("time").Lt(eu)) |
|
// if cid > 0 { |
|
// q.Filter(elastic.NewTermsQuery("channel_id", cid)) |
|
// } |
|
// buk := &common.GroupSumBuckets{} |
|
// db.ES().GroupSumBy(common.ESIndexBalance, "event", q, buk, "", false, 0, "value") |
|
// for _, v := range buk.Buckets { |
|
// ret[common.GetCurrencyTypeName(common.CurrencyEvent(utils.GetInt(v.Key)))] = utils.RoundFloat(v.Value.Value/common.DecimalDigits, 2) |
|
// } |
|
// return ret |
|
// } |
|
|
|
type OutputDataProviderReq struct { |
|
Start string `json:"Start" binding:"required"` |
|
End string `json:"End" binding:"required"` |
|
Channel int `json:"Channel"` |
|
Page int `json:"Page" binding:"required"` |
|
Num int `json:"Num" binding:"required"` |
|
} |
|
|
|
type OutputDataProviderResp struct { |
|
Count int64 |
|
Titles []string |
|
GameProviderData []OneOutputProviderData |
|
Total OneOutputProviderData |
|
} |
|
|
|
type OneOutputProviderData struct { |
|
Date string |
|
Time int64 |
|
Data []OneProviderData |
|
} |
|
|
|
type OneProviderData struct { |
|
ProviderID int |
|
ProviderName string |
|
Value string |
|
} |
|
|
|
// OutputDataProvider 厂商产出统计 |
|
func OutputDataProvider(c *gin.Context) { |
|
a := app.NewApp(c) |
|
defer func() { |
|
a.Response() |
|
}() |
|
req := new(OutputDataProviderReq) |
|
if !a.S(req) { |
|
return |
|
} |
|
log.Debug("OutputDataProviderReq:%+v", req) |
|
if req.Page < 1 { |
|
a.Code = values.CodeParam |
|
return |
|
} |
|
resp := &OutputDataProviderResp{} |
|
a.Data = resp |
|
for i := common.ProviderZero + 1; i < common.ProviderAll; i++ { |
|
if i > common.ProviderEvolutionGaming && i != common.ProviderPragmaticPlay && i != common.ProviderIBC && i != common.ProviderPlayStar { |
|
continue |
|
} |
|
provider := call.GetConfigGameProvider(i) |
|
if provider == nil { |
|
continue |
|
} |
|
resp.Titles = append(resp.Titles, provider.ProviderName) |
|
} |
|
var oneDay int64 = 24 * 60 * 60 |
|
|
|
su, eu := util.GetQueryUnix(req.Start, req.End) |
|
if req.Num > 60 { |
|
a.Code = values.CodeParam |
|
return |
|
} |
|
resp.Count = (eu - su) / (24 * 60 * 60) |
|
|
|
start := eu - int64(req.Page-1)*int64(req.Num)*oneDay |
|
end := start - int64(req.Num)*oneDay |
|
if end < su { |
|
end = su |
|
} |
|
group := new(sync.WaitGroup) |
|
count := (start - end) / oneDay |
|
group.Add(int(count)) |
|
resp.GameProviderData = make([]OneOutputProviderData, count) |
|
resp.Total = OneOutputProviderData{ |
|
Data: GetOutputProviderData(su, eu, req.Channel), |
|
} |
|
step := 0 |
|
for i := start - oneDay; i >= end; i -= oneDay { |
|
tmp := step |
|
t := i |
|
utils.Go(func() { |
|
resp.GameProviderData[tmp] = OneOutputProviderData{ |
|
Date: time.Unix(t, 0).Format("20060102"), |
|
Time: t, |
|
Data: GetOutputProviderData(t, t+oneDay, req.Channel), |
|
} |
|
group.Done() |
|
}) |
|
step++ |
|
} |
|
group.Wait() |
|
} |
|
|
|
func GetOutputProviderData(su, eu int64, cid int) []OneProviderData { |
|
ret := []OneProviderData{} |
|
q := elastic.NewBoolQuery() |
|
q.Filter(elastic.NewRangeQuery("time").Gte(su)) |
|
q.Filter(elastic.NewRangeQuery("time").Lt(eu)) |
|
if cid > 0 { |
|
q.Filter(elastic.NewTermsQuery("channel_id", cid)) |
|
} |
|
buk := &common.GroupSumBuckets{} |
|
q.Filter(elastic.NewTermsQuery("event", common.GetGameEvents()...)) |
|
db.ES().GroupSumBy(common.ESIndexBalance, "exi1", q, buk, "", false, 0, "value") |
|
for _, v := range buk.Buckets { |
|
provider := call.GetConfigGameProvider(utils.GetInt(v.Key)) |
|
if provider == nil { |
|
continue |
|
} |
|
ret = append(ret, OneProviderData{ |
|
ProviderID: provider.ProviderID, |
|
ProviderName: provider.ProviderName, |
|
Value: utils.RoundFloat(v.Value.Value/common.DecimalDigits, 2), |
|
}) |
|
} |
|
return ret |
|
} |
|
|
|
type OutputDataGamesReq struct { |
|
Start string `json:"Start" binding:"required"` |
|
End string `json:"End" binding:"required"` |
|
Channel int `json:"Channel"` |
|
ProviderID int `json:"ProviderID"` |
|
} |
|
|
|
type OutputDataGamesResp struct { |
|
GameData map[string]struct { |
|
Count int64 |
|
Value string |
|
} |
|
} |
|
|
|
func OutputDataGames(c *gin.Context) { |
|
a := app.NewApp(c) |
|
defer func() { |
|
a.Response() |
|
}() |
|
req := new(OutputDataGamesReq) |
|
if !a.S(req) { |
|
return |
|
} |
|
log.Debug("OutputDataGamesReq:%+v", req) |
|
resp := &OutputDataGamesResp{ |
|
GameData: make(map[string]struct { |
|
Count int64 |
|
Value string |
|
}), |
|
} |
|
a.Data = resp |
|
su, eu := util.GetQueryUnix(req.Start, req.End) |
|
q := elastic.NewBoolQuery() |
|
q.Filter(elastic.NewRangeQuery("time").Gte(su)) |
|
q.Filter(elastic.NewRangeQuery("time").Lt(eu)) |
|
q.Filter(elastic.NewTermsQuery("event", common.GetGameEvents()...)) |
|
if req.Channel > 0 { |
|
q.Filter(elastic.NewTermQuery("channel_id", req.Channel)) |
|
} |
|
if req.ProviderID > 0 { |
|
q.Filter(elastic.NewTermQuery("exi1", req.ProviderID)) |
|
} |
|
buk := &common.GroupSumBuckets{} |
|
db.ES().GroupSumBy(common.ESIndexBalance, "exi2", q, buk, "", false, 0, "value") |
|
for _, v := range buk.Buckets { |
|
thisGame := call.GetConfigGameListByID(req.ProviderID, utils.GetInt(v.Key)) |
|
if thisGame == nil { |
|
continue |
|
} |
|
resp.GameData[fmt.Sprintf("%s(%d)", thisGame.Name, thisGame.GameID)] = struct { |
|
Count int64 |
|
Value string |
|
}{ |
|
Count: utils.GetInt64(v.Doc_count), |
|
Value: utils.RoundFloat(v.Value.Value/common.DecimalDigits, 2), |
|
} |
|
} |
|
}
|
|
|