1,锁详情页新增虹膜、手掌的入口
2,新增虹膜列表页面 3,新增添加永久、限时、循环类型虹膜界面 4,新增添加虹膜手势过程页面
This commit is contained in:
parent
fbb102eca3
commit
10f1496d57
@ -16,14 +16,14 @@ import '../../../../tools/titleAppBar.dart';
|
|||||||
import '../../../../translations/trans_lib.dart';
|
import '../../../../translations/trans_lib.dart';
|
||||||
import 'faceList_logic.dart';
|
import 'faceList_logic.dart';
|
||||||
|
|
||||||
class FaceList extends StatefulWidget {
|
class FaceListPage extends StatefulWidget {
|
||||||
const FaceList({Key? key}) : super(key: key);
|
const FaceListPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FaceList> createState() => _FaceListState();
|
State<FaceListPage> createState() => _FaceListPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FaceListState extends State<FaceList> {
|
class _FaceListPageState extends State<FaceListPage> {
|
||||||
final logic = Get.put(FaceListLogic());
|
final logic = Get.put(FaceListLogic());
|
||||||
final state = Get.find<FaceListLogic>().state;
|
final state = Get.find<FaceListLogic>().state;
|
||||||
|
|
||||||
|
|||||||
301
star_lock/lib/main/lockDetail/iris/addIris/addIris_logic.dart
Normal file
301
star_lock/lib/main/lockDetail/iris/addIris/addIris_logic.dart
Normal file
@ -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<Reply> _replySubscription;
|
||||||
|
void _initReplySubscription() {
|
||||||
|
_replySubscription =
|
||||||
|
EventBusManager().eventBus!.on<Reply>().listen((reply) async {
|
||||||
|
// 添加人脸开始
|
||||||
|
if (reply is SenderAddFaceReply) {
|
||||||
|
_replyAddFaceBegin(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加指纹过程
|
||||||
|
if (reply is SenderAddFaceProcessReply) {
|
||||||
|
_replyAddFaceProcess(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加指纹确认
|
||||||
|
if (reply is SenderAddFaceConfirmationReply) {
|
||||||
|
_replyAddFaceConfirmation(reply);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _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<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> 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<void> _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<void> _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<void> 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<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
95
star_lock/lib/main/lockDetail/iris/addIris/addIris_page.dart
Normal file
95
star_lock/lib/main/lockDetail/iris/addIris/addIris_page.dart
Normal file
@ -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<AddIrisPage> createState() => _AddIrisPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddIrisPageState extends State<AddIrisPage> {
|
||||||
|
final logic = Get.put(AddIrisLogic());
|
||||||
|
final state = Get.find<AddIrisLogic>().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,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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"];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<AddIrisTypeManagePage> createState() => _AddIrisTypeManagePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddIrisTypeManagePageState extends State<AddIrisTypeManagePage> {
|
||||||
|
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),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<AddIrisTypeManageTabbar> createState() =>
|
||||||
|
_AddFaceTypeManageTabbarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddFaceTypeManageTabbarState extends State<AddIrisTypeManageTabbar>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late TabController _tabController;
|
||||||
|
|
||||||
|
final List<ItemView> _itemTabs = <ItemView>[
|
||||||
|
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<ItemView> _fromCheckInTypeItemTabs = <ItemView>[
|
||||||
|
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;
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<AddIrisTypePage> createState() => _AddFaceTypePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddFaceTypePageState extends State<AddIrisTypePage> {
|
||||||
|
final logic = Get.put(AddIrisTypeLogic());
|
||||||
|
final state = Get.find<AddIrisTypeLogic>().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;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
445
star_lock/lib/main/lockDetail/iris/irisList/irisList_logic.dart
Normal file
445
star_lock/lib/main/lockDetail/iris/irisList/irisList_logic.dart
Normal file
@ -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<Reply> _replySubscription;
|
||||||
|
void _initReplySubscription() {
|
||||||
|
_replySubscription =
|
||||||
|
EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||||
|
// 添加人脸开始(此处用作删除人脸)
|
||||||
|
if ((reply is SenderAddFaceReply) && (state.isDeletFaceData == true)) {
|
||||||
|
_replyAddFaceBegin(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply is SenderQueryingFaceStatusReply) {
|
||||||
|
// 获取人脸状态
|
||||||
|
_replyQueryingFaceStatus(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply is SenderCheckingUserInfoCountReply) {
|
||||||
|
_replyCheckingUserInfoCount(reply);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加人脸开始---这里用作删除人脸
|
||||||
|
Future<void> _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<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> 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<void> _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<void> _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<void> _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<void> senderQueryingFaceStatus() async {
|
||||||
|
BlueManage().bludSendData(BlueManage().connectDeviceName,
|
||||||
|
(BluetoothConnectionState state) async {
|
||||||
|
if (state == BluetoothConnectionState.connected) {
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = changeStringListToIntList(token!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> 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<void> senderCheckingUserInfoCount() async {
|
||||||
|
BlueManage().bludSendData(BlueManage().connectDeviceName,
|
||||||
|
(BluetoothConnectionState state) async {
|
||||||
|
if (state == BluetoothConnectionState.connected) {
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = changeStringListToIntList(token!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> 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<void> senderAddFace() async {
|
||||||
|
showEasyLoading();
|
||||||
|
showBlueConnetctToastTimer(action: () {
|
||||||
|
dismissEasyLoading();
|
||||||
|
});
|
||||||
|
BlueManage().bludSendData(BlueManage().connectDeviceName,
|
||||||
|
(BluetoothConnectionState deviceConnectionState) async {
|
||||||
|
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> 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<OtherTypeRefreshListEvent>().listen((event) {
|
||||||
|
getFaceListData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> 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<void> onInit() async {
|
||||||
|
// TODO: implement onInit
|
||||||
|
super.onInit();
|
||||||
|
print("onInit()");
|
||||||
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
|
if (isDemoMode == false) {
|
||||||
|
// senderQueryingFingerprintStatus();
|
||||||
|
// senderCheckingCardStatus();
|
||||||
|
|
||||||
|
// senderCheckingUserInfoCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onClose() async {
|
||||||
|
// TODO: implement onClose
|
||||||
|
super.onClose();
|
||||||
|
|
||||||
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
|
if (isDemoMode == false) {
|
||||||
|
_replySubscription.cancel();
|
||||||
|
_teamEvent.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
280
star_lock/lib/main/lockDetail/iris/irisList/irisList_page.dart
Normal file
280
star_lock/lib/main/lockDetail/iris/irisList/irisList_page.dart
Normal file
@ -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<IrisListPage> createState() => _IrisListPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IrisListPageState extends State<IrisListPage> {
|
||||||
|
final logic = Get.put(IrisListLogic());
|
||||||
|
final state = Get.find<IrisListLogic>().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();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 = <FingerprintItemData>[].obs;
|
||||||
|
|
||||||
|
var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示
|
||||||
|
|
||||||
|
IrisListState() {
|
||||||
|
Map map = Get.arguments;
|
||||||
|
lockId.value = map["lockId"];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -672,13 +671,31 @@ class _LockDetailPageState extends State<LockDetailPage>
|
|||||||
TranslationLoader.lanKeys!.humanFace!.tr,
|
TranslationLoader.lanKeys!.humanFace!.tr,
|
||||||
state.openDoorBtnisUneable.value,
|
state.openDoorBtnisUneable.value,
|
||||||
state.bottomBtnisEable.value, () {
|
state.bottomBtnisEable.value, () {
|
||||||
Get.toNamed(Routers.faceList, arguments: {
|
Get.toNamed(Routers.faceListPage, arguments: {
|
||||||
"lockId": state.keyInfos.value.lockId,
|
"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) {
|
if (state.keyInfos.value.lockFeature!.videoIntercom == 1) {
|
||||||
showWidgetArr.add(
|
showWidgetArr.add(
|
||||||
|
|||||||
@ -46,7 +46,7 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
width: 1.sw,
|
width: 1.sw,
|
||||||
height: 1.sh,
|
height: 1.sh,
|
||||||
color: Colors.white,
|
// color: Colors.white,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Obx(() {
|
Obx(() {
|
||||||
|
|||||||
@ -292,7 +292,7 @@ class _DemoModeLockDetailPageState extends State<DemoModeLockDetailPage> {
|
|||||||
bottomItem('images/main/icon_face.png', '人脸', () {
|
bottomItem('images/main/icon_face.png', '人脸', () {
|
||||||
// gotoLogin();
|
// gotoLogin();
|
||||||
|
|
||||||
Get.toNamed(Routers.faceList, arguments: {
|
Get.toNamed(Routers.faceListPage, arguments: {
|
||||||
"lockId": 1,
|
"lockId": 1,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user