Skip to content

BLoC 状态管理

当前 Flutter 前端以 feature 为单位组织 BLoC。每个 feature 目录通常包含:

  • xxx_bloc.dart
  • xxx_event.dart
  • xxx_state.dart

BLoC 清单

BLoC负责范围主要状态 / 现象依赖页面
AuthBloc验证码发送、注册、密码登录、认证重置AuthInitial / AuthLoading / SmsCodeSent / RegistrationSuccess / AuthAuthenticated / AuthErrorPhoneInputScreenVerificationCodeScreenPasswordLoginScreen
SplashBloc启动时登录态检查与分流initial / checking / resolved + home/login 目标SplashScreen
OnboardingBloc多步建档流程、草稿/编辑、提交initial / inProgress / saving / submitting / completed / errorOnboardingFlowScreen
ProfileOverviewBloc我的页与首页所需档案摘要initial / loading / guest / loaded / errorHomeScreenProfilePagePersonalInfoScreen
AssessmentOverviewBloc首页今日状态摘要initial / loading / loaded / empty / errorDashboardPage
ChatBlocChat 消息流、会话列表、历史、切会话ChatLoading / ChatMessagesLoaded / ChatErrorChatScreenChatHistoryScreen
PrescriptionBloc当前处方、生成处方、处方错误Loading / Loaded / Generated / Error / GeneratingDashboardPageChatScreenExerciseScreen
ExerciseBloc运动中心、执行、日志保存、卡路里计算ExerciseLoading / ExerciseLoaded / ExecutionStarted / LogSaved / Error / CaloriesUpdatedExerciseScreenExerciseExecutionScreenExerciseFeedbackScreen
ExerciseHistoryBloc运动历史列表与分页loading / loaded / empty / error / deleting / custom addExerciseHistoryScreen
CalendarBloc日历月数据与选日详情CalendarLoading / CalendarLoaded / CalendarErrorCalendarScreen
HealthOverviewBloc健康总览、趋势、推荐Initial / Loading / Loaded / ErrorHealthOverviewScreen
CompanionBloc陪伴相关状态Companion feature 数据流伴随健康总览/陪伴相关页面
SafetyCheckBloc安全检查流程安全校验、风险确认modal / assessment 相关流程
DetailedAssessmentBloc详细评估表单评估过程与提交DetailedAssessmentModal
WeeklyReportBloc周报生成、预览、导出initial / loading / generated / error / export statesWeeklyReportScreen

当前模式

1. 事件驱动明确

  • 页面只负责发 event。
  • API、storage、数据转换等主要在 bloc 内或其依赖 client / service 中完成。

2. 状态风格并不完全统一

  • 一部分 feature 使用强类型枚举状态,例如 ProfileOverviewStateOnboardingState
  • 一部分 feature 使用多个离散 state class,例如 AuthStateHealthOverviewState
  • 这意味着跨 feature 的阅读体验不完全一致

3. 错误处理分布不统一

  • AuthBloc 倾向把错误压成 AuthError(message)
  • ChatBloc 多数错误回落到 ChatError 或直接打印日志
  • ExerciseBloc 错误更多通过 ExerciseError + SnackBar 呈现

4. 根部注册不等于当前主链可达

  • HealthOverviewBlocWeeklyReportBloc 等在代码中仍保留并注册,相关测试也存在。
  • 这说明状态实现可被继续维护,但不改变 HealthOverviewScreenWeeklyReportScreen 当前入口隐藏的产品口径。
  • 阅读 BLoC 清单时,应区分“状态模块存在”和“页面属于当前可达主链”。

新增或修改 BLoC 的判断

场景推荐处理
页面只有局部展开、输入框、开关等短生命周期状态优先留在 screen/widget 本地 state
状态需要跨页面、跨 tab、跨 API 请求或跨存储复用进入对应 feature BLoC
状态只服务 API response 转换,不参与 UI 状态流优先在 API client / model / helper 中处理
多个主业务域共同消费同一结果先确认是否已有 BLoC 承担该域,避免让页面直接协调多个 API
维护隐藏入口页保留原 BLoC 和测试,但文档不把它提升为当前主流程

交接时判断一个 BLoC 是否健康,重点看三件事:事件是否对应用户或业务动作,状态是否能解释页面的 loading / loaded / error / empty,依赖是否可注入并能被测试替换。

三个最关键的 BLoC

AuthBloc

  • 依赖:AuthApiClientFlutterSecureStorage
  • 作用:完成短信注册、密码注册、密码登录,并把 token / user_id 写入 secure storage
  • 特点:是前端“认证态入口”的核心块

ChatBloc

  • 依赖:ChatApiClient
  • 作用:管理当前会话 ID、消息列表、历史分页、会话切换、删除会话
  • 特点:会维护内存态 _messages_currentSessionId,不是纯无状态 bloc

ExerciseBloc

  • 依赖:SportApiClientPrescriptionApiClientFeedbackApiClientUserApiClientFlutterSecureStorage
  • 作用:加载当前处方、动作分类、执行开始、日志保存、MET/卡路里计算
  • 特点:一部分数据来自真实后端,一部分仍是本地 mock 构造

工程层面的关键事实

  • ChatBloc 已支持通过构造参数注入 ChatApiClient,测试中有明确 contract。
  • ExerciseBloc 依赖最多,是当前前端较重的业务 BLoC 之一。
  • ProfileOverviewBlocAssessmentOverviewBloc 共同支撑首页,说明首页不是“一个 bloc 管一切”的粗暴模式。
  • WeeklyReportBlocHealthOverviewBloc 的存在说明代码仍保留对应能力,不应在主流程文档中把它们写成当前入口。

这份清单的价值,不只是告诉读者项目里有哪些 BLoC,更在于帮助判断:

  • 某个需求应不应该进入新的 BLoC
  • 某个页面是不是已经承担了过多跨域状态
  • 某个修改会不会同时影响多个业务域

来源锚点

  • apps/flutter_app/lib/bloc/
  • apps/flutter_app/lib/bloc/auth/auth_bloc.dart
  • apps/flutter_app/lib/bloc/chat/chat_bloc.dart
  • apps/flutter_app/lib/bloc/exercise/exercise_bloc.dart
  • apps/flutter_app/lib/bloc/onboarding/onboarding_state.dart