web-server 注册、登录、获取服务器列表;game-server token 校验
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import 'reflect-metadata'
|
||||
import * as mongoose from 'mongoose';
|
||||
import { Application, IBoot } from 'egg';
|
||||
|
||||
export default class FooBoot implements IBoot {
|
||||
private readonly app: Application;
|
||||
|
||||
constructor(app: Application) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
async configWillLoad() {
|
||||
// Ready to call configDidLoad,`
|
||||
// Config, plugin files are referred,`
|
||||
// this is the last chance to modify the config.
|
||||
await this.connectDB(this.app)
|
||||
}
|
||||
|
||||
configDidLoad() {
|
||||
// Config, plugin files have loaded.
|
||||
}
|
||||
|
||||
async didLoad() {
|
||||
// All files have loaded, start plugin here.
|
||||
}
|
||||
|
||||
async willReady() {
|
||||
// All plugins have started, can do some thing before app ready.
|
||||
// await this.customLoadModel();
|
||||
}
|
||||
|
||||
async didReady() {
|
||||
// Worker is ready, can do some things
|
||||
// don't need to block the app boot.
|
||||
}
|
||||
|
||||
async serverDidReady() {
|
||||
// Server is listening.
|
||||
}
|
||||
|
||||
async beforeClose() {
|
||||
// Do some thing before app close.
|
||||
}
|
||||
|
||||
//#region 手动挂载model,测试需要ctx.model
|
||||
|
||||
public async connectDB(app: Application) {
|
||||
const { url, options } = app.config.mongoose
|
||||
if (url) {
|
||||
const connection = await mongoose.connect(url, options)
|
||||
app.context.connection = connection
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
module.exports = FooBoot;
|
||||
@@ -1,3 +1,12 @@
|
||||
export const TURBO_CORE_URL = 'https://coresrv.tgamebox.cn';
|
||||
export const APP_ID = 'KbZMUfUfppLFDG7dXtNkLWbyapK0JTHY';
|
||||
export const PARM_SECRET = 'ipqw05du6ob4x130w89t31yrqd6xs005zzltcmg2zpqnvrjp1s';
|
||||
export const APP_ID = 'AXaXmIHPs9eONvzrBesD8aSKQNXYdALF';
|
||||
export const TURBO_PARM_SECRET = 'ipqw05du6ob4x130w89t31yrqd6xs005zzltcmg2zpqnvrjp1s';
|
||||
|
||||
export const ENCRYPT_IV = 'f7182j5f04e377ux';
|
||||
export const ENCRYPT_KEY = 'fiqaxijabbantusmprc234fj';
|
||||
|
||||
export const AUTH_SMS_CNT_PER_DAY = 8;
|
||||
|
||||
export const COUNTER = {
|
||||
UID: 'uid'
|
||||
}
|
||||
@@ -3,7 +3,13 @@ import { Controller } from 'egg';
|
||||
export default class AccountController extends Controller {
|
||||
public async getSms() {
|
||||
const { ctx } = this;
|
||||
console.log(ctx.request.body);
|
||||
ctx.body = await ctx.service.turboCore.getSms(ctx.request.body.telNo);
|
||||
const { tel } = ctx.request.body;
|
||||
ctx.body = await ctx.service.auth.getSms(tel);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { SERVER_NOT_FOUND } from './../../../shared/statusCode';
|
||||
import { STATUS_SUC } from '../../../shared/statusCode';
|
||||
import { GameModel } from '../db/Game';
|
||||
import { Controller } from 'egg';
|
||||
|
||||
export default class GameController extends Controller {
|
||||
public async getServerList() {
|
||||
const { ctx } = this;
|
||||
const { serverType } = ctx.request.body;
|
||||
let serverList: Array<any> = await GameModel.getServerListByType(serverType);
|
||||
if (serverList && serverList.length > 0) {
|
||||
ctx.body = {status: STATUS_SUC.code, data: { serverList }};
|
||||
} else {
|
||||
ctx.body = ctx.service.utils.exceptionResult(SERVER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { prop, pre } from '@typegoose/typegoose';
|
||||
|
||||
/**
|
||||
* BaseModel
|
||||
*/
|
||||
@pre<BaseModel>('save', function (next) {
|
||||
if (!this.createdAt || this.isNew) {
|
||||
this.createdAt = this.updatedAt = new Date()
|
||||
} else {
|
||||
this.updatedAt = new Date()
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
export default class BaseModel {
|
||||
|
||||
_id?: string
|
||||
|
||||
@prop()
|
||||
createdAt: Date
|
||||
|
||||
@prop()
|
||||
updatedAt: Date
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop } from '@typegoose/typegoose';
|
||||
|
||||
/**
|
||||
* 短信字段接口
|
||||
*/
|
||||
@index({ name: 1 })
|
||||
export default class Counter extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
name: string;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CounterModel = getModelForClass(Counter);
|
||||
@@ -0,0 +1,70 @@
|
||||
import { APP_ID } from './../consts/consts';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop } from '@typegoose/typegoose';
|
||||
|
||||
class ServerInfo {
|
||||
@prop({ required: true})
|
||||
name: string;
|
||||
|
||||
@prop({ required: true})
|
||||
host: string;
|
||||
|
||||
@prop({ required: false})
|
||||
port: number;
|
||||
|
||||
@prop({ required: true})
|
||||
status: number;
|
||||
|
||||
@prop({ required: true})
|
||||
createTime: Date;
|
||||
|
||||
@prop({ required: true})
|
||||
serverType: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户字段接口
|
||||
*/
|
||||
@index({ id: 1 })
|
||||
export default class Game extends BaseModel {
|
||||
|
||||
@prop({ required: true})
|
||||
id: number;
|
||||
|
||||
@prop({ required: true})
|
||||
name: string;
|
||||
|
||||
@prop({ required: true})
|
||||
nameEn: string;
|
||||
|
||||
@prop({ required: true})
|
||||
des: string;
|
||||
|
||||
@prop({ required: true})
|
||||
serverList: Array<ServerInfo>;
|
||||
|
||||
@prop({ required: true})
|
||||
iconUrl: string;
|
||||
|
||||
@prop({ required: true})
|
||||
version: string;
|
||||
|
||||
@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<ServerInfo> = game ? game.serverList : [];
|
||||
serverList = serverList.filter(item => { return item.serverType === serverType; })
|
||||
return serverList;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export const GameModel = getModelForClass(Game);
|
||||
@@ -0,0 +1,62 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop } from '@typegoose/typegoose';
|
||||
const moment = require('moment');
|
||||
|
||||
/**
|
||||
* 短信字段接口
|
||||
*/
|
||||
@index({ tel: 1 })
|
||||
export default class Sms extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
tel: string;
|
||||
|
||||
@prop({ required: true })
|
||||
telHash: string;
|
||||
|
||||
@prop({ required: true })
|
||||
code: string;
|
||||
|
||||
@prop({ required: true })
|
||||
used: boolean;
|
||||
|
||||
@prop({ required: true })
|
||||
updateTime: Date;
|
||||
|
||||
@prop({ required: true })
|
||||
countToday: number;
|
||||
|
||||
public static async findByTel(tel: string) {
|
||||
let sms = await smsModel.findOne({ tel }).lean();
|
||||
return sms;
|
||||
}
|
||||
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
|
||||
export const smsModel = getModelForClass(Sms);
|
||||
@@ -0,0 +1,79 @@
|
||||
import { COUNTER } from './../consts/consts';
|
||||
import { CounterModel } from './Counter';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop } from '@typegoose/typegoose';
|
||||
|
||||
/**
|
||||
* 用户字段接口
|
||||
*/
|
||||
@index({ tel: 1 })
|
||||
@index({ uid: 1 })
|
||||
export default class User extends BaseModel {
|
||||
|
||||
@prop({ required: true})
|
||||
uid: number;
|
||||
|
||||
@prop({ required: true})
|
||||
username: string;
|
||||
|
||||
@prop({ required: true})
|
||||
token: string;
|
||||
|
||||
@prop({ required: true})
|
||||
tel: string;
|
||||
|
||||
@prop({ required: true})
|
||||
telHash: string;
|
||||
|
||||
@prop({ required: true})
|
||||
lastLoginTime: Date;
|
||||
|
||||
@prop({ required: true})
|
||||
createTime: Date;
|
||||
|
||||
// 平台:ios, android, web, pc
|
||||
@prop({ required: true})
|
||||
platform: string;
|
||||
|
||||
@prop({ required: true})
|
||||
pkgName: string;
|
||||
|
||||
// 服务器类型:official, channel, ios, oversea
|
||||
@prop({ required: true})
|
||||
serverType: string;
|
||||
|
||||
public static async createUser() {
|
||||
|
||||
}
|
||||
|
||||
public static async updateToken(tel: string, token: string, platform: string, pkgName: string, serverType: string) {
|
||||
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, {token, lastLoginTime: curTime});
|
||||
user = await UserModel.findOneAndUpdate({tel}, update, {upsert: true, new: true}).lean();
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async findUserByToken(token: string) {
|
||||
const user = await UserModel.findOne({token}).select('uid token').lean();
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async findUserByTel(tel: string) {
|
||||
const user = await UserModel.findOne({tel}).select('uid tel').lean();
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async findUserByUid(uid: number) {
|
||||
const user = await UserModel.findOne({uid}).select('uid tel').lean();
|
||||
return user;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export const UserModel = getModelForClass(User);
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ENCRYPT_KEY, ENCRYPT_IV } from './../consts/consts';
|
||||
import { Context } from 'egg';
|
||||
const crypto = require('crypto');
|
||||
const isJSON = require('koa-is-json');
|
||||
|
||||
function aesEncrypt(data, key, iv) {
|
||||
const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
|
||||
var crypted = cipher.update(data, 'utf8', 'hex');
|
||||
crypted += cipher.final('hex');
|
||||
return crypted;
|
||||
}
|
||||
|
||||
function aesDecrypt(data, key, iv) {
|
||||
const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
|
||||
var decrypted = decipher.update(data, 'hex', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
module.exports = options => {
|
||||
return async function parmsDecode(ctx: Context, next) {
|
||||
if (options.threshold && ctx.length < options.threshold) return;
|
||||
let reqBody = ctx.request.body;
|
||||
if (!reqBody.data) return;
|
||||
|
||||
if (isJSON(reqBody)) {
|
||||
let encodeStr = aesEncrypt(JSON.stringify(reqBody), ENCRYPT_KEY, ENCRYPT_IV);
|
||||
console.log(`encoded str: ${encodeStr}`);
|
||||
}
|
||||
|
||||
let decodeStr = aesDecrypt(reqBody.data, ENCRYPT_KEY, ENCRYPT_IV);
|
||||
try {
|
||||
ctx.request.body = JSON.parse(decodeStr);
|
||||
} catch (e) {
|
||||
console.error('parms parse err');
|
||||
}
|
||||
|
||||
await next();
|
||||
|
||||
let resBody = ctx.body;
|
||||
console.log('return value:', resBody);
|
||||
if (isJSON(resBody)) {
|
||||
ctx.body = {result: aesEncrypt(JSON.stringify(resBody), ENCRYPT_KEY, ENCRYPT_IV)};
|
||||
} else {
|
||||
ctx.body = {result: aesEncrypt(JSON.stringify({status: 3, data: 'internal err'}), ENCRYPT_KEY, ENCRYPT_IV)};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { STATUS_TOKEN_ERR, STATUS_WRONG_PARMS } from './../../../shared/statusCode';
|
||||
import { UserModel } from './../db/User';
|
||||
import { Context } from 'egg';
|
||||
|
||||
module.exports = () => {
|
||||
return async function tokenParser(ctx: Context, next) {
|
||||
if (!ctx.request.body || !ctx.request.body.token) {
|
||||
ctx.body = ctx.service.utils.exceptionResult(STATUS_WRONG_PARMS);
|
||||
return;
|
||||
}
|
||||
const user = await UserModel.findUserByToken(ctx.request.body.token);
|
||||
if (!user) {
|
||||
console.log('token invalid');
|
||||
ctx.body = ctx.service.utils.exceptionResult(STATUS_TOKEN_ERR);
|
||||
return;
|
||||
}
|
||||
await next();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ import { Application } from 'egg';
|
||||
|
||||
export default (app: Application) => {
|
||||
const { controller, router } = app;
|
||||
|
||||
const tokenParser = app.middleware.tokenParser();
|
||||
router.get('/', controller.home.index);
|
||||
router.post('/user/getsms', controller.account.getSms);
|
||||
router.post('/user/smslogin', controller.account.smsLogin);
|
||||
router.post('/game/getserverlist', tokenParser, controller.game.getServerList);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { UserModel } from './../db/User';
|
||||
import { SMS_IN_60S, SMS_CNT_LIMIT, STATUS_SUC, STATUS_WRONG_PARMS, SMS_INVALID } from './../../../shared/statusCode';
|
||||
import { smsModel } from './../db/Sms';
|
||||
import { Service } from 'egg';
|
||||
const _ = require('underscore');
|
||||
|
||||
/**
|
||||
* 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: '手机号合法'};
|
||||
}
|
||||
|
||||
async sendSmsCodeByGuodu(tel, code) {
|
||||
const ctx = this.ctx;
|
||||
let 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取手机验证码
|
||||
* @param telNo - 用户手机号
|
||||
*/
|
||||
|
||||
public async getSms(tel: string) {
|
||||
|
||||
const telVerify = this.checkTelNo(tel);
|
||||
if (telVerify.status !== 0) {
|
||||
return telVerify;
|
||||
}
|
||||
|
||||
let sms = await smsModel.findByTel(tel);
|
||||
if (!!sms) {
|
||||
if (sms.timeLimit(60000)) {
|
||||
return this.ctx.service.utils.exceptionResult(SMS_IN_60S);
|
||||
}
|
||||
if (sms.cntLimit(8)) {
|
||||
return this.ctx.service.utils.exceptionResult(SMS_CNT_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
let code: string = '';
|
||||
if (!sms || !sms.used) {
|
||||
code = this.ctx.service.utils.generateNum(6);
|
||||
} else {
|
||||
code = sms.code;
|
||||
}
|
||||
|
||||
await this.sendSmsCodeByGuodu(tel, code);
|
||||
await smsModel.updateByTel(tel, code, false, new Date(), sms?.hasSendToday() ? sms.countToday + 1 : 1);
|
||||
return this.ctx.service.utils.exceptionResult(STATUS_SUC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取到手机验证码之后发送验证登录请求
|
||||
* @param telNo 登录手机号
|
||||
* @param code 登录验证码
|
||||
*/
|
||||
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;
|
||||
}
|
||||
if (!_.isString(code) || code.length !== 6) {
|
||||
return ctx.service.utils.exceptionResult(STATUS_WRONG_PARMS);
|
||||
}
|
||||
|
||||
// 手机验证码核验
|
||||
const smsValid: boolean = await smsModel.validateSms(tel, code);
|
||||
if (!smsValid) {
|
||||
return ctx.service.utils.exceptionResult(SMS_INVALID);
|
||||
}
|
||||
|
||||
// 用户注册登录
|
||||
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 }};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TURBO_CORE_URL, APP_ID, PARM_SECRET } from './../consts/consts';
|
||||
import { TURBO_CORE_URL, APP_ID, TURBO_PARM_SECRET } from './../consts/consts';
|
||||
import { Service } from 'egg';
|
||||
const crypto = require('crypto');
|
||||
/**
|
||||
@@ -7,31 +7,56 @@ const crypto = require('crypto');
|
||||
export default class TurboCore extends Service {
|
||||
|
||||
/**
|
||||
* sayHi to you
|
||||
* @param name - your name
|
||||
* 用户获取手机验证码
|
||||
* @param telNo - 用户手机号
|
||||
*/
|
||||
|
||||
public async getSms(telNo: string) {
|
||||
const ctx = this.ctx;
|
||||
let body = {
|
||||
'telNo':telNo
|
||||
}
|
||||
telNo
|
||||
};
|
||||
const result = await ctx.curl(`${TURBO_CORE_URL}/user/getSms`, {
|
||||
// 必须指定 method
|
||||
method: 'POST',
|
||||
// 通过 contentType 告诉 HttpClient 以 JSON 格式发送
|
||||
contentType: 'json',
|
||||
headers: {
|
||||
'AppId': APP_ID,
|
||||
'sign': this.getTurboSign( body, PARM_SECRET)
|
||||
'sign': this.getTurboSign( body, TURBO_PARM_SECRET)
|
||||
},
|
||||
data: body,
|
||||
// 明确告诉 HttpClient 以 JSON 格式处理返回的响应 body
|
||||
dataType: 'json',
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户获取到手机验证码之后发送验证登录请求
|
||||
* @param telNo 登录手机号
|
||||
* @param code 登录验证码
|
||||
*/
|
||||
public async smsLogin(telNo: string, code: string) {
|
||||
const ctx = this.ctx;
|
||||
let body = {
|
||||
telNo, code
|
||||
};
|
||||
const result = await ctx.curl(`${TURBO_CORE_URL}/user/getSms`, {
|
||||
method: 'POST',
|
||||
contentType: 'json',
|
||||
headers: {
|
||||
'AppId': APP_ID,
|
||||
'sign': this.getTurboSign( body, TURBO_PARM_SECRET)
|
||||
},
|
||||
data: body,
|
||||
dataType: 'json',
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多宝规则下的参数签名
|
||||
* @param params 参数列表
|
||||
* @param secret 密钥
|
||||
*/
|
||||
private getTurboSign(params, secret) {
|
||||
let paramsString = this.joinParamsStr(params);
|
||||
let stringToSign = paramsString;
|
||||
@@ -46,6 +71,10 @@ export default class TurboCore extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将参数组合成字符串
|
||||
* @param params 参数列表
|
||||
*/
|
||||
private joinParamsStr(params) {
|
||||
let signString = Object.keys(params).filter(function (key) {
|
||||
return params[key] !== undefined && params[key] !== '' && ['pfx', 'partner_key', 'sign', 'key'].indexOf(key) < 0;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Service } from 'egg';
|
||||
const csprng = require('csprng');
|
||||
/**
|
||||
* Utils Service
|
||||
*/
|
||||
export default class Utils extends Service {
|
||||
/**
|
||||
* 生成 len 长度的随机字符串
|
||||
* @param len 长度
|
||||
* @param radix 基数
|
||||
*/
|
||||
public generateStr(len: number, radix: number = 36) {
|
||||
return csprng(len, radix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定长度的随机数
|
||||
* @param len 随机数长度
|
||||
*/
|
||||
public generateNum(len: number) {
|
||||
let code = "";
|
||||
for (let i = 0; i < len; i++) {
|
||||
code += parseInt(`${Math.random() * 10}`);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
public exceptionResult(status) {
|
||||
const { code, simStr} = status;
|
||||
return {status: code, data: simStr};
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,12 @@ export default (appInfo: EggAppInfo) => {
|
||||
},
|
||||
};
|
||||
// add your egg config in here
|
||||
config.middleware = [];
|
||||
config.middleware = ['parmsDecode'];
|
||||
|
||||
config.mongoose = {
|
||||
url: 'mongodb://root:zyz_2020@dds-8vbdb47c6fb58a541.mongodb.zhangbei.rds.aliyuncs.com:3717,dds-8vbdb47c6fb58a542.mongodb.zhangbei.rds.aliyuncs.com:3717/admin?replicaSet=mgset-500808098', // 内网
|
||||
options: {},
|
||||
};
|
||||
|
||||
// add your special config in here
|
||||
const bizConfig = {
|
||||
|
||||
Generated
+18
@@ -2844,6 +2844,14 @@
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"csprng": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/csprng/download/csprng-0.1.2.tgz",
|
||||
"integrity": "sha1-S8aPEvo2jSUqWYQcusqXSxirReI=",
|
||||
"requires": {
|
||||
"sequin": "*"
|
||||
}
|
||||
},
|
||||
"csrf": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/csrf/download/csrf-3.1.0.tgz",
|
||||
@@ -9137,6 +9145,11 @@
|
||||
"upper-case-first": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"sequin": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/sequin/download/sequin-0.1.1.tgz",
|
||||
"integrity": "sha1-XC04nWajg3NOqvvEXt6ywcsb5wE="
|
||||
},
|
||||
"serialize-json": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/serialize-json/download/serialize-json-1.0.3.tgz",
|
||||
@@ -10096,6 +10109,11 @@
|
||||
"random-bytes": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.10.2.tgz?cache=0&sync_timestamp=1585605854253&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funderscore%2Fdownload%2Funderscore-1.10.2.tgz",
|
||||
"integrity": "sha1-c9aqNmjzGI5K2w8ZQ70Sz9fvqq8="
|
||||
},
|
||||
"unescape": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/unescape/download/unescape-1.0.1.tgz",
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
"clean": "ets clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"csprng": "^0.1.2",
|
||||
"egg": "^2.6.1",
|
||||
"egg-scripts": "^2.6.0"
|
||||
"egg-scripts": "^2.6.0",
|
||||
"underscore": "^1.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^2.2.40",
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
|
||||
import 'egg';
|
||||
import ExportAccount from '../../../app/controller/account';
|
||||
import ExportGame from '../../../app/controller/game';
|
||||
import ExportHome from '../../../app/controller/home';
|
||||
|
||||
declare module 'egg' {
|
||||
interface IController {
|
||||
account: ExportAccount;
|
||||
game: ExportGame;
|
||||
home: ExportHome;
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// This file is created by egg-ts-helper@1.25.8
|
||||
// Do not modify this file!!!!!!!!!
|
||||
|
||||
import 'egg';
|
||||
import ExportParmsDecode from '../../../app/middleware/parmsDecode';
|
||||
import ExportTokenParser from '../../../app/middleware/tokenParser';
|
||||
|
||||
declare module 'egg' {
|
||||
interface IMiddleware {
|
||||
parmsDecode: typeof ExportParmsDecode;
|
||||
tokenParser: typeof ExportTokenParser;
|
||||
}
|
||||
}
|
||||
+4
@@ -6,12 +6,16 @@ type AnyClass = new (...args: any[]) => any;
|
||||
type AnyFunc<T = any> = (...args: any[]) => T;
|
||||
type CanExportFunc = AnyFunc<Promise<any>> | AnyFunc<IterableIterator<any>>;
|
||||
type AutoInstanceType<T, U = T extends CanExportFunc ? T : T extends AnyFunc ? ReturnType<T> : T> = U extends AnyClass ? InstanceType<U> : U;
|
||||
import ExportAuth from '../../../app/service/Auth';
|
||||
import ExportTest from '../../../app/service/Test';
|
||||
import ExportTurboCore from '../../../app/service/TurboCore';
|
||||
import ExportUtils from '../../../app/service/Utils';
|
||||
|
||||
declare module 'egg' {
|
||||
interface IService {
|
||||
auth: AutoInstanceType<typeof ExportAuth>;
|
||||
test: AutoInstanceType<typeof ExportTest>;
|
||||
turboCore: AutoInstanceType<typeof ExportTurboCore>;
|
||||
utils: AutoInstanceType<typeof ExportUtils>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user