优化邮件发送
This commit is contained in:
parent
d4e875e423
commit
305d784426
@ -19,6 +19,8 @@
|
|||||||
"additem": "ts-node -r tsconfig-paths/register src/addboxdata.ts",
|
"additem": "ts-node -r tsconfig-paths/register src/addboxdata.ts",
|
||||||
"taskid": "ts-node -r tsconfig-paths/register src/generateTaskId.ts",
|
"taskid": "ts-node -r tsconfig-paths/register src/generateTaskId.ts",
|
||||||
"token": "ts-node -r tsconfig-paths/register src/generateToken.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:watch": "jest --watch",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@ import { SyncLocker } from 'common/SyncLocker'
|
|||||||
|
|
||||||
class MailController extends BaseController {
|
class MailController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 通过邮件, 密码形式的登录
|
* 通过邮件验证码形式的登录
|
||||||
*/
|
*/
|
||||||
@router('post /api/user/verify_email')
|
@router('post /api/user/verify_email')
|
||||||
async loginWithEmail(req, res) {
|
async loginWithEmail(req, res) {
|
||||||
@ -41,13 +41,10 @@ class MailController extends BaseController {
|
|||||||
if (userCheck && userCheck.id !== user.id) {
|
if (userCheck && userCheck.id !== user.id) {
|
||||||
throw new ZError(13, 'Email already binded to another account')
|
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) {
|
if (!recordCode) {
|
||||||
throw new ZError(14, 'code expired')
|
throw new ZError(14, 'code expired')
|
||||||
}
|
}
|
||||||
if (recordCode.status !== CodeStatus.PENDING) {
|
|
||||||
throw new ZError(15, 'code expired')
|
|
||||||
}
|
|
||||||
if (recordCode.code !== code) {
|
if (recordCode.code !== code) {
|
||||||
throw new ZError(16, 'code error')
|
throw new ZError(16, 'code error')
|
||||||
}
|
}
|
||||||
@ -84,8 +81,8 @@ class MailController extends BaseController {
|
|||||||
throw new ZError(13, 'Email already binded to another account')
|
throw new ZError(13, 'Email already binded to another account')
|
||||||
}
|
}
|
||||||
type = parseInt(type)
|
type = parseInt(type)
|
||||||
let record = await CodeRecord.findByEmail(email, type)
|
let record = await CodeRecord.findByEmail(user.id, email, type)
|
||||||
if (!record || record.status === CodeStatus.EXPIRED || record.status === CodeStatus.FAIL) {
|
if (!record || record.user !== user.id) {
|
||||||
record = new CodeRecord({ email, type, code: DEFAULT_CODE, user: user.id })
|
record = new CodeRecord({ email, type, code: DEFAULT_CODE, user: user.id })
|
||||||
await record.save()
|
await record.save()
|
||||||
}
|
}
|
||||||
@ -109,14 +106,19 @@ class MailController extends BaseController {
|
|||||||
}
|
}
|
||||||
setImmediate(async () => {
|
setImmediate(async () => {
|
||||||
try {
|
try {
|
||||||
let result = await new EmailSvr().sendMail(msgData)
|
let { errcode, errmsg, data } = await new EmailSvr().sendMail(msgData)
|
||||||
record.mailSend = true
|
if (errcode) {
|
||||||
record.emailId = result.messageId
|
logger.info(`error send mail:: email: ${email}, type: ${type}, errcode: ${errcode}, errmsg: ${errmsg}`)
|
||||||
record.expiredAt = Date.now() + DEFAULT_EXPIRE_TIME
|
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()
|
await record.save()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.info(`error send mail:: email: ${email}, type: ${type}`)
|
logger.info(`error send mail:: email: ${email}, type: ${type}, errmsg: ${err.message || err}`)
|
||||||
logger.error(err)
|
|
||||||
record.status = CodeStatus.FAIL
|
record.status = CodeStatus.FAIL
|
||||||
await record.save()
|
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()
|
@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({ code: 1 }, { unique: true })
|
||||||
@index({ expiredAt: 1 }, { unique: false })
|
@index({ expiredAt: 1, status: 1 }, { unique: false })
|
||||||
@modelOptions({
|
@modelOptions({
|
||||||
schemaOptions: { collection: 'code_send_record', timestamps: true },
|
schemaOptions: { collection: 'code_send_record', timestamps: true },
|
||||||
})
|
})
|
||||||
@ -82,8 +82,13 @@ class CodeRecordClass extends BaseModule {
|
|||||||
return this.findOne({ code }).exec()
|
return this.findOne({ code }).exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async findByEmail(this: ReturnModelType<typeof CodeRecordClass>, email: string, type: CodeType) {
|
public static async findByEmail(
|
||||||
return this.findOne({ email, type, status: CodeStatus.PENDING }).exec()
|
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 {
|
export default class CodeTaskSchedule {
|
||||||
async parseAllRecord() {
|
async parseAllRecord() {
|
||||||
let now = Date.now()
|
let now = Date.now()
|
||||||
await CodeRecord.deleteMany({ expiredAt: { $lt: now } })
|
await CodeRecord.updateMany({ expiredAt: { $lt: now }, status: CodeStatus.PENDING }, { status: CodeStatus.EXPIRED })
|
||||||
}
|
}
|
||||||
scheduleAll() {
|
scheduleAll() {
|
||||||
const job = schedule.scheduleJob('*/1 * * * *', async () => {
|
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