Skip to content

【增强】统一所有接口返回值 #196

@bendangmi

Description

@bendangmi

需求

需要将生成的所有后端接口返回值进行统一处理

使用

在pageage.json中添加执行脚本:openapi2ts && node scripts/update-api-response.js

#!/usr/bin/env node

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// 获取当前脚本所在目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// API 目录路径(相对于项目根目录)
const projectRoot = path.join(__dirname, '..');
const apiDir = path.join(projectRoot, 'src', 'api');

// 排除的文件列表
const excludeFiles = [
  'index.ts',
  'typings.d.ts',
  'fileTransferUtil.ts'  // 工具类文件,可能不需要修改
];

// 正则表达式匹配 request<类型> 模式
const requestTypeRegex = /request<([^>]+)>/g;

/**
 * 更新单个 API 文件
 * @param {string} filePath - 文件路径
 * @returns {object} - 更新结果 { updated: boolean, changeCount: number }
 */
function updateApiFile(filePath) {
  try {
    const content = fs.readFileSync(filePath, 'utf8');
    
    // 查找所有匹配的内容
    const matches = content.match(requestTypeRegex) || [];
    
    if (matches.length === 0) {
      return { updated: false, changeCount: 0 };
    }
    
    // 替换所有的 request<任何类型> 为 request<API.BaseResponseVoid>
    const updatedContent = content.replace(requestTypeRegex, 'request<API.BaseResponseVoid>');
    
    // 检查是否有变化
    if (content !== updatedContent) {
      fs.writeFileSync(filePath, updatedContent, 'utf8');
      return { updated: true, changeCount: matches.length };
    } else {
      return { updated: false, changeCount: 0 };
    }
  } catch (error) {
    console.error(`❌ 处理文件失败: ${path.basename(filePath)}`, error.message);
    return { updated: false, changeCount: 0 };
  }
}

/**
 * 获取所有需要处理的 TypeScript 文件
 * @returns {string[]} - 文件路径列表
 */
function getApiFiles() {
  try {
    const files = fs.readdirSync(apiDir);
    
    return files
      .filter(file => {
        // 只处理 .ts 文件,排除 .d.ts 文件和指定的排除文件
        return file.endsWith('.ts') && 
               !file.endsWith('.d.ts') && 
               !excludeFiles.includes(file);
      })
      .map(file => path.join(apiDir, file));
  } catch (error) {
    console.error(`❌ 读取 API 目录失败: ${error.message}`);
    return [];
  }
}

/**
 * 主函数
 */
function main() {
  console.log('🚀 开始批量更新 API 接口返回值类型...');
  console.log(`📂 API 目录: ${apiDir}\n`);
  
  // 检查 API 目录是否存在
  if (!fs.existsSync(apiDir)) {
    console.error(`❌ API 目录不存在: ${apiDir}`);
    process.exit(1);
  }
  
  // 获取所有需要处理的文件
  const apiFiles = getApiFiles();
  
  if (apiFiles.length === 0) {
    console.log('⚠️  未找到需要处理的 TypeScript 文件');
    return;
  }
  
  console.log(`📝 找到 ${apiFiles.length} 个文件需要处理:\n`);
  
  let updatedCount = 0;
  let totalInterfaces = 0;
  
  // 处理每个文件
  apiFiles.forEach(filePath => {
    const fileName = path.basename(filePath);
    console.log(`📄 正在处理: ${fileName}`);
    
    const result = updateApiFile(filePath);
    
    if (result.updated) {
      updatedCount++;
      totalInterfaces += result.changeCount;
      console.log(`✅ 已更新: ${fileName} (${result.changeCount} 个接口)`);
    } else if (result.changeCount === 0) {
      console.log(`⏭️  无接口需要更新: ${fileName}`);
    } else {
      console.log(`⏭️  无需更新: ${fileName}`);
    }
    
    console.log('');
  });
  
  // 输出汇总信息
  console.log('═'.repeat(50));
  console.log('✨ 批量更新完成!');
  console.log(`📊 统计信息:`);
  console.log(`   - 处理文件数: ${apiFiles.length}`);
  console.log(`   - 更新文件数: ${updatedCount}`);
  console.log(`   - 更新接口数: ${totalInterfaces}`);
  
  if (updatedCount > 0) {
    console.log('\n🎉 所有接口返回值已统一设置为 API.BaseResponseVoid');
  } else {
    console.log('\n✅ 所有文件均已是最新状态,无需更新');
  }
}

// 运行主函数
main();

// 导出函数供其他模块使用
export { updateApiFile, getApiFiles };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions