增加修复数据的脚本
This commit is contained in:
parent
2dc526796d
commit
f2da3f1b57
1033
initdatas/chest_id.txt
Normal file
1033
initdatas/chest_id.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,9 @@
|
||||
"lint": "eslint --ext .ts src/**",
|
||||
"format": "eslint --ext .ts src/** --fix",
|
||||
"initdata": "ts-node src/initdata.ts",
|
||||
"repairdata": "ts-node -r tsconfig-paths/register src/repairdata.ts",
|
||||
"repairdata2": "ts-node -r tsconfig-paths/register src/repairdata2.ts",
|
||||
"repairredis": "ts-node -r tsconfig-paths/register src/repairredis.ts",
|
||||
"test:watch": "jest --watch",
|
||||
"test": "jest"
|
||||
},
|
||||
|
@ -375,7 +375,17 @@ class GameController extends BaseController {
|
||||
// updateData['$inc']['maxNoChestCount'] = step
|
||||
// }
|
||||
// }
|
||||
await ActivityGame.updateOne({ user: user.id, activity: user.activity }, updateData)
|
||||
let saveRes = await ActivityGame.findOneAndUpdate(
|
||||
{ user: user.id, activity: user.activity, tickets: { $gte: step } },
|
||||
updateData,
|
||||
{
|
||||
new: false,
|
||||
upsert: false,
|
||||
includeResultMetadata: true,
|
||||
},
|
||||
)
|
||||
// TODO:: check saveRes
|
||||
console.log(saveRes)
|
||||
await updateRankScore({
|
||||
user: user.id,
|
||||
score: score,
|
||||
|
20
src/models/DeleteRecord.ts
Normal file
20
src/models/DeleteRecord.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { dbconn } from 'decorators/dbconn'
|
||||
import { getModelForClass, index, modelOptions, mongoose, prop } from '@typegoose/typegoose'
|
||||
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
|
||||
import { BaseModule } from './Base'
|
||||
/**
|
||||
* 宝箱券
|
||||
*/
|
||||
@dbconn()
|
||||
@index({ type: 1 }, { unique: false })
|
||||
@modelOptions({
|
||||
schemaOptions: { collection: 'delete_record', timestamps: true },
|
||||
options: { allowMixed: Severity.ALLOW },
|
||||
})
|
||||
export class DeleteRecordClass extends BaseModule {
|
||||
@prop()
|
||||
public type: string
|
||||
@prop({ type: mongoose.Schema.Types.Mixed })
|
||||
public data: any
|
||||
}
|
||||
export const DeleteRecord = getModelForClass(DeleteRecordClass, { existingConnection: DeleteRecordClass['db'] })
|
96
src/repairdata.ts
Normal file
96
src/repairdata.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import mongoose from 'mongoose'
|
||||
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 { ActivityChest } from 'models/ActivityChest'
|
||||
import { VoucherRecord } from 'models/VoucherRecord'
|
||||
import { NFTHolderRecord } from 'models/NFTHodlerRecord'
|
||||
import { TicketRecord } from 'models/TicketRecord'
|
||||
const db = mongoose.connection
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
await mongoose.connect(process.env.DB_MAIN)
|
||||
let chests = await ActivityChest.find({})
|
||||
// 过滤掉箱子码开出来的箱子
|
||||
console.log('箱子总数: ', chests.length)
|
||||
let voucherChestSet = new Set()
|
||||
let voucherRecords = await VoucherRecord.find({ status: 9 })
|
||||
for (let record of voucherRecords) {
|
||||
if (record.chests.length > 0) {
|
||||
voucherChestSet.add(record.chests[0])
|
||||
}
|
||||
}
|
||||
let chestsLeft = []
|
||||
for (let chest of chests) {
|
||||
if (!voucherChestSet.has(chest.id)) {
|
||||
chestsLeft.push(chest)
|
||||
}
|
||||
}
|
||||
console.log('过滤掉箱子码开出来的箱子: ', voucherChestSet.size, '剩余: ', chestsLeft.length)
|
||||
// 过滤掉正常合作伙伴nft holeder的箱子
|
||||
let nftHolderRecords = await NFTHolderRecord.find({})
|
||||
let nftHolderChestSet = new Set()
|
||||
for (let record of nftHolderRecords) {
|
||||
if (record.rewards.length > 0) {
|
||||
nftHolderChestSet.add(record.rewards[0])
|
||||
}
|
||||
}
|
||||
let chestsLeft2 = []
|
||||
for (let chest of chestsLeft) {
|
||||
if (!nftHolderChestSet.has(chest.id)) {
|
||||
chestsLeft2.push(chest)
|
||||
}
|
||||
}
|
||||
console.log('过滤掉正常NFT holder记录的箱子: ', nftHolderChestSet.size, '剩余: ', chestsLeft2.length)
|
||||
// 根据探索记录时间和箱子生成时间过滤正常的箱子
|
||||
let ticketRecords = await TicketRecord.find({ score: { $lt: 0 } })
|
||||
let exploreChestSet = new Set()
|
||||
for (let ticketRecord of ticketRecords) {
|
||||
// query chest createAt between ticketRecord.createAt and ticketRecord.createAt - 1 second
|
||||
let total = Math.abs(ticketRecord.score)
|
||||
let chestArr = []
|
||||
for (let chest of chestsLeft2) {
|
||||
if (
|
||||
chest.user === ticketRecord.user &&
|
||||
// @ts-ignore
|
||||
chest.createdAt < ticketRecord.createdAt &&
|
||||
// @ts-ignore
|
||||
chest.createdAt > ticketRecord.createdAt - 1000
|
||||
) {
|
||||
chestArr.push(chest)
|
||||
}
|
||||
}
|
||||
// 有限保留已开过和品质高的箱子
|
||||
chestArr.sort((a, b) => {
|
||||
return b.status - a.status
|
||||
})
|
||||
let count = 0
|
||||
for (let chest of chestArr) {
|
||||
if (count >= total) {
|
||||
break
|
||||
}
|
||||
exploreChestSet.add(chest.id)
|
||||
count++
|
||||
}
|
||||
}
|
||||
let chestsLeft3 = []
|
||||
for (let chest of chestsLeft2) {
|
||||
if (!exploreChestSet.has(chest.id)) {
|
||||
chestsLeft3.push(chest)
|
||||
}
|
||||
}
|
||||
console.log(chestsLeft3.length)
|
||||
console.log('过滤掉探索获得的箱子: ', exploreChestSet.size, '剩余: ', chestsLeft3.length)
|
||||
let file = require('fs')
|
||||
let ids = chestsLeft3.map(chest => chest.id)
|
||||
file.writeFileSync('initdatas/chest_id.txt', ids.join('\n'))
|
||||
|
||||
console.log('Finished repair box data in the database')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
process.exit(0)
|
||||
})()
|
123
src/repairdata2.ts
Normal file
123
src/repairdata2.ts
Normal file
@ -0,0 +1,123 @@
|
||||
import mongoose from 'mongoose'
|
||||
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 { ActivityChest } from 'models/ActivityChest'
|
||||
import { ScoreRecord } from 'models/ScoreRecord'
|
||||
import { DeleteRecord } from 'models/DeleteRecord'
|
||||
import { rankKey, updateRank, updateRankInvite } from 'services/rank.svr'
|
||||
import { ZRedisClient } from 'zutils'
|
||||
import { RANK_SCORE_SCALE } from 'common/Constants'
|
||||
const db = mongoose.connection
|
||||
|
||||
const updateRedis = async (activity, user, score) => {
|
||||
const key = rankKey(activity)
|
||||
await updateRank(key, score, user)
|
||||
}
|
||||
|
||||
const updateRedisInvite = async (activity, sourceUser, user, score) => {
|
||||
const keyInvite = `${activity}:invite`
|
||||
await updateRankInvite(keyInvite, parseInt(score * RANK_SCORE_SCALE + ''), `${sourceUser}_${user}`)
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
return false
|
||||
let fs = require('fs')
|
||||
let ids = fs.readFileSync('initdatas/chest_id.txt', 'utf-8').split('\n')
|
||||
let ids2 = []
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
if (ids[i].trim()) {
|
||||
ids2.push(ids[i])
|
||||
}
|
||||
}
|
||||
let chests = await ActivityChest.find({ _id: { $in: ids2 } })
|
||||
const activity = 'uaw_activity'
|
||||
console.time('delete')
|
||||
let opts = { url: process.env.REDIS }
|
||||
new ZRedisClient(opts)
|
||||
for (let chest of chests) {
|
||||
if (chest.status === 1) {
|
||||
// 未开启
|
||||
// 处理助力分数
|
||||
if (chest.bonusUsers.length > 0) {
|
||||
for (let user of chest.bonusUsers) {
|
||||
let record = await ScoreRecord.findOne({ user: user, activity: chest.activity, type: 'enhance_chest_gift' })
|
||||
console.log('助力分数: ', record.score)
|
||||
await updateRedis(activity, user, -record.score)
|
||||
let dRecord = new DeleteRecord({
|
||||
type: 'enhance_chest_gift',
|
||||
data: record,
|
||||
})
|
||||
await dRecord.save()
|
||||
await ScoreRecord.deleteOne({ _id: record.id })
|
||||
}
|
||||
}
|
||||
} else if (chest.status === 9) {
|
||||
// 已开启
|
||||
// 处理助力分数
|
||||
if (chest.bonusUsers.length > 0) {
|
||||
for (let user of chest.bonusUsers) {
|
||||
let record = await ScoreRecord.findOne({ user: user, activity: chest.activity, type: 'enhance_chest_gift' })
|
||||
console.log('助力分数: ', record.score)
|
||||
// update redis
|
||||
await updateRedis(activity, user, -record.score)
|
||||
let dRecord = new DeleteRecord({
|
||||
type: 'enhance_chest_gift',
|
||||
data: record,
|
||||
})
|
||||
await dRecord.save()
|
||||
await ScoreRecord.deleteOne({ _id: record.id })
|
||||
}
|
||||
}
|
||||
// 处理已开箱所得分数
|
||||
let record = await ScoreRecord.findOne({
|
||||
'data.chestId': chest.id,
|
||||
user: chest.user,
|
||||
activity: chest.activity,
|
||||
type: 'open_chest',
|
||||
})
|
||||
console.log('开箱所得分数: ', record.score)
|
||||
// update redis
|
||||
await updateRedis(activity, chest.user, -record.score)
|
||||
let dRecord = new DeleteRecord({
|
||||
type: 'open_chest',
|
||||
data: record,
|
||||
})
|
||||
await dRecord.save()
|
||||
await ScoreRecord.deleteOne({ _id: record.id })
|
||||
// 处理邀请者所得分数
|
||||
let subRecords = await ScoreRecord.find({
|
||||
'data.fromUser': record.user,
|
||||
'data.chestId': chest.id,
|
||||
type: 'invite_rebate',
|
||||
})
|
||||
for (let subRecord of subRecords) {
|
||||
console.log('邀请者所得分数: ', subRecord.score, subRecord.id)
|
||||
// update redis
|
||||
await updateRedis(activity, subRecord.user, -record.score)
|
||||
await updateRedisInvite(activity, record.user, subRecord.user, -record.score)
|
||||
let dRecord = new DeleteRecord({
|
||||
type: 'invite_rebate',
|
||||
data: subRecord,
|
||||
})
|
||||
await dRecord.save()
|
||||
await ScoreRecord.deleteOne({ _id: subRecord.id })
|
||||
}
|
||||
// 移除当前箱子
|
||||
}
|
||||
let dRecordChest = new DeleteRecord({
|
||||
type: 'chest',
|
||||
data: chest,
|
||||
})
|
||||
await dRecordChest.save()
|
||||
await ActivityChest.deleteOne({ _id: chest.id })
|
||||
}
|
||||
console.timeEnd('delete')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
process.exit(0)
|
||||
})()
|
94
src/repairredis.ts
Normal file
94
src/repairredis.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import mongoose from 'mongoose'
|
||||
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 { ActivityChest } from 'models/ActivityChest'
|
||||
import { ScoreRecord } from 'models/ScoreRecord'
|
||||
import { DeleteRecord } from 'models/DeleteRecord'
|
||||
import { rankKey, updateRank, updateRankInvite } from 'services/rank.svr'
|
||||
import { ZRedisClient } from 'zutils'
|
||||
import { RANK_SCORE_SCALE } from 'common/Constants'
|
||||
const db = mongoose.connection
|
||||
|
||||
const totalKey = 'uaw_activity:score'
|
||||
const keyInvite = `uaw_activity:invite`
|
||||
|
||||
const updateRedis = async (activity, user, score) => {
|
||||
await updateRank(totalKey, score, user)
|
||||
}
|
||||
|
||||
const updateRedisInvite = async (activity, sourceUser, user, score) => {
|
||||
await updateRankInvite(keyInvite, parseInt(score * RANK_SCORE_SCALE + ''), `${sourceUser}_${user}`)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
return false
|
||||
try {
|
||||
let records = await ScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
|
||||
console.time('first')
|
||||
// _id, count
|
||||
console.log('records: ', records.length)
|
||||
let opts = { url: process.env.REDIS }
|
||||
new ZRedisClient(opts)
|
||||
let vals = []
|
||||
for (let i = 0, l = records.length; i < l; i++) {
|
||||
vals.push(records[i].count * 100 + 1 - Date.now() / 1000 / 10000000000)
|
||||
vals.push(records[i]._id)
|
||||
if (i++ % 1000 === 0) {
|
||||
await updateRedis2(totalKey, vals)
|
||||
vals.length = 0
|
||||
}
|
||||
}
|
||||
if (vals.length > 0) {
|
||||
await updateRedis2(totalKey, vals)
|
||||
}
|
||||
console.timeEnd('first')
|
||||
let records2 = await ScoreRecord.aggregate([
|
||||
{ $match: { type: 'invite_rebate' } },
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
user: '$user',
|
||||
from: '$data.fromUser',
|
||||
},
|
||||
count: { $sum: '$score' },
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
console.time('second')
|
||||
// _id, count
|
||||
console.log('records2: ', records2.length)
|
||||
let vals2 = []
|
||||
for (let i = 0, l = records.length; i < l; i++) {
|
||||
vals2.push(records[i].count * 100)
|
||||
vals2.push(`${records[i]._id.from}_${records[i]._id.user}`)
|
||||
if (i++ % 1000 === 0) {
|
||||
await updateRedis2(keyInvite, vals2)
|
||||
vals2.length = 0
|
||||
}
|
||||
}
|
||||
if (vals2.length > 0) {
|
||||
await updateRedis2(keyInvite, vals2)
|
||||
}
|
||||
console.timeEnd('second')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
console.log('end')
|
||||
process.exit(0)
|
||||
})()
|
@ -68,7 +68,7 @@ export const updateRankScore = async ({
|
||||
* @param score
|
||||
* @param member
|
||||
*/
|
||||
const updateRank = async (key: string, score: number, member: string) => {
|
||||
export const updateRank = async (key: string, score: number, member: string) => {
|
||||
let scoreSaved = (await new ZRedisClient().zscore(key, member)) + ''
|
||||
if (scoreSaved) {
|
||||
scoreSaved = scoreSaved.substring(0, scoreSaved.indexOf('.'))
|
||||
@ -76,10 +76,12 @@ const updateRank = async (key: string, score: number, member: string) => {
|
||||
let scoreOld = parseInt(scoreSaved || '0')
|
||||
score = score * RANK_SCORE_SCALE + scoreOld
|
||||
const scoreToSave = score + 1 - Date.now() / 1000 / 10000000000
|
||||
let vals = ['1', '2']
|
||||
new ZRedisClient().pub.zadd(...vals)
|
||||
await new ZRedisClient().zadd(key, scoreToSave, member)
|
||||
}
|
||||
|
||||
const updateRankInvite = async (key: string, score: number, member: string) => {
|
||||
export const updateRankInvite = async (key: string, score: number, member: string) => {
|
||||
await new ZRedisClient().zincrby(key, score, member)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user