Files
biz_xfj_cloud/lib/common/utils/app/app_face_tool.dart
T
2026-07-24 15:27:20 +08:00

130 lines
4.2 KiB
Dart

import 'package:common_utils/common_utils.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
abstract class AppFaceTool {
static const String _tag = "app 人脸工具";
// 跳转到人脸识别页面
static Future<bool> jumpFacePage() async {
if (AppRuntimeTool.useManualHardwareInput) return false;
final isJump = await FaceDiscernPlugs.jumpFaceDiscernPage();
if (!isJump) return false;
Future.delayed(const Duration(seconds: 2), () {
AppSubScreenTool.hide();
});
return true;
}
// 检查人脸激活参数
static bool validateSysFaceParams(SysSetting sysSetting) {
if (ObjectUtil.isEmpty(sysSetting.faceAppId)) {
return false;
}
if (ObjectUtil.isEmpty(sysSetting.faceSdkKey)) {
return false;
}
if (ObjectUtil.isEmpty(sysSetting.faceActiveKey)) {
return false;
}
return true;
}
// 批量注册人脸
static Future<bool> faceRegister({
String? userId,
bool forceRegister = false,
}) async {
if (AppRuntimeTool.useManualHardwareInput) return true;
var faceCount = await FaceDiscernPlugs.getFaceCount();
if (faceCount == 0 || forceRegister) {
final result = await FaceDiscernPlugs.rebuildFaceLibrary(
userId: userId,
);
if (result.failedSampleIds.isNotEmpty) {
logger.w('|$_tag|批量注册人脸失败数量:${result.failedSampleIds.length}');
}
}
faceCount = await FaceDiscernPlugs.getFaceCount();
if (faceCount == 0) return false;
return true;
}
// 是否激活人脸sdk
static Future<bool> isActiveSdk() async {
if (AppRuntimeTool.useManualHardwareInput) return true;
final status = await getStatus();
return status?.activated == true;
}
static Future<FacePluginStatus?> getStatus() async {
final setting = await AppSettingTool.getSysSetting();
// 参数完整性来自本地已同步配置,不依赖人脸硬件或原生通道;虚拟机和手动输入模式也应明确展示“等待同步配置”。
if (!validateSysFaceParams(setting)) {
return const FacePluginStatus(
activated: false,
activationCode: -1,
parametersComplete: false,
engineReady: false,
engineCode: -1,
databaseCount: 0,
memoryCount: 0,
registrationInProgress: false,
libraryConsistent: false,
);
}
if (AppRuntimeTool.useManualHardwareInput) return null;
return FaceDiscernPlugs.getFaceStatus(
appId: setting.faceAppId ?? '',
sdkKey: setting.faceSdkKey ?? '',
activeKey: setting.faceActiveKey ?? '',
);
}
/// 激活参数只来自后端同步后的系统设置,页面不接收也不展示密钥明文。
static Future<FaceActivationResult> activateSdk() async {
final setting = await AppSettingTool.getSysSetting();
if (!validateSysFaceParams(setting)) {
return const FaceActivationResult(
success: false,
code: -1,
message: '人脸插件参数不完整,请先同步设备配置',
requiresPermission: false,
canOpenSettings: false,
);
}
final permission = await Permission.phone.status;
if (!permission.isGranted) {
final requested = await Permission.phone.request();
if (!requested.isGranted) {
return FaceActivationResult(
success: false,
code: -1,
message: requested.isPermanentlyDenied
? '电话状态权限已被永久拒绝,请在系统设置中开启'
: '激活需要电话状态权限,请授权后重试',
requiresPermission: true,
canOpenSettings: requested.isPermanentlyDenied,
);
}
}
return FaceDiscernPlugs.activateFaceSdk(
appId: setting.faceAppId!,
sdkKey: setting.faceSdkKey!,
activeKey: setting.faceActiveKey!,
);
}
// 删除人脸
static Future<bool> removeFace({String? sampleId}) async {
if (sampleId == null) return false;
if (AppRuntimeTool.useManualHardwareInput) return true;
final isActive = await AppFaceTool.isActiveSdk();
if (!isActive) return false;
return await FaceDiscernPlugs.removeFace(sampleId: sampleId);
}
}