Files
biz_xfj_cloud/lib/common/utils/app/terminal_navigation_tool.dart
T

101 lines
3.4 KiB
Dart

import 'package:common_utils/common_utils.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
/// 新终端侧边栏的统一导航守卫。
///
/// 统一终端导航仍需保留设备绑定、联网限制和设置密码校验,
/// 否则视觉重构会意外放开原有业务入口。
abstract final class TerminalNavigationTool {
/// 终端工作区使用独立导航栈,避免切换菜单时重建顶部状态栏和侧边栏。
static const navigatorId = 1;
static bool _verificationInProgress = false;
static Future<void> open(String route) async {
if (_requiresAdminUnlock(route)) {
if (!await _verifyAdminSession(actionLabel: '进入设置')) return;
_replaceWorkspace(route);
return;
}
if (!await _checkIsBind()) return;
if (_requiresNetwork(route) && !AppNetworkTool.isAutoNetwork()) {
Toast.error(msg: '请先连接网络');
return;
}
_replaceWorkspace(route);
}
/// 仅替换终端二级页面,保留一级外壳及应用级资源。
static void replaceWorkspace(String route) => _replaceWorkspace(route);
static void _replaceWorkspace(String route) {
Get.offAllNamed(route, id: navigatorId);
}
/// 退出前统一执行管理密码校验,避免侧栏与顶栏出口出现不同的安全规则。
static Future<void> logout() async {
if (!await _verifyAdminSession(actionLabel: '退出登录')) return;
Get.find<TerminalAdminSessionControl>().lock();
if (AppNetworkTool.isAutoNetwork()) {
// await AppSettingTool.setUserSetting(UserSetting());
}
Get.offAllNamed(RouteNames.login);
}
/// 顶栏锁状态可主动发起验证,不需要先进入设置或退出流程。
static Future<void> unlockAdminSession() async {
await _verifyAdminSession(actionLabel: '解锁管理操作');
}
static Future<bool> _verifyAdminSession({
required String actionLabel,
}) async {
final session = Get.find<TerminalAdminSessionControl>();
if (session.isUnlocked) return true;
session.lock();
// 快速连续点击设置与退出时只允许存在一个密码弹层,避免重复 Overlay 和 GlobalKey。
if (_verificationInProgress) return false;
final context = Get.context;
if (context == null) return false;
_verificationInProgress = true;
try {
final verified = await terminalAdminPasswordDialog(
context,
actionLabel: actionLabel,
);
// 弹层取消与验证成功都要等退场结束,避免快速再次点击叠加两个 Overlay。
await Future<void>.delayed(const Duration(milliseconds: 200));
if (!verified) return false;
session.unlock();
return true;
} finally {
_verificationInProgress = false;
}
}
/// 查询菜单是学生本人自助入口,不纳入管理密码校验。
static bool _requiresAdminUnlock(String route) {
return route == RouteNames.setting;
}
static bool _requiresNetwork(String route) {
return route == RouteNames.menuQuery ||
route == RouteNames.canteenReserve ||
route == RouteNames.takeFood ||
route == RouteNames.canteenOrderTotal;
}
static Future<bool> _checkIsBind() async {
final setting = await AppSettingTool.getSysSetting();
if (ObjectUtil.isEmpty(setting.serviceMerchantId)) {
Toast.error(msg: '请前往设置绑定设备');
return false;
}
return true;
}
}