fix pvp刷新对手时保存数据
This commit is contained in:
@@ -1,26 +1,27 @@
|
||||
import {Application, BackendSession, pinus} from 'pinus';
|
||||
import { uniq, findWhere, findIndex } from 'underscore';
|
||||
import { gameData, getPvpBoxs } from '../../../pubUtils/data';
|
||||
import { refreshEnemies, getEnemies, getLvByScore, defaultHeroes, comsumeChallengeCnt, refresh, findPvpDefByRoleId, checkRoleIsRobot, getRefOppCnt, findPvpDefAllByRoleId, generPVPOppRecInfo, generMyRecInfo, getRobotLineup, getPlayerLineup } from '../../../services/pvpService';
|
||||
import { refreshEnemies, getEnemies, getLvByScore, defaultHeroes, comsumeChallengeCnt, refresh, findPvpDefByRoleId, checkRoleIsRobot, getRefOppCnt, findPvpDefAllByRoleId, generPVPOppRecInfo, generMyRecInfo } from '../../../services/pvpService';
|
||||
import { RoleModel, RoleType } from '../../../db/Role';
|
||||
import { STATUS } from '../../../consts/statusCode';
|
||||
import { resResult, genCode } from '../../../pubUtils/util';
|
||||
import { SystemConfigModel } from '../../../db/SystemConfig'
|
||||
|
||||
import { PvpDefenseModel, OppPlayers } from '../../../db/PvpDefense';
|
||||
import { oppHeroesDefenseInter, pvpEndParamInter, RankParam, PlayerDetail, PlayerDetailHero } from '../../../pubUtils/interface';
|
||||
import { pvpEndParamInter, RankParam, PlayerDetail, PlayerDetailHero } from '../../../pubUtils/interface';
|
||||
import { PVP_HERO_POS, REDIS_KEY } from '../../../consts';
|
||||
import { PVP } from '../../../pubUtils/dicParam';
|
||||
import { addItems } from '../../../services/rewardService';
|
||||
import { HeroModel } from '../../../db/Hero';
|
||||
import { checkBattleHeroesByHid } from '../../../services/normalBattleService';
|
||||
import { BattleRecordModel } from '../../../db/BattleRecord';
|
||||
import { PvpRecordModel, HeroesRecord } from '../../../db/PvpRecord';
|
||||
import { PvpRecordModel } from '../../../db/PvpRecord';
|
||||
import { existsRank, initRank, getRank, setRank, getMyRank } from '../../../services/redisService';
|
||||
import { handleCost } from '../../../services/rewardService';
|
||||
import { nowSeconds } from '../../../pubUtils/timeUtil';
|
||||
import { setPvpSeasonResult, resetPvpWarId, resetPvpSeasonTime } from '../../../services/timeTaskService';
|
||||
import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult';
|
||||
import { PvpHistoryOppModel, PvpHistoryOppType } from '../../../db/PvpHistoryOpp';
|
||||
|
||||
export default function(app: Application) {
|
||||
return new PvpHandler(app);
|
||||
}
|
||||
@@ -158,22 +159,13 @@ export class PvpHandler {
|
||||
let oppoRoleId = msg.roleId;
|
||||
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
|
||||
let { oppPlayers } = pvpDefense;
|
||||
let role = <RoleType>pvpDefense.role;
|
||||
|
||||
let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId);
|
||||
if(!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
|
||||
|
||||
let system = await SystemConfigModel.findSystemConfig();
|
||||
let mapWarJson = gameData.warJson.get(system.warId);
|
||||
let { oppRoleId, heroes } = <PvpHistoryOppType>curOpp.oppDef;
|
||||
|
||||
let heroes = new Array<oppHeroesDefenseInter>();
|
||||
if(curOpp.isRobot) { // 机器人
|
||||
heroes = await getRobotLineup(mapWarJson, curOpp, role.topFiveCe, role.lv);
|
||||
} else { // 真人
|
||||
heroes = await getPlayerLineup(mapWarJson, curOpp);
|
||||
}
|
||||
|
||||
return resResult(STATUS.SUCCESS, { roleId: oppoRoleId, pos: curOpp.pos, heroes });
|
||||
return resResult(STATUS.SUCCESS, { roleId: oppRoleId, pos: curOpp.pos, heroes });
|
||||
}
|
||||
|
||||
// 开战
|
||||
@@ -287,6 +279,9 @@ export class PvpHandler {
|
||||
await setRank(REDIS_KEY.PVP_RANK, 0, roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), params);
|
||||
let myRank = await getMyRank(REDIS_KEY.PVP_RANK, 0, roleId);
|
||||
|
||||
// 对手记录更新
|
||||
await PvpHistoryOppModel.setStatus(roleId, oppRoleId, 1);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
battleCode, isSuccess,
|
||||
score, pLv, myRank, hisScore,
|
||||
@@ -386,34 +381,17 @@ export class PvpHandler {
|
||||
let result: PlayerDetail;
|
||||
|
||||
if(isRobot) { // 如果是机器人,从自己的pvpDefense中寻找
|
||||
let role = await RoleModel.findByRoleId(roleId);
|
||||
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
|
||||
let { oppPlayers } = pvpDefense;
|
||||
let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId);
|
||||
if(!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
|
||||
|
||||
let heroes = new Array<PlayerDetailHero>();
|
||||
|
||||
let { robot } = curOpp;
|
||||
let { warId } = robot;
|
||||
let dicWarJson = gameData.warJson.get(warId);
|
||||
|
||||
for(let json of dicWarJson) {
|
||||
const { actorId, relation } = json;
|
||||
if(relation == 2 && actorId > 0) { // 默认格子
|
||||
let dicHero = gameData.hero.get(actorId);
|
||||
heroes.push({
|
||||
actorId,
|
||||
star: dicHero.initialStars,
|
||||
colorStar: 0,
|
||||
quality: dicHero.quality,
|
||||
score: 0,
|
||||
lv: role.lv
|
||||
});
|
||||
}
|
||||
let pvpHistoryOpp = await PvpHistoryOppModel.findByRoleIdAndOppId(roleId, oppoRoleId);
|
||||
if(!pvpHistoryOpp) {
|
||||
return resResult(STATUS.PVP_ROLE_NOT_FOUND);
|
||||
}
|
||||
result = new PlayerDetail({...robot, lv: role.lv, heroes})
|
||||
|
||||
let heroes = pvpHistoryOpp.heroes.map(hero => {
|
||||
let newHero = new PlayerDetailHero();
|
||||
newHero.setPvpHeroInfo(hero);
|
||||
return newHero;
|
||||
})
|
||||
result = new PlayerDetail({...pvpHistoryOpp, roleId: pvpHistoryOpp.oppRoleId, heroes});
|
||||
} else { // 查询对方pvpDefense
|
||||
let pvpDefense = await PvpDefenseModel.findByRoleId(oppoRoleId);
|
||||
let dbHeroes = await HeroModel.findByRole(oppoRoleId);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
|
||||
import { fromCallback } from 'bluebird';
|
||||
import { checkPvp, findPvpDefByRoleId } from '../services/pvpService'
|
||||
import { getFuncsSwitch } from '../pubUtils/data';
|
||||
import { FUNCS_ID, FUNC_OPT_TYPE } from '../consts/constModules/sysConst';
|
||||
import { RoleModel } from '../db/Role';
|
||||
import { startEvent } from "./eventSercive";
|
||||
|
||||
export async function eventOnPlayerLvUp(roleId: string, lv: number, addFuncs: Array<number>, dataFuncs: Array<number>) {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RoleType, RoleModel } from '../db/Role';
|
||||
import { PVP_HERO_POS, ROBOT_NAME, REDIS_KEY, PVP_CONST } from '../consts';
|
||||
import { setPvpDefResult } from '../services/timeTaskService';
|
||||
import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
|
||||
import { getRandomIndexByLen, genCode, getRandomByLen, shouldRefresh, reduceCe } from '../pubUtils/util';
|
||||
import { getRandomIndexByLen, genCode, getRandomByLen, shouldRefresh, reduceCe, getChineseName } from '../pubUtils/util';
|
||||
import { oppPlayersInter, RankParam, pvpEndParamInter, oppHeroesDefenseInter, Attributes } from '../pubUtils/interface';
|
||||
import { gameData, getPLvByScore } from "../pubUtils/data";
|
||||
import { PVP } from '../pubUtils/dicParam';
|
||||
@@ -13,11 +13,11 @@ import { setRank, getMyRank, getFieldByRank } from './redisService';
|
||||
import { nowSeconds, checkTodayTime } from '../pubUtils/timeUtil';
|
||||
import { HeroesRecord } from '../db/PvpRecord';
|
||||
import { HeroModel, HeroType } from '../db/Hero';
|
||||
import { CeAttrNumber, CeAttr, CeAttrRole } from '../db/generalField';
|
||||
import { CeAttrNumber, CeAttr, CeAttrRole, PvpEnemies, PvpHeroInfo } from '../db/generalField';
|
||||
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
|
||||
import { findWhere, findIndex } from 'underscore';
|
||||
import { pinus } from 'pinus';
|
||||
|
||||
import { PvpHistoryOppModel, PvpHistoryOppType } from '../db/PvpHistoryOpp';
|
||||
|
||||
export async function initPvpInfo(role: RoleType) {
|
||||
let heroes: Array<Heroes> = [];
|
||||
@@ -62,47 +62,39 @@ export async function checkPvp(role: RoleType) {
|
||||
* @param pLv 玩家本人的队伍等级
|
||||
*/
|
||||
export async function getEnemies(oppPlayers: OppPlayers[], winStreakNum: number) {
|
||||
|
||||
let result = new Array<oppPlayersInter>();
|
||||
for(let {pos, isRobot, oppDef, robot} of oppPlayers) {
|
||||
let dicOpponent = dicPvpOpponent.get(pos);
|
||||
if(isRobot) {
|
||||
let { roleId, roleName, headHid, sHid, pLv, defCe } = robot;
|
||||
result.push({
|
||||
pos, roleId, roleName, headHid, sHid, pLv, defCe: reduceCe(defCe),
|
||||
addScore: dicOpponent.score,
|
||||
rankLv: 0,
|
||||
plusScore: getPlusScore(winStreakNum)
|
||||
});
|
||||
} else {
|
||||
let opp = <PvpDefenseType>oppDef;
|
||||
let role = <RoleType>opp.role;
|
||||
let { roleId, roleName, headHid, sHid, lv } = role;
|
||||
let { pLv, defCe } = opp;
|
||||
let rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, roleId);
|
||||
result.push({
|
||||
pos, roleId, roleName, headHid, sHid, pLv, defCe: reduceCe(defCe),
|
||||
addScore: dicOpponent.score,
|
||||
rankLv, // 读取排名
|
||||
plusScore: getPlusScore(winStreakNum)
|
||||
});
|
||||
}
|
||||
for(let oppPlayer of oppPlayers) {
|
||||
let dicOpponent = dicPvpOpponent.get(oppPlayer.pos);
|
||||
let oppDef = <PvpHistoryOppType>oppPlayer.oppDef; // select 'oppRoleId pos roleName headHid sHid rankLv pLv defCe'
|
||||
result.push({
|
||||
...oppDef,
|
||||
roleId: oppDef.oppRoleId,
|
||||
defCe: reduceCe(oppDef.defCe),
|
||||
addScore: dicOpponent.score,
|
||||
rankLv: 0,
|
||||
plusScore: getPlusScore(winStreakNum)
|
||||
});
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 刷新对手
|
||||
export async function refreshEnemies(role: RoleType, score: number, pLv: number) {
|
||||
let { roleId, topFiveCe } = role;
|
||||
let system = await SystemConfigModel.findSystemConfig();
|
||||
let mapWarJson = gameData.warJson.get(system.warId);
|
||||
|
||||
let { roleId } = role;
|
||||
let oppPlayers = new Array<OppPlayers>();
|
||||
let opp = dicPvpOpponent.values()
|
||||
for(let dicOpp of opp) {
|
||||
let flag = false; // 是否筛选成功
|
||||
if(score >= PVP_CONST.SCORE_LINE) { // TODO 将这个放到const
|
||||
flag = await matchPlayer(oppPlayers, roleId, pLv, dicOpp);
|
||||
if(!flag) flag = await matchPlayerByRank(oppPlayers, roleId, dicOpp.id); // 当前后分数段没有时,返回前一名的玩家
|
||||
if(!flag) flag = matchRobot(oppPlayers, topFiveCe, pLv, dicOpp);
|
||||
if(score >= PVP_CONST.SCORE_LINE) { // 将这个放到const
|
||||
flag = await matchPlayer(oppPlayers, mapWarJson, roleId, pLv, dicOpp); // 按照等级匹配对手
|
||||
if(!flag) flag = await matchPlayerByRank(oppPlayers, mapWarJson, roleId, dicOpp.id); // 当前后分数段没有时,返回前一名的玩家
|
||||
if(!flag) flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp);
|
||||
} else {
|
||||
flag = matchRobot(oppPlayers, topFiveCe, pLv, dicOpp);
|
||||
flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp);
|
||||
}
|
||||
if(!flag) continue;
|
||||
}
|
||||
@@ -110,7 +102,7 @@ export async function refreshEnemies(role: RoleType, score: number, pLv: number)
|
||||
return oppPlayers;
|
||||
}
|
||||
|
||||
export async function matchPlayerByRank(oppPlayers: OppPlayers[], roleId: string, pos: number) {
|
||||
export async function matchPlayerByRank(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pos: number) {
|
||||
let ridRanks = new Array<number>(); // 已经被使用了的排名
|
||||
for(let { roleId: curRoleId } of oppPlayers) {
|
||||
let rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, curRoleId);
|
||||
@@ -146,17 +138,18 @@ export async function matchPlayerByRank(oppPlayers: OppPlayers[], roleId: string
|
||||
oppRoleId = result[0];
|
||||
|
||||
let pvpdefense = await PvpDefenseModel.findByRoleId(oppRoleId);
|
||||
let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, mapWarJson, roleId, pos);
|
||||
|
||||
oppPlayers.push({
|
||||
roleId: pvpdefense.roleId,
|
||||
oppDef: pvpdefense._id,
|
||||
oppDef: pvpHistoryOpp._id,
|
||||
pos,
|
||||
isRobot: false,
|
||||
robot: null
|
||||
});
|
||||
return true
|
||||
}
|
||||
|
||||
async function matchPlayer(oppPlayers: OppPlayers[], roleId: string, pLv: number, dicOpp: DicPvpOpponent ) {
|
||||
async function matchPlayer(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pLv: number, dicOpp: DicPvpOpponent ) {
|
||||
let { id: pos, minLv, maxLv } = dicOpp
|
||||
let range = await PvpDefenseModel.findByTeamLv(pLv + minLv, pLv + maxLv);
|
||||
range = range.filter(cur => {
|
||||
@@ -165,7 +158,7 @@ async function matchPlayer(oppPlayers: OppPlayers[], roleId: string, pLv: number
|
||||
if(range.length <= 0) return false;
|
||||
|
||||
let index = getRandomIndexByLen(range.length);
|
||||
let result = range[index];
|
||||
let result = range[index]; // 本次匹配结果 pvpdefense
|
||||
if(!result) return false;
|
||||
if(result.roleId == roleId) {
|
||||
range.splice(index, 1);
|
||||
@@ -173,18 +166,54 @@ async function matchPlayer(oppPlayers: OppPlayers[], roleId: string, pLv: number
|
||||
index = getRandomIndexByLen(range.length);
|
||||
result = range[index];
|
||||
}
|
||||
|
||||
let pvpHistoryOpp = await generPlayerOppHis(result, mapWarJson, roleId, pos);
|
||||
oppPlayers.push({
|
||||
roleId: result.roleId,
|
||||
oppDef: result._id,
|
||||
oppDef: pvpHistoryOpp._id,
|
||||
pos,
|
||||
isRobot: false,
|
||||
robot: null
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
function matchRobot(oppPlayers: OppPlayers[], myCe: number, pLv: number, dicOpp: DicPvpOpponent) {
|
||||
/**
|
||||
* @description 对手是玩家时,生成并返回pvpHistoryOpp
|
||||
* @param result 随机出的对手pvpDefense
|
||||
* @param mapWarJson 本周地图出兵表
|
||||
* @param roleId 自己的玩家id
|
||||
* @param pos 刷新这个对手的位置
|
||||
*/
|
||||
async function generPlayerOppHis(result: PvpDefenseType, mapWarJson: DicWarJson[], roleId: string, pos: number) {
|
||||
let heroScores = result.heroScores;
|
||||
let role = <RoleType>result.role;
|
||||
let rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, role.roleId);
|
||||
let heroes = new Array<PvpEnemies>();
|
||||
for(let warJson of mapWarJson) {
|
||||
if(warJson.relation == 1) continue;
|
||||
let h = result.heroes.find(cur => cur.dataId == warJson.dataId);
|
||||
if(h) {
|
||||
let hs = heroScores.find(cur => cur.hid == warJson.actorId); // 这个武将的军功
|
||||
let hero = <HeroType>h.hero;
|
||||
let heroInfo = new PvpHeroInfo();
|
||||
heroInfo.setHeroInfo(hero);
|
||||
heroInfo.setOutIndex(h.order);
|
||||
let attribute = getPlayerAttribute(hero.ceAttr, role.globalCeAttr);
|
||||
heroInfo.setAttribute(attribute);
|
||||
let enemy = new PvpEnemies(warJson, heroInfo, hs?hs.score: 0);
|
||||
heroes.push(enemy);
|
||||
} else {
|
||||
let enemy = new PvpEnemies(warJson, new PvpHeroInfo(), 0);
|
||||
heroes.push(enemy);
|
||||
}
|
||||
}
|
||||
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({
|
||||
...result, ...role, pos, rankLv, heroes, roleId, oppRoleId: result.roleId
|
||||
});
|
||||
return pvpHistoryOpp;
|
||||
}
|
||||
|
||||
async function matchRobot(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], role: RoleType, pLv: number, dicOpp: DicPvpOpponent) {
|
||||
let { lv: myLv, topFiveCe: myCe, roleId } = role;
|
||||
let { id: pos, minLv, maxLv, ratio } = dicOpp;
|
||||
let range = gameData.pvpWar;
|
||||
if(range.length <= 0) return false;
|
||||
@@ -193,17 +222,41 @@ function matchRobot(oppPlayers: OppPlayers[], myCe: number, pLv: number, dicOpp:
|
||||
let result = range[index];
|
||||
if(!result) return false;
|
||||
|
||||
let roleId = generateRobotRoleId();
|
||||
let roleName = getRandomByLen(ROBOT_NAME);
|
||||
let robotWarjson = gameData.warJson.get(result.war_id);
|
||||
if(!robotWarjson) { /* TODO 判空处理 */ }
|
||||
let heroes = new Array<PvpEnemies>();
|
||||
for(let warJson of mapWarJson) {
|
||||
if(warJson.relation == 1) continue;
|
||||
let h = robotWarjson.find(cur => cur.dataId == warJson.dataId);
|
||||
if(h) {
|
||||
let dicHero = gameData.hero.get(h.actorId);
|
||||
if(!dicHero) continue;
|
||||
let heroInfo = new PvpHeroInfo();
|
||||
heroInfo.setRobotInfo(h, myLv, dicHero.initialStars, dicHero.quality);
|
||||
let attribute = getRobotAttribute(h.attribute, myCe, PVP_CONST.ENEMY_CE, ratio);
|
||||
heroInfo.setAttribute(attribute);
|
||||
let enemy = new PvpEnemies(warJson, heroInfo, 0);
|
||||
heroes.push(enemy);
|
||||
} else {
|
||||
let enemy = new PvpEnemies(warJson, new PvpHeroInfo(), 0);
|
||||
heroes.push(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
let oppRoleId = generateRobotRoleId();
|
||||
let roleName = getChineseName();
|
||||
let hisPLv = Math.floor(pLv + (minLv + maxLv)/2);
|
||||
if(hisPLv < 1) hisPLv = 1
|
||||
let robot = new Robot(roleId, roleName, Math.floor(myCe * ratio), hisPLv, result.war_id)
|
||||
|
||||
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({
|
||||
roleId, oppRoleId, roleName, pos, defCe: Math.floor(myCe * ratio), pLv: hisPLv, lv: myLv, heroes
|
||||
});
|
||||
|
||||
oppPlayers.push({
|
||||
roleId,
|
||||
oppDef: null,
|
||||
roleId: oppRoleId,
|
||||
oppDef: pvpHistoryOpp._id,
|
||||
pos,
|
||||
isRobot: true,
|
||||
robot
|
||||
isRobot: true
|
||||
});
|
||||
return true
|
||||
}
|
||||
@@ -386,10 +439,10 @@ export async function findPvpDefAllByRoleId(roleId: string) {
|
||||
let role = <RoleType>pvpDefense.role;
|
||||
let oppPlayers = await refreshEnemies(role, pvpDefense.score, pvpDefense.pLv);
|
||||
update.oppPlayers = oppPlayers;
|
||||
pvpDefense.oppPlayers = oppPlayers;
|
||||
}
|
||||
|
||||
await PvpDefenseModel.updateInfo( roleId, update);
|
||||
let updateResult = await PvpDefenseModel.updateInfoAndInclude( roleId, update);
|
||||
pvpDefense.oppPlayers = updateResult.oppPlayers;
|
||||
pvpDefense.challengeCnt = challengeCnt;
|
||||
pvpDefense.challengeRefTime = challengeRefTime;
|
||||
pvpDefense.refOppCnt = refOppCnt;
|
||||
@@ -399,52 +452,13 @@ export async function findPvpDefAllByRoleId(roleId: string) {
|
||||
return {pvpDefense, warId, shouldRefOpp};
|
||||
}
|
||||
|
||||
// 获取机器人阵容
|
||||
export async function getRobotLineup(mapWarJson: DicWarJson[], curOpp: OppPlayers, topFiveCe: number, lv: number) {
|
||||
let heroes = new Array<oppHeroesDefenseInter>();
|
||||
let { pos, robot } = curOpp;
|
||||
let { warId } = robot;
|
||||
let dicWarJson = gameData.warJson.get(warId);
|
||||
let dicOpp = gameData.pvpOpponent.get(pos);
|
||||
for(let json of dicWarJson) {
|
||||
let curDicMapJson = mapWarJson.find(cur => cur.dataId == json.dataId);
|
||||
const { actorId, actorName, attribute, skill, seid, star, spine, relation } = json;
|
||||
|
||||
if(relation == 2 && actorId > 0) { // 默认格子
|
||||
let newAttribute = getRobotAttribute(attribute, topFiveCe, PVP_CONST.ENEMY_CE, dicOpp.ratio);
|
||||
let heroInfo = { actorId, actorName, skill, seid, star, spine, attribute: newAttribute, lv };
|
||||
heroes.push({
|
||||
...curDicMapJson, ...heroInfo
|
||||
});
|
||||
}
|
||||
}
|
||||
return heroes
|
||||
}
|
||||
|
||||
// 获取阵容阵容
|
||||
export async function getPlayerLineup(mapWarJson: DicWarJson[], curOpp: OppPlayers, ) {
|
||||
let heroes = new Array<oppHeroesDefenseInter>();
|
||||
|
||||
let oppDef = <PvpDefenseType>curOpp.oppDef;
|
||||
let role = <RoleType>oppDef.role;
|
||||
let { globalCeAttr } = role;
|
||||
for(let { actorId, hero, dataId, order } of oppDef.heroes) {
|
||||
if(actorId > 0) {
|
||||
let curDicMapJson = mapWarJson.find(cur => cur.dataId == dataId);
|
||||
let dicHero = gameData.hero.get(actorId);
|
||||
let h = <HeroType>hero;
|
||||
let { ceAttr } = h;
|
||||
let newAttribute = getPlayerAttribute(ceAttr, globalCeAttr);
|
||||
let heroInfo = { outIndex: order, actorId, actorName: dicHero.name, skill:0, seid:'&', star: h.star, spine: 0, attribute: newAttribute, lv: h.lv };
|
||||
heroes.push({
|
||||
...curDicMapJson, ...heroInfo
|
||||
});
|
||||
}
|
||||
}
|
||||
return heroes
|
||||
}
|
||||
|
||||
// 按比例计算出兵表中的属性
|
||||
/**
|
||||
* 根据比例计算机器人属性
|
||||
* @param attribute 出兵表中的属性字段
|
||||
* @param ce 我的战力
|
||||
* @param enemyCe 出兵表对手战力
|
||||
* @param ratio 系数
|
||||
*/
|
||||
export function getRobotAttribute(attribute: Attributes, ce: number, enemyCe: number, ratio: number) {
|
||||
|
||||
let newAttribute = new CeAttrNumber();
|
||||
@@ -457,7 +471,11 @@ export function getRobotAttribute(attribute: Attributes, ce: number, enemyCe: nu
|
||||
return newAttribute;
|
||||
}
|
||||
|
||||
// 计算玩家的属性
|
||||
/**
|
||||
* @description 根据玩家数据获取到他的属性
|
||||
* @param ceAttr hero表的ceAttr
|
||||
* @param globalCeAttr role表中的globalCeAttr
|
||||
*/
|
||||
export function getPlayerAttribute(ceAttr: CeAttr, globalCeAttr: CeAttrRole) {
|
||||
let newAttribute = new CeAttrNumber();
|
||||
for(let attrName in newAttribute) {
|
||||
@@ -529,27 +547,15 @@ export async function generMyRecInfo(heroScores: HeroScores[], winStreakNum: num
|
||||
// 获取对手战报记录
|
||||
export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayers, oppRoleId: string, oppHeroes: pvpEndParamInter[], myLv: number) {
|
||||
let oppHeroRecords = new Array<HeroesRecord>();
|
||||
let oppRole = <PvpHistoryOppType>curOpp.oppDef;
|
||||
if(!oppRole) { /* TODO 判空处理 */ }
|
||||
for (let { hid, damage, heal, underDamage } of oppHeroes) {
|
||||
if (curOpp.isRobot) {
|
||||
let dicHero = gameData.hero.get(hid);
|
||||
let { quality, initialStars: star } = dicHero;
|
||||
oppHeroRecords.push({
|
||||
hid, quality, star, colorStar: 0, lv: 0, damage, heal, underDamage
|
||||
});
|
||||
} else {
|
||||
const myHero = await HeroModel.findByHidAndRole(hid, oppRoleId, 'quality star colorStar lv');
|
||||
let { quality, star, colorStar, lv } = myHero;
|
||||
oppHeroRecords.push({
|
||||
hid, quality, star, colorStar, lv, damage, heal, underDamage
|
||||
});
|
||||
let historyHero = oppRole.heroes.find(cur => cur.actorId == hid);
|
||||
if(historyHero) {
|
||||
let hs = new HeroesRecord(historyHero, damage, heal, underDamage);
|
||||
oppHeroRecords.push(hs);
|
||||
}
|
||||
}
|
||||
let oppRole;
|
||||
if (curOpp.isRobot) {
|
||||
oppRole = { ...curOpp.robot, title: 1, topFiveCe: curOpp.robot.defCe, lv: myLv };
|
||||
} else {
|
||||
oppRole = await RoleModel.findByRoleId(oppRoleId);
|
||||
}
|
||||
return {
|
||||
roleId: oppRole.roleId,
|
||||
roleName: oppRole.roleName,
|
||||
@@ -557,7 +563,7 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayers,
|
||||
sHid: oppRole.sHid,
|
||||
headHid: oppRole.headHid,
|
||||
title: oppRole.title,
|
||||
ce: oppRole.topFiveCe,
|
||||
ce: oppRole.defCe,
|
||||
heroes: oppHeroRecords,
|
||||
isSuccess: !isSuccess,
|
||||
score: 0
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"@typegoose/typegoose": "^7.3.5",
|
||||
"@types/mongoose": "^5.7.36",
|
||||
"bcrypt": "^5.0.0",
|
||||
"chinese-random-name": "^1.0.0",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.27.0",
|
||||
"mongoose": "^5.10.4",
|
||||
|
||||
@@ -1,44 +1,8 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { EXPEDITION_WAR_RECORD_STATUS } from '../consts';
|
||||
import { Enemies } from './generalField'
|
||||
|
||||
class Enemies {
|
||||
@prop({ required: true })
|
||||
actorId: number; // 敌人id
|
||||
@prop({ required: false })
|
||||
actorName: string; // 敌人名
|
||||
@prop({ required: false })
|
||||
dataId: number; // 战场中唯一指向武将的代码
|
||||
@prop({ required: false })
|
||||
relation: number; // 角色属于我方还是地方
|
||||
@prop({ required: false })
|
||||
outIndex: number; // 程序将信息存入数组顺序
|
||||
@prop({ required: false })
|
||||
x: number; // 战场x坐标
|
||||
@prop({ required: false })
|
||||
y: number; // 战场y坐标
|
||||
@prop({ required: false })
|
||||
direction: number; // 朝向
|
||||
@prop({ required: false })
|
||||
var: number; // 变量
|
||||
@prop({ required: false })
|
||||
lv: number; // 角色等级
|
||||
@prop({ required: false })
|
||||
hide: number; // 是否隐藏
|
||||
@prop({ required: false })
|
||||
initial_ai: number; // AI类型
|
||||
@prop({ required: true })
|
||||
attribute: {hp: number, atk: number, matk: number, def: number, mdef: number, agi: number, luk: number, speed: number, hit: number, cri: number, flee: number, antCri: number, damageIncrease: number, damageDecrease: number, defIgnore: number, bloodSuck: number, ap: number}; // 属性
|
||||
@prop({ required: false })
|
||||
skill: string; // 技能
|
||||
@prop({ required: false })
|
||||
seid: string; // 技能
|
||||
@prop({ required: false })
|
||||
star: number; // 角色星级
|
||||
@prop({ required: false })
|
||||
spine: string; // S动画
|
||||
|
||||
}
|
||||
|
||||
class EnemiesCurHPAP {
|
||||
@prop({ required: true })
|
||||
@@ -72,7 +36,7 @@ export default class ExpeditionWarRecord extends BaseModel {
|
||||
@prop({ required: true, default: '' })
|
||||
enemyId: string; // 敌军队伍id或玩家id
|
||||
@prop({ required: true, type: Enemies, default: [], _id: false })
|
||||
enemies: Array<Enemies>; // 敌军数据
|
||||
enemies: Array<Enemies>; // 敌军数据
|
||||
@prop({ required: true, type: EnemiesCurHPAP, default: [], _id: false })
|
||||
enemiesCurHpAp: Array<EnemiesCurHPAP>; // 敌军数据
|
||||
@prop({ required: true, default: 0 })
|
||||
|
||||
@@ -2,8 +2,8 @@ import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
|
||||
import Hero, { } from './Hero';
|
||||
import Role, { } from './Role';
|
||||
import PvpDef, { } from './PvpDefense';
|
||||
import { PVP_PLAYER_POS, PVP_HERO_POS } from '../consts';
|
||||
import PvpHistoryOpp from './PvpHistoryOpp';
|
||||
|
||||
export interface pvpUpdateInter {
|
||||
_id?: string;
|
||||
@@ -91,14 +91,12 @@ export class Robot {
|
||||
export class OppPlayers {
|
||||
@prop({ required: true })
|
||||
roleId: string;
|
||||
@prop({ ref: 'PvpDefense', type: mongoose.Schema.Types.ObjectId })
|
||||
oppDef: Ref<PvpDef>;
|
||||
@prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId })
|
||||
oppDef: Ref<PvpHistoryOpp>;
|
||||
@prop({ required: true })
|
||||
pos: number;
|
||||
@prop({ required: true })
|
||||
isRobot: boolean;
|
||||
@prop({ required: true, type: Robot, default: null, _id: false })
|
||||
robot: Robot
|
||||
}
|
||||
|
||||
export class HeroScores {
|
||||
@@ -136,7 +134,7 @@ export default class PvpDefense extends BaseModel {
|
||||
isDefaultHero: boolean;
|
||||
@prop({ required: true, default: 0 })
|
||||
refOppCnt: number; // 刷新对手总次数,消耗可根据消耗表算出
|
||||
@prop({ required: true, default: 0 })
|
||||
@prop({ required: true, default: new Date() })
|
||||
refOppTime: Date; // 刷新对手时间
|
||||
@prop({ required: true, default: 0 })
|
||||
challengeCnt: number; // 可挑战次数
|
||||
@@ -159,7 +157,7 @@ export default class PvpDefense extends BaseModel {
|
||||
|
||||
public static async findByScale(roleId: string, min: number, max: number, lean = true) {
|
||||
const result: PvpDefenseType[] = await PvpDefenseModel.find({ roleId: { $ne: roleId }, defCe: { $lte: max, $gte: min } })
|
||||
.populate('role', 'headHid sHid topFiveCe roleId roleName')
|
||||
.populate('role', 'headHid sHid topFiveCe roleId roleName lv')
|
||||
.populate('heroes.hero')
|
||||
.sort({ updatedAt: -1 }).limit(100).lean(lean);
|
||||
return result;
|
||||
@@ -203,15 +201,9 @@ export default class PvpDefense extends BaseModel {
|
||||
|
||||
public static async findByRoleIdIncludeAll(roleId: string) {
|
||||
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId })
|
||||
.populate('role', 'headHid sHid topFiveCe roleId roleName')
|
||||
.populate('role', 'headHid sHid topFiveCe roleId roleName lv')
|
||||
.populate('heroes.hero')
|
||||
.populate({
|
||||
path: 'oppPlayers.oppDef',
|
||||
populate: {
|
||||
path: 'role heroes.hero',
|
||||
select: 'headHid sHid topFiveCe roleId roleName hid ceAttr globalCeAttr'
|
||||
}
|
||||
}).lean();
|
||||
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName headHid sHid rankLv pLv defCe heroes').lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -223,13 +215,8 @@ export default class PvpDefense extends BaseModel {
|
||||
public static async updateInfoAndInclude(roleId: string, update: pvpUpdateInter) {
|
||||
delete update._id;
|
||||
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
|
||||
.populate({
|
||||
path: 'oppPlayers.oppDef',
|
||||
populate: {
|
||||
path: 'role',
|
||||
select: 'headHid sHid topFiveCe roleId roleName'
|
||||
}
|
||||
}).lean();
|
||||
.populate('role', 'headHid sHid topFiveCe roleId roleName lv')
|
||||
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName headHid sHid rankLv pLv defCe').lean();
|
||||
return result;
|
||||
}
|
||||
public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) {
|
||||
|
||||
67
shared/db/PvpHistoryOpp.ts
Normal file
67
shared/db/PvpHistoryOpp.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
|
||||
import { PvpEnemies } from './generalField';
|
||||
|
||||
export class HeroScores {
|
||||
@prop({ required: true })
|
||||
hid: number;
|
||||
@prop({ required: true })
|
||||
score: number;
|
||||
}
|
||||
|
||||
@index({ roleId: 1 })
|
||||
export default class PvpHistoryOpp extends BaseModel {
|
||||
@prop({ required: true })
|
||||
roleId: string; // 玩家id
|
||||
@prop({ required: true })
|
||||
pos: number; // 对手位置
|
||||
@prop({ required: true })
|
||||
oppRoleId: string; // 对手角色 id
|
||||
@prop({ required: true })
|
||||
roleName: string; // 角色名称
|
||||
@prop({ required: true, default: 19 })
|
||||
headHid: number; // 对手头像
|
||||
@prop({ required: true, default: 19 })
|
||||
sHid: number; // 对手形象
|
||||
@prop({ required: true, default: 0 })
|
||||
score: number; // 对手军功
|
||||
@prop({ required: true, default: 1 })
|
||||
pLv: number; // 对手等级
|
||||
@prop({ required: true, default: 1 })
|
||||
lv: number; // 对手角色等级
|
||||
@prop({ required: true, default: 1 })
|
||||
title: number; // 对手等级
|
||||
@prop({ required: true, default: 0 })
|
||||
defCe: number; // 防守战力
|
||||
@prop({ required: true, default: 0 })
|
||||
rankLv: number; // 对手排名
|
||||
@prop({ required: true, type: PvpEnemies, default: [] })
|
||||
heroes: PvpEnemies[]; // 对手阵容
|
||||
@prop({ required: true, default: 0 })
|
||||
status: number; // 状态 0-仅刷出 1-挑战过
|
||||
|
||||
public static async createPvpOpp(params: PvpOppCreateParam, lean = true) {
|
||||
const doc = new PvpHistoryOppModel();
|
||||
const update = Object.assign(doc.toJSON(), params);
|
||||
delete update._id;
|
||||
const defense: PvpHistoryOppType = await PvpHistoryOppModel.findOneAndUpdate({ roleId: params.roleId, pos: params.pos }, update, { upsert: true, new: true }).lean(lean);
|
||||
return defense;
|
||||
}
|
||||
|
||||
public static async findByRoleIdAndOppId(roleId: string, oppRoleId: string) {
|
||||
const result: PvpHistoryOppType = await PvpHistoryOppModel.findOne({ roleId, oppRoleId, status: 0 }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async setStatus(roleId: string, oppRoleId: string, status: number) {
|
||||
const result: PvpHistoryOppType = await PvpHistoryOppModel.findOneAndUpdate({ roleId, oppRoleId }, {status}, {new: true}).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const PvpHistoryOppModel = getModelForClass(PvpHistoryOpp);
|
||||
|
||||
export interface PvpHistoryOppType extends Pick<DocumentType<PvpHistoryOpp>, keyof PvpHistoryOpp> { };
|
||||
export type PvpOppCreateParam = Partial<PvpHistoryOppType>; // 将所有字段变成可选项
|
||||
@@ -2,6 +2,7 @@ import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { getBeforeDayDate } from '../pubUtils/timeUtil';
|
||||
import { genCode } from '../pubUtils/util';
|
||||
import { PvpHeroInfo } from './generalField';
|
||||
|
||||
export class HeroesRecord {
|
||||
@prop({ required: true, default: 0 })
|
||||
@@ -20,6 +21,17 @@ export class HeroesRecord {
|
||||
heal: number; // 治疗
|
||||
@prop({ required: true, default: 0 })
|
||||
underDamage: number; // 承伤
|
||||
|
||||
constructor(pvpHero: PvpHeroInfo, damage: number, heal: number, underDamage: number) {
|
||||
this.hid = pvpHero.actorId;
|
||||
this.quality = pvpHero.quality;
|
||||
this.star = pvpHero.star;
|
||||
this.colorStar = pvpHero.colorStar;
|
||||
this.lv = pvpHero.lv;
|
||||
this.damage = damage;
|
||||
this.heal = heal;
|
||||
this.underDamage = underDamage;
|
||||
}
|
||||
}
|
||||
|
||||
export class PlayerInfo {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { prop } from '@typegoose/typegoose';
|
||||
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
|
||||
import { HeroType } from './Hero';
|
||||
|
||||
export class CeAttrData {
|
||||
@prop({ required: true })
|
||||
@@ -120,3 +122,125 @@ export class CeAttrNumber {
|
||||
bloodSuck?: number = 0;
|
||||
}
|
||||
|
||||
// 从玩家数据中覆盖warjson的部分字段
|
||||
export class PvpHeroInfo {
|
||||
@prop({ required: true })
|
||||
actorId?: number = 0; // 敌人id
|
||||
@prop({ required: false })
|
||||
actorName?: string = ""; // 敌人名
|
||||
@prop({ required: false })
|
||||
outIndex?: number = 0; // 程序将信息存入数组顺序
|
||||
@prop({ required: false })
|
||||
star?: number = 0; // 角色星级
|
||||
@prop({ required: false })
|
||||
lv?: number = 0; // 角色等级
|
||||
@prop({ required: false })
|
||||
skill?: string = "0"; // 技能
|
||||
@prop({ required: false })
|
||||
seid?: string = "&"; // 技能
|
||||
@prop({ required: false })
|
||||
spine?: string = "0"; // S动画
|
||||
@prop({ required: false })
|
||||
colorStar?: number = 0; // 觉醒
|
||||
@prop({ required: false })
|
||||
quality?: number = 0; // 品质
|
||||
|
||||
@prop({ required: true, _id: false, default: new CeAttrNumber() })
|
||||
attribute?: CeAttrNumber; // 属性
|
||||
|
||||
setHeroInfo(hero: HeroType) {
|
||||
this.actorId = hero.hid;
|
||||
this.actorName = hero.hName;
|
||||
this.star = hero.star;
|
||||
this.lv = hero.lv;
|
||||
this.colorStar = hero.colorStar;
|
||||
this.quality = hero.quality;
|
||||
}
|
||||
|
||||
setRobotInfo(warjson: DicWarJson, lv: number, initialStar: number, quality: number) {
|
||||
this.actorId = warjson.actorId;
|
||||
this.actorName = warjson.actorName;
|
||||
this.star = initialStar;
|
||||
this.lv = lv;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
setAttribute(attribute: CeAttrNumber) {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
setOutIndex(order: number) {
|
||||
this.outIndex = order;
|
||||
}
|
||||
}
|
||||
|
||||
// 远征敌军
|
||||
export class Enemies extends PvpHeroInfo {
|
||||
@prop({ required: true })
|
||||
actorId: number; // 敌人id
|
||||
@prop({ required: false })
|
||||
actorName: string; // 敌人名
|
||||
@prop({ required: false })
|
||||
dataId: number; // 战场中唯一指向武将的代码
|
||||
@prop({ required: false })
|
||||
relation: number; // 角色属于我方还是地方
|
||||
@prop({ required: false })
|
||||
x: number; // 战场x坐标
|
||||
@prop({ required: false })
|
||||
y: number; // 战场y坐标
|
||||
@prop({ required: false })
|
||||
direction: number; // 朝向
|
||||
@prop({ required: false })
|
||||
var: number; // 变量
|
||||
@prop({ required: false })
|
||||
hide: number; // 是否隐藏
|
||||
@prop({ required: false })
|
||||
initial_ai: number; // AI类型
|
||||
|
||||
// warjson 出兵表
|
||||
// heroInfo 覆盖掉出兵表的相应参数
|
||||
constructor(warjson: DicWarJson, heroInfo: PvpHeroInfo) {
|
||||
super();
|
||||
this.actorId = heroInfo.actorId != undefined? heroInfo.actorId: warjson.actorId;
|
||||
this.actorName = heroInfo.actorName != undefined? heroInfo.actorName: warjson.actorName;
|
||||
this.dataId = warjson.dataId;
|
||||
this.relation = warjson.relation;
|
||||
this.outIndex = heroInfo.outIndex != undefined? heroInfo.outIndex: warjson.outIndex;
|
||||
this.x = warjson.x;
|
||||
this.y = warjson.y;
|
||||
this.direction = warjson.direction;
|
||||
this.var = warjson.var;
|
||||
this.lv = heroInfo.lv != undefined? heroInfo.lv: warjson.lv;
|
||||
this.hide = warjson.hide;
|
||||
this.initial_ai = warjson.initial_ai;
|
||||
this.attribute = heroInfo.attribute;
|
||||
this.skill = heroInfo.skill != undefined? heroInfo.skill: warjson.skill;
|
||||
this.seid = heroInfo.seid != undefined? heroInfo.seid: warjson.seid;
|
||||
this.star = heroInfo.star != undefined? heroInfo.star: warjson.star;
|
||||
this.spine = heroInfo.spine!= undefined? heroInfo.spine: warjson.spine;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class PvpEnemies extends Enemies {
|
||||
@prop({ required: true })
|
||||
star: number;
|
||||
@prop({ required: true })
|
||||
colorStar: number;
|
||||
@prop({ required: true })
|
||||
quality: number;
|
||||
@prop({ required: true })
|
||||
lv: number;
|
||||
@prop({ required: true })
|
||||
score: number;
|
||||
|
||||
// score: 这个武将的军功
|
||||
constructor(warjson: DicWarJson, heroInfo: PvpHeroInfo, score: number) {
|
||||
super(warjson, heroInfo);
|
||||
this.star = heroInfo.star;
|
||||
this.colorStar = heroInfo.colorStar;
|
||||
this.quality = heroInfo.quality;
|
||||
this.lv = heroInfo.lv;
|
||||
this.score = score;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import { RoleType } from "../db/Role";
|
||||
import { Robot } from "../db/PvpDefense";
|
||||
import { reduceCe } from "./util";
|
||||
import { PvpHeroInfo, PvpEnemies } from "../db/generalField";
|
||||
|
||||
export interface RewardInter {
|
||||
id: number;
|
||||
@@ -121,13 +122,22 @@ export class RankParam {
|
||||
}
|
||||
}
|
||||
|
||||
export interface PlayerDetailHero {
|
||||
export class PlayerDetailHero {
|
||||
actorId: number;
|
||||
lv: number;
|
||||
star: number;
|
||||
colorStar: number;
|
||||
quality: number;
|
||||
score: number;
|
||||
|
||||
setPvpHeroInfo?(hero: PvpEnemies) {
|
||||
this.actorId = hero.actorId;
|
||||
this.lv = hero.lv;
|
||||
this.star = hero.star;
|
||||
this.colorStar = hero.colorStar;
|
||||
this.quality = hero.quality;
|
||||
this.score = hero.score;
|
||||
}
|
||||
}
|
||||
|
||||
export class PlayerDetail {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
|
||||
import { HERO_CE_RATIO, ABI_STAGE } from '../consts';
|
||||
|
||||
import { findIndex } from 'underscore';
|
||||
|
||||
const randomName = require("chinese-random-name");
|
||||
const moment = require('moment');
|
||||
|
||||
export function genCode(len) {
|
||||
@@ -516,3 +516,7 @@ export function getAllAttrStage() {
|
||||
};
|
||||
return attrs;
|
||||
}
|
||||
|
||||
export function getChineseName() {
|
||||
return randomName.generate()
|
||||
}
|
||||
Reference in New Issue
Block a user