adminindex - 副本.js 30 KB

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