statistics文件下载

This commit is contained in:
sk 2024-12-26 08:26:00 +08:00
parent 82887c39c1
commit 0cc66a8b28
6 changed files with 269 additions and 117 deletions

12
go.mod
View File

@ -92,7 +92,7 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6 // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.etcd.io/etcd/api/v3 v3.5.16 // indirect
@ -103,12 +103,12 @@ require (
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.7.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect

11
go.sum
View File

@ -388,6 +388,8 @@ github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2
github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6 h1:8m6DWBG+dlFNbx5ynvrE7NgI+Y7OlZVMVTpayoW+rCc=
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE=
github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
@ -441,6 +443,8 @@ golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
@ -477,6 +481,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -489,6 +495,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -518,6 +525,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -530,6 +539,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=

View File

@ -1,7 +1,8 @@
#StartTime: "2024-12-19T00:00:00+08:00"
#EndTime: "2024-12-20T00:00:00+08:00"
StartTime: "2024-12-25T00:00:00+08:00"
EndTime: "2024-12-26T00:00:00+08:00"
IsDatabaseMode: true
ListenPort: 8888
Switch: # 1: open, 0: close
- 1 # 新用户游戏破产率

View File

@ -1,7 +1,6 @@
package main
import (
"errors"
"fmt"
"golang.org/x/exp/maps"
"strings"
@ -18,6 +17,10 @@ type ExcelData struct {
Head []string
Index int
IndexCell int
TableName string
TableHead []string
DataName string
}
func (e *ExcelData) SetHead(head []string) *ExcelData {
@ -67,13 +70,26 @@ func NewExcelMgr() *ExcelMgr {
}
}
func (e *ExcelMgr) Register(id int, head []string) *ExcelData {
func (e *ExcelMgr) Register(id int, head []string, filename string) *ExcelData {
e.List[id] = &ExcelData{
File: excelize.NewFile(),
Head: head,
Index: 0,
}
name := ChineseToPinYin([]string{filename})
if len(name) == 0 {
return nil
}
tableName := fmt.Sprintf("task_%s", name[0])
e.List[id].TableName = tableName
for _, v := range head {
cl := ChineseToPinYin([]string{v})[0]
e.List[id].TableHead = append(e.List[id].TableHead, cl)
}
e.List[id].DataName = filename
e.List[id].NewSheet("Sheet1")
if len(head) > 0 {
@ -87,12 +103,14 @@ func (e *ExcelMgr) Get(id int) *ExcelData {
return e.List[id]
}
func (e *ExcelMgr) Save(id int, fileName string) error {
func (e *ExcelMgr) Save(id int, startTime, endTime string) error {
d := e.List[id]
if d == nil {
return nil
}
filename := fmt.Sprintf("%s_%s_%s.xlsx", d.DataName, startTime, endTime)
if VP.GetBool("IsDatabaseMode") {
rows, err := d.GetRows("Sheet1")
if err != nil {
@ -105,30 +123,25 @@ func (e *ExcelMgr) Save(id int, fileName string) error {
return err
}
list := strings.Split(fileName, "_")
name := ChineseToPinYin(list)
if len(name) == 0 {
return errors.New("tableName is empty")
}
tableName := fmt.Sprintf("task_%s", name[0])
files := make(map[string]string)
index := make(map[string]string)
for _, v := range d.Head {
cl := ChineseToPinYin([]string{v})[0]
d.TableHead = append(d.TableHead, cl)
files[cl] = v
if strings.Contains(v, "*") {
index[cl] = "INDEX"
}
}
createSQL := buildCreateTableSQLWithIndices(tableName, list[0], files, index)
createSQL := buildCreateTableSQLWithIndices(d.TableName, d.DataName, files, index)
if err = db.Exec(createSQL).Error; err != nil {
logger.Logger.Errorf("createTable error: %v", err)
return err
}
if err = insertData(db.DB, tableName, maps.Keys(files), rows); err != nil {
if err = insertData(db.DB, d.TableName, maps.Keys(files), rows); err != nil {
logger.Logger.Errorf("insertData error: %v", err)
return err
}
@ -136,7 +149,49 @@ func (e *ExcelMgr) Save(id int, fileName string) error {
return nil
}
return d.SaveAs(fileName)
return d.SaveAs(filename)
}
func (e *ExcelMgr) Pull(id int, startTime, endTime string) (*excelize.File, string, error) {
d := e.List[id]
if d == nil {
return nil, "", nil
}
db, err := mysqlx.GetDatabase("1")
if err != nil {
logger.Logger.Errorf("GetDatabase error: %v", err)
return nil, "", err
}
rows, err := db.Table(d.TableName).Where("ri_qi between ? and ?", startTime, endTime).Select(d.TableHead).Rows()
if err != nil {
logger.Logger.Errorf("Pull error: %v", err)
return nil, "", err
}
defer rows.Close()
f := excelize.NewFile()
f.NewSheet("Sheet1")
f.SetSheetRow("Sheet1", "A1", &d.Head)
index := 2
for rows.Next() {
data := make([]interface{}, len(d.TableHead))
scanArgs := make([]interface{}, len(d.TableHead))
for i := range data {
scanArgs[i] = &data[i]
}
err = rows.Scan(scanArgs...)
if err != nil {
logger.Logger.Errorf("Pull error: %v", err)
return nil, "", err
}
f.SetSheetRow("Sheet1", "A"+fmt.Sprintf("%d", index), &data)
index++
}
return f, fmt.Sprintf("%s_%s_%s", d.DataName, startTime, endTime), nil
}
// 构建创建表的 SQL 语句,支持中文描述和索引

View File

@ -0,0 +1,51 @@
package main
import (
"net/http"
"strconv"
)
/*
下载
GET http://127.0.0.1:8888/statistics/task?data_type=0&start_time=2024-12-26&end_time=2024-12-26
请求参数
data_type 数据类型
0新用户游戏破产率
1新用户平均游戏时长
2用户平均游戏时长
3新用户平均局数
4平均倍数
5活跃破产率
start_time 开始时间
end_time 结束时间
*/
// Download 下载
func Download(w http.ResponseWriter, r *http.Request) {
// 请求参数
// data_type 数据类型
// start_time 开始时间
// end_time 结束时间
// Request parameters
dataType, err := strconv.Atoi(r.URL.Query().Get("data_type"))
if err != nil {
http.Error(w, "Invalid data_type", http.StatusBadRequest)
return
}
startTime := r.URL.Query().Get("start_time")
endTime := r.URL.Query().Get("end_time")
f, name, err := ExcelMgrSingle.Pull(dataType, startTime, endTime)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer f.Close()
w.Header().Set("Content-Type", "application/octet-stream;charset=UTF-8")
w.Header().Set("Content-Disposition", "attachment; filename=\""+name+".xlsx\"")
f.Write(w)
}

View File

@ -2,6 +2,10 @@ package main
import (
"fmt"
"mongo.games.com/goserver/core/utils"
"net/http"
"os"
"os/signal"
"sort"
"time"
@ -31,6 +35,86 @@ const (
)
var VP *viper.Viper
var ExcelMgrSingle *ExcelMgr
func run() {
if VP.GetBool("IsDatabaseMode") {
VP.Set("StartTime", common.HMSToTime(0, 0, 0).Format(time.RFC3339))
VP.Set("EndTime", common.HMSToTime(0, 0, 0).AddDate(0, 0, 1).Format(time.RFC3339))
}
startTime, err := time.Parse(time.RFC3339, VP.GetString("StartTime"))
if err != nil {
panic(fmt.Sprintf("time.Parse err: %v", err))
return
}
endTime, err := time.Parse(time.RFC3339, VP.GetString("EndTime"))
if err != nil {
panic(fmt.Sprintf("time.Parse err: %v", err))
return
}
switchArr := VP.GetIntSlice("Switch")
for {
if startTime.Unix() >= endTime.Unix() {
break
}
startTimeStr := startTime.Format(time.RFC3339)
et := startTime.AddDate(0, 0, 1)
endTimeStr := et.Format(time.RFC3339)
logger.Logger.Infof("startTime: %v endTime: %v", startTimeStr, endTimeStr)
if switchArr[ExcelTypeNewPlayerBankrupt] == 1 {
// 新用户游戏破产率
ExcelMgrSingle.GenNewPlayerBankruptRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameTimeAvg] == 1 {
// 新用户平均游戏时长
ExcelMgrSingle.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
// 用户平均游戏时长
ExcelMgrSingle.GenPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameCountAvg] == 1 {
// 新用户平均局数
ExcelMgrSingle.GenGameCountExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameRate] == 1 {
// 平均倍数
ExcelMgrSingle.GenGameRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeActiveRate] == 1 {
// 活跃破产率
ExcelMgrSingle.GenActiveBankruptRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeCtrlWinRate] == 1 {
// 控赢胜率
ExcelMgrSingle.GenCtrlWinRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeRobotWinRate] == 1 {
// 机器人胜率
ExcelMgrSingle.GenRobotWinRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeCoinAvg] == 1 {
// 人均获得金币
ExcelMgrSingle.GenCoinAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeBankruptOffline] == 1 {
// 破产后离线
ExcelMgrSingle.GenBankruptOfflineExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeOfflineCoin] == 1 {
// 离线金币
ExcelMgrSingle.GenOfflineCoinExcel("1", startTimeStr, endTimeStr)
}
startTime = et
}
ExcelMgrSingle.SaveAll(VP.GetString("StartTime")[:10], endTime.AddDate(0, 0, -1).Format(time.DateOnly))
}
func main() {
defer func() {
@ -60,134 +144,84 @@ func main() {
mysqlx.Init(myConf)
defer mysqlx.Close()
if VP.GetString("StartTime") == "" {
VP.Set("StartTime", common.HMSToTime(0, 0, 0).Format(time.RFC3339))
}
if VP.GetString("EndTime") == "" {
VP.Set("EndTime", common.HMSToTime(0, 0, 0).AddDate(0, 0, 1).Format(time.RFC3339))
}
startTime, err := time.Parse(time.RFC3339, VP.GetString("StartTime"))
if err != nil {
panic(fmt.Sprintf("time.Parse err: %v", err))
return
}
endTime, err := time.Parse(time.RFC3339, VP.GetString("EndTime"))
if err != nil {
panic(fmt.Sprintf("time.Parse err: %v", err))
return
}
mgr := NewExcelMgr()
mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期*", "场次id*", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeGameTimeAvg, []string{"日期*", "场次id*", "参与人数", "平均游戏时长"})
mgr.Register(ExcelTypeGameTimeAllAvg, []string{"日期*", "场次id*", "参与人数", "平均游戏时长"})
mgr.Register(ExcelTypeGameCountAvg, []string{"日期*", "场次id*", "参与人数", "平均局数"})
mgr.Register(ExcelTypeGameRate, []string{"日期*", "场次id*", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeActiveRate, []string{"日期*", "场次id*", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeCtrlWinRate, []string{"日期*", "场次id*", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeCtrlWinRate*10, []string{"日期*", "场次id*", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeRobotWinRate, []string{"日期*", "场次id*", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeCoinAvg, []string{"日期*", "场次id*", "参与人数", "人均获得金币"})
mgr.Register(ExcelTypeBankruptOffline, []string{"日期*", "场次id*", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeOfflineCoin, []string{"日期*", "场次id*", "破产人数", "参与人数", "破产率"})
switchArr := VP.GetIntSlice("Switch")
ExcelMgrSingle = mgr
mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "新用户破产率")
mgr.Register(ExcelTypeGameTimeAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"}, "新用户平均游戏时长")
mgr.Register(ExcelTypeGameTimeAllAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"}, "用户平均游戏时长")
mgr.Register(ExcelTypeGameCountAvg, []string{"日期", "场次id", "参与人数", "平均局数"}, "新用户平均局数")
mgr.Register(ExcelTypeGameRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "平均倍数")
mgr.Register(ExcelTypeActiveRate, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "活跃破产率")
mgr.Register(ExcelTypeCtrlWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "控赢胜率")
mgr.Register(ExcelTypeCtrlWinRate*10, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "控数胜率")
mgr.Register(ExcelTypeRobotWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "机器人输率")
mgr.Register(ExcelTypeCoinAvg, []string{"日期", "场次id", "参与人数", "人均获得金币"}, "人均获得金币")
mgr.Register(ExcelTypeBankruptOffline, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "破产后离线")
mgr.Register(ExcelTypeOfflineCoin, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "离线金币")
for {
if startTime.Unix() >= endTime.Unix() {
break
if VP.GetBool("IsDatabaseMode") {
// 每天凌晨执行一次 run方法
var f func()
f = func() {
nextTime := common.HMSToTime(0, 0, 0).AddDate(0, 0, 1)
time.AfterFunc(nextTime.Sub(time.Now())+time.Second*10, func() {
go utils.RepeatUntilPanicless(run)
f()
})
}
startTimeStr := startTime.Format(time.RFC3339)
et := startTime.AddDate(0, 0, 1)
endTimeStr := et.Format(time.RFC3339)
logger.Logger.Infof("startTime: %v endTime: %v", startTimeStr, endTimeStr)
f()
//run()
if switchArr[ExcelTypeNewPlayerBankrupt] == 1 {
// 新用户游戏破产率
mgr.GenNewPlayerBankruptRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameTimeAvg] == 1 {
// 新用户平均游戏时长
mgr.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
// 用户平均游戏时长
mgr.GenPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameCountAvg] == 1 {
// 新用户平均局数
mgr.GenGameCountExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameRate] == 1 {
// 平均倍数
mgr.GenGameRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeActiveRate] == 1 {
// 活跃破产率
mgr.GenActiveBankruptRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeCtrlWinRate] == 1 {
// 控赢胜率
mgr.GenCtrlWinRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeRobotWinRate] == 1 {
// 机器人胜率
mgr.GenRobotWinRateExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeCoinAvg] == 1 {
// 人均获得金币
mgr.GenCoinAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeBankruptOffline] == 1 {
// 破产后离线
mgr.GenBankruptOfflineExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeOfflineCoin] == 1 {
// 离线金币
mgr.GenOfflineCoinExcel("1", startTimeStr, endTimeStr)
}
listenPort := VP.GetString("ListenPort")
http.HandleFunc("/statistics/task", Download)
go http.ListenAndServe(fmt.Sprintf(":%v", listenPort), nil)
startTime = et
logger.Logger.Infof("start server 0.0.0.0:%v", listenPort)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
sig := <-c
logger.Logger.Infof("closing down (signal: %v)", sig)
} else {
run()
}
mgr.SaveAll(VP.GetString("StartTime")[:10], endTime.AddDate(0, 0, -1).Format(time.DateOnly))
}
func (e *ExcelMgr) SaveAll(startTime, endTime string) {
switchArr := VP.GetIntSlice("Switch")
if switchArr[ExcelTypeNewPlayerBankrupt] == 1 {
e.Save(ExcelTypeNewPlayerBankrupt, fmt.Sprintf("新用户破产率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeNewPlayerBankrupt, startTime, endTime)
}
if switchArr[ExcelTypeGameTimeAvg] == 1 {
e.Save(ExcelTypeGameTimeAvg, fmt.Sprintf("新用户平均游戏时长_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeGameTimeAvg, startTime, endTime)
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
e.Save(ExcelTypeGameTimeAllAvg, fmt.Sprintf("用户平均游戏时长_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeGameTimeAllAvg, startTime, endTime)
}
if switchArr[ExcelTypeGameCountAvg] == 1 {
e.Save(ExcelTypeGameCountAvg, fmt.Sprintf("新用户平均局数_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeGameCountAvg, startTime, endTime)
}
if switchArr[ExcelTypeGameRate] == 1 {
e.Save(ExcelTypeGameRate, fmt.Sprintf("平均倍数_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeGameRate, startTime, endTime)
}
if switchArr[ExcelTypeActiveRate] == 1 {
e.Save(ExcelTypeActiveRate, fmt.Sprintf("活跃破产率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeActiveRate, startTime, endTime)
}
if switchArr[ExcelTypeCtrlWinRate] == 1 {
e.Save(ExcelTypeCtrlWinRate, fmt.Sprintf("控赢胜率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeCtrlWinRate*10, fmt.Sprintf("控输胜率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeCtrlWinRate, startTime, endTime)
e.Save(ExcelTypeCtrlWinRate*10, startTime, endTime)
}
if switchArr[ExcelTypeRobotWinRate] == 1 {
e.Save(ExcelTypeRobotWinRate, fmt.Sprintf("机器人输率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeRobotWinRate, startTime, endTime)
}
if switchArr[ExcelTypeCoinAvg] == 1 {
e.Save(ExcelTypeCoinAvg, fmt.Sprintf("人均获得金币_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeCoinAvg, startTime, endTime)
}
if switchArr[ExcelTypeBankruptOffline] == 1 {
e.Save(ExcelTypeBankruptOffline, fmt.Sprintf("破产后离线_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeBankruptOffline, startTime, endTime)
}
if switchArr[ExcelTypeOfflineCoin] == 1 {
e.Save(ExcelTypeOfflineCoin, fmt.Sprintf("离线金币_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeOfflineCoin, startTime, endTime)
}
}