import 'package:cupertino_ui/cupertino_ui.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/widgets/feature_ui.dart'; import '../../../core/widgets/settings_ui.dart'; import '../../../l10n/app_localizations.dart'; import 'device_manage_controller.dart'; /// 绑定设备页(手动输入 SN)。 /// /// 提供 SN / 备注名输入、「确认绑定」与「扫码绑定」两个入口。 /// 扫码入口跳转 `/device/scan`,扫描结果回填到 SN 输入框。 class DeviceBindPage extends ConsumerStatefulWidget { const DeviceBindPage({super.key, this.initialSn}); /// 由扫码页回传的初始 SN(可选)。 final String? initialSn; @override ConsumerState createState() => _DeviceBindPageState(); } class _DeviceBindPageState extends ConsumerState { late final TextEditingController _snController; final TextEditingController _remarkController = TextEditingController(); @override void initState() { super.initState(); _snController = TextEditingController(text: widget.initialSn ?? ''); } @override void dispose() { _snController.dispose(); _remarkController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final action = ref.watch(deviceManageControllerProvider); // 一次性错误提示:展示后立即消费。 ref.listen(deviceManageControllerProvider, (prev, next) { final alert = next.alert; if (alert == null) return; ref.read(deviceManageControllerProvider.notifier).consumeAlert(); AppDialogs.alert(context, message: alert, confirmText: l10n.commonConfirm); }); return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text(l10n.deviceBindTitle), leading: CupertinoButton( padding: EdgeInsets.zero, child: const Icon(CupertinoIcons.back), onPressed: () => context.pop(), ), ), child: SafeArea( child: ListView( padding: const EdgeInsets.only(top: 8, bottom: 24), children: [ CardBox( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( children: [ LabeledField( label: l10n.deviceBindSnLabel, controller: _snController, placeholder: l10n.deviceBindSnHint, keyboardType: TextInputType.text, ), LabeledField( label: l10n.deviceBindRemarkLabel, controller: _remarkController, placeholder: l10n.deviceBindRemarkHint, maxLength: 20, ), ], ), ), Padding( padding: const EdgeInsets.fromLTRB(22, 6, 22, 2), child: Text( l10n.deviceBindTip, style: const TextStyle(fontSize: 12, color: AppColors.sub, height: 1.5), ), ), const SizedBox(height: 6), PrimaryButton( text: l10n.deviceBindConfirm, loading: action.submitting, onPressed: () => _submit(l10n), ), SecondaryButton( text: l10n.deviceBindScan, icon: CupertinoIcons.qrcode_viewfinder, onPressed: action.submitting ? null : () => _openScanner(l10n), ), ], ), ), ); } /// 校验 SN 后提交绑定,成功则提示并返回上一页。 Future _submit(AppLocalizations l10n) async { final sn = _snController.text.trim(); if (sn.isEmpty) { await AppDialogs.alert( context, message: l10n.deviceBindSnEmpty, confirmText: l10n.commonConfirm, ); return; } final ok = await ref.read(deviceManageControllerProvider.notifier).bind( sn, remark: _remarkController.text, ); if (!ok || !mounted) return; await AppDialogs.alert( context, message: l10n.deviceBindSuccess, confirmText: l10n.commonConfirm, ); if (mounted) context.pop(); } /// 打开扫码页;扫描成功后把 SN 回填输入框。 Future _openScanner(AppLocalizations l10n) async { final code = await context.push('/device/scan'); if (code == null || code.isEmpty || !mounted) return; setState(() => _snController.text = code); } }