Files
nj/app/lib/features/achievement/bloc/achievement_bloc.dart
iven e57c3427a4 fix(app): 18 处 catch(e) 添加 debugPrint 异常日志
- parent_bloc: 6 处 (LoadChildren/BindChild/ViewJournals/ExportData/DeleteData/UnbindChild)
- search_bloc: 3 处 (SearchByMood/SearchByTag/SearchByKeyword)
- achievement_bloc: 1 处 (_fetchAchievements)
- sticker_bloc: 2 处 (_fetchPacks/fetchStickersInPack)
- template_bloc: 1 处 (_fetchTemplates)
- mood_bloc: 1 处 (_loadStats)
- home_bloc: 1 处 (_onLoadData)
- calendar_bloc: 1 处 (_onMonthChanged)
- sync_engine: 1 处 (trySync)
- weekly_page: 已有 debugPrint,无需修改
2026-06-02 23:21:16 +08:00

111 lines
2.8 KiB
Dart

// 成就 BLoC — 通过 API 加载成就列表
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:nuanji_app/data/remote/api_client.dart';
// ===== 模型 =====
/// 成就数据
class Achievement {
final String id;
final String code;
final String name;
final String? description;
final String? icon;
final String category;
final bool isUnlocked;
final DateTime? unlockedAt;
const Achievement({
required this.id,
required this.code,
required this.name,
this.description,
this.icon,
required this.category,
this.isUnlocked = false,
this.unlockedAt,
});
}
// ===== State =====
/// 成就页面状态
class AchievementState {
final List<Achievement> achievements;
final bool isLoading;
final String? errorMessage;
const AchievementState({
this.achievements = const [],
this.isLoading = false,
this.errorMessage,
});
int get unlockedCount =>
achievements.where((a) => a.isUnlocked).length;
AchievementState copyWith({
List<Achievement>? achievements,
bool? isLoading,
String? errorMessage,
}) =>
AchievementState(
achievements: achievements ?? this.achievements,
isLoading: isLoading ?? this.isLoading,
errorMessage: errorMessage,
);
}
// ===== BLoC =====
/// 成就 BLoC — ChangeNotifier 模式
class AchievementBloc extends ChangeNotifier {
final ApiClient _api;
AchievementState _state = const AchievementState();
AchievementState get state => _state;
AchievementBloc({required ApiClient api}) : _api = api;
/// 加载成就列表
void load() {
_state = _state.copyWith(isLoading: true);
notifyListeners();
_fetchAchievements();
}
Future<void> _fetchAchievements() async {
try {
final response = await _api.get('/diary/achievements');
final body = response.data as Map<String, dynamic>;
final list = body['data'] as List? ?? [];
final achievements = list.map((item) {
final m = item as Map<String, dynamic>;
return Achievement(
id: m['id'] as String,
code: m['code'] as String,
name: m['name'] as String,
description: m['description'] as String?,
icon: m['icon'] as String?,
category: m['category'] as String,
isUnlocked: m['is_unlocked'] as bool? ?? false,
unlockedAt: m['unlocked_at'] != null
? DateTime.tryParse(m['unlocked_at'] as String)
: null,
);
}).toList();
_state = _state.copyWith(isLoading: false, achievements: achievements);
} catch (e) {
debugPrint('AchievementBloc._fetchAchievements 失败: $e');
_state = _state.copyWith(
isLoading: false,
errorMessage: '加载成就列表失败',
);
}
notifyListeners();
}
}