copy.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. const fs = require('fs');
  2. const path = require('path');
  3. // 获取命令行参数
  4. const sourceFile = process.argv[2];
  5. const targetDir = process.argv[3];
  6. if (!sourceFile || !targetDir) {
  7. console.log('使用方法: node copy.js <源文件路径> <目标目录>');
  8. process.exit(1);
  9. }
  10. // 确保目标目录存在
  11. if (!fs.existsSync(targetDir)) {
  12. fs.mkdirSync(targetDir, { recursive: true });
  13. }
  14. // 读取源文件内容
  15. const sourceContent = fs.readFileSync(sourceFile, 'utf8');
  16. // 解析TypeScript类定义
  17. function processClassContent(content) {
  18. // 匹配类名
  19. const classNameMatch = content.match(/export\s+default\s+class\s+(\w+)/);
  20. if (!classNameMatch) {
  21. return content; // 如果不是类定义,直接返回原内容
  22. }
  23. const className = classNameMatch[1];
  24. // 匹配data字段
  25. const dataMatch = content.match(/private\s+static\s+data\s*=\s*({[\s\S]*?})\/\/\s*(.*?)(?=\n\s*static|\n\s*})/);
  26. if (!dataMatch) {
  27. return content; // 如果没有找到data字段,直接返回原内容
  28. }
  29. const jsonData = dataMatch[1];
  30. const fieldComments = dataMatch[2];
  31. // console.log(jsonData);
  32. // 解析字段注释
  33. const publicProperties = parseJsonFieldTypes(jsonData);
  34. // 生成公共属性定义
  35. // const publicProperties = generatePublicProperties(fieldDefs);
  36. // 更新getData方法返回类型
  37. const updatedContent = content
  38. .replace(/static\s+getData\(key:\s*any\):\s*any/, `static getData(key: any): ${className}`)
  39. .replace(/return\s+null;/, 'return null!;');
  40. // 在类定义后插入公共属性
  41. const classStartMatch = updatedContent.match(/(export\s+default\s+class\s+\w+\s*{)/);
  42. if (classStartMatch) {
  43. const insertPosition = classStartMatch.index + classStartMatch[0].length;
  44. const newContent =
  45. updatedContent.substring(0, insertPosition) +
  46. '\n' + publicProperties +
  47. updatedContent.substring(insertPosition);
  48. return newContent;
  49. }
  50. return updatedContent;
  51. }
  52. // 从JSON数据解析字段类型
  53. function parseJsonFieldTypes(jsonString) {
  54. try {
  55. const properties = [];
  56. const jsonData = JSON.parse(jsonString);
  57. // console.log(jsonData);
  58. // 如果JSON是数组,取第一个元素作为模板
  59. let sampleData = null;
  60. for(let key in jsonData) {
  61. sampleData = jsonData[key];
  62. break;
  63. }
  64. if (sampleData && typeof sampleData === 'object') {
  65. Object.keys(sampleData).forEach(key => {
  66. const value = sampleData[key];
  67. let type = 'any';
  68. if (typeof value === 'number') {
  69. type = 'number';
  70. } else if (typeof value === 'string') {
  71. type = 'string';
  72. } else if (typeof value === 'boolean') {
  73. type = 'boolean';
  74. } else if (Array.isArray(value)) {
  75. // 判断数组元素类型
  76. if (value.length > 0) {
  77. const firstElement = value[0];
  78. if (typeof firstElement === 'number') {
  79. type = 'number[]';
  80. } else if (typeof firstElement === 'string') {
  81. type = 'string[]';
  82. } else if (typeof firstElement === 'boolean') {
  83. type = 'boolean[]';
  84. } else {
  85. type = 'any[]';
  86. }
  87. } else {
  88. type = 'any[]';
  89. }
  90. } else if (value === null) {
  91. type = 'any';
  92. } else if (typeof value === 'object') {
  93. type = 'object';
  94. }
  95. properties.push(` public ${key}: ${type};`);
  96. });
  97. }
  98. return properties.join('\n');
  99. } catch (error) {
  100. console.error('解析JSON数据时出错:', error);
  101. return {};
  102. }
  103. }
  104. // 根据JSON字段类型生成公共属性
  105. function generatePropertiesFromJson(jsonString) {
  106. const fieldTypes = parseJsonFieldTypes(jsonString);
  107. const properties = [];
  108. Object.keys(fieldTypes).forEach(fieldName => {
  109. const fieldType = fieldTypes[fieldName];
  110. properties.push(` public ${fieldName}: ${fieldType};`);
  111. });
  112. return properties.join('\n');
  113. }
  114. // 解析字段定义
  115. function parseFieldDefinitions(comments) {
  116. const fieldDefs = [];
  117. const parts = comments.split(',');
  118. parts.forEach(part => {
  119. const trimmed = part.trim();
  120. const match = trimmed.match(/(\w+):(.+)/);
  121. if (match) {
  122. const fieldName = match[1].trim();
  123. const fieldDesc = match[2].trim();
  124. fieldDefs.push({ name: fieldName, description: fieldDesc });
  125. }
  126. });
  127. return fieldDefs;
  128. }
  129. // 生成公共属性定义
  130. function generatePublicProperties(fieldDefs) {
  131. const properties = [];
  132. fieldDefs.forEach(field => {
  133. let type = 'string'; // 默认类型
  134. console.log(field);
  135. // 根据字段名推断类型
  136. if (field.name === 'ID' || field.name.includes('_id') ||
  137. field.name === 'grade_type' || field.name === 'default_have' ||
  138. field.name === 'atk' || field.name === 'skill_id' ||
  139. field.name === 'attribute') {
  140. type = 'number';
  141. } else if (field.name === 'speed' || field.name === 'zoom_factor') {
  142. type = 'number';
  143. } else {
  144. type = 'string';
  145. }
  146. properties.push(` public ${field.name}: ${type};`);
  147. });
  148. return properties.join('\n');
  149. }
  150. // 处理文件
  151. try {
  152. const processedContent = processClassContent(sourceContent);
  153. // 生成目标文件路径
  154. const sourceFileName = path.basename(sourceFile);
  155. const targetFile = path.join(targetDir, sourceFileName);
  156. // 写入处理后的内容
  157. fs.writeFileSync(targetFile, processedContent, 'utf8');
  158. console.log(`文件已成功处理并保存到: ${targetFile}`);
  159. } catch (error) {
  160. console.error('处理文件时发生错误:', error.message);
  161. process.exit(1);
  162. }