Files
biz_xfj_cloud/lib/pages/root/device_setup/view.dart
T
2026-09-04 16:23:30 +08:00

152 lines
5.6 KiB
Dart

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<DeviceSetupPage> createState() => _DeviceSetupPageState();
}
/// 首次设备绑定页面状态;绑定成功后进入统一业务终端工作区。
class _DeviceSetupPageState extends State<DeviceSetupPage> {
/// PC 设备管理中生成的服务端设备 ID 输入控制器。
final _controller = TextEditingController();
/// 是否正在提交绑定并加载角色配置,用于禁用重复操作。
bool _submitting = false;
/// 最近一次校验或服务端绑定错误;为空时不展示错误文案。
String? _error;
/// 释放设备 ID 输入控制器。
@override
void dispose() {
_controller.dispose();
super.dispose();
}
/// 校验设备 ID、绑定食堂或超市设备并进入业务终端工作区。
Future<void> _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<AppControl>().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<void> _logout() async {
await AppSettingTool.setUserSetting(UserSetting());
await Get.find<AppControl>().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 Icon(Icons.print_outlined,
size: 42, color: XfjDesignTokens.primary),
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,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
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('绑定并继续'),
),
],
),
],
),
),
),
),
),
),
),
);
}
}