diff --git a/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart b/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart index 04c429a1..f2d79311 100644 --- a/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart +++ b/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart @@ -16,14 +16,14 @@ import '../../../../tools/titleAppBar.dart'; import '../../../../translations/trans_lib.dart'; import 'faceList_logic.dart'; -class FaceList extends StatefulWidget { - const FaceList({Key? key}) : super(key: key); +class FaceListPage extends StatefulWidget { + const FaceListPage({Key? key}) : super(key: key); @override - State createState() => _FaceListState(); + State createState() => _FaceListPageState(); } -class _FaceListState extends State { +class _FaceListPageState extends State { final logic = Get.put(FaceListLogic()); final state = Get.find().state; diff --git a/star_lock/lib/main/lockDetail/iris/addIris/addIris_logic.dart b/star_lock/lib/main/lockDetail/iris/addIris/addIris_logic.dart new file mode 100644 index 00000000..4404283e --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIris/addIris_logic.dart @@ -0,0 +1,301 @@ +import 'dart:async'; + +// import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/blue/io_protocol/io_addFace.dart'; +import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/main/lockDetail/face/addFace/addFace_state.dart'; +import 'package:star_lock/tools/eventBusEventManage.dart'; + +import '../../../../../blue/blue_manage.dart'; +import '../../../../../blue/io_reply.dart'; +import '../../../../../blue/io_tool/io_tool.dart'; +import '../../../../../blue/io_tool/manager_event_bus.dart'; +import '../../../../../blue/sender_manage.dart'; +import '../../../../../network/api_repository.dart'; +import '../../../../../tools/baseGetXController.dart'; +import '../../../../../tools/storage.dart'; + +class AddIrisLogic extends BaseGetXController { + final AddFaceState state = AddFaceState(); + + // 监听设备返回的数据 + late StreamSubscription _replySubscription; + void _initReplySubscription() { + _replySubscription = + EventBusManager().eventBus!.on().listen((reply) async { + // 添加人脸开始 + if (reply is SenderAddFaceReply) { + _replyAddFaceBegin(reply); + } + + // 添加指纹过程 + if (reply is SenderAddFaceProcessReply) { + _replyAddFaceProcess(reply); + } + + // 添加指纹确认 + if (reply is SenderAddFaceConfirmationReply) { + _replyAddFaceConfirmation(reply); + } + }); + } + + Future _replyAddFaceBegin(Reply reply) async { + int status = reply.data[2]; + print("status:$status"); + + switch (status) { + case 0x00: + //成功 + // print("${reply.commandType!.typeValue} 人脸开始数据解析成功"); + state.ifConnectScuess.value = true; + + // 最大图片数 + state.maxRegCount.value = reply.data[10]; + print("人脸开始state.maxRegCount.value:${state.maxRegCount.value}"); + // state.fingerprintNumber.value = reply.data.last.toString(); + break; + case 0x06: + //无权限 + print("${reply.commandType!.typeValue} 需要鉴权"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + print("_replyAddFaceReplyToken:$token"); + Storage.setStringList(saveBlueToken, saveStrList); + + IoSenderManage.senderAddFaceCommand( + keyID: "1", + userID: await Storage.getUid(), + faceNo: 1, + useCountLimit: 0xff, + // startTime:0x11223344, + // endTime:0x11223344, + startTime: state.startDate.value ~/ 1000, + endTime: state.endDate.value ~/ 1000, + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: token, + ); + break; + case 0x07: + //无权限 + print("${reply.commandType!.typeValue} 用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType!.typeValue} 权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType!.typeValue} 失败"); + + break; + } + } + + Future _replyAddFaceProcess(Reply reply) async { + int status = reply.data[2]; + print("******33 status:$status"); + + switch (status) { + case 0x00: + //成功 + print("${reply.commandType!.typeValue} 注册人脸过程数据解析成功"); + if (reply.data[5] == 255) { + // 注册人脸失败 + print("${reply.commandType!.typeValue} 注册人脸过程失败"); + showToast("添加失败"); + Get.close(2); + } else { + // state.addFaceProcessNumber.value++; + + // 当前注册数 + state.regIndex.value = reply.data[6]; + print("注册人脸过程state.regIndex.value:${state.regIndex.value}"); + } + break; + case 0x06: + //需要权限 + + break; + case 0x07: + //无权限 + print("${reply.commandType!.typeValue} 用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType!.typeValue} 权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType!.typeValue} 注册人脸过程default失败"); + + break; + } + } + + Future _replyAddFaceConfirmation(Reply reply) async { + int status = reply.data[2]; + print("status:$status"); + + switch (status) { + case 0x00: + //成功 + print("${reply.commandType!.typeValue} 人脸确认数据解析成功"); + // print("添加人脸确认成功,调用添加指纹接口"); + if (state.faceNumber.value == (reply.data[6]).toString()) { + return; + } else { + state.faceNumber.value = (reply.data[6]).toString(); + } + addFaceData(); + break; + case 0x06: + //需要权限 + + break; + case 0x07: + //无权限 + print("${reply.commandType!.typeValue} 用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType!.typeValue} 权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType!.typeValue} 人脸确认default失败"); + + break; + } + } + + // 添加人脸开始 + Future senderAddFace() async { + showBlueConnetctToastTimer(action: () { + Get.close(1); + }); + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + cancelBlueConnetctToastTimer(); + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + print( + "openDoorTokenPubToken:$getTokenList state.startDate.value:${state.startDate.value}"); + print( + "限时人脸开始时间:${state.startDate.value ~/ 1000} 限时人脸结束时间:${state.endDate.value ~/ 1000}"); + + IoSenderManage.senderAddFaceCommand( + keyID: "1", + userID: await Storage.getUid(), + faceNo: state.isAdministrator.value == true ? 254 : 1, + useCountLimit: 0xff, + // startTime:0x11223344, + // endTime:0x11223344, + startTime: state.startDate.value ~/ 1000, + endTime: state.endDate.value ~/ 1000, + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList, + ); + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { + if (state.ifCurrentScreen.value == true) { + showBlueConnetctToast(); + } + cancelBlueConnetctToastTimer(); + Get.close(1); + } + }); + } + + // 添加人脸 + void addFaceData() async { + var entity = await ApiRepository.to.addFaceData( + lockId: state.lockId.value, + faceName: state.faceName.value, + faceNumber: state.faceNumber.value, + faceType: state.faceType.value, + startDate: state.startDate.value, + endDate: state.endDate.value, + featureData: state.featureData.value, + addType: state.addType.value, + cyclicConfig: state.cyclicConfig.value, + faceRight: state.isAdministrator.value == true ? 1 : 0, + ); + + if (entity.errorCode!.codeIsSuccessful) { + // Toast.show(msg: "添加成功"); + print('更新人脸用户账号成功了么1'); + updateFaceUserNoLoadData(entity.data!.faceId!); + } + } + + // 更新人脸用户账号 + void updateFaceUserNoLoadData(int faceId) async { + var entity = await ApiRepository.to.updateFaceUserNo( + faceId: faceId, + lockId: state.lockId.value, + faceUserNo: state.faceNumber.value, + ); + if (entity.errorCode!.codeIsSuccessful) { + print('更新人脸用户账号成功了么2'); + showToast("添加成功"); + if (state.fromType.value == 2) { + // 回调人脸号 + eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent( + state.faceNumber.value)); + } else if (state.fromType.value == 1) { + eventBus.fire(OtherTypeRefreshListEvent()); + } + Get.close(2); + } + } + + @override + void onReady() { + // TODO: implement onReady + super.onReady(); + + // _initReplySubscription(); + } + + @override + void onInit() { + // TODO: implement onInit + super.onInit(); +//开始添加后发送指令 + // senderAddFace(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + + // _replySubscription.cancel(); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIris/addIris_page.dart b/star_lock/lib/main/lockDetail/iris/addIris/addIris_page.dart new file mode 100644 index 00000000..552898ae --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIris/addIris_page.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/iris/addIris/addIris_logic.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/submitBtn.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; + +class AddIrisPage extends StatefulWidget { + const AddIrisPage({Key? key}) : super(key: key); + + @override + State createState() => _AddIrisPageState(); +} + +class _AddIrisPageState extends State { + final logic = Get.put(AddIrisLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: TitleAppBar( + barTitle: "${TranslationLoader.lanKeys!.addTip!.tr}虹膜", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: ListView( + children: [ + SizedBox( + height: 50.h, + ), + Obx(() => Image.asset( + state.isClickAddFace.value == false + ? 'images/main/icon_addFace_step1.png' + : 'images/main/icon_addFace_step2.png', + width: 100.w, + height: 457.h, + fit: BoxFit.fitHeight, + )), + SizedBox( + height: 60.h, + ), + Container( + padding: EdgeInsets.only(left: 20.w, right: 20.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Text( + "请单人正对门锁,距离一个成年人手臂长度\n(约0.6米)。\n保持脸部无遮挡,露出五官。", + textAlign: TextAlign.left, + maxLines: null, + style: + TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600), + ), + ), + ], + ), + ), + SizedBox( + height: 120.h, + ), + Obx( + () => state.isClickAddFace.value == false + ? Container( + padding: EdgeInsets.only(left: 20.w, right: 20.w), + child: SubmitBtn( + btnName: "准备好了,开始添加", + borderRadius: 20.w, + onClick: () { + state.isClickAddFace.value = true; + logic.senderAddFace(); + }), + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '正在录入中...', + style: TextStyle( + color: AppColors.darkGrayTextColor, + fontSize: 22.sp), + textAlign: TextAlign.center, + ) + ], + ), + ) + ], + ), + ); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIris/addIris_state.dart b/star_lock/lib/main/lockDetail/iris/addIris/addIris_state.dart new file mode 100644 index 00000000..6dbf77d0 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIris/addIris_state.dart @@ -0,0 +1,37 @@ +import 'package:get/get.dart'; + +class AddIrisState { + var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 + + var ifConnectScuess = false.obs; + var maxRegCount = 0.obs; // 最大注册次数 + var regIndex = 0.obs; // 当前注册次数 + + var faceNumber = "".obs; + + final lockId = 0.obs; + final endDate = 0.obs; + final addType = "".obs; + final faceName = "".obs; + final faceType = 0.obs; + final startDate = 0.obs; + final cyclicConfig = [].obs; + final fromType = 1.obs; + final featureData = ''.obs; + final isClickAddFace = false.obs; + final isAdministrator = false.obs; + + AddIrisState() { + Map map = Get.arguments; + lockId.value = map["lockId"]; + endDate.value = map["endDate"]; + addType.value = map["addType"]; + faceName.value = map["faceName"]; + faceType.value = map["faceType"]; + startDate.value = map["startDate"]; + lockId.value = map["lockId"]; + cyclicConfig.value = map["cyclicConfig"]; + fromType.value = map["fromType"]; + isAdministrator.value = map["isAdministrator"]; + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_page.dart b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_page.dart new file mode 100644 index 00000000..7ee02f0b --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_page.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_tabbar.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; + +class AddIrisTypeManagePage extends StatefulWidget { + const AddIrisTypeManagePage({Key? key}) : super(key: key); + + @override + State createState() => _AddIrisTypeManagePageState(); +} + +class _AddIrisTypeManagePageState extends State { + var index = 0; + + @override + Widget build(BuildContext context) { + Map map = Get.arguments; + var lockId = map["lockId"]; + var fromType = map["fromType"]; // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + var fromTypeTwoStaffName = ""; + if (fromType == 2) { + fromTypeTwoStaffName = map["fromTypeTwoStaffName"]; // 从添加员工进入 传入员工名字 + } + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: "${TranslationLoader.lanKeys!.addTip!.tr}虹膜", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: Column( + children: [ + AddIrisTypeManageTabbar( + lockId: lockId, + fromType: fromType, + fromTypeTwoStaffName: fromTypeTwoStaffName, + initialIndex: index), + ], + ), + ); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_tabbar.dart b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_tabbar.dart new file mode 100644 index 00000000..fa1f94e8 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisTypeManage/addIrisTypeManage_tabbar.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/iris/addIrisType/addIrisType_page.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/CustomUnderlineTabIndicator.dart'; +import '../../../../../translations/trans_lib.dart'; + +class AddIrisTypeManageTabbar extends StatefulWidget { + var initialIndex = 1; + var lockId = 0; + var fromType = 1; // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + var fromTypeTwoStaffName = ""; // 从添加员工进入 传入员工名字 + AddIrisTypeManageTabbar( + {Key? key, + required this.lockId, + required this.fromType, + required this.fromTypeTwoStaffName, + required this.initialIndex}) + : super(key: key); + + @override + State createState() => + _AddFaceTypeManageTabbarState(); +} + +class _AddFaceTypeManageTabbarState extends State + with SingleTickerProviderStateMixin { + late TabController _tabController; + + final List _itemTabs = [ + ItemView(title: TranslationLoader.lanKeys!.permanent!.tr, selectType: "0"), + ItemView(title: TranslationLoader.lanKeys!.timeLimit!.tr, selectType: "1"), + ItemView( + title: TranslationLoader.lanKeys!.circulation!.tr, selectType: "2"), + ]; + + final List _fromCheckInTypeItemTabs = [ + ItemView(title: TranslationLoader.lanKeys!.permanent!.tr, selectType: "0"), + ItemView(title: TranslationLoader.lanKeys!.timeLimit!.tr, selectType: "1"), + ]; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _tabController = TabController( + vsync: this, + length: _itemTabs.length, + initialIndex: widget.initialIndex); + + _tabController.addListener(() { + // print("_tabController.animation!.value:${_tabController.animation!.value} _tabController.index:${_tabController.index}"); + if (_tabController.animation!.value == _tabController.index) { + FocusScope.of(context).requestFocus(FocusNode()); + } + }); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Column( + children: [ + _tabBar(), + _pageWidget(), + ], + )); + } + + TabBar _tabBar() { + return TabBar( + controller: _tabController, + tabs: widget.fromType == 1 + ? _itemTabs.map((ItemView item) => _tab(item)).toList() + : _fromCheckInTypeItemTabs + .map((ItemView item) => _tab(item)) + .toList(), + isScrollable: true, + indicatorColor: Colors.red, + unselectedLabelColor: Colors.black, + unselectedLabelStyle: TextStyle( + color: AppColors.mainColor, + fontSize: 24.sp, + ), + automaticIndicatorColorAdjustment: true, + labelColor: AppColors.mainColor, + labelStyle: TextStyle( + color: AppColors.mainColor, + fontSize: 24.sp, + fontWeight: FontWeight.w600), + indicator: CustomUnderlineTabIndicator( + borderSide: BorderSide(color: AppColors.mainColor, width: 4.w), + strokeCap: StrokeCap.round, + width: 30.w), + ); + } + + Tab _tab(ItemView item) { + return Tab( + child: SizedBox( + width: 1.sw / 5, + child: Text(item.title, textAlign: TextAlign.center))); + } + + Widget _pageWidget() { + return Expanded( + child: TabBarView( + controller: _tabController, + children: widget.fromType == 1 + ? _itemTabs + .map((ItemView item) => AddIrisTypePage( + selectType: item.selectType, + lockId: widget.lockId, + fromType: widget.fromType, + fromTypeTwoStaffName: widget.fromTypeTwoStaffName)) + .toList() + : _itemTabs + .map((ItemView item) => AddIrisTypePage( + selectType: item.selectType, + lockId: widget.lockId, + fromType: widget.fromType, + fromTypeTwoStaffName: widget.fromTypeTwoStaffName)) + .toList(), + + // _itemTabs.map((ItemView item) => AddFaceTypePage(selectType: item.selectType, lockId: widget.lockId, fromType: widget.fromType, fromTypeTwoStaffName:widget.fromTypeTwoStaffName)).toList(), + ), + ); + } +} + +class ItemView { + const ItemView({required this.title, required this.selectType}); + + final String title; + final String selectType; +} diff --git a/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_logic.dart b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_logic.dart new file mode 100644 index 00000000..5a6972b4 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_logic.dart @@ -0,0 +1,99 @@ +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/face/addFaceType/addFaceType_state.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import '../../../../appRouters.dart'; +import '../../../../network/api_repository.dart'; + +class AddIrisTypeLogic extends BaseGetXController { + AddFaceTypeState state = AddFaceTypeState(); + + // 添加指纹 + void addFaceData() async { + var faceType = 0; // 永久:1;限时2,单次3,循环:4 + var startDate = ""; + var endDate = ""; + if (state.seletType.value == "0") { + faceType = 1; + startDate = "0"; + endDate = "0"; + } else if (state.seletType.value == "1") { + faceType = 2; + if (state.beginTimeTimestamp.value.isEmpty) { + showToast("请选择开始时间"); + return; + } + if (state.endTimeTimestamp.value.isEmpty) { + showToast("请选择结束时间"); + return; + } + + // if(DateTime.now().millisecondsSinceEpoch > int.parse(state.beginTimeTimestamp.value)){ + // Toast.show(msg: "生效时间要大于当前时间"); + // return; + // } + + if (int.parse(state.beginTimeTimestamp.value) >= + int.parse(state.endTimeTimestamp.value)) { + showToast("失效时间要大于生效时间"); + return; + } + + startDate = state.beginTimeTimestamp.value; + endDate = state.endTimeTimestamp.value; + } else if (state.seletType.value == "2") { + if (state.effectiveDateTime.value <= 0) { + showToast("请选择生效时间"); + return; + } + if (state.failureDateTime.value <= 0) { + showToast("请选择失效时间"); + return; + } + + if (state.weekdaysList.value.isEmpty) { + showToast("请选择有效日"); + return; + } + + // if(DateTime.now().millisecondsSinceEpoch >= state.effectiveDateTime.value){ + // Toast.show(msg: "生效时间要大于当前时间"); + // return; + // } + + if (state.effectiveDateTime.value >= state.failureDateTime.value) { + showToast("失效时间要大于生效时间"); + return; + } + startDate = state.effectiveDateTime.value.toString(); + endDate = state.failureDateTime.value.toString(); + faceType = 4; + } + + print( + "传出去的给你限时人脸开始时间:${int.parse(startDate) ~/ 1000} 限时人脸结束时间:${int.parse(endDate) ~/ 1000}"); + // 人脸 + Get.toNamed(Routers.addIrisPage, arguments: { + "lockId": state.lockId.value, + "endDate": int.parse(endDate), + "addType": "1", + "faceName": state.nameController.text, + "faceNumber": "123456", + "faceType": faceType, + "startDate": int.parse(startDate), + "cyclicConfig": state.weekdaysList.value, + "fromType": state.fromType.value, + "isAdministrator": state.isAdministrator.value, + }); + } + + // 校验指纹名字是否重复 + void checkFaceNameDuplicated(String faceName) async { + var entity = await ApiRepository.to.checkFaceNameDuplicatedData( + lockId: state.lockId.value.toString(), + faceName: faceName, + ); + if (entity.errorCode!.codeIsSuccessful) { + addFaceData(); + } + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_page.dart b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_page.dart new file mode 100644 index 00000000..7decf64e --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_page.dart @@ -0,0 +1,322 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/iris/addIrisType/addIrisType_logic.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; + +import '../../../../appRouters.dart'; +import '../../../../app_settings/app_colors.dart'; +import '../../../../tools/commonItem.dart'; +import '../../../../tools/storage.dart'; +import '../../../../tools/submitBtn.dart'; +import '../../../../translations/trans_lib.dart'; + +class AddIrisTypePage extends StatefulWidget { + final String selectType; // 永久限时循环下标 + final int lockId; + final int fromType; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + final String fromTypeTwoStaffName; // 从添加员工进入 传入员工名字 + + const AddIrisTypePage( + {Key? key, + required this.selectType, + required this.lockId, + required this.fromType, + required this.fromTypeTwoStaffName}) + : super(key: key); + + @override + State createState() => _AddFaceTypePageState(); +} + +class _AddFaceTypePageState extends State { + final logic = Get.put(AddIrisTypeLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + state.seletType.value = widget.selectType; + state.lockId.value = widget.lockId; + if (widget.fromTypeTwoStaffName.isNotEmpty) { + state.nameController.text = widget.fromTypeTwoStaffName; + } + state.fromType.value = widget.fromType; + + return indexChangeWidget(); + } + + Widget indexChangeWidget() { + switch (int.parse(widget.selectType)) { + case 0: + { + // 永久 + // return sendElectronicKeySucceed(); + return Column( + children: [ + perpetualKeyWidget( + TranslationLoader.lanKeys!.name!.tr, + TranslationLoader.lanKeys!.pleaseEnter!.tr, + state.nameController), + keyBottomWidget() + ], + ); + } + case 1: + { + // 限时 + return Column( + children: [ + perpetualKeyWidget( + TranslationLoader.lanKeys!.name!.tr, + TranslationLoader.lanKeys!.pleaseEnter!.tr, + state.nameController), + keyTimeLimitWidget(), + keyBottomWidget() + ], + ); + } + case 2: + { + // 循环 + return Column( + children: [ + perpetualKeyWidget( + TranslationLoader.lanKeys!.name!.tr, + TranslationLoader.lanKeys!.pleaseEnter!.tr, + state.nameController), + CommonItem( + leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, + rightTitle: "", + isHaveDirection: true, + action: () async { + Map result = await Get.toNamed( + Routers.electronicKeyPeriodValidityPage); + state.weekdaysList.value = result['validityValue']; + state.effectiveDateTime.value = + result['starDate'].millisecondsSinceEpoch; + state.failureDateTime.value = + result['endDate'].millisecondsSinceEpoch; + print( + '得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}'); + }), + SizedBox(height: 10.h), + keyBottomWidget() + ], + ); + } + default: + return Container(); + } + } + + // 密码命名输入框 + Widget perpetualKeyWidget( + String titleStr, String rightTitle, TextEditingController controller) { + return Column( + children: [ + Container(height: 10.h), + CommonItem( + leftTitel: titleStr, + rightTitle: "", + isHaveRightWidget: true, + rightWidget: getTFWidget(rightTitle)), + Container(height: 10.h), + ], + ); + } + + // 限时顶部选择日期 + Widget keyTimeLimitWidget() { + return Column( + children: [ + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, + rightTitle: state.beginTime.value, + isHaveLine: true, + isHaveDirection: true, + action: () async { + Pickers.showDatePicker(context, mode: DateMode.YMDHM, + onConfirm: (p) { + state.beginTime.value = + '${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}'; + state.beginTimeTimestamp.value = + DateTime.parse(state.beginTime.value) + .millisecondsSinceEpoch + .toString(); + }); + })), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, + rightTitle: state.endTime.value, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.YMDHM, + onConfirm: (p) { + state.endTime.value = + '${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}'; + state.endTimeTimestamp.value = + DateTime.parse(state.endTime.value) + .millisecondsSinceEpoch + .toString(); + }); + })), + Container(height: 10.h), + ], + ); + } + + Widget keyBottomWidget() { + return Column( + children: [ + // CommonItem( + // leftTitel: TranslationLoader.lanKeys!.face!.tr, + // rightTitle: "", + // isTipsImg: false, + // isHaveRightWidget: true, + // rightWidget: SizedBox( + // width: 60.w, height: 50.h, child: _isStressFingerprint())), + CommonItem( + leftTitel: "是否是管理员", + rightTitle: "", + isTipsImg: false, + isHaveRightWidget: true, + rightWidget: SizedBox( + width: 60.w, height: 50.h, child: Obx(() => _isAdmin()))), + SizedBox(height: 30.h), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.next!.tr, + onClick: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // print("state.selectType:${state.selectType.value}"); + if (state.nameController.text.isEmpty) { + logic.showToast("请输入姓名"); + return; + } + logic.checkFaceNameDuplicated(state.nameController.text); + } else { + // Get.toNamed(Routers.selectLockTypePage); + logic.showToast("演示模式"); + } + }), + ], + ); + } + + // 发送电子钥匙成功 + Widget sendElectronicKeySucceed() { + return Column( + children: [ + Container( + height: 300.h, + width: 1.sw, + color: Colors.white, + child: Column( + children: [ + SizedBox( + height: 30.h, + ), + Image.asset( + 'images/main/icon_main_addLock.png', + width: 150.w, + height: 150.w, + color: AppColors.mainColor, + ), + SizedBox( + height: 20.h, + ), + Text( + "操作成功,密码为", + style: TextStyle( + fontSize: 32.sp, + color: Colors.black, + fontWeight: FontWeight.w500), + ), + SizedBox( + height: 10.h, + ), + Text( + "62689876", + style: TextStyle( + fontSize: 60.sp, + color: Colors.black, + fontWeight: FontWeight.w500), + ), + ], + ), + ), + SizedBox( + height: 20.h, + ), + SubmitBtn( + btnName: '完成', + fontSize: 28.sp, + borderRadius: 20.w, + margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w), + padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + onClick: () {}), + SubmitBtn( + btnName: '分享', + fontSize: 28.sp, + borderRadius: 20.w, + margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w), + padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + onClick: () {}), + SubmitBtn( + btnName: '标记为:已入住', + fontSize: 28.sp, + borderRadius: 20.w, + margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w), + padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + onClick: () {}), + ], + ); + } + + // 接受者信息输入框 + Widget getTFWidget(String tfStr) { + return Container( + height: 50.h, + width: 300.w, + child: Row( + children: [ + Expanded( + child: TextField( + //输入框一行 + maxLines: 1, + controller: state.nameController, + autofocus: false, + textAlign: TextAlign.end, + decoration: InputDecoration( + //输入里面输入文字内边距设置 + contentPadding: const EdgeInsets.only(top: 12.0, bottom: 8.0), + hintText: tfStr, + hintStyle: TextStyle(fontSize: 24.sp), + //不需要输入框下划线 + border: InputBorder.none, + ), + ), + ), + SizedBox( + width: 10.w, + ), + ], + ), + ); + } + + // 是否是管理员 + CupertinoSwitch _isAdmin() { + return CupertinoSwitch( + activeColor: CupertinoColors.activeBlue, + trackColor: CupertinoColors.systemGrey5, + thumbColor: CupertinoColors.white, + value: state.isAdministrator.value, + onChanged: (value) { + state.isAdministrator.value = value; + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_state.dart b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_state.dart new file mode 100644 index 00000000..412ed2d0 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/addIrisType/addIrisType_state.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class AddFaceTypeState { + final lockId = 0.obs; + final seletType = "0".obs; // 0永久 1显示 2循环 + final fromType = 1.obs; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + var fromTypeTwoStaffName = "".obs; // 考勤添加人脸员工名字 + final isStressFingerprint = false.obs; + final isAdministrator = false.obs; // 是否是管理员 + + var beginTime = "".obs; // 开始时间 + var endTime = "".obs; // 结束时间 + var beginTimeTimestamp = "".obs; // 开始时间时间戳 + var endTimeTimestamp = "".obs; // 结束时间时间戳 + + var effectiveDateTime = 0.obs; // 生效时间 + var failureDateTime = 0.obs; // 失效时间 + var weekdaysList = [].obs; + + final TextEditingController nameController = TextEditingController(); + AddFaceTypeState() { + // Map map = Get.arguments; + // lockId.value = map["lockId"]; + // fromType.value = map["fromType"]; + // if(fromType.value == 2){ + // fromTypeTwoStaffName = map["fromTypeTwoStaffName"]; // 从添加员工进入 传入员工名字 + // // nameController.text = fromTypeTwoStaffName.value; + // } + + // print("lockId:${lockId.value} fromType:${fromType.value}"); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_logic.dart b/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_logic.dart new file mode 100644 index 00000000..e69de29b diff --git a/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_page.dart b/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_page.dart new file mode 100644 index 00000000..e69de29b diff --git a/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_state.dart b/star_lock/lib/main/lockDetail/iris/irisDetail/irisDetail_state.dart new file mode 100644 index 00000000..e69de29b diff --git a/star_lock/lib/main/lockDetail/iris/irisList/irisList_logic.dart b/star_lock/lib/main/lockDetail/iris/irisList/irisList_logic.dart new file mode 100644 index 00000000..42722238 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/irisList/irisList_logic.dart @@ -0,0 +1,445 @@ +import 'dart:async'; + +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:star_lock/blue/io_protocol/io_addFace.dart'; +import 'package:star_lock/blue/io_protocol/io_queryingFaceStatus.dart'; +import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/main/lockDetail/iris/irisList/irisList_state.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import '../../../../blue/blue_manage.dart'; +import '../../../../blue/io_protocol/io_checkingUserInfoCount.dart'; +import '../../../../blue/io_reply.dart'; +import '../../../../blue/io_tool/io_tool.dart'; +import '../../../../blue/io_tool/manager_event_bus.dart'; +import '../../../../blue/sender_manage.dart'; +import '../../../../network/api_repository.dart'; +import '../../../../tools/eventBusEventManage.dart'; +import '../../../../tools/storage.dart'; + +class IrisListLogic extends BaseGetXController { + IrisListState state = IrisListState(); + + // 获取解析后的数据 + late StreamSubscription _replySubscription; + void _initReplySubscription() { + _replySubscription = + EventBusManager().eventBus!.on().listen((reply) { + // 添加人脸开始(此处用作删除人脸) + if ((reply is SenderAddFaceReply) && (state.isDeletFaceData == true)) { + _replyAddFaceBegin(reply); + } + + if (reply is SenderQueryingFaceStatusReply) { + // 获取人脸状态 + _replyQueryingFaceStatus(reply); + } + + if (reply is SenderCheckingUserInfoCountReply) { + _replyCheckingUserInfoCount(reply); + } + }); + } + + // 添加人脸开始---这里用作删除人脸 + Future _replyAddFaceBegin(Reply reply) async { + int status = reply.data[2]; + print("status:$status"); + + switch (status) { + case 0x00: + //成功 + print("${reply.commandType!.typeValue} list人脸数据解析成功"); + state.isDeletFaceData = false; + cancelBlueConnetctToastTimer(); + dismissEasyLoading(); + if (state.isDeletAll == false) { + deletFacesData(); + } else { + clearAllFacesData(); + } + break; + case 0x06: + //无权限 + print("${reply.commandType!.typeValue} 需要鉴权"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderAddFaceCommand( + keyID: state.deletKeyID, + userID: state.deletUserID, + faceNo: state.deletFaceNo, + useCountLimit: 0, + startTime: 0x11223344, + endTime: 0x11223344, + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList, + ); + break; + case 0x07: + //无权限 + print("${reply.commandType!.typeValue} 用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType!.typeValue} 权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType!.typeValue} list人脸失败"); + + break; + } + } + + // 获取人脸状态 + Future _replyQueryingFaceStatus(Reply reply) async { + int status = reply.data[2]; + + switch (status) { + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + // _getLockStatus(); + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // 获取卡片状态 + Future _replyReferEventRecordNumber(Reply reply) async { + int status = reply.data[2]; + switch (status) { + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + // _getLockStatus(); + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // 查询用户、指纹、密码、卡片数量(用于判断是否同步) + Future _replyCheckingUserInfoCount(Reply reply) async { + int status = reply.data[2]; + + // 用户数量 + int userNum = reply.data[5]; + // print("userNum:$userNum"); + + // 指纹数量 + int fingerNum = reply.data[6]; + // print("fingerNum:$fingerNum"); + + // 密码数量 + int pwdNum = reply.data[7]; + + // 卡片数量 + int cardNum = reply.data[8]; + + // 记录数量 + int logsNum = reply.data[9]; + + // 版本 + int verNo = reply.data[10]; + + // 最大管理员指纹数量 + int maxAdminFingerNum = reply.data[11]; + + // 最大用户指纹数量 + int maxUserFingerNum = reply.data[12]; + + // 最大管理员密码数量 + int maxAdminPassNum = reply.data[13]; + + // 最大用户密码数量 + int maxUserPassNum = reply.data[14]; + + // 最大管理员卡片数量 + int maxAdminCardNum = reply.data[15]; + + // 最大用户卡片数量 + int maxUserCardNum = reply.data[16]; + + // 序列号 + var serialNo = reply.data.sublist(17, 21); + print("serialNo:$serialNo"); + + switch (status) { + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + // _getLockStatus(); + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // 获取人脸状态 + Future senderQueryingFaceStatus() async { + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState state) async { + if (state == BluetoothConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List getPublicKeyList = changeStringListToIntList(publicKey!); + + IoSenderManage.senderQueryingFaceStatusCommand( + keyID: BlueManage().connectDeviceName, + userID: await Storage.getUid(), + role: 0xff, + faceCount: 20, + faceNo: 1, + token: getTokenList, + needAuthor: 1, + publicKey: getPublicKeyList, + privateKey: getPrivateKeyList, + ); + } + }); + } + + // 查询用户、指纹、密码、卡片数量(用于判断是否同步) + Future senderCheckingUserInfoCount() async { + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState state) async { + if (state == BluetoothConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List getPublicKeyList = changeStringListToIntList(publicKey!); + + IoSenderManage.senderCheckingUserInfoCountCommand( + keyID: BlueManage().connectDeviceName, + userID: await Storage.getUid(), + role: 0xff, + nowTime: DateTime.now().millisecondsSinceEpoch ~/ 1000, + token: getTokenList, + needAuthor: 1, + publicKey: getPublicKeyList, + privateKey: getPrivateKeyList, + ); + } + }); + } + + // 删除人脸 + Future senderAddFace() async { + showEasyLoading(); + showBlueConnetctToastTimer(action: () { + dismissEasyLoading(); + }); + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderAddFaceCommand( + keyID: state.deletKeyID, + userID: state.deletUserID, + faceNo: state.deletFaceNo, + useCountLimit: 0, + startTime: 0x11223344, + endTime: 0x11223344, + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList, + ); + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + if (state.ifCurrentScreen.value == true) { + showBlueConnetctToast(); + } + } + }); + } + + // 获取人脸列表 + void getFaceListData() async { + var entity = await ApiRepository.to.getFaceListData( + lockId: state.lockId.value.toString(), + pageNo: '1', + pageSize: '20', + searchStr: state.searchController.text, + ); + if (entity.errorCode!.codeIsSuccessful) { + state.faceItemListData.value = entity.data!.list!; + } + } + + // 删除的人脸 + void deletFacesData() async { + var faceId = ""; + var type = "1"; + if (state.isDeletAll == false) { + faceId = state.deletKeyID; + type = "0"; + } + print("delet faceId $faceId"); + var entity = await ApiRepository.to.deleteFaceData( + faceId: int.parse(faceId), + lockId: state.lockId.value, + ); + if (entity.errorCode!.codeIsSuccessful) { + showToast("删除成功"); + state.isDeletFaceData = false; + getFaceListData(); + } + } + + // 重置所有的人脸 + void clearAllFacesData() async { + var faceId = ""; + var type = "1"; + if (state.isDeletAll == false) { + faceId = state.deletKeyID; + type = "0"; + } + print("delet faceId $faceId"); + var entity = await ApiRepository.to.clearFaceData( + lockId: state.lockId.value, + ); + if (entity.errorCode!.codeIsSuccessful) { + showToast("重置成功"); + state.isDeletFaceData = false; + getFaceListData(); + } + } + + // 监听修改完详情之后刷新列表 + late StreamSubscription _teamEvent; + void _initRefreshAction() { + _teamEvent = eventBus.on().listen((event) { + getFaceListData(); + }); + } + + @override + Future onReady() async { + // TODO: implement onReady + super.onReady(); + print("onReady()"); + + // 获取是否是演示模式 演示模式不获取接口 + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + // print("aaaaaaa:$isDemoMode"); + if (isDemoMode == false) { + _initReplySubscription(); + + _initRefreshAction(); + + getFaceListData(); + } + } + + @override + Future onInit() async { + // TODO: implement onInit + super.onInit(); + print("onInit()"); + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // senderQueryingFingerprintStatus(); + // senderCheckingCardStatus(); + + // senderCheckingUserInfoCount(); + } + } + + @override + Future onClose() async { + // TODO: implement onClose + super.onClose(); + + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + _replySubscription.cancel(); + _teamEvent.cancel(); + } + } +} diff --git a/star_lock/lib/main/lockDetail/iris/irisList/irisList_page.dart b/star_lock/lib/main/lockDetail/iris/irisList/irisList_page.dart new file mode 100644 index 00000000..da59cf6d --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/irisList/irisList_page.dart @@ -0,0 +1,280 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; +import 'package:star_lock/main/lockDetail/iris/irisList/irisList_logic.dart'; +import 'package:star_lock/tools/keySearchWidget.dart'; +import 'package:star_lock/tools/left_slide_actions.dart'; + +import '../../../../appRouters.dart'; +import '../../../../app_settings/app_colors.dart'; +import '../../../../tools/noData.dart'; +import '../../../../tools/showIosTipView.dart'; +import '../../../../tools/storage.dart'; +import '../../../../tools/submitBtn.dart'; +import '../../../../tools/titleAppBar.dart'; +import '../../../../translations/trans_lib.dart'; + +class IrisListPage extends StatefulWidget { + const IrisListPage({Key? key}) : super(key: key); + + @override + State createState() => _IrisListPageState(); +} + +class _IrisListPageState extends State { + final logic = Get.put(IrisListLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: '虹膜', + haveBack: true, + backgroundColor: AppColors.mainColor, + actionsList: [ + TextButton( + child: Text( + TranslationLoader.lanKeys!.reset!.tr, + style: TextStyle(color: Colors.white, fontSize: 24.sp), + ), + onPressed: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + showDeletAlertDialog(context); + } else { + // Get.toNamed(Routers.selectLockTypePage); + logic.showToast("演示模式"); + } + }, + ), + ], + ), + body: Column( + children: [ + KeySearchWidget( + editingController: state.searchController, + onSubmittedAction: () { + logic.getFaceListData(); + }, + ), + SizedBox( + height: 20.h, + ), + Expanded(child: _buildMainUI()), + AddBottomWhiteBtn( + btnName: '${TranslationLoader.lanKeys!.add!.tr}虹膜', + onClick: () async { + // var data = + // await Get.toNamed(Routers.addFaceTypeManagePage, arguments: { + // "lockId": state.lockId.value, + // "fromType": 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + // }); + var data = + await Get.toNamed(Routers.addIrisTypeManagePage, arguments: { + "lockId": state.lockId.value, + "fromType": 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + }); + if (data != null) { + logic.getFaceListData(); + } + }, + ), + SizedBox(height: 64.h) + ], + ), + ); + } + + Widget _buildMainUI() { + { + return Obx(() => state.faceItemListData.value.isNotEmpty + ? ListView.separated( + itemCount: state.faceItemListData.value.length, + itemBuilder: (c, index) { + FingerprintItemData getFaceItemData = + state.faceItemListData.value[index]; + // 人脸 + if (index < state.faceItemListData.value.length) { + return LeftSlideActions( + key: Key(getFaceItemData.faceName!), + actionsWidth: 60, + actions: [ + _buildDeleteBtn(getFaceItemData), + ], + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(1)), + ), + child: _keyItem( + 'images/icon_face.png', + getFaceItemData.faceName!, + (getFaceItemData.faceType! != 1) + ? (getFaceItemData.endDate! < + DateTime.now().millisecondsSinceEpoch + ? "已失效" + : "") + : "", + getFaceItemData.validTimeStr!, + // fingerprintItemData.fingerprintType! == 1 + // ? "永久" + // : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", + () async { + var data = + await Get.toNamed(Routers.faceDetailPage, arguments: { + "faceItemData": getFaceItemData, + }); + if (data != null) { + logic.getFaceListData(); + } + }), + ); + } + return const SizedBox.shrink(); + }, + separatorBuilder: (BuildContext context, int index) { + return const Divider( + height: 1, + color: AppColors.greyLineColor, + ); + }, + ) + : NoData(noDataHeight: 1.sh - ScreenUtil().statusBarHeight - 170.h)); + } + } + + Widget _buildDeleteBtn(FingerprintItemData faceItemData) { + return GestureDetector( + onTap: () { + // 省略: 弹出是否删除的确认对话框。 + state.deletKeyID = faceItemData.faceId.toString(); + state.deletFaceNo = int.parse(faceItemData.faceNumber!); + showIosTipViewDialog(context); + }, + child: Container( + width: 60, + color: const Color(0xFFF20101), + alignment: Alignment.center, + child: const Text( + '删除', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white, + height: 1, + ), + ), + ), + ); + } + + void showIosTipViewDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return ShowIosTipView( + title: "提示", + tipTitle: "确定要删除吗?", + sureClick: () async { + Get.back(); + state.isDeletFaceData = true; + state.isDeletAll = false; + state.deletUserID = (await Storage.getUid())!; + logic.senderAddFace(); + }, + cancelClick: () { + Get.back(); + }, + ); + }, + ); + } + + Widget _keyItem(String lockTypeIcon, String lockTypeTitle, + String ifInvalidation, String showTime, Function() action) { + return GestureDetector( + onTap: action, + child: Container( + height: 90.h, + // margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w), + color: Colors.white, + // decoration: BoxDecoration( + // color: Colors.white, + // // borderRadius: BorderRadius.circular(10.w), + // ), + child: Row( + children: [ + SizedBox(width: 30.w), + Image.asset(lockTypeIcon, width: 60.w, height: 60.w), + SizedBox(width: 20.w), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(lockTypeTitle, + style: TextStyle( + fontSize: 24.sp, color: AppColors.blackColor)), + Expanded(child: Container()), + Text(ifInvalidation, + style: TextStyle(fontSize: 22.sp, color: Colors.red)), + SizedBox(width: 10.w), + ], + ), + SizedBox(height: 5.h), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text(showTime, + style: TextStyle( + fontSize: 18.sp, + color: AppColors.placeholderTextColor)), + ], + ), + SizedBox(width: 20.h), + ], + ), + ), + SizedBox(width: 20.h), + ], + ), + ), + ); + } + + void showDeletAlertDialog(BuildContext context) { + showCupertinoDialog( + context: context, + builder: (context) { + return CupertinoAlertDialog( + title: const Text("提示"), + content: const Text('重置后,该锁的人脸都将被删除哦,确认要重置吗?'), + actions: [ + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.cancel!.tr), + onPressed: () { + Navigator.pop(context); + }, + ), + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.sure!.tr), + onPressed: () { + Navigator.pop(context); + state.isDeletFaceData = true; + state.isDeletAll = true; + state.deletKeyID = "1"; + state.deletUserID = "DeleteAll!@#"; + state.deletFaceNo = 255; + logic.senderAddFace(); + }, + ), + ], + ); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/iris/irisList/irisList_state.dart b/star_lock/lib/main/lockDetail/iris/irisList/irisList_state.dart new file mode 100644 index 00000000..ac926272 --- /dev/null +++ b/star_lock/lib/main/lockDetail/iris/irisList/irisList_state.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; + +class IrisListState { + final TextEditingController searchController = TextEditingController(); + final lockId = 0.obs; + + // 因为删除跟添加人脸用的同一个协议 所以这里用做判断 + var isDeletFaceData = false; + var isDeletAll = false; + var deletKeyID = ""; + var deletUserID = "DeleteAll!@#"; + var deletFaceNo = 0; + + final faceItemListData = [].obs; + + var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 + + IrisListState() { + Map map = Get.arguments; + lockId.value = map["lockId"]; + } +} diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart index db14ee45..6e51f024 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -672,13 +671,31 @@ class _LockDetailPageState extends State TranslationLoader.lanKeys!.humanFace!.tr, state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { - Get.toNamed(Routers.faceList, arguments: { + Get.toNamed(Routers.faceListPage, arguments: { "lockId": state.keyInfos.value.lockId, - }); // Toast.show(msg: "功能暂未开放"); + }); }), ); } + showWidgetArr.add( + bottomItem('images/main/icon_face.png', '虹膜', + state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + Get.toNamed(Routers.irisListPage, arguments: { + "lockId": state.keyInfos.value.lockId, + }); + }), + ); + + showWidgetArr.add( + bottomItem( + 'images/main/icon_face.png', + '手掌', + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, + () {}), + ); + //可视对讲门锁新增->监控 if (state.keyInfos.value.lockFeature!.videoIntercom == 1) { showWidgetArr.add( diff --git a/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart b/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart index 77b6edf8..5cd40acc 100644 --- a/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart +++ b/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart @@ -46,7 +46,7 @@ class _LockMonitoringPageState extends State { child: Container( width: 1.sw, height: 1.sh, - color: Colors.white, + // color: Colors.white, child: Stack( children: [ Obx(() { diff --git a/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart b/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart index ef881d66..39568fe0 100644 --- a/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart +++ b/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart @@ -292,7 +292,7 @@ class _DemoModeLockDetailPageState extends State { bottomItem('images/main/icon_face.png', '人脸', () { // gotoLogin(); - Get.toNamed(Routers.faceList, arguments: { + Get.toNamed(Routers.faceListPage, arguments: { "lockId": 1, }); }),