425 lines
13 KiB
Dart
425 lines
13 KiB
Dart
/// 完整项目示例
|
|
/// 演示在真实 Flutter 项目中如何集成和使用 Swagger Generator
|
|
library;
|
|
|
|
import 'dart:io';
|
|
import 'package:swagger_generator_flutter/swagger_generator_flutter.dart';
|
|
|
|
/// 项目配置
|
|
class ProjectConfig {
|
|
static const String projectName = 'MyFlutterApp';
|
|
static const String apiServiceName = 'ApiService';
|
|
static const String outputDir = 'lib/api/generated';
|
|
static const String swaggerFile = 'swagger.json';
|
|
|
|
// API 配置
|
|
static const String baseUrl = 'https://api.myapp.com';
|
|
static const String apiVersion = 'v1';
|
|
|
|
// 生成配置
|
|
static const bool enableModularApis = true;
|
|
static const bool enableBaseResult = true;
|
|
static const bool enablePagination = true;
|
|
static const bool enableFileUpload = true;
|
|
static const bool enableCaching = true;
|
|
static const bool enableValidation = true;
|
|
}
|
|
|
|
void main() async {
|
|
print('🚀 ${ProjectConfig.projectName} API 代码生成');
|
|
print('=' * 60);
|
|
|
|
final generator = ProjectApiGenerator();
|
|
|
|
try {
|
|
await generator.generateProjectApi();
|
|
print('\n🎉 API 代码生成完成!');
|
|
} catch (e, stackTrace) {
|
|
print('❌ 生成失败: $e');
|
|
print('堆栈跟踪: $stackTrace');
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/// 项目 API 生成器
|
|
class ProjectApiGenerator {
|
|
late PerformanceParser parser;
|
|
late OptimizedRetrofitGenerator generator;
|
|
late EnhancedValidator validator;
|
|
|
|
ProjectApiGenerator() {
|
|
_initializeComponents();
|
|
}
|
|
|
|
/// 初始化组件
|
|
void _initializeComponents() {
|
|
// 配置高性能解析器
|
|
parser = PerformanceParser(
|
|
config: ParseConfig(
|
|
enablePerformanceStats: true,
|
|
enableParallelParsing: false, // 禁用并行解析避免类型转换问题
|
|
enableCaching: ProjectConfig.enableCaching,
|
|
maxConcurrency: 4,
|
|
enableMemoryOptimization: true,
|
|
),
|
|
);
|
|
|
|
// 配置优化生成器
|
|
generator = OptimizedRetrofitGenerator(
|
|
className: ProjectConfig.apiServiceName,
|
|
generateModularApis: ProjectConfig.enableModularApis,
|
|
generateBaseResult: ProjectConfig.enableBaseResult,
|
|
generatePagination: ProjectConfig.enablePagination,
|
|
generateFileUpload: ProjectConfig.enableFileUpload,
|
|
baseResultType: 'ApiResult',
|
|
pageResultType: 'PagedApiResult',
|
|
);
|
|
|
|
// 配置验证器
|
|
validator = EnhancedValidator(
|
|
includeWarnings: true,
|
|
);
|
|
}
|
|
|
|
/// 生成项目 API
|
|
Future<void> generateProjectApi() async {
|
|
// 1. 检查环境
|
|
await _checkEnvironment();
|
|
|
|
// 2. 读取和解析文档
|
|
final document = await _parseSwaggerDocument();
|
|
|
|
// 3. 验证文档
|
|
await _validateDocument(document);
|
|
|
|
// 4. 生成 API 代码
|
|
await _generateApiCode(document);
|
|
|
|
// 5. 生成配置文件
|
|
await _generateConfigFiles();
|
|
|
|
// 6. 生成使用示例
|
|
await _generateUsageExamples();
|
|
|
|
// 7. 生成文档
|
|
await _generateDocumentation(document);
|
|
|
|
// 8. 显示总结
|
|
_showSummary();
|
|
}
|
|
|
|
/// 检查环境
|
|
Future<void> _checkEnvironment() async {
|
|
print('🔍 检查环境...');
|
|
|
|
// 检查 swagger.json 文件
|
|
final swaggerFile = File(ProjectConfig.swaggerFile);
|
|
if (!swaggerFile.existsSync()) {
|
|
throw Exception('找不到 ${ProjectConfig.swaggerFile} 文件');
|
|
}
|
|
|
|
// 检查输出目录
|
|
final outputDir = Directory(ProjectConfig.outputDir);
|
|
if (!outputDir.existsSync()) {
|
|
print('📁 创建输出目录: ${ProjectConfig.outputDir}');
|
|
outputDir.createSync(recursive: true);
|
|
}
|
|
|
|
// 检查依赖
|
|
final pubspecFile = File('pubspec.yaml');
|
|
if (pubspecFile.existsSync()) {
|
|
final content = await pubspecFile.readAsString();
|
|
final requiredDeps = ['dio', 'retrofit', 'json_annotation'];
|
|
final missingDeps = <String>[];
|
|
|
|
for (final dep in requiredDeps) {
|
|
if (!content.contains(dep)) {
|
|
missingDeps.add(dep);
|
|
}
|
|
}
|
|
|
|
if (missingDeps.isNotEmpty) {
|
|
print('⚠️ 缺少依赖: ${missingDeps.join(', ')}');
|
|
print(' 请在 pubspec.yaml 中添加这些依赖');
|
|
}
|
|
}
|
|
|
|
print('✅ 环境检查完成');
|
|
}
|
|
|
|
/// 解析 Swagger 文档
|
|
Future<SwaggerDocument> _parseSwaggerDocument() async {
|
|
print('\n📖 解析 Swagger 文档...');
|
|
|
|
final jsonString = await File(ProjectConfig.swaggerFile).readAsString();
|
|
print(' - 文档大小: ${(jsonString.length / 1024).toStringAsFixed(2)}KB');
|
|
|
|
final stopwatch = Stopwatch()..start();
|
|
final document = await parser.parseDocument(jsonString);
|
|
stopwatch.stop();
|
|
|
|
print('✅ 解析完成');
|
|
print(' - 解析时间: ${stopwatch.elapsedMilliseconds}ms');
|
|
print(' - API 标题: ${document.title}');
|
|
print(' - API 版本: ${document.version}');
|
|
print(' - 路径数量: ${document.paths.length}');
|
|
print(' - 模型数量: ${document.models.length}');
|
|
print(' - 服务器数量: ${document.servers.length}');
|
|
|
|
// 显示性能统计
|
|
final stats = parser.lastStats;
|
|
if (stats != null) {
|
|
print(' - 处理速度: ${stats.pathsPerSecond.toStringAsFixed(1)} paths/s');
|
|
print(
|
|
' - 吞吐量: ${(stats.bytesPerSecond / 1024).toStringAsFixed(2)} KB/s');
|
|
}
|
|
|
|
return document;
|
|
}
|
|
|
|
/// 验证文档
|
|
Future<void> _validateDocument(SwaggerDocument document) async {
|
|
if (!ProjectConfig.enableValidation) {
|
|
print('\n⏭️ 跳过文档验证');
|
|
return;
|
|
}
|
|
|
|
print('\n✅ 验证文档...');
|
|
|
|
final isValid = validator.validateDocument(document);
|
|
final errors =
|
|
validator.errorReporter.getErrorsBySeverity(ErrorSeverity.error);
|
|
final warnings =
|
|
validator.errorReporter.getErrorsBySeverity(ErrorSeverity.warning);
|
|
final criticalErrors =
|
|
validator.errorReporter.getErrorsBySeverity(ErrorSeverity.critical);
|
|
|
|
print(' - 验证结果: ${isValid ? "✅ 通过" : "❌ 失败"}');
|
|
print(' - 严重错误: ${criticalErrors.length}');
|
|
print(' - 错误: ${errors.length}');
|
|
print(' - 警告: ${warnings.length}');
|
|
|
|
if (criticalErrors.isNotEmpty) {
|
|
print('\n🚨 严重错误:');
|
|
for (final error in criticalErrors.take(3)) {
|
|
print(' - ${error.title}: ${error.description}');
|
|
}
|
|
throw Exception('文档包含严重错误,无法继续生成');
|
|
}
|
|
|
|
if (errors.isNotEmpty) {
|
|
print('\n❌ 错误:');
|
|
for (final error in errors.take(3)) {
|
|
print(' - ${error.title}: ${error.description}');
|
|
}
|
|
}
|
|
|
|
if (warnings.isNotEmpty) {
|
|
print('\n⚠️ 警告:');
|
|
for (final warning in warnings.take(3)) {
|
|
print(' - ${warning.title}: ${warning.description}');
|
|
}
|
|
}
|
|
|
|
// 保存验证报告
|
|
final report = validator.errorReporter.generateReport();
|
|
final reportFile = File('${ProjectConfig.outputDir}/validation_report.txt');
|
|
await reportFile.writeAsString(report);
|
|
print(' - 验证报告: ${reportFile.path}');
|
|
}
|
|
|
|
/// 生成 API 代码
|
|
Future<void> _generateApiCode(SwaggerDocument document) async {
|
|
print('\n🔧 生成 API 代码...');
|
|
|
|
final stopwatch = Stopwatch()..start();
|
|
final generatedCode = generator.generateFromDocument(document);
|
|
stopwatch.stop();
|
|
|
|
print('✅ 代码生成完成');
|
|
print(' - 生成时间: ${stopwatch.elapsedMilliseconds}ms');
|
|
print(' - 代码大小: ${(generatedCode.length / 1024).toStringAsFixed(2)}KB');
|
|
print(' - 代码行数: ${generatedCode.split('\n').length}');
|
|
|
|
// 保存主 API 文件
|
|
final apiFile = File(
|
|
'${ProjectConfig.outputDir}/${ProjectConfig.apiServiceName.toLowerCase()}.dart');
|
|
await apiFile.writeAsString(generatedCode);
|
|
print(' - API 文件: ${apiFile.path}');
|
|
|
|
// 检查生成的特性
|
|
final features = <String>[];
|
|
if (generatedCode.contains('class ApiResult')) features.add('基础响应类型');
|
|
if (generatedCode.contains('class PagedApiResult')) features.add('分页支持');
|
|
if (generatedCode.contains('MultipartFile')) features.add('文件上传');
|
|
if (generatedCode.contains('class ApiUtils')) features.add('工具类');
|
|
|
|
if (features.isNotEmpty) {
|
|
print(' - 生成特性: ${features.join(', ')}');
|
|
}
|
|
}
|
|
|
|
/// 生成配置文件
|
|
Future<void> _generateConfigFiles() async {
|
|
print('\n⚙️ 生成配置文件...');
|
|
|
|
// 生成 API 配置
|
|
final apiConfig = '''
|
|
/// API 配置文件
|
|
/// 自动生成,请勿手动修改
|
|
class ApiConfig {
|
|
static const String baseUrl = '${ProjectConfig.baseUrl}';
|
|
static const String apiVersion = '${ProjectConfig.apiVersion}';
|
|
static const int connectTimeout = 30000;
|
|
static const int receiveTimeout = 30000;
|
|
static const int sendTimeout = 30000;
|
|
|
|
// 请求头
|
|
static const Map<String, String> defaultHeaders = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
};
|
|
|
|
// 调试模式
|
|
static const bool debugMode = true;
|
|
}
|
|
''';
|
|
|
|
final configFile = File('${ProjectConfig.outputDir}/api_config.dart');
|
|
await configFile.writeAsString(apiConfig);
|
|
print(' - API 配置: ${configFile.path}');
|
|
|
|
// 生成 Dio 配置
|
|
final dioConfig = '''
|
|
/// Dio 配置文件
|
|
import 'package:dio/dio.dart';
|
|
import 'api_config.dart';
|
|
|
|
class DioConfig {
|
|
static Dio createDio() {
|
|
final dio = Dio(BaseOptions(
|
|
baseUrl: ApiConfig.baseUrl,
|
|
connectTimeout: Duration(milliseconds: ApiConfig.connectTimeout),
|
|
receiveTimeout: Duration(milliseconds: ApiConfig.receiveTimeout),
|
|
sendTimeout: Duration(milliseconds: ApiConfig.sendTimeout),
|
|
headers: ApiConfig.defaultHeaders,
|
|
));
|
|
|
|
if (ApiConfig.debugMode) {
|
|
dio.interceptors.add(LogInterceptor(
|
|
requestBody: true,
|
|
responseBody: true,
|
|
requestHeader: true,
|
|
responseHeader: false,
|
|
));
|
|
}
|
|
|
|
return dio;
|
|
}
|
|
}
|
|
''';
|
|
|
|
final dioConfigFile = File('${ProjectConfig.outputDir}/dio_config.dart');
|
|
await dioConfigFile.writeAsString(dioConfig);
|
|
print(' - Dio 配置: ${dioConfigFile.path}');
|
|
}
|
|
|
|
/// 生成使用示例
|
|
Future<void> _generateUsageExamples() async {
|
|
print('\n📝 生成使用示例...');
|
|
|
|
final example = '''
|
|
/// API 使用示例
|
|
/// 展示如何在 Flutter 项目中使用生成的 API
|
|
import 'package:dio/dio.dart';
|
|
import 'generated/${ProjectConfig.apiServiceName.toLowerCase()}.dart';
|
|
import 'dio_config.dart';
|
|
|
|
class ApiExample {
|
|
late final ${ProjectConfig.apiServiceName} apiService;
|
|
|
|
ApiExample() {
|
|
final dio = DioConfig.createDio();
|
|
apiService = ${ProjectConfig.apiServiceName}(dio);
|
|
}
|
|
|
|
/// 示例:获取用户列表
|
|
Future<void> getUsersExample() async {
|
|
try {
|
|
final response = await apiService.getUsers();
|
|
print('用户列表: \$response');
|
|
} catch (e) {
|
|
print('获取用户列表失败: \$e');
|
|
}
|
|
}
|
|
|
|
/// 示例:创建用户
|
|
Future<void> createUserExample() async {
|
|
try {
|
|
final userData = {
|
|
'name': 'John Doe',
|
|
'email': 'john@example.com',
|
|
};
|
|
final response = await apiService.createUser(userData);
|
|
print('用户创建成功: \$response');
|
|
} catch (e) {
|
|
print('创建用户失败: \$e');
|
|
}
|
|
}
|
|
}
|
|
''';
|
|
|
|
final exampleFile = File('${ProjectConfig.outputDir}/api_example.dart');
|
|
await exampleFile.writeAsString(example);
|
|
print(' - 使用示例: ${exampleFile.path}');
|
|
}
|
|
|
|
/// 生成文档
|
|
Future<void> _generateDocumentation(SwaggerDocument document) async {
|
|
print('\n📚 生成文档...');
|
|
|
|
final docs = StringBuffer();
|
|
docs.writeln('# ${document.title} API 文档');
|
|
docs.writeln();
|
|
docs.writeln('版本: ${document.version}');
|
|
docs.writeln('描述: ${document.description}');
|
|
docs.writeln();
|
|
docs.writeln('## 服务器');
|
|
for (final server in document.servers) {
|
|
docs.writeln('- ${server.url}: ${server.description}');
|
|
}
|
|
docs.writeln();
|
|
docs.writeln('## API 端点');
|
|
docs.writeln('总计: ${document.paths.length} 个端点');
|
|
docs.writeln();
|
|
docs.writeln('## 数据模型');
|
|
docs.writeln('总计: ${document.models.length} 个模型');
|
|
docs.writeln();
|
|
docs.writeln('## 使用方法');
|
|
docs.writeln('请参考 `api_example.dart` 文件中的示例代码。');
|
|
|
|
final docsFile = File('${ProjectConfig.outputDir}/README.md');
|
|
await docsFile.writeAsString(docs.toString());
|
|
print(' - API 文档: ${docsFile.path}');
|
|
}
|
|
|
|
/// 显示总结
|
|
void _showSummary() {
|
|
print('\n📊 生成总结');
|
|
print('-' * 40);
|
|
print('✅ 项目: ${ProjectConfig.projectName}');
|
|
print('✅ API 服务: ${ProjectConfig.apiServiceName}');
|
|
print('✅ 输出目录: ${ProjectConfig.outputDir}');
|
|
print('✅ 模块化 API: ${ProjectConfig.enableModularApis ? "启用" : "禁用"}');
|
|
print('✅ 基础响应类型: ${ProjectConfig.enableBaseResult ? "启用" : "禁用"}');
|
|
print('✅ 分页支持: ${ProjectConfig.enablePagination ? "启用" : "禁用"}');
|
|
print('✅ 文件上传: ${ProjectConfig.enableFileUpload ? "启用" : "禁用"}');
|
|
|
|
print('\n🎯 下一步:');
|
|
print('1. 运行 `flutter packages pub run build_runner build` 生成序列化代码');
|
|
print('2. 在项目中导入生成的 API 文件');
|
|
print('3. 参考 `api_example.dart` 中的使用示例');
|
|
print('4. 查看 `README.md` 了解 API 详情');
|
|
}
|
|
}
|