items.dart 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import 'package:flutter/material.dart';
  2. abstract class ListItem {
  3. String get id;
  4. String get title;
  5. int get width;
  6. int get height;
  7. int get difficulty;
  8. int get rows => difficulty;
  9. int get cols => difficulty;
  10. bool get hard;
  11. String get thumb;
  12. String get image;
  13. String get cachePath => 'cache/$id.jpeg';
  14. String get jsonPath => 'work/$id.json';
  15. ValueNotifier notifier = ValueNotifier(0);
  16. // 新增:用于序列化
  17. Map<String, dynamic> toJson(); // 添加抽象方法,强制子类实现
  18. }
  19. /// assets图片, 内置图
  20. class AssetItem extends ListItem {
  21. @override
  22. final String id;
  23. @override
  24. final String title;
  25. @override
  26. final int width;
  27. @override
  28. final int height;
  29. @override
  30. final int difficulty;
  31. @override
  32. final bool hard;
  33. @override
  34. final String thumb;
  35. @override
  36. final String image;
  37. AssetItem(this.id, this.title, this.width, this.height, this.difficulty, this.hard, this.thumb, this.image);
  38. // 从JSON文件读取
  39. AssetItem.fromJSON(Map<String, dynamic> json)
  40. : id = json['_id'],
  41. title = json['title'] ?? '',
  42. width = json['width'],
  43. height = json['height'],
  44. difficulty = json['difficulty'],
  45. hard = json['hard'] ?? false,
  46. thumb = json['thumb'],
  47. image = json['raw'];
  48. @override
  49. String toString() {
  50. return 'AssetItem(id=$id, width=$width, height=$height, rows=$rows, cols=$cols, thumb=$thumb, image=$image';
  51. }
  52. @override
  53. Map<String, dynamic> toJson() => {'_id': id, 'width': width, 'height': height, 'difficulty': difficulty, 'hard': hard, 'thumb': thumb, 'raw': image};
  54. }
  55. class RemoteItem extends ListItem {
  56. @override
  57. final String id;
  58. @override
  59. final String title;
  60. @override
  61. final int width;
  62. @override
  63. final int height;
  64. @override
  65. final int difficulty;
  66. @override
  67. final bool hard;
  68. @override
  69. final String thumb;
  70. @override
  71. final String image;
  72. RemoteItem(this.id, this.title, this.width, this.height, this.difficulty, this.hard, this.thumb, this.image);
  73. factory RemoteItem.fromJSON(Map<String, dynamic> json) {
  74. // return RemoteItem(json['_id'], json['width'], json['height'], json['difficulty'], json['raw']);
  75. return RemoteItem(
  76. json['_id'],
  77. json['title'] ?? '',
  78. json['width'],
  79. json['height'],
  80. json['difficulty'] ?? 3,
  81. json['hard'] ?? false,
  82. json['thumb'],
  83. json['raw'],
  84. ); // 临时本地调试
  85. }
  86. @override
  87. Map<String, dynamic> toJson() => {
  88. '_id': id,
  89. 'title': title,
  90. 'width': width,
  91. 'height': height,
  92. 'difficulty': difficulty,
  93. 'hard': hard,
  94. 'thumb': thumb,
  95. 'raw': image,
  96. };
  97. }
  98. // 记录已完成作品的信息
  99. class Work extends ListItem {
  100. @override
  101. final String id; // 作品ID
  102. @override
  103. final String title; // 作品标题
  104. @override
  105. final int difficulty; // 难度 (rows/cols)
  106. @override
  107. final bool hard; // 是否困难模式
  108. @override
  109. final int width; // 原始图片宽度
  110. @override
  111. final int height; // 原始图片高度
  112. @override
  113. final String thumb;
  114. @override
  115. final String image;
  116. final DateTime completedTime; // 完成时间
  117. final Duration? timeSpent; // 完成耗时 (可选)
  118. Work({
  119. required this.id,
  120. required this.title,
  121. required this.difficulty,
  122. required this.hard,
  123. required this.width,
  124. required this.height,
  125. required this.thumb,
  126. required this.image,
  127. required this.completedTime,
  128. this.timeSpent,
  129. });
  130. // 序列化为 JSON
  131. @override
  132. Map<String, dynamic> toJson() {
  133. return {
  134. 'id': id,
  135. 'title': title,
  136. 'difficulty': difficulty,
  137. 'hard': hard,
  138. 'width': width,
  139. 'height': height,
  140. 'thumb': thumb,
  141. 'image': image,
  142. 'completedTime': completedTime.toIso8601String(), // 日期时间转为ISO字符串
  143. 'timeSpentSeconds': timeSpent?.inSeconds, // 耗时转为秒
  144. };
  145. }
  146. // 从 JSON 反序列化
  147. factory Work.fromJson(Map<String, dynamic> json) {
  148. return Work(
  149. id: json['id'],
  150. title: json['title'] ?? '',
  151. difficulty: json['difficulty'],
  152. hard: json['hard'] ?? false,
  153. width: json['width'],
  154. height: json['height'],
  155. thumb: json['thumb'],
  156. image: json['image'],
  157. completedTime: DateTime.parse(json['completedTime']),
  158. timeSpent: json['timeSpentSeconds'] != null ? Duration(seconds: json['timeSpentSeconds']) : null,
  159. );
  160. }
  161. // 从 ListItem 创建 Work
  162. factory Work.fromListItem(ListItem item, {Duration? timeSpent}) {
  163. return Work(
  164. id: item.id,
  165. title: item.title,
  166. difficulty: item.difficulty,
  167. hard: item.hard,
  168. width: item.width,
  169. height: item.height,
  170. thumb: item.thumb,
  171. image: item.image,
  172. completedTime: DateTime.now(),
  173. timeSpent: timeSpent,
  174. );
  175. }
  176. }