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.
294 lines
7.3 KiB
294 lines
7.3 KiB
|
1 year ago
|
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),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|