fix(app): Phase 1.1 紧急修复 — SyncEngine 接入 + authorId + catch 异常处理
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled

- feat(sync): SyncEngine 接入 EditorPage, 保存时 enqueue + 网络恢复自动 trySync
- fix(editor): authorId 从 AuthBloc 获取, 替代硬编码 'local'
- fix(bloc): class_bloc/calendar/profile/parent catch(_).全部改为 debugPrint
- feat(editor): 编辑器工具栏拆分 (brush_panel/tag_panel/text_format_bar/dot_grid_painter)
- feat(editor): EditorBloc 扩展 + EditorPage 增强
- feat(search): SearchBloc 扩展搜索功能
- feat(home): HomeBloc/HomePage 增强
- feat(auth): LoginPage 增强
- feat(templates): TemplateGalleryPage 重构
- fix(web): 管理端班级/日记页面修复
- fix(server): comment_service + theme_handler 修复
- docs: 添加全链路审计报告和验证截图
This commit is contained in:
iven
2026-06-02 21:21:43 +08:00
parent 7e928ae1e1
commit 49d4aa36a7
55 changed files with 2738 additions and 677 deletions

View File

@@ -54,6 +54,9 @@ final class HomeLoaded extends HomeState {
/// 总日记数spec §3.4 quick-stats
final int totalCount;
/// 今日天气从今日日记中提取null 则默认晴)
final Weather? todayWeather;
const HomeLoaded({
this.recentJournals = const [],
this.hasTodayEntry = false,
@@ -61,6 +64,7 @@ final class HomeLoaded extends HomeState {
this.streakDays = 0,
this.monthCount = 0,
this.totalCount = 0,
this.todayWeather,
});
}
@@ -111,10 +115,21 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
// 推算连续天数
final streakDays = _calculateStreak(journals);
// 本月日记数 & 总数spec §3.4 quick-stats
// 本月日记数spec §3.4 quick-stats
final monthCount = journals.where((j) =>
j.date.year == today.year && j.date.month == today.month).length;
final totalCount = journals.length;
// 总日记数 — 使用仓库计数方法(不受分页限制)
final totalCount = await _journalRepo.getJournalCount();
// 今日天气 — 从今日日记中提取
final todayJournal = journals.firstWhere(
(j) => j.date.year == today.year &&
j.date.month == today.month &&
j.date.day == today.day,
orElse: () => journals.first, // fallback for type safety
);
final todayWeather = hasTodayEntry ? todayJournal.weather : null;
emit(HomeLoaded(
recentJournals: journals,
@@ -123,6 +138,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
streakDays: streakDays,
monthCount: monthCount,
totalCount: totalCount,
todayWeather: todayWeather,
));
} catch (e) {
emit(const HomeLoaded()); // 空状态而非错误,离线友好

View File

@@ -100,7 +100,7 @@ class _HomeView extends StatelessWidget {
_MoodSelectorCard(
topMood: state.topMood,
weather: const _Weather(icon: '', label: '晴 26°'),
todayWeather: state.todayWeather,
onMoodTap: (_) => context.push('/editor'),
),
const SizedBox(height: DesignTokens.spacing20),
@@ -261,12 +261,12 @@ class _StreakBadge extends StatelessWidget {
class _MoodSelectorCard extends StatelessWidget {
const _MoodSelectorCard({
required this.topMood,
required this.weather,
required this.todayWeather,
required this.onMoodTap,
});
final Mood? topMood;
final _Weather weather;
final Weather? todayWeather;
final ValueChanged<Mood> onMoodTap;
static const _moods = [
@@ -277,6 +277,14 @@ class _MoodSelectorCard extends StatelessWidget {
('🤔', '思考', Mood.thinking),
];
static const _weatherMap = {
Weather.sunny: ('', ''),
Weather.cloudy: ('', '多云'),
Weather.rainy: ('🌧', ''),
Weather.snowy: ('', ''),
Weather.windy: ('💨', ''),
};
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
@@ -306,10 +314,13 @@ class _MoodSelectorCard extends StatelessWidget {
),
),
const Spacer(),
Text(
'${weather.icon} ${weather.label}',
style: TextStyle(fontSize: 13, color: theme.colorScheme.onSurfaceVariant),
),
Builder(builder: (context) {
final w = _weatherMap[todayWeather] ?? _weatherMap[Weather.sunny]!;
return Text(
'${w.$1} ${w.$2}',
style: TextStyle(fontSize: 13, color: theme.colorScheme.onSurfaceVariant),
);
}),
],
),
const SizedBox(height: DesignTokens.spacing12),
@@ -376,12 +387,6 @@ class _MoodOption extends StatelessWidget {
}
}
class _Weather {
const _Weather({required this.icon, required this.label});
final String icon;
final String label;
}
/// 4. "今天的日记" 渐变卡片 + 浮动写按钮
class _TodayCard extends StatelessWidget {
const _TodayCard({required this.hasTodayEntry, required this.onTap});
@@ -621,7 +626,9 @@ class _JournalCard extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final moodColor = AppColors.moodColors[journal.mood.value] ?? AppColors.accent;
final excerpt = journal.tags.isEmpty ? '点击查看详情' : journal.tags.take(3).map((t) => '#$t').join(' ');
final excerpt = journal.contentExcerpt?.isNotEmpty == true
? journal.contentExcerpt!
: (journal.tags.isEmpty ? '点击查看详情' : journal.tags.take(3).map((t) => '#$t').join(' '));
return Material(
color: theme.colorScheme.surface,