Commit f408015e authored by szh's avatar szh

update

parent 5fda1f1c
package elfGame
const (
PointTypeGame = iota
PointTypeInviter // 邀请
PointTypeHelp // 助力
PointTypeGameGuide // 游戏指导
PointTypeFrozen // 锁仓奖励
PointTypeFrozenPre // 锁仓指导
PointTypeRecover // 回收
)
const (
OrderType = iota // 精灵召唤
OrderTypeTool //道具购买
OrderTypeCap //工坊开启
OrderTypeSecond // 二次召唤
)
\ No newline at end of file
package elfGame package elfGame
import ( import (
"runtime"
"testing" "testing"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
...@@ -17,36 +18,296 @@ import ( ...@@ -17,36 +18,296 @@ import (
var client *gorm.DB var client *gorm.DB
// addr => info
var usersMap map[string]*model.Users var usersMap map[string]*model.Users
// id => info
var usersIdMap map[int64]*model.Users var usersIdMap map[int64]*model.Users
// month data map
var usersMapCalc map[int64]*CalcData var usersMapCalc map[int64]*CalcData
// day point map
var usersMapPoint map[int64]*CalcPointData
var topList []string var topList []string
// 系统精灵列表
var sysAsset map[int64]*model.SystemAsset var sysAsset map[int64]*model.SystemAsset
// 实时精灵
var userAsset map[int64][]*model.UserAsset var userAsset map[int64][]*model.UserAsset
// 精灵打造历史
var userIncome map[int64][]*model.UserAssetIncome var userIncome map[int64][]*model.UserAssetIncome
// 用户积分列表历史
var userPointList map[int64][]*model.UserPoint
// 用户订单列表历史
var userOrderList map[int64][]*model.OrderRecords
// 用户精灵列表历史
var userElfOrderList map[int64][]*model.OrderRecords
// 推荐关系 地址 =》 下级
var usersInviter map[int64][]int64
// 部落关系表 部落=>上级部落
var tribeMap map[int64]int64
// 用户领取列表
var usersIncomeCollect map[int64][]*model.AssetIncomeCollect
// 用户提币列表
var usersIncomeWithdraw map[int64][]*model.AssetIncomeWithdraw
// 账户统计
var usersAccountData map[int64]*ElfAccountData
var usersData map[int64]*model.UserData
// 用户空投记录
var userAirdrop map[int64][]*model.AirDropTx
const PerCent = 100 const PerCent = 100
const FixTime = 0 //3600 * 8
const AIR = "0x99ba98bf40135d181bf20db9962dd916f53b5e58" const AIR = "0x99ba98bf40135d181bf20db9962dd916f53b5e58"
var chain33Client types.Chain33Client var chain33Client types.Chain33Client
func init() { func init() {
dsn := "root:root@tcp(127.0.0.1:3306)/elf?charset=utf8mb4&parseTime=True&loc=Local" dsn := "root:fzm123456@tcp(192.168.122.119:3306)/elf?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil { if err != nil {
panic("failed to connect database") panic("failed to connect database")
} }
sd,err := db.DB()
sd.SetMaxOpenConns(100)
sd.SetMaxIdleConns(10)
client = db client = db
chain33Client, _ = NewGrpcClient("cloud.bityuan.com") chain33Client, _ = NewGrpcClient("172.16.100.93:8802")
}
func Test1(t *testing.T) {
tt := time.Tick(2 * time.Second)
go func() {
for range tt {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Println("info:NumGoroutine:", runtime.NumGoroutine())
fmt.Println("info:Mem:", m.Sys/(1024*1024))
fmt.Println("info:HeapAlloc:", m.HeapAlloc/(1024*1024))
}
}()
} }
type CalcData struct { type CalcData struct {
Addr string //部落地址 Addr string //部落地址
Reward float64 //部落收益 PersonReward float64 //个人累计打造收益
PopBuy int64 // 伞下质押 InviterAddr string //上级部落
PopAddrs int64 // 伞下质押地址 InviterAddrReward float64 //上级部落
Reward float64 //部落收益
NextBuy int64 // 直推质押BTY
NextAddrs int64 // 直推地址数
PopBuy int64 // 伞下质押BTY
PopAddrs int64 // 伞下地址数
PopReward float64 // 伞下累计收益 PopReward float64 // 伞下累计收益
BuyList map[int64]int64 //自己购买统计 精灵->数量 BuyList map[int64]int64 //自己购买统计 精灵->数量
Buy int64 // 当前质押
BuyListHistory map[int64]int64 //自己累计购买
PopBuyListHistory map[int64]int64 //伞下累计购买
NextBuyHistory int64 // 直推质押BTY累计
PopBuyHistory int64 // 伞下质押BTY累计
BuyHistory int64 // 累计质押
AirReward float64
PopAirReward float64 // 空投
}
type CalcPointData struct {
Id int64
Addr string
DayAsset int64 // 今日召唤精灵
DayTool int64 // 今日道具
TotalPoint float64 // 总积分值
PassPoint float64 // 通关积分
InvitePoint float64 // 邀请积分
HelpPoint float64 // 助力积分
PassGuide float64 // 通关指导
FrozenPoint float64 // 锁仓
FrozenGuide float64 // 锁仓指导
RecoverPoint float64 // 回收积分
RegDate string // 注册时间
Invitor string // 邀请人
HasAsset bool // 是否有精灵 包括可升级的
MiningAmount int64 // 精灵打造收益
}
// 积分榜统计
func TestPointData(t *testing.T) {
var err error
initData()
usersMapPoint = make(map[int64]*CalcPointData,0)
fmt.Println("user num",len(usersMapPoint))
for k, v:= range usersIdMap {
if _, ok := usersMapPoint[k];!ok {
usersMapPoint[k] = &CalcPointData{
Id:k,
Addr: v.AccountID,
DayAsset: 0,
}
}
}
up := make([]*model.UserPoint,0)
err = client.Model(&model.UserPoint{}).
Where("create_time >=? and create_time < ?",
GetTodayTime("2006-01-02").
AddDate(0,0,-1),GetTodayTime("2006-01-02")).Find(&up).Error
if err != nil {
panic(err)
}
for _,v := range up {
if _, ok := userPointList[v.UserID];!ok {
newList := make([]*model.UserPoint,0)
newList = append(newList,v)
userPointList[v.UserID] = newList
} else {
userPointList[v.UserID] = append(userPointList[v.UserID],v)
}
}
// 统计召唤数据数据
orders := make([]*model.OrderRecords,0)
err = client.Model(&model.OrderRecords{}).
Where("create_time >=? and create_time < ?",
GetTodayTime("2006-01-02").
AddDate(0,0,-1),GetTodayTime("2006-01-02")).Find(&orders).Error
if err != nil {
panic(err)
}
fmt.Println("order day num ",len(orders))
for _,v := range orders {
if _, ok := userOrderList[v.UserID];!ok {
newList := make([]*model.OrderRecords,0)
newList = append(newList,v)
userOrderList[v.UserID] = newList
} else {
userOrderList[v.UserID] = append(userOrderList[v.UserID],v)
}
}
var total = 0
for k,v := range userOrderList {
for _, vv := range v {
if vv.CreateTime.Unix() + FixTime >= GetTodayTime("2006-01-02").AddDate(0,0,-1).Unix() && vv.CreateTime.Unix() + FixTime < GetTodayTime("2006-01-02").Unix() {
switch vv.Type {
case OrderTypeTool: // 召唤工具
total++
usersMapPoint[k].DayTool++
case OrderTypeSecond: // 二次召唤
total++
usersMapPoint[k].DayAsset += int64(vv.TotalAmount)
case OrderType: // 首次召唤
if _,ok := sysAsset[vv.AssetID];ok {
usersMapPoint[k].DayAsset += int64(sysAsset[vv.AssetID].BasePrice)
} else {
fmt.Println("WRONG ASSET ID ",vv)
}
case OrderTypeCap:
}
}
}
}
for k, v := range usersMapPoint {
if k == 25088 {
fmt.Println("25088 真实订单数",len(userElfOrderList[k]))
}
// 查询某一天是否存在精灵 按精灵的购买的起始时间和打造的最后一天为截止 时间范围内都算有资产 特殊情况精灵购买后一直没有打造
for _,vv := range userElfOrderList[k] {
if vv.AssetID < 19 || vv.AssetID > 24 {
continue
}
var start,end time.Time
if v.HasAsset {
break
}
switch vv.Type {
case OrderType:
start = vv.CreateTime
end = vv.CreateTime.AddDate(0,0,sysAsset[vv.AssetID].LockDay)
// 异常情况 精灵购买后 闲置了一段时间
for _,vvv := range userIncome[k] {
if vvv.TokenID == vv.TokenID {
if vvv.CreateTime.Unix() > end.Unix() {
end = vvv.CreateTime
}
}
}
if end.IsZero(){
v.HasAsset = true
}
if start.Unix() < GetTodayTime("2006-01-02").Unix() && end.Unix() > GetTodayTime("2006-01-02").Unix() {
v.HasAsset = true
}
case OrderTypeSecond:
start = vv.CreateTime
end = vv.CreateTime.AddDate(0,0,sysAsset[vv.AssetID].LockDay)
// 异常情况 精灵购买后 闲置了一段时间
for _,vvv := range userIncome[k] {
if vvv.TokenID == vv.TokenID {
if vvv.CreateTime.Unix() > end.Unix() {
end = vvv.CreateTime
}
}
}
if end.IsZero() {
v.HasAsset = true
}
if start.Unix() < GetTodayTime("2006-01-02").Unix() && end.Unix() > GetTodayTime("2006-01-02").Unix() {
v.HasAsset = true
}
if k == 25088 {
fmt.Println("25088 ","token_id" ,vv.TokenID,end.IsZero(),v.HasAsset)
fmt.Println("start ",start,"end",end)
}
}
//fmt.Println("start ",start,"end",end)
}
}
fmt.Println("total tool ",total)
for _, v := range usersMapPoint {
// 确定邀请人
if usersMap[v.Addr].InvitorId > 0 {
v.Invitor = usersIdMap[usersMap[v.Addr].InvitorId].AccountID
}
v.RegDate = GetDate(usersMap[v.Addr].CreatedAt.Unix() + FixTime).Format("2006-01-02")
for _,vv := range userPointList[v.Id] {
if vv.CreateTime.After(GetTodayTime("2006-01-02")) || vv.CreateTime.Before(GetTodayTime("2006-01-02").AddDate(0,0,-1)) {
fmt.Println("not right time",vv.CreateTime)
continue
}
switch vv.Scense {
case PointTypeGame:
v.TotalPoint += vv.Point
v.PassPoint += vv.Point
case PointTypeInviter:
v.InvitePoint += vv.Point
v.TotalPoint += vv.Point
case PointTypeFrozen:
v.FrozenPoint += vv.Point
v.TotalPoint += vv.Point
case PointTypeFrozenPre:
v.FrozenGuide += vv.Point
v.TotalPoint += vv.Point
case PointTypeHelp:
v.HelpPoint += vv.Point
v.TotalPoint += vv.Point
case PointTypeGameGuide:
v.PassGuide += vv.Point
v.TotalPoint += vv.Point
case PointTypeRecover:
v.RecoverPoint += vv.Point
v.TotalPoint += vv.Point
}
}
}
err = CreatePointJob()
if err != nil {
panic(err)
}
} }
// 导入空投地址列表
func TestUpdateAirDropTx(t *testing.T) { func TestUpdateAirDropTx(t *testing.T) {
users := make([]*model.Users,0) users := make([]*model.Users,0)
usersMap = make(map[string]*model.Users,0) usersMap = make(map[string]*model.Users,0)
...@@ -72,24 +333,29 @@ func TestUpdateAirDropTx(t *testing.T) { ...@@ -72,24 +333,29 @@ func TestUpdateAirDropTx(t *testing.T) {
} }
CCC: CCC:
//GetTransactionByAddr(ctx context.Context, in *ReqAddr, opts ...grpc.CallOption) (*ReplyTxInfos, error) //GetTransactionByAddr(ctx context.Context, in *ReqAddr, opts ...grpc.CallOption) (*ReplyTxInfos, error)
replys, err := chain33Client.GetTransactionByAddr(context.Background(), &types.ReqAddr{Addr:AIR,Count:100,Direction:1,Flag:1,Height:height}) replys, err := chain33Client.GetTransactionByAddr(context.Background(), &types.ReqAddr{Addr:AIR,Count:300,Direction:1,Flag:1,Height:height})
if err != nil { if err != nil {
fmt.Println("err", err) fmt.Println("err", err)
time.Sleep(time.Second * 1)
goto CCC
} }
fmt.Println(replys) fmt.Println(replys)
for _,v := range replys.TxInfos { for _,v := range replys.TxInfos {
t1 := time.Now()
RRR: RRR:
tx,err := chain33Client.QueryTransaction(context.Background(),&types.ReqHash{Hash:v.Hash}) tx,err := chain33Client.QueryTransaction(context.Background(),&types.ReqHash{Hash:v.Hash})
if err != nil { if err != nil {
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
goto RRR goto RRR
} }
fmt.Println("cost",time.Since(t1))
if tx.Receipt.Ty != 2 { if tx.Receipt.Ty != 2 {
continue continue
} }
to := 0 to := 0
if m,ok := usersMap[tx.Tx.To];!ok { if m,ok := usersMap[strings.ToLower(tx.Tx.To)];!ok {
to = 1 to = 1
} else { } else {
to = int(m.ID) to = int(m.ID)
...@@ -118,27 +384,68 @@ func TestUpdateAirDropTx(t *testing.T) { ...@@ -118,27 +384,68 @@ func TestUpdateAirDropTx(t *testing.T) {
if v.Height > height { if v.Height > height {
height = v.Height height = v.Height
} }
fmt.Println("cost",time.Since(t1))
fmt.Println("height",v.Height,"amount",v.Assets[0].Amount,"hash",hash) fmt.Println("height",v.Height,"amount",v.Assets[0].Amount,"hash",hash)
} }
if len(replys.TxInfos) > 0 { if len(replys.TxInfos) > 0 {
goto CCC goto CCC
} }
fmt.Println("import done") fmt.Println("import done")
} }
func TestElfMonth(t *testing.T) { func TestBuildTree(t *testing.T) {
tl := GetMonthStartAndEnd("2024","04") initData()
t1 := time.Now()
for k,_ := range usersIdMap {
_ = buildUserInvitation(k)
//fmt.Println("uid",k,"invitation", v.Invitations,"new",invitation)
}
fmt.Println("cost",time.Since(t1))
}
// 构建用户路径
func buildUserInvitation(uid int64) string {
if uid == 0 {
panic("wrong uid")
}
if _,ok := usersIdMap[uid];ok {
if usersIdMap[uid].Invitor == "" {
return fmt.Sprintf("%d",uid)
} else {
invitation := buildUserInvitation(usersIdMap[uid].InvitorId)
return fmt.Sprintf("%s,%d",invitation,uid)
}
} else {
panic("uid not exist")
}
}
// 初始化一些数据 方便调用
func initData() {
//tl := GetMonthStartAndEnd("2024","04")
users := make([]*model.Users,0) users := make([]*model.Users,0)
var err error var err error
// get all user // get all user
err = client.Model(&model.Users{}).Find(&users).Error err = client.Model(&model.Users{}).Find(&users).Error
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println("total addr",len(users))
for _,v := range users { for _,v := range users {
v.AccountID = strings.ToLower(v.AccountID) v.AccountID = strings.ToLower(v.AccountID)
v.Invitor = strings.ToLower(v.Invitor) v.Invitor = strings.ToLower(v.Invitor)
} }
userAirdrop =make(map[int64][]*model.AirDropTx,0)
userElfOrderList = make(map[int64][]*model.OrderRecords,0)
usersData = make(map[int64]*model.UserData,0)
usersIncomeCollect = make(map[int64][]*model.AssetIncomeCollect,0)
// 用户提币列表
usersIncomeWithdraw = make(map[int64][]*model.AssetIncomeWithdraw,0)
usersInviter = make(map[int64][]int64,0)
userOrderList = make(map[int64][]*model.OrderRecords,0)
userPointList = make(map[int64][]*model.UserPoint,0)
usersMap = make(map[string]*model.Users,0) usersMap = make(map[string]*model.Users,0)
usersIdMap = make(map[int64]*model.Users,0) usersIdMap = make(map[int64]*model.Users,0)
// get all asset list 200 1000 2000 5000 10000 // get all asset list 200 1000 2000 5000 10000
...@@ -183,12 +490,48 @@ func TestElfMonth(t *testing.T) { ...@@ -183,12 +490,48 @@ func TestElfMonth(t *testing.T) {
userIncome[v.UserID] = nb userIncome[v.UserID] = nb
} }
} }
aic := make([]*model.AssetIncomeCollect,0)
err = client.Debug().Model(&model.AssetIncomeCollect{}).Find(&aic).Error
if err != nil {
panic(err)
}
for _,v := range aic {
if _, ok := usersIncomeCollect[v.UserID];!ok {
nd := make([]*model.AssetIncomeCollect,0)
nd = append(nd,v)
usersIncomeCollect[v.UserID] = nd
} else {
usersIncomeCollect[v.UserID] = append(usersIncomeCollect[v.UserID],v)
}
}
aiw := make([]*model.AssetIncomeWithdraw,0)
err = client.Debug().Model(&model.AssetIncomeWithdraw{}).Find(&aiw).Error
if err != nil {
panic(err)
}
for _,v := range aiw {
if _, ok := usersIncomeWithdraw[v.UserID];!ok {
nd := make([]*model.AssetIncomeWithdraw,0)
nd = append(nd,v)
usersIncomeWithdraw[v.UserID] = nd
} else {
usersIncomeWithdraw[v.UserID] = append(usersIncomeWithdraw[v.UserID],v)
}
}
usersD := make([]*model.UserData,0)
err = client.Model(&model.UserData{}).Find(&usersD).Error
if err != nil {
panic(err)
}
for _, v := range usersD {
if _, ok:= usersData[v.ID];!ok {
usersData[v.ID] = v
}
}
usersMapCalc = make(map[int64]*CalcData,0) usersMapCalc = make(map[int64]*CalcData,0)
fmt.Println("total addr",len(users))
topList = make([]string,0) topList = make([]string,0)
nextNum := 0 nextNum := 0
userInviter := make(map[string][]string,0)
// 找出top地址列表 生成 usersMap 和 usersIdMap表 // 找出top地址列表 生成 usersMap 和 usersIdMap表
for _,v := range users { for _,v := range users {
usersMapCalc[v.ID] = &CalcData{ usersMapCalc[v.ID] = &CalcData{
...@@ -196,22 +539,6 @@ func TestElfMonth(t *testing.T) { ...@@ -196,22 +539,6 @@ func TestElfMonth(t *testing.T) {
} }
usersMap[v.AccountID] = v usersMap[v.AccountID] = v
usersIdMap[v.ID] = v usersIdMap[v.ID] = v
if v.Invitor != "" {
if _,ok := userInviter[v.Invitor];!ok {
userInviter[v.Invitor] = []string{v.AccountID}
} else {
userInviter[v.Invitor] = append(userInviter[v.Invitor],v.AccountID)
}
nextNum++
}
}
for _,v := range users {
if v.Invitor == "" {
if m,ok := userInviter[v.AccountID];ok {
fmt.Println("top addr",v.AccountID," next num",len(m))
topList = append(topList,v.AccountID)
}
}
} }
fmt.Println("top num",len(topList),"next num",nextNum) fmt.Println("top num",len(topList),"next num",nextNum)
totalBuy := 0 totalBuy := 0
...@@ -227,149 +554,395 @@ func TestElfMonth(t *testing.T) { ...@@ -227,149 +554,395 @@ func TestElfMonth(t *testing.T) {
panic("not go here") panic("not go here")
} }
} }
// 用户精灵统计 // 用户精灵实时统计
if data, ok := userAsset[v.ID];ok { if data, ok := userAsset[v.ID];ok {
for _,vv := range data { for _,vv := range data {
if vv.CreateTime.Unix() > tl["start"].Unix() && vv.CreateTime.Unix() < tl["end"].Unix()+86400 { if _, ok2 := sysAsset[vv.AssetID];ok2 {
usersIdMap[v.ID].Buy += int64(sysAsset[vv.AssetID].BasePrice) usersIdMap[v.ID].Buy += int64(sysAsset[vv.AssetID].BasePrice)
totalBuy += sysAsset[vv.AssetID].BasePrice totalBuy += sysAsset[vv.AssetID].BasePrice
} }
} }
} }
// 用户精灵打造统计
if data, ok := userIncome[v.ID];ok {
for _,vv := range data {
if vv.CreateTime.Unix() > tl["start"].Unix() && vv.CreateTime.Unix() < tl["end"].Unix()+86400 {
if vv.Income >= float64(200) {
continue
}
usersIdMap[v.ID].Reward += vv.Income
totalReward += vv.Income
}
}
}
if usersIdMap[v.ID].Buy > 0 { if usersIdMap[v.ID].Buy > 0 {
fmt.Println("用户精灵购买",usersIdMap[v.ID].Buy,"用户精灵收益",usersIdMap[v.ID].Reward) //fmt.Println("用户精灵购买",usersIdMap[v.ID].Buy,"用户精灵收益",usersIdMap[v.ID].Reward)
} }
} }
fmt.Println("用户精灵购买总量",totalBuy,"用户精灵收益总量",totalReward) fmt.Println("用户精灵购买总量",totalBuy,"用户精灵收益总量",totalReward)
fmt.Println("先理顺树关系") fmt.Println("先理顺树关系")
checkNum := 0 t1 := time.Now()
checkMap := make(map[int64]int64,0) for _, v := range users {
GOOP: invitation := buildUserInvitation(v.ID)
v.Invitations = invitation
for _,v := range users { if v.Invitor == "" {
fmt.Println(checkNum)
if usersIdMap[v.ID].IsCheck {
continue continue
} }
// 没有上级 inviterId := usersMap[v.Invitor].ID
if v.Invitor == "" { if _,ok := usersInviter[inviterId];!ok {
// 没有下级 usersInviter[inviterId] = []int64{v.ID}
if m,ok := userInviter[v.AccountID];ok { } else {
if len(m) == 0 { usersInviter[inviterId] = append(usersInviter[inviterId],v.ID)
usersIdMap[v.ID].IsCheck = true }
if _,ok := checkMap[v.ID];!ok { }
checkMap[v.ID] = v.ID
} else { orders := make([]*model.OrderRecords,0)
panic("why dup1") err = client.Model(&model.OrderRecords{}).Where("token_id > ? and asset_id > ?",0,0).Find(&orders).Error
} if err != nil {
checkNum++ panic(err)
}
for _, v := range orders {
if _,ok := userElfOrderList[v.UserID];ok {
userElfOrderList[v.UserID] = append(userElfOrderList[v.UserID],v)
} else {
nd := make([]*model.OrderRecords,0)
nd = append(nd,v)
userElfOrderList[v.UserID] = nd
}
}
airs := make([]*model.AirDropTx,0)
err = client.Model(&model.AirDropTx{}).Find(&airs).Error
if err != nil {
panic(err)
}
for _, v := range airs {
if v.ToID <= 1 {
continue
}
if _, ok := userAirdrop[int64(v.ToID)];ok {
userAirdrop[int64(v.ToID)] = append(userAirdrop[int64(v.ToID)],v)
} else {
nd := make([]*model.AirDropTx,0)
nd = append(nd,v)
userAirdrop[int64(v.ToID)] = nd
}
}
fmt.Println("空头记录数量",len(userAirdrop))
fmt.Println("cost",time.Since(t1))
fmt.Println("create tree ok ")
fmt.Println("相关数据加载完成")
}
func initTribe() error {
file := "部落推荐关系.xlsx"
xfile, err := xlsx.OpenFile(file)
if err != nil {
panic(err)
}
fmt.Println("users count",len(usersMap))
tribeMap = make(map[int64]int64, 0)
for _, rows := range xfile.Sheets[0].Rows {
var uid,inviterId int64
for kk,cell := range rows.Cells {
if cell.String() == "" || !strings.Contains(cell.String(),"0x") {
continue
}
addr := cell.String()
addr = strings.TrimSpace(addr)
addr = strings.ReplaceAll(addr,"\n","")
addr = strings.ToLower(addr)
if kk == 0 {
if m,ok := usersMap[addr];ok {
inviterId = m.ID
} else { } else {
// level = 2 fmt.Println(addr,len(addr))
for _, vv := range m { panic("why")
vvId := usersMap[vv].ID
if usersIdMap[vvId].IsCheck {
continue
}
usersIdMap[vvId].IsCheck = true
checkNum++
usersIdMap[vvId].Invitations = fmt.Sprintf("%d,%d",v.ID,vvId)
if _,ok := checkMap[vvId];!ok {
checkMap[vvId] = vvId
} else {
panic("why dup2")
}
}
usersIdMap[v.ID].IsCheck = true
checkNum++
}
} else {
if usersIdMap[v.ID].IsCheck {
continue
} }
usersIdMap[v.ID].IsCheck = true } else if kk == 1 {
checkNum++ if m,ok := usersMap[addr];ok {
if _,ok := checkMap[v.ID];!ok { uid = m.ID
checkMap[v.ID] = v.ID
} else { } else {
panic("why dup3") panic("why")
} }
} }
} else { fmt.Println(cell.String())
if usersIdMap[v.ID].IsCheck { continue
continue }
fmt.Println("tribe uid",uid,"tribe inviterid",inviterId)
if uid > 0 && inviterId > 0 {
if _,ok := tribeMap[uid];!ok{
tribeMap[uid]= inviterId
} else {
panic("not right")
} }
// level >= 3 }
preId := usersIdMap[v.ID].InvitorId }
if preId == 0 { fmt.Println("部落关系初始化成功 条数",len(tribeMap))
panic(err) return nil
}
// 获取地址关系树以及其他统计数据
func getAllUserDetail(addr string) (user *model.Users,err error) {
return
}
func convertPoint(data *model.UserPointTemp) *model.UserPoint {
return &model.UserPoint{
ID: data.ID,
UserID: data.UserID,
AttrLevel: data.AttrLevel,
TokenID: data.TokenID,
Scense: data.Scense,
Point: data.Point,
Processed: data.Processed,
CreateTime: data.CreateTime,
Issued: data.Issued,
}
}
type ElfAccountData struct {
Addr string
Balance float64
Collect float64
Collect2 float64
Withdraw float64
Withdrawing float64
}
// 统计所有地址领取总额 在挖的总额 已提币总额
func TestAccount(t *testing.T) {
var err error
usersAccountData = make(map[int64]*ElfAccountData,0)
initData()
fmt.Println("user total",len(usersIdMap))
fmt.Println("领取记录条数",len(usersIncomeCollect))
fmt.Println("提币记录条数",len(usersIncomeWithdraw))
for k, v := range usersIdMap {
if _,ok := usersAccountData[k];!ok {
usersAccountData[k] = &ElfAccountData{
Addr: v.AccountID,
Collect: 0,
Withdraw: 0,
} }
//有上级 }
// 查看上级是否check for _, vv := range usersIncomeCollect[k] {
if usersIdMap[preId].IsCheck { usersAccountData[k].Collect += vv.Income
usersIdMap[v.ID].Invitations = usersIdMap[preId].Invitations+","+fmt.Sprintf("%d",v.ID) }
fmt.Println("invitations" ,usersIdMap[v.ID].Invitations,"invitor ",usersIdMap[preId].Invitations) for _, vv := range userIncome[k] {
usersIdMap[v.ID].IsCheck = true usersAccountData[k].Collect2 += vv.Income
checkNum++ }
if _,ok := checkMap[v.ID];!ok { for _, vv := range usersIncomeWithdraw[k] {
checkMap[v.ID] = v.ID if vv.Status == 1 {
} else { usersAccountData[k].Withdraw += vv.Amount
panic("why dup4") } else if vv.Status == 0{
} usersAccountData[k].Withdrawing += vv.Amount
} else {
fmt.Println("上级没有check",v.AccountID)
} }
} }
if usersData[k] != nil {
usersAccountData[k].Balance = usersData[k].Income
}
} }
if checkNum < len(users) { err = CreateAccountJob()
goto GOOP if err != nil {
panic(err)
} }
fmt.Println("create tree ok ") }
// 质押算的是月底地址实时的状态 其余参数算累计
func TestElfMonthData(t *testing.T) {
var err error
tl := GetMonthStartAndEnd("2024","04")
initData()
initTribe()
fmt.Println("tribe count",len(tribeMap))
fmt.Println("user inviters",len(usersInviter))
fmt.Println("calc pop reward popBuy") fmt.Println("calc pop reward popBuy")
for _,v := range users { tokenMap := make(map[int64]*model.OrderRecords,0)
usersMapCalc[v.ID].Reward = usersIdMap[v.ID].Reward // 算个人质押 最后一天质押取历史所有订单 && 1号有打造收益的精灵 时间截止月底最后一天
// 统计有上级的地址 // PersonReward Buy BuyList NextAddrs PopAddrs
if v.Invitor != "" { baby := 0
ids := strings.Split(usersIdMap[v.ID].Invitations,",") for k,v := range usersIdMap {
for _,id := range ids { // orders := make([]*model.OrderRecords,0)
iid,err := strconv.Atoi(id) // err = client.Model(&model.OrderRecords{}).Where("user_id = ?",k).Find(&orders).Error
if err != nil { // if err != nil {
panic(err) // panic(err)
// }
// 个人所有订单
for _, vv := range userElfOrderList[k] {
if vv.TokenID > 0 {
if _, ok := tokenMap[vv.TokenID];!ok {
tokenMap[vv.TokenID] = vv
} }
// 更新上级所有地址数据 }
if vv.TokenID > 0 && vv.AssetID > 0 {
if _,ok := sysAsset[vv.AssetID];ok {
usersMapCalc[k].BuyHistory += int64(sysAsset[vv.AssetID].BasePrice)
if usersMapCalc[k].BuyListHistory == nil {
usersMapCalc[k].BuyListHistory = map[int64]int64{19:0,20:0,21:0,22:0,23:0,24:0}
usersMapCalc[k].BuyListHistory[vv.AssetID] += int64(sysAsset[vv.AssetID].BasePrice)
} else {
usersMapCalc[k].BuyListHistory[vv.AssetID] += int64(sysAsset[vv.AssetID].BasePrice)
}
}
}
}
//算个人收益即打造收益 出去成本
for _, vv := range userIncome[k] {
// 时间范围内收益
if vv.CreateTime.Unix() < tl["end"].Unix()+86399 && vv.CreateTime.Unix() > tl["start"].Unix() {
// 更新个人累计收益
if vv.Income >= 200 {
continue
}
usersMapCalc[k].PersonReward += vv.Income
} else if vv.CreateTime.Unix() >= tl["end"].AddDate(0,0,1).Unix() && vv.CreateTime.Unix() < tl["end"].AddDate(0,0,2).Unix(){//1号 精灵打造的收益 说明精灵在上个月最后一天还质押着
if _,ok := tokenMap[vv.TokenID];ok {
// 当前质押BTY
usersMapCalc[k].Buy += int64(sysAsset[vv.AssetID].BasePrice)
if usersMapCalc[k].BuyList == nil {
usersMapCalc[k].BuyList = map[int64]int64{19:0,20:0,21:0,22:0,23:0,24:0}
}
usersMapCalc[k].BuyList[vv.AssetID] += int64(sysAsset[vv.AssetID].BasePrice)
} else {
baby++
continue
}
}
}
// 直推地址数
// usersMapCalc[k].NextAddrs = int64(len(usersInviter[k]))
for _, vv := range usersInviter[k] {
if usersIdMap[vv].CreatedAt.Unix() < tl["end"].AddDate(0,0,1).Unix() {
usersMapCalc[k].NextAddrs++
}
}
if v.Invitations != "" && strings.Contains(v.Invitations,","){
slist := strings.Split(v.Invitations,",")
for _,vv := range slist {
iid,_ := strconv.Atoi(vv)
if int64(iid) != v.ID { if int64(iid) != v.ID {
usersMapCalc[int64(iid)].PopBuy += usersIdMap[int64(iid)].Buy //更新对应上级的伞下地址数
usersMapCalc[int64(iid)].PopReward += usersIdMap[int64(iid)].Reward if v.CreatedAt.Unix() > tl["end"].AddDate(0,0,1).Unix() {
// fmt.Println("addr after time")
continue
}
usersMapCalc[int64(iid)].PopAddrs++ usersMapCalc[int64(iid)].PopAddrs++
} }
} }
} }
// 空投计算
airAmount := 0
for _, vv := range userAirdrop[k] {
airAmount += vv.Amount
}
usersMapCalc[k].AirReward = Decimal(float64(airAmount)/100,2)
}
// 统计直推质押 伞下质押 伞下月产收益
for k,v := range usersIdMap {
if v.Invitations == "" {
continue
}
if !strings.Contains(v.Invitations,",") {
continue
}
list := strings.Split(v.Invitations,",")
for _,vv := range list {
iid ,_ := strconv.Atoi(vv)
if int64(iid) == k {
continue
}
if v.CreatedAt.Unix() > tl["end"].AddDate(0,0,1).Unix() {
continue
}
//iid 都是k用户的上级
usersMapCalc[int64(iid)].PopReward += usersMapCalc[k].PersonReward
usersMapCalc[int64(iid)].PopBuy += usersMapCalc[k].Buy
usersMapCalc[int64(iid)].PopBuyHistory += usersMapCalc[k].BuyHistory
usersMapCalc[int64(iid)].PopAirReward += usersMapCalc[k].AirReward
if usersMapCalc[int64(iid)].PopBuyListHistory == nil {
usersMapCalc[int64(iid)].PopBuyListHistory = map[int64]int64{19:0,20:0,21:0,22:0,23:0,24:0}
usersMapCalc[int64(iid)].PopBuyListHistory[19] += usersMapCalc[k].BuyListHistory[19]
usersMapCalc[int64(iid)].PopBuyListHistory[20] += usersMapCalc[k].BuyListHistory[20]
usersMapCalc[int64(iid)].PopBuyListHistory[21] += usersMapCalc[k].BuyListHistory[21]
usersMapCalc[int64(iid)].PopBuyListHistory[22] += usersMapCalc[k].BuyListHistory[22]
usersMapCalc[int64(iid)].PopBuyListHistory[23] += usersMapCalc[k].BuyListHistory[23]
} else {
usersMapCalc[int64(iid)].PopBuyListHistory[19] += usersMapCalc[k].BuyListHistory[19]
usersMapCalc[int64(iid)].PopBuyListHistory[20] += usersMapCalc[k].BuyListHistory[20]
usersMapCalc[int64(iid)].PopBuyListHistory[21] += usersMapCalc[k].BuyListHistory[21]
usersMapCalc[int64(iid)].PopBuyListHistory[22] += usersMapCalc[k].BuyListHistory[22]
usersMapCalc[int64(iid)].PopBuyListHistory[23] += usersMapCalc[k].BuyListHistory[23]
}
}
// 直推质押
// usersMapCalc[k].NextAddrs = int64(len(usersInviter[k]))
for _, vv := range usersInviter[k] {
if usersIdMap[vv].CreatedAt.Unix() < tl["end"].AddDate(0,0,1).Unix() {
usersMapCalc[k].NextBuy += usersMapCalc[vv].Buy
}
}
}
fmt.Println("baby num",baby)
err = CreateMonthJob()
if err != nil {
panic(err)
} }
fmt.Println("统计完成") err = CreateMonthJob2()
err = CreateXlsxJob()
if err != nil { if err != nil {
panic(err) panic(err)
} }
} }
// 获取地址关系树以及其他统计数据 func CreateAccountJob() error {
func getAllUserDetail(addr string) (user *model.Users,err error) { file := xlsx.NewFile()
return sheet, err := file.AddSheet("地址账户")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"地址", "累计领取","累计领取(2)", "账户余额", "累计提币","提币中",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for _, v := range usersAccountData {
if v.Balance == 0 && v.Collect ==0 && v.Withdraw == 0 && v.Withdrawing == 0 && v.Collect2 == 0{
continue
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //地址
cell.Value = v.Addr
cell = row.AddCell() //累计领取
cell.SetValue(v.Collect)
cell = row.AddCell() //累计领取(2)
cell.SetValue(v.Collect2)
cell = row.AddCell() //账户余额
cell.SetValue(v.Balance)
cell = row.AddCell() //累计提币
cell.SetValue(v.Withdraw)
cell = row.AddCell() //提币中
cell.SetValue(v.Withdrawing)
}
fileName := fmt.Sprintf("%s-账户资产统计.xlsx", "2024-05-10")
err = file.Save(fileName)
if err != nil {
return err
}
return nil
} }
func CreateXlsxJob() error { func CreateMonthJob() error {
file := xlsx.NewFile() file := xlsx.NewFile()
sheet, err := file.AddSheet("部落数据统计") sheet, err := file.AddSheet("部落数据统计")
if err != nil { if err != nil {
...@@ -377,7 +950,7 @@ func CreateXlsxJob() error { ...@@ -377,7 +950,7 @@ func CreateXlsxJob() error {
return err return err
} }
result := []string{ result := []string{
"地址", "收益", "伞下地址数", "伞下质押", "伞下累计收益", "部落地址", "当前质押BTY", "传说质押", "皇冠质押","直推地址数","直推质押BTY","伞下地址数","伞下质押BTY","伞下月产收益","部落奖励","上级部落地址","上级部落奖励",
} }
row := sheet.AddRow() row := sheet.AddRow()
...@@ -387,24 +960,48 @@ func CreateXlsxJob() error { ...@@ -387,24 +960,48 @@ func CreateXlsxJob() error {
cell.Value = v cell.Value = v
} }
for _, v := range usersMapCalc { for k, t := range tribeMap {
row := sheet.AddRow() v := usersMapCalc[k]
row.SetHeightCM(1) //设置每行的高度 if k == 25 {
cell := row.AddCell() //地址 fmt.Println(v.BuyList)
cell.Value = v.Addr }
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //部落地址
cell.Value = v.Addr
cell = row.AddCell() //当前质押BTY
cell.SetValue(v.Buy)
cell = row.AddCell() //传说质押
cell.SetValue(v.BuyList[23])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.BuyList[22])
cell = row.AddCell() //直推地址数
cell.SetValue(v.NextAddrs)
cell = row.AddCell() //收益 cell = row.AddCell() //直推质押BTY
cell.SetValue(v.Reward) cell.SetValue(v.NextBuy)
cell = row.AddCell() //伞下地址数 cell = row.AddCell() //伞下地址数
cell.SetValue(v.PopAddrs) cell.SetValue(v.PopAddrs)
cell = row.AddCell() //伞下质押 cell = row.AddCell() //伞下质押BTY
cell.SetValue(v.PopBuy) cell.SetValue(v.PopBuy)
cell = row.AddCell() //伞下累计收益 cell = row.AddCell() //伞下月产收益
cell.SetValue(v.PopReward) cell.SetValue(v.PopReward)
cell = row.AddCell() //部落奖励
cell.SetValue(v.Reward)
cell = row.AddCell() //上级部落地址
cell.SetValue(usersIdMap[t].AccountID)
cell = row.AddCell() //上级部落奖励
cell.SetValue(v.InviterAddrReward)
} }
fileName := fmt.Sprintf("%s-部落统计.xlsx", "2024-04") fileName := fmt.Sprintf("%s-部落统计.xlsx", "2024-04")
...@@ -413,4 +1010,142 @@ func CreateXlsxJob() error { ...@@ -413,4 +1010,142 @@ func CreateXlsxJob() error {
return err return err
} }
return nil return nil
}
func CreateMonthJob2() error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("部落数据统计2")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"部落地址", "传说质押", "皇冠质押","璀璨","晶核","原石","伞下累计质押BTY","伞下累计空投","上级部落地址",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for k, t := range tribeMap {
v := usersMapCalc[k]
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //部落地址
cell.Value = v.Addr
cell = row.AddCell() //传说质押
cell.SetValue(v.PopBuyListHistory[23])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[22])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[21])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[20])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[19])
cell = row.AddCell() //伞下质押BTY
cell.SetValue(v.PopBuyHistory)
cell = row.AddCell() //伞下空投Y
cell.SetValue(v.PopAirReward)
cell = row.AddCell() //上级部落地址
cell.SetValue(usersIdMap[t].AccountID)
}
fileName := fmt.Sprintf("%s-部落统计2.xlsx", "2024-05-10")
err = file.Save(fileName)
if err != nil {
return err
}
return nil
}
func CreatePointJob() error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("积分统计")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"地址","是否有资产", "今日召唤", "今日道具", "总积分值", "通关","邀请","助力","通过指导","锁仓","锁仓指导","回收","注册时间","邀请人",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for _, v := range usersMapPoint {
if v.TotalPoint == 0 {
continue
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //地址
cell.Value = v.Addr
cell = row.AddCell()
if v.HasAsset {
cell.SetValue(1)
} else {
cell.SetValue(0)
}
cell = row.AddCell() // 今日召唤
cell.SetValue(v.DayAsset)
cell = row.AddCell() // 今日道具
cell.SetValue(v.DayTool)
cell = row.AddCell() // 总积分值
cell.SetValue(v.TotalPoint)
cell = row.AddCell() // 通关
cell.SetValue(v.PassPoint)
cell = row.AddCell() // 邀请
cell.SetValue(v.InvitePoint)
cell = row.AddCell() // 助力
cell.SetValue(v.HelpPoint)
cell = row.AddCell() // 通过指导
cell.SetValue(v.PassGuide)
cell = row.AddCell() // 锁仓
cell.SetValue(v.FrozenPoint)
cell = row.AddCell() // 锁仓指导
cell.SetValue(v.FrozenGuide)
cell = row.AddCell() // 回收
cell.SetValue(v.RecoverPoint)
cell = row.AddCell() // 注册时间
cell.SetValue(v.RegDate)
cell = row.AddCell() // 邀请人
cell.SetValue(v.Invitor)
}
fileName := fmt.Sprintf("%s-积分统计.xlsx", GetTodayTime("2006-01-02").Format("2006-01-02"))
err = file.Save(fileName)
if err != nil {
return err
}
return nil
} }
\ No newline at end of file
...@@ -84,6 +84,11 @@ func (obj *_AirDropTxMgr) WithToID(toID int) Option { ...@@ -84,6 +84,11 @@ func (obj *_AirDropTxMgr) WithToID(toID int) Option {
return optionFunc(func(o *options) { o.query["to_id"] = toID }) return optionFunc(func(o *options) { o.query["to_id"] = toID })
} }
// WithTo to获取
func (obj *_AirDropTxMgr) WithTo(to string) Option {
return optionFunc(func(o *options) { o.query["to"] = to })
}
// WithAmount amount获取 // WithAmount amount获取
func (obj *_AirDropTxMgr) WithAmount(amount int) Option { func (obj *_AirDropTxMgr) WithAmount(amount int) Option {
return optionFunc(func(o *options) { o.query["amount"] = amount }) return optionFunc(func(o *options) { o.query["amount"] = amount })
......
...@@ -11,6 +11,7 @@ type AirDropTx struct { ...@@ -11,6 +11,7 @@ type AirDropTx struct {
Height int `gorm:"column:height" json:"height"` Height int `gorm:"column:height" json:"height"`
UserID int `gorm:"column:user_id" json:"userId"` UserID int `gorm:"column:user_id" json:"userId"`
ToID int `gorm:"column:to_id" json:"toId"` ToID int `gorm:"column:to_id" json:"toId"`
To string `gorm:"column:to" json:"to"`
Amount int `gorm:"column:amount" json:"amount"` Amount int `gorm:"column:amount" json:"amount"`
Blocktime int `gorm:"column:blocktime" json:"blocktime"` Blocktime int `gorm:"column:blocktime" json:"blocktime"`
} }
......
package tool
import (
"flag"
"fmt"
"strings"
"time"
elfGame "elf"
"elf/model"
"github.com/33cn/chain33/types"
"github.com/tealeg/xlsx"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var client *gorm.DB
// addr => info
var usersMap map[string]*model.Users
// id => info
var usersIdMap map[int64]*model.Users
// month data map
var usersMapCalc map[int64]*CalcData
// day point map
var usersMapPoint map[int64]*CalcPointData
var topList []string
// 系统精灵列表
var sysAsset map[int64]*model.SystemAsset
// 实时精灵
var userAsset map[int64][]*model.UserAsset
// 精灵打造历史
var userIncome map[int64][]*model.UserAssetIncome
// 用户积分列表历史
var userPointList map[int64][]*model.UserPoint
// 用户订单列表历史
var userOrderList map[int64][]*model.OrderRecords
// 用户精灵列表历史
var userElfOrderList map[int64][]*model.OrderRecords
// 推荐关系 地址 =》 下级
var usersInviter map[int64][]int64
// 部落关系表 部落=>上级部落
var tribeMap map[int64]int64
// 用户领取列表
var usersIncomeCollect map[int64][]*model.AssetIncomeCollect
// 用户提币列表
var usersIncomeWithdraw map[int64][]*model.AssetIncomeWithdraw
// 账户统计
var usersAccountData map[int64]*ElfAccountData
var usersData map[int64]*model.UserData
// 用户空投记录
var userAirdrop map[int64][]*model.AirDropTx
const PerCent = 100
const FixTime = 0 //3600 * 8
const AIR = "0x99ba98bf40135d181bf20db9962dd916f53b5e58"
var chain33Client types.Chain33Client
type CalcData struct {
Addr string //部落地址
PersonReward float64 //个人累计打造收益
InviterAddr string //上级部落
InviterAddrReward float64 //上级部落
Reward float64 //部落收益
NextBuy int64 // 直推质押BTY
NextAddrs int64 // 直推地址数
PopBuy int64 // 伞下质押BTY
PopAddrs int64 // 伞下地址数
PopReward float64 // 伞下累计收益
BuyList map[int64]int64 //自己购买统计 精灵->数量
Buy int64 // 当前质押
BuyListHistory map[int64]int64 //自己累计购买
PopBuyListHistory map[int64]int64 //伞下累计购买
NextBuyHistory int64 // 直推质押BTY累计
PopBuyHistory int64 // 伞下质押BTY累计
BuyHistory int64 // 累计质押
AirReward float64
PopAirReward float64 // 空投
}
type CalcPointData struct {
Id int64
Addr string
DayAsset int64 // 今日召唤精灵
DayTool int64 // 今日道具
TotalPoint float64 // 总积分值
PassPoint float64 // 通关积分
InvitePoint float64 // 邀请积分
HelpPoint float64 // 助力积分
PassGuide float64 // 通关指导
FrozenPoint float64 // 锁仓
FrozenGuide float64 // 锁仓指导
RecoverPoint float64 // 回收积分
RegDate string // 注册时间
Invitor string // 邀请人
HasAsset bool // 是否有精灵 包括可升级的
MiningAmount int64 // 精灵打造收益
}
type ElfAccountData struct {
Addr string
Balance float64
Collect float64
Collect2 float64
Withdraw float64
Withdrawing float64
}
func init2() {
dsn := "root:fzm123456@tcp(192.168.122.119:3306)/elf?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
sd,err := db.DB()
sd.SetMaxOpenConns(100)
sd.SetMaxIdleConns(10)
client = db
chain33Client, _ = elfGame.NewGrpcClient("172.16.100.93:8802")
}
var tag = flag.Int("t",0,"脚本任务类型 0 积分榜")
var root = flag.String("r","root","mysql account")
var pwd = flag.String("p","fzm123456","mysql password")
var host = flag.String("h","192.168.122.119:3306","mysql host")
var database = flag.String("d","elf","mysql database")
var chain33Host = flag.String("c","cloud.bityuan.com","bty grpc host")
func main() {
flag.Parse()
dsn := "root:fzm123456@tcp(192.168.122.119:3306)/elf?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
sd,err := db.DB()
sd.SetMaxOpenConns(100)
sd.SetMaxIdleConns(10)
client = db
chain33Client, _ = elfGame.NewGrpcClient("172.16.100.93:8802")
}
// 初始化一些数据 方便调用
func initData() {
//tl := GetMonthStartAndEnd("2024","04")
users := make([]*model.Users,0)
var err error
// get all user
err = client.Model(&model.Users{}).Find(&users).Error
if err != nil {
panic(err)
}
fmt.Println("total addr",len(users))
for _,v := range users {
v.AccountID = strings.ToLower(v.AccountID)
v.Invitor = strings.ToLower(v.Invitor)
}
userAirdrop =make(map[int64][]*model.AirDropTx,0)
userElfOrderList = make(map[int64][]*model.OrderRecords,0)
usersData = make(map[int64]*model.UserData,0)
usersIncomeCollect = make(map[int64][]*model.AssetIncomeCollect,0)
// 用户提币列表
usersIncomeWithdraw = make(map[int64][]*model.AssetIncomeWithdraw,0)
usersInviter = make(map[int64][]int64,0)
userOrderList = make(map[int64][]*model.OrderRecords,0)
userPointList = make(map[int64][]*model.UserPoint,0)
usersMap = make(map[string]*model.Users,0)
usersIdMap = make(map[int64]*model.Users,0)
// get all asset list 200 1000 2000 5000 10000
sysAsset = make(map[int64]*model.SystemAsset,0)
assets := make([]*model.SystemAsset,0)
err = client.Debug().Table("system_asset").Find(&assets).Error
if err != nil {
panic(err)
}
for _, v := range assets {
sysAsset[v.ID] = v
}
userAsset = make(map[int64][]*model.UserAsset,0)
userIncome = make(map[int64][]*model.UserAssetIncome,0)
buys := make([]*model.UserAsset,0)
err = client.Debug().Table("user_asset").Find(&buys).Error
if err != nil {
panic(err)
}
fmt.Println("total user asser num",len(buys))
for _,v := range buys {
if _,ok := userAsset[v.UserID];ok{
userAsset[v.UserID] = append(userAsset[v.UserID],v)
} else {
nb := make([]*model.UserAsset,0)
nb = append(nb,v)
userAsset[v.UserID] = nb
}
}
incomeList := make([]*model.UserAssetIncome,0)
err = client.Debug().Table("user_asset_income").Find(&incomeList).Error
if err != nil {
panic(err)
}
fmt.Println("total user asset income num",len(incomeList))
for _,v := range incomeList {
if _,ok := userIncome[v.UserID];ok{
userIncome[v.UserID] = append(userIncome[v.UserID],v)
} else {
nb := make([]*model.UserAssetIncome,0)
nb = append(nb,v)
userIncome[v.UserID] = nb
}
}
aic := make([]*model.AssetIncomeCollect,0)
err = client.Debug().Model(&model.AssetIncomeCollect{}).Find(&aic).Error
if err != nil {
panic(err)
}
for _,v := range aic {
if _, ok := usersIncomeCollect[v.UserID];!ok {
nd := make([]*model.AssetIncomeCollect,0)
nd = append(nd,v)
usersIncomeCollect[v.UserID] = nd
} else {
usersIncomeCollect[v.UserID] = append(usersIncomeCollect[v.UserID],v)
}
}
aiw := make([]*model.AssetIncomeWithdraw,0)
err = client.Debug().Model(&model.AssetIncomeWithdraw{}).Find(&aiw).Error
if err != nil {
panic(err)
}
for _,v := range aiw {
if _, ok := usersIncomeWithdraw[v.UserID];!ok {
nd := make([]*model.AssetIncomeWithdraw,0)
nd = append(nd,v)
usersIncomeWithdraw[v.UserID] = nd
} else {
usersIncomeWithdraw[v.UserID] = append(usersIncomeWithdraw[v.UserID],v)
}
}
usersD := make([]*model.UserData,0)
err = client.Model(&model.UserData{}).Find(&usersD).Error
if err != nil {
panic(err)
}
for _, v := range usersD {
if _, ok:= usersData[v.ID];!ok {
usersData[v.ID] = v
}
}
usersMapCalc = make(map[int64]*CalcData,0)
topList = make([]string,0)
nextNum := 0
// 找出top地址列表 生成 usersMap 和 usersIdMap表
for _,v := range users {
usersMapCalc[v.ID] = &CalcData{
Addr:v.AccountID,
}
usersMap[v.AccountID] = v
usersIdMap[v.ID] = v
}
fmt.Println("top num",len(topList),"next num",nextNum)
totalBuy := 0
totalReward := float64(0)
// 补全 InvitorId 以及个人购买精灵量
for _,v := range users {
if v.Invitor != "" {
if iid, ok := usersMap[v.Invitor];ok {
usersMap[v.AccountID].InvitorId = iid.ID
usersIdMap[v.ID].InvitorId = iid.ID
} else {
fmt.Println(v.Invitor,v.AccountID,usersMap[v.Invitor])
panic("not go here")
}
}
// 用户精灵实时统计
if data, ok := userAsset[v.ID];ok {
for _,vv := range data {
if _, ok2 := sysAsset[vv.AssetID];ok2 {
usersIdMap[v.ID].Buy += int64(sysAsset[vv.AssetID].BasePrice)
totalBuy += sysAsset[vv.AssetID].BasePrice
}
}
}
if usersIdMap[v.ID].Buy > 0 {
//fmt.Println("用户精灵购买",usersIdMap[v.ID].Buy,"用户精灵收益",usersIdMap[v.ID].Reward)
}
}
fmt.Println("用户精灵购买总量",totalBuy,"用户精灵收益总量",totalReward)
fmt.Println("先理顺树关系")
t1 := time.Now()
for _, v := range users {
invitation := buildUserInvitation(v.ID)
v.Invitations = invitation
if v.Invitor == "" {
continue
}
inviterId := usersMap[v.Invitor].ID
if _,ok := usersInviter[inviterId];!ok {
usersInviter[inviterId] = []int64{v.ID}
} else {
usersInviter[inviterId] = append(usersInviter[inviterId],v.ID)
}
}
orders := make([]*model.OrderRecords,0)
err = client.Model(&model.OrderRecords{}).Where("token_id > ? and asset_id > ?",0,0).Find(&orders).Error
if err != nil {
panic(err)
}
for _, v := range orders {
if _,ok := userElfOrderList[v.UserID];ok {
userElfOrderList[v.UserID] = append(userElfOrderList[v.UserID],v)
} else {
nd := make([]*model.OrderRecords,0)
nd = append(nd,v)
userElfOrderList[v.UserID] = nd
}
}
airs := make([]*model.AirDropTx,0)
err = client.Model(&model.AirDropTx{}).Find(&airs).Error
if err != nil {
panic(err)
}
for _, v := range airs {
if v.ToID <= 1 {
continue
}
if _, ok := userAirdrop[int64(v.ToID)];ok {
userAirdrop[int64(v.ToID)] = append(userAirdrop[int64(v.ToID)],v)
} else {
nd := make([]*model.AirDropTx,0)
nd = append(nd,v)
userAirdrop[int64(v.ToID)] = nd
}
}
fmt.Println("空头记录数量",len(userAirdrop))
fmt.Println("cost",time.Since(t1))
fmt.Println("create tree ok ")
fmt.Println("相关数据加载完成")
}
func buildUserInvitation(uid int64) string {
if uid == 0 {
panic("wrong uid")
}
if _,ok := usersIdMap[uid];ok {
if usersIdMap[uid].Invitor == "" {
return fmt.Sprintf("%d",uid)
} else {
invitation := buildUserInvitation(usersIdMap[uid].InvitorId)
return fmt.Sprintf("%s,%d",invitation,uid)
}
} else {
panic("uid not exist")
}
}
func initTribe() error {
file := "部落推荐关系.xlsx"
xfile, err := xlsx.OpenFile(file)
if err != nil {
panic(err)
}
fmt.Println("users count",len(usersMap))
tribeMap = make(map[int64]int64, 0)
for _, rows := range xfile.Sheets[0].Rows {
var uid,inviterId int64
for kk,cell := range rows.Cells {
if cell.String() == "" || !strings.Contains(cell.String(),"0x") {
continue
}
addr := cell.String()
addr = strings.TrimSpace(addr)
addr = strings.ReplaceAll(addr,"\n","")
addr = strings.ToLower(addr)
if kk == 0 {
if m,ok := usersMap[addr];ok {
inviterId = m.ID
} else {
fmt.Println(addr,len(addr))
panic("why")
}
} else if kk == 1 {
if m,ok := usersMap[addr];ok {
uid = m.ID
} else {
panic("why")
}
}
fmt.Println(cell.String())
continue
}
fmt.Println("tribe uid",uid,"tribe inviterid",inviterId)
if uid > 0 && inviterId > 0 {
if _,ok := tribeMap[uid];!ok{
tribeMap[uid]= inviterId
} else {
panic("not right")
}
}
}
fmt.Println("部落关系初始化成功 条数",len(tribeMap))
return nil
}
func CreateMonthJob() error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("部落数据统计")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"部落地址", "当前质押BTY", "传说质押", "皇冠质押","直推地址数","直推质押BTY","伞下地址数","伞下质押BTY","伞下月产收益","部落奖励","上级部落地址","上级部落奖励",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for k, t := range tribeMap {
v := usersMapCalc[k]
if k == 25 {
fmt.Println(v.BuyList)
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //部落地址
cell.Value = v.Addr
cell = row.AddCell() //当前质押BTY
cell.SetValue(v.Buy)
cell = row.AddCell() //传说质押
cell.SetValue(v.BuyList[23])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.BuyList[22])
cell = row.AddCell() //直推地址数
cell.SetValue(v.NextAddrs)
cell = row.AddCell() //直推质押BTY
cell.SetValue(v.NextBuy)
cell = row.AddCell() //伞下地址数
cell.SetValue(v.PopAddrs)
cell = row.AddCell() //伞下质押BTY
cell.SetValue(v.PopBuy)
cell = row.AddCell() //伞下月产收益
cell.SetValue(v.PopReward)
cell = row.AddCell() //部落奖励
cell.SetValue(v.Reward)
cell = row.AddCell() //上级部落地址
cell.SetValue(usersIdMap[t].AccountID)
cell = row.AddCell() //上级部落奖励
cell.SetValue(v.InviterAddrReward)
}
fileName := fmt.Sprintf("%s-部落统计.xlsx", "2024-04")
err = file.Save(fileName)
if err != nil {
return err
}
return nil
}
func CreateMonthJob2() error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("部落数据统计2")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"部落地址", "传说质押", "皇冠质押","璀璨","晶核","原石","伞下累计质押BTY","伞下累计空投","上级部落地址",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for k, t := range tribeMap {
v := usersMapCalc[k]
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //部落地址
cell.Value = v.Addr
cell = row.AddCell() //传说质押
cell.SetValue(v.PopBuyListHistory[23])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[22])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[21])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[20])
cell = row.AddCell() //皇冠质押
cell.SetValue(v.PopBuyListHistory[19])
cell = row.AddCell() //伞下质押BTY
cell.SetValue(v.PopBuyHistory)
cell = row.AddCell() //伞下空投Y
cell.SetValue(v.PopAirReward)
cell = row.AddCell() //上级部落地址
cell.SetValue(usersIdMap[t].AccountID)
}
fileName := fmt.Sprintf("%s-部落统计2.xlsx", "2024-05-10")
err = file.Save(fileName)
if err != nil {
return err
}
return nil
}
func CreatePointJob() error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("积分统计")
if err != nil {
fmt.Println(err)
return err
}
result := []string{
"地址","是否有资产", "今日召唤", "今日道具", "总积分值", "通关","邀请","助力","通过指导","锁仓","锁仓指导","回收","注册时间","邀请人",
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
for _, v := range result {
cell := row.AddCell()
cell.Value = v
}
for _, v := range usersMapPoint {
if v.TotalPoint == 0 {
continue
}
row := sheet.AddRow()
row.SetHeightCM(1) //设置每行的高度
cell := row.AddCell() //地址
cell.Value = v.Addr
cell = row.AddCell()
if v.HasAsset {
cell.SetValue(1)
} else {
cell.SetValue(1)
}
cell = row.AddCell() // 今日召唤
cell.SetValue(v.DayAsset)
cell = row.AddCell() // 今日道具
cell.SetValue(v.DayTool)
cell = row.AddCell() // 总积分值
cell.SetValue(v.TotalPoint)
cell = row.AddCell() // 通关
cell.SetValue(v.PassPoint)
cell = row.AddCell() // 邀请
cell.SetValue(v.InvitePoint)
cell = row.AddCell() // 助力
cell.SetValue(v.HelpPoint)
cell = row.AddCell() // 通过指导
cell.SetValue(v.PassGuide)
cell = row.AddCell() // 锁仓
cell.SetValue(v.FrozenPoint)
cell = row.AddCell() // 锁仓指导
cell.SetValue(v.FrozenGuide)
cell = row.AddCell() // 回收
cell.SetValue(v.RecoverPoint)
cell = row.AddCell() // 注册时间
cell.SetValue(v.RegDate)
cell = row.AddCell() // 邀请人
cell.SetValue(v.Invitor)
}
fileName := fmt.Sprintf("%s-积分统计.xlsx", elfGame.GetTodayTime("2006-01-02").Format("2006-01-02"))
err = file.Save(fileName)
if err != nil {
return err
}
return nil
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment