任务:完成主要接口

This commit is contained in:
luying
2021-04-19 19:35:45 +08:00
parent b29b8634ad
commit ced80d9b94
16 changed files with 515 additions and 41 deletions

View File

@@ -125,6 +125,7 @@ const itid_array = [
{ id: 32, name: '典籍', table: 'equip', type: EQUIP_TYPE.BOOK },
{ id: 33, name: '神兵', table: 'equip', type: EQUIP_TYPE.WEAPON },
{ id: 34, name: '代币', table: 'item', type: CONSUME_TYPE.POINT },
{ id: 53, name: '武将招募券', table: 'item', type: CONSUME_TYPE.POINT },
{ id: 39, name: '时装', table: 'hero', type: CONSUME_TYPE.SKIN },
{ id: 40, name: '装备碎片', table: 'item', type: CONSUME_TYPE.PIECE },
{ id: 41, name: '图纸', table: 'item', type: CONSUME_TYPE.CONSUME },

View File

@@ -469,7 +469,10 @@ export const FILENAME = {
DIC_RANK_REWARD: 'dic_zyz_rankingReward',
DIC_MAIN_TASK: 'dic_zyz_mainTask',
DIC_DAILY_TASK: 'dic_zyz_dailyTask',
DIC_ACHIEVEMENT: 'dic_zyz_achievement'
DIC_ACHIEVEMENT: 'dic_zyz_achievement',
DIC_MAIN_TASK_STAGE: 'dic_zyz_mainTaskStage',
DIC_TASK_BOX: 'dic_zyz_taskBox',
DIC_ACHIEVEMENT_BOX: 'dic_zyz_dic_zyz_achievementBox',
}
export const WAR_RELATE_TABLES = [

View File

@@ -313,6 +313,14 @@ export const STATUS = {
SKIN_HAS_NOT_HERO: { code: 30903, simStr: '未拥有该武将不可获得皮肤' },
HERO_NOT_MAX: { code: 30904, simStr: '该武将未升满星' },
// 任务相关 31001-31100
TASK_NOT_REACH_CONDITION: { code: 30900, simStr: '任务不满足条件' },
TASK_HAS_RECEIVED: { code: 30901, simStr: '奖励已领取' },
TASK_NOT_ALL_RECEIVED: { code: 30902, simStr: '任务未领取完' },
TASK_ACTIVE_NOT_ENOUGH: { code: 30903, simStr: '活跃不足' },
TASK_POINT_NOT_ENOUGH: { code: 30904, simStr: '积分不足' },
TASK_BOX_HAS_RECEIVED: { code: 30905, simStr: '奖励已领取' },
// 社交相关状态 40000 - 49999
SYS_CHANNEL_AUTH_NOT_ENOUGH: {code: 40000, simStr: '无法在系统频道发送消息'},
UPDATE_PRIVATE_MSG_READ_TIME_ERR: {code: 40001, simStr: '更新私聊阅读时间失败'},

88
shared/db/UserTask.ts Normal file
View File

@@ -0,0 +1,88 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
import { getCurWeekDate } from '../pubUtils/timeUtil';
/**
* 玩家购买商店记录表,每个商品一条,每次刷新新建一条
**/
@modelOptions({ schemaOptions: { id: false } })
@index({ roleId: 1, itemId: 1 })
export default class UserTask extends BaseModel {
@prop({ required: true })
roleId: string; // 玩家id
@prop({ required: true, default: 1 })
mainTaskStage: number; // 主线所处在的阶段
@prop({ required: true, default: 0 })
dailyTaskPoint: number; // 每日任务的累计积分
@prop({ required: true })
dailyTaskRefWeekly: Date; // 每日任务的每周刷新时间
@prop({ required: true, default: 0 })
dailyTaskPointWeekly: number; // 每日任务的每周活跃积分
@prop({ required: true, type: Number, default: [] })
dailyTaskBox: number[]; // 每日任务每周已领取箱子
@prop({ required: true, default: 0 })
achievementPoint: number; // 成就积分
@prop({ required: true, type: Number, default: [] })
achievementBox: number[]; // 成就已领取了的箱子
public static async findByRole(roleId: string) {
let curWeek = getCurWeekDate(1, 5);
let rec: UserTaskType = await UserTaskModel.findOneAndUpdate({ roleId }, { $setOnInsert: {
mainTaskStage: 1, dailyTaskPoint: 0, dailyTaskRefWeekly: curWeek, dailyTaskPointWeekly: 0, dailyTaskBox: [], achievementPoint: 0, achievementBox: []
} }, { new: true, upsert: true }).lean();
return rec;
}
public static async resetDailyScore(roleId: string, point: number, curWeek: Date) {
let rec: UserTaskType = await UserTaskModel.findOneAndUpdate({ roleId }, {
$set: { dailyTaskRefWeekly: curWeek, dailyTaskPointWeekly: point, dailyTaskBox: [] },
$inc: { dailyTaskPoint: point }
}, { new: true }).lean();
return rec;
}
public static async incInfo(roleId: string, inc: UserTaskIncParam) {
let rec: UserTaskType = await UserTaskModel.findOneAndUpdate({ roleId }, {
$inc: inc
}, { new: true }).lean();
return rec;
}
public static async decreaseDailyPoint(roleId: string, point: number) {
let rec: UserTaskType = await UserTaskModel.findOneAndUpdate( { roleId, dailyTaskPoint: { $gte: point }}, { $inc: { dailyTaskPoint: -point } }, { new: true }).lean();
return rec;
}
public static async pushDailyBox(roleId: string, id: number, curWeek: Date, shouldRefresh: boolean) {
let rec: UserTaskType;
if(shouldRefresh) {
rec = await UserTaskModel.findOneAndUpdate({ roleId }, {
$set: { dailyTaskRefWeekly: curWeek, dailyTaskPointWeekly: 0, dailyTaskBox: [ id ] }
}, { new: true }).lean()
} else {
rec = await UserTaskModel.findOneAndUpdate({ roleId }, { $push: { dailyTaskBox: id } }, { new: true }).lean();
}
return rec;
}
public static async pushAchievementBox(roleId: string, id: number) {
let rec = await UserTaskModel.findOneAndUpdate({ roleId }, { $push: { achievementBox: id } }, { new: true }).lean();
return rec;
}
}
export const UserTaskModel = getModelForClass(UserTask);
export interface UserTaskType extends Pick<DocumentType<UserTask>, keyof UserTask> { }
export type UserTaskParam = Partial<UserTaskType>;
export type UserTaskIncParam = Pick<UserTaskParam, 'mainTaskStage'|'dailyTaskPoint'|'dailyTaskPointWeekly'|'achievementPoint'>;

View File

@@ -32,34 +32,33 @@ export default class UserTaskRec extends BaseModel {
@prop({ required: true })
count: number; // 达成次数
@prop({ required: true, default: false })
received: boolean; // 是否已领取
@prop({ required: true, type: Number, default: [] })
received: number[]; // 是否已领取
private static getRefreshCondition(type: number) {
let today = getTodayZeroDate(5);
if(type == TASK_FUN_TYPE.DAILY) {
return { createdAt: { $gte: today } };
return { type, createdAt: { $gte: today } };
} else {
return {};
return { type };
}
}
public static async setTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, type, group, ...condition }, { $setOnInsert: { code: genCode(8), taskType, received: false }, $set: { count } }, { new: true, upsert: true }).lean();
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $set: { count } }, { new: true, upsert: true }).lean();
return rec;
}
public static async incTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, type, group, ...condition }, { $setOnInsert: { code: genCode(8), taskType, received: false }, $inc: { count } }, { new: true, upsert: true }).lean();
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $inc: { count } }, { new: true, upsert: true }).lean();
return rec;
}
public static async checkHistoryAndSetTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOne({ roleId, type, group, ...condition }).lean();
let rec: UserTaskRecType = await UserTaskRecModel.findByRoleAndGroup(roleId, type, group, taskType);
if(rec) {
if(rec.count < count) {
rec = await UserTaskRecModel.setTaskRec(roleId, type, taskType, group, count);
@@ -70,7 +69,38 @@ export default class UserTaskRec extends BaseModel {
return rec;
}
public static async findByRoleAndType(roleId: string, type: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType[] = await UserTaskRecModel.find({ roleId, ...condition }).lean();
let map = new Map<number, Map<number, UserTaskRecType>>(); // taskType => group => userTask
for(let userTaskRec of rec) {
let { taskType, group } = userTaskRec;
if(!map.has(taskType)) {
map.set(taskType, new Map<number, UserTaskRecType>());
}
map.get(taskType).set(group, userTaskRec);
}
return map;
}
public static async findByRoleAndGroup(roleId: string, type: number, taskType: number, group: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOne({ roleId, taskType, group, ...condition }).lean();
return rec;
}
public static async receiveTask(roleId: string, type: number, taskType: number, group: number, id: number) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, taskType, group, ...condition }, { $push: { received: id } }, { new: true }).lean();
return rec;
}
public static async getReceiveRec(roleId: string, type: number) {
let condition = this.getRefreshCondition(type);
let rec = await UserTaskRecModel.find({ roleId, ...condition }).lean();
console.log(JSON.stringify(rec))
return rec
}
}
export const UserTaskRecModel = getModelForClass(UserTaskRec);

