161 lines
6.2 KiB
Dart
161 lines
6.2 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.applyManualLogoutPasswordPolicy();
|
|
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 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('绑定并继续'),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|