import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:vitalapp/architecture/utils/prompt_box.dart'; import 'package:vitalapp/components/alert_dialog.dart'; import 'package:vitalapp/rpc.dart'; import 'package:vitalapp/store/store.dart'; import 'package:fis_common/extensions/string.dart'; import 'package:fis_common/logger/logger.dart'; import 'controller.dart'; import 'facial_recognition_capturer.dart'; class FacialRecognitionControllerPlus extends FacialRecognitionController { FacialRecognitionControllerPlus({required super.mode, super.patientInfo}); FacialRecognitionCapturer? facialRecognitionCapturer; @override void doFacialRecognition() async { facialRecognitionCapturer = FacialRecognitionCapturer(); final capturer = facialRecognitionCapturer!; capturer.frameCachedEvent.addListener((sender, e) { if (e.isNotEmpty) { // 更新预览图像 state.processingImageLocalPath = e; } }); capturer.successEvent.addListener(_onCaptureSuccess); capturer.failEvent.addListener(_onCaptureFail); capturer.timeoutEvent.addListener(_onCaptureTimeout); await capturer.init(kCameraController, faceDetector); await capturer.run(); } @override void doCancelCapture() { facialRecognitionCapturer?.stop(); facialRecognitionCapturer = null; super.doCancelCapture(); } @override void dispose() { // TODO: implement dispose super.dispose(); } void _onCaptureSuccess(_, String e) async { try { // url让RPC分析 PatientBaseDTO result = await rpc.vitalPatient.getPatientBaseByFaceImageAsync( GetPatientBaseByFaceImageRequest( token: Store.user.token, image: e, ), ); final type = result.faceScanErrorType; if (type == FaceScanErrorTypeEnum2.Success) { doCancelCapture(); finishFaceDetection(result); } else if (type == FaceScanErrorTypeEnum2.NoCreated) { doCancelCapture(); await Get.dialog( VAlertDialog( title: "提示", width: 500, showCancel: false, content: Container( height: 32, padding: const EdgeInsets.symmetric(horizontal: 24), alignment: Alignment.center, child: const Text( "未检测到当前人脸匹配的身份证,请先录入身份证信息", style: TextStyle(fontSize: 20), ), ), onConfirm: () { Get.back(); }, ), barrierDismissible: false, barrierColor: Colors.black.withOpacity(.4), ); Get.back(); } else { if (result.errorMessage.isNotNullOrEmpty) { logger.e(result.errorMessage!); } PromptBox.toast('无法识别面部信息,请确保面部清晰可见'); _continueCapture(); } } catch (e) { logger.e("FacialRecognitionController onCaptureSuccess handle error.", e); PromptBox.toast('无法识别面部信息'); _continueCapture(); } finally { state.processingImageLocalPath = ''; } } void _onCaptureFail(_, e) async { facialRecognitionCapturer?.callPause(); // 错误提示 PromptBox.toast(e.message); // 给错误提示一点显示时间 await Future.delayed(const Duration(milliseconds: 1000)); facialRecognitionCapturer?.callContinue(); } void _onCaptureTimeout(_, e) { // 结束 PromptBox.toast('人脸识别失败,请先录入人脸信息或更新人脸信息'); doCancelCapture(); } /// 发送继续采集信号 void _continueCapture() { facialRecognitionCapturer?.callContinue(); } }