增加活动和挑战奖励的发放
This commit is contained in:
parent
de3d850c62
commit
bf6028c934
@ -97,7 +97,14 @@
|
||||
"timeLeft": 1, // 当局剩余时间
|
||||
"gameResult": 0 // 当局的游戏结果, 单人的话和上一层gameResult相同
|
||||
}
|
||||
}
|
||||
},
|
||||
"rewards": [{
|
||||
coupon: '优惠券的id',
|
||||
name: '优惠券名',
|
||||
count: 1, //数量
|
||||
couponUrl: '优惠券详情图的url',
|
||||
ids: ['获取记录的短id']
|
||||
}]
|
||||
}
|
||||
```
|
||||
### 3. 开始匹配
|
||||
|
@ -13,7 +13,8 @@ import {
|
||||
transformRecord,
|
||||
updateExamRank
|
||||
} from '../../services/GameLogic'
|
||||
import { validShopId } from '../../models/shop/Shop'
|
||||
import { Shop, validShopId } from '../../models/shop/Shop'
|
||||
import { UserReward } from '../../models/UserReward'
|
||||
|
||||
class ExamController extends BaseController {
|
||||
@role('anon')
|
||||
@ -34,6 +35,11 @@ class ExamController extends BaseController {
|
||||
}
|
||||
let params = {}
|
||||
let results: any[] = []
|
||||
let shopData = await Shop.fetchByID(shop)
|
||||
if (!shopData) {
|
||||
throw new ZError(13, 'shop not found')
|
||||
}
|
||||
shop = shopData.id
|
||||
let history = new PuzzleSession({ shop, level: 0})
|
||||
if (record.source === 0) {
|
||||
if (record.qtypes && record.qtypes.length > 0) {
|
||||
@ -141,8 +147,23 @@ class ExamController extends BaseController {
|
||||
rspData.rankList = rankList
|
||||
rspData.userRank = userRank
|
||||
rspData.rankTotal = rankTotal
|
||||
let examData = await ShopExam.findById(history.activityId)
|
||||
let rewardList = []
|
||||
if (!examData && examData.rewardInfo && examData.rewardInfo.length > 0) {
|
||||
let rewards = examData.getReward(statMap.score)
|
||||
for (let reward of rewards) {
|
||||
let geted = await UserReward.examRewardGeted(history, accountid, reward.id)
|
||||
if (geted) {
|
||||
continue
|
||||
}
|
||||
const data = await UserReward.addOneRecord(history, accountid, reward.id, reward.coupon, reward.count)
|
||||
rewardList.push(data)
|
||||
}
|
||||
}
|
||||
rspData.rewords = rewardList
|
||||
}
|
||||
rspData.gameResult = gameResult
|
||||
rspData.rewords = {}
|
||||
return rspData
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
updateSingleRank
|
||||
} from '../../services/GameLogic'
|
||||
import { Shop, validShopId } from '../../models/shop/Shop'
|
||||
import { ShopActivity } from '../../models/shop/ShopActivity'
|
||||
|
||||
|
||||
class PuzzleController extends BaseController {
|
||||
@ -57,7 +58,7 @@ class PuzzleController extends BaseController {
|
||||
}
|
||||
const cfg = fetchLevelCfg(level)
|
||||
let params = {}
|
||||
let typeArr = await fetchSinglePuzzleType({shopId: shop, levelCfg: cfg})
|
||||
let { shopId, typeArr } = await fetchSinglePuzzleType({shopId: shop, levelCfg: cfg})
|
||||
if (typeArr?.length > 0) {
|
||||
params = {$or: [{tag: {$in: typeArr}}, {sub_tag: {$in: typeArr}}]}
|
||||
}
|
||||
@ -65,7 +66,7 @@ class PuzzleController extends BaseController {
|
||||
let record2 = await Puzzle.randomQuestions(Object.assign(params, {quality: 2}), 5)
|
||||
let record3 = await Puzzle.randomQuestions(Object.assign(params, {quality: 3}), 5)
|
||||
const records = (record1.concat(record2)).concat(record3)
|
||||
let history = new PuzzleSession({ shop, level })
|
||||
let history = new PuzzleSession({ shop: shopId, level })
|
||||
history.members.set(accountid, new PuzzleStatusClass())
|
||||
for (let record of records) {
|
||||
history.questions.set(record.id, record.a1)
|
||||
@ -203,7 +204,7 @@ class PuzzleController extends BaseController {
|
||||
@role('anon')
|
||||
@router('post /api/:accountid/puzzle/match')
|
||||
async joinMultipleGame(req, res) {
|
||||
const { shop, aid, accountid, debug_begin_sec, debug_qcount } = req.params
|
||||
let { shop, aid, accountid, debug_begin_sec, debug_qcount } = req.params
|
||||
let data: any = { shop, maxTime: 3600, accountid }
|
||||
let beginSecond = (debug_begin_sec ? +debug_begin_sec : 20)
|
||||
beginSecond = (Math.max(2, beginSecond)) * 1000
|
||||
@ -213,12 +214,19 @@ class PuzzleController extends BaseController {
|
||||
* 如果没有人请求, 说明没人参加, 也没必要开启定时了
|
||||
* TODO:: 读取店铺活动配置
|
||||
*/
|
||||
let activityId = '1111111'
|
||||
|
||||
let roomId = ''
|
||||
let sessionId = ''
|
||||
let sessionMatch = ''
|
||||
let beginTime = 0
|
||||
if (!aid) {
|
||||
throw new ZError(12, 'params no match')
|
||||
}
|
||||
let activity = await ShopActivity.findById(aid)
|
||||
let shopData = await Shop.fetchByID(shop)
|
||||
shop = shopData.id
|
||||
if (!activity) {
|
||||
throw new ZError(13, 'activity not found')
|
||||
}
|
||||
let result = new RoomState().isLock(shop)
|
||||
try {
|
||||
await retry<Promise<string>>(async () => {
|
||||
@ -226,7 +234,7 @@ class PuzzleController extends BaseController {
|
||||
throw new RoomLockErr('')
|
||||
}
|
||||
new RoomState().lock(shop)
|
||||
let history = await PuzzleSession.findOne({ shop, status: {$in: [0, 1]}, type: 1 })
|
||||
let history = await PuzzleSession.findOne({ shop, status: {$in: [0, 1]}, type: 1, activityId: aid })
|
||||
if (history) {
|
||||
// if (history && !history.hasExpired()) {
|
||||
beginTime = history.begin
|
||||
@ -261,6 +269,7 @@ class PuzzleController extends BaseController {
|
||||
roomId = rsp.data?.room?.roomId
|
||||
sessionId = rsp.data?.sessionId
|
||||
history = new PuzzleSession({shop, status: 0, type: 1})
|
||||
history.activityId = aid
|
||||
let memberData = new PuzzleStatusClass()
|
||||
memberData.sessionId = sessionId
|
||||
history.members.set(accountid, memberData)
|
||||
|
@ -10,6 +10,7 @@ import { customAlphabet, } from 'nanoid'
|
||||
import { Shop } from './shop/Shop'
|
||||
import { Coupon } from './shop/Coupon'
|
||||
import { getCouponUrl } from '../services/File'
|
||||
import { PuzzleSessionClass } from './match/PuzzleSession'
|
||||
|
||||
const nanoid = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
||||
|
||||
@ -60,6 +61,9 @@ class UserRewardClass extends BaseModule {
|
||||
@prop()
|
||||
public coupon: string
|
||||
|
||||
@prop()
|
||||
public rewardId: string
|
||||
|
||||
/**
|
||||
* 状态
|
||||
* 0: 未使用
|
||||
@ -102,6 +106,50 @@ class UserRewardClass extends BaseModule {
|
||||
}
|
||||
}
|
||||
|
||||
public compactInfo() {
|
||||
return {
|
||||
id: this.sid,
|
||||
couponUrl: getCouponUrl(this.sid, this.coupon),
|
||||
}
|
||||
}
|
||||
|
||||
public static async addOneRecord(history: PuzzleSessionClass, accountId: string, rewardId: string, coupon: string, count: number, ) {
|
||||
let ids: string[] = []
|
||||
let cdata = await Coupon.findById(coupon)
|
||||
for (let i = 0; i < count; i++) {
|
||||
let record = new UserReward({
|
||||
accountId,
|
||||
shop: history.shop,
|
||||
sessionId: history._id,
|
||||
status: 0,
|
||||
rewardId
|
||||
})
|
||||
if (history.type === 1) {
|
||||
record.activityId = history.activityId
|
||||
}
|
||||
await record.save()
|
||||
ids.push(record.sid)
|
||||
}
|
||||
return {
|
||||
coupon,
|
||||
name: cdata.name,
|
||||
count,
|
||||
couponUrl: getCouponUrl(history.shop, coupon),
|
||||
ids
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查挑战的奖励是否已领取
|
||||
* @param {PuzzleSessionClass} history
|
||||
* @param {string} accountId
|
||||
* @param rewardId
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
public static async examRewardGeted(history: PuzzleSessionClass, accountId: string, rewardId: string) {
|
||||
let records = await UserReward.find({accountId, examId: history.activityId, rewardId, shop: history.shop}, {_id: 1}).limit(1)
|
||||
return records.length > 0
|
||||
}
|
||||
}
|
||||
|
||||
export const UserReward = getModelForClass(UserRewardClass, {existingConnection: UserRewardClass.db})
|
||||
|
@ -9,8 +9,9 @@ import { noJson } from '../../decorators/nojson'
|
||||
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
|
||||
import moment from 'moment'
|
||||
import { GameEnv } from '../../config/GameEnv'
|
||||
import { Base } from '@typegoose/typegoose/lib/defaultClasses'
|
||||
|
||||
export class ActivityRewardClass {
|
||||
export class ActivityRewardClass extends Base{
|
||||
@prop()
|
||||
public id: number
|
||||
@prop()
|
||||
@ -172,6 +173,24 @@ export class ShopActivityClass extends BaseModule {
|
||||
result.next = getNextTime(record, result.current)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据排名获取奖励
|
||||
* @param {number} rank
|
||||
* @return {null | {count: number, id: string}}
|
||||
*/
|
||||
public getReward(rank: number) {
|
||||
if (!this.rewardInfo || this.rewardInfo.length === 0) {
|
||||
return null
|
||||
}
|
||||
this.rewardInfo.sort((a, b) => a.rank - b.rank)
|
||||
for (let reward of this.rewardInfo) {
|
||||
if (rank < reward.rank || (reward.rankEnd && rank < reward.rankEnd)) {
|
||||
return {id: reward._id + '', coupon:reward.coupon, count: reward.count}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export const ShopActivity = getModelForClass(ShopActivityClass, { existingConnection: ShopActivityClass.db })
|
||||
|
@ -8,6 +8,7 @@ import { BaseModule } from '../Base'
|
||||
import { noJson } from '../../decorators/nojson'
|
||||
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
|
||||
import { Base } from '@typegoose/typegoose/lib/defaultClasses'
|
||||
import { UserReward } from '../UserReward'
|
||||
|
||||
export class ShopPuzzleClass extends Base{
|
||||
@prop()
|
||||
@ -22,7 +23,7 @@ export class ShopPuzzleClass extends Base{
|
||||
public a4: string
|
||||
}
|
||||
|
||||
export class ExamRewardClass {
|
||||
export class ExamRewardClass extends Base{
|
||||
@prop()
|
||||
public id: number
|
||||
@prop()
|
||||
@ -179,6 +180,19 @@ export class ShopExamClass extends BaseModule {
|
||||
}
|
||||
})
|
||||
}
|
||||
public getReward(score: number) {
|
||||
if (!this.rewardInfo || this.rewardInfo.length === 0) {
|
||||
return []
|
||||
}
|
||||
this.rewardInfo.sort((a, b) => a.rank - b.rank)
|
||||
let results = []
|
||||
for (let reward of this.rewardInfo) {
|
||||
if (score >= reward.rank) {
|
||||
results.push({id: reward._id + '', coupon:reward.coupon, count: reward.count})
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
export const ShopExam = getModelForClass(ShopExamClass, { existingConnection: ShopExamClass.db })
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
beginGame,
|
||||
endGame,
|
||||
endGame, sendMsg,
|
||||
sendQuestion,
|
||||
updateRound,
|
||||
updateScore
|
||||
@ -16,6 +16,7 @@ import { mission_vo } from '../config/parsers/mission_vo'
|
||||
import { ShopActivity } from '../models/shop/ShopActivity'
|
||||
import { getAccountRank, getRankCount, getRankList, updateRank } from './Rank'
|
||||
import { PuzzleRank } from '../models/match/PuzzleRank'
|
||||
import { UserReward } from '../models/UserReward'
|
||||
|
||||
|
||||
export function transformRecord(records: any[]) {
|
||||
@ -64,7 +65,12 @@ export function checkSubFinish(history: any, qid: string) {
|
||||
*/
|
||||
export async function startGame(roomId: string, sessionId: string) {
|
||||
let history = await PuzzleSession.findById(sessionId)
|
||||
let records = await Puzzle.randomQuestions({status: 1, is_hide: 0, deleted: 0, dp: 1}, history.total)
|
||||
let typeArr = await fetchPvpPuzzleType({shopId: history.shop, aid: history.activityId})
|
||||
let params = {}
|
||||
if (typeArr?.length > 0) {
|
||||
params = {$or: [{tag: {$in: typeArr}}, {sub_tag: {$in: typeArr}}]}
|
||||
}
|
||||
let records = await Puzzle.randomQuestions(params, history.total)
|
||||
await beginGame(roomId, {})
|
||||
for (let record of records) {
|
||||
history.questions.set(record.id, record.a1)
|
||||
@ -85,6 +91,8 @@ export async function sendOneQuestion(history: any) {
|
||||
history.status = 9
|
||||
await history.save()
|
||||
await endGame(roomId, {closeTime: BaseConst.ROOM_AUTO_CLOSE_TIME})
|
||||
//TODO:: 发送奖励
|
||||
await sendReward(history)
|
||||
return
|
||||
}
|
||||
const questions:string[] = Array.from(history.questions.keys())
|
||||
@ -114,6 +122,31 @@ export async function sendOneQuestion(history: any) {
|
||||
}, history.scheduleKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送活动奖励
|
||||
* @param history
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
export async function sendReward(history: any) {
|
||||
let activity = await ShopActivity.findById(history.activity)
|
||||
if (activity.rewardInfo.length === 0) {
|
||||
return
|
||||
}
|
||||
let members = []
|
||||
for (let [ key, val ] of history.members) {
|
||||
members.push({accountId: key, score: val.score, sessionId: val.sessionId})
|
||||
}
|
||||
members.sort((a, b) => a.score - b.score)
|
||||
for (let i = 0, len = members.length; i < len; i++) {
|
||||
const adata = activity.getReward(i)
|
||||
if (!adata) {
|
||||
continue
|
||||
}
|
||||
const data = await UserReward.addOneRecord(history, members[i].accountId, adata.id, adata.coupon, adata.count)
|
||||
await sendMsg(history.room, members[i].sessionId, 'rewords', data)
|
||||
}
|
||||
}
|
||||
|
||||
export function calcExamScore(time: number, combo: number) {
|
||||
const cfg = new GameEnv()
|
||||
return cfg.pvpBaseScore + time / 100 * cfg.pvpTimeRate + combo * cfg.pvpComboRate
|
||||
@ -281,7 +314,7 @@ export async function fetchSinglePuzzleType({shopId, levelCfg} : {shopId: string
|
||||
if (typeArr.length === 0 && levelCfg?.keyID) {
|
||||
typeArr = levelCfg.keyID.split(':')
|
||||
}
|
||||
return typeArr
|
||||
return {shopId: shop.id, typeArr}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user