656 lines
21 KiB
Dart
Raw Normal View History

2023-07-10 17:50:31 +08:00
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2023-07-10 17:50:31 +08:00
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:uuid/uuid.dart';
2023-07-10 17:50:31 +08:00
import '../../../appRouters.dart';
import '../../../app_settings/app_colors.dart';
2023-08-30 10:56:18 +08:00
import '../../../blue/blue_manage.dart';
2023-08-30 14:55:42 +08:00
import '../../../blue/io_tool/io_tool.dart';
import '../../../tools/appRouteObserver.dart';
2023-08-30 14:55:42 +08:00
import '../../../tools/storage.dart';
2023-07-10 17:50:31 +08:00
import '../../../translations/trans_lib.dart';
2023-11-01 17:28:59 +08:00
import '../../lockMian/entity/lockListInfo_entity.dart';
import 'lockDetail_logic.dart';
2023-07-10 17:50:31 +08:00
class LockDetailPage extends StatefulWidget {
2023-11-01 17:28:59 +08:00
final bool isFrist;
final LockListInfoItemEntity lockListInfoItemEntity;
2023-08-31 11:18:15 +08:00
const LockDetailPage(
{Key? key, required this.isFrist, required this.lockListInfoItemEntity})
: super(key: key);
2023-07-10 17:50:31 +08:00
@override
State<LockDetailPage> createState() => _LockDetailPageState();
}
2024-01-08 11:28:22 +08:00
class _LockDetailPageState extends State<LockDetailPage>
with TickerProviderStateMixin, RouteAware {
// with RouteAware
final logic = Get.put(LockDetailLogic());
final state = Get.find<LockDetailLogic>().state;
static const methodChannel = MethodChannel('talkPlugin');
2023-08-30 10:56:18 +08:00
@override
void initState() {
// TODO: implement initState
super.initState();
2023-11-01 17:28:59 +08:00
state.keyInfos.value = widget.lockListInfoItemEntity;
2023-12-16 11:20:36 +08:00
state.lockUserNo = state.keyInfos.value.lockUserNo!;
state.senderUserId = state.keyInfos.value.senderUserId!;
state.isAttendance.value = state.keyInfos.value.lockSetting!.attendance!;
2024-01-08 11:28:22 +08:00
state.isOpenLockNeedOnline.value =
state.keyInfos.value.lockSetting!.appUnlockOnline!;
state.electricQuantity.value = state.keyInfos.value.electricQuantity!;
2024-01-08 11:28:22 +08:00
BlueManage().connectDeviceName =
state.keyInfos.value.bluetooth!.bluetoothDeviceName!;
2023-08-30 14:55:42 +08:00
2024-01-08 11:28:22 +08:00
List<int> publicKeyData =
state.keyInfos.value.bluetooth!.publicKey!.cast<int>();
2023-08-30 14:55:42 +08:00
var saveStrList = changeIntListToStringList(publicKeyData);
Storage.setStringList(saveBluePublicKey, saveStrList);
// 私钥
2024-01-08 11:28:22 +08:00
List<int> privateKeyData =
state.keyInfos.value.bluetooth!.privateKey!.cast<int>();
2023-08-30 14:55:42 +08:00
var savePrivateKeyList = changeIntListToStringList(privateKeyData);
Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
// signKey
2024-01-08 11:28:22 +08:00
List<int> signKeyData =
state.keyInfos.value.bluetooth!.signKey!.cast<int>();
var saveSignKeyList = changeIntListToStringList(signKeyData);
Storage.setStringList(saveBlueSignKey, saveSignKeyList);
2023-10-12 14:00:49 +08:00
2024-01-03 15:33:53 +08:00
var saveTokenList = changeIntListToStringList([0, 0, 0, 0]);
Storage.setStringList(saveBlueToken, saveTokenList);
// logic.startScanAction();
listeningAnimations();
2023-08-30 10:56:18 +08:00
}
2023-07-10 17:50:31 +08:00
@override
Widget build(BuildContext context) {
return Stack(children: [
Container(
width: 1.sw,
height: 1.sh - ScreenUtil().statusBarHeight * 2,
color: Colors.white,
child: Column(
children: [
topWidget(),
Expanded(child: Obx(() => bottomWidget())),
],
),
),
Obx(() => Visibility(
visible: state.iSClosedUnlockSuccessfulPopup.value,
child: GestureDetector(
onTap: () {
state.iSClosedUnlockSuccessfulPopup.value = false;
},
child: Container(
width: 1.sw,
height: 1.sh,
color: Colors.black.withOpacity(0.3),
child: _unlockSuccessWidget()),
),
))
]);
2023-07-10 17:50:31 +08:00
}
Widget topWidget() {
2023-08-30 10:56:18 +08:00
// KeyInfos keyInfo = widget.lockMainEntity.data!.keyInfos![0];
return Column(
children: [
SizedBox(height: 50.h),
Stack(
alignment: Alignment.center,
children: [
2023-11-18 10:38:13 +08:00
SizedBox(
width: 1.sw - 120.w * 2,
child: Center(
2024-01-08 11:28:22 +08:00
child: Text(
widget.lockListInfoItemEntity.lockAlias!,
style:
TextStyle(fontSize: 22.sp, fontWeight: FontWeight.w400),
))),
Positioned(
child: Obx(() => Row(
2024-01-08 11:28:22 +08:00
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text("${state.electricQuantity.value}%",
style: TextStyle(
fontSize: 18.sp,
color: AppColors.darkGrayTextColor)),
SizedBox(width: 2.w),
Image.asset(
showElectricIcon(state.electricQuantity.value),
width: 30.w,
height: 24.w),
SizedBox(width: 30.w),
],
)))
],
),
SizedBox(height: 30.h),
Container(
// width: 1.sw,
color: Colors.white,
height: 330.w,
child: Stack(
2023-07-10 17:50:31 +08:00
children: [
Center(
child: GestureDetector(
2024-01-08 11:28:22 +08:00
child: Obx(() => Stack(
children: [
Image.asset(
// state.connectState.value == 0 ? 'images/main/icon_main_openLockBtn_grey.png' : 'images/main/icon_main_openLockBtn_center.png',
'images/main/icon_main_openLockBtn_center.png',
width: 330.w,
height: 330.w,
),
state.openLockBtnState.value == 1
? buildRotationTransition()
: Positioned(
child: Image.asset(
'images/main/icon_main_openLockBtn_circle.png',
width: 330.w,
height: 330.w,
)),
],
)),
2024-01-08 11:28:22 +08:00
onTap: () {
// Get.log("点击开锁");
logic.startOpenLock();
},
onLongPressStart: (details) {
Get.log("长按开锁");
// logic.startConnect();
},
)),
2023-07-10 17:50:31 +08:00
],
),
),
SizedBox(
height: 30.h,
),
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Text(
// '门已上锁',
// style: TextStyle(
// fontSize: 26.sp,
// color: Colors.black,
// fontWeight: FontWeight.w500),
// ),
// ],
// ),
// SizedBox(
// height: 6.h,
// ),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
TranslationLoader.lanKeys!.clickUnlockAndHoldDownClose!.tr,
style: TextStyle(
fontSize: 22.sp,
color: AppColors.btnDisableColor,
fontWeight: FontWeight.w500),
),
],
),
SizedBox(
height: 30.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/icon_electronicKey_admin.png',
width: 24.w,
height: 20.w,
color: AppColors.mainColor, //应根据状态显示(当前角色为超级管理员 应显示蓝色图标)
),
SizedBox(
width: 6.w,
),
Text(
state.keyInfos.value.isLockOwner == 1
2023-11-28 13:47:49 +08:00
? TranslationLoader.lanKeys!.superAdmin!.tr
2024-01-08 11:28:22 +08:00
: (state.keyInfos.value.keyRight == 1
? TranslationLoader.lanKeys!.authorizedAdmin!.tr
: TranslationLoader.lanKeys!.normalUser!.tr),
style: TextStyle(
fontSize: 20.sp, color: AppColors.darkGrayTextColor),
),
SizedBox(
width: 80.w,
),
Image.asset(
state.keyInfos.value.remoteEnable == 1
? 'images/main/icon_main_remoteUnlocking.png'
: 'images/main/icon_main_remoteUnlocking_grey.png',
width: 24.w,
height: 20.w,
// color: state.keyInfos.value.remoteEnable == 1
// ? AppColors.btnDisableColor
// : AppColors.mainColor,
),
SizedBox(
width: 6.w,
),
Text(
2023-11-28 13:47:49 +08:00
TranslationLoader.lanKeys!.gatewayDevice!.tr,
style: TextStyle(
fontSize: 20.sp,
color: state.keyInfos.value.remoteEnable == 1
? AppColors.mainColor
: AppColors.btnDisableColor),
),
],
),
SizedBox(
height: 20.h,
),
Divider(
height: 1,
color: AppColors.greyLineColor,
indent: 20.w,
endIndent: 20.w,
)
],
);
2023-07-10 17:50:31 +08:00
}
//旋转动画
Widget buildRotationTransition() {
return Positioned(
child: RotationTransition(
//设置动画的旋转中心
alignment: Alignment.center,
//动画控制器
turns: state.animationController,
//将要执行动画的子view
child: Image.asset(
'images/main/icon_main_openLockBtn_circle.png',
width: 330.w,
height: 330.w,
),
),
);
}
Widget bottomWidget() {
2023-07-10 17:50:31 +08:00
return Container(
margin: EdgeInsets.only(left: 10.w, right: 10.w, top: 40.h),
2023-07-10 17:50:31 +08:00
// color: Colors.blue,
2023-11-01 17:28:59 +08:00
child: GridView.count(
crossAxisCount: 4,
// childAspectRatio: 3,
crossAxisSpacing: 20.w,
mainAxisSpacing: 0.h,
physics: const NeverScrollableScrollPhysics(),
2023-12-16 11:20:36 +08:00
children: getBottomWidget()),
2023-07-10 17:50:31 +08:00
);
}
2023-12-16 11:20:36 +08:00
// 根据权限显示不同的底部按钮
2024-01-08 11:28:22 +08:00
List<Widget> getBottomWidget() {
if (state.keyInfos.value.isLockOwner == 1 ||
state.keyInfos.value.keyRight == 1) {
2023-12-16 11:20:36 +08:00
// 超级管理员、授权管理员
return getAllWidget();
2024-01-08 11:28:22 +08:00
} else {
2023-12-16 11:20:36 +08:00
return getNormalWidget();
}
}
// 普通用户
List<Widget> getNormalWidget() {
var showWidgetArr = [
// 操作记录
bottomItem('images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr, () {
2024-01-08 11:28:22 +08:00
Get.toNamed(Routers.lockOperatingRecordPage,
arguments: {"keyInfo": widget.lockListInfoItemEntity});
}),
2023-12-16 11:20:36 +08:00
// 设置
2024-01-08 11:28:22 +08:00
bottomItem(
'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr,
() {
2023-12-27 10:47:58 +08:00
// BlueManage().stopScan();
2023-12-16 11:20:36 +08:00
Get.toNamed(Routers.lockSetPage,
arguments: {"lockId": widget.lockListInfoItemEntity.lockId});
}),
];
return showWidgetArr;
}
// 授权管理员、超级管理员字段
List<Widget> getAllWidget() {
2023-09-07 18:36:16 +08:00
var showWidgetArr = <Widget>[];
// 考勤
if (state.isAttendance.value == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_clockingIn.png',
TranslationLoader.lanKeys!.checkingIn!.tr, () {
Get.toNamed(Routers.checkingInListPage,
arguments: state.keyInfos.value);
}));
}
2023-09-07 18:36:16 +08:00
2023-11-01 17:28:59 +08:00
// 电子钥匙
showWidgetArr.add(bottomItem('images/main/icon_main_electronicKey.png',
TranslationLoader.lanKeys!.electronicKey!.tr, () {
Get.toNamed(Routers.electronicKeyListPage,
arguments: {"keyInfo": widget.lockListInfoItemEntity});
2023-11-01 17:28:59 +08:00
}));
2023-11-01 17:28:59 +08:00
// 密码
showWidgetArr.add(bottomItem('images/main/icon_main_password.png',
TranslationLoader.lanKeys!.password!.tr, () {
Get.toNamed(Routers.passwordKeyListPage,
arguments: {"keyInfo": widget.lockListInfoItemEntity});
2023-11-01 17:28:59 +08:00
}));
2023-11-01 17:28:59 +08:00
// ic卡
if (state.keyInfos.value.lockFeature!.icCard == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_icCard.png',
TranslationLoader.lanKeys!.card!.tr, () {
Get.toNamed(Routers.cardListPage, arguments: {
2023-11-01 17:28:59 +08:00
"lockId": widget.lockListInfoItemEntity.lockId,
});
}));
}
2023-11-01 17:28:59 +08:00
// 指纹
if (state.keyInfos.value.lockFeature!.fingerprint == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_fingerprint.png',
TranslationLoader.lanKeys!.fingerprint!.tr, () {
Get.toNamed(Routers.fingerprintListPage, arguments: {
"lockId": widget.lockListInfoItemEntity.lockId,
});
}));
2023-11-01 17:28:59 +08:00
}
2023-11-01 17:28:59 +08:00
// 遥控
if (state.keyInfos.value.lockFeature!.bluetoothRemoteControl == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_remoteControl.png',
TranslationLoader.lanKeys!.remoteControl!.tr, () {
Get.toNamed(Routers.remoteControlListPage);
}));
2023-11-01 17:28:59 +08:00
}
2023-09-07 18:36:16 +08:00
//可视对讲门锁新增->人脸
2023-11-01 17:28:59 +08:00
if (state.keyInfos.value.lockFeature!.d3Face == 1) {
showWidgetArr.add(
2024-01-08 11:28:22 +08:00
bottomItem('images/main/icon_face.png',
TranslationLoader.lanKeys!.humanFace!.tr, () {
Get.toNamed(Routers.faceList, arguments: {
"lockId": widget.lockListInfoItemEntity.lockId,
}); // Toast.show(msg: "功能暂未开放");
// tokNative('videoTalk',
// arguments: {'videoTalk': 'videoTalk'}).then((result) {
// print('$result');
// });
2023-11-01 17:28:59 +08:00
}),
);
}
2023-09-07 18:36:16 +08:00
//可视对讲门锁新增->监控
2023-11-01 17:28:59 +08:00
if (state.keyInfos.value.lockFeature!.videoIntercom == 1) {
showWidgetArr.add(
2024-01-03 15:24:42 +08:00
bottomItem('images/main/icon_catEyes.png',
TranslationLoader.lanKeys!.monitoring!.tr, () {
Get.toNamed(Routers.realTimePicturePage, arguments: {
2024-01-08 11:28:22 +08:00
"lockName": widget.lockListInfoItemEntity.lockName,
2024-01-03 15:24:42 +08:00
"isMonitoring": true
2023-11-18 10:38:13 +08:00
});
2023-11-01 17:28:59 +08:00
}),
);
}
2023-09-07 18:36:16 +08:00
var endWiddget = [
// 授权管理员
bottomItem('images/main/icon_main_authorizedAdmin.png',
TranslationLoader.lanKeys!.authorizedAdmin!.tr, () {
Get.toNamed(Routers.authorizedAdminListPage,
arguments: {"keyInfo": widget.lockListInfoItemEntity});
}),
2023-09-07 18:36:16 +08:00
// 操作记录
bottomItem('images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr, () {
Get.toNamed(Routers.lockOperatingRecordPage,
arguments: {"keyInfo": widget.lockListInfoItemEntity});
}),
2023-11-13 09:47:19 +08:00
// 视频日志
2024-01-08 11:28:22 +08:00
bottomItem('images/main/icon_lockDetail_videoLog.png',
TranslationLoader.lanKeys!.videoLog!.tr, () {
2023-11-13 09:47:19 +08:00
//视频日志
2023-11-18 10:38:13 +08:00
Get.toNamed(Routers.videoLogPage);
2023-11-13 09:47:19 +08:00
}),
// 消息提醒
2024-01-08 11:28:22 +08:00
bottomItem('images/main/icon_lockDetail_messageReminding.png',
TranslationLoader.lanKeys!.messageReminding!.tr, () {
2023-11-13 09:47:19 +08:00
Get.toNamed(Routers.msgNotificationPage);
}),
2023-09-07 18:36:16 +08:00
// 设置
2024-01-08 11:28:22 +08:00
bottomItem(
'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr,
() {
2023-12-27 10:47:58 +08:00
// BlueManage().stopScan();
Get.toNamed(Routers.lockSetPage,
arguments: {"lockId": widget.lockListInfoItemEntity.lockId});
}),
2023-09-07 18:36:16 +08:00
];
showWidgetArr.addAll(endWiddget);
return showWidgetArr;
}
Widget bottomItem(String iconUrl, String name, Function() onClick) {
var width = 42.w;
var height = 42.h;
2023-07-10 17:50:31 +08:00
return GestureDetector(
onTap: onClick,
2023-07-10 17:50:31 +08:00
child: Container(
// height: 300.h,
color: Colors.white,
2023-07-10 17:50:31 +08:00
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: width,
height: height,
child: Image.asset(iconUrl,
width: width, height: height, fit: BoxFit.fitWidth),
2023-07-10 17:50:31 +08:00
),
SizedBox(height: 10.w),
Expanded(
child: Text(name,
style: TextStyle(
fontSize: 20.sp, color: AppColors.blackColor),
textAlign: TextAlign.center))
2023-07-10 17:50:31 +08:00
],
)),
2023-07-10 17:50:31 +08:00
);
}
2024-01-02 18:03:50 +08:00
listeningAnimations() async {
await Future.delayed(Duration.zero, () {
state.animationController = AnimationController(
2024-01-04 16:43:27 +08:00
duration: const Duration(seconds: 1), vsync: this);
state.animationController.repeat();
//动画开始、结束、向前移动或向后移动时会调用StatusListener
state.animationController.addStatusListener((status) {
2024-01-02 18:03:50 +08:00
// print("AnimationStatus:$status");
if (status == AnimationStatus.completed) {
2023-12-27 10:47:58 +08:00
state.animationController.reset();
state.animationController.forward();
} else if (status == AnimationStatus.dismissed) {
2023-12-27 10:47:58 +08:00
state.animationController.reset();
state.animationController.forward();
}
});
});
2024-01-02 18:03:50 +08:00
// logic.connectBlueAndAnimationController();
}
2024-01-08 11:28:22 +08:00
String showElectricIcon(int electricnumber) {
if (electricnumber >= 100) {
return 'images/main/icon_lockElectricLevel_5.png';
2024-01-08 11:28:22 +08:00
} else if ((electricnumber > 50) && (electricnumber < 100)) {
return 'images/main/icon_lockElectricLevel_4.png';
2024-01-08 11:28:22 +08:00
} else if ((electricnumber > 25) && (electricnumber <= 50)) {
return 'images/main/icon_lockElectricLevel_3.png';
2024-01-08 11:28:22 +08:00
} else if ((electricnumber > 5) && (electricnumber <= 25)) {
return 'images/main/icon_lockElectricLevel_2.png';
2024-01-08 11:28:22 +08:00
} else if (electricnumber <= 5) {
return 'images/main/icon_lockElectricLevel_1.png';
}
return 'images/main/icon_lockElectricLevel_5.png';
}
static Future<dynamic> tokNative(String method,
{required Map arguments}) async {
if (arguments == null) {
return await methodChannel.invokeMethod(method);
} else {
return await methodChannel.invokeMethod(method, arguments);
}
}
//开锁成功弹出的小界面
void _showFullScreenOverlay(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).pop(); // 关闭底部表单
},
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.black.withOpacity(0.5),
child: _unlockSuccessWidget(),
),
);
},
);
}
Widget _unlockSuccessWidget() {
2024-01-04 15:52:47 +08:00
return Stack(
alignment: Alignment.center,
children: [
Image.asset(
'images/main/unlocked_bg.png',
width: 358.w,
height: 348.h,
),
Positioned(
top: 1.sh / 2 - 70.h,
2024-01-04 15:52:47 +08:00
child: Column(
children: [
Text(
widget.lockListInfoItemEntity.lockAlias!,
style: TextStyle(
color: AppColors.placeholderTextColor, fontSize: 24.sp),
2024-01-04 15:52:47 +08:00
),
SizedBox(
height: 10.h,
),
Text(
getCurrentFormattedTime(),
style: TextStyle(
color: AppColors.darkGrayTextColor, fontSize: 24.sp),
2024-01-04 15:52:47 +08:00
)
],
))
],
);
}
String getCurrentFormattedTime() {
// 获取当前时间
DateTime now = DateTime.now();
// 格式化日期和时间
String formattedTime = DateFormat('MM/dd HH:mm').format(now);
return formattedTime;
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
/// 路由订阅
AppRouteObserver().routeObserver.subscribe(this, ModalRoute.of(context)!);
}
@override
void dispose() {
// TODO: implement dispose
/// 取消路由订阅
// print("LockDetailPage===dispose");
AppRouteObserver().routeObserver.unsubscribe(this);
state.closedUnlockSuccessfulTimer?.cancel();
// state.animationController.reset();
// state.animationController.forward();
// state.animationController.dispose();
super.dispose();
2023-12-14 11:14:56 +08:00
BlueManage().disconnect(BlueManage().connectDeviceMacAddress);
}
/// 从上级界面进入 当前界面即将出现
@override
2023-12-14 11:14:56 +08:00
void didPush() {
super.didPush();
// print("LockDetailPage===didPush");
state.ifCurrentScreen.value = true;
2023-12-14 11:14:56 +08:00
}
/// 返回上一个界面 当前界面即将消失
@override
2023-12-14 11:14:56 +08:00
void didPop() {
super.didPop();
// print("LockDetailPage===didPop");
state.ifCurrentScreen.value = false;
logic.cancelBlueConnetctToastTimer();
state.animationController.reset();
state.animationController.forward();
state.animationController.dispose();
2023-12-14 11:14:56 +08:00
}
/// 从下级返回 当前界面即将出现
@override
2023-12-14 11:14:56 +08:00
void didPopNext() {
super.didPopNext();
state.ifCurrentScreen.value = true;
// print("LockDetailPage===didPopNext");
2023-12-14 11:14:56 +08:00
}
/// 进入下级界面 当前界面即将消失
@override
2023-12-14 11:14:56 +08:00
void didPushNext() {
super.didPushNext();
// print("LockDetailPage===didPushNext");
state.ifCurrentScreen.value = false;
logic.cancelBlueConnetctToastTimer();
state.animationController.reset();
state.animationController.forward();
2023-12-14 11:14:56 +08:00
}
2023-07-10 17:50:31 +08:00
}