Skip to content

模型生成

使用 flu-cli add model 命令生成数据模型类,支持从 JSON 自动生成。

基本用法

bash
flu-cli add model <name> [options]
flu-cli a model <name> [options]

参数

参数说明
--json <file>从 JSON 文件生成
-f, --feature所属功能模块

基础模型

创建模型

bash
flu-cli a model user

生成的代码

dart
class User {
  final String id;
  final String name;

  User({
    required this.id,
    required this.name,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as String,
      name: json['name'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
    };
  }
}

从 JSON 生成

创建 JSON 文件

bash
cat > user.json << 'EOF'
{
  "id": "1",
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "is_active": true,
  "tags": ["flutter", "dart"],
  "profile": {
    "avatar": "https://example.com/avatar.jpg",
    "bio": "Flutter developer"
  }
}
EOF

生成模型

bash
flu-cli a model user --json user.json

生成的代码

dart
class User {
  final String id;
  final String name;
  final String email;
  final int age;
  final bool isActive;
  final List<String> tags;
  final Profile profile;

  User({
    required this.id,
    required this.name,
    required this.email,
    required this.age,
    required this.isActive,
    required this.tags,
    required this.profile,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as String,
      name: json['name'] as String,
      email: json['email'] as String,
      age: json['age'] as int,
      isActive: json['is_active'] as bool,
      tags: (json['tags'] as List<dynamic>).cast<String>(),
      profile: Profile.fromJson(json['profile']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'email': email,
      'age': age,
      'is_active': isActive,
      'tags': tags,
      'profile': profile.toJson(),
    };
  }
}

class Profile {
  final String avatar;
  final String bio;

  Profile({
    required this.avatar,
    required this.bio,
  });

  factory Profile.fromJson(Map<String, dynamic> json) {
    return Profile(
      avatar: json['avatar'] as String,
      bio: json['bio'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'avatar': avatar,
      'bio': bio,
    };
  }
}

类型推断

flu-cli 会自动推断 JSON 中的类型:

JSON 值Dart 类型
"text"String
123int
123.45double
truebool
["a", "b"]List<String>
[1, 2]List<int>
{"key": "value"}嵌套对象

完整示例

创建复杂模型

json
{
    "id": "1",
    "title": "Flutter App",
    "description": "A new Flutter project",
    "price": 99.99,
    "is_published": true,
    "tags": ["mobile", "flutter"],
    "author": {
        "id": "author-1",
        "name": "John Doe",
        "email": "john@example.com"
    },
    "reviews": [
        {
            "id": "review-1",
            "rating": 5,
            "comment": "Great app!"
        }
    ],
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-02T00:00:00Z"
}

生成并完善

dart
class Product {
  final String id;
  final String title;
  final String description;
  final double price;
  final bool isPublished;
  final List<String> tags;
  final Author author;
  final List<Review> reviews;
  final DateTime createdAt;
  final DateTime updatedAt;

  Product({
    required this.id,
    required this.title,
    required this.description,
    required this.price,
    required this.isPublished,
    required this.tags,
    required this.author,
    required this.reviews,
    required this.createdAt,
    required this.updatedAt,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'] as String,
      title: json['title'] as String,
      description: json['description'] as String,
      price: (json['price'] as num).toDouble(),
      isPublished: json['is_published'] as bool,
      tags: (json['tags'] as List<dynamic>).cast<String>(),
      author: Author.fromJson(json['author']),
      reviews: (json['reviews'] as List<dynamic>)
          .map((e) => Review.fromJson(e))
          .toList(),
      createdAt: DateTime.parse(json['created_at']),
      updatedAt: DateTime.parse(json['updated_at']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'price': price,
      'is_published': isPublished,
      'tags': tags,
      'author': author.toJson(),
      'reviews': reviews.map((e) => e.toJson()).toList(),
      'created_at': createdAt.toIso8601String(),
      'updated_at': updatedAt.toIso8601String(),
    };
  }

  // 添加 copyWith 方法
  Product copyWith({
    String? id,
    String? title,
    String? description,
    double? price,
    bool? isPublished,
    List<String>? tags,
    Author? author,
    List<Review>? reviews,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return Product(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      price: price ?? this.price,
      isPublished: isPublished ?? this.isPublished,
      tags: tags ?? this.tags,
      author: author ?? this.author,
      reviews: reviews ?? this.reviews,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }

  @override
  String toString() {
    return 'Product(id: $id, title: $title, price: $price)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Product && other.id == id;
  }

  @override
  int get hashCode => id.hashCode;
}

最佳实践

1. 添加 copyWith

dart
Product copyWith({
  String? title,
  double? price,
}) {
  return Product(
    id: id,
    title: title ?? this.title,
    price: price ?? this.price,
    // ...
  );
}

2. 添加 toString

dart
@override
String toString() {
  return 'User(id: $id, name: $name, email: $email)';
}

3. 添加相等性比较

dart
@override
bool operator ==(Object other) {
  if (identical(this, other)) return true;
  return other is User && other.id == id;
}

@override
int get hashCode => id.hashCode;

4. 使用代码生成

对于复杂模型,考虑使用 json_serializable:

yaml
dependencies:
    json_annotation: ^4.8.0

dev_dependencies:
    build_runner: ^2.4.0
    json_serializable: ^6.7.0
dart
import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  final String id;
  final String name;

  User({required this.id, required this.name});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

下一步

Released under the MIT License.