From 0cc66a8b288bc7562bbe5fdab8ef03643c7910c2 Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Thu, 26 Dec 2024 08:26:00 +0800 Subject: [PATCH] =?UTF-8?q?statistics=E6=96=87=E4=BB=B6=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 12 +- go.sum | 11 ++ statistics/task/etc/config.yaml | 5 +- statistics/task/excelmgr.go | 79 +++++++++-- statistics/task/handler.go | 51 +++++++ statistics/task/main.go | 228 ++++++++++++++++++-------------- 6 files changed, 269 insertions(+), 117 deletions(-) create mode 100644 statistics/task/handler.go diff --git a/go.mod b/go.mod index 101e647..4c38e80 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index b521a07..50b60dc 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/statistics/task/etc/config.yaml b/statistics/task/etc/config.yaml index a5f0508..b479fa3 100644 --- a/statistics/task/etc/config.yaml +++ b/statistics/task/etc/config.yaml @@ -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 # 新用户游戏破产率 diff --git a/statistics/task/excelmgr.go b/statistics/task/excelmgr.go index b7dd8ca..bc83808 100644 --- a/statistics/task/excelmgr.go +++ b/statistics/task/excelmgr.go @@ -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 语句,支持中文描述和索引 diff --git a/statistics/task/handler.go b/statistics/task/handler.go new file mode 100644 index 0000000..7d48057 --- /dev/null +++ b/statistics/task/handler.go @@ -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) +} diff --git a/statistics/task/main.go b/statistics/task/main.go index 886904e..4edf75e 100644 --- a/statistics/task/main.go +++ b/statistics/task/main.go @@ -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) } }