diff --git a/game-server/app/db/BaseModel.ts b/game-server/app/db/BaseModel.ts index 1e3db4a46..c269587b6 100644 --- a/game-server/app/db/BaseModel.ts +++ b/game-server/app/db/BaseModel.ts @@ -3,13 +3,13 @@ import { prop, pre } from '@typegoose/typegoose'; /** * BaseModel */ -@pre('save', function (next) { +@pre('save', function(next) { if (!this.createdAt || this.isNew) { - this.createdAt = this.updatedAt = new Date() + this.createdAt = this.updatedAt = new Date(); } else { - this.updatedAt = new Date() + this.updatedAt = new Date(); } - next() + next(); }) export default class BaseModel { @@ -21,4 +21,4 @@ export default class BaseModel { @prop() updatedAt: Date -} \ No newline at end of file +} diff --git a/game-server/app/db/Counter.ts b/game-server/app/db/Counter.ts index 798475c80..1f755fe61 100644 --- a/game-server/app/db/Counter.ts +++ b/game-server/app/db/Counter.ts @@ -2,21 +2,21 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; /** - * 短信字段接口 + * 自增 ID */ @index({ name: 1 }) export default class Counter extends BaseModel { - @prop({ required: true }) - name: string; + @prop({ required: true }) + name: string; - @prop({ required: true, default: 1 }) - seq: number; + @prop({ required: true, default: 1 }) + seq: number; - public static async getNewCounter(name: string) { - const counter = await CounterModel.findOneAndUpdate({name}, {$inc: {seq: 1}}, {new: true, upsert: true}).lean(); - return counter?.seq; - } + public static async getNewCounter(name: string, lean = true) { + const counter = await CounterModel.findOneAndUpdate({ name }, { $inc: { seq: 1 } }, { new: true, upsert: true }).lean(lean); + return counter?.seq; + } } diff --git a/game-server/app/db/Equip.ts b/game-server/app/db/Equip.ts new file mode 100644 index 000000000..3634a8cfe --- /dev/null +++ b/game-server/app/db/Equip.ts @@ -0,0 +1,49 @@ +import { COUNTER } from './../consts/consts'; +import { CounterModel } from './Counter'; +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop } from '@typegoose/typegoose'; + + +@index({ roleId: 1, hid: 1, eid: 1 }) +@index({ seqId: 1 }) +export default class Equip extends BaseModel { + @prop({ required: true }) + roleId: string; // 角色 id + @prop({ required: true }) + roleName: string; // 角色名称 + + @prop({ required: true }) + eid: number; // 装备 id + @prop({ required: true }) + type: number; // 装备类型 + @prop({ required: true }) + eName: string; // 装备名称 + @prop({ required: true }) + seqId: number; // 装备表自增 id + @prop({ required: true }) + hid: number; // 装备此装备的武将 id + + @prop({ required: true }) + lv: number; // 强化等级 + randSe: [{ // 强化随机属性 + seType: number; // 属性类型 + value: number; // 属性数值 + }]; + + @prop({ required: true }) + randRange: number; // 物攻策攻数值浮动上下限变化率,浮点数 + @prop({ required: true }) + initHoleCnt: number; // 初始珠宝孔位个数 + @prop({ required: true }) + holes: [{ + id: number; // 宝石 id,待定,也可能是 type + lv + lv: number; // 宝石等级 + }]; + + public static async findbyRole(roleId: string, lean = true) { + const equips = await EquipModel.find({ roleId }).lean(lean); + return equips; + } +} + +export const EquipModel = getModelForClass(Equip); diff --git a/game-server/app/db/Game.ts b/game-server/app/db/Game.ts index 500e531ce..af40b3749 100644 --- a/game-server/app/db/Game.ts +++ b/game-server/app/db/Game.ts @@ -3,68 +3,72 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; class ServerInfo { - @prop({ required: true}) - name: string; + @prop({ required: true }) + name: string; - @prop({ required: true}) - host: string; + @prop({ required: true }) + host: string; - @prop({ required: false}) - port: number; + @prop({ required: false }) + port: number; - @prop({ required: true}) - status: number; + @prop({ required: true }) + status: number; - @prop({ required: true}) - createTime: Date; + @prop({ required: true }) + createTime: Date; - @prop({ required: true}) - serverType: string; + @prop({ required: true }) + serverType: string; } /** - * 用户字段接口 + * 游戏字段接口 */ @index({ id: 1 }) export default class Game extends BaseModel { - @prop({ required: true}) + @prop({ required: true }) id: number; - @prop({ required: true}) + @prop({ required: true }) name: string; - @prop({ required: true}) + @prop({ required: true }) nameEn: string; - @prop({ required: true}) + @prop({ required: true }) des: string; - @prop({ required: true}) + @prop({ required: true }) serverList: Array; - @prop({ required: true}) + @prop({ required: true }) iconUrl: string; - @prop({ required: true}) + @prop({ required: true }) version: string; - @prop({ required: true}) + @prop({ required: true }) versionCode: number; public static async getServerListByType(serverType: string) { - let game = await GameModel.findOne().lean(); - if (!game) { - const serverInfo: ServerInfo = {name: '常山少年', host: 'pinus_test.trgame.cn', port: 3014, status: 1, createTime: new Date(), serverType: 'official'}; - const iconUrl = `https://download.tgamebox.cn/avatar/${APP_ID}/1.png`; - game = await GameModel.findOneAndUpdate({}, {id: 1, name: '赵云传', nameEn: 'zyz', des: '牛逼的战棋', iconUrl, version: '0.0.1', versionCode: 1, $push: {serverList: serverInfo}}, {upsert: true, new: true}).lean(); - } - let serverList: Array = game ? game.serverList : []; - serverList = serverList.filter(item => { return item.serverType === serverType; }) - return serverList; + let game = await GameModel.findOne().lean(); + if (!game) { + const serverInfo: ServerInfo = { name: '常山少年', host: 'pinus_test.trgame.cn', port: 3014, status: 1, createTime: new Date(), serverType: 'official' }; + const iconUrl = `https://download.tgamebox.cn/avatar/${APP_ID}/1.png`; + game = await GameModel.findOneAndUpdate( + {}, + { id: 1, name: '赵云传', nameEn: 'zyz', des: '牛逼的战棋', iconUrl, version: '0.0.1', versionCode: 1, $push: { serverList: serverInfo } }, + { upsert: true, new: true }, + ).lean(); + } + console.log(serverType, game); + let serverList: Array = game ? game.serverList : []; + serverList = serverList.filter(item => { return item.serverType === serverType; }); + console.log(serverType, serverList); + return serverList; } - - //#endregion } -export const GameModel = getModelForClass(Game); \ No newline at end of file +export const GameModel = getModelForClass(Game); diff --git a/game-server/app/db/Hero.ts b/game-server/app/db/Hero.ts new file mode 100644 index 000000000..a8ad03850 --- /dev/null +++ b/game-server/app/db/Hero.ts @@ -0,0 +1,62 @@ +import { COUNTER } from './../consts/consts'; +import { CounterModel } from './Counter'; +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop } from '@typegoose/typegoose'; + +/** + * 英雄表 +*/ +@index({ roleId: 1, hid: 1 }) +export default class Hero extends BaseModel { + + @prop({ required: true }) + roleId: string; // 角色 id + @prop({ required: true }) + roleName: string; // 角色名称 + + @prop({ required: true }) + hid: number; // 武将 id + @prop({ required: true }) + hName: string; // 武将名 + @prop({ required: true }) + seqId: number; // 武将表自增 id + + @prop({ required: true }) + exp: number; // 经验值 + @prop({ required: true }) + lv: number; // 武将等级 + @prop({ required: true }) + ce: number; // 武将战力 + + @prop({ required: true }) + star: number; // 星级 + @prop({ required: true }) + rank: number; // 阶数 + @prop({ required: true }) + favour: number; // 好感度 + @prop({ required: true }) + favourLv: number; // 好感等级 + @prop({ required: true }) + conections: [{ // 羁绊 + id: number; // 羁绊编号 + name: string; // 羁绊名称 + valid: boolean; // 是否开启 + }]; + @prop({ required: true }) + skins: [{ // 皮肤 + id: number; // id + enable: boolean; // 是否装备 + }] + + equips: [ // 武将装备 + // ref: ObjectID; // 装备引用 + ]; + + public static async findByRole(roleId: string, lean = true) { + const heros = await HeroModel.find({ roleId }).lean(lean); + return heros || []; + } + +} + +export const HeroModel = getModelForClass(Hero); diff --git a/game-server/app/db/Role.ts b/game-server/app/db/Role.ts new file mode 100644 index 000000000..c8e635654 --- /dev/null +++ b/game-server/app/db/Role.ts @@ -0,0 +1,106 @@ +import { COUNTER } from './../consts/consts'; +import { CounterModel } from './Counter'; +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop } from '@typegoose/typegoose'; +import User from './User'; + +/** + * 角色字段接口 +*/ +@index({ roleId: 1 }) +// @index({ userInfo.uid: 1, serverId: 1 }) +export default class Role extends BaseModel { + + @prop({ required: true }) + userInfo: User; + + @prop({ required: true }) + seqId: number; + + @prop({ required: true }) + roleId: string; // 角色 id,生成编码 + @prop({ required: true }) + roleName: string; // 角色名 + @prop({ required: true }) + serverType: string; // 服务器类型 + @prop({ required: true }) + serverId: number; // 区服 id + @prop({ required: true, default: false }) + blocked: boolean; // 是否屏蔽 + @prop({ required: true }) + code: string; // 邀请码 + + @prop({ required: true, default: 0 }) + exp: number; // 经验值 + @prop({ required: true, default: 1 }) + lv: number; // 主公等级 + @prop({ required: true, default: 0 }) + ce: number; // 总战力 + @prop({ required: true, default: 100 }) + tili: number; // 体力值 + + @prop({ required: true, default: 0 }) + vLv: number; // VIP 等级 + @prop({ required: true, default: 100 }) + gold: number; // 总金币 + @prop({ required: true, default: 0 }) + paidGold: number; // 支付所得金币 + @prop({ required: true, default: 100 }) + giftGold: number; // 赠送所得金币 + @prop({ required: true, default: 0 }) + totalPay: number; // 总支付金额 + @prop({ required: true, default: 0 }) + totalBuy: number; // 总金币购买 + @prop({ required: true, default: 0 }) + totalCost: number; // 金币总花费 + @prop({ required: true, default: [] }) + payRecord: [{ // 支付记录 + id: string; // 购买项 product id + cnt: number; // 购买次数 + }]; + + @prop({ required: true, default: [] }) + consumeGoods: [{ // 消耗品 + id: number; // id + cnt: number; // 数量 + }]; + @prop({ required: true, default: [] }) + souls: [{ // 将魂 + id: number; // 武将 id + cnt: number; // 数量 + }]; + @prop({ required: true, default: [] }) + pieces: [{ // 装备碎片 + id: number; // 装备 id + cnt: number; // 数量 + }]; + @prop({ required: true, default: [] }) + jewels: [{ // 珠宝 + id: number; // 待定,也可能是 type + lv + cnt: number; // 数量 + }]; + + @prop({ required: true, default: [] }) + warStar: [{ // 关卡星级 + id: number; // 关卡 id + star: number; // 星级 + }]; + + @prop({ required: true, default: 1 }) + loginCnt: number; // 登录次数 + @prop({ required: true }) + createTime: Date; // 创建时间 + @prop({ required: true }) + loginTime: Date; // 更新 / 登录时间 + + public static async findByUid(uid: number, serverId: number, lean = true) { + const role = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); + return role; + } + + public static async createRole(userInfo: User, serverType: string, serverId: number, roleName: string) { + + } +} + +export const RoleModel = getModelForClass(Role); diff --git a/game-server/app/db/Sms.ts b/game-server/app/db/Sms.ts index 3b7d17161..12afc0c5e 100644 --- a/game-server/app/db/Sms.ts +++ b/game-server/app/db/Sms.ts @@ -8,55 +8,57 @@ const moment = require('moment'); @index({ tel: 1 }) export default class Sms extends BaseModel { - @prop({ required: true }) - tel: string; + @prop({ required: true }) + tel: string; - @prop({ required: true }) - telHash: string; + @prop({ required: true }) + telHash: string; - @prop({ required: true }) - code: string; + @prop({ required: true }) + code: string; - @prop({ required: true }) - used: boolean; + @prop({ required: true }) + used: boolean; - @prop({ required: true }) - updateTime: Date; + @prop({ required: true }) + updateTime: Date; - @prop({ required: true }) - countToday: number; + @prop({ required: true }) + countToday: number; - public static async findByTel(tel: string) { - let sms = await smsModel.findOne({ tel }).lean(); - return sms; + public static async findByTel(tel: string, lean = true) { + const sms = await smsModel.findOne({ tel }).lean(lean); + return sms; + } + + public static async updateByTel(tel: string, code: string, used: boolean, updateTime: Date, countToday: number, lean = true) { + await smsModel.findOneAndUpdate({ tel }, { code, used, updateTime, countToday }, { upsert: true }).lean(lean); + } + + public static async validateSms(tel: string, code: string, lean = true) { + const record = await smsModel.findOneAndUpdate({ tel, code, used: false }, { used: true }).lean(lean); + return !!record; + } + + public async timeLimit(interval: number) { + if (Date.now() > this.updateTime.getTime() + interval) { + return false; } + return true; + } - public static async updateByTel(tel: string, code: string, used: boolean, updateTime: Date, countToday: number) { - await smsModel.findOneAndUpdate({tel}, {code, used, updateTime, countToday}, {upsert: true}); + public async cntLimit(cnt: number) { + console.log('hasSendToday:', this.hasSendToday()); + if (await this.hasSendToday() && this.countToday >= cnt) { + return true; } + return false; + } - public static async validateSms(tel: string, code: string) { - const record = await smsModel.findOneAndUpdate({tel, code, used: false}, {used: true}); - return !!record; - } - - public async timeLimit(interval: number) { - if (this.updateTime.getTime() > Date.now() - interval) { - return true; - } - return false; - } - - public async cntLimit(cnt: number) { - if (this.hasSendToday() && this.countToday >= cnt) { - return true; - } - return false; - } - - public async hasSendToday() { - return moment(this.updateTime).format("YYYY-MM-DD") === moment(Date.now()).format("YYYY-MM-DD"); - } + public async hasSendToday() { + console.log(moment(this.updateTime).format('YYYY-MM-DD'), moment(Date.now()).format('YYYY-MM-DD')); + return moment(this.updateTime).format('YYYY-MM-DD') === moment(Date.now()).format('YYYY-MM-DD'); + } } -export const smsModel = getModelForClass(Sms); \ No newline at end of file +export const smsModel = getModelForClass(Sms); diff --git a/game-server/app/db/User.ts b/game-server/app/db/User.ts index 891a5421a..ac5dae45f 100644 --- a/game-server/app/db/User.ts +++ b/game-server/app/db/User.ts @@ -10,70 +10,82 @@ import { index, getModelForClass, prop } from '@typegoose/typegoose'; @index({ uid: 1 }) export default class User extends BaseModel { - @prop({ required: true}) + @prop({ required: true }) uid: number; - @prop({ required: true}) + @prop({ required: true }) username: string; - @prop({ required: true}) + @prop({ required: true }) token: string; - @prop({ required: true}) + @prop({ required: true }) tel: string; - @prop({ required: true}) + @prop({ required: true }) telHash: string; - @prop({ required: true}) + @prop({ required: true }) + channelId: string; + + @prop({ required: true }) + guestId: string; + + // 最后登录 IP + @prop({ required: true }) + ip: string; + + @prop({ required: true }) lastLoginTime: Date; - @prop({ required: true}) + @prop({ required: true }) createTime: Date; - // 平台:ios, android, web, pc - @prop({ required: true}) platform: string; + @prop({ required: true }) + platforms: [{ + platform: string; // 平台:ios, android, web, pc + unionId: string; // 用户标识 + }]; - @prop({ required: true}) + @prop({ required: true }) pkgName: string; // 服务器类型:official, channel, ios, oversea - @prop({ required: true}) + @prop({ required: true }) serverType: string; - public static async createUser() { + // 账号是否被屏蔽 + @prop({ required: true }) + blocked: boolean; - } - - public static async updateToken(tel: string, token: string, platform: string, pkgName: string, serverType: string) { - let user = await UserModel.findOne({tel}).lean(); + public static async updateToken(tel: string, token: string, platform: string, pkgName: string, serverType: string, lean = true) { + let user = await UserModel.findOne({ tel }).lean(); const curTime: Date = new Date(); let update = {}; if (!user) { const uid = await CounterModel.getNewCounter(COUNTER.UID); - update = Object.assign(update, {platform, pkgName, serverType, createTime: curTime, uid, username: `用户${uid}`}); + update = Object.assign(update, { platform, pkgName, serverType, createTime: curTime, uid, username: `用户${uid}` }); } - update = Object.assign(update, {token, lastLoginTime: curTime}); - user = await UserModel.findOneAndUpdate({tel}, update, {upsert: true, new: true}).lean(); + update = Object.assign(update, { token, lastLoginTime: curTime }); + user = await UserModel.findOneAndUpdate({ tel }, update, { upsert: true, new: true }).lean(lean); return user; } - public static async findUserByToken(token: string) { - const user = await UserModel.findOne({token}).select('uid token').lean(); + public static async findUserByToken(token: string, lean = true) { + const user = await UserModel.findOne({ token }).select('uid token').lean(lean); return user; } - public static async findUserByTel(tel: string) { - const user = await UserModel.findOne({tel}).select('uid tel').lean(); + public static async findUserByTel(tel: string, lean = true) { + const user = await UserModel.findOne({ tel }).select('uid tel').lean(lean); return user; } - public static async findUserByUid(uid: number) { - const user = await UserModel.findOne({uid}).select('uid tel').lean(); + public static async findUserByUid(uid: number, lean = true) { + const user = await UserModel.findOne({ uid }).select('uid tel').lean(lean); return user; } - //#endregion } -export const UserModel = getModelForClass(User); \ No newline at end of file +export const UserModel = getModelForClass(User); diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index 01d875b41..9dbcd1d6a 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -1,6 +1,9 @@ +import { RoleModel } from './../../../db/Role'; import { UserModel } from './../../../db/User'; -import {Application} from 'pinus'; +import { Application, Session } from 'pinus'; import {FrontendSession} from 'pinus'; +import Hero from '../../../db/Hero'; +import Equip from '../../../db/Equip'; export default function (app: Application) { return new EntryHandler(app); @@ -10,16 +13,16 @@ export class EntryHandler { constructor(private app: Application) { } - /** * New client entry chat server. * * @param {Object} msg request message * @param {Object} session current session object */ - async enter(msg: { rid: string, username: string, token: string }, session: FrontendSession) { + async enter(msg: { rid: string, username: string, token: string, serverId: number }, session: FrontendSession) { let self = this; let rid = msg.rid; + let serverId = msg.serverId; let uid = msg.username + '*' + rid; let sessionService = self.app.get('sessionService'); @@ -32,6 +35,14 @@ export class EntryHandler { }; } + let role = await RoleModel.findByUid(user.uid, serverId); + if (!role) { + return { + code: 201, + error: true, + data: '用户还未创建角色', + } + } // duplicate log in if (!!sessionService.getByUid(uid)) { console.log('uid not found'); @@ -43,6 +54,8 @@ export class EntryHandler { await session.abind(uid); session.set('rid', rid); + session.set('uid', user.uid); + session.set('roleId', role.roleId); session.push('rid', function (err) { if (err) { console.error('set rid for session service failed! error is : %j', err.stack); @@ -52,9 +65,14 @@ export class EntryHandler { // put user into channel let users = await self.app.rpc.chat.chatRemote.add.route(session)(uid, self.app.get('serverId'), rid, true); - + let heros = await Hero.findByRole(role.roleId); + let equips = await Equip.findbyRole(role.roleId); + role['heros'] = heros; + role['equips'] = equips; return { - users: users + status: 200, + users: users, + role }; } diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts new file mode 100644 index 000000000..e69de29bb diff --git a/game-server/app/servers/role/remote/roleRemote.ts b/game-server/app/servers/role/remote/roleRemote.ts new file mode 100644 index 000000000..e69de29bb diff --git a/shared/statusCode.ts b/shared/statusCode.ts index 77ff6a320..b08190e8d 100644 --- a/shared/statusCode.ts +++ b/shared/statusCode.ts @@ -7,4 +7,5 @@ export const SMS_IN_60S = {code: 100001, simStr: '60秒内只能发送一次'}; export const SMS_CNT_LIMIT = {code: 100002, simStr: '今日短信条数已达上限'}; export const SMS_INVALID = {code: 100003, simStr: '验证码无效'}; -export const SERVER_NOT_FOUND = {code: 200001, simStr: '未找到服务器列表'}; \ No newline at end of file +export const SERVER_NOT_FOUND = {code: 200001, simStr: '未找到服务器列表'}; +export const ROLE_NOT_FOUND = {code: 200002, simStr: '未找到角色'}; \ No newline at end of file diff --git a/web-server/app/controller/account.ts b/web-server/app/controller/account.ts index b694013e6..d3c2c6041 100644 --- a/web-server/app/controller/account.ts +++ b/web-server/app/controller/account.ts @@ -12,4 +12,16 @@ export default class AccountController extends Controller { const { tel, code, platform, pkgName, serverType } = ctx.request.body; ctx.body = await ctx.service.auth.smsLogin(tel, code, platform, pkgName, serverType); } + + public async checkRole() { + const { ctx } = this; + const { serverId } = ctx.request.body; + ctx.body = await ctx.service.auth.checkRole(serverId); + } + + public async createRole() { + const { ctx } = this; + const { serverId, roleName } = ctx.request.body; + ctx.body = await ctx.service.auth.createRole(serverId, roleName); + } } diff --git a/web-server/app/db/Equip.ts b/web-server/app/db/Equip.ts index 68b24d645..18442509c 100644 --- a/web-server/app/db/Equip.ts +++ b/web-server/app/db/Equip.ts @@ -1,5 +1,3 @@ -import { COUNTER } from './../consts/consts'; -import { CounterModel } from './Counter'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; diff --git a/web-server/app/db/Hero.ts b/web-server/app/db/Hero.ts index f9adbc685..5e2b86356 100644 --- a/web-server/app/db/Hero.ts +++ b/web-server/app/db/Hero.ts @@ -1,5 +1,3 @@ -import { COUNTER } from './../consts/consts'; -import { CounterModel } from './Counter'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; diff --git a/web-server/app/db/Role.ts b/web-server/app/db/Role.ts index 3a9a56bed..f40563bc1 100644 --- a/web-server/app/db/Role.ts +++ b/web-server/app/db/Role.ts @@ -1,5 +1,3 @@ -import { COUNTER } from './../consts/consts'; -import { CounterModel } from './Counter'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; import User from './User'; @@ -10,7 +8,6 @@ import User from './User'; @index({ roleId: 1 }) // @index({ userInfo.uid: 1, serverId: 1 }) export default class Role extends BaseModel { - @prop({ required: true }) userInfo: User; @@ -25,68 +22,87 @@ export default class Role extends BaseModel { serverType: string; // 服务器类型 @prop({ required: true }) serverId: number; // 区服 id - @prop({ required: true }) + @prop({ required: true, default: false }) blocked: boolean; // 是否屏蔽 @prop({ required: true }) code: string; // 邀请码 - @prop({ required: true }) + @prop({ required: true, default: 0 }) exp: number; // 经验值 - @prop({ required: true }) + @prop({ required: true, default: 1 }) lv: number; // 主公等级 - @prop({ required: true }) + @prop({ required: true, default: 0 }) ce: number; // 总战力 - @prop({ required: true }) + @prop({ required: true, default: 100 }) tili: number; // 体力值 - @prop({ required: true }) + @prop({ required: true, default: 0 }) vLv: number; // VIP 等级 - @prop({ required: true }) + @prop({ required: true, default: 100 }) gold: number; // 总金币 + @prop({ required: true, default: 0 }) paidGold: number; // 支付所得金币 + @prop({ required: true, default: 100 }) giftGold: number; // 赠送所得金币 + @prop({ required: true, default: 0 }) totalPay: number; // 总支付金额 + @prop({ required: true, default: 0 }) totalBuy: number; // 总金币购买 + @prop({ required: true, default: 0 }) totalCost: number; // 金币总花费 + @prop({ required: true, default: [] }) payRecord: [{ // 支付记录 id: string; // 购买项 product id cnt: number; // 购买次数 }]; - @prop({ required: true }) + @prop({ required: true, default: [] }) consumeGoods: [{ // 消耗品 id: number; // id cnt: number; // 数量 }]; - @prop({ required: true }) + @prop({ required: true, default: [] }) souls: [{ // 将魂 id: number; // 武将 id cnt: number; // 数量 }]; - @prop({ required: true }) + @prop({ required: true, default: [] }) pieces: [{ // 装备碎片 id: number; // 装备 id cnt: number; // 数量 }]; - @prop({ required: true }) + @prop({ required: true, default: [] }) jewels: [{ // 珠宝 id: number; // 待定,也可能是 type + lv cnt: number; // 数量 }]; - @prop({ required: true }) + @prop({ required: true, default: [] }) warStar: [{ // 关卡星级 id: number; // 关卡 id star: number; // 星级 }]; - @prop({ required: true }) + @prop({ required: true, default: 1 }) loginCnt: number; // 登录次数 @prop({ required: true }) createTime: Date; // 创建时间 @prop({ required: true }) loginTime: Date; // 更新 / 登录时间 + + public static async findByUid(uid: number, serverId: number, lean = true) { + const role = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); + return role; + } + + public static async createRole(uid: number, serverId: number, roleInfo: {roleId: string; roleName: string; seqId: number; code: string}, lean = true) { + const user = await User.findUserByUid(uid); + if (!user) return null; + const info = Object.assign(roleInfo, { userInfo: user, serverType: user.serverType, serverId }); + const role = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, info, { upsert: true, new: true }).lean(lean); + return role; + } } export const RoleModel = getModelForClass(Role); diff --git a/web-server/app/db/User.ts b/web-server/app/db/User.ts index 58a0d8dfc..ac5dae45f 100644 --- a/web-server/app/db/User.ts +++ b/web-server/app/db/User.ts @@ -2,7 +2,6 @@ import { COUNTER } from './../consts/consts'; import { CounterModel } from './Counter'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; -import Sms from './Sms'; /** * 用户字段接口 diff --git a/web-server/app/middleware/tokenParser.ts b/web-server/app/middleware/tokenParser.ts index 5f56d553c..854faa6bf 100644 --- a/web-server/app/middleware/tokenParser.ts +++ b/web-server/app/middleware/tokenParser.ts @@ -14,6 +14,7 @@ module.exports = () => { ctx.body = ctx.service.utils.exceptionResult(STATUS_TOKEN_ERR); return; } + ctx.uid = user.uid; await next(); }; }; diff --git a/web-server/app/router.ts b/web-server/app/router.ts index 401bdc210..dbecc92f2 100644 --- a/web-server/app/router.ts +++ b/web-server/app/router.ts @@ -6,5 +6,7 @@ export default (app: Application) => { router.get('/', controller.home.index); router.post('/user/getsms', controller.account.getSms); router.post('/user/smslogin', controller.account.smsLogin); + router.post('/user/checkrole', tokenParser, controller.account.checkRole); + router.post('/user/createrole', tokenParser, controller.account.createRole); router.post('/game/getserverlist', tokenParser, controller.game.getServerList); }; diff --git a/web-server/app/service/Auth.ts b/web-server/app/service/Auth.ts index 0411fd4cf..e9603dda4 100644 --- a/web-server/app/service/Auth.ts +++ b/web-server/app/service/Auth.ts @@ -1,7 +1,9 @@ +import { RoleModel } from './../db/Role'; import { UserModel } from './../db/User'; -import { SMS_IN_60S, SMS_CNT_LIMIT, STATUS_SUC, STATUS_WRONG_PARMS, SMS_INVALID } from './../../../shared/statusCode'; +import { SMS_IN_60S, SMS_CNT_LIMIT, STATUS_SUC, STATUS_WRONG_PARMS, SMS_INVALID, ROLE_NOT_FOUND } from './../../../shared/statusCode'; import { smsModel } from './../db/Sms'; import { Service } from 'egg'; +import Counter from '../db/Counter'; const _ = require('underscore'); /** @@ -98,6 +100,30 @@ export default class Auth extends Service { // 用户注册登录 const token = ctx.service.utils.generateStr(256); const user = await UserModel.updateToken(tel, token, platform, pkgName, serverType); - return { status: STATUS_SUC, data: { token, uid: user?.uid } }; + return { status: STATUS_SUC.code, data: { token, uid: user?.uid } }; + } + + public async checkRole(serverId: number) { + const ctx = this.ctx; + const { uid } = ctx; + const role = await RoleModel.findByUid(uid, serverId); + if (role) { + return { status: STATUS_SUC.code, data: { roleId: role.roleId } }; + } + return ctx.service.utils.exceptionResult(ROLE_NOT_FOUND); + } + + public async createRole(serverId: number, roleName: string) { + console.log('enter Auth createRole'); + const ctx = this.ctx; + const { uid } = ctx; + const roleId = ctx.service.utils.genCode(10); + const code = ctx.service.utils.genCode(6); + const seqId = await Counter.getNewCounter('role') || -1; + const role = await RoleModel.createRole(uid, serverId, { roleId, code, roleName, seqId }); + if (role) { + return { status: STATUS_SUC.code, data: { roleId: role.roleId } }; + } + return ctx.service.utils.exceptionResult(ROLE_NOT_FOUND); } } diff --git a/web-server/app/service/Utils.ts b/web-server/app/service/Utils.ts index 093a65859..074877c01 100644 --- a/web-server/app/service/Utils.ts +++ b/web-server/app/service/Utils.ts @@ -10,7 +10,17 @@ export default class Utils extends Service { * @param radix 基数 */ public generateStr(len: number, radix = 36) { - return csprng(len, radix); + return `${csprng(len, radix)}`; + } + + public genCode(len) { + const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz'; + const charArr = chars.split(''); + let code = ''; + for (let i = 0; i < len; i++) { + code += charArr[Math.floor(Math.random() * charArr.length)]; + } + return code; } /** diff --git a/web-server/package-lock.json b/web-server/package-lock.json index 667416971..b65004895 100644 --- a/web-server/package-lock.json +++ b/web-server/package-lock.json @@ -8643,7 +8643,8 @@ "version": "2.2.2", "resolved": "https://registry.npm.taobao.org/picomatch/download/picomatch-2.2.2.tgz", "integrity": "sha1-IfMz6ba46v8CRo9RRupAbTRfTa0=", - "dev": true + "dev": true, + "optional": true }, "pify": { "version": "3.0.0", diff --git a/web-server/typings/config/plugin.d.ts b/web-server/typings/config/plugin.d.ts index 9d467a6be..5e11bebe7 100644 --- a/web-server/typings/config/plugin.d.ts +++ b/web-server/typings/config/plugin.d.ts @@ -14,6 +14,8 @@ import 'egg-schedule'; import 'egg-static'; import 'egg-jsonp'; import 'egg-view'; +import 'egg-cors'; +import 'egg-alinode'; import { EggPluginItem } from 'egg'; declare module 'egg' { interface EggPlugin { @@ -29,5 +31,7 @@ declare module 'egg' { static?: EggPluginItem; jsonp?: EggPluginItem; view?: EggPluginItem; + cors?: EggPluginItem; + alinode?: EggPluginItem; } } \ No newline at end of file