登录:装备,密码,短信登录

This commit is contained in:
luying
2021-03-02 20:21:12 +08:00
parent 95deef6230
commit 9dfee7f49c
7 changed files with 397 additions and 170 deletions

View File

@@ -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 },

View File

@@ -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: '缺少关卡信息' },

View File

@@ -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>{};

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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);
}
}