adminindex.js 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. const path = require('./path.json');
  2. const readline = require('readline');
  3. const fs = require('fs');
  4. const xl = require('xlsx');
  5. let excelDir = './excel'; // excel配置表目录
  6. let outDir = './out'; // 导出目录
  7. let outJsonFolder = 'excel'; // 导出的json目录
  8. //前端需要在load界面加载的表
  9. let loadJson = ["audioInfo", "languageLang", "languageClientText", "mathInfo", "packageInfo"]
  10. const cluster = require('cluster');
  11. //后端配置
  12. let serverPath = "./common/"
  13. let apiurl = "../zhetian_backend_kaifa/public/api/assets/main.bundle.js"
  14. // 前后端解析索引的行
  15. let hang = 3; // 前端3 后端4
  16. // 表格列表 example: ["iconopen","mainTask"]
  17. let excelFiles = [];
  18. // 表名 +分表名
  19. let excelFen = [];
  20. // 表格与表单的数据类型 example:{iconopen:{id:string}}
  21. let excelAndSheets = {};
  22. var s_xls = require('./s_xls');
  23. const { exit } = require('process');
  24. // 检测传入的参数
  25. var args = process.argv.splice(2)
  26. var jiexiTarget = args[0] || "" // s:后端 c:前端
  27. function exeExcelConfig_c() {
  28. let str = '';
  29. str += `import GameController from "../GameController"\nimport { gameMethod } from "./gameMethod"\n`
  30. // 添加类型定义
  31. excelFiles.forEach((excelName) => {
  32. str += `// type for ${excelName}.excel\n`;
  33. for (const sheetName in excelAndSheets[excelName]) {
  34. str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
  35. //遍历索引存入类型定义
  36. let keyObjList = excelAndSheets[excelName][sheetName];
  37. for (const key in keyObjList) {
  38. str += `${key.split(',')[0]}:${keyObjList[key].value},`;
  39. }
  40. // 去掉最后一个逗号 ","
  41. if (str.charAt(str.length - 1) == ',') {
  42. str = str.substring(0, str.length - 1);
  43. }
  44. str += '}';
  45. str += '\n';
  46. }
  47. });
  48. str += '\n';
  49. //导出
  50. str += `export class XlsConfig {\n`;
  51. excelFen.forEach((element) => {
  52. str += ` xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
  53. });
  54. // str += ` constructor(callback: Function) {\n`
  55. // let str111 = [];
  56. // excelFen.forEach((element) => {
  57. // str111.push('"' + element + '"');
  58. // });
  59. // str += ` }\n`
  60. str += `
  61. constructor(bundleName:string, callback: Function) {
  62. cc.assetManager.loadBundle(bundleName, (err, bundle) => {
  63. if (err) {
  64. GameController.clear()
  65. cc.game.restart()
  66. return
  67. }
  68. if (gameMethod.isEmpty(bundle) && cc.sys.platform == cc.sys.WECHAT_GAME) {
  69. //小游戏平台,缓存过期,自动清理缓存,重启游戏
  70. console.error("加载配置表的bundle失败,清理缓存重新加载")
  71. cc.assetManager.cacheManager.clearCache()
  72. GameController.clear()
  73. cc.game.restart()
  74. return
  75. }
  76. bundle.loadDir("", (err2, assets: cc.JsonAsset[]) => {
  77. if (err2) {
  78. GameController.clear()
  79. cc.game.restart()
  80. return
  81. }
  82. assets.forEach(element => {
  83. this["xls" + this.firstUpCase(element.name)] = element.json
  84. });
  85. callback(this)
  86. })
  87. })
  88. }
  89. // 首字母大写
  90. private firstUpCase(str: string) {
  91. return str[0].toUpperCase() + str.substring(1)
  92. }
  93. }`;
  94. if (hang == 3) {
  95. outDir = path.configPath;
  96. } else {
  97. outDir = serverPath;
  98. }
  99. // 写入文件
  100. let outPath = `${outDir}xlsConfig.ts`;
  101. fs.writeFile(outPath, str, function (err) {
  102. if (err) {
  103. console.log('xlsConfig写入失败:', err);
  104. }
  105. });
  106. let pro = '';
  107. if (hang == 4) {
  108. pro += 'import { CTX } from "../src/util/master";\n';
  109. }
  110. pro += `export default class ConfProxy<T> {
  111. static getKey(args: string[]): string {
  112. let out = ""
  113. args.forEach(element => {
  114. out += element
  115. out += "_"
  116. });
  117. return out
  118. }
  119. static setKey(target: any, args: string[]): string {
  120. let out = ""
  121. args.forEach(element => {
  122. out += target[element]
  123. out += "_"
  124. });
  125. return out
  126. }
  127. pool: { [key: string]: T } = {}
  128. name:string = ""
  129. constructor(xlsname:string,conf: T[], ...args: string[]) {
  130. this.name = xlsname
  131. conf.forEach(element => {
  132. this.pool[ConfProxy.setKey(element, args)] = element
  133. });
  134. }
  135. getItem(...args: string[]): T | null {
  136. return this.pool[ConfProxy.getKey(args)]
  137. }`;
  138. if (hang == 4) {
  139. pro += `
  140. getItemCtx(ctx:CTX,...args: string[]): T {
  141. let back = this.pool[ConfProxy.getKey(args)]
  142. if(back == null){
  143. console.error("配置错误"+args,this.name)
  144. ctx.throw("配置错误"+args)
  145. }
  146. return back
  147. }
  148. `;
  149. }
  150. pro += `
  151. }
  152. export class ConfListProxy<T> {
  153. pool: { [key: string]: T[] } = {}
  154. name:string = ""
  155. constructor(xlsname:string,conf: T[], ...args: string[]) {
  156. this.name = xlsname
  157. conf.forEach(element => {
  158. let key = ConfProxy.setKey(element, args)
  159. if (this.pool[key] == null) {
  160. this.pool[key] = []
  161. }
  162. this.pool[key].push(element)
  163. });
  164. }
  165. getItemList(...args: string[]): T[] | null {
  166. return this.pool[ConfProxy.getKey(args)]
  167. }
  168. }`;
  169. pro += '\n';
  170. // 写入文件
  171. let proPath = '';
  172. if (hang == 3) {
  173. proPath = `${path.configPath}confProxy.ts`;
  174. } else {
  175. proPath = serverPath + `confProxy.ts`;
  176. }
  177. fs.writeFile(proPath, pro, function (err) {
  178. if (err) {
  179. console.log('ConfProxy写入失败:', err);
  180. }
  181. });
  182. }
  183. function exeExcelConfig() {
  184. let str = '';
  185. // 引入ts文件
  186. excelFen.forEach((element) => {
  187. str += `const ${element} = require( "./excel/${element}.json")\n`;
  188. });
  189. str += '\n';
  190. // 添加类型定义
  191. excelFiles.forEach((excelName) => {
  192. str += `// type for ${excelName}.excel\n`;
  193. for (const sheetName in excelAndSheets[excelName]) {
  194. str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
  195. //遍历索引存入类型定义
  196. let keyObjList = excelAndSheets[excelName][sheetName];
  197. for (const key in keyObjList) {
  198. str += `${key.split(',')[0]}:${keyObjList[key].value},`;
  199. }
  200. // 去掉最后一个逗号 ","
  201. if (str.charAt(str.length - 1) == ',') {
  202. str = str.substring(0, str.length - 1);
  203. }
  204. str += '}';
  205. str += '\n';
  206. }
  207. });
  208. str += '\n';
  209. //导出
  210. str += `export class XlsConfig {\n`;
  211. excelFen.forEach((element) => {
  212. str += ` xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
  213. });
  214. str += ` constructor() {\n`;
  215. excelFen.forEach((element) => {
  216. str += ` this.xls${toUpperCaseByStr(element)} = <xls${toUpperCaseByStr(element)}[]>${element}\n`;
  217. });
  218. str += ` }\n`;
  219. str += '}\n';
  220. if (hang == 3) {
  221. outDir = path.configPath;
  222. } else {
  223. outDir = serverPath
  224. }
  225. // 写入文件
  226. let outPath = `${outDir}xlsConfig.ts`;
  227. fs.writeFile(outPath, str, function (err) {
  228. if (err) {
  229. console.log('xlsConfig写入失败:', err);
  230. }
  231. });
  232. let pro = '';
  233. if (hang == 4) {
  234. pro += 'import { CTX } from "../src/util/master";\n';
  235. }
  236. pro += `export default class ConfProxy<T> {
  237. static getKey(args: string[]): string {
  238. let out = ""
  239. args.forEach(element => {
  240. out += element
  241. out += "_"
  242. });
  243. return out
  244. }
  245. static setKey(target: any, args: string[]): string {
  246. let out = ""
  247. args.forEach(element => {
  248. out += target[element]
  249. out += "_"
  250. });
  251. return out
  252. }
  253. pool: { [key: string]: T } = {}
  254. name:string = ""
  255. constructor(xlsname:string,conf: T[], ...args: string[]) {
  256. this.name = xlsname
  257. conf.forEach(element => {
  258. this.pool[ConfProxy.setKey(element, args)] = element
  259. });
  260. }
  261. getItem(...args: string[]): T | null {
  262. return this.pool[ConfProxy.getKey(args)]
  263. }`;
  264. if (hang == 4) {
  265. pro += `
  266. getItemCtx(ctx:CTX,...args: string[]): T {
  267. let back = this.pool[ConfProxy.getKey(args)]
  268. if(back == null){
  269. console.error("配置错误"+args,this.name)
  270. ctx.throw("配置错误"+args)
  271. }
  272. return back
  273. }
  274. `;
  275. }
  276. pro += `
  277. }
  278. export class ConfListProxy<T> {
  279. pool: { [key: string]: T[] } = {}
  280. name:string = ""
  281. constructor(xlsname:string,conf: T[], ...args: string[]) {
  282. this.name = xlsname
  283. conf.forEach(element => {
  284. let key = ConfProxy.setKey(element, args)
  285. if (this.pool[key] == null) {
  286. this.pool[key] = []
  287. }
  288. this.pool[key].push(element)
  289. });
  290. }
  291. getItemList(...args: string[]): T[] | null {
  292. return this.pool[ConfProxy.getKey(args)]
  293. }`;
  294. if (hang == 4) {
  295. pro += `
  296. getItemListCtx(ctx:CTX,...args: string[]): T[] {
  297. let back = this.pool[ConfProxy.getKey(args)]
  298. if(back == null){
  299. console.error("list配置错误"+args,this.name)
  300. ctx.throw("list配置错误"+args)
  301. }
  302. return back
  303. }
  304. `;
  305. }
  306. pro += `
  307. }
  308. `
  309. pro += '\n';
  310. // 写入文件
  311. let proPath = '';
  312. if (hang == 3) {
  313. proPath = `${path.configPath}confProxy.ts`;
  314. } else {
  315. proPath = serverPath + `confProxy.ts`;
  316. }
  317. fs.writeFile(proPath, pro, function (err) {
  318. if (err) {
  319. console.log('ConfProxy写入失败:', err);
  320. }
  321. });
  322. }
  323. // 字符串开头变为大写
  324. function toUpperCaseByStr(txt) {
  325. return txt.slice(0, 1).toUpperCase() + txt.slice(1);
  326. }
  327. // 分析配置表
  328. function doExcel(excel) {
  329. let excelName = excel.split('_')[0];
  330. if (s_xls.XlsBack[excelName] == null) {
  331. return
  332. }
  333. let fileDir = `${excelDir}/${excel}`;
  334. let workbook = xl.readFile(fileDir);
  335. // 获取 Excel 中所有表名
  336. const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']
  337. let _sheetNames = [];
  338. for (const element of sheetNames) {
  339. if (s_xls.XlsBack[excelName][element] == null) {
  340. continue
  341. }
  342. _sheetNames.push(element);
  343. }
  344. if (_sheetNames.length == 0) {
  345. return;
  346. }
  347. console.time("...start excel " + excel)
  348. // 加到【excelAndSheets】中
  349. let obj = {};
  350. excelAndSheets[excelName] = {};
  351. _sheetNames.forEach((sheetName) => {
  352. let sheet = workbook.Sheets[sheetName];
  353. excelAndSheets[excelName][sheetName] = {};
  354. doSheet(obj, excelName, sheetName, sheet);
  355. });
  356. let outDir1 = ""
  357. let outDir2 = ""
  358. if (hang == 3) {
  359. outDir1 = `${path.jsonPath}`;
  360. if (!fs.existsSync(outDir1)) {
  361. fs.mkdirSync(outDir1)
  362. }
  363. outDir2 = `${path.loadJsonPath}`;
  364. if (!fs.existsSync(outDir2)) {
  365. fs.mkdirSync(outDir2)
  366. }
  367. } else {
  368. outDir1 = serverPath + `${outJsonFolder}`;
  369. if (!fs.existsSync(outDir1)) {
  370. fs.mkdirSync(outDir1)
  371. }
  372. }
  373. for (const key in obj) {
  374. let jsonStr = `${geshihua(obj[key])}`;
  375. if (outDir2 != "" && loadJson.indexOf(key) >= 0) {
  376. fs.writeFileSync(`${outDir2}/${key}.json`, jsonStr, function (err) {
  377. if (err) {
  378. console.log(err);
  379. }
  380. });
  381. } else {
  382. fs.writeFileSync(`${outDir1}/${key}.json`, jsonStr, function (err) {
  383. if (err) {
  384. console.log(err);
  385. }
  386. });
  387. }
  388. }
  389. console.timeEnd("...start excel " + excel)
  390. }
  391. function geshihua(data) {
  392. let count = 1;
  393. let _data = '[\n';
  394. for (const val of data) {
  395. if (count == 1) {
  396. _data += ' ' + JSON.stringify(val);
  397. } else {
  398. _data += `,\n`;
  399. _data += ' ' + JSON.stringify(val);
  400. }
  401. count++;
  402. }
  403. _data += '\n]';
  404. return _data;
  405. }
  406. //分析表单 obj数据,表名,表单名,表单数据内容
  407. function doSheet(obj, excelName, sheetName, sheet) {
  408. let newKey = excelName + toUpperCaseByStr(sheetName);
  409. excelFen.push(newKey);
  410. if (obj[newKey] == null) {
  411. obj[newKey] = [];
  412. }
  413. // 索引列表 example:{A:"",B:"id",C:"hp",D:"attack"}
  414. let keyList = {};
  415. // 类型列表 example:{A:"number",B:"string",C:"boolean",D:"{}[]"}
  416. let typeList = {};
  417. //备注
  418. let psList = {};
  419. let _tempObj = {};
  420. for (const key in sheet) {
  421. // 单元格定位id example: A25
  422. const sheetKey = sheet[key];
  423. // A25->25
  424. let _hang = key.replace(/[^0-9]+/gi, '');
  425. // A25->A
  426. let _lie = key.replace(/[^A-Z]+/gi, '');
  427. if (_lie == 'A') {
  428. if (Object.keys(_tempObj).length > 0) {
  429. //这边检测是否有放空配置的。如果有 , 补上默认类型
  430. let _tempObj_1 = {};
  431. for (const key in keyList) {
  432. if (_tempObj[keyList[key]] == null) {
  433. if (typeList[key] == 'number') {
  434. _tempObj_1[keyList[key]] = 0;
  435. } else if (typeList[key] == 'string') {
  436. _tempObj_1[keyList[key]] = '';
  437. } else if (typeList[key] == 'boolean') {
  438. _tempObj_1[keyList[key]] = false;
  439. } else if (typeList[key].indexOf('[]') != -1) {
  440. _tempObj_1[keyList[key]] = null;
  441. } else if (typeList[key].substring(0, 0 + 1) == '{') {
  442. _tempObj_1[keyList[key]] = null;
  443. } else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
  444. _tempObj_1[keyList[key]] = null;
  445. } else {
  446. console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
  447. }
  448. } else {
  449. _tempObj_1[keyList[key]] = _tempObj[keyList[key]];
  450. }
  451. }
  452. obj[newKey].push(_tempObj_1);
  453. _tempObj = {};
  454. }
  455. }
  456. if (sheet['A' + _hang] == null) {
  457. // 第一列没有配置参数,就跳过
  458. continue;
  459. }
  460. if (_hang == 1) {
  461. psList[_lie] = sheetKey.v;
  462. }
  463. // 储存类型
  464. if (_hang == 2) {
  465. typeList[_lie] = sheetKey.v;
  466. }
  467. // 储存索引
  468. if (_hang == hang && sheetKey.v && typeList[_lie]) {
  469. // 正则抽取真正的值(去掉所有的*)
  470. let realVal = sheetKey.v.replace(/[\*]/g, '');
  471. // 判断下作为key的字段
  472. let isKey = 0; // 0:不是key,1:单key,2:列表key
  473. if (sheetKey.v.slice(0, 2) == '**') {
  474. isKey = 2;
  475. } else if (sheetKey.v.slice(0, 1) == '*') {
  476. isKey = 1;
  477. }
  478. keyList[_lie] = realVal.split(',')[0].trim();
  479. // id:string
  480. excelAndSheets[excelName][sheetName][keyList[_lie]] = {
  481. ps: psList[_lie],
  482. isKey: isKey,
  483. value: typeList[_lie],
  484. keys: realVal
  485. };
  486. }
  487. // 储存数据
  488. if (_hang >= 5 && keyList[_lie] != null && typeList[_lie] != null) {
  489. // 根据类型转化数据内容,在做储存处理
  490. let _val;
  491. if (typeList[_lie] == 'number') {
  492. if (typeof sheetKey.v != 'number') {
  493. _val = Number(sheetKey.v);
  494. if (isNaN(_val)) {
  495. console.log(
  496. '\x1b[33m%s\x1b[0m',
  497. '警告,出现NaN数据类型,表名:' +
  498. excelName +
  499. ' 表单:' +
  500. sheetName +
  501. ' 索引:' +
  502. keyList[_lie] +
  503. ' 表格ID:' +
  504. key
  505. );
  506. }
  507. _val = 0;
  508. } else {
  509. _val = sheetKey.v;
  510. }
  511. } else if (typeList[_lie] == 'boolean') {
  512. if (sheetKey.v == 'true' || sheetKey.v == 'TRUE' || sheetKey.v == true) {
  513. _val = true;
  514. } else {
  515. _val = false;
  516. }
  517. } else if (typeList[_lie][0] == '{' || typeList[_lie].slice(-1) == ']') {
  518. try {
  519. _val = JSON.parse(sheetKey.v);
  520. } catch (error) {
  521. console.log(
  522. '\x1b[33m%s\x1b[0m',
  523. '警告:json格式错误,表名:' + excelName + ' 表单:' + sheetName + ' 索引:' + keyList[_lie] + ' 表格ID:' + key
  524. );
  525. }
  526. } else if (typeList[_lie] == 'string') {
  527. if (typeof sheetKey.v == 'number') {
  528. _val = Math.floor(sheetKey.v).toString();
  529. } else {
  530. _val = sheetKey.v;
  531. }
  532. } else {
  533. _val = sheetKey.v;
  534. }
  535. _tempObj[keyList[_lie].trim()] = _val;
  536. }
  537. }
  538. //这边检测是否有放空配置的。如果有 , 补上默认类型
  539. let _tempObj_1 = {};
  540. for (const key in keyList) {
  541. if (_tempObj[keyList[key]] == null) {
  542. if (typeList[key] == 'number') {
  543. _tempObj_1[keyList[key]] = 0;
  544. } else if (typeList[key] == 'string') {
  545. _tempObj_1[keyList[key]] = '';
  546. } else if (typeList[key] == 'boolean') {
  547. _tempObj_1[keyList[key]] = false;
  548. } else if (typeList[key].indexOf('[]') != -1) {
  549. _tempObj_1[keyList[key]] = null;
  550. } else if (typeList[key].substring(0, 0 + 1) == '{') {
  551. _tempObj_1[keyList[key]] = null;
  552. } else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
  553. _tempObj_1[keyList[key]] = null;
  554. } else {
  555. console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
  556. }
  557. } else {
  558. _tempObj_1[keyList[key]] = _tempObj[keyList[key]];
  559. }
  560. }
  561. // 储存最后一个
  562. obj[newKey].push(_tempObj_1);
  563. }
  564. // //--------------------start------------------- 控制台人机交互
  565. function readSyncByRl(tips) {
  566. tips = tips || '> ';
  567. return new Promise((resolve) => {
  568. const rl = readline.createInterface({
  569. input: process.stdin,
  570. output: process.stdout
  571. });
  572. rl.question(tips, (answer) => {
  573. rl.close();
  574. resolve(answer.trim());
  575. });
  576. });
  577. }
  578. /**
  579. * 后端创建xls对应gameCfg完成脚本
  580. */
  581. function createGameCfg_s() {
  582. let strs = '';
  583. strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
  584. let strHead = `XlsConfig`;
  585. let count = 2;
  586. for (const key1 in s_xls.XlsBack) {
  587. for (const key2 in s_xls.XlsBack[key1]) {
  588. if (s_xls.XlsBack[key1][key2].length <= 0) {
  589. continue;
  590. }
  591. strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
  592. count++;
  593. if (count % 9 == 0) {
  594. strHead += `\n`;
  595. }
  596. }
  597. }
  598. strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
  599. strs += `export default class Gamecfg {\n`;
  600. strs += ` static init() {\n`;
  601. strs += ` let xls = new XlsConfig()\n`;
  602. for (const key1 in s_xls.XlsBack) {
  603. for (const key2 in s_xls.XlsBack[key1]) {
  604. if (s_xls.XlsBack[key1][key2].length <= 0) {
  605. continue;
  606. }
  607. for (const val of s_xls.XlsBack[key1][key2]) {
  608. let cs = ``;
  609. for (let index = 1; index < val.length; index++) {
  610. cs += `,"${val[index]}"`;
  611. }
  612. if (val[0] == 'ConfProxy') {
  613. strs += ` Gamecfg.${key1}${toUpperCaseByStr(key2)} = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  614. continue;
  615. }
  616. if (val[0] == 'ConfListProxy') {
  617. strs += ` Gamecfg.${key1}${toUpperCaseByStr(key2)}List = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}List",xls.xls${toUpperCaseByStr(
  618. key1
  619. )}${toUpperCaseByStr(key2)} ${cs})\n`;
  620. continue;
  621. }
  622. let cs1 = ``;
  623. for (let index = 2; index < val.length; index++) {
  624. cs1 += `,"${val[index]}"`;
  625. }
  626. //别名
  627. if (val[1] == 'ConfProxy') {
  628. strs += ` Gamecfg.${key1}${toUpperCaseByStr(val[0])} = new ${val[1]}("${key1}${toUpperCaseByStr(val[0])}",xls.xls${toUpperCaseByStr(
  629. key1
  630. )}${toUpperCaseByStr(key2)} ${cs1})\n`;
  631. continue;
  632. }
  633. if (val[1] == 'ConfListProxy') {
  634. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  635. val[0]
  636. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  637. val[0]
  638. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  639. continue;
  640. }
  641. }
  642. }
  643. }
  644. strs += ` }\n`;
  645. for (const key1 in s_xls.XlsBack) {
  646. for (const key2 in s_xls.XlsBack[key1]) {
  647. if (s_xls.XlsBack[key1][key2].length <= 0) {
  648. continue;
  649. }
  650. for (const val of s_xls.XlsBack[key1][key2]) {
  651. if (val[0] == 'ConfProxy') {
  652. strs += ` static ${key1}${toUpperCaseByStr(key2)} : ${val[0]}<xls${toUpperCaseByStr(
  653. key1
  654. )}${toUpperCaseByStr(key2)} >\n`;
  655. continue;
  656. }
  657. if (val[0] == 'ConfListProxy') {
  658. strs += ` static ${key1}${toUpperCaseByStr(key2)}List : ${val[0]}<xls${toUpperCaseByStr(
  659. key1
  660. )}${toUpperCaseByStr(key2)}>\n`;
  661. continue;
  662. }
  663. //别名
  664. if (val[1] == 'ConfProxy') {
  665. strs += ` static ${key1}${toUpperCaseByStr(val[0])} : ${val[1]}<xls${toUpperCaseByStr(
  666. key1
  667. )}${toUpperCaseByStr(key2)}>\n`;
  668. continue;
  669. }
  670. if (val[1] == 'ConfListProxy') {
  671. strs += ` static ${key1}${toUpperCaseByStr(
  672. val[0]
  673. )}List : ${val[1]}<xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}>\n`;
  674. continue;
  675. }
  676. }
  677. }
  678. }
  679. strs += `}\n`;
  680. // 写入文件
  681. let proPath = '';
  682. if (hang == 3) {
  683. proPath = `${path.configPath}gameCfg.ts`;
  684. } else {
  685. proPath = serverPath + `gameCfg.ts`;
  686. }
  687. fs.writeFile(proPath, strs, function (err) {
  688. if (err) {
  689. console.log('gameCfg写入失败:', err);
  690. }
  691. });
  692. }
  693. /**
  694. * 前端创建xls对应gameCfg完成脚本
  695. */
  696. function createGameCfg_c() {
  697. let strs = '';
  698. strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
  699. let strHead = `XlsConfig`;
  700. let count = 2;
  701. for (const key1 in s_xls.XlsBack) {
  702. for (const key2 in s_xls.XlsBack[key1]) {
  703. if (s_xls.XlsBack[key1][key2].length <= 0) {
  704. continue;
  705. }
  706. strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
  707. count++;
  708. if (count % 9 == 0) {
  709. strHead += `\n`;
  710. }
  711. }
  712. }
  713. strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
  714. strs += `export default class Gamecfg {\n`;
  715. for (const key1 in s_xls.XlsBack) {
  716. for (const key2 in s_xls.XlsBack[key1]) {
  717. if (s_xls.XlsBack[key1][key2].length <= 0) {
  718. continue;
  719. }
  720. for (const val of s_xls.XlsBack[key1][key2]) {
  721. if (val[0] == 'ConfProxy') {
  722. strs += ` static ${key1}${toUpperCaseByStr(key2)}:${val[0]}<xls${toUpperCaseByStr(
  723. key1
  724. )}${toUpperCaseByStr(key2)}>\n`;
  725. continue;
  726. }
  727. if (val[0] == 'ConfListProxy') {
  728. strs += ` static ${key1}${toUpperCaseByStr(key2)}List:${val[0]}<xls${toUpperCaseByStr(
  729. key1
  730. )}${toUpperCaseByStr(key2)}>\n`;
  731. continue;
  732. }
  733. //别名
  734. if (val[1] == 'ConfProxy') {
  735. strs += ` static ${key1}${toUpperCaseByStr(val[0])}:${val[1]}<xls${toUpperCaseByStr(
  736. key1
  737. )}${toUpperCaseByStr(key2)}>\n`;
  738. continue;
  739. }
  740. //别名
  741. if (val[1] == 'ConfListProxy') {
  742. strs += ` static ${key1}${toUpperCaseByStr(val[0])}List:${val[1]}<xls${toUpperCaseByStr(
  743. key1
  744. )}${toUpperCaseByStr(key2)}>\n`;
  745. continue;
  746. }
  747. }
  748. }
  749. }
  750. strs += `\n`;
  751. strs += ` static initLoading(loadSuccess: Function) {\n`;
  752. strs += ` try {\n`;
  753. strs += ` new XlsConfig("loadJson",(xls: XlsConfig) => {\n`;
  754. for (const key1 in s_xls.XlsBack) {
  755. for (const key2 in s_xls.XlsBack[key1]) {
  756. if (s_xls.XlsBack[key1][key2].length <= 0) {
  757. continue;
  758. }
  759. let jsonName = key1 + toUpperCaseByStr(key2)
  760. if (loadJson.indexOf(jsonName) < 0) {
  761. continue
  762. }
  763. for (const val of s_xls.XlsBack[key1][key2]) {
  764. let cs = ``;
  765. for (let index = 1; index < val.length; index++) {
  766. cs += `,"${val[index]}"`;
  767. }
  768. if (val[0] == 'ConfProxy') {
  769. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  770. key2
  771. )} = new ${val[0]}("${key1}${toUpperCaseByStr(
  772. key2
  773. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  774. continue;
  775. }
  776. if (val[0] == 'ConfListProxy') {
  777. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  778. key2
  779. )}List = new ${val[0]}("${key1}${toUpperCaseByStr(
  780. key2
  781. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  782. continue;
  783. }
  784. let cs1 = ``;
  785. for (let index = 2; index < val.length; index++) {
  786. cs1 += `,"${val[index]}"`;
  787. }
  788. //别名
  789. if (val[1] == 'ConfProxy') {
  790. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  791. val[0]
  792. )} = new ${val[1]}("${key1}${toUpperCaseByStr(
  793. val[0]
  794. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  795. continue;
  796. }
  797. if (val[1] == 'ConfListProxy') {
  798. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  799. val[0]
  800. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  801. val[0]
  802. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  803. continue;
  804. }
  805. }
  806. }
  807. }
  808. strs += `
  809. loadSuccess(true)
  810. })
  811. } catch (error) {
  812. loadSuccess(false)
  813. }
  814. }`;
  815. strs += `\n`;
  816. strs += ` static init(loadSuccess: Function) {\n`;
  817. strs += ` try {\n`;
  818. strs += ` new XlsConfig("pzwj",(xls: XlsConfig) => {\n`;
  819. for (const key1 in s_xls.XlsBack) {
  820. for (const key2 in s_xls.XlsBack[key1]) {
  821. if (s_xls.XlsBack[key1][key2].length <= 0) {
  822. continue;
  823. }
  824. let jsonName = key1 + toUpperCaseByStr(key2)
  825. if (loadJson.indexOf(jsonName) >= 0) {
  826. continue
  827. }
  828. for (const val of s_xls.XlsBack[key1][key2]) {
  829. let cs = ``;
  830. for (let index = 1; index < val.length; index++) {
  831. cs += `,"${val[index]}"`;
  832. }
  833. if (val[0] == 'ConfProxy') {
  834. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  835. key2
  836. )} = new ${val[0]}("${key1}${toUpperCaseByStr(
  837. key2
  838. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  839. continue;
  840. }
  841. if (val[0] == 'ConfListProxy') {
  842. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  843. key2
  844. )}List = new ${val[0]}("${key1}${toUpperCaseByStr(
  845. key2
  846. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  847. continue;
  848. }
  849. let cs1 = ``;
  850. for (let index = 2; index < val.length; index++) {
  851. cs1 += `,"${val[index]}"`;
  852. }
  853. //别名
  854. if (val[1] == 'ConfProxy') {
  855. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  856. val[0]
  857. )} = new ${val[1]}("${key1}${toUpperCaseByStr(
  858. val[0]
  859. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  860. continue;
  861. }
  862. if (val[1] == 'ConfListProxy') {
  863. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  864. val[0]
  865. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  866. val[0]
  867. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  868. continue;
  869. }
  870. }
  871. }
  872. }
  873. strs += `
  874. loadSuccess(true)
  875. })
  876. } catch (error) {
  877. loadSuccess(false)
  878. }
  879. }
  880. }`;
  881. // 写入文件
  882. let proPath = '';
  883. if (hang == 3) {
  884. proPath = `${path.configPath}gameCfg.ts`;
  885. } else {
  886. proPath = serverPath + `gameCfg.ts`;
  887. }
  888. fs.writeFile(proPath, strs, function (err) {
  889. if (err) {
  890. console.log('gameCfg写入失败:', err);
  891. }
  892. });
  893. }
  894. function createXyc() {
  895. const body = fs.readFileSync(apiurl, "utf-8");
  896. let arr = body.split('/a/apidoc"}]},')
  897. arr[1] = '[' + arr[1]
  898. let arr1 = arr[1].split('}];const');
  899. let str2 = arr1[0].replace(/!1/g, '0') + '}]';
  900. let apidoc = `//所有接口定义\n`
  901. apidoc += `export let apidoc:{[key:string]:string} = {\n`
  902. try {
  903. let strc = '';
  904. var jsons = eval('(' + str2 + ')');
  905. for (const json of jsons) {
  906. let jsontitle = json.url.split('/');
  907. let title = toUpperCaseByStr(jsontitle[1]) + toUpperCaseByStr(jsontitle[2]);
  908. let jsonUrl = json.url.slice(1);
  909. strc += `//${json.name}\n`;
  910. strc += `export class ${title}\n`;
  911. strc += `{\n`;
  912. strc += ` static url:string = "${jsonUrl}"\n`;
  913. strc += `}\n`;
  914. strc += `export interface ${title}Pram{\n`;
  915. apidoc += ` "/${jsonUrl}":"${json.name}",\n`
  916. let _Parameter = [];
  917. let hasUuid = 0;
  918. let hasToken = 0;
  919. if (json.parameter != null) {
  920. for (const Parameter of json.parameter.fields.Parameter) {
  921. let description = Parameter.description;
  922. let arr11 = description.split('<p>');
  923. let arr12 = arr11[1].split('</p>');
  924. let _type = Parameter.type;
  925. _Parameter.push({
  926. type: _type,
  927. field: Parameter.field,
  928. description: arr12[0]
  929. });
  930. if (Parameter.field == 'uuid') {
  931. hasUuid = 1;
  932. }
  933. if (Parameter.field == 'token') {
  934. hasToken = 1;
  935. }
  936. }
  937. }
  938. for (const _rameter of _Parameter) {
  939. if (hasUuid == 1 && hasToken == 1) {
  940. if (_rameter.field == 'uuid' || _rameter.field == 'token') {
  941. continue;
  942. }
  943. }
  944. strc += ` ${_rameter.field}:${_rameter.type} //${_rameter.description}\n`;
  945. }
  946. strc += `}\n\n`;
  947. }
  948. apidoc += `}`
  949. if (hang == 3) {
  950. outDir = path.configPath;
  951. } else {
  952. outDir = serverPath
  953. }
  954. strc += `
  955. //前端返回的特殊事件
  956. export interface keyValue{
  957. [key:string]:number
  958. }
  959. export interface keyValues{
  960. [key:string]:number[]
  961. }
  962. export interface keyValueString{
  963. [key:string]:string
  964. }
  965. export type ZixuanSelectCs = [string,string,number];
  966. export type Wxmspinzhi = [number,number]
  967. export type Wxmskeys = [number,string,string];
  968. export type Wxmslm = [number,string];
  969. `
  970. let proPath = `${outDir}Xyc.ts`;
  971. fs.writeFileSync(proPath, strc, function (err) {
  972. if (err) {
  973. console.log('Xyc写入失败:', err);
  974. }
  975. });
  976. let proPath1 = `${outDir}apidoc.ts`;
  977. fs.writeFileSync(proPath1, apidoc, function (err) {
  978. if (err) {
  979. console.log('Xyc写入失败:', err);
  980. }
  981. });
  982. } catch (error) {
  983. console.log('===', error);
  984. }
  985. }
  986. //拷贝 s_to_proto
  987. function copy_s_to_proto() {
  988. fs.copyFile(serverPath + 'Xys.ts', './s_to_proto/Xys.ts', (err) => {
  989. console.log('=', err);
  990. });
  991. fs.copyFile(serverPath + 'Xyc.ts', './s_to_proto/Xyc.ts', (err) => {
  992. console.log('=', err);
  993. });
  994. fs.copyFile(serverPath + 'gameMethod.ts', './s_to_proto/gameMethod.ts', (err) => {
  995. console.log('=', err);
  996. });
  997. fs.copyFile(serverPath + 'fight.ts', './s_to_proto/fight.ts', (err) => {
  998. console.log('=', err);
  999. });
  1000. }
  1001. //拷贝 proto
  1002. function copy_proto_to_c() {
  1003. outDir = path.configPath;
  1004. fs.copyFile('./s_to_proto/Xys.ts', outDir + 'Xys.ts', (err) => {
  1005. console.log('=', err);
  1006. });
  1007. fs.copyFile('./s_to_proto/Xyc.ts', outDir + 'Xyc.ts', (err) => {
  1008. console.log('=', err);
  1009. });
  1010. fs.copyFile('./s_to_proto/gameMethod.ts', outDir + 'gameMethod.ts', (err) => {
  1011. console.log('=', err);
  1012. });
  1013. fs.copyFile('./s_to_proto/fight.ts', outDir + 'fight.ts', (err) => {
  1014. console.log('=', err);
  1015. });
  1016. }
  1017. /**
  1018. * 延迟多少毫秒
  1019. */
  1020. function sleep(ms) {
  1021. if (ms < 1) {
  1022. return;
  1023. }
  1024. return new Promise((reslove, reject) => {
  1025. setTimeout(() => {
  1026. reslove(1);
  1027. }, ms);
  1028. });
  1029. }
  1030. // 开始解析配置表
  1031. function doExe(res) {
  1032. // console.log(res);
  1033. if (res != 'c' && res != 's' && res != 'C' && res != 'S') {
  1034. console.log('非法输入');
  1035. return;
  1036. }
  1037. if (res == 'c' || res == 'C') {
  1038. hang = 3;
  1039. } else {
  1040. hang = 4;
  1041. }
  1042. if (hang == 3) {
  1043. outDir = path.configPath;
  1044. } else {
  1045. outDir = serverPath;
  1046. }
  1047. console.log('\x1b[37m'); // 控制台文字切为白色
  1048. if (hang == 4) {
  1049. fs.rm(serverPath + outJsonFolder, { recursive: true }, (err, data) => {
  1050. if (err) {
  1051. console.log('删除json文件失败' + err);
  1052. }
  1053. console.log('删除json文件成功');
  1054. let sendNum = 0
  1055. let overNum = 0
  1056. // 解析表格
  1057. fs.readdirSync(excelDir).forEach((excelName) => {
  1058. if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
  1059. excelFiles.push(excelName.split('_')[0]);
  1060. const worker = cluster.fork(excelName);
  1061. sendNum += 1
  1062. worker.send({ "hang": 4, "excelName": excelName })
  1063. worker.on('message', function (mes) {
  1064. let mesarr = JSON.parse(mes)
  1065. for (const ar of mesarr.excelFen) {
  1066. excelFen.push(ar)
  1067. }
  1068. for (const key in mesarr.excelAndSheets) {
  1069. excelAndSheets[key] = mesarr.excelAndSheets[key]
  1070. }
  1071. overNum += 1
  1072. console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
  1073. })
  1074. }
  1075. });
  1076. const intervalId = setInterval(() => {
  1077. if (sendNum <= overNum) {
  1078. console.log("----全部完成----")
  1079. clearInterval(intervalId);
  1080. }
  1081. }, 1000);
  1082. });
  1083. }
  1084. if (hang == 3) {
  1085. fs.unlink(path.excelPath + outJsonFolder + '/excel.zip', (err, data) => {
  1086. if (err) {
  1087. console.log('删除zip文件失败' + err);
  1088. }
  1089. console.log('删除zip文件成功');
  1090. let sendNum = 0
  1091. let overNum = 0
  1092. let xls = {}
  1093. // 解析表格
  1094. fs.readdirSync(excelDir).forEach((excelName) => {
  1095. if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
  1096. excelFiles.push(excelName.split('_')[0]);
  1097. // doExcel(excelName);
  1098. xls[excelName] = 1
  1099. const worker = cluster.fork(excelName);
  1100. sendNum += 1
  1101. worker.send({ "hang": 3, "excelName": excelName })
  1102. worker.on('message', function (mes) {
  1103. let mesarr = JSON.parse(mes)
  1104. for (const ar of mesarr.excelFen) {
  1105. excelFen.push(ar)
  1106. }
  1107. for (const key in mesarr.excelAndSheets) {
  1108. excelAndSheets[key] = mesarr.excelAndSheets[key]
  1109. }
  1110. overNum += 1
  1111. delete xls[excelName]
  1112. console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
  1113. worker.destroy();
  1114. })
  1115. }
  1116. });
  1117. const intervalId = setInterval(() => {
  1118. if (sendNum <= overNum) {
  1119. // 生成配置表读取文件(ts)
  1120. exeExcelConfig_c();
  1121. console.log('*******创建配置文件完成*******');
  1122. // createXyc();
  1123. // console.log('*******创建xyc完成*******');
  1124. createGameCfg_c();
  1125. console.log('*******创建xls对应gameCfg完成*******');
  1126. copy_proto_to_c();
  1127. console.log('*******拷贝完成*******');
  1128. console.log("----全部完成----")
  1129. clearInterval(intervalId);
  1130. }
  1131. }, 1000);
  1132. });
  1133. }
  1134. sleep(4000);
  1135. // if (hang == 3) {
  1136. //
  1137. // }
  1138. }
  1139. if (!cluster.isMaster) {
  1140. process.on("message", function (message) {
  1141. hang = message.hang
  1142. doExcel(message.excelName)
  1143. process.send(JSON.stringify({ "excelFen": excelFen, "excelAndSheets": excelAndSheets }))
  1144. process.exit()
  1145. });
  1146. return
  1147. }
  1148. if (jiexiTarget == "s" || jiexiTarget == "c") {
  1149. doExe(jiexiTarget)
  1150. } else {
  1151. readSyncByRl('exe client->c or server->s:').then((res) => {
  1152. doExe(res)
  1153. });
  1154. }
  1155. // //---------------------end-------------------- 控制台人机交互