From 9e4719eadb63748a86224ed182285ce37df4c82f Mon Sep 17 00:00:00 2001 From: zhl Date: Thu, 7 Jan 2021 17:51:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8E=B7=E5=8F=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 36 +++++++++++++--- src/api.server.ts | 7 +-- src/controllers/AccountController.ts | 39 ++++++++++++++--- src/models/Account.ts | 62 +++++++++++++++++++++++---- src/models/CardGroup.ts | 64 ++++++++++++++++++++++++++++ src/models/GameRecord.ts | 36 ++++++++++++++++ src/models/subdoc/Card.ts | 46 ++++++++++++++++++++ src/models/subdoc/Hero.ts | 15 +++++++ 8 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 src/models/CardGroup.ts create mode 100644 src/models/GameRecord.ts create mode 100644 src/models/subdoc/Card.ts create mode 100644 src/models/subdoc/Hero.ts diff --git a/docs/api.md b/docs/api.md index 976fb3f..f634066 100644 --- a/docs/api.md +++ b/docs/api.md @@ -6,7 +6,7 @@ 通用返回JSON结构, 接口Response的数据结构说明只包含data部分 ``` JSON { - "errcode": 0, //0:成功 + "errcode": 0, //0:成功 4: 帐号被封, 100: 所有未定义的错误 "errmsg": "", //错误描述 "data": {}, // 数据 } @@ -26,7 +26,31 @@ 3. Response: JSON ```js - +{ + accountid: '', + cards: [number], + heros: [{ + heroid: number, + owned: true, // 是否已拥有 + usetype: 1, // 赛季专属, 0: 通用, 1: 赛季排位专用, 2: 匹配专用 + level: number, // 等级 + exp: number, // 当前的经验值 + free: false, // 是否免费 + free_expire: 1609919293, // 免费到期时间, 0: 说明是永久免费 + }], + moneys: { + 'coin': 0, // 金币 + 'diamond': 0, // 钻石 + 'hero_shard': 0, // 通用英雄碎片 + 'hero_exp': 0, // 通用英雄经验 + 'hero_shard_heroid': 0, // 英雄专用碎片 + 'hero_exp_heroid': 0, // 英雄专用经验 + 'card_scroll': 0, //抽卡卷轴 + }, + normal_stat: [0, 0, 0, 0] //匹配: 胜利场数, 失败场数, 平局场数, 掉线场数 + season_stat: [0, 0, 0, 0] // 当前赛季状态 + season_rank: 1 // 当前赛季排名 +} ``` ### 2. 可用卡牌信息 @@ -55,7 +79,7 @@ ### 3. 可用英雄列表 1. Method: POST -2. URI: /api/:accountid +2. URI: /api/:accountid/heros | 字段 | 说明 | | -------- | -------------------------------------- | @@ -70,12 +94,12 @@ ```js [{ - heroid: '', // 英雄id + heroid: 1022, // 英雄id owned: true, // 是否已拥有 ban: false, // 是否被禁用 usetype: 1, // 赛季专属, 0: 通用, 1: 赛季排位专用, 2: 匹配专用 free: false, // 是否免费 - free_expire: 1609919293 // 免费到期时间 + free_expire: 1609919293 // 免费到期时间, 0: 说明是永久免费 level: 1, // 等级 exp: 0, // 当前的经验值 }] @@ -94,7 +118,7 @@ ```js [{ - id: '', // 卡组id + gid: '', // 卡组id heroid: '', // 英雄id selected: true, // 当前选择的卡组 isdefault: false, // 是否是默认卡组, 默认卡组不能编辑 diff --git a/src/api.server.ts b/src/api.server.ts index 94d715f..0e830ff 100644 --- a/src/api.server.ts +++ b/src/api.server.ts @@ -42,9 +42,11 @@ export class ApiServer { logger.log('register api routers'); let self = this; for (let [controller, config] of RouterMap.decoratedRouters) { - let controllers = Array.isArray(controller) ? controller : [controller] + let controllers = + Array.isArray(controller) ? controller : [controller] controllers.forEach((controller) => { - logger.info('find api router', config.method || 'all', config.path, controller.name); + logger.info('find api router', config.method || 'all', + config.path, controller.name); // @ts-ignore self.server[config.method || 'all'](config.path, { preValidation: async function (request: FastifyRequest, reply: FastifyReply) { @@ -54,7 +56,6 @@ export class ApiServer { }, controller); }) } - // this.server.register(new AccountRouter().applyAll, {prefix: 'user', logLevel: 'debug'}); } /** * 加载所有的controller diff --git a/src/controllers/AccountController.ts b/src/controllers/AccountController.ts index da776b6..2d8d75c 100644 --- a/src/controllers/AccountController.ts +++ b/src/controllers/AccountController.ts @@ -2,17 +2,46 @@ import BaseController from "../common/base.controller"; import {role, router} from "../decorators/router"; import {Account} from "../models/Account"; import {ZError} from "../common/ZError"; +import {Hero} from "../models/subdoc/Hero"; export default class AccountController extends BaseController { @role('anon') @router('post /api/:accountid/uinfo') - async info(req: any, res: any) { + async info(req: any) { let {accountid} = req.params; - // if (true) { - // throw new ZError(101, 'no acc'); - // } let account = (await Account.findOrCreate({_id: accountid})).doc; - return account.toJson(); + let result: any = {accountid: account.id}; + if (account.locked) { + throw new ZError(4, 'account locked'); + } + result.cards = account.cards; + let heros: any[] = []; + for(let [key, hero] of account.heros) { + heros.push({ + heroid: hero.heroid, + owned: true, + usetype: 0, + level: hero.level, + exp: hero.exp, + free: hero.free, + free_expire: 0 + }); + } + //TODO:: 添加限免英雄和免费英雄 + result.heros = heros; + // let hero = new Hero(); + // hero.free = true; + // hero.level = 1; + // hero.exp = 0; + // hero.heroid = 30012; + // account.heros.set(30012+'', hero) + await account.save(); + result.moneys = account.moneys; + result.normal_stat= account.normal_stat; + result.season_stat = account.season_stat; + result.extinfo = account.extinfo; + result.rank = 0; + return result; } } diff --git a/src/models/Account.ts b/src/models/Account.ts index 005ada0..35e2a46 100644 --- a/src/models/Account.ts +++ b/src/models/Account.ts @@ -9,30 +9,74 @@ import { import {dbconn} from '../decorators/dbconn'; // @ts-ignore import findOrCreate from 'mongoose-findorcreate'; -import {Base, FindOrCreate, TimeStamps} from "@typegoose/typegoose/lib/defaultClasses"; +import { + Base, + FindOrCreate, + TimeStamps +} from "@typegoose/typegoose/lib/defaultClasses"; +import {Card} from "./subdoc/Card"; +import {Hero} from "./subdoc/Hero"; interface AccountClass extends Base, TimeStamps {} @dbconn() // @index({ _id: 1}, { unique: true }) @plugin(findOrCreate) -@modelOptions({schemaOptions: {collection: "account", timestamps: true}}) - +@modelOptions({schemaOptions: + {collection: "account", timestamps: true} +}) class AccountClass extends FindOrCreate{ @prop() public _id: string; - @prop() - public city?: string; + @prop({default: false}) public locked: boolean; @prop() - public lockedTime?: Date; + public lockedtime?: number; + @prop() public comment?: string; @prop() public lastLogin?: Date; + /** + * 已获得卡牌信息 + */ + @prop({ type: () => [Number] }) + public cards: number[]; + /** + * 已解锁英雄信息 + */ + @prop({ type: Hero, default: new Map() }) + public heros: Map; + /** + * 货币信息 + * coin: 金币 + * diamond: 钻石 + * hero_shard: 通用英雄碎片 + * hero_exp: 通用英雄经验 + * hero_shard_heroid: 英雄专用碎片 + * hero_exp_heroid: 英雄专用经验 + * card_scroll: 抽卡卷轴 + */ + @prop({ type: Number, default: new Map() }) + public moneys: Map; + + /** + * 匹配: 胜利场数, 失败场数, 平局场数, 掉线场数 + */ + @prop({type: Number, default: [0,0,0,0]}) + public normal_stat: number[]; + /** + * 当前赛季: 胜利场数, 失败场数, 平局场数, 掉线场数 + */ + @prop({type: Number, default: [0,0,0,0]}) + public season_stat: number[]; + + /** + * 所有未定义的信息, 供扩展 + */ @prop({type: mongoose.Schema.Types.Mixed}) - public moreinfo: any; + public extinfo: any; public toJson() { return { @@ -41,5 +85,7 @@ class AccountClass extends FindOrCreate{ } } + +export const Account = getModelForClass(AccountClass, // @ts-ignore -export const Account = getModelForClass(AccountClass, {existingConnection: AccountClass['db']}); + {existingConnection: AccountClass['db']}); diff --git a/src/models/CardGroup.ts b/src/models/CardGroup.ts new file mode 100644 index 0000000..42ad65e --- /dev/null +++ b/src/models/CardGroup.ts @@ -0,0 +1,64 @@ +import { + getModelForClass, + index, + modelOptions, + prop +} from "@typegoose/typegoose"; +import {Base, TimeStamps} from "@typegoose/typegoose/lib/defaultClasses"; +import {dbconn} from "../decorators/dbconn"; +import {Card} from "./subdoc/Card"; + +interface CardGroupClass extends Base, TimeStamps { +} + +/** + * 卡组信息 + */ + +@dbconn() +@index({accountid: 1, heroid: 1, deleted: 1}, {unique: false}) +@modelOptions({ + schemaOptions: + {collection: "card_group", timestamps: true} +}) +class CardGroupClass { + @prop({required: true}) + public accountid!: string; + @prop({required: true}) + public heroid!: number; + /** + * 是否是默认选中的卡组 + */ + @prop({default: false}) + public selected: boolean; + /** + * 是否是默认卡组 + */ + @prop({default: false}) + public isdefault: boolean; + @prop({_id: false, type: () => [Card]}) + public cards: Card[]; + /** + * 删除标记 + */ + @prop({default: false}) + public deleted: boolean; + /** + * 删除时间 + */ + @prop() + public deletetime: Date; + + public toJson() { + return { + heroid: this.heroid, + selected: this.selected, + isdefault: this.isdefault, + cards: this.cards.map(o => o.toJson()) + } + } +} + +export const CardGroup = getModelForClass(CardGroupClass, +// @ts-ignore + {existingConnection: CardGroupClass['db']}) diff --git a/src/models/GameRecord.ts b/src/models/GameRecord.ts new file mode 100644 index 0000000..5172ef0 --- /dev/null +++ b/src/models/GameRecord.ts @@ -0,0 +1,36 @@ +import {dbconn} from "../decorators/dbconn"; +import { + getModelForClass, + index, + modelOptions, + prop +} from "@typegoose/typegoose"; +import {Base, TimeStamps} from "@typegoose/typegoose/lib/defaultClasses"; + +interface GameRecordClass extends Base, TimeStamps { +} + +/** + * 对战记录 + */ +@dbconn() +@index({accountid: 1}, {unique: false}) +@modelOptions({ + schemaOptions: + {collection: "game_record", timestamps: true} +}) +class GameRecordClass { + @prop() + public accountid: string; + + toJson() { + return { + accountid: this.accountid, + } + } +} + + +export const GameRecord = getModelForClass(GameRecordClass, + // @ts-ignore + {existingConnection: GameRecordClass['db']}) diff --git a/src/models/subdoc/Card.ts b/src/models/subdoc/Card.ts new file mode 100644 index 0000000..402b2c7 --- /dev/null +++ b/src/models/subdoc/Card.ts @@ -0,0 +1,46 @@ +import {prop} from "@typegoose/typegoose"; + +/** + * 卡牌信息 + */ +export class Card { + @prop() + public cardid: number; + /** + * 是否已拥有 + */ + @prop() + public owned: boolean; + /** + * 是否被禁 + */ + @prop({default: false}) + public ban: boolean; + /** + * 赛季类型 + * 0: 通用, 1: 赛季排位专用, 2: 匹配专用 + */ + @prop({default: 0}) + public usetype: number; + /** + * 是否是限免卡牌 + */ + @prop({default: false}) + public free: boolean; + /** + * 限免过期时间 + */ + @prop() + public free_expire: number; + + public toJson() { + return { + cardid: this.cardid, + owned: this.owned, + ban: this.ban, + usetype: this.usetype, + free: this.free, + free_expire: this.free_expire + } + } +} diff --git a/src/models/subdoc/Hero.ts b/src/models/subdoc/Hero.ts new file mode 100644 index 0000000..61615db --- /dev/null +++ b/src/models/subdoc/Hero.ts @@ -0,0 +1,15 @@ +import {prop} from "@typegoose/typegoose"; + +export class Hero { + @prop() + public heroid: number; + /** + * 是否是免费英雄 + */ + @prop({default: false}) + public free: boolean; + @prop({default: 1}) + public level: number; + @prop({default: 0}) + public exp: number; +}