// 发现页 BLoC — 管理发现页数据加载状态 // // 职责:调用 /diary/discover API,解析响应,管理加载/成功/失败状态。 import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../data/remote/api_client.dart'; import '../models/discover_models.dart'; part 'discover_event.dart'; part 'discover_state.dart'; class DiscoverBloc extends Bloc { final ApiClient _api; DiscoverBloc({required ApiClient api}) : _api = api, super(const DiscoverInitial()) { on(_onLoadData); on(_onRefresh); } /// 首次加载 — 显示 loading 状态 Future _onLoadData( DiscoverLoadData event, Emitter emit, ) async { emit(const DiscoverLoading()); await _fetchData(emit); } /// 刷新 — 不显示 loading,静默更新 Future _onRefresh( DiscoverRefresh event, Emitter emit, ) async { await _fetchData(emit); } /// 通用数据获取逻辑 Future _fetchData(Emitter emit) async { try { final response = await _api.get('/diary/discover'); final body = response.data as Map; // 后端信封格式: { success, data: { ... }, message } final dataJson = body['data'] as Map? ?? {}; final discoverData = DiscoverData.fromJson(dataJson); emit(DiscoverLoaded(discoverData)); } on OfflineException { // 离线时,如果有已加载的数据,保留它 if (state is DiscoverLoaded) return; emit(const DiscoverError('网络不可用,请检查网络连接')); } catch (e) { if (state is DiscoverLoaded) return; emit(DiscoverError('加载失败:${_friendlyError(e)}')); } } /// 将异常转换为用户友好的错误消息 String _friendlyError(Object error) { final msg = error.toString(); if (msg.contains('SocketException') || msg.contains('Connection refused')) { return '无法连接服务器'; } if (msg.contains('401')) { return '登录已过期,请重新登录'; } if (msg.contains('403')) { return '没有访问权限'; } if (msg.contains('500')) { return '服务器错误,请稍后重试'; } return '请稍后重试'; } }