task-svr/src/queryScoreList.ts
2024-07-09 11:22:29 +08:00

245 lines
7.9 KiB
TypeScript

import * as dotenv from 'dotenv'
const envFile = process.env.NODE_ENV && process.env.NODE_ENV === 'production' ? `.env.production` : '.env.development'
dotenv.config({ path: envFile })
console.log(process.env.DB_MAIN)
import mongoose from 'mongoose'
import { ActivityUser } from 'models/ActivityUser'
import { ScoreRecord } from 'models/ScoreRecord'
import { ZRedisClient } from 'zutils'
import { formatNumShow } from 'common/Utils'
import { RANK_SCORE_SCALE } from 'common/Constants'
import { InGameScoreRecord } from 'models/InGameScoreRecord'
import { DeleteRecord } from 'models/DeleteRecord'
import { Types } from 'mongoose'
import { InGameStats } from 'models/InGameStats'
import { NFTHolderRecord } from 'models/NFTHodlerRecord'
let fs = require('fs')
/**
* 生成积分明细
*/
mongoose.set('debug', false)
const ACTIVITY = 'uaw_activity'
const totalKey = 'uaw_activity:static:score'
const gameTotalKey = 'uaw_activity:static:gamescore'
const releationKey = `uaw_score_invite_rebate`
const pageSize = 100
const updateRedis2 = (key, vals) => {
return new Promise((resolve, reject) => {
new ZRedisClient().pub.zadd(key, vals, function (err, res) {
if (err) {
reject(err)
} else {
resolve(res)
}
})
})
}
const saveScoreToRedis = async () => {
let records = await ScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
let vals = []
for (let i = 0, l = records.length; i < l; i++) {
if (records[i].count == 0) {
continue
}
vals.push((records[i].count * RANK_SCORE_SCALE) | 0)
vals.push(records[i]._id)
if (i % 1000 === 0) {
await updateRedis2(totalKey, vals)
vals.length = 0
}
}
if (vals.length > 0) {
await updateRedis2(totalKey, vals)
}
}
const saveTypeScoreToRedis = async (type: string) => {
const key = `uaw_score_${type}`
await new ZRedisClient().del(key)
let records = await ScoreRecord.aggregate([
{ $match: { type } },
{ $group: { _id: '$user', count: { $sum: '$score' } } },
])
let vals = []
for (let i = 0, l = records.length; i < l; i++) {
if (records[i].count == 0) {
continue
}
vals.push((records[i].count * RANK_SCORE_SCALE) | 0)
vals.push(records[i]._id)
if (i % 1000 === 0) {
await updateRedis2(key, vals)
vals.length = 0
}
}
if (vals.length > 0) {
await updateRedis2(key, vals)
}
}
const generateScoreList = async (start: number) => {
let end = start + pageSize
const records = await new ZRedisClient().zrevrange(totalKey, start, end)
let results = []
for (let i = 0; i < records.length; i += 2) {
const id = records[i]
let score = formatNumShow(parseInt(records[i + 1]) / RANK_SCORE_SCALE)
const releatScore = await new ZRedisClient().zscore(releationKey, id)
const releatScoreShow = formatNumShow(releatScore ? parseInt(releatScore + '') / RANK_SCORE_SCALE : 0)
const user = await ActivityUser.findById(id)
const rank = start + i / 2 + 1
results.push(
`${rank}\t${user?.address}\t${score}\t${releatScoreShow}\t${holderMap.get(user?.address.toLowerCase()) || 1}\t${founderSet.has(user.address) ? 1 : 0}\t${explorerSet.has(user.address) ? 1 : 0}\t${badgeSet.has(user.address) ? 1 : 0}\t${candySet.has(user.address) ? 1 : 0}`,
)
}
fs.writeFileSync('outdatas/scorelist.txt', results.join('\n') + '\n', { flag: 'a+' })
}
const saveGameScoreToRedis = async () => {
let records = await InGameScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
let vals = []
for (let i = 0, l = records.length; i < l; i++) {
if (records[i].count == 0) {
continue
}
vals.push((records[i].count * 100) | 0)
vals.push(records[i]._id)
if (i % 1000 === 0) {
await updateRedis2(gameTotalKey, vals)
vals.length = 0
}
}
if (vals.length > 0) {
await updateRedis2(gameTotalKey, vals)
}
}
const generateGameScoreList = async (start: number) => {
let end = start + pageSize
// const records = await new ZRedisClient().zrevrange(gameTotalKey, start, end)
const records = await InGameStats.find({ score: { $gt: 0 } })
.sort({ score: -1 })
.skip(start)
.limit(pageSize)
let results = []
for (let i = 0; i < records.length; i++) {
let score = records[i].score
if (score === 0) {
continue
}
let address = ''
const user = await ActivityUser.findById(records[i].user)
if (!user) {
const userDel = await DeleteRecord.findOne({ 'data._id': new Types.ObjectId(records[i].user) })
if (userDel) {
address = userDel.data.address
}
} else {
address = user.address
}
const rank = start + i + 1
results.push(`${rank}\t${address}\t${score}`)
}
fs.writeFileSync('outdatas/gameScorelist.txt', results.join('\n') + '\n', { flag: 'a+' })
}
const generateWhiteList = async () => {
let records = await ActivityUser.find({ whiteListNum: { $gt: 0 } })
let results = []
for (let i = 0; i < records.length; i++) {
results.push(`${records[i].address} \t ${records[i].whiteListNum}`)
}
let records2 = await DeleteRecord.find({ 'data.whiteListNum': { $gt: 0 } })
for (let i = 0; i < records2.length; i++) {
results.push(`${records2[i].data.address} \t ${records2[i].data.whiteListNum}`)
}
fs.writeFileSync('outdatas/whitelist.txt', results.join('\n') + '\n', { flag: 'a+' })
}
const holders = [
['explorer', '0x0cee888fa25810ca648d697099bc17a2c9e1dfbf', 1.5],
['candy', '0xefd4c863e73e7e9cc33d46fb30ce51510fcfdeb0', 1.5],
['badge', '0xd728de3d9ebed90e84abe84539280cbc5b18e304', 2],
['founder', '0xec23679653337d4c6390d0eeba682246a6067777', 3],
]
const holderMap = new Map()
let explorerSet = new Set()
let candySet = new Set()
let badgeSet = new Set()
let founderSet = new Set()
const queryHolder = async () => {
for (let holder of holders) {
const [name, contract] = holder
let records = await NFTHolderRecord.find({ contract: contract + '' })
for (let i = 0; i < records.length; i++) {
const uid = records[i].user
let user = await ActivityUser.findById(uid)
if (!user) {
continue
}
let address = user.address.toLowerCase()
if (name === 'explorer') {
explorerSet.add(address)
} else if (name === 'candy') {
candySet.add(address)
} else if (name === 'badge') {
badgeSet.add(address)
} else if (name === 'founder') {
founderSet.add(address)
}
if (!holderMap.has(address)) {
holderMap.set(address, 1)
}
holderMap.set(address, holderMap.get(address) * parseFloat(holder[2] + ''))
}
}
}
;(async () => {
try {
let opts = { url: process.env.REDIS }
new ZRedisClient(opts)
await new ZRedisClient().del(totalKey)
// await new ZRedisClient().del(gameTotalKey)
console.time('update redis')
await saveScoreToRedis()
console.timeEnd('update redis')
console.time('query holder info')
await queryHolder()
console.timeEnd('query holder info')
console.time('update releation redis')
await saveTypeScoreToRedis('invite_rebate')
console.timeEnd('update releation redis')
console.time('generate score list')
const total = (await new ZRedisClient().zcard(totalKey)) as number
for (let i = 0; i < total; i += pageSize) {
await generateScoreList(i)
}
console.timeEnd('generate score list')
// console.time('update game redis')
// await saveGameScoreToRedis()
// console.timeEnd('update game redis')
// console.time('generate game score list')
// const totalGame = (await new ZRedisClient().zcard(gameTotalKey)) as number
// const totalGame = await InGameStats.countDocuments({ score: { $gt: 0 } })
// for (let i = 0; i < totalGame; i += pageSize) {
// await generateGameScoreList(i)
// }
// console.timeEnd('generate game score list')
// console.time('generate white list')
// await generateWhiteList()
// console.timeEnd('generate white list')
} catch (e) {
console.log(e)
}
console.log('end')
process.exit(0)
})()