Skip to content

Data Models Explained

David Zhang edited this page Oct 4, 2020 · 3 revisions

数据模型主要是和论坛后端API提供的数据相对应。论坛后端API提供JSON格式的数据,Dart有JSON序列化的库,可通过build runner直接生成序列化代码,相关模型在https://github.com/BYR-App-Dev/byr_mobile_app/blob/master/lib/nforum/nforum_structures.darthttps://github.com/BYR-App-Dev/byr_mobile_app/blob/master/lib/nforum/nforum_structures.g.dart

一个常见的后端返回的JSON数据可见下面的十大数据(内容只保留1条) 接口为https://bbs.byr.cn/open/widget/topten.json

{
    "name": "topten",
    "title": "近期热门话题",
    "time": 1601798342,
    "article": [
        {
            "id": 322849,
            "group_id": 322849,
            "reply_id": 322849,
            "flag": "",
            "position": 0,
            "is_top": false,
            "is_subject": true,
            "has_attachment": false,
            "is_admin": false,
            "title": "有没有安徽安庆的朋友(33)",
            "user": {
                "id": "tititi",
                "user_name": "yiku",
                "face_url": "https://bbs.byr.cn/img/face_default_m.jpg",
                "face_width": 0,
                "face_height": 0,
                "gender": "m",
                "astro": "水瓶座",
                "life": 135,
                "qq": "",
                "msn": "",
                "home_page": "",
                "level": "用户",
                "is_online": false,
                "post_count": 53,
                "last_login_time": 1601784868,
                "last_login_ip": "10.28.198.*",
                "is_hide": false,
                "is_register": true,
                "score": 1745,
                "follow_num": 0,
                "fans_num": 0,
                "is_follow": false,
                "is_fan": false
            },
            "post_time": 1556619077,
            "board_name": "Anhui",
            "board_description": "情淮徽皖·安徽",
            "content": "有没有安徽安庆的朋友\n--\n\n",
            "attachment": {
                "file": [],
                "remain_space": "5MB",
                "remain_count": 20
            },
            "reply_count": 72,
            "last_reply_user_id": "hehe88",
            "last_reply_time": 1601797897,
            "id_count": "33"
        },
    ]
}

最基础的类有Pagination,这个和论坛后端一致,每个被分页的数据模型都包含一个Pagination类型的对象,这些可被分页的模型我们统一基类为PageableListBaseModel,该基类包含一个List,其中的单个数据为PageableBaseModel。

abstract class PageableBaseModel {}

abstract class PageableListBaseModel<T extends PageableBaseModel> {
  PageableListBaseModel({
    this.pagination,
    this.article,
  });

  PaginationModel pagination;
  List<T> article;
}

每个可被分页的数据都是包含一个叫article的list,和一个Pagination对象。

如果article是显示文章的(还可能显示投票、消息等),我们定义这层基类为ArticleListBaseModel,list中的article为ArticleBaseModel对象

@JsonSerializable()
class ArticleBaseModel extends PageableBaseModel {
  ArticleBaseModel({
    this.groupId,
    this.title,
    this.user,
    this.postTime,
    this.boardName,
  }) : super();

  @JsonKey(name: 'group_id')
  var groupId;
  String title;
  UserModel user;
  @JsonKey(name: 'post_time')
  var postTime;
  @JsonKey(name: 'board_name')
  var boardName;

  factory ArticleBaseModel.fromJson(Map<String, dynamic> json) => _$ArticleBaseModelFromJson(json);

  Map<String, dynamic> toJson() => _$ArticleBaseModelToJson(this);
}

abstract class ArticleListBaseModel<T extends ArticleBaseModel> extends PageableListBaseModel<T> {
  ArticleListBaseModel({
    this.pagination,
    this.article,
  }) : super(pagination: pagination, article: article);

  PaginationModel pagination;
  List<T> article;
}

于是一个具体的帖子的数据我们便可以定义为如下的ThreadModel

@JsonSerializable()
class ThreadModel extends ArticleListBaseModel<ThreadArticleModel> {
  ThreadModel({
    this.id,
    this.groupId,
    this.replyId,
    this.flag,
    this.position,
    this.isTop,
    this.isSubject,
    this.hasAttachment,
    this.isAdmin,
    this.title,
    this.user,
    this.postTime,
    this.boardName,
    this.boardDescription,
    this.likeSum,
    this.isLiked,
    this.votedownSum,
    this.isVotedown,
    this.hiddenByVotedown,
    this.collect,
    this.replyCount,
    this.lastReplyUserId,
    this.lastReplyTime,
    this.likeArticles,
    this.pagination,
    this.article,
  }) : super(
          pagination: pagination,
          article: article,
        );

  int id;
  @JsonKey(name: 'group_id')
  int groupId;
  @JsonKey(name: 'reply_id')
  int replyId;
  @JsonKey(name: 'flag')
  String flag;
  int position;
  @JsonKey(name: 'is_top')
  bool isTop;
  @JsonKey(name: 'is_subject')
  bool isSubject;
  @JsonKey(name: 'has_attachment')
  bool hasAttachment;
  @JsonKey(name: 'is_admin')
  bool isAdmin;
  String title;
  UserModel user;
  @JsonKey(name: 'post_time')
  int postTime;
  @JsonKey(name: 'board_name')
  String boardName;
  @JsonKey(name: 'board_description')
  String boardDescription;
  @JsonKey(name: 'like_sum')
  String likeSum;
  @JsonKey(name: 'is_liked')
  bool isLiked;
  @JsonKey(name: 'votedown_sum')
  String votedownSum;
  @JsonKey(name: 'is_votedown')
  bool isVotedown;
  @JsonKey(name: 'hidden_by_votedown')
  bool hiddenByVotedown;
  @JsonKey(name: 'collect')
  bool collect;
  @JsonKey(name: 'reply_count')
  int replyCount;
  @JsonKey(name: 'last_reply_user_id')
  String lastReplyUserId;
  @JsonKey(name: 'last_reply_time')
  int lastReplyTime;
  @JsonKey(name: 'like_articles')
  List<LikeArticleModel> likeArticles;
  PaginationModel pagination;
  List<ThreadArticleModel> article;

  factory ThreadModel.fromJson(Map<String, dynamic> json) => _$ThreadModelFromJson(json);

  Map<String, dynamic> toJson() => _$ThreadModelToJson(this);
}
Clone this wiki locally