增加助力和签到接口一些返回数据
This commit is contained in:
parent
f2da3f1b57
commit
43ff417a2c
18
docs/uaw.md
18
docs/uaw.md
@ -55,6 +55,11 @@
|
|||||||
#### 20240416
|
#### 20240416
|
||||||
1. 增加接口: 兑换宝箱激活码(30)
|
1. 增加接口: 兑换宝箱激活码(30)
|
||||||
|
|
||||||
|
#### 20240423
|
||||||
|
1. 签到列表接口(11)增加返回字段: 是否已领取奖励
|
||||||
|
1. 检查签到并领取奖励(23), 增加post参数, 可以领取指定天数的奖励
|
||||||
|
1. 宝箱助力(18), 增加返回scoreBonus, 表示当前宝箱已得到的助力积分
|
||||||
|
|
||||||
### 1. 钱包预登录
|
### 1. 钱包预登录
|
||||||
|
|
||||||
#### Request
|
#### Request
|
||||||
@ -387,7 +392,8 @@ query param
|
|||||||
"day": "20240105", // 格式化后签到日期, 时区按SG(UTC+8)
|
"day": "20240105", // 格式化后签到日期, 时区按SG(UTC+8)
|
||||||
"time": 1704436745, // 具体的签到时间
|
"time": 1704436745, // 具体的签到时间
|
||||||
"count": 0, //连签天数
|
"count": 0, //连签天数
|
||||||
"total": 10 //累计签到天数
|
"total": 10, //累计签到天数
|
||||||
|
"claimed": true, // 当日签到奖励是否已领取
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@ -587,6 +593,7 @@ body:
|
|||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
score: 100, // 自己获得的积分
|
score: 100, // 自己获得的积分
|
||||||
|
scoreBonus: 1 //当前箱子已助力积分
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -693,6 +700,15 @@ body:
|
|||||||
- 头部:
|
- 头部:
|
||||||
- Authorization: Bearer JWT_token
|
- Authorization: Bearer JWT_token
|
||||||
|
|
||||||
|
body:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"day": "20240418" //需要领取的天数, 该字段为空的话, 领取当日的
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
#### Response
|
#### Response
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"repairdata": "ts-node -r tsconfig-paths/register src/repairdata.ts",
|
"repairdata": "ts-node -r tsconfig-paths/register src/repairdata.ts",
|
||||||
"repairdata2": "ts-node -r tsconfig-paths/register src/repairdata2.ts",
|
"repairdata2": "ts-node -r tsconfig-paths/register src/repairdata2.ts",
|
||||||
"repairredis": "ts-node -r tsconfig-paths/register src/repairredis.ts",
|
"repairredis": "ts-node -r tsconfig-paths/register src/repairredis.ts",
|
||||||
|
"checkredis": "ts-node -r tsconfig-paths/register src/checkredis.ts",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
|
67
src/checkredis.ts
Normal file
67
src/checkredis.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 { 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 () => {
|
||||||
|
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++) {
|
||||||
|
const score = parseInt(records[i].count * 100 + '')
|
||||||
|
let totalScoreStr = await new ZRedisClient().zscore(totalKey, records[i]._id)
|
||||||
|
let totalScore = parseInt(totalScoreStr + '')
|
||||||
|
if (score != totalScore) {
|
||||||
|
if (Math.abs(score - totalScore) > 1) {
|
||||||
|
console.log(`user: ${records[i]._id}, score: ${score}, redis: ${totalScore}`)
|
||||||
|
await new ZRedisClient().zincrby(totalKey, score - totalScore, records[i]._id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i % 1000 === 0) {
|
||||||
|
console.log(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.timeEnd('first')
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
console.log('end')
|
||||||
|
process.exit(0)
|
||||||
|
})()
|
@ -15,6 +15,11 @@ export const isValidVoucherCode = (str: string) => {
|
|||||||
let reg = new RegExp(`^[${BASE52_ALPHABET}]{12}$`)
|
let reg = new RegExp(`^[${BASE52_ALPHABET}]{12}$`)
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
// check if a string is a valid day tag, like 20240408
|
||||||
|
export const isValidDayTag = (str: string) => {
|
||||||
|
return /^[0-9]{8}$/.test(str)
|
||||||
|
}
|
||||||
|
|
||||||
export const formatNumShow = (num: number) => {
|
export const formatNumShow = (num: number) => {
|
||||||
if (num >= 10) {
|
if (num >= 10) {
|
||||||
return Math.round(num) + ''
|
return Math.round(num) + ''
|
||||||
|
@ -249,7 +249,7 @@ class BoxController extends BaseController {
|
|||||||
throw new ZError(16, 'user enhance times exceed')
|
throw new ZError(16, 'user enhance times exceed')
|
||||||
}
|
}
|
||||||
const score = chest.bounsCfg[chest.bonusUsers.length] || chest.bounsCfg[chest.bounsCfg.length - 1]
|
const score = chest.bounsCfg[chest.bonusUsers.length] || chest.bounsCfg[chest.bounsCfg.length - 1]
|
||||||
await ActivityChest.updateOne(
|
let doc = await ActivityChest.findOneAndUpdate(
|
||||||
{ _id: chest.id },
|
{ _id: chest.id },
|
||||||
{
|
{
|
||||||
$inc: { scoreBonus: score },
|
$inc: { scoreBonus: score },
|
||||||
@ -278,6 +278,7 @@ class BoxController extends BaseController {
|
|||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
score: ENHANCE_CHEST_GIFT,
|
score: ENHANCE_CHEST_GIFT,
|
||||||
|
scoreBonus: doc.scoreBonus,
|
||||||
}
|
}
|
||||||
// const chestsForUser = await ActivityChest.find({ user: uid, activity: user.activity })
|
// const chestsForUser = await ActivityChest.find({ user: uid, activity: user.activity })
|
||||||
// 如果用户没有宝箱, 则说明用户是新用户, 生成一个宝箱
|
// 如果用户没有宝箱, 则说明用户是新用户, 生成一个宝箱
|
||||||
|
@ -11,7 +11,7 @@ import { ExploreRecord } from 'models/ExploreRecord'
|
|||||||
import { isObjectId } from 'zutils/utils/string.util'
|
import { isObjectId } from 'zutils/utils/string.util'
|
||||||
import { GeneralScription } from 'models/chain/GeneralScription'
|
import { GeneralScription } from 'models/chain/GeneralScription'
|
||||||
import { CheckIn } from 'models/chain/CheckIn'
|
import { CheckIn } from 'models/chain/CheckIn'
|
||||||
import { formatNumShow } from 'common/Utils'
|
import { formatNumShow, isValidDayTag } from 'common/Utils'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,14 +27,26 @@ class GameController extends BaseController {
|
|||||||
logger.db('checkin', req)
|
logger.db('checkin', req)
|
||||||
const user = req.user
|
const user = req.user
|
||||||
const { address } = user
|
const { address } = user
|
||||||
const dateTag = formatDate(new Date())
|
let { day } = req.params
|
||||||
|
if (day) {
|
||||||
|
if (!isValidDayTag(day)) {
|
||||||
|
throw new ZError(11, 'invalid day')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dateTag = day || formatDate(new Date())
|
||||||
|
const ticketRecordExists = await TicketRecord.findOne({
|
||||||
|
user: user.id,
|
||||||
|
activity: user.activity,
|
||||||
|
type: DAILY_SIGN,
|
||||||
|
'data.dataTag': dateTag,
|
||||||
|
})
|
||||||
|
if (ticketRecordExists) {
|
||||||
|
throw new ZError(12, 'already claimed')
|
||||||
|
}
|
||||||
const gameRecord = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
const gameRecord = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||||
if (MANUAL_OPEN_GAME && gameRecord.status === 0) {
|
if (MANUAL_OPEN_GAME && gameRecord.status === 0) {
|
||||||
throw new ZError(11, 'map not open')
|
throw new ZError(11, 'map not open')
|
||||||
}
|
}
|
||||||
if (dateTag === gameRecord.lastSignDay) {
|
|
||||||
throw new ZError(12, 'already claimed')
|
|
||||||
}
|
|
||||||
const record = await checkInToday(address, dateTag)
|
const record = await checkInToday(address, dateTag)
|
||||||
if (!record) {
|
if (!record) {
|
||||||
throw new ZError(13, 'had not check in')
|
throw new ZError(13, 'had not check in')
|
||||||
@ -43,13 +55,10 @@ class GameController extends BaseController {
|
|||||||
user: user.id,
|
user: user.id,
|
||||||
activity: user.activity,
|
activity: user.activity,
|
||||||
type: DAILY_SIGN,
|
type: DAILY_SIGN,
|
||||||
data: {},
|
data: { dataTag: dateTag },
|
||||||
score: 1,
|
score: 1,
|
||||||
})
|
})
|
||||||
await ActivityGame.updateOne(
|
await ActivityGame.updateOne({ user: user.id, activity: user.activity }, { $inc: { tickets: 1 } })
|
||||||
{ user: user.id, activity: user.activity },
|
|
||||||
{ lastSignDay: dateTag, $inc: { tickets: 1 } },
|
|
||||||
)
|
|
||||||
await ticketRecord.save()
|
await ticketRecord.save()
|
||||||
return { ticket: 1 }
|
return { ticket: 1 }
|
||||||
}
|
}
|
||||||
@ -73,6 +82,16 @@ class GameController extends BaseController {
|
|||||||
days = Math.floor((now - start) / 86400000)
|
days = Math.floor((now - start) / 86400000)
|
||||||
}
|
}
|
||||||
const res = await queryCheckInList(user.address.toLowerCase(), days, 0)
|
const res = await queryCheckInList(user.address.toLowerCase(), days, 0)
|
||||||
|
const ticketRecords = await TicketRecord.find({ user: user.id, activity: user.activity, type: DAILY_SIGN })
|
||||||
|
const claimedSet = new Set()
|
||||||
|
ticketRecords.forEach(record => {
|
||||||
|
// @ts-ignore
|
||||||
|
let dateTag = record.data?.dateTag || formatDate(record.createdAt)
|
||||||
|
claimedSet.add(dateTag)
|
||||||
|
})
|
||||||
|
for (let record of res) {
|
||||||
|
record.claimed = claimedSet.has(record.day)
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +36,6 @@ const updateRedis2 = (key, vals) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
return false
|
|
||||||
try {
|
try {
|
||||||
let records = await ScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
|
let records = await ScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
|
||||||
console.time('first')
|
console.time('first')
|
||||||
@ -48,7 +47,7 @@ const updateRedis2 = (key, vals) => {
|
|||||||
for (let i = 0, l = records.length; i < l; i++) {
|
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].count * 100 + 1 - Date.now() / 1000 / 10000000000)
|
||||||
vals.push(records[i]._id)
|
vals.push(records[i]._id)
|
||||||
if (i++ % 1000 === 0) {
|
if (i % 1000 === 0) {
|
||||||
await updateRedis2(totalKey, vals)
|
await updateRedis2(totalKey, vals)
|
||||||
vals.length = 0
|
vals.length = 0
|
||||||
}
|
}
|
||||||
@ -77,7 +76,7 @@ const updateRedis2 = (key, vals) => {
|
|||||||
for (let i = 0, l = records.length; i < l; i++) {
|
for (let i = 0, l = records.length; i < l; i++) {
|
||||||
vals2.push(records[i].count * 100)
|
vals2.push(records[i].count * 100)
|
||||||
vals2.push(`${records[i]._id.from}_${records[i]._id.user}`)
|
vals2.push(`${records[i]._id.from}_${records[i]._id.user}`)
|
||||||
if (i++ % 1000 === 0) {
|
if (i % 1000 === 0) {
|
||||||
await updateRedis2(keyInvite, vals2)
|
await updateRedis2(keyInvite, vals2)
|
||||||
vals2.length = 0
|
vals2.length = 0
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user