items.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:intl/intl.dart';
  4. abstract class ListItem {
  5. String get id;
  6. int get width;
  7. int get height;
  8. int get difficulty;
  9. int get rows => difficulty;
  10. int get cols => difficulty;
  11. bool get hard;
  12. String get thumb;
  13. String get image;
  14. String get cachePath => 'cache/$id.jpeg';
  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 int width;
  25. @override
  26. final int height;
  27. @override
  28. final int difficulty;
  29. @override
  30. final bool hard;
  31. @override
  32. final String thumb;
  33. @override
  34. final String image;
  35. AssetItem(this.id, this.width, this.height, this.difficulty, this.hard, this.thumb, this.image);
  36. // 从JSON文件读取
  37. AssetItem.fromJSON(Map<String, dynamic> json)
  38. : id = json['_id'],
  39. width = json['width'],
  40. height = json['height'],
  41. difficulty = json['difficulty'],
  42. hard = json['hard'] ?? false,
  43. thumb = json['thumb'],
  44. image = json['raw'];
  45. @override
  46. String toString() {
  47. return 'AssetItem(id=$id, width=$width, height=$height, rows=$rows, cols=$cols, thumb=$thumb, image=$image';
  48. }
  49. @override
  50. Map<String, dynamic> toJson() => {'_id': id, 'width': width, 'height': height, 'difficulty': difficulty, 'hard': hard, 'thumb': thumb, 'raw': image};
  51. }
  52. class RemoteItem extends ListItem {
  53. @override
  54. final String id;
  55. @override
  56. final int width;
  57. @override
  58. final int height;
  59. @override
  60. final int difficulty;
  61. @override
  62. final bool hard;
  63. @override
  64. final String thumb;
  65. @override
  66. final String image;
  67. RemoteItem(this.id, this.width, this.height, this.difficulty, this.hard, this.thumb, this.image);
  68. factory RemoteItem.fromJSON(Map<String, dynamic> json) {
  69. // return RemoteItem(json['_id'], json['width'], json['height'], json['difficulty'], json['raw']);
  70. return RemoteItem(
  71. json['_id'],
  72. json['width'],
  73. json['height'],
  74. json['difficulty'],
  75. json['hard'] ?? false,
  76. json['thumb'].replaceAll('localhost', '10.0.2.2'),
  77. json['raw'].replaceAll('localhost', '10.0.2.2'),
  78. ); // 临时本地调试
  79. }
  80. @override
  81. Map<String, dynamic> toJson() => {'_id': id, 'width': width, 'height': height, 'difficulty': difficulty, 'hard': hard, 'thumb': thumb, 'raw': image};
  82. }
  83. // 记录已完成作品的信息
  84. class Work extends ListItem {
  85. @override
  86. final String id; // 作品ID
  87. @override
  88. final int difficulty; // 难度 (rows/cols)
  89. @override
  90. final bool hard; // 是否困难模式
  91. @override
  92. final int width; // 原始图片宽度
  93. @override
  94. final int height; // 原始图片高度
  95. @override
  96. final String thumb;
  97. @override
  98. final String image;
  99. final DateTime completedTime; // 完成时间
  100. final Duration? timeSpent; // 完成耗时 (可选)
  101. Work({
  102. required this.id,
  103. required this.difficulty,
  104. required this.hard,
  105. required this.width,
  106. required this.height,
  107. required this.thumb,
  108. required this.image,
  109. required this.completedTime,
  110. this.timeSpent,
  111. });
  112. // 序列化为 JSON
  113. @override
  114. Map<String, dynamic> toJson() {
  115. return {
  116. 'id': id,
  117. 'difficulty': difficulty,
  118. 'hard': hard,
  119. 'width': width,
  120. 'height': height,
  121. 'thumb': thumb,
  122. 'image': image,
  123. 'completedTime': completedTime.toIso8601String(), // 日期时间转为ISO字符串
  124. 'timeSpentSeconds': timeSpent?.inSeconds, // 耗时转为秒
  125. };
  126. }
  127. // 从 JSON 反序列化
  128. factory Work.fromJson(Map<String, dynamic> json) {
  129. return Work(
  130. id: json['id'],
  131. difficulty: json['difficulty'],
  132. hard: json['hard'] ?? false,
  133. width: json['width'],
  134. height: json['height'],
  135. thumb: json['thumb'],
  136. image: json['image'],
  137. completedTime: DateTime.parse(json['completedTime']),
  138. timeSpent: json['timeSpentSeconds'] != null ? Duration(seconds: json['timeSpentSeconds']) : null,
  139. );
  140. }
  141. // 从 ListItem 创建 Work
  142. factory Work.fromListItem(ListItem item, {Duration? timeSpent}) {
  143. return Work(
  144. id: item.id,
  145. difficulty: item.difficulty,
  146. hard: item.hard,
  147. width: item.width,
  148. height: item.height,
  149. thumb: item.thumb,
  150. image: item.image,
  151. completedTime: DateTime.now(),
  152. timeSpent: timeSpent,
  153. );
  154. }
  155. }