登录:装备,密码,短信登录
This commit is contained in:
@@ -7,6 +7,8 @@ export const ENCRYPT_KEY = 'fiqaxijabbantusmprc234fj';
|
||||
|
||||
export const AUTH_SMS_CNT_PER_DAY = 8;
|
||||
|
||||
export const ADULT_AGE = 18;
|
||||
|
||||
export const COUNTER = {
|
||||
UID: { name: 'uid', def: 1 },
|
||||
GMUID: { name: 'gmuid', def: 1 },
|
||||
|
||||
@@ -17,6 +17,7 @@ export const STATUS = {
|
||||
DUP_LOGIN: { code: 10006, simStr: '重复登录' },
|
||||
NEW_SERVER_ERR: { code: 10007, simStr: '添加新服务器失败' },
|
||||
SERVER_EXISTS: { code: 10008, simStr: '服务器已存在' },
|
||||
PASSWORD_ERR: { code: 10009, simStr: '密码错误' },
|
||||
// 战斗相关状态 20000 - 29999
|
||||
// 战斗通用 20000 - 20099
|
||||
BATTLE_MISS_INFO: { code: 20001, simStr: '缺少关卡信息' },
|
||||
|
||||
@@ -3,6 +3,8 @@ import { CounterModel } from './Counter';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { genCode } from '../pubUtils/util';
|
||||
const bcrypt = require('bcrypt');
|
||||
const SALT_WORK_FACTOR = 5
|
||||
|
||||
/**
|
||||
* 用户字段接口
|
||||
@@ -24,16 +26,42 @@ export default class User extends BaseModel {
|
||||
token: string;
|
||||
|
||||
@prop({ required: true })
|
||||
tel: string;
|
||||
tel: string; // 账号
|
||||
|
||||
@prop({ required: true, default: '' })
|
||||
telHash: string;
|
||||
|
||||
@prop({ required: true })
|
||||
password: string;
|
||||
|
||||
@prop({ required: true })
|
||||
salt: string;
|
||||
|
||||
@prop({ required: true, default: '' })
|
||||
channelId: string;
|
||||
|
||||
// 游客相关
|
||||
@prop({ required: false, default: false })
|
||||
isGuest: boolean; // 是否是游客
|
||||
@prop({ required: false })
|
||||
guestId: string;
|
||||
guestId: string; // 游客id
|
||||
@prop({ required: false, default: 0 })
|
||||
guestTime: number; // 游客体验时间
|
||||
|
||||
// 防沉迷相关
|
||||
@prop({ required: false, default: false })
|
||||
hasAuthenticated: boolean; // 是否是已认证
|
||||
@prop({ required: false })
|
||||
birthday: string; // 生日年月
|
||||
@prop({ required: false })
|
||||
pi: string; // 已通过实名认证用户唯一标识
|
||||
@prop({ required: false, default: 0 })
|
||||
todayPlayTime: number; // 今日游戏时间
|
||||
@prop({ required: false })
|
||||
refDaily: Date; // 刷新todayPlayTime时间
|
||||
|
||||
@prop({ required: false, default: false })
|
||||
hasSetPw: boolean; // 是否设置过密码
|
||||
|
||||
// 最后登录 IP
|
||||
@prop({ required: false })
|
||||
@@ -52,6 +80,9 @@ export default class User extends BaseModel {
|
||||
unionId: string; // 用户标识
|
||||
}];
|
||||
|
||||
@prop({ required: true, type: String, default: [], _id: false })
|
||||
device: string[];
|
||||
|
||||
@prop({ required: true, default: 'com.bantu.zyz' })
|
||||
pkgName: string;
|
||||
|
||||
@@ -67,23 +98,68 @@ export default class User extends BaseModel {
|
||||
@prop({ required: true, default: 0 })
|
||||
auth: number;
|
||||
|
||||
public static async updateToken(tel: string, token: string, platform: string, pkgName: string, serverType: string, lean = true) {
|
||||
let user: UserType = await UserModel.findOne({ tel }).lean();
|
||||
public static async createUser(isGuest: boolean, tel: string, token: string, platform: string, pkgName: string, serverType: string, deviceId: string, lean = true) {
|
||||
const curTime: Date = new Date();
|
||||
|
||||
const uid = await CounterModel.getNewCounter(COUNTER.UID);
|
||||
const userCode = genCode(8);
|
||||
const doc = new UserModel();
|
||||
let update = {};
|
||||
if (!user) {
|
||||
const uid = await CounterModel.getNewCounter(COUNTER.UID);
|
||||
const userCode = genCode(8);
|
||||
const doc = new UserModel();
|
||||
update = Object.assign(update, { platform, pkgName, serverType, createTime: curTime, uid, userCode, username: `用户${uid}` }, doc.toJSON());
|
||||
}
|
||||
update = Object.assign(update, doc.toJSON(), { platform, pkgName, serverType, createTime: curTime, uid, userCode, username: `用户${uid}`, isGuest });
|
||||
if(isGuest) update["guestId"] = tel;
|
||||
update = Object.assign(update, { token, lastLoginTime: curTime });
|
||||
user = await UserModel.findOneAndUpdate({ tel }, update, { upsert: true, new: true }).lean(lean);
|
||||
delete update["device"];
|
||||
|
||||
const user = await UserModel.findOneAndUpdate({ tel }, { $set: update, $addToSet: {device: deviceId}}, { upsert: true, new: true }).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async updateToken(tel: string, token: string, deviceId: string, lean = true) {
|
||||
const curTime: Date = new Date();
|
||||
|
||||
let user = await UserModel.findOneAndUpdate({ tel }, { $set: { token, lastLoginTime: curTime }, $addToSet: {device: deviceId}}, { new: true }).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async createOrUpdate(isGuest: boolean, tel: string, token: string, platform: string, pkgName: string, serverType: string, deviceId: string) {
|
||||
let user: UserType = await UserModel.findOne({ tel }).lean();
|
||||
if (!user) {
|
||||
user = await UserModel.createUser(isGuest, tel, token, platform, pkgName, serverType, deviceId);
|
||||
} else {
|
||||
user = await UserModel.updateToken(tel, token, deviceId);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private static async encryptPass(password: string, salt?: string) {
|
||||
if (!salt) {
|
||||
salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
|
||||
}
|
||||
let npassword = await bcrypt.hash(password, salt);
|
||||
return { npassword, salt };
|
||||
}
|
||||
|
||||
public static async setPass(uid: number, password: string, lean = true) {
|
||||
let r = await this.encryptPass(password);
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid }, { $set: { password: r.npassword, salt: r.salt, hasSetPw: true }}).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async checkPass(tel: string, password: string, token: string, deviceId: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ tel }).select('salt').lean();
|
||||
if (user) {
|
||||
const curTime: Date = new Date();
|
||||
let { salt } = user;
|
||||
let { npassword } = await this.encryptPass(password, salt);
|
||||
const checkUser: UserType = await UserModel.findOneAndUpdate({ tel, password: npassword }, { $set: { token, lastLoginTime: curTime }, $addToSet: {device: deviceId}}).select('uid username name token').lean(lean);
|
||||
return checkUser;
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
public static async findUserByToken(token: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ token }).select('uid token serverType auth userCode').lean(lean);
|
||||
const user: UserType = await UserModel.findOne({ token }).select('uid token serverType auth tel userCode').lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -119,6 +195,7 @@ export default class User extends BaseModel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const UserModel = getModelForClass(User);
|
||||
|
||||
export interface UserType extends Pick<DocumentType<User>, keyof User>{};
|
||||
|
||||
@@ -94,3 +94,23 @@ export function getTodayZeroDate() {
|
||||
date.setSeconds(0);
|
||||
return date;
|
||||
}
|
||||
|
||||
export function getAge(birthday: string) {
|
||||
let d = new Date(birthday + ' 00:00:00');
|
||||
let _year = d.getFullYear();
|
||||
let _month = d.getMonth() + 1;
|
||||
let _day = d.getDate();
|
||||
|
||||
let age = 0;
|
||||
let now = new Date();
|
||||
let year = now.getFullYear();
|
||||
let month = now.getMonth() + 1;
|
||||
let day = now.getDate();
|
||||
|
||||
if (year >= _year && month >= _month && day >= _day) {
|
||||
age = year - _year;
|
||||
}else{
|
||||
age = year - _year - 1;
|
||||
}
|
||||
return age
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Controller } from 'egg';
|
||||
|
||||
export default class AccountController extends Controller {
|
||||
|
||||
public async deviceLogin() {
|
||||
const { ctx } = this;
|
||||
const { token, isGuest, deviceId, platform, pkgName, serverType } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.deviceLogin(isGuest, token, deviceId, platform, pkgName, serverType);
|
||||
}
|
||||
|
||||
public async getSms() {
|
||||
const { ctx } = this;
|
||||
const { tel } = ctx.request.body;
|
||||
@@ -9,8 +16,20 @@ export default class AccountController extends Controller {
|
||||
|
||||
public async smsLogin() {
|
||||
const { ctx } = this;
|
||||
const { tel, code, platform, pkgName, serverType } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.smsLogin(tel, code, platform, pkgName, serverType);
|
||||
const { tel, code, platform, pkgName, serverType, deviceId } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.smsLogin(tel, deviceId, code, platform, pkgName, serverType);
|
||||
}
|
||||
|
||||
public async setPassword() {
|
||||
const { ctx } = this;
|
||||
const { password } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.setPassword(password);
|
||||
}
|
||||
|
||||
public async pwLogin() {
|
||||
const { ctx } = this;
|
||||
const { tel, deviceId, pw } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.pwLogin(tel, deviceId, pw);
|
||||
}
|
||||
|
||||
public async checkRole() {
|
||||
|
||||
@@ -5,8 +5,11 @@ export default (app: Application) => {
|
||||
const tokenParser = app.middleware.tokenParser();
|
||||
router.get('/dev', controller.home.dev);
|
||||
router.get('/', controller.home.index);
|
||||
router.post('/user/devicelogin', controller.account.deviceLogin);
|
||||
router.post('/user/getsms', controller.account.getSms);
|
||||
router.post('/user/smslogin', controller.account.smsLogin);
|
||||
router.post('/user/setpassword', tokenParser, controller.account.setPassword);
|
||||
router.post('/user/pwlogin', controller.account.pwLogin);
|
||||
router.post('/user/checkrole', tokenParser, controller.account.checkRole);
|
||||
router.post('/user/createrole', tokenParser, controller.account.createRole);
|
||||
router.post('/game/getserverlist', tokenParser, controller.game.getServerList);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { COUNTER, HERO_SYSTEM_TYPE, DEFAULT_LV, DEFAULT_ITEMS, ITID, DEFAULT_GOLD, DEFAULT_HERO_LV, DEFAULT_EQUIPS, DEFAULT_COIN } from '@consts';
|
||||
import { COUNTER, HERO_SYSTEM_TYPE, DEFAULT_LV, DEFAULT_ITEMS, ITID, DEFAULT_GOLD, DEFAULT_HERO_LV, DEFAULT_EQUIPS, DEFAULT_COIN, ADULT_AGE } from '@consts';
|
||||
import { DEFAULT_HEROES } from '@consts';
|
||||
import { HeroModel } from '@db/Hero';
|
||||
import { RoleModel } from '@db/Role';
|
||||
import { UserModel } from '@db/User';
|
||||
import { UserModel, UserType } from '@db/User';
|
||||
import { STATUS } from '@consts';
|
||||
import { smsModel } from '@db/Sms';
|
||||
import { Service } from 'egg';
|
||||
@@ -11,178 +11,283 @@ import { getHeroInfoById } from 'app/pubUtils/gamedata';
|
||||
import { calPlayerCeAndSave, reCalAllHeroCe } from 'app/pubUtils/playerCe';
|
||||
import { getExpByLv, getHeroExpByLv, gameData } from 'app/pubUtils/data';
|
||||
import { isString } from 'underscore';
|
||||
import { getAge } from 'app/pubUtils/timeUtil';
|
||||
import { shouldRefresh } from 'app/pubUtils/util';
|
||||
|
||||
/**
|
||||
* Test Service
|
||||
*/
|
||||
export default class Auth extends Service {
|
||||
|
||||
public checkTelNo(telNo) {
|
||||
if (!isString(telNo)) {
|
||||
return { status: 1, data: '参数类型错误' };
|
||||
}
|
||||
if (telNo.length !== 11) {
|
||||
return { status: 1, data: '手机号长度错误' };
|
||||
}
|
||||
return { status: 0, data: '手机号合法' };
|
||||
}
|
||||
/**
|
||||
* 设备免密登录
|
||||
* @param telNo - 用户手机号
|
||||
*/
|
||||
|
||||
async sendSmsCodeByGuodu(tel, code) {
|
||||
const ctx = this.ctx;
|
||||
const url = `http://221.179.172.68:8000/QxtSms/QxtFirewall?OperID=bantu3&OperPass=c8XcTffG&DesMobile=${tel}&Content=${encodeURIComponent(`【同人游戏】验证码${code},您正在登录赵云传,若非本人操作,请勿泄露`)}&Content_Code=1`;
|
||||
const result = await ctx.curl(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
public async deviceLogin(isGuest: boolean, token: string, deviceId: string, platform: string, pkgName: string, serverType: string) {
|
||||
const ctx = this.ctx;
|
||||
|
||||
testLimit(sms, interval) {
|
||||
if (sms.updateTime.getTime() > Date.now() - interval) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
let user = await UserModel.findUserByToken(token);
|
||||
|
||||
/**
|
||||
* 用户获取手机验证码
|
||||
* @param telNo - 用户手机号
|
||||
*/
|
||||
if (!user) {
|
||||
if(isGuest) {
|
||||
const tel = ctx.service.utils.genCode(10);
|
||||
const token = ctx.service.utils.generateStr(256);
|
||||
user = await UserModel.createUser(isGuest, tel, token, platform, pkgName, serverType, deviceId);
|
||||
let param = this.getReturnParam(user);
|
||||
return this.ctx.service.utils.resResult(STATUS.SUCCESS, {
|
||||
canLogin: true,
|
||||
...param
|
||||
});
|
||||
} else {
|
||||
|
||||
public async getSms(tel: string) {
|
||||
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
const sms = await smsModel.findByTel(tel, false);
|
||||
if (sms) {
|
||||
if (await sms.timeLimit(10000)) {
|
||||
return this.ctx.service.utils.resResult(STATUS.SMS_IN_60S);
|
||||
}
|
||||
if (await sms.cntLimit(8)) {
|
||||
return this.ctx.service.utils.resResult(STATUS.SMS_CNT_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
let code = '';
|
||||
if (sms && (!sms.used || sms.isFixed)) {
|
||||
code = sms.code;
|
||||
} else {
|
||||
code = this.ctx.service.utils.generateNum(6);
|
||||
}
|
||||
|
||||
const smsResult = await this.sendSmsCodeByGuodu(tel, code);
|
||||
console.log(smsResult);
|
||||
await smsModel.updateByTel(tel, code, false, new Date(), sms?.hasSendToday() ? sms.countToday + 1 : 1);
|
||||
return this.ctx.service.utils.resResult(STATUS.SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取到手机验证码之后发送验证登录请求
|
||||
* @param tel 登录手机号
|
||||
* @param code 登录验证码
|
||||
* @param platform 平台
|
||||
* @param pkgName 包名
|
||||
* @param serverType 服务器类型
|
||||
*/
|
||||
public async smsLogin(tel: string, code: string, platform: string, pkgName: string, serverType: string) {
|
||||
const ctx = this.ctx;
|
||||
// 参数检查
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
|
||||
// ! 测试阶段允许客户端不传验证码,此时不做验证码验证,直接注册或登录账号
|
||||
// TODO 上线前改掉或仅保留在测试服
|
||||
if (code !== '') {
|
||||
if (!isString(code) || code.length !== 6) {
|
||||
return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
|
||||
}
|
||||
|
||||
// 手机验证码核验
|
||||
const smsValid: boolean = await smsModel.validateSms(tel, code);
|
||||
if (!smsValid) {
|
||||
const sms = await smsModel.findByTel(tel);
|
||||
if(sms && sms.isFixed) { // 固定手机号登录
|
||||
if (sms.code !== code) {
|
||||
return ctx.service.utils.resResult(STATUS.SMS_INVALID);
|
||||
}
|
||||
return this.ctx.service.utils.resResult(STATUS.SUCCESS, {
|
||||
canLogin: false
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return ctx.service.utils.resResult(STATUS.SMS_INVALID);
|
||||
const token = ctx.service.utils.generateStr(256);
|
||||
user = await UserModel.updateToken(user.tel, token, deviceId);
|
||||
let param = this.getReturnParam(user);
|
||||
return this.ctx.service.utils.resResult(STATUS.SUCCESS, {
|
||||
canLogin: true,
|
||||
...param
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 用户注册登录
|
||||
const token = ctx.service.utils.generateStr(256);
|
||||
const user = await UserModel.updateToken(tel, token, platform, pkgName, serverType);
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { token, userCode: user?.userCode });
|
||||
}
|
||||
private getReturnParam(user: UserType) {
|
||||
let age = getAge(user.birthday);
|
||||
let isAdult = age >= ADULT_AGE;
|
||||
let todayPlayTime = user.todayPlayTime;
|
||||
if(shouldRefresh(user.refDaily, new Date(), 0)) {
|
||||
todayPlayTime = 0;
|
||||
}
|
||||
return {
|
||||
tel: user.tel,
|
||||
isGuest: !!user.isGuest,
|
||||
guestTime: user.guestTime, // 游客已体验时间
|
||||
hasAuthenticated: !!user.hasAuthenticated, // 是否进行过实名认证
|
||||
isAdult, // 是否已成年
|
||||
todayPlayTime, // 今天已游戏时长
|
||||
|
||||
public async checkRole(serverId: number) {
|
||||
const ctx = this.ctx;
|
||||
const { uid } = ctx;
|
||||
const role = await RoleModel.findByUid(uid, serverId);
|
||||
if (role) {
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { roleId: role.roleId });
|
||||
hasSetPw: user.hasSetPw, // 是否设置了密码
|
||||
token: user.token, // 用户token
|
||||
userCode: user.userCode // 用户标识
|
||||
}
|
||||
}
|
||||
return ctx.service.utils.resResult(STATUS.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(COUNTER.ROLE) || -1;
|
||||
const role = await RoleModel.createRole(uid, serverId, { roleId, code, roleName, seqId, lv: DEFAULT_LV, exp: (getExpByLv(DEFAULT_LV - 1)||{sum:0}).sum||0 });
|
||||
if (role) {
|
||||
let skinIds = new Array<number>();
|
||||
for (let hid of DEFAULT_HEROES) {
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if(hero) {
|
||||
continue;
|
||||
public checkTelNo(telNo) {
|
||||
if (!isString(telNo)) {
|
||||
return { status: 1, data: '参数类型错误' };
|
||||
}
|
||||
|
||||
let dicHero = getHeroInfoById(hid);
|
||||
if(!dicHero) {
|
||||
break;
|
||||
if (telNo.length !== 11) {
|
||||
return { status: 1, data: '手机号长度错误' };
|
||||
}
|
||||
let {quality, initialStars: star, jobid: job, name: hName, initialSkin} = dicHero;
|
||||
return { status: 0, data: '手机号合法' };
|
||||
}
|
||||
|
||||
hero = await HeroModel.createHero({
|
||||
roleId, roleName: role.roleName, hid, hName, star, quality, job, serverId: role.serverId,
|
||||
skins:[{id: initialSkin, enable: true}], lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1)||0
|
||||
async sendSmsCodeByGuodu(tel, code) {
|
||||
const ctx = this.ctx;
|
||||
const url = `http://221.179.172.68:8000/QxtSms/QxtFirewall?OperID=bantu3&OperPass=c8XcTffG&DesMobile=${tel}&Content=${encodeURIComponent(`【同人游戏】验证码${code},您正在登录赵云传,若非本人操作,请勿泄露`)}&Content_Code=1`;
|
||||
const result = await ctx.curl(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
skinIds.push(initialSkin);
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, roleId, hero, {}, role);
|
||||
|
||||
}
|
||||
await reCalAllHeroCe(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, {}, skinIds)
|
||||
|
||||
for(let {id, count} of DEFAULT_ITEMS) {
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
if(!dicGoods) continue;
|
||||
let itidObj = ITID.get(dicGoods.itid);
|
||||
if(!itidObj) continue;
|
||||
await ctx.service.utils.addBags(roleId, role.roleName, {id, itemName: dicGoods.name, count, type: itidObj.type, hid: 0});
|
||||
}
|
||||
|
||||
for(let {id, count} of DEFAULT_EQUIPS) {
|
||||
for(let j = 0; j < count; j++) {
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
if(!dicGoods) continue;
|
||||
|
||||
await ctx.service.utils.addEquips(roleId, role.roleName, {id, ...dicGoods, hid: 0});
|
||||
}
|
||||
}
|
||||
await RoleModel.addGoldFree(roleId, DEFAULT_GOLD);
|
||||
await RoleModel.addCoin(roleId, DEFAULT_COIN);
|
||||
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { roleId: role.roleId });
|
||||
return result.data;
|
||||
}
|
||||
|
||||
testLimit(sms, interval) {
|
||||
if (sms.updateTime.getTime() > Date.now() - interval) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取手机验证码
|
||||
* @param telNo - 用户手机号
|
||||
*/
|
||||
|
||||
public async getSms(tel: string) {
|
||||
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
const sms = await smsModel.findByTel(tel, false);
|
||||
if (sms) {
|
||||
if (await sms.timeLimit(10000)) {
|
||||
return this.ctx.service.utils.resResult(STATUS.SMS_IN_60S);
|
||||
}
|
||||
if (await sms.cntLimit(8)) {
|
||||
return this.ctx.service.utils.resResult(STATUS.SMS_CNT_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
let code = '';
|
||||
if (sms && (!sms.used || sms.isFixed)) {
|
||||
code = sms.code;
|
||||
} else {
|
||||
code = this.ctx.service.utils.generateNum(6);
|
||||
}
|
||||
|
||||
const smsResult = await this.sendSmsCodeByGuodu(tel, code);
|
||||
console.log(smsResult);
|
||||
await smsModel.updateByTel(tel, code, false, new Date(), sms?.hasSendToday() ? sms.countToday + 1 : 1);
|
||||
return this.ctx.service.utils.resResult(STATUS.SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取到手机验证码之后发送验证登录请求
|
||||
* @param tel 登录手机号
|
||||
* @param code 登录验证码
|
||||
* @param platform 平台
|
||||
* @param pkgName 包名
|
||||
* @param serverType 服务器类型
|
||||
*/
|
||||
public async smsLogin(tel: string, deviceId: string, code: string, platform: string, pkgName: string, serverType: string) {
|
||||
const ctx = this.ctx;
|
||||
// 参数检查
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
|
||||
// ! 测试阶段允许客户端不传验证码,此时不做验证码验证,直接注册或登录账号
|
||||
// TODO 上线前改掉或仅保留在测试服
|
||||
if (code !== '') {
|
||||
if (!isString(code) || code.length !== 6) {
|
||||
return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
|
||||
}
|
||||
|
||||
// 手机验证码核验
|
||||
const smsValid: boolean = await smsModel.validateSms(tel, code);
|
||||
if (!smsValid) {
|
||||
const sms = await smsModel.findByTel(tel);
|
||||
if (sms && sms.isFixed) { // 固定手机号登录
|
||||
if (sms.code !== code) {
|
||||
return ctx.service.utils.resResult(STATUS.SMS_INVALID);
|
||||
}
|
||||
} else {
|
||||
return ctx.service.utils.resResult(STATUS.SMS_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户注册登录
|
||||
const token = ctx.service.utils.generateStr(256);
|
||||
const user = await UserModel.createOrUpdate(false, tel, token, platform, pkgName, serverType, deviceId);
|
||||
let param = this.getReturnParam(user);
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置密码
|
||||
* @param password 密码
|
||||
*/
|
||||
public async setPassword(password: string) {
|
||||
const { ctx } = this;
|
||||
const { uid } = ctx;
|
||||
|
||||
let user = await UserModel.setPass(uid, password);
|
||||
if (user) {
|
||||
let param = this.getReturnParam(user);
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, param);
|
||||
} else {
|
||||
return ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码登录
|
||||
* @param tel 登录手机号
|
||||
* @param code 登录验证码
|
||||
* @param platform 平台
|
||||
* @param pkgName 包名
|
||||
* @param serverType 服务器类型
|
||||
*/
|
||||
public async pwLogin(tel: string, deviceId: string, pw: string) {
|
||||
const ctx = this.ctx;
|
||||
// 参数检查
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
|
||||
|
||||
// 用户注册登录
|
||||
const token = ctx.service.utils.generateStr(256);
|
||||
const user = await UserModel.checkPass(tel, pw, token, deviceId);
|
||||
if(!user) return ctx.service.utils.resResult(STATUS.PASSWORD_ERR);
|
||||
|
||||
let param = this.getReturnParam(user);
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { ...param });
|
||||
}
|
||||
|
||||
public async checkRole(serverId: number) {
|
||||
const ctx = this.ctx;
|
||||
const { uid } = ctx;
|
||||
const role = await RoleModel.findByUid(uid, serverId);
|
||||
if (role) {
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { roleId: role.roleId });
|
||||
}
|
||||
return ctx.service.utils.resResult(STATUS.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(COUNTER.ROLE) || -1;
|
||||
const role = await RoleModel.createRole(uid, serverId, { roleId, code, roleName, seqId, lv: DEFAULT_LV, exp: (getExpByLv(DEFAULT_LV - 1) || { sum: 0 }).sum || 0 });
|
||||
if (role) {
|
||||
let skinIds = new Array<number>();
|
||||
for (let hid of DEFAULT_HEROES) {
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (hero) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let dicHero = getHeroInfoById(hid);
|
||||
if (!dicHero) {
|
||||
break;
|
||||
}
|
||||
let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = dicHero;
|
||||
|
||||
hero = await HeroModel.createHero({
|
||||
roleId, roleName: role.roleName, hid, hName, star, quality, job, serverId: role.serverId,
|
||||
skins: [{ id: initialSkin, enable: true }], lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0
|
||||
});
|
||||
skinIds.push(initialSkin);
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, roleId, hero, {});
|
||||
|
||||
}
|
||||
await reCalAllHeroCe(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, {}, skinIds)
|
||||
|
||||
for (let { id, count } of DEFAULT_ITEMS) {
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
if (!dicGoods) continue;
|
||||
let itidObj = ITID.get(dicGoods.itid);
|
||||
if (!itidObj) continue;
|
||||
await ctx.service.utils.addBags(roleId, role.roleName, { id, itemName: dicGoods.name, count, type: itidObj.type, hid: 0 });
|
||||
}
|
||||
|
||||
for (let { id, count } of DEFAULT_EQUIPS) {
|
||||
for (let j = 0; j < count; j++) {
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
if (!dicGoods) continue;
|
||||
|
||||
await ctx.service.utils.addEquips(roleId, role.roleName, { id, ...dicGoods, hid: 0 });
|
||||
}
|
||||
}
|
||||
await RoleModel.addGoldFree(roleId, DEFAULT_GOLD);
|
||||
await RoleModel.addCoin(roleId, DEFAULT_COIN);
|
||||
|
||||
return ctx.service.utils.resResult(STATUS.SUCCESS, { roleId: role.roleId });
|
||||
}
|
||||
return ctx.service.utils.resResult(STATUS.ROLE_NOT_FOUND);
|
||||
}
|
||||
return ctx.service.utils.resResult(STATUS.ROLE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user