印度包网
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

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),
}
}
}