修改箱子助力流程
This commit is contained in:
parent
b518d21ad1
commit
3312b8c1ed
38
docs/uaw.md
38
docs/uaw.md
@ -24,6 +24,9 @@
|
||||
1. 探索状态(12), 移除signCfg, 增加seqStat, 用于标识连续签到奖励领取状态
|
||||
1. 增加领取连续签到奖励(25)的接口
|
||||
|
||||
#### 20240408
|
||||
1. 增加宝箱助力状态查询(26), 用于助力上链前查询是否符合条件
|
||||
|
||||
### 1. 钱包预登录
|
||||
|
||||
#### Request
|
||||
@ -690,7 +693,7 @@ body:
|
||||
|
||||
```js
|
||||
{
|
||||
"days": 3 // 领取的累计签到天数
|
||||
"code": 3 // 领取的累计签到天数
|
||||
}
|
||||
|
||||
```
|
||||
@ -704,3 +707,36 @@ body:
|
||||
```
|
||||
|
||||
###
|
||||
|
||||
### 26.\* 宝箱助力状态查询
|
||||
|
||||
#### Request
|
||||
|
||||
- URL:`/api/chest/enhance/state`
|
||||
- 方法:`POST`
|
||||
- 头部:
|
||||
- Authorization: Bearer JWT_token
|
||||
|
||||
body:
|
||||
|
||||
```js
|
||||
{
|
||||
"code": "1123", // 宝箱的分享code, code和id选择传一个, 如果两个都传, 优先使用id来查询箱子
|
||||
"id": "123123"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
```js
|
||||
{
|
||||
userCurrent: 1, // 用户当日已助力次数
|
||||
userMax: 10, // 用户当日最大可助力次数
|
||||
chestCurrent: 1, // 宝箱当前助力次数
|
||||
chestMax: 10, // 宝箱最大可助力次数
|
||||
enhanced: 0, // 用户是否已经为当前宝箱助力
|
||||
}
|
||||
```
|
||||
|
||||
###
|
@ -49,3 +49,8 @@ export const SCORE_INVITE_REBATE = 'invite_rebate'
|
||||
|
||||
// google reCaptcha最小分数
|
||||
export const RECAPTCHA_MIN_SCORE = 0.5
|
||||
|
||||
// 基础用户每日可助力次数
|
||||
export const MAX_ENHANCE_COUNT_BASE = 1
|
||||
// 高级用户每日可助力次数
|
||||
export const MAX_ENHANCE_COUNT_ADV = 10
|
||||
|
@ -6,10 +6,12 @@ import { formatDate } from 'zutils/utils/date.util'
|
||||
import { ScoreRecord } from 'models/ScoreRecord'
|
||||
import { ChestRecord } from 'models/chain/ChestRecord'
|
||||
import { generateNewChest } from 'services/game.svr'
|
||||
import { SCORE_OPEN_CHEST } from 'common/Constants'
|
||||
import { MAX_ENHANCE_COUNT_ADV, MAX_ENHANCE_COUNT_BASE, SCORE_OPEN_CHEST } from 'common/Constants'
|
||||
import { formatAddress } from 'zutils/utils/chain.util'
|
||||
import { isObjectIdString, isValidShareCode } from 'common/Utils'
|
||||
import { checkReCaptcha } from 'services/google.svr'
|
||||
import { GeneralScription } from 'models/chain/GeneralScription'
|
||||
import { ChestEnhanceRecord } from 'models/ChestEnhanceRecord'
|
||||
|
||||
/**
|
||||
* 宝箱相关接口
|
||||
@ -89,6 +91,50 @@ class BoxController extends BaseController {
|
||||
}
|
||||
return result
|
||||
}
|
||||
/**
|
||||
* 宝箱助力状态查询
|
||||
*/
|
||||
@router('post /api/chest/enhance/state')
|
||||
async enhanceState(req) {
|
||||
const { code, id } = req.params
|
||||
const user = req.user
|
||||
if (code && !isValidShareCode(code)) {
|
||||
throw new ZError(11, 'invalid share code')
|
||||
}
|
||||
if (id && !isObjectIdString(id)) {
|
||||
throw new ZError(11, 'invalid chest id')
|
||||
}
|
||||
if (!code && !id) {
|
||||
throw new ZError(11, 'must provide share code or chest id')
|
||||
}
|
||||
let chest: any
|
||||
if (id) {
|
||||
chest = await ActivityChest.findById(id)
|
||||
} else {
|
||||
chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity })
|
||||
}
|
||||
if (!chest) {
|
||||
throw new ZError(12, 'chest not found')
|
||||
}
|
||||
if (chest.status === ChestStatusEnum.OPENED) {
|
||||
throw new ZError(14, 'chest already opened')
|
||||
}
|
||||
if (chest.status === ChestStatusEnum.LOCKED) {
|
||||
throw new ZError(15, 'chest is locked')
|
||||
}
|
||||
const enhanced = chest.bonusUsers.includes(user.id) ? 1 : 0
|
||||
const userMax = user.twitterId && user.discordId ? MAX_ENHANCE_COUNT_ADV : MAX_ENHANCE_COUNT_BASE
|
||||
const dateTag = formatDate(new Date())
|
||||
const userCurrent = await ChestEnhanceRecord.countDocuments({ user: user.id, activity: user.activity, dateTag })
|
||||
|
||||
return {
|
||||
userCurrent,
|
||||
userMax,
|
||||
enhanced,
|
||||
chestCurrent: chest.bonusUsers.length,
|
||||
chestMax: chest.maxBounsCount,
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 宝箱助力
|
||||
*/
|
||||
@ -102,6 +148,14 @@ class BoxController extends BaseController {
|
||||
if (!isValidShareCode(code)) {
|
||||
throw new ZError(11, 'invalid share code')
|
||||
}
|
||||
const chainRecord = await GeneralScription.findOne({
|
||||
from: user.address.toLowerCase(),
|
||||
op: 'chest_enhance',
|
||||
data: code,
|
||||
})
|
||||
if (!chainRecord) {
|
||||
throw new ZError(13, 'waiting for chain confirm')
|
||||
}
|
||||
|
||||
// TODO:: 待规则确定后, 检查用户是否符合助力条件
|
||||
const chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity })
|
||||
@ -124,6 +178,12 @@ class BoxController extends BaseController {
|
||||
if (process.env.NODE_ENV === 'production' && chest.user === uid) {
|
||||
throw new ZError(15, 'can not enhance self')
|
||||
}
|
||||
const userMax = user.twitterId && user.discordId ? MAX_ENHANCE_COUNT_ADV : MAX_ENHANCE_COUNT_BASE
|
||||
const dateTag = formatDate(new Date())
|
||||
const userCurrent = await ChestEnhanceRecord.countDocuments({ user: user.id, activity: user.activity, dateTag })
|
||||
if (userCurrent >= userMax) {
|
||||
throw new ZError(16, 'user enhance times exceed')
|
||||
}
|
||||
const score = Math.floor(Math.random() * (chest.bounsCfg[1] - chest.bounsCfg[0] + 1) + chest.bounsCfg[0])
|
||||
await ActivityChest.updateOne(
|
||||
{ _id: chest.id },
|
||||
@ -132,20 +192,31 @@ class BoxController extends BaseController {
|
||||
$push: { bonusUsers: uid, bonusScores: score },
|
||||
},
|
||||
)
|
||||
const chestsForUser = await ActivityChest.find({ user: uid, activity: user.activity })
|
||||
// 如果用户没有宝箱, 则说明用户是新用户, 生成一个宝箱
|
||||
if (chestsForUser.length === 0) {
|
||||
const newChest = generateNewChest(uid, user.activity, 1, ChestStatusEnum.NORMAL)
|
||||
await newChest.save()
|
||||
return {
|
||||
score: 0,
|
||||
chests: [newChest.toJson()],
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
score: 0,
|
||||
}
|
||||
const enhanceRecord = new ChestEnhanceRecord({
|
||||
user: uid,
|
||||
activity: user.activity,
|
||||
dateTag,
|
||||
chest: chest.id,
|
||||
score,
|
||||
})
|
||||
await enhanceRecord.save()
|
||||
return {
|
||||
score,
|
||||
}
|
||||
// const chestsForUser = await ActivityChest.find({ user: uid, activity: user.activity })
|
||||
// 如果用户没有宝箱, 则说明用户是新用户, 生成一个宝箱
|
||||
// if (chestsForUser.length === 0) {
|
||||
// const newChest = generateNewChest(uid, user.activity, 1, ChestStatusEnum.NORMAL)
|
||||
// await newChest.save()
|
||||
// return {
|
||||
// score: 0,
|
||||
// chests: [newChest.toJson()],
|
||||
// }
|
||||
// } else {
|
||||
// return {
|
||||
// score: 0,
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
43
src/models/ChestEnhanceRecord.ts
Normal file
43
src/models/ChestEnhanceRecord.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||
import { dbconn } from 'decorators/dbconn'
|
||||
import { BaseModule } from './Base'
|
||||
|
||||
@dbconn()
|
||||
@index({ user: 1, activity: 1, dateTag: 1 }, { unique: false })
|
||||
@index({ user: 1, activity: 1, chest: 1 }, { unique: false })
|
||||
@index({ activity: 1, chest: 1 }, { unique: false })
|
||||
@modelOptions({
|
||||
schemaOptions: { collection: 'chest_enhance_record', timestamps: true },
|
||||
})
|
||||
class ChestEnhanceRecordClass extends BaseModule {
|
||||
@prop({ required: true })
|
||||
public user: string
|
||||
|
||||
@prop({ required: true })
|
||||
public activity: string
|
||||
|
||||
@prop()
|
||||
public chest: string
|
||||
|
||||
@prop()
|
||||
public dateTag: string
|
||||
|
||||
@prop()
|
||||
public score: number
|
||||
|
||||
public toJson() {
|
||||
return {
|
||||
user: this.user,
|
||||
activity: this.activity,
|
||||
chest: this.chest,
|
||||
score: this.score,
|
||||
dateTag: this.dateTag,
|
||||
//@ts-ignore
|
||||
time: this.createdAt.getTime(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ChestEnhanceRecord = getModelForClass(ChestEnhanceRecordClass, {
|
||||
existingConnection: ChestEnhanceRecordClass['db'],
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user