55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
/**
|
||
* 引力值迁移脚本
|
||
* 将现有用户的多维额度合并到 gravity 字段
|
||
* 公式: gravity = interviewCredits×5 + resumeOptimizeCredits×3 + resumeDownloadCredits×2 + shareCredits×1 + remaining×5
|
||
* 用法: npx ts-node --project tsconfig.json scripts/migrate-gravity.ts
|
||
*/
|
||
import { NestFactory } from '@nestjs/core'
|
||
import { AppModule } from '../src/app.module'
|
||
import { getModelToken } from '@nestjs/mongoose'
|
||
import { User, UserDocument } from '../src/modules/user/user.schema'
|
||
import { Model } from 'mongoose'
|
||
|
||
async function bootstrap() {
|
||
const app = await NestFactory.createApplicationContext(AppModule)
|
||
const userModel = app.get<Model<UserDocument>>(getModelToken(User.name))
|
||
|
||
const total = await userModel.countDocuments().exec()
|
||
console.log(`Total users: ${total}`)
|
||
|
||
let migrated = 0
|
||
let skipped = 0
|
||
const cursor = userModel.find().cursor()
|
||
|
||
for await (const user of cursor) {
|
||
const interviewVal = (user.interviewCredits ?? 0) * 5
|
||
const optimizeVal = (user.resumeOptimizeCredits ?? 0) * 3
|
||
const downloadVal = (user.resumeDownloadCredits ?? 0) * 2
|
||
const oldRemainVal = (user.remaining ?? 0) * 5
|
||
const shareVal = (user.shareCredits ?? 0) * 1
|
||
const totalGravity = interviewVal + optimizeVal + downloadVal + oldRemainVal + shareVal
|
||
|
||
if (totalGravity <= 0 && (user.gravity ?? 0) === 0) {
|
||
skipped++
|
||
continue
|
||
}
|
||
|
||
await userModel.findByIdAndUpdate(user._id, {
|
||
$set: {
|
||
gravity: Math.max(user.gravity ?? 0, totalGravity),
|
||
interviewCredits: 0,
|
||
resumeOptimizeCredits: 0,
|
||
resumeDownloadCredits: 0,
|
||
remaining: 0,
|
||
shareCredits: 0,
|
||
},
|
||
}).exec()
|
||
migrated++
|
||
}
|
||
|
||
console.log(`Migrated: ${migrated}, Skipped (no credits): ${skipped}`)
|
||
await app.close()
|
||
}
|
||
|
||
bootstrap().catch(console.error)
|