View File

@@ -22,4 +22,11 @@ export class TaskParam {
title?: number;
job?: number;
aid?: number;
}
export class TaskListReturn {
type: number; // 类型
id: number; // 任务id
count: number; // 达成次数
received: boolean; // 是否领取
}

View File

@@ -73,7 +73,9 @@ import { dicShop, dicShopItem } from "./dictionary/DicShop";
import { dicShopList } from "./dictionary/DicShopList";
import { dicRank } from "./dictionary/DicRank";
import { dicRankReward } from "./dictionary/DicRankReward";
import { dicTaskType, dicMainTask, dicDailyTask, dicAchievement } from "./dictionary/DicTask";
import { dicTaskType, taskMap, dicMainTask, dicDailyTask, dicAchievement } from "./dictionary/DicTask";
import { dicMainTaskStage } from "./dictionary/DicMainTaskStage";
import { dicTaskBox } from './dictionary/DicTaskBox';
export const gameData = {
blurprtCompose: dicBlueprtCompose,
@@ -174,9 +176,12 @@ export const gameData = {
rank: dicRank,
generalRankReward: dicRankReward,
taskType: dicTaskType,
tasks: taskMap,
mainTask: dicMainTask,
dailyTask: dicDailyTask,
achievement: dicAchievement
achievement: dicAchievement,
mainTaskStage: dicMainTaskStage,
taskBox: dicTaskBox
};
// 在此提供一些原先在gamedata中提供的方法以便更方便获取gameData数据

View File

@@ -0,0 +1,27 @@
// 主线任务阶段内容
import {readJsonFile, parseNumberList, parseGoodStr} from '../util'
import { FILENAME } from '../../consts'
import { RewardInter } from '../interface';
export interface DicMainTaskStage {
// id
readonly id: number;
// 阶段
readonly stageId: number;
// 包括哪些id
readonly mainTaskId: number[];
// 奖励
readonly reward: RewardInter[];
}
const str = readJsonFile(FILENAME.DIC_MAIN_TASK_STAGE);
let arr = JSON.parse(str);
export const dicMainTaskStage = new Map<number, DicMainTaskStage>();
arr.forEach(o => {
o.mainTaskId = parseNumberList(o.mainTaskId);
o.reward = parseGoodStr(o.reward);
dicMainTaskStage.set(o.id, o);
});
arr = undefined;

View File

@@ -89,6 +89,10 @@ export type DicTask = DicTaskBase & { type: number };
export const dicMainTask = new Map<number, DicMainTask>(); // 主线任务
export const dicDailyTask = new Map<number, DicDailyTask>(); // 每日任务
export const dicAchievement = new Map<number, DicAchievement>(); // 成就
export const taskMap = new Map<number, Map<number, DicMainTask|DicDailyTask|DicAchievement>>();
taskMap.set(TASK_FUN_TYPE.MAIN, dicMainTask);
taskMap.set(TASK_FUN_TYPE.DAILY, dicDailyTask);
taskMap.set(TASK_FUN_TYPE.ACHIEVEMENT, dicAchievement);
export const dicTaskType = new Map<number, DicTask[]>();

View File

@@ -0,0 +1,37 @@
// 主线任务阶段内容
import {readJsonFile, parseGoodStr} from '../util'
import { FILENAME, TASK_FUN_TYPE } from '../../consts'
import { RewardInter } from '../interface';
export interface DicTaskBox {
// id
readonly id: number;
// 积分
readonly point: number;
// 奖励
readonly reward: RewardInter[];
}
export const dicTaskBox = new Map<number, Map<number, DicTaskBox>>();
const str1 = readJsonFile(FILENAME.DIC_TASK_BOX);
let arr1 = JSON.parse(str1);
arr1.forEach(o => {
if(!dicTaskBox.has(TASK_FUN_TYPE.DAILY)) {
dicTaskBox.set(TASK_FUN_TYPE.DAILY, new Map<number, DicTaskBox>());
}
o.reward = parseGoodStr(o.reward);
dicTaskBox.get(TASK_FUN_TYPE.DAILY).set(o.id, o);
});
arr1 = undefined;
const str2 = readJsonFile(FILENAME.DIC_ACHIEVEMENT_BOX);
let arr2 = JSON.parse(str2);
arr2.forEach(o => {
if(!dicTaskBox.has(TASK_FUN_TYPE.ACHIEVEMENT)) {
dicTaskBox.set(TASK_FUN_TYPE.ACHIEVEMENT, new Map<number, DicTaskBox>());
}
o.reward = parseGoodStr(o.reward);
dicTaskBox.get(TASK_FUN_TYPE.ACHIEVEMENT).set(o.id, o);
});
arr2 = undefined;

View File

@@ -3,14 +3,14 @@ import { DicTask } from './dictionary/DicTask';
import { TASK_TYPE, ABI_STAGE, WAR_TYPE, GUILD_JOB, TASK_FUN_TYPE, FUNCS_ID } from '../consts';
import { UserTaskRecModel, UserTaskRecType } from '../db/UserTaskRec'
import { RoleType, RoleModel } from '../db/Role';
import { TaskParam } from '../domain/roleField/task';
import { TaskParam, TaskListReturn } from '../domain/roleField/task';
import { getTodayZeroPoint } from './timeUtil';
import { HeroType } from '../db/Hero';
import { EquipType, EquipModel } from '../db/Equip';
import { ItemInter } from './interface';
export async function checkTaskWithRoles(taskType: number, roles: RoleType[], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
for(let role of roles) {
if(role) {
let singlePush = await checkTaskWithRole(role.roleId, taskType, role, funcs);
@@ -21,7 +21,7 @@ export async function checkTaskWithRoles(taskType: number, roles: RoleType[], fu
}
export async function checkTaskWithRole(roleId: string, taskType: number, role: RoleType, funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.LOGIN_SUM)
{
@@ -52,7 +52,7 @@ export async function checkTaskWithRole(roleId: string, taskType: number, role:
export async function checkTaskWithHeroes(roleId: string, taskType: number, heroes: HeroType[], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
for(let hero of heroes) {
let singlePush = await checkTaskWithHero(roleId, taskType, hero, [], funcs);
pushMessage.concat(singlePush);
@@ -61,7 +61,7 @@ export async function checkTaskWithHeroes(roleId: string, taskType: number, hero
}
export async function checkTaskWithHero(roleId: string, taskType: number, hero: HeroType, args: number[] = [], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.HERO_STAR_UP)
{
let dicHero = gameData.hero.get(hero.hid);
@@ -133,7 +133,7 @@ export async function checkTaskWithHero(roleId: string, taskType: number, hero:
export async function checkTaskWithEquip(roleId: string, taskType: number, equip: EquipType, args: number[] = [], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.EQUIP_QUALITY)
{
// args[0] 1装上 -1脱下
@@ -194,7 +194,7 @@ export async function checkTaskWithEquip(roleId: string, taskType: number, equip
}
export async function checkTaskWithArgs(roleId: string, taskType: number, args: number[], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.ROLE_SCHOOL_PUT_HERO)
{
@@ -231,7 +231,7 @@ export async function checkTaskWithArgs(roleId: string, taskType: number, args:
export async function checkTaskWithWar(roleId: string, taskType: number, warId: number, heroes: number[], count: number, star: number, funcs?: number[]) {
let dicWar = gameData.war.get(warId);
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.BATTLE_WITH_HERO)
{
pushMessage = await checkTask(roleId, taskType, count, true, { warId, heroes }, funcs);
@@ -295,7 +295,7 @@ export async function checkTaskWithWar(roleId: string, taskType: number, warId:
export async function checkTaskWithGoods(roleId: string, taskType: number, goods: ItemInter[], funcs?: number[]) {
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
if(taskType == TASK_TYPE.COM_BATTLE_DROP)
{
for(let { id, count } of goods) {
@@ -309,7 +309,7 @@ export async function checkTaskWithGoods(roleId: string, taskType: number, goods
// 根据taskType判断有哪些任务需要check的
export async function checkTask(roleId: string, taskType: number, count: number, isInc: boolean, param: TaskParam, funcs?: number[]) {
let tasks = gameData.taskType.get(taskType)||[];
let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>();
let pushMessage = new Array<TaskListReturn>();
let groups = new Map<number, { task0: DicTask, tasks: DicTask[] }>();
for(let dicTask of tasks) {
if(!groups.has(dicTask.group)) {
@@ -326,8 +326,9 @@ export async function checkTask(roleId: string, taskType: number, count: number,
let rec = await checkTaskRec(roleId, group, task0, count, isInc, param, funcs);
if(rec) {
for(let dicTask of tasks) {
if(checkRecResult(rec, dicTask.condition)) {
pushMessage.push({ type: dicTask.type, id: dicTask.id, count: rec.count, received: rec.received });
if(checkRecResult(rec, dicTask.id, dicTask.condition)) {
let received = rec.received||[];
pushMessage.push({ type: dicTask.type, id: dicTask.id, count: rec.count, received: received.includes(dicTask.id) });
}
}
}
@@ -473,9 +474,9 @@ function checkHero(taskParam: number[], index: number, heroes: number[]) {
return heroes.indexOf(hid) != -1;
}
function checkRecResult(rec: UserTaskRecType, condition: number) {
function checkRecResult(rec: UserTaskRecType, id: number, condition: number) {
if(!rec) return false;
if(rec.received) return false;
if(rec.received && rec.received.includes(id)) return false; // 已领取,不再推送
if(rec.count >= condition) {
return rec