aozhiwei 6e391ae87a 1
2024-07-29 14:14:20 +08:00

225 lines
5.7 KiB
Go

package task
import (
"q5"
"f5"
"mt"
"main/service"
"jccommon"
"main/constant"
"time"
"fmt"
)
type contribution struct {
lockMetas []*mt.Contract
}
type accountStacking struct {
accountAddress string
nfts []*jccommon.NftStacking
}
func (this* accountStacking) calcScore() float64 {
return jccommon.CalcContributionScore(this.nfts)
}
func (this* accountStacking) getNftJsonData() string {
uPo := jccommon.NewUserStackingPo()
uPo.AccountAddress = this.accountAddress
cPoHash := new(q5.ConcurrentMap[string, *jccommon.ContractStackingPo])
for _, v := range this.nfts {
key := fmt.Sprintf("%d_%s_%d", v.NetId, v.ContractAddress, v.TokenType)
nPo := jccommon.NewNftStackingPo()
nPo.TokenId = v.TokenId
nPo.ItemId = v.ItemId
nPo.Quality = v.Quality
if cPo, ok := cPoHash.Load(key); ok {
q5.AppendSlice(&(*cPo).Nfts, nPo)
} else {
cPo := jccommon.NewContractStackingPo()
cPo.NetId = v.NetId
cPo.ContractAddress = v.ContractAddress
cPo.TokenType = v.TokenType
q5.AppendSlice(&uPo.Contracts, cPo)
q5.AppendSlice(&cPo.Nfts, nPo)
cPoHash.Store(key, cPo)
}
}
return q5.EncodeJson(uPo)
}
func (this* contribution) init() {
this.lockMetas = []*mt.Contract{}
mt.Table.Contract.Traverse(func (ele *mt.Contract) bool {
if ele.GetName() == jccommon.CONTRACT_NAME_NFTLock {
q5.AppendSlice(&this.lockMetas, ele)
f5.GetSysLog().Info("task.contribution.init load lockMetas net_id:%d name:%s contract_address:%s",
ele.GetNetId(),
ele.GetName(),
ele.GetAddress())
}
return true
})
if len(this.lockMetas) <= 0 {
panic("task.contribution.init lockMetas is empty")
return
}
go this.calc()
}
func (this* contribution) unInit() {
}
func (this* contribution) stat(statTime int64, nowTime int64) {
service.RepairAllHeroNftQuality()
for true {
if this.internalStat(statTime, nowTime) {
return
}
time.Sleep(time.Second * 60)
}
}
func (this* contribution) internalStat(statTime int64, nowTime int64) bool {
if len(this.lockMetas) <= 0 {
panic("task.contribution.internalStat lockMetas is empty")
return false
}
statDaySeconds := q5.GetDaySeconds(statTime, 0)
if statDaySeconds <= 0 {
panic("task.contribution.statDayseconds error")
return true
}
if err, ok := this.isStatEd(statDaySeconds); err != nil {
return false
} else {
if ok {
return true
}
}
{
addressHash := new(q5.ConcurrentMap[string, *accountStacking])
sqlTpl := "SELECT * FROM t_nft WHERE idx > %d AND token_type <> ? AND last_lock_time <= ? AND owner_address IN ("
params := []string{
q5.ToString(jccommon.NFT_TYPE_GOLD_BULLION),
q5.ToString(statDaySeconds),
}
{
inited := false
for _, lockMeta := range this.lockMetas {
if !inited {
inited = true
sqlTpl += "?"
} else {
sqlTpl += ",?"
}
q5.AppendSlice(&params, lockMeta.GetAddress())
}
sqlTpl += ") ORDER BY idx LIMIT 1000"
}
err := f5.GetGoStyleDb().BatchLoadFullTable(
constant.BCNFT_DB,
func (lastIdx int64) string {
sql := fmt.Sprintf(sqlTpl, lastIdx)
return sql
},
params,
func () {
time.Sleep(time.Millisecond * 10)
},
func (ds *f5.DataSet) bool {
return this.loadFromDb(addressHash, ds)
})
if err != nil {
return false
}
return this.saveToDb(statDaySeconds, addressHash)
}
}
func (this* contribution) calc() {
for true {
nowTime := f5.GetApp().GetRealSeconds()
this.stat(nowTime - 3600 * 24, nowTime)
nowTime = f5.GetApp().GetRealSeconds()
daySeconds := q5.GetDaySeconds(nowTime, 0)
sleepTime := daySeconds + 3600 * 24 - nowTime + 3
time.Sleep(time.Second * time.Duration(sleepTime))
}
}
func (this* contribution) isStatEd(statDaySeconds int64) (error, bool) {
return nil, false
}
func (this* contribution) loadFromDb(addressHash *q5.ConcurrentMap[string, *accountStacking],
ds *f5.DataSet) bool {
accountAddress := ds.GetByName("last_lock_address")
if accountAddress == "" {
return true
}
ownerAddress := ds.GetByName("owner_address")
p := new(jccommon.NftStacking)
p.NetId = q5.ToInt32(ds.GetByName("net_id"))
p.ContractAddress = ds.GetByName("contract_address")
p.TokenType = q5.ToInt32(ds.GetByName("token_type"))
p.TokenId = ds.GetByName("token_id")
p.ItemId = q5.ToInt32(ds.GetByName("item_id"))
p.Quality = q5.ToInt32(ds.GetByName("quality"))
lockMeta := mt.Table.Contract.GetByNetIdName(p.NetId, jccommon.CONTRACT_NAME_NFTLock)
if lockMeta == nil {
return true
}
if lockMeta.GetAddress() != ownerAddress {
return true
}
if a, ok := addressHash.Load(accountAddress); ok {
q5.AppendSlice(&(*a).nfts, p)
} else {
a := new(accountStacking)
a.accountAddress = accountAddress
a.nfts = []*jccommon.NftStacking{}
q5.AppendSlice(&a.nfts, p)
addressHash.Store(accountAddress, a)
}
return true
}
func (this* contribution) saveToDb(
statDaySeconds int64,
addressHash *q5.ConcurrentMap[string, *accountStacking]) bool {
var resultErr error
nowTime := f5.GetApp().GetRealSeconds()
addressHash.Range(func (k string, v *accountStacking) bool {
score := v.calcScore()
nftData := v.getNftJsonData()
f5.GetGoStyleDb().Upsert(
constant.BCNFT_DB,
"t_staking_daily_settlement",
[][]string{
{"account_address", v.accountAddress},
{"settle_date", q5.ToString(statDaySeconds)},
},
[][]string{
{"last_contribution", q5.ToString(score)},
{"last_nft_data", nftData},
{"modifytime", q5.ToString(nowTime)},
},
[][]string{
{"account_address", v.accountAddress},
{"settle_date", q5.ToString(statDaySeconds)},
{"contribution", q5.ToString(score)},
{"nft_data", nftData},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
},
func (err error, lastInsertId int64, rowsAffected int64) {
resultErr = err
})
return resultErr == nil
})
return resultErr == nil
}