|
@@ -0,0 +1,197 @@
|
|
|
+const fs = require('fs');
|
|
|
+const path = require('path');
|
|
|
+
|
|
|
+// 获取命令行参数
|
|
|
+const sourceFile = process.argv[2];
|
|
|
+const targetDir = process.argv[3];
|
|
|
+
|
|
|
+if (!sourceFile || !targetDir) {
|
|
|
+ console.log('使用方法: node copy.js <源文件路径> <目标目录>');
|
|
|
+ process.exit(1);
|
|
|
+}
|
|
|
+
|
|
|
+// 确保目标目录存在
|
|
|
+if (!fs.existsSync(targetDir)) {
|
|
|
+ fs.mkdirSync(targetDir, { recursive: true });
|
|
|
+}
|
|
|
+
|
|
|
+// 读取源文件内容
|
|
|
+const sourceContent = fs.readFileSync(sourceFile, 'utf8');
|
|
|
+
|
|
|
+// 解析TypeScript类定义
|
|
|
+function processClassContent(content) {
|
|
|
+ // 匹配类名
|
|
|
+ const classNameMatch = content.match(/export\s+default\s+class\s+(\w+)/);
|
|
|
+ if (!classNameMatch) {
|
|
|
+ return content; // 如果不是类定义,直接返回原内容
|
|
|
+ }
|
|
|
+
|
|
|
+ const className = classNameMatch[1];
|
|
|
+
|
|
|
+ // 匹配data字段
|
|
|
+ const dataMatch = content.match(/private\s+static\s+data\s*=\s*({[\s\S]*?})\/\/\s*(.*?)(?=\n\s*static|\n\s*})/);
|
|
|
+ if (!dataMatch) {
|
|
|
+ return content; // 如果没有找到data字段,直接返回原内容
|
|
|
+ }
|
|
|
+
|
|
|
+ const jsonData = dataMatch[1];
|
|
|
+ const fieldComments = dataMatch[2];
|
|
|
+
|
|
|
+ // console.log(jsonData);
|
|
|
+ // 解析字段注释
|
|
|
+ const publicProperties = parseJsonFieldTypes(jsonData);
|
|
|
+
|
|
|
+ // 生成公共属性定义
|
|
|
+ // const publicProperties = generatePublicProperties(fieldDefs);
|
|
|
+
|
|
|
+ // 更新getData方法返回类型
|
|
|
+ const updatedContent = content
|
|
|
+ .replace(/static\s+getData\(key:\s*any\):\s*any/, `static getData(key: any): ${className}`)
|
|
|
+ .replace(/return\s+null;/, 'return null!;');
|
|
|
+
|
|
|
+ // 在类定义后插入公共属性
|
|
|
+ const classStartMatch = updatedContent.match(/(export\s+default\s+class\s+\w+\s*{)/);
|
|
|
+ if (classStartMatch) {
|
|
|
+ const insertPosition = classStartMatch.index + classStartMatch[0].length;
|
|
|
+ const newContent =
|
|
|
+ updatedContent.substring(0, insertPosition) +
|
|
|
+ '\n' + publicProperties +
|
|
|
+ updatedContent.substring(insertPosition);
|
|
|
+ return newContent;
|
|
|
+ }
|
|
|
+
|
|
|
+ return updatedContent;
|
|
|
+}
|
|
|
+
|
|
|
+// 从JSON数据解析字段类型
|
|
|
+function parseJsonFieldTypes(jsonString) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ const properties = [];
|
|
|
+ const jsonData = JSON.parse(jsonString);
|
|
|
+ // console.log(jsonData);
|
|
|
+
|
|
|
+ // 如果JSON是数组,取第一个元素作为模板
|
|
|
+ let sampleData = null;
|
|
|
+ for(let key in jsonData) {
|
|
|
+ sampleData = jsonData[key];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sampleData && typeof sampleData === 'object') {
|
|
|
+ Object.keys(sampleData).forEach(key => {
|
|
|
+ const value = sampleData[key];
|
|
|
+ let type = 'any';
|
|
|
+
|
|
|
+ if (typeof value === 'number') {
|
|
|
+ type = 'number';
|
|
|
+ } else if (typeof value === 'string') {
|
|
|
+ type = 'string';
|
|
|
+ } else if (typeof value === 'boolean') {
|
|
|
+ type = 'boolean';
|
|
|
+ } else if (Array.isArray(value)) {
|
|
|
+ // 判断数组元素类型
|
|
|
+ if (value.length > 0) {
|
|
|
+ const firstElement = value[0];
|
|
|
+ if (typeof firstElement === 'number') {
|
|
|
+ type = 'number[]';
|
|
|
+ } else if (typeof firstElement === 'string') {
|
|
|
+ type = 'string[]';
|
|
|
+ } else if (typeof firstElement === 'boolean') {
|
|
|
+ type = 'boolean[]';
|
|
|
+ } else {
|
|
|
+ type = 'any[]';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ type = 'any[]';
|
|
|
+ }
|
|
|
+ } else if (value === null) {
|
|
|
+ type = 'any';
|
|
|
+ } else if (typeof value === 'object') {
|
|
|
+ type = 'object';
|
|
|
+ }
|
|
|
+
|
|
|
+ properties.push(` public ${key}: ${type};`);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return properties.join('\n');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析JSON数据时出错:', error);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 根据JSON字段类型生成公共属性
|
|
|
+function generatePropertiesFromJson(jsonString) {
|
|
|
+ const fieldTypes = parseJsonFieldTypes(jsonString);
|
|
|
+ const properties = [];
|
|
|
+
|
|
|
+ Object.keys(fieldTypes).forEach(fieldName => {
|
|
|
+ const fieldType = fieldTypes[fieldName];
|
|
|
+ properties.push(` public ${fieldName}: ${fieldType};`);
|
|
|
+ });
|
|
|
+
|
|
|
+ return properties.join('\n');
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 解析字段定义
|
|
|
+function parseFieldDefinitions(comments) {
|
|
|
+ const fieldDefs = [];
|
|
|
+ const parts = comments.split(',');
|
|
|
+
|
|
|
+ parts.forEach(part => {
|
|
|
+ const trimmed = part.trim();
|
|
|
+ const match = trimmed.match(/(\w+):(.+)/);
|
|
|
+ if (match) {
|
|
|
+ const fieldName = match[1].trim();
|
|
|
+ const fieldDesc = match[2].trim();
|
|
|
+ fieldDefs.push({ name: fieldName, description: fieldDesc });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return fieldDefs;
|
|
|
+}
|
|
|
+
|
|
|
+// 生成公共属性定义
|
|
|
+function generatePublicProperties(fieldDefs) {
|
|
|
+ const properties = [];
|
|
|
+
|
|
|
+ fieldDefs.forEach(field => {
|
|
|
+ let type = 'string'; // 默认类型
|
|
|
+ console.log(field);
|
|
|
+ // 根据字段名推断类型
|
|
|
+ if (field.name === 'ID' || field.name.includes('_id') ||
|
|
|
+ field.name === 'grade_type' || field.name === 'default_have' ||
|
|
|
+ field.name === 'atk' || field.name === 'skill_id' ||
|
|
|
+ field.name === 'attribute') {
|
|
|
+ type = 'number';
|
|
|
+ } else if (field.name === 'speed' || field.name === 'zoom_factor') {
|
|
|
+ type = 'number';
|
|
|
+ } else {
|
|
|
+ type = 'string';
|
|
|
+ }
|
|
|
+
|
|
|
+ properties.push(` public ${field.name}: ${type};`);
|
|
|
+ });
|
|
|
+
|
|
|
+ return properties.join('\n');
|
|
|
+}
|
|
|
+
|
|
|
+// 处理文件
|
|
|
+try {
|
|
|
+ const processedContent = processClassContent(sourceContent);
|
|
|
+
|
|
|
+ // 生成目标文件路径
|
|
|
+ const sourceFileName = path.basename(sourceFile);
|
|
|
+ const targetFile = path.join(targetDir, sourceFileName);
|
|
|
+
|
|
|
+ // 写入处理后的内容
|
|
|
+ fs.writeFileSync(targetFile, processedContent, 'utf8');
|
|
|
+
|
|
|
+ console.log(`文件已成功处理并保存到: ${targetFile}`);
|
|
|
+} catch (error) {
|
|
|
+ console.error('处理文件时发生错误:', error.message);
|
|
|
+ process.exit(1);
|
|
|
+}
|