Commit 93f966d8 authored by 杨梦雅's avatar 杨梦雅

会员权益,降级奖品,助力

parent 134702e0
......@@ -82,6 +82,12 @@ export const PRIZE_TYPE = {
CARD: 6
}
// 权益类型
export const BENEFIT_TYPE = {
NORMAL: 1,
MEMBER: 2
}
// 奖品分类
export const PRIZE_DATA_TYPE = {
RANKING: 1, // 排行榜
......
......@@ -22,7 +22,7 @@ export default class AwardsController {
*/
@checkParams(['activityId'])
@services([CommonAwardsService])
async getMyPrizeList(
async getMyAwardsList(
context: IContext<IParams>,
{ activityInfo }: IControllerInfos,
[awardSer]: [CommonAwardsService]
......
......@@ -16,7 +16,7 @@ export default class AwardsController {
*/
@checkParams(['activityId'])
@services([CommonAwardsService])
async getMyPrizeList(
async getMyAwardsList(
context: IContext<IParams>,
{ activityInfo, userInfo }: IControllerInfos,
[commonAwardsService]: [CommonAwardsService]
......@@ -72,7 +72,7 @@ export default class AwardsController {
@registeInfos(['session'])
@services([CommonAwardsService])
@preCheck([checkActivityTime])
async drawLotteryPrize(
async drawLottery(
context: IContext<IParams>,
{ activityInfo, userInfo, session }: IControllerInfos,
[commonAwardsService]: [CommonAwardsService]
......
......@@ -8,14 +8,14 @@ export default class StatController {
/**
* 增加埋点记录
*/
@checkParams(['activityId', 'type'])
@checkParams(['activityId', 'key'])
@services([CommonStatService])
async addStat(
context: IContext<IParams>,
{ activityInfo, userInfo }: IControllerInfos,
[commonStatService]: [CommonStatService]
) {
const commonStatAddStatResult1 = await commonStatService.addStat(context.data.type, userInfo)
const commonStatAddStatResult1 = await commonStatService.addStat(context.data.key, userInfo)
return resultsModel.success({
...commonStatAddStatResult1
})
......
......@@ -33,17 +33,17 @@ export default class TaskController {
/**
* 完成任务
*/
@checkParams(['activityId', 'taskType'])
@checkParams(['activityId', 'key'])
@registeInfos(['session', 'task'])
@services([CommonGrowtaskService])
@preCheck([checkActivityTime, checkGrowTaskLimit, checkExchangeCreditsTask])
async doCompleteTask(
async completeTask(
context: IContext<IParams>,
{ activityInfo, userInfo, session, task }: IControllerInfos,
[commonGrowtaskService]: [CommonGrowtaskService]
) {
const commonGrowtaskCompleteTaskResult1 = await commonGrowtaskService.completeTask(
context.data.taskType,
context.data.key,
activityInfo,
userInfo,
task
......@@ -55,16 +55,16 @@ export default class TaskController {
/**
* 领取任务奖励
*/
@checkParams(['activityId', 'taskType', 'rewardsKey'])
@checkParams(['activityId', 'key', 'rewardsKey'])
@services([CommonGrowtaskService])
@preCheck([checkActivityTime, checkRemainTimes])
async receiveTaskRewards(
async receiveTask(
context: IContext<IParams>,
{ activityInfo, userInfo }: IControllerInfos,
[commonGrowtaskService]: [CommonGrowtaskService]
) {
const commonGrowtaskReceiveTaskRewardsResult1 = await commonGrowtaskService.receiveTaskRewards(
context.data.taskType,
context.data.key,
context.data.rewardsKey,
userInfo
)
......
......@@ -42,16 +42,16 @@ export default class Task {
* 商品相关任务 需要传itemId参数
* 积分兑换任务 需要传credits参数
*/
@checkParams(['activityId', 'taskType', 'itemId?', 'credits?'])
@checkParams(['activityId', 'key', 'itemId?', 'credits?'])
@registeInfos(['session', 'task'])
@services([CommonGrowtaskService])
@preCheck([checkActivityTime, checkGrowTaskLimit, checkExchangeCreditsTask])
async doCompleteTask(
async completeTask(
context: IContext<IParams>,
{ userInfo, activityInfo, task }: IControllerInfos,
[growTaskService]: [CommonGrowtaskService]
) {
const { taskType } = context.data
const { key: taskType } = context.data
// 更新user表
const result = await growTaskService.completeTask(taskType, activityInfo, userInfo, task)
......@@ -63,16 +63,16 @@ export default class Task {
* 领取任务奖励
* 领取的奖励增加的key值 如: gameTimes 前端传入
*/
@checkParams(['activityId', 'taskType', 'rewardsKey'])
@checkParams(['activityId', 'key', 'rewardsKey'])
@services([CommonGrowtaskService])
@preCheck([checkActivityTime, checkRemainTimes])
async receiveTaskRewards(
async receiveTask(
context: IContext<IParams>,
{ userInfo }: IControllerInfos,
[growTaskService]: [CommonGrowtaskService]
): Promise<IResult<{ rewards: number }>> {
const { rewardsKey } = context.data
const { taskType } = context.data
const { key: taskType } = context.data
const rewardsResult = await growTaskService.receiveTaskRewards(taskType, rewardsKey, userInfo)
......
......@@ -42,16 +42,16 @@ export default class Task {
* 商品相关任务 需要传itemId参数
* 积分兑换任务 需要传credits参数
*/
@checkParams(['activityId', 'taskType', 'itemId?', 'credits?'])
@checkParams(['activityId', 'key', 'itemId?', 'credits?', 'inviteId?'])
@registeInfos(['session'])
@services([CommonTaskService])
@preCheck([checkActivityTime, checkTaskLimit, checkExchangeCreditsTask])
async doCompleteTask(
async completeTask(
context: IContext<IParams>,
{ userInfo, activityInfo }: IControllerInfos,
[taskService]: [CommonTaskService]
) {
const { taskType } = context.data
const { key: taskType } = context.data
// 更新user表
const result = await taskService.completeTask(taskType, activityInfo, userInfo)
......@@ -63,16 +63,16 @@ export default class Task {
* 领取任务奖励
* 领取的奖励增加的key值 如: gameTimes 前端传入
*/
@checkParams(['activityId', 'taskType', 'rewardsKey'])
@checkParams(['activityId', 'key', 'rewardsKey'])
@services([CommonTaskService])
@preCheck([checkActivityTime, checkRemainTimes])
async receiveTaskRewards(
async receiveTask(
context: IContext<IParams>,
{ userInfo }: IControllerInfos,
[taskService]: [CommonTaskService]
): Promise<IResult<{ rewards: number }>> {
const { rewardsKey } = context.data
const { taskType } = context.data
const { key: taskType } = context.data
const rewardsResult = await taskService.receiveTaskRewards(taskType, rewardsKey, userInfo)
......
......@@ -24,17 +24,17 @@ export default {
getVipInfo: CommonUserControllerInstance.getVipInfo,
getRankList: CommonUserControllerInstance.getRankList,
getTaskList: CommonTaskControllerInstance.getTaskList,
doCompleteTask: CommonTaskControllerInstance.doCompleteTask,
receiveTaskRewards: CommonTaskControllerInstance.receiveTaskRewards,
completeTask: CommonTaskControllerInstance.completeTask,
receiveTask: CommonTaskControllerInstance.receiveTask,
getCollectGoodsList: CommonTaskControllerInstance.getCollectGoodsList,
login: CommonLoginControllerInstance.login,
getActivityBaseInfoById: CommonBaseControllerInstance.getActivityBaseInfoById,
addStat: CommonStatControllerInstance.addStat,
getStats: CommonStatControllerInstance.getStats,
getMyPrizeList: CommonAwardsControllerInstance.getMyPrizeList,
getMyAwardsList: CommonAwardsControllerInstance.getMyAwardsList,
receiveObjectPrize: CommonAwardsControllerInstance.receiveObjectPrize,
receiveEnamePrize: CommonAwardsControllerInstance.receiveEnamePrize,
drawLotteryPrize: CommonAwardsControllerInstance.drawLotteryPrize,
drawLottery: CommonAwardsControllerInstance.drawLottery,
endOfActivityRewards: CommonAwardsControllerInstance.endOfActivityRewards,
getShareInfo: CommonShareControllerInstance.getShareInfo,
doHelp: CommonShareControllerInstance.doHelp,
......
......@@ -14,7 +14,8 @@ import {
DELETE_STATUS,
SWICH_TOCK,
SHIP_STATUS,
ACTIVITY_OPEN_PRIZE_STATUS
ACTIVITY_OPEN_PRIZE_STATUS,
BENEFIT_TYPE
} from '../../constants'
import { AWARDS_DB_NAME, PRIZE_CONFIG_DB_NAME } from '../../db'
import { sendTBAward, getSellerSession, rand, formatPrizeProbalityRange } from '../../utils'
......@@ -85,7 +86,9 @@ export default class AwardsService extends UserService {
remark: 1,
useUrl: 1,
shipCompany: 1,
shipNum: 1
shipNum: 1,
benefitType: 1,
ename: 1
},
sort: {
createTime: -1
......@@ -193,8 +196,19 @@ export default class AwardsService extends UserService {
// 发放淘宝权益(奖品数据已插入到awards_info表,且状态drawStatus 为1或者6)
async recieveEnamePrize(_id: string, awardInfo: IAwards, session: string) {
// 发放淘宝权益
let result = await sendTBAward(this.context, session, awardInfo)
let result
// 判断权益类型
const { type, benefitType } = awardInfo
if (type === PRIZE_TYPE.ENAME && benefitType === BENEFIT_TYPE.MEMBER) {
// 会员权益,前端领取成功
result = {
drawStatus: DRAW_STATUS.SUCCESS,
remark: ''
}
} else {
// 发放淘宝权益
result = await sendTBAward(this.context, session, awardInfo)
}
// 更新
await this.awardsdao.update(
{ _id },
......@@ -223,6 +237,9 @@ export default class AwardsService extends UserService {
prizeDataType
})
// 降级奖品
const backupPrize = prizesPool.find(v => !!v.isBackUp)
// 谢谢参与
const thanksPrize = prizesPool.find(v => v.type === PRIZE_TYPE.THANKS) || {
type: PRIZE_TYPE.THANKS,
prizeDataType,
......@@ -234,22 +251,30 @@ export default class AwardsService extends UserService {
// 未找到奖品,降级到谢谢参与
if (!prize) {
prize = thanksPrize
prize = backupPrize || thanksPrize
}
let reduceResult: ICodeType | number = 1
// 不是积分奖品, 检查是否扣库存
if (prize.type !== PRIZE_TYPE.CREDITS && prize.type !== PRIZE_TYPE.THANKS) {
if (!prize.isBackUp && prize.type !== PRIZE_TYPE.CREDITS && prize.type !== PRIZE_TYPE.THANKS) {
reduceResult = await this.reduceStock(prize._id)
// 扣库存失败降级到降级奖品
if ((reduceResult as ICodeType)?.code || !reduceResult) {
prize = backupPrize || thanksPrize
}
}
// 扣库存失败降级到谢谢参与
if ((reduceResult as ICodeType)?.code || !reduceResult) {
prize = thanksPrize
// 如果降级奖品限制库存,则扣库存,失败降级到谢谢参与
if (prize.isBackUp && prize.type !== PRIZE_TYPE.CREDITS && prize.type !== PRIZE_TYPE.THANKS) {
reduceResult = await this.reduceStock(prize._id)
// 扣库存失败降级到降级奖品
if ((reduceResult as ICodeType)?.code || !reduceResult) {
prize = thanksPrize
}
}
const { type, _id, ename, image, name, useUrl, credits } = prize
const { type, _id, ename, image, name, useUrl, credits, benefitType } = prize
const { userNick } = userInfo
let record = {
......@@ -261,6 +286,7 @@ export default class AwardsService extends UserService {
remark: '',
useUrl,
type,
benefitType,
ename,
name,
image,
......@@ -275,6 +301,8 @@ export default class AwardsService extends UserService {
return {
id: result,
type,
benefitType,
ename,
name,
image
}
......@@ -282,7 +310,7 @@ export default class AwardsService extends UserService {
// 根据查询条件获取奖品配置
async getPrizeConfig(
query: { activityId: string; [queryParam: string]: any },
query: { activityId: string;[queryParam: string]: any },
projection: IFindProjection = {}
): Promise<IActivityPrize[]> {
return this.activityprizedao.find<IActivityPrize>(
......@@ -346,7 +374,7 @@ export default class AwardsService extends UserService {
)
const prizeList = []
prizeConfigList.forEach(prizeConfig => {
const { rank, _id: prizeId, type, name, ename, image, credits } = prizeConfig
const { rank, _id: prizeId, type, name, ename, image, credits, benefitType } = prizeConfig
let [min, max] = rank.split('-')
if (!max) max = min
for (let i = +min - 1; i < +max; i++) {
......@@ -360,6 +388,7 @@ export default class AwardsService extends UserService {
prizeDataType,
remark: '',
credits: +credits,
benefitType,
ename,
type,
name,
......
......@@ -115,11 +115,40 @@ export default class TaskService extends UserService {
async completeTask(taskType: ITaskType, activityInfo: IActivityInfo, userInfo: IUserInfo, customRecord: Object = {}) {
const today = getToday()
const rewards = activityInfo?.tasks?.[taskType]?.value || 0
const {
let {
openId,
data: { itemId }
data: { itemId, inviteId, isVip }
} = this.context
// 邀请任务由被邀请人完成,单独处理
if (taskType === 'invites') {
if (!inviteId) return CODE_TYPES.ERROR_INVALID_INVITE_ID
if (openId === inviteId) return CODE_TYPES.ERROR_NO_INVITE_SELF
if (userInfo?.inviteId) return CODE_TYPES.ERROR_AREADY_INVITE_SUCCESS
// 是否是新会员助力
if (!isVip) return CODE_TYPES.ERROR_NO_VIP
const isNewVip = !userInfo?.member?.flag && isVip
if (!isNewVip) return CODE_TYPES.ERROR_INVITE
const { _id, tasks: { invites } } = activityInfo
// 获取邀请者信息
const inviteUserInfo = await this.userdao.findOne<IUserInfo>({
activityId: _id,
openId: inviteId
})
// inviteId的用户信息查询不到, 则inviteId无效
if(!inviteUserInfo) return CODE_TYPES.ERROR_INVALID_INVITE_ID
const { taskRateType, times } = invites
const { todayCompleteTimes } = getTodayCompleteTask('invites', inviteUserInfo)
// 助力次数超限制
if (taskRateType === TASK_RATE_TYPE.EVERYDAY && todayCompleteTimes >= times) {
return CODE_TYPES.ERROR_INVITE_TIMES_LIMIT
}
openId = inviteId
userInfo = inviteUserInfo
}
const record = { itemId, openId: taskType === 'invites' ? openId : undefined, ...customRecord }
let updateQuery: IUpdateQuery = {
$inc: {
......
......@@ -10,6 +10,7 @@ interface ICommonAwards {
activityId: string
prizeId: string
ename?: string
benefitType?: number
credits?: number
type: number
image: string
......
......@@ -25,6 +25,8 @@ interface ICommonActivityPrize {
useUrl?: string
stock?: number
useStock?: number
isBackUp?: boolean
benefitType?: number
openId?: string
deleteStatus?: number
createTime?: number
......
......@@ -14,10 +14,10 @@ import { CODE_TYPES } from '../../../errorCode'
* @return {*}
*/
export default async function checkExchangeCreditsTask(
context: IContext<{ activityId: string; taskType: ITaskType; credits?: number }>,
context: IContext<{ activityId: string; key: ITaskType; credits?: number }>,
{ session }: IControllerInfos
) {
const { taskType, credits } = context.data
const { key: taskType, credits } = context.data
// 不是兑换积分类型不校验
if (taskType !== 'exchangeCredits') return
......
......@@ -6,10 +6,10 @@ import { getTotalCompleteTask, getTodayCompleteGrowTask } from '../task'
import { TASK_RATE_TYPE } from '../../../constants'
export default async function checkTaskLimit(
context: IContext<{ activityId: string; taskType: ITaskType; itemId?: string }>,
context: IContext<{ activityId: string; key: ITaskType; itemId?: string }>,
{ userInfo, activityInfo, task }: IControllerInfos
) {
const { taskType, itemId } = context.data
const { key: taskType, itemId } = context.data
const { itemIds } = activityInfo?.tasks?.[taskType] || {}
if (!taskType) {
console.error('使用checkTaskLimit, 云函数必须传入taskType参数')
......
......@@ -4,12 +4,12 @@ import { resultsModel } from '../../../sdk'
import { CODE_TYPES } from '../../../errorCode'
export default async function checkRemainTimes(
context: IContext<{ taskType: ITaskType }>,
context: IContext<{ key: ITaskType }>,
{ userInfo }: IControllerInfos
) {
const { taskType } = context.data
const { key } = context.data
const { remainTimes } = userInfo
// 暂无领取次数
if (!remainTimes?.[taskType]) return resultsModel.error(CODE_TYPES.ERROR_TASK_NORECEIVE)
if (!remainTimes?.[key]) return resultsModel.error(CODE_TYPES.ERROR_TASK_NORECEIVE)
}
......@@ -6,10 +6,15 @@ import { getTodayCompleteTask, getTotalCompleteTask } from '../task'
import { TASK_RATE_TYPE } from '../../../constants'
export default async function checkTaskLimit(
context: IContext<{ activityId: string; taskType: ITaskType; itemId?: string }>,
context: IContext<{ activityId: string; key: ITaskType; itemId?: string }>,
{ userInfo, activityInfo }: IControllerInfos
) {
const { taskType, itemId } = context.data
const { key: taskType, itemId } = context.data
// 邀请任务单独处理
if(taskType === 'invites'){
return
}
const { itemIds } = activityInfo?.tasks?.[taskType] || {}
if (!taskType) {
console.error('使用checkTaskLimit, 云函数必须传入taskType参数')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment