2025-06-04 18:17:39 +08:00
package main
import (
"bytes"
"context"
"database/sql"
"fmt"
"github.com/oylshe1314/framework/client/db"
2025-06-06 18:31:44 +08:00
opts "github.com/oylshe1314/framework/options"
2025-06-04 18:17:39 +08:00
"github.com/oylshe1314/framework/util"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"os"
"strconv"
"time"
)
type QueryClient struct {
MongoClient db . MongoClient
MysqlClient db . MysqlClient
}
func ( this * QueryClient ) Init ( ) ( err error ) {
err = this . MongoClient . Init ( )
if err != nil {
return err
}
fmt . Printf ( "mongodb %s/%s connected\n" , this . MongoClient . Address ( ) , this . MongoClient . Database ( ) )
err = this . MysqlClient . Init ( )
if err != nil {
return err
}
fmt . Printf ( "mysql %s/%s connected\n" , this . MysqlClient . Address ( ) , this . MysqlClient . Database ( ) )
return nil
}
func ( this * QueryClient ) Close ( ) error {
_ = this . MongoClient . Close ( )
_ = this . MysqlClient . Close ( )
return nil
}
var functions = [ ] string {
"query all charge data" ,
"query level lost data" ,
"query first charge data" ,
"query player gold data" ,
"query player shop log" ,
"query player flirt info" ,
"query hero flirt count" ,
"query player lottery consume" ,
"query mura charge total" ,
}
func main ( ) {
if len ( os . Args ) < 2 {
fmt . Println ( "Usage:" )
fmt . Println ( " A number of function index(1-8)" )
for i , function := range functions {
fmt . Printf ( " %d:\n %s\n" , i + 1 , function )
}
return
}
index , err := strconv . ParseInt ( os . Args [ 1 ] , 10 , 64 )
if err != nil {
fmt . Println ( "error args" , err )
return
}
if index < 1 || int ( index ) > len ( functions ) {
fmt . Println ( "error index" )
return
}
2025-06-06 18:31:44 +08:00
opt , err := opts . ReadJson ( "./config.json" )
2025-06-04 18:17:39 +08:00
if err != nil {
fmt . Println ( err )
return
}
var client = & QueryClient { }
err = opt . Init ( client )
if err != nil {
fmt . Println ( err )
return
}
defer client . Close ( )
fmt . Println ( functions [ index - 1 ] )
switch index {
case 1 :
err = client . queryAllCharge ( )
if err != nil {
fmt . Println ( err )
return
}
case 2 :
err = client . queryLevelLost ( )
if err != nil {
fmt . Println ( err )
return
}
case 3 :
err = client . queryFirstCharge ( )
if err != nil {
fmt . Println ( err )
return
}
case 4 :
err = client . queryPlayerGold ( )
if err != nil {
fmt . Println ( err )
return
}
case 5 :
err = client . queryPlayerShopLog ( )
if err != nil {
fmt . Println ( err )
return
}
case 6 :
err = client . queryFlirtInfo ( )
if err != nil {
fmt . Println ( err )
return
}
case 7 :
err = client . queryFlirtCount ( )
if err != nil {
fmt . Println ( err )
return
}
case 8 :
err = client . queryLotteryConsume ( )
if err != nil {
fmt . Println ( err )
return
}
case 9 :
err = client . queryMuraChargeTotal ( )
if err != nil {
fmt . Println ( err )
return
}
}
}
type _AllChargePlayer struct {
Base struct {
Level int32 ` bson:"level" `
CreateTime int64 ` bson:"createtime" `
} ` bson:"base" `
}
type _AllChargeOrderAggregate struct {
OrderId string ` bson:"_id" `
AccountId uint64 ` bson:"accountid" `
ProductId uint64 ` bson:"productid" `
ChargeTime int64 ` bson:"chargetime" `
Players [ ] * _AllChargePlayer ` bson:"players" `
}
func ( this * QueryClient ) queryAllCharge ( ) error {
cur , err := this . MongoClient . Collection ( "chargeorder" ) . Aggregate (
this . MongoClient . Context ( ) ,
bson . A {
bson . M { "$match" : bson . M { "paystatus" : 1 } } ,
bson . M { "$lookup" : bson . M { "from" : "player" , "localField" : "accountid" , "foreignField" : "_id" , "as" : "players" } } ,
bson . M { "$project" : bson . M { "_id" : 1 , "accountid" : 1 , "productid" : 1 , "chargetime" : 1 , "players.base.level" : 1 , "players.base.createtime" : 1 } } ,
} )
if err != nil {
return err
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,当前等级,充值ID,充值时间,创角时间\n" )
for cur . Next ( context . Background ( ) ) {
var aggregate = new ( _AllChargeOrderAggregate )
err = cur . Decode ( aggregate )
if err != nil {
return err
}
if len ( aggregate . Players ) < 1 {
continue
}
fmt . Printf ( "query player %d\n" , aggregate . AccountId )
var rt = time . Unix ( aggregate . ChargeTime , 0 )
var logTable = fmt . Sprintf ( "upgrade_level_log_%d%02d%02d" , rt . Year ( ) , rt . Month ( ) , rt . Day ( ) )
err = this . MysqlClient . QueryRow ( fmt . Sprintf ( "show tables like '%s';" , logTable ) ) . Scan ( & logTable )
if err != nil {
if err == sql . ErrNoRows {
fmt . Printf ( "check table %s does not exists\n" , logTable )
continue
}
return err
}
var ct = time . Unix ( aggregate . Players [ 0 ] . Base . CreateTime , 0 )
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%s,%s\n" , aggregate . AccountId , aggregate . Players [ 0 ] . Base . Level , aggregate . ProductId , rt . Format ( "2006年01月02日15时04分05秒" ) , ct . Format ( "2006年01月02日15时04分05秒" ) ) )
}
err = os . WriteFile ( "./all_charge.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _PlayerBase struct {
Level uint32 ` bson:"level" `
CreateTime int64 ` bson:"createtime" `
LogoffTime int64 ` bson:"logofftime" `
MainlineSceneId uint32 ` bson:"MainlineSceneId" `
}
type _Player struct {
AccountId uint64 ` bson:"_id" `
Base _PlayerBase ` bson:"base" `
}
func ( this * QueryClient ) queryLevelLost ( ) error {
findOpts := options . Find ( ) . SetProjection ( bson . M { "_id" : 1 , "base.level" : 1 , "base.createtime" : 1 , "base.logofftime" : 1 , "base.MainlineSceneId" : 1 } )
cur , err := this . MongoClient . Collection ( "player" ) . Find ( this . MongoClient . Context ( ) , bson . M { } , findOpts )
if err != nil {
return err
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,当前等级,当前关卡,注册时间,下线时间,\n" )
for cur . Next ( context . Background ( ) ) {
var player = new ( _Player )
err = cur . Decode ( player )
if err != nil {
return err
}
var ct = time . Unix ( player . Base . CreateTime , 0 )
var ot = time . Unix ( player . Base . LogoffTime , 0 )
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%s,%s\n" ,
player . AccountId ,
player . Base . Level ,
player . Base . MainlineSceneId ,
ct . Format ( "2006年01月02日15时04分05秒" ) ,
ot . Format ( "2006年01月02日15时04分05秒" ) ,
) )
}
err = os . WriteFile ( "./level_lost.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _ChargeOrder struct {
OrderNumber string ` bson:"_id" `
AccountId uint64 ` bson:"accountid" `
ProductId int32 ` bson:"productid" `
ProductPrice int32 ` bson:"productprice" `
ChargeTime int64 ` bson:"chargetime" `
PayStatus int32 ` bson:"paystatus" `
}
type _ChargePlayer struct {
Base struct {
CreateTime int64 ` bson:"createtime" `
} ` bson:"base" `
}
type _ChargeOrderAggregate struct {
AccountId uint64 ` bson:"_id" `
ChargeTime int64 ` bson:"chargetime" `
Orders [ ] * _ChargeOrder ` bson:"orders" `
Players [ ] * _ChargePlayer ` bson:"players" `
}
func ( this * QueryClient ) queryFirstCharge ( ) error {
cur , err := this . MongoClient . Collection ( "chargeorder" ) . Aggregate (
this . MongoClient . Context ( ) ,
bson . A {
bson . M { "$match" : bson . M { "paystatus" : 1 } } ,
bson . M { "$group" : bson . M { "_id" : "$accountid" , "chargetime" : bson . M { "$min" : "$chargetime" } } } ,
bson . M {
"$lookup" : bson . M {
"from" : "chargeorder" ,
"let" : bson . M { "groupId" : "$_id" , "groupCt" : "$chargetime" } ,
"pipeline" : bson . A {
bson . M {
"$match" : bson . M {
"$expr" : bson . M {
"$and" : bson . A {
bson . M { "$eq" : bson . A { "$accountid" , "$$groupId" } } ,
bson . M { "$eq" : bson . A { "$chargetime" , "$$groupCt" } } ,
} ,
} ,
} ,
} ,
} ,
"as" : "orders" ,
} ,
} ,
bson . M { "$lookup" : bson . M { "from" : "player" , "localField" : "_id" , "foreignField" : "_id" , "as" : "players" } } ,
bson . M { "$project" : bson . M { "_id" : 1 , "chargetime" : 1 , "orders" : 1 , "players.base.createtime" : 1 } } ,
} )
if err != nil {
return err
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,当前等级,充值ID,充值时间,\n" )
for cur . Next ( context . Background ( ) ) {
var aggregate = new ( _ChargeOrderAggregate )
err = cur . Decode ( aggregate )
if err != nil {
return err
}
if len ( aggregate . Orders ) < 1 || len ( aggregate . Players ) < 1 {
continue
}
fmt . Printf ( "query player %d\n" , aggregate . AccountId )
var ct = time . Unix ( aggregate . ChargeTime , 0 )
var logTable = fmt . Sprintf ( "upgrade_level_log_%d%02d%02d" , ct . Year ( ) , ct . Month ( ) , ct . Day ( ) )
err = this . MysqlClient . QueryRow ( fmt . Sprintf ( "show tables like '%s';" , logTable ) ) . Scan ( & logTable )
if err != nil {
if err == sql . ErrNoRows {
fmt . Printf ( "check table %s does not exists\n" , logTable )
continue
}
return err
}
var curLevel uint32
err = this . MysqlClient . QueryRow (
fmt . Sprintf ( "select cur_level from %s where account_id=? and log_time < ? order by id desc limit 1;" , logTable ) ,
aggregate . AccountId ,
aggregate . ChargeTime ,
) . Scan ( & curLevel )
if err != nil && err != sql . ErrNoRows {
return err
}
var rt = time . Unix ( aggregate . Players [ 0 ] . Base . CreateTime , 0 )
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%s,%s\n" , aggregate . AccountId , curLevel , aggregate . Orders [ 0 ] . ProductId , rt . Format ( "2006年01月02日15时04分05秒" ) , ct . Format ( "2006年01月02日15时04分05秒" ) ) )
}
err = os . WriteFile ( "./first_charge.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _PlayerGold struct {
AccountId uint64 ` bson:"_id" `
Base struct {
Gold int ` bson:"gold" `
} ` bson:"base" `
ObtainTotal int ` bson:"-" `
ConsumeTotel int ` bson:"-" `
}
func ( this * QueryClient ) queryPlayerGold ( ) error {
var opt = options . Find ( )
opt . SetProjection ( bson . M { "_id" : 1 , "base.gold" : 1 } )
cur , err := this . MongoClient . Collection ( "player" ) . Find ( context . Background ( ) , bson . M { } , opt )
if err != nil {
return err
}
var playerMap = map [ uint64 ] * _PlayerGold { }
for cur . Next ( context . Background ( ) ) {
var player = new ( _PlayerGold )
err = cur . Decode ( player )
if err != nil {
return err
}
playerMap [ player . AccountId ] = player
}
var beginTime = int64 ( 1689091200 )
var now = util . Unix ( )
for ; beginTime < now ; beginTime += 86400 {
var y , m , d = time . Unix ( beginTime , 0 ) . In ( util . UTC8 ( ) ) . Date ( )
var ymd = y * 10000 + int ( m ) * 100 + d
var rows * sql . Rows
var table = fmt . Sprintf ( "obtain_money_log_%d" , ymd )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "show tables like '%s';" , table ) )
if err != nil {
return err
}
if rows . Next ( ) {
_ = rows . Close ( )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "select player_id, sum(consume_count) from %s where money_type=0 group by player_id" , table ) )
if err != nil {
return err
}
for rows . Next ( ) {
var playerId uint64
var obtainTotal int
err = rows . Scan ( & playerId , & obtainTotal )
if err != nil {
_ = rows . Close ( )
return err
}
var player = playerMap [ playerId ]
if player != nil {
player . ObtainTotal += obtainTotal
}
}
_ = rows . Close ( )
} else {
_ = rows . Close ( )
}
table = fmt . Sprintf ( "consume_money_log_%d" , ymd )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "show tables like '%s';" , table ) )
if err != nil {
return err
}
if rows . Next ( ) {
_ = rows . Close ( )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "select player_id, sum(consume_count) from %s where money_type=0 group by player_id" , table ) )
if err != nil {
return err
}
for rows . Next ( ) {
var playerId uint64
var consumeTotal int
err = rows . Scan ( & playerId , & consumeTotal )
if err != nil {
_ = rows . Close ( )
return err
}
var player = playerMap [ playerId ]
if player != nil {
player . ConsumeTotel += consumeTotal
}
}
_ = rows . Close ( )
} else {
_ = rows . Close ( )
}
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,当前五彩石,总产出量,总消耗量,\n" )
for _ , player := range playerMap {
if player . Base . Gold == 0 && player . ObtainTotal == 0 && player . ConsumeTotel == 0 {
continue
}
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%d,\n" , player . AccountId , player . Base . Gold , player . ObtainTotal , player . ConsumeTotel ) )
}
err = os . WriteFile ( "./player_gold.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _ShopLog struct {
ItemId int
ItemNum int
}
type _PlayerGem struct {
AccountId uint64 ` bson:"_id" `
Base struct {
Gem int ` bson:"gem" `
} ` bson:"base" `
ShopLog map [ int ] * _ShopLog
}
func ( this * QueryClient ) queryPlayerShopLog ( ) error {
var opt = options . Find ( )
opt . SetProjection ( bson . M { "_id" : 1 , "base.gem" : 1 } )
cur , err := this . MongoClient . Collection ( "player" ) . Find ( context . Background ( ) , bson . M { "base.level" : bson . M { "$gte" : 20 } } , opt )
if err != nil {
return err
}
var gemTotal int
var playerMap = map [ uint64 ] * _PlayerGem { }
for cur . Next ( context . Background ( ) ) {
var player = & _PlayerGem { ShopLog : map [ int ] * _ShopLog { } }
err = cur . Decode ( player )
if err != nil {
return err
}
playerMap [ player . AccountId ] = player
gemTotal += player . Base . Gem
}
var beginTime = int64 ( 1689091200 )
var now = util . Unix ( )
for ; beginTime < now ; beginTime += 86400 {
var y , m , d = time . Unix ( beginTime , 0 ) . In ( util . UTC8 ( ) ) . Date ( )
var ymd = y * 10000 + int ( m ) * 100 + d
var rows * sql . Rows
var table = fmt . Sprintf ( "shop_log_%d" , ymd )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "show tables like '%s';" , table ) )
if err != nil {
return err
}
if rows . Next ( ) {
_ = rows . Close ( )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "select player_id,item_id,count(1) from %s where shop_type=0 group by player_id, item_id;" , table ) )
if err != nil {
return err
}
for rows . Next ( ) {
var playerId uint64
var itemId int
var itemNum int
err = rows . Scan ( & playerId , & itemId , & itemNum )
if err != nil {
_ = rows . Close ( )
return err
}
var player = playerMap [ playerId ]
if player != nil {
var log = player . ShopLog [ itemId ]
if log == nil {
log = & _ShopLog { ItemId : itemId , ItemNum : itemNum }
player . ShopLog [ log . ItemId ] = log
} else {
log . ItemNum += itemNum
}
}
}
_ = rows . Close ( )
} else {
_ = rows . Close ( )
}
}
var buff bytes . Buffer
buff . WriteString ( "星石总量,\n" )
buff . WriteString ( fmt . Sprintf ( "%d,\n" , gemTotal ) )
buff . WriteString ( "玩家ID,玩家星石,道具ID,道具数量,\n" )
for _ , player := range playerMap {
for _ , log := range player . ShopLog {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%d,\n" , player . AccountId , player . Base . Gem , log . ItemId , log . ItemNum ) )
}
}
err = os . WriteFile ( "./player_shop_log.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
var sealCopyScenes = map [ int ] struct { } {
50201 : { } ,
50204 : { } ,
50207 : { } ,
50210 : { } ,
50213 : { } ,
50216 : { } ,
50219 : { } ,
50301 : { } ,
50304 : { } ,
50307 : { } ,
50310 : { } ,
50313 : { } ,
50316 : { } ,
50319 : { } ,
50401 : { } ,
50404 : { } ,
50407 : { } ,
50410 : { } ,
50413 : { } ,
50416 : { } ,
50419 : { } ,
}
var heroFlirtItems = map [ int ] struct { } {
13001 : { } ,
13002 : { } ,
13003 : { } ,
13004 : { } ,
13005 : { } ,
13006 : { } ,
13007 : { } ,
13008 : { } ,
13009 : { } ,
13010 : { } ,
13011 : { } ,
13012 : { } ,
13013 : { } ,
13014 : { } ,
13015 : { } ,
13016 : { } ,
13017 : { } ,
13018 : { } ,
13019 : { } ,
13020 : { } ,
13101 : { } ,
13102 : { } ,
13103 : { } ,
13104 : { } ,
13105 : { } ,
13106 : { } ,
13107 : { } ,
13108 : { } ,
13109 : { } ,
13110 : { } ,
}
type _PassedCopy struct {
SceneId int ` name:"copypassed" key:"1" `
TotalNum int
}
type _PlayerHero struct {
HeroID int
Talent int //天赋
FlirtLevel [ ] bool //当前调戏层级
FlirtExciting [ ] int //当前兴奋值
FlirtAttrUnlock [ ] bool //调戏属性解锁
}
func ( this * _PlayerHero ) FlirtFinishedLevel ( ) int {
var li = 0
for i , b := range this . FlirtAttrUnlock {
if ! b {
break
}
li = i + 1
}
return li
}
type _ConsumeItem struct {
ItemId int
ItemNum int
}
type _PlayerCopyPassed struct {
AccountId uint64 ` bson:"_id" `
PassedCopy map [ int ] * _PassedCopy ` bson:"copypassed" `
PlayerHero map [ int ] * _PlayerHero ` bson:"hero" `
ConsumeItem map [ int ] * _ConsumeItem
}
func ( this * QueryClient ) queryFlirtInfo ( ) error {
var opt = options . Find ( )
opt . SetProjection ( bson . M { "_id" : 1 , "copypassed" : 1 , "hero" : 1 } )
cur , err := this . MongoClient . Collection ( "player" ) . Find ( context . Background ( ) , bson . M { "base.level" : bson . M { "$gte" : 20 } } , opt )
if err != nil {
return err
}
var playerMap = map [ uint64 ] * _PlayerCopyPassed { }
for cur . Next ( context . Background ( ) ) {
var player = & _PlayerCopyPassed { PassedCopy : map [ int ] * _PassedCopy { } , PlayerHero : map [ int ] * _PlayerHero { } , ConsumeItem : map [ int ] * _ConsumeItem { } }
err = cur . Decode ( player )
if err != nil {
return err
}
playerMap [ player . AccountId ] = player
}
var beginTime = int64 ( 1689091200 )
var now = util . Unix ( )
for ; beginTime < now ; beginTime += 86400 {
var y , m , d = time . Unix ( beginTime , 0 ) . In ( util . UTC8 ( ) ) . Date ( )
var ymd = y * 10000 + int ( m ) * 100 + d
var rows * sql . Rows
var table = fmt . Sprintf ( "consume_item_log_%d" , ymd )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "show tables like '%s';" , table ) )
if err != nil {
return err
}
if rows . Next ( ) {
_ = rows . Close ( )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "select player_id, item_id, sum(item_num) from %s where log_type in (515,516) group by player_id, item_id;" , table ) )
if err != nil {
return err
}
for rows . Next ( ) {
var playerId uint64
var itemId int
var itemNum int
err = rows . Scan ( & playerId , & itemId , & itemNum )
if err != nil {
_ = rows . Close ( )
return err
}
var player = playerMap [ playerId ]
if player != nil {
var item = player . ConsumeItem [ itemId ]
if item == nil {
item = & _ConsumeItem { ItemId : itemId , ItemNum : itemNum }
player . ConsumeItem [ item . ItemId ] = item
} else {
item . ItemNum += itemNum
}
}
}
_ = rows . Close ( )
} else {
_ = rows . Close ( )
}
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,场景ID,通关次数,\n" )
for _ , player := range playerMap {
for _ , passedCopy := range player . PassedCopy {
if _ , ok := sealCopyScenes [ passedCopy . SceneId ] ; ok {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,\n" , player . AccountId , passedCopy . SceneId , passedCopy . TotalNum ) )
}
}
}
for _ , player := range playerMap {
buff . WriteString ( "\n玩家ID,英雄数量,\n" )
buff . WriteString ( fmt . Sprintf ( "%d,%d,\n" , player . AccountId , len ( player . PlayerHero ) ) )
buff . WriteString ( "玩家ID,英雄ID,契印星数,完成调教房间,房间1高潮值,房间2高潮值\n" )
for _ , playerHero := range player . PlayerHero {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%d,%d,%d,\n" , player . AccountId , playerHero . HeroID , playerHero . Talent + 1 , playerHero . FlirtFinishedLevel ( ) , playerHero . FlirtExciting [ 0 ] , playerHero . FlirtExciting [ 1 ] ) )
}
}
buff . WriteString ( "\n玩家ID,道具ID,道具使用数量,\n" )
for _ , player := range playerMap {
for _ , item := range player . ConsumeItem {
if _ , ok := heroFlirtItems [ item . ItemId ] ; ok {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,\n" , player . AccountId , item . ItemId , item . ItemNum ) )
}
}
}
err = os . WriteFile ( "./player_flirt_info.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _PlayerFlirtCount struct {
AccountId uint64 ` bson:"_id" `
PlayerHero map [ int ] * _PlayerHero ` bson:"hero" `
}
func ( this * QueryClient ) queryFlirtCount ( ) error {
cur , err := this . MongoClient . Collection ( "player" ) . Find ( this . MongoClient . Context ( ) , bson . M { } )
if err != nil {
return err
}
var players [ ] * _PlayerFlirtCount
err = cur . All ( this . MongoClient . Context ( ) , & players )
if err != nil {
return err
}
var heroMap = map [ int ] map [ int ] int { }
for _ , player := range players {
for _ , hero := range player . PlayerHero {
var levelMap = heroMap [ hero . HeroID ]
if levelMap == nil {
levelMap = map [ int ] int { }
heroMap [ hero . HeroID ] = levelMap
}
for i , b := range hero . FlirtAttrUnlock {
if i < len ( heroMap ) && b {
levelMap [ i + 1 ] = levelMap [ i + 1 ] + 1
}
}
}
}
var buff bytes . Buffer
buff . WriteString ( "英雄ID,房间1完成数,房间2完成数,房间3完成数,\n" )
for heroId , levelMap := range heroMap {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,%d,\n" , heroId , levelMap [ 1 ] , levelMap [ 2 ] , levelMap [ 3 ] ) )
}
err = os . WriteFile ( "./player_flirt_info.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _PlayerLotteryConsume struct {
PlayerId uint64
Ordinary uint64
Advanced uint64
}
func ( this * QueryClient ) queryLotteryConsume ( ) error {
var beginDate = "2023-12-29" //include the day of the beginning date
var endDate = "2024-01-10" //but exclude the day of the end date
timeBegin , err := time . ParseInLocation ( time . DateOnly , beginDate , util . UTC8 ( ) )
if err != nil {
return err
}
timeEnd , err := time . ParseInLocation ( time . DateOnly , endDate , util . UTC8 ( ) )
if err != nil {
return err
}
var tables [ ] string
for ; timeBegin . Before ( timeEnd ) ; timeBegin = timeBegin . AddDate ( 0 , 0 , 1 ) {
tables = append ( tables , fmt . Sprintf ( "consume_item_log_%s" , timeBegin . Format ( "20060102" ) ) )
}
var rows * sql . Rows
var players = map [ uint64 ] * _PlayerLotteryConsume { }
for _ , table := range tables {
fmt . Printf ( "querying table %s\n" , table )
rows , err = this . MysqlClient . Query ( fmt . Sprintf ( "show tables like '%s';" , table ) )
if err != nil {
return err
}
if rows . Next ( ) {
_ = rows . Close ( )
var query = fmt . Sprintf ( "select player_id, item_id, sum(item_num) from %s where item_id in (10007, 10013) group by player_id, item_id;" , table )
rows , err = this . MysqlClient . Query ( query )
if err != nil {
return err
}
for rows . Next ( ) {
var playerId , itemId , itemNum uint64
err = rows . Scan ( & playerId , & itemId , & itemNum )
var player = players [ playerId ]
if player == nil {
player = & _PlayerLotteryConsume { PlayerId : playerId }
players [ player . PlayerId ] = player
}
switch itemId {
case 10007 :
player . Ordinary += itemNum
case 10013 :
player . Advanced += itemNum
}
}
_ = rows . Close ( )
}
}
var buff bytes . Buffer
buff . WriteString ( "玩家ID,普通抽奖券消耗,高级抽奖券消耗,\n" )
for _ , player := range players {
buff . WriteString ( fmt . Sprintf ( "%d,%d,%d,\n" , player . PlayerId , player . Ordinary , player . Advanced ) )
}
err = os . WriteFile ( "./player_lottery_consume.csv" , buff . Bytes ( ) , 0777 )
if err != nil {
return err
}
return nil
}
type _MuraPlayer struct {
AccountId uint64 ` bson:"_id" `
Platform uint32 ` bson:"platform" `
}
func ( this * QueryClient ) queryMuraChargeTotal ( ) error {
cur , err := this . MongoClient . Collection ( "player" ) . Find ( this . MongoClient . Context ( ) , bson . M { "platform" : 6 } )
if err != nil {
return err
}
var total int32 = 0
var player = new ( _MuraPlayer )
for cur . Next ( this . MongoClient . Context ( ) ) {
err = cur . Decode ( player )
if err != nil {
return err
}
fmt . Println ( "Query Mura charge player: " , player . AccountId )
cc , err := this . MongoClient . Collection ( "chargeorder" ) . Find ( this . MongoClient . Context ( ) , bson . M { "accountid" : player . AccountId , "paystatus" : 1 } )
if err != nil {
return err
}
for cc . Next ( this . MongoClient . Context ( ) ) {
var order = new ( _ChargeOrder )
err = cc . Decode ( order )
if err != nil {
return err
}
fmt . Println ( "Query Mura charge order: " , order . OrderNumber )
total += order . ProductPrice
}
}
fmt . Println ( "Query Mura charge total: " , total )
return nil
}