fix(app): 修复 P2~P4 共 10 项前端问题
P2 必须修复: - 教师布置主题 classId 从硬编码改为班级下拉选择器 - 班级日记墙使用服务端 classId 过滤替代前端过滤 - Profile 统计栏接入 JournalRepository 真实数据 - WeeklyPage 从全硬编码改为 JournalRepository 数据驱动 P3 建议改进: - 提取 mood_utils.dart 公共函数,消除 4 处重复定义 - 贴纸库搜索框连接 StickerBloc 按名称过滤 P4 细节打磨: - 家长页多孩子时显示 DropdownButton 选择器 - 搜索结果日记卡片点击跳转 /editor?id= - MonthlyPage 照片数量从 JournalElement 统计 - calendar_page/mood_page/search_page 统一使用 moodToEmoji/moodToLabel
This commit is contained in:
@@ -34,6 +34,7 @@ class IsarJournalRepository implements JournalRepository {
|
||||
int? pageSize,
|
||||
String? mood,
|
||||
String? tag,
|
||||
String? classId,
|
||||
}) async {
|
||||
var query = _isar.journalEntryCollections
|
||||
.where()
|
||||
@@ -58,6 +59,11 @@ class IsarJournalRepository implements JournalRepository {
|
||||
query = query.and().tagsJsonContains(tag);
|
||||
}
|
||||
|
||||
// 班级过滤
|
||||
if (classId != null) {
|
||||
query = query.and().classIdEqualTo(classId);
|
||||
}
|
||||
|
||||
// 按日期降序排列
|
||||
var results = await query
|
||||
.sortByDateEpochDesc()
|
||||
@@ -74,6 +80,15 @@ class IsarJournalRepository implements JournalRepository {
|
||||
return results.map(_fromCollection).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getJournalCount() async {
|
||||
return _isar.journalEntryCollections
|
||||
.where()
|
||||
.filter()
|
||||
.isDeletedEqualTo(false)
|
||||
.count();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<JournalEntry?> getJournal(String id) async {
|
||||
final col = await _isar.journalEntryCollections
|
||||
@@ -262,6 +277,7 @@ class IsarJournalRepository implements JournalRepository {
|
||||
..isPrivate = entry.isPrivate
|
||||
..sharedToClass = entry.sharedToClass
|
||||
..assignedTopicId = entry.assignedTopicId
|
||||
..contentExcerpt = entry.contentExcerpt
|
||||
..version = entry.version
|
||||
..createdAtEpoch = entry.createdAt.millisecondsSinceEpoch
|
||||
..updatedAtEpoch = entry.updatedAt.millisecondsSinceEpoch
|
||||
@@ -290,6 +306,7 @@ class IsarJournalRepository implements JournalRepository {
|
||||
isPrivate: col.isPrivate,
|
||||
sharedToClass: col.sharedToClass,
|
||||
assignedTopicId: col.assignedTopicId,
|
||||
contentExcerpt: col.contentExcerpt,
|
||||
version: col.version,
|
||||
createdAt: DateTime.fromMillisecondsSinceEpoch(col.createdAtEpoch),
|
||||
updatedAt: DateTime.fromMillisecondsSinceEpoch(col.updatedAtEpoch),
|
||||
|
||||
@@ -15,7 +15,7 @@ import '../models/journal_element.dart';
|
||||
/// - [dateFrom]/[dateTo]: 日期范围过滤(闭区间)
|
||||
/// - [page]/[pageSize]: 分页参数,从 1 开始
|
||||
abstract class JournalRepository {
|
||||
/// 获取日记列表(支持日期范围、心情、标签过滤和分页)
|
||||
/// 获取日记列表(支持日期范围、心情、标签、班级过滤和分页)
|
||||
Future<List<JournalEntry>> getJournals({
|
||||
DateTime? dateFrom,
|
||||
DateTime? dateTo,
|
||||
@@ -23,8 +23,12 @@ abstract class JournalRepository {
|
||||
int? pageSize,
|
||||
String? mood,
|
||||
String? tag,
|
||||
String? classId,
|
||||
});
|
||||
|
||||
/// 获取日记总数
|
||||
Future<int> getJournalCount();
|
||||
|
||||
/// 获取单篇日记(返回 null 表示不存在)
|
||||
Future<JournalEntry?> getJournal(String id);
|
||||
|
||||
@@ -66,6 +70,7 @@ class InMemoryJournalRepository implements JournalRepository {
|
||||
int? pageSize,
|
||||
String? mood,
|
||||
String? tag,
|
||||
String? classId,
|
||||
}) async {
|
||||
var results = _journals.values.toList();
|
||||
|
||||
@@ -87,6 +92,11 @@ class InMemoryJournalRepository implements JournalRepository {
|
||||
results = results.where((j) => j.tags.contains(tag)).toList();
|
||||
}
|
||||
|
||||
// 班级过滤
|
||||
if (classId != null) {
|
||||
results = results.where((j) => j.classId == classId).toList();
|
||||
}
|
||||
|
||||
// 按日期降序排列(最新在前)
|
||||
results.sort((a, b) => b.date.compareTo(a.date));
|
||||
|
||||
@@ -101,6 +111,9 @@ class InMemoryJournalRepository implements JournalRepository {
|
||||
return results;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getJournalCount() async => _journals.length;
|
||||
|
||||
@override
|
||||
Future<JournalEntry?> getJournal(String id) async {
|
||||
return _journals[id];
|
||||
|
||||
@@ -21,6 +21,7 @@ class RemoteJournalRepository implements JournalRepository {
|
||||
int? pageSize,
|
||||
String? mood,
|
||||
String? tag,
|
||||
String? classId,
|
||||
}) async {
|
||||
final queryParams = <String, dynamic>{};
|
||||
// 后端 NaiveDateTime 格式: "2026-06-01T00:00:00"(不带毫秒)
|
||||
@@ -34,6 +35,7 @@ class RemoteJournalRepository implements JournalRepository {
|
||||
if (pageSize != null) queryParams['page_size'] = pageSize;
|
||||
if (mood != null) queryParams['mood'] = mood;
|
||||
if (tag != null) queryParams['tag'] = tag;
|
||||
if (classId != null) queryParams['class_id'] = classId;
|
||||
|
||||
final response = await _api.get('/diary/journals', queryParams: queryParams);
|
||||
final body = response.data as Map<String, dynamic>;
|
||||
@@ -43,6 +45,16 @@ class RemoteJournalRepository implements JournalRepository {
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getJournalCount() async {
|
||||
final response = await _api.get('/diary/journals', queryParams: {
|
||||
'page': 1,
|
||||
'page_size': 1,
|
||||
});
|
||||
final body = response.data as Map<String, dynamic>;
|
||||
return (body['total'] as int?) ?? 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<JournalEntry?> getJournal(String id) async {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user