优化邮件发送
This commit is contained in:
parent
d4e875e423
commit
305d784426
@ -19,6 +19,8 @@
|
||||
"additem": "ts-node -r tsconfig-paths/register src/addboxdata.ts",
|
||||
"taskid": "ts-node -r tsconfig-paths/register src/generateTaskId.ts",
|
||||
"token": "ts-node -r tsconfig-paths/register src/generateToken.ts",
|
||||
"ingame": "ts-node -r tsconfig-paths/register src/fixIngame.ts",
|
||||
"testdraw": "ts-node -r tsconfig-paths/register src/testdraw.ts",
|
||||
"test:watch": "jest --watch",
|
||||
"test": "jest"
|
||||
},
|
||||
|
@ -16,7 +16,7 @@ import { SyncLocker } from 'common/SyncLocker'
|
||||
|
||||
class MailController extends BaseController {
|
||||
/**
|
||||
* 通过邮件, 密码形式的登录
|
||||
* 通过邮件验证码形式的登录
|
||||
*/
|
||||
@router('post /api/user/verify_email')
|
||||
async loginWithEmail(req, res) {
|
||||
@ -41,13 +41,10 @@ class MailController extends BaseController {
|
||||
if (userCheck && userCheck.id !== user.id) {
|
||||
throw new ZError(13, 'Email already binded to another account')
|
||||
}
|
||||
let recordCode = await CodeRecord.findByEmail(email, CodeType.LOGIN)
|
||||
let recordCode = await CodeRecord.findByEmail(user.id, email, CodeType.LOGIN)
|
||||
if (!recordCode) {
|
||||
throw new ZError(14, 'code expired')
|
||||
}
|
||||
if (recordCode.status !== CodeStatus.PENDING) {
|
||||
throw new ZError(15, 'code expired')
|
||||
}
|
||||
if (recordCode.code !== code) {
|
||||
throw new ZError(16, 'code error')
|
||||
}
|
||||
@ -84,8 +81,8 @@ class MailController extends BaseController {
|
||||
throw new ZError(13, 'Email already binded to another account')
|
||||
}
|
||||
type = parseInt(type)
|
||||
let record = await CodeRecord.findByEmail(email, type)
|
||||
if (!record || record.status === CodeStatus.EXPIRED || record.status === CodeStatus.FAIL) {
|
||||
let record = await CodeRecord.findByEmail(user.id, email, type)
|
||||
if (!record || record.user !== user.id) {
|
||||
record = new CodeRecord({ email, type, code: DEFAULT_CODE, user: user.id })
|
||||
await record.save()
|
||||
}
|
||||
@ -109,14 +106,19 @@ class MailController extends BaseController {
|
||||
}
|
||||
setImmediate(async () => {
|
||||
try {
|
||||
let result = await new EmailSvr().sendMail(msgData)
|
||||
record.mailSend = true
|
||||
record.emailId = result.messageId
|
||||
record.expiredAt = Date.now() + DEFAULT_EXPIRE_TIME
|
||||
let { errcode, errmsg, data } = await new EmailSvr().sendMail(msgData)
|
||||
if (errcode) {
|
||||
logger.info(`error send mail:: email: ${email}, type: ${type}, errcode: ${errcode}, errmsg: ${errmsg}`)
|
||||
record.status = CodeStatus.FAIL
|
||||
} else {
|
||||
logger.info(`success send mail:: email: ${email}, type: ${type}, messageId: ${data.messageId}`)
|
||||
record.mailSend = true
|
||||
record.emailId = data.messageId
|
||||
record.expiredAt = Date.now() + DEFAULT_EXPIRE_TIME
|
||||
}
|
||||
await record.save()
|
||||
} catch (err) {
|
||||
logger.info(`error send mail:: email: ${email}, type: ${type}`)
|
||||
logger.error(err)
|
||||
logger.info(`error send mail:: email: ${email}, type: ${type}, errmsg: ${err.message || err}`)
|
||||
record.status = CodeStatus.FAIL
|
||||
await record.save()
|
||||
}
|
||||
|
67
src/fixIngame.ts
Normal file
67
src/fixIngame.ts
Normal file
@ -0,0 +1,67 @@
|
||||
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 { InGameScoreRecord } from 'models/InGameScoreRecord'
|
||||
import { InGameTaskRecord } from 'models/InGameTaskRecord'
|
||||
import { InGameStats } from 'models/InGameStats'
|
||||
import { NftClaimRecord } from 'models/NftClaimRecord'
|
||||
import { DeleteRecord } from 'models/DeleteRecord'
|
||||
;(async () => {
|
||||
try {
|
||||
let taskRecords = await InGameTaskRecord.find({ ticket: { $gt: 0 } })
|
||||
let scoreRecords = await InGameScoreRecord.find({ type: 'draw_ingame' })
|
||||
let claimRecords = await NftClaimRecord.find({})
|
||||
let taskMap = new Map()
|
||||
let scoreMap = new Map()
|
||||
for (let record of taskRecords) {
|
||||
if (!taskMap.has(record.user)) {
|
||||
taskMap.set(record.user, 0)
|
||||
}
|
||||
taskMap.set(record.user, taskMap.get(record.user) + record.ticket)
|
||||
}
|
||||
for (let record of claimRecords) {
|
||||
if (!taskMap.has(record.user)) {
|
||||
taskMap.set(record.user, 0)
|
||||
}
|
||||
taskMap.set(record.user, taskMap.get(record.user) + 1)
|
||||
}
|
||||
for (let record of scoreRecords) {
|
||||
if (!scoreMap.has(record.user)) {
|
||||
scoreMap.set(record.user, [])
|
||||
}
|
||||
scoreMap.get(record.user).push(record.score)
|
||||
}
|
||||
for (let [user, records] of scoreMap) {
|
||||
if (!taskMap.has(user)) {
|
||||
console.log('User', user, 'has no task record')
|
||||
for (let record of records) {
|
||||
let dRecord = new DeleteRecord({
|
||||
type: 'ingame_draw',
|
||||
data: record,
|
||||
})
|
||||
await dRecord.save()
|
||||
await InGameScoreRecord.deleteOne({ _id: record.id })
|
||||
}
|
||||
await InGameStats.findOneAndUpdate(
|
||||
{ user: user },
|
||||
{ score: 0 },
|
||||
{
|
||||
new: false,
|
||||
upsert: false,
|
||||
includeResultMetadata: true,
|
||||
},
|
||||
)
|
||||
console.log(`fix user data: ${user}`)
|
||||
} else if (taskMap.get(user) < records.length) {
|
||||
console.log('User', user, 'has less task record than score record')
|
||||
}
|
||||
}
|
||||
console.log('Finished repair ingame data in the database')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
process.exit(0)
|
||||
})()
|
@ -34,9 +34,9 @@ export const isValiedCode = (code: string) => {
|
||||
* 邮件验证码发送记录
|
||||
*/
|
||||
@dbconn()
|
||||
@index({ email: 1, type: 1, status: 1 }, { unique: true, partialFilterExpression: { status: 1 } })
|
||||
@index({ user: 1, email: 1, type: 1, status: 1 }, { unique: true, partialFilterExpression: { status: 1 } })
|
||||
@index({ code: 1 }, { unique: true })
|
||||
@index({ expiredAt: 1 }, { unique: false })
|
||||
@index({ expiredAt: 1, status: 1 }, { unique: false })
|
||||
@modelOptions({
|
||||
schemaOptions: { collection: 'code_send_record', timestamps: true },
|
||||
})
|
||||
@ -82,8 +82,13 @@ class CodeRecordClass extends BaseModule {
|
||||
return this.findOne({ code }).exec()
|
||||
}
|
||||
|
||||
public static async findByEmail(this: ReturnModelType<typeof CodeRecordClass>, email: string, type: CodeType) {
|
||||
return this.findOne({ email, type, status: CodeStatus.PENDING }).exec()
|
||||
public static async findByEmail(
|
||||
this: ReturnModelType<typeof CodeRecordClass>,
|
||||
user: string,
|
||||
email: string,
|
||||
type: CodeType,
|
||||
) {
|
||||
return this.findOne({ user, email, type, status: CodeStatus.PENDING }).exec()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import * as schedule from 'node-schedule'
|
||||
export default class CodeTaskSchedule {
|
||||
async parseAllRecord() {
|
||||
let now = Date.now()
|
||||
await CodeRecord.deleteMany({ expiredAt: { $lt: now } })
|
||||
await CodeRecord.updateMany({ expiredAt: { $lt: now }, status: CodeStatus.PENDING }, { status: CodeStatus.EXPIRED })
|
||||
}
|
||||
scheduleAll() {
|
||||
const job = schedule.scheduleJob('*/1 * * * *', async () => {
|
||||
|
28
src/testdraw.ts
Normal file
28
src/testdraw.ts
Normal file
@ -0,0 +1,28 @@
|
||||
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 { drawOnce } from 'services/game.svr'
|
||||
import { ZRedisClient } from 'zutils'
|
||||
;(async () => {
|
||||
try {
|
||||
let opts = { url: process.env.REDIS }
|
||||
new ZRedisClient(opts)
|
||||
let resultMap = new Map()
|
||||
const total = 10000
|
||||
for (let i = 0; i < total; i++) {
|
||||
let reward = await drawOnce(false)
|
||||
// console.log(reward)
|
||||
resultMap.set(reward.amount, (resultMap.get(reward.amount) || 0) + 1)
|
||||
}
|
||||
for (let [key, value] of resultMap) {
|
||||
console.log(key, value, parseFloat(value) / parseFloat(total + ''))
|
||||
}
|
||||
process.exit(0)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})()
|
Loading…
x
Reference in New Issue
Block a user