import { generate } from 'openapi-typescript-codegen'; import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs'; import { join } from 'path'; import axios from 'axios'; // 配置 const config = { // input: process.env.OPENAPI_URL || 'https://bowongai--glam-api-fastapi-app.modal.run/openapi.json', // OpenAPI规范URL input: process.env.OPENAPI_URL || 'http://192.168.0.127:8010/openapi.json', // OpenAPI规范URL output: './src/api', // 生成的API代码输出目录 client: 'axios', // 使用axios作为HTTP客户端 useOptions: true, useUnionTypes: true, exportSchemas: true, exportServices: true, exportCore: true, exportModels: true, exportClient: true, }; async function fetchOpenApiSpec(url) { try { console.log(`📡 正在获取OpenAPI规范: ${url}`); const response = await axios.get(url); return response.data; } catch (error) { console.error(`❌ 获取OpenAPI规范失败: ${error.message}`); throw error; } } function createIndexFiles() { const apiDir = config.output; // 创建services/index.ts const servicesDir = join(apiDir, 'services'); if (existsSync(servicesDir)) { const serviceFiles = readdirSync(servicesDir) .filter(file => file.endsWith('.ts') && file !== 'index.ts' && file !== 'Service.ts') .map(file => file.replace('.ts', '')); const servicesIndexContent = serviceFiles.map(service => `export * from './${service}';`).join('\n'); writeFileSync(join(servicesDir, 'index.ts'), servicesIndexContent); console.log('📝 创建services/index.ts完成'); } // 创建models/index.ts const modelsDir = join(apiDir, 'models'); if (existsSync(modelsDir)) { const modelFiles = readdirSync(modelsDir) .filter(file => file.endsWith('.ts') && file !== 'index.ts') .map(file => file.replace('.ts', '')); const modelsIndexContent = modelFiles.map(model => `export * from './${model}';`).join('\n'); writeFileSync(join(modelsDir, 'index.ts'), modelsIndexContent); console.log('📝 创建models/index.ts完成'); } } function createApiEntry() { const servicesDir = join(config.output, 'services'); const modelsDir = join(config.output, 'models'); const apiDir = join('src', 'api'); const apiFile = join(apiDir, 'index.ts'); // 读取 service 文件 let serviceFiles = []; if (existsSync(servicesDir)) { serviceFiles = readdirSync(servicesDir) .filter(file => file.endsWith('.ts') && file !== 'index.ts' && file !== 'Service.ts') .map(file => file.replace('.ts', '')); } // 读取 model 文件 let modelFiles = []; if (existsSync(modelsDir)) { modelFiles = readdirSync(modelsDir) .filter(file => file.endsWith('.ts') && file !== 'index.ts') .map(file => file.replace('.ts', '')); } // 生成 import 语句 const importStatements = [ `import { OpenAPI } from '@/api/core/OpenAPI';`, ...serviceFiles.map(name => `import * as ${name} from '@/api/services/${name}';`), ].join('\n'); // 生成 api 对象 const apiObject = ['export const api = {', ...serviceFiles.map(name => ` ...${name},`), ' OpenAPI,', '};'].join('\n'); // 生成 baseURL 逻辑 const baseUrlLogic = `\nconst baseURL = (() => {\n const url = import.meta.env.VITE_API_BASE_URL || ''; return url;\n})();\nOpenAPI.BASE = baseURL;\n`; // 生成类型 re-export const typeExports = modelFiles.map(name => `export type { ${name} } from '@/api/models/${name}';`).join('\n'); // 合成文件内容 const content = `${importStatements}\n${baseUrlLogic}\n${apiObject}\n\n${typeExports}\n`; // 确保 api 目录存在 if (!existsSync(apiDir)) { require('fs').mkdirSync(apiDir, { recursive: true }); } // 写入文件 writeFileSync(apiFile, content); console.log('📝 自动生成 src/api/index.ts 完成'); } async function generateApi() { try { console.log('🚀 开始生成API代码...'); let openApiSpec; // 检查输入是URL还是本地文件 if (config.input.startsWith('http://') || config.input.startsWith('https://')) { // 从URL获取OpenAPI规范 openApiSpec = await fetchOpenApiSpec(config.input); } else { // 从本地文件读取 if (!existsSync(config.input)) { console.error(`❌ OpenAPI文件不存在: ${config.input}`); console.log('请确保openapi.json文件存在于项目根目录,或设置OPENAPI_URL环境变量'); return; } openApiSpec = JSON.parse(readFileSync(config.input, 'utf8')); } // 生成API代码 await generate({ input: openApiSpec, // 直接传入规范对象 output: config.output, client: config.client, useOptions: config.useOptions, useUnionTypes: config.useUnionTypes, exportSchemas: config.exportSchemas, exportServices: config.exportServices, exportCore: config.exportCore, exportModels: config.exportModels, exportClient: config.exportClient, }); console.log('✅ API代码生成完成!'); console.log(`📁 输出目录: ${config.output}`); // 创建索引文件 createIndexFiles(); // 自动生成 api/index.ts(包含 api 和 ApiModel) createApiEntry(); } catch (error) { console.error('❌ 生成API代码时出错:', error); } } // 运行生成器 generateApi();