import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ttstd_family_care/core/network/error_message.dart'; import 'package:ttstd_family_care/features/device/data/device_providers.dart'; /// 设备管理(绑定 / 解绑)操作状态。 /// /// [submitting] 表示正在请求中,用于禁用按钮并展示 loading; /// [alert] 为一次性提示文案,UI 展示后必须调用 [DeviceManageController.consumeAlert] 消费; /// [lastSuccess] 标记最近一次操作是否成功,供 UI 决定是否关闭页面。 class DeviceManageState { const DeviceManageState({ this.submitting = false, this.alert, this.lastSuccess = false, }); final bool submitting; final String? alert; final bool lastSuccess; DeviceManageState copyWith({ bool? submitting, String? alert, bool? lastSuccess, }) => DeviceManageState( submitting: submitting ?? this.submitting, alert: alert, lastSuccess: lastSuccess ?? this.lastSuccess, ); } /// 设备绑定 / 解绑控制器。 /// /// 页面级控制器,**不使用** keepAlive,随页面销毁自动释放(见 AGENTS.md §4)。 /// 操作成功后主动 `ref.invalidate(myDevicesProvider)` 刷新绑定列表。 class DeviceManageController extends Notifier { @override DeviceManageState build() => const DeviceManageState(); /// 绑定设备。[sn] 为设备序列号,[remark] 为可选备注名。 /// /// SN 为空等输入校验由 UI 层负责(便于使用本地化文案),此处只做兜底裁剪。 /// 返回是否绑定成功。 Future bind(String sn, {String? remark}) => _run(() => ref.read(deviceRepositoryProvider).bindDevice( sn.trim(), remark: remark?.trim(), )); /// 解绑设备。返回是否解绑成功。 Future unbind(String sn) => _run(() => ref.read(deviceRepositoryProvider).unbindDevice(sn)); /// 消费一次性提示,避免重复弹窗。 void consumeAlert() { if (state.alert != null) { state = state.copyWith(alert: null, lastSuccess: state.lastSuccess); } } /// 统一执行绑定/解绑请求:处理 submitting 开关、错误文案与列表刷新。 Future _run(Future Function() action) async { if (state.submitting) return false; state = state.copyWith(submitting: true, alert: null, lastSuccess: false); try { final error = await action(); if (error != null) { state = state.copyWith( submitting: false, alert: error, lastSuccess: false, ); return false; } // 绑定关系变化,刷新已绑定设备列表。 ref.invalidate(myDevicesProvider); state = state.copyWith(submitting: false, lastSuccess: true); return true; } catch (e) { // 统一文案映射,禁止直接 toString()(见 AGENTS.md §12)。 state = state.copyWith( submitting: false, alert: userMessageOf(e), lastSuccess: false, ); return false; } } } /// 设备管理控制器 Provider(页面级,不 keepAlive)。 final deviceManageControllerProvider = NotifierProvider( DeviceManageController.new, );