修改箱子助力流程
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. 探索状态(12), 移除signCfg, 增加seqStat, 用于标识连续签到奖励领取状态
|
||||||
1. 增加领取连续签到奖励(25)的接口
|
1. 增加领取连续签到奖励(25)的接口
|
||||||
|
|
||||||
|
#### 20240408
|
||||||
|
1. 增加宝箱助力状态查询(26), 用于助力上链前查询是否符合条件
|
||||||
|
|
||||||
### 1. 钱包预登录
|
### 1. 钱包预登录
|
||||||
|
|
||||||
#### Request
|
#### Request
|
||||||
@ -690,7 +693,7 @@ body:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
"days": 3 // 领取的累计签到天数
|
"code": 3 // 领取的累计签到天数
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -703,4 +706,37 @@ 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最小分数
|
// google reCaptcha最小分数
|
||||||
export const RECAPTCHA_MIN_SCORE = 0.5
|
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 { ScoreRecord } from 'models/ScoreRecord'
|
||||||
import { ChestRecord } from 'models/chain/ChestRecord'
|
import { ChestRecord } from 'models/chain/ChestRecord'
|
||||||
import { generateNewChest } from 'services/game.svr'
|
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 { formatAddress } from 'zutils/utils/chain.util'
|
||||||
import { isObjectIdString, isValidShareCode } from 'common/Utils'
|
import { isObjectIdString, isValidShareCode } from 'common/Utils'
|
||||||
import { checkReCaptcha } from 'services/google.svr'
|
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
|
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)) {
|
if (!isValidShareCode(code)) {
|
||||||
throw new ZError(11, 'invalid share 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:: 待规则确定后, 检查用户是否符合助力条件
|
// TODO:: 待规则确定后, 检查用户是否符合助力条件
|
||||||
const chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity })
|
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) {
|
if (process.env.NODE_ENV === 'production' && chest.user === uid) {
|
||||||
throw new ZError(15, 'can not enhance self')
|
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])
|
const score = Math.floor(Math.random() * (chest.bounsCfg[1] - chest.bounsCfg[0] + 1) + chest.bounsCfg[0])
|
||||||
await ActivityChest.updateOne(
|
await ActivityChest.updateOne(
|
||||||
{ _id: chest.id },
|
{ _id: chest.id },
|
||||||
@ -132,20 +192,31 @@ class BoxController extends BaseController {
|
|||||||
$push: { bonusUsers: uid, bonusScores: score },
|
$push: { bonusUsers: uid, bonusScores: score },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const chestsForUser = await ActivityChest.find({ user: uid, activity: user.activity })
|
const enhanceRecord = new ChestEnhanceRecord({
|
||||||
// 如果用户没有宝箱, 则说明用户是新用户, 生成一个宝箱
|
user: uid,
|
||||||
if (chestsForUser.length === 0) {
|
activity: user.activity,
|
||||||
const newChest = generateNewChest(uid, user.activity, 1, ChestStatusEnum.NORMAL)
|
dateTag,
|
||||||
await newChest.save()
|
chest: chest.id,
|
||||||
return {
|
score,
|
||||||
score: 0,
|
})
|
||||||
chests: [newChest.toJson()],
|
await enhanceRecord.save()
|
||||||
}
|
return {
|
||||||
} else {
|
score,
|
||||||
return {
|
|
||||||
score: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 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