实现抽奖接口

This commit is contained in:
zhl 2021-06-07 16:32:37 +08:00
parent bb2d99742c
commit 3bdd960cfa
5 changed files with 154 additions and 15 deletions

View File

@ -526,12 +526,15 @@
3. Response: JSON 3. Response: JSON
```js ```js
[{ [ // 奖励列表
"name": '显示名', {
"reward_type": '奖励物品的id', coupon: '优惠券的id',
"reward_count": 100, //奖励物品数量 name: '优惠券名',
"icon": "item/item_0" // 奖励物品的图片地址, 可能是本地,远程, 如果该字段为空的话, 需要取本地的默认值 count: 1, //数量
}] couponUrl: '优惠券详情图的url',
rewardType: 0, // 0: 优惠券, 1: 抽奖券
}
]
``` ```
### 14. 抽奖 ### 14. 抽奖
@ -553,12 +556,13 @@
3. Response: JSON 3. Response: JSON
```js ```js
{ [{ // 本次请求新获得的物品
"name": '显示名', coupon: '优惠券的id',
"reward_type": '奖励物品的id', name: '优惠券名',
"reward_count": 100, //奖励物品数量 count: 1, //数量
"icon": "item/item_0" // 奖励物品的图片地址, 可能是本地,远程, 如果该字段为空的话, 需要取本地的默认值 couponUrl: '优惠券详情图的url',
} rewardType: 0, // 0: 优惠券, 1: 抽奖券
}]
``` ```
@ -583,13 +587,13 @@
```js ```js
{ {
num: 10, // 已邀请人数 num: 10, // 已邀请人数
newget: [ // 本次请求新获得的物品 newget: [{ // 本次请求新获得的物品
coupon: '优惠券的id', coupon: '优惠券的id',
name: '优惠券名', name: '优惠券名',
count: 1, //数量 count: 1, //数量
couponUrl: '优惠券详情图的url', couponUrl: '优惠券详情图的url',
rewardType: 0, // 0: 优惠券, 1: 抽奖券 rewardType: 0, // 0: 优惠券, 1: 抽奖券
] }]
rewards: [ // 奖励列表 rewards: [ // 奖励列表
{ {
coupon: '优惠券的id', coupon: '优惠券的id',

View File

@ -94,7 +94,7 @@ class GameUserController extends BaseController {
throw new ZError(12, '当前店铺未配置相关信息') throw new ZError(12, '当前店铺未配置相关信息')
} }
if (!cfg.share_cfgs || cfg.share_cfgs.length === 0) { if (!cfg.share_cfgs || cfg.share_cfgs.length === 0) {
throw new ZError(12, '当前店铺未配置相关信息') throw new ZError(13, '当前店铺未配置相关信息')
} }
let rewardList = [] let rewardList = []
let newItems: any[] = [] let newItems: any[] = []

View File

@ -0,0 +1,105 @@
import BaseController from '../../common/base.controller'
import { role, router } from '../../decorators/router'
import { ZError } from '../../common/ZError'
import { Shop } from '../../models/shop/Shop'
import { ShopCfg } from '../../models/shop/ShopCfg'
import { Coupon } from '../../models/shop/Coupon'
import { getCouponUrl } from '../../services/File'
import { UserItem } from '../../models/user/UserItem'
import { LOTTERY_TICKET } from '../../constants/BaseConst'
import { UserReward } from '../../models/user/UserReward'
import { random_prob } from '../../utils/number.util'
class LotteryController extends BaseController {
@role('anon')
@router('post /api/:accountId/lottery_info')
async info(req: any) {
const { accountId, sid, sessionid } = req.params
if (!sid) {
throw new ZError(10, '缺少必要参数: sid')
}
const shop = await Shop.fetchByID(sid)
if (!shop) {
throw new ZError(11, '无法找到对应店铺')
}
const cfg = await ShopCfg.findOne({ shop: shop.id })
if (!cfg) {
throw new ZError(12, '当前店铺未配置相关信息')
}
if (!cfg.lottery_cfgs || cfg.lottery_cfgs.length === 0) {
throw new ZError(12, '当前店铺未配置相关信息')
}
let rewardList = []
let couponMap: Map<string, any> = new Map()
for (let reward of cfg.lottery_cfgs) {
let name = '抽奖券'
let couponUrl = reward.icon
if (reward.rewardType === 0) {
if (!couponMap.has(reward.coupon)) {
let coupon = await Coupon.findById(reward.coupon)
couponMap.set(coupon.id, coupon)
}
name = couponMap.get(reward.coupon).name
couponUrl = reward.icon || getCouponUrl(shop.id, reward.coupon)
}
rewardList.push({
coupon: reward.coupon,
name,
count: reward.count,
couponUrl,
rewardType: reward.rewardType,
})
}
return rewardList
}
@role('anon')
@router('post /api/:accountId/lottery')
async draw(req: any) {
const { accountId, sid, sessionid } = req.params
if (!sid) {
throw new ZError(10, '缺少必要参数: sid')
}
const shop = await Shop.fetchByID(sid)
if (!shop) {
throw new ZError(11, '无法找到对应店铺')
}
const cfg = await ShopCfg.findOne({ shop: shop.id })
if (!cfg) {
throw new ZError(12, '当前店铺未配置相关信息')
}
if (!cfg.lottery_cfgs || cfg.lottery_cfgs.length === 0) {
throw new ZError(13, '当前店铺未配置相关信息')
}
const count = await UserItem.fetchCount({ accountId, shop: shop.id, item: LOTTERY_TICKET })
if (count < 1) {
throw new ZError(14, '券不够了')
}
await UserItem.addOne({
accountId,
shop: shop.id,
item: LOTTERY_TICKET,
count: -1,
reason: 'lottery',
params: {},
})
let arr = []
for (let data of cfg.lottery_cfgs) {
arr.push(data.rank)
}
let idx = random_prob(arr)
const reward = cfg.lottery_cfgs[idx]
let obj = await UserReward.saveOneRecord({
accountId,
shop: shop.id,
itemId: reward.coupon,
count: reward.count,
rewardId: reward._id + '',
activityId: 'lottery',
source: 'lottery',
})
let rewardList = []
rewardList.push(obj)
return rewardList
}
}

View File

@ -30,6 +30,12 @@ export class ShareCfgClass extends Base {
} }
export class LotteryCfgClass extends Base { export class LotteryCfgClass extends Base {
/**
*
* @type {number}
*/
@prop()
public rank: number
@prop() @prop()
public name: string public name: string

View File

@ -8,3 +8,27 @@ export function getRandom(max: number, min?: number): number {
min = min || 0 min = min || 0
return Math.floor(Math.random() * (max - min) + min) return Math.floor(Math.random() * (max - min) + min)
} }
/**
* index
* @since 1.0.0
* @param prob_array
*/
export function random_prob(prob_array: number[]): number {
let total = 0
for (let _d of prob_array) {
total += _d
}
prob_array = prob_array.map(o => o / total)
// 获取随机数
let r = Math.random()
// 对概率数组的处理
let s = prob_array
.map((v, index) => {
return { index: index, prob: v }
})
.sort((a, b) => a.prob - b.prob)
// 判断随机位置
let result = s.find(v => (r -= v.prob) <= 0)
return result ? result.index : s.length - 1
}