Commit 7ae6dc4f authored by 王波's avatar 王波

优化修改

parent 6a697143
......@@ -2,7 +2,7 @@
import { services, preCheck, registeInfos, preUpdate, checkParams } from '../decorator/common'
import { resultsModel } from '../sdk'
import { CommonUserService, CommonStatService, CommonTaskService, CommonGrowTaskService } from '../service/common'
import { CommonStatService, CommonGrowTaskService } from '../service/common'
import { STAT_TYPE } from '../constants'
import { checkActivityTime, checkInviteId, checkHelpRecord, checkNewVip } from '../utils/common/check'
import { updateHelpRecord, updateVip } from '../utils/common/update'
......
......@@ -25,11 +25,11 @@ export default class Task {
@preUpdate([updateVip, updateSignGrowTask, updateGrowOrderGoods])
async getTaskList(
context: IContext<IParams>,
{ userInfo, activityInfo }: IControllerInfos,
{ userInfo, activityInfo, task }: IControllerInfos,
[growTaskService]: [CommonGrowTaskService]
): Promise<IResult<{ list: ITaskInfo[] }>> {
// 读取B端 tasks字段配置自动生成任务列表
const result = await growTaskService.initTaskList(userInfo, activityInfo)
const result = await growTaskService.initTaskList(userInfo, activityInfo, task)
return resultsModel.success({
...result
......
......@@ -22,3 +22,4 @@ export const PRIZE_CONFIG_DB_NAME = 'b_prize_config'
export const ACTIVITY_CONFIG_DB_NAME = 'b_activity_config'
export const OEDER_DB_NAME = 'c_user_order'
......@@ -7,7 +7,13 @@
import UserService from './user.service'
import { getToday, getUserOrderlist, generateVipUrl, formatVipCbUrl, setNewFollowUserData } from '../../utils'
import { TASK_RATE_TYPE, TASK_STATUS } from '../../constants'
import { getTodayCompleteTask, getTotalCompleteTask, setTaskStatus, updateTaskInfo } from '../../utils/common/task'
import {
getTotalCompleteTask,
setGrowTaskStatus,
updateTaskInfo,
getTodayCompleteGrowTask,
getOrderCount
} from '../../utils/common/task'
import { CODE_TYPES } from '../../errorCode'
export interface ITaskInfo {
......@@ -29,11 +35,16 @@ export default class TaskService extends UserService {
}
// 根据活动tasks字段渲染任务
async initTaskList(userInfo: IUserInfo, activityInfo: IActivityInfo) {
async initTaskList(userInfo: IUserInfo, activityInfo: IActivityInfo, task: ITask) {
let list = []
const keyList = Object.keys(activityInfo?.tasks || {})
for (let index = 0; index < keyList.length; index++) {
// @ts-ignore
const taskType: ITaskType = keyList[index]
list.push(await this.initTask(task, taskType, activityInfo?.tasks?.[taskType]?.title, userInfo, activityInfo))
}
return {
list: Object.keys(activityInfo?.tasks || {}).map((task: ITaskType) => {
return this.initTask(task, activityInfo?.tasks?.[task]?.title, userInfo, activityInfo)
})
list
}
}
/**
......@@ -46,14 +57,29 @@ export default class TaskService extends UserService {
* @return {ITaskInfo} {ITaskInfo} 任务信息
* @memberof TaskService
*/
initTask(taskType: ITaskType, title: string, userInfo: IUserInfo, activityInfo: IActivityInfo): ITaskInfo {
async initTask(
task: ITask,
taskType: ITaskType,
title: string,
userInfo: IUserInfo,
activityInfo: IActivityInfo
): Promise<ITaskInfo> {
if (!activityInfo?.tasks?.[taskType]) {
console.error(`活动缺少${taskType}任务配置项`)
}
const { value, itemIds = '', taskRateType, times = 1, link = '' } = activityInfo?.tasks?.[taskType] || {}
const { remainTimes } = userInfo
const { todayCompleteTimes } = getTodayCompleteTask(taskType, userInfo)
const { completeTimes } = getTotalCompleteTask(taskType, userInfo)
let { todayCompleteTimes } = getTodayCompleteGrowTask(taskType, task)
let { completeTimes } = getTotalCompleteTask(taskType, userInfo)
if (taskType === 'orderGoods') {
//如果是下单任务,需要单独去根据订单类型去订单表获取下单列表
todayCompleteTimes = completeTimes = await getOrderCount(
this.context,
userInfo.openId,
activityInfo._id,
taskRateType
)
}
return {
taskType,
......@@ -65,7 +91,7 @@ export default class TaskService extends UserService {
url: taskType === 'member' ? generateVipUrl(formatVipCbUrl(this.context)) : link,
todayCompleteTimes,
completeTimes,
status: setTaskStatus(userInfo, taskType, taskRateType, times),
status: setGrowTaskStatus(userInfo, taskType, taskRateType, times, todayCompleteTimes, completeTimes),
waitReceive: remainTimes?.[taskType]
}
}
......
......@@ -37,7 +37,7 @@ export default class TaskService extends UserService {
}
}
/**
* 根据任务类型初始化 b端 tasks字段必须有相应的配置
* 根据任务类型初始化 b端 tasks字段必须有相应的配置TODO
*
* @param {ITaskType} taskType 任务类型
* @param {string} title 任务标题
......
......@@ -2,8 +2,7 @@
type IAwards = ICommonAwards & ICustomAwards
interface ICustomAwards {
}
interface ICustomAwards {}
interface ICommonAwards {
_id?: string
id?: string
......
/** @format */
import * as dayjs from 'dayjs'
import { getEndTimestamp, getStartTimestamp, transformBeijingDate } from '../../sdk'
const EIGHT_HOURS = 8 * 60 * 60 * 1000
/**
* 格式化时间 统一处理8小时时差问题
* YYYY-MM-DDTHH:mm:ss
*
* formatDate().format('YYYY-MM-DD HH:mm:ss')
* formatDate('2021/01/21').getStartTimestamp()
* formatDate('2021/01/21').getEndTimestamp()
* formatDate('2021/01/21').getTimestamp()
* @export
* @param {(string | number)} date
* @return {
* format 格式化时间
* getTimestamp 时间戳
* getStartTimestamp 某天开始的时间戳
* getEndTimestamp 某天结束的时间戳
* getYear 获取年份
* getMonth 获取月份
* getDay 获取天
* getHour 获取小时
* getMinute 获取分钟
* geSecond 获取秒数
* getMillisecond 获取毫秒
* }
*/
export function formatDate(date: string | number = Date.now()) {
const beijingDate = typeof date === 'string' ? new Date(date) : transformBeijingDate(date)
return {
format: (template = 'YYYY-MM-DD') => dayjs(beijingDate).format(template),
getTimestamp: () => (typeof date === 'number' ? date : dayjs(date).valueOf() - EIGHT_HOURS),
getStartTimestamp: () => getStartTimestamp(dayjs(beijingDate).format('YYYY/MM/DD')),
getEndTimestamp: () => getEndTimestamp(dayjs(beijingDate).format('YYYY/MM/DD')),
getYear: () => dayjs(beijingDate).get('year'),
getMonth: () => dayjs(beijingDate).get('month'),
getDay: () => dayjs(beijingDate).get('day'),
getHour: () => dayjs(beijingDate).get('hour'),
getMinute: () => dayjs(beijingDate).get('minute'),
geSecond: () => dayjs(beijingDate).get('second'),
getMillisecond: () => dayjs(beijingDate).get('millisecond')
}
}
......@@ -2,7 +2,7 @@
import { getToday } from './getToday'
import { TASK_STATUS, TASK_RATE_TYPE } from '../../constants'
import { TASK_DB_NAME } from '../../db'
import { TASK_DB_NAME, OEDER_DB_NAME } from '../../db'
import { BaseDao } from '../../sdk'
import Task from '../../controller/task.controller'
......@@ -176,21 +176,63 @@ export async function updateTaskInfo(context: IContext<IParams>, _id: string, ta
}
/**
* 增加每日任务每日任务,适用于普通每日任务
* 更新每日任务,适用于购买商品每日任务
* @param context
* @param activityId
*/
export async function updateGoodsTaskInfo(context: IContext<IParams>, _id: string, taskType: string, value) {
let taskInfodao: IBaseDao = new BaseDao(context, TASK_DB_NAME)
const today = getToday()
return await taskInfodao.update(
{
_id
},
{
$set: {
[`taskInfo.${today}.${taskType}`]: value
}
}
)
export async function getOrderCount(
context: IContext<IParams>,
openId: string,
activityId: string,
taskRateType: number
) {
let orderdao: IBaseDao = new BaseDao(context, OEDER_DB_NAME)
const project =
taskRateType === TASK_RATE_TYPE.EVERYDAY
? {
openId,
activityId,
createDay: getToday()
}
: {
openId,
activityId
}
return await orderdao.count(project)
}
/**
*
* 根据用户和任务完成情况,设置任务状态
*
* @param {IUserInfo} useInfo
* @param {string} taskType
* @param {number} taskRateType
* @param {number} [limitTimesEverday] 每天限制次数 任务频率为每天的时候必填
* @return {taskTatus} 1未完成 2 待领取 3 已完成
* @memberof TaskService
*/
export function setGrowTaskStatus(
userInfo: IUserInfo,
taskType: string,
taskRateType: number,
limitTimesEveryday: number = 1,
todayCompleteTimes: number,
completeTimes: number
): number {
const waitReceive = userInfo?.remainTimes?.[taskType] || 0
if (waitReceive) return TASK_STATUS.WAIT_RECEIVE
switch (taskRateType) {
case TASK_RATE_TYPE.FOREVER:
return completeTimes >= limitTimesEveryday ? TASK_STATUS.DONE : TASK_STATUS.WAIT_DO
break
case TASK_RATE_TYPE.EVERYDAY:
return todayCompleteTimes >= limitTimesEveryday ? TASK_STATUS.DONE : TASK_STATUS.WAIT_DO
break
case TASK_RATE_TYPE.NOLIMIT:
return TASK_STATUS.WAIT_DO
break
}
}
......@@ -7,8 +7,6 @@ import updateUserInfo, { reduceGameTimes, updateHelpRecord } from './updateUserI
import updateSignGrowTask from './updateSignGrowTask'
import updateGrowOrderGoods from './updateGrowOrderGoods'
const update = {
updateVip,
updateSignTask,
......
/** @format */
import { getToday } from '../getToday'
import { getTotalCompleteTask, getTodayCompleteGrowTask, updateGoodsTaskInfo } from '../task'
import { TASK_RATE_TYPE } from '../../../constants'
import { getUserOrderlist } from '../getUserOrderlist'
import { OEDER_DB_NAME } from '../../../db'
import { resultsModel } from '../../../sdk'
import { BaseDao } from '../../../sdk'
import { CODE_TYPES } from '../../../errorCode'
import { formatDate } from '../date'
export default async function updateOrderGoods(
export default async function updateGrowOrderGoods(
context: IContext<IParams>,
{ userInfo, activityInfo, task }: IControllerInfos
{ userInfo, activityInfo }: IControllerInfos
): Promise<IPreUpdateQuery> {
const taskType = 'orderGoods'
const { value, itemIds, taskRateType, times } = activityInfo?.tasks?.[taskType] || {}
const { completeTimes, taskInfo } = getTotalCompleteTask(taskType, userInfo)
const { todayCompleteTimes } = getTodayCompleteGrowTask(taskType, task)
let orderdao: IBaseDao = new BaseDao(context, OEDER_DB_NAME)
const orderList =
taskRateType === TASK_RATE_TYPE.EVERYDAY
? await orderdao.find({
openId: userInfo.openId,
activityId: userInfo.activityId,
createDay: getToday
})
: await orderdao.find({
openId: userInfo.openId,
activityId: userInfo.activityId
})
const completeTimes = orderList?.length || 0
if (!activityInfo?.tasks?.[taskType]) return {}
// 永久任务且已完成
if (taskRateType === TASK_RATE_TYPE.FOREVER && completeTimes >= times) {
// 每日任务或者是永久任务的任务且已完成
if (taskRateType !== TASK_RATE_TYPE.NOLIMIT && completeTimes >= times) {
return {}
}
// 每日限制完成且完成次数达到限制
if (taskRateType === TASK_RATE_TYPE.EVERYDAY && todayCompleteTimes >= times) {
return {}
}
return taskRateType === TASK_RATE_TYPE.EVERYDAY ?
await getEverydayGoods(context, taskType, itemIds, task, times, value, userInfo)
: await getOrderGoods(taskType, itemIds, times, value, userInfo, taskInfo)
}
/**
* 更新永久订单信息
* @param taskType
* @param itemIds
* @param times
* @param value
* @param userInfo
*/
async function getOrderGoods(taskType: string, itemIds: string, times: number, value: number, userInfo: IUserInfo, taskInfo: ITaskDetail[]): Promise<IPreUpdateQuery> {
const today = getToday()
const orderResult = await getUserOrderlist(
this.context,
//@ts-ignore
userInfo.createTime || activityInfo?.startTime || Date.now(),
Date.now()
)
const itemIdsArr = itemIds.split(',').map(v => +v)
let projection = {
$inc: {
[`remainTimes.${taskType}`]: 0
},
$set: {}
//设置查询淘宝订单时间
let startTime = Date.now()
if (taskRateType === TASK_RATE_TYPE.EVERYDAY) {
let TodayTime = formatDate(today).getTimestamp()
startTime = TodayTime > userInfo.createTime ? TodayTime : userInfo.createTime
} else {
startTime = userInfo.createTime || activityInfo?.startTime || Date.now()
}
let targetOrders = userInfo?.taskInfo?.[today]?.[taskType] || []
orderResult.forEach(v => {
// @ts-ignore
// 商品订单包含目标商品 且orderId为新订单
if (itemIdsArr.includes(v.itemId) && !taskInfo.some(order => order.orderId === v.orderId)) {
if (targetOrders.length >= times) {
return
}
projection.$inc[`remainTimes.${taskType}`] += +value
targetOrders.push({
itemId: v.itemId,
orderId: v.orderId,
payTime: v.payTime,
tId: v.tId,
createTime: Date.now()
})
}
if (targetOrders?.length) {
projection.$set[`taskInfo.${today}.${taskType}`] = targetOrders
}
})
return projection
}
/**
* 更新每日订单信息,仅适用于下单,如果是每日确认收货,需要单独处理
* @param context
* @param taskType
* @param itemIds
* @param task
* @param times
* @param value
* @param userInfo
*/
async function getEverydayGoods(context: IContext<IParams>, taskType: string, itemIds: string, task: ITask, times: number, value: number, userInfo: IUserInfo): Promise<IPreUpdateQuery> {
const today = getToday()
const TodayTime = new Date(today).getTime()
let startTime = TodayTime > userInfo.createTime ? TodayTime : userInfo.createTime
const orderResult = await getUserOrderlist(
context,
//@ts-ignore
......@@ -113,33 +59,34 @@ async function getEverydayGoods(context: IContext<IParams>, taskType: string, it
},
$set: {}
}
let targetOrders = task?.taskInfo?.[today]?.[taskType] || []
let targetLength = targetOrders.length
//筛选符合任务的订单并添加到下单表
let targetOrders = []
orderResult.forEach(v => {
// @ts-ignore
// 商品订单包含目标商品 且orderId为新订单
if (itemIdsArr.includes(v.itemId) && !task?.taskInfo.some(order => order.orderId === v.orderId)) {
if (targetOrders.length >= times) {
if (itemIdsArr.includes(v.itemId) && !orderList.some(order => order.orderId === v.orderId)) {
if (targetOrders.length + completeTimes >= times) {
return
}
projection.$inc[`remainTimes.${taskType}`] += +value
targetOrders.push({
openId: userInfo.openId,
activityId: activityInfo._id,
itemId: v.itemId,
orderId: v.orderId,
payTime: v.payTime,
tId: v.tId,
createTime: Date.now()
createTime: Date.now(),
createDay: today
})
}
})
if (targetOrders?.length && targetLength !== targetOrders?.length) {
const result = await updateGoodsTaskInfo(context, today, taskType, targetOrders)
if (result !== 1) {
if (targetOrders?.length) {
const result = await orderdao.insertMany(targetOrders)
if (!result || result.length === 0) {
// @ts-ignore
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '订单任务更新失败')
}
projection.$inc[`remainTimes.${taskType}`] = result.length * value
}
return projection
......
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