import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; /// 登录后的食堂或超市服务端设备绑定页。 class DeviceSetupPage extends StatefulWidget { /// 创建登录后首次绑定服务端设备的页面。 const DeviceSetupPage({super.key}); /// 创建设备 ID 输入、提交和错误反馈状态。 @override State createState() => _DeviceSetupPageState(); } /// 首次设备绑定页面状态;绑定成功后进入统一业务终端工作区。 class _DeviceSetupPageState extends State { /// PC 设备管理中生成的服务端设备 ID 输入控制器。 final _controller = TextEditingController(); /// 是否正在提交绑定并加载角色配置,用于禁用重复操作。 bool _submitting = false; /// 最近一次校验或服务端绑定错误;为空时不展示错误文案。 String? _error; /// 释放设备 ID 输入控制器。 @override void dispose() { _controller.dispose(); super.dispose(); } /// 校验设备 ID、绑定食堂或超市设备并进入业务终端工作区。 Future _bind() async { final id = int.tryParse(_controller.text.trim()); if (id == null || id <= 0) { setState(() => _error = '请输入有效的设备 ID'); return; } setState(() { _submitting = true; _error = null; }); try { final bound = await AppSettingTool.bindSys(id); if (!bound) throw StateError('设备绑定失败,请确认设备 ID、单位以及后台绑定关系'); await Get.find().resumeAuthenticatedServices(); await AppMqTool.mqRefresh(); await SyncPrintTool.pullPendingTasks(); Get.offAllNamed(RouteNames.terminal); } catch (error) { if (mounted) { setState( () => _error = error.toString().replaceFirst('Bad state: ', ''), ); } } finally { if (mounted) { setState(() => _submitting = false); } } } /// 清理账号登录态并返回登录页,不保留未完成的设备绑定输入。 Future _logout() async { // 登录密码是否清除遵循基本设置里的手动退出忘记密码开关。 await AppSettingTool.applyManualLogoutPasswordPolicy(); await Get.find().suspendAuthenticatedServices(); Get.offAllNamed(RouteNames.login); } /// 构建适合终端横屏触控的设备 ID 绑定表单。 @override Widget build(BuildContext context) { return Scaffold( backgroundColor: XfjDesignTokens.canvas, body: SafeArea( child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 560), child: Padding( padding: const EdgeInsets.all(32), child: Material( color: XfjDesignTokens.surface, shape: RoundedRectangleBorder( side: const BorderSide(color: XfjDesignTokens.line), borderRadius: BorderRadius.circular(XfjDesignTokens.cardRadius), ), child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 20), const Text('绑定终端设备', style: TextStyle( fontSize: 28, fontWeight: FontWeight.w800, color: XfjDesignTokens.ink)), const SizedBox(height: 8), const Text('输入 PC 设备管理中创建的设备 ID', style: TextStyle( fontSize: 16, color: XfjDesignTokens.muted)), const SizedBox(height: 28), TextField( controller: _controller, enabled: !_submitting, // 系统软键盘在定制 ROM 上不可用,设备 ID 为纯数字。 keyboardType: TextInputType.none, textInputAction: TextInputAction.done, onTap: _submitting ? null : () => AppSoftKeyboard.show( context, controller: _controller, mode: AppSoftKeyboardMode.digits, allowPattern: RegExp('[0-9]'), semanticLabel: '设备 ID 数字键盘', ), onSubmitted: (_) => _bind(), decoration: InputDecoration( labelText: '设备 ID', errorText: _error, border: const OutlineInputBorder(), ), ), const SizedBox(height: 24), Row( children: [ TextButton( onPressed: _submitting ? null : _logout, child: const Text('退出登录')), const Spacer(), FilledButton.icon( onPressed: _submitting ? null : _bind, icon: _submitting ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2)) : const Icon(Icons.link), label: const Text('绑定并继续'), ), ], ), ], ), ), ), ), ), ), ), ); } }