Merge branch 'develop_sky_liyi' into 'develop_sky'
Develop sky liyi See merge request StarlockTeam/app-starlock!240
This commit is contained in:
commit
c954ee6918
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1067,7 +1067,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1067,7 +1067,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1066,7 +1066,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1067,7 +1067,7 @@
|
||||
"波兰语": "Լեհերեն",
|
||||
"斯洛伐克语": "Սլովենչինա",
|
||||
"捷克语": "Չեշտինա",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1067,7 +1067,7 @@
|
||||
"波兰语": "პოლსკი",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1067,7 +1067,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1065,7 +1065,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -1070,7 +1070,7 @@
|
||||
"波兰语": "Polski",
|
||||
"斯洛伐克语": "Slovenčina",
|
||||
"捷克语": "Čeština",
|
||||
"希腊语": "Ελληνικά",
|
||||
"希腊语": "ελληνικά",
|
||||
"希伯来语": "עברית",
|
||||
"塞尔维亚语": "Српски",
|
||||
"土耳其语": "Türkçe",
|
||||
|
||||
@ -362,6 +362,27 @@ class BlueManage {
|
||||
// 00=未配对,01=已配对
|
||||
if (pairStatus == '00') {
|
||||
return true; // 未配对才返回true
|
||||
} else {
|
||||
// 将十六进制字符串转换为整数(0~255)
|
||||
int statusValue = int.parse(pairStatus, radix: 16);
|
||||
// 提取 byte0(配对状态:第1位)
|
||||
int byte0 = (statusValue >> 0) & 0x01; // 取最低位
|
||||
|
||||
// 提取 byte1(事件状态:第2位)
|
||||
int byte1 = (statusValue >> 1) & 0x01; // 取次低位
|
||||
|
||||
// 判断是否未配对
|
||||
bool isPaired = (byte0 == 1);
|
||||
|
||||
// 判断是否有新事件
|
||||
bool hasNewEvent = (byte1 == 1);
|
||||
|
||||
// 返回是否未配对(原逻辑)
|
||||
if (isPaired) {
|
||||
return true; // 已配对返回false
|
||||
} else {
|
||||
return false; // 未配对返回true
|
||||
}
|
||||
}
|
||||
// 已配对(01)不返回true,继续判断下一个uuid
|
||||
}
|
||||
@ -644,7 +665,7 @@ class BlueManage {
|
||||
scanDevices.clear();
|
||||
startScanSingle(deviceName, 15, (List<ScanResult> scanDevices) {
|
||||
_connectDevice(scanDevices, deviceName, connectStateCallBack,
|
||||
isAddEquipment: isAddEquipment, isReconnect: false);
|
||||
isAddEquipment: isAddEquipment, isReconnect: true);
|
||||
});
|
||||
} else {
|
||||
connectStateCallBack(BluetoothConnectionState.disconnected);
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import 'package:flustars/flustars.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:star_lock/appRouters.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_logic.dart';
|
||||
@ -295,6 +297,132 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
);
|
||||
}
|
||||
|
||||
String formatTimestampToHHmm(int timestampMs) {
|
||||
// 1. 将毫秒时间戳转换为秒(DateTime 需要秒级时间戳)
|
||||
int timestampSec = timestampMs ~/ 1000;
|
||||
|
||||
// 2. 创建 DateTime 对象
|
||||
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestampMs);
|
||||
|
||||
// 3. 使用 DateFormat 格式化为 "HH:mm"
|
||||
DateFormat formatter = DateFormat('HH:mm');
|
||||
return formatter.format(dateTime);
|
||||
}
|
||||
|
||||
String _buildIDByType(DoorLockLogDataItem item) {
|
||||
final recordType = item.recordType;
|
||||
switch (recordType) {
|
||||
case 10:
|
||||
if (item.username != null && item.username != '') {
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'指纹'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
} else {
|
||||
return item.recordStr ?? '';
|
||||
}
|
||||
|
||||
case 20:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'密码'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 30:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'卡'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 40:
|
||||
if (item.username != null && item.username != '') {
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'蓝牙'.tr +
|
||||
'开锁'.tr +
|
||||
'(' +
|
||||
'ID'.tr +
|
||||
':${item.username})';
|
||||
} else {
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'蓝牙'.tr +
|
||||
'开锁'.tr +
|
||||
'(' +
|
||||
'ID'.tr +
|
||||
':${item.userid})';
|
||||
}
|
||||
|
||||
case 50:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'组合模式'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 60:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'添加指纹'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 70:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'添加密码'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 80:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'添加卡'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 90:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'删除'.tr +
|
||||
'指纹'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 100:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'删除'.tr +
|
||||
'密码'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 110:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'删除'.tr +
|
||||
'卡'.tr +
|
||||
'(ID:${item.username})';
|
||||
|
||||
case 160:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'人脸'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 190:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'胁迫指纹'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 200:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'胁迫密码'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
case 210:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'胁迫卡片'.tr +
|
||||
'开锁'.tr +
|
||||
'(ID:${item.username})';
|
||||
default:
|
||||
return item.recordStr ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
Color _buildTextColorByType(DoorLockLogDataItem item) {
|
||||
final recordType = item.recordType;
|
||||
switch (recordType) {
|
||||
case 120:
|
||||
case 150:
|
||||
case 130:
|
||||
case 190:
|
||||
case 200:
|
||||
case 210:
|
||||
case 220:
|
||||
return Colors.red;
|
||||
default:
|
||||
return Colors.black;
|
||||
}
|
||||
}
|
||||
|
||||
TimelineTileBuilder _timelineBuilderWidget() {
|
||||
return TimelineTileBuilder.fromStyle(
|
||||
contentsAlign: ContentsAlign.basic,
|
||||
@ -309,18 +437,26 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 20.w, top: 20.h),
|
||||
padding: EdgeInsets.only(left: 20.w, top: 20.h, right: 20.w),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
timelineData.recordStr ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
// 使用 SingleChildScrollView 实现横向滚动
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal, // 横向滚动
|
||||
child: Text(
|
||||
_buildIDByType(timelineData),
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: _buildTextColorByType(timelineData),
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
// 关键:禁用换行,强制单行显示
|
||||
maxLines: 1,
|
||||
// 可选:添加省略号(如果文本过长)
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
|
||||
@ -281,7 +281,6 @@ class AddFingerprintLogic extends BaseGetXController {
|
||||
privateKey: getPrivateKeyList,
|
||||
token: getTokenList,
|
||||
).toString();
|
||||
|
||||
showBlueConnetctToastTimer(action: () async {
|
||||
final String getMobile = (await Storage.getMobile())!;
|
||||
ApmHelper.instance.trackEvent('add_fingerprint', {
|
||||
@ -460,14 +459,7 @@ class AddFingerprintLogic extends BaseGetXController {
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
senderAddFingerprint();
|
||||
}
|
||||
|
||||
|
||||
@ -122,26 +122,26 @@ class _AddFingerprintPageState extends State<AddFingerprintPage> with RouteAware
|
||||
String getIconNumber(int number) {
|
||||
String iconPath = '';
|
||||
switch (number) {
|
||||
case 0:
|
||||
case 1:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_one.png';
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_two.png';
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_three.png';
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_four.png';
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_five.png';
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_six.png';
|
||||
break;
|
||||
default:
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_six.png';
|
||||
iconPath = 'images/main/icon_addFingerprint_fingerprint_one.png';
|
||||
break;
|
||||
}
|
||||
return iconPath;
|
||||
|
||||
@ -340,10 +340,10 @@ class FingerprintListLogic extends BaseGetXController {
|
||||
Future<FingerprintListDataEntity> getFingerprintsListData(
|
||||
{required bool isRefresh}) async {
|
||||
// 如果是下拉刷新,清空已有数据
|
||||
if (isRefresh) {
|
||||
// if (isRefresh) {
|
||||
state.fingerprintItemListData.clear();
|
||||
pageNo = 1;
|
||||
}
|
||||
|
||||
final FingerprintListDataEntity entity =
|
||||
await ApiRepository.to.getFingerprintsListData(
|
||||
lockId: state.lockId.value.toString(),
|
||||
|
||||
@ -442,10 +442,13 @@ class LockSetLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 获取锁设置信息
|
||||
Future<LockSetInfoEntity> getLockSettingInfoData() async {
|
||||
Future<LockSetInfoEntity> getLockSettingInfoData({
|
||||
bool isUnShowLoading = false,
|
||||
}) async {
|
||||
final LockSetInfoEntity entity =
|
||||
await ApiRepository.to.getLockSettingInfoData(
|
||||
lockId: state.lockId.toString(),
|
||||
isUnShowLoading: isUnShowLoading,
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.lockSetInfoData.value = entity.data!;
|
||||
@ -718,7 +721,7 @@ class LockSetLogic extends BaseGetXController {
|
||||
records: records,
|
||||
isUnShowLoading: true);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
await getLockSettingInfoData();
|
||||
await getLockSettingInfoData(isUnShowLoading: true);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,11 +167,9 @@ class LockVoiceSettingLogic extends BaseGetXController {
|
||||
BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
// 延迟1秒后重试(避免频繁请求)
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
// 递归调用自身,重试次数+1
|
||||
sendFileToDevice(data, token);
|
||||
});
|
||||
|
||||
// 断开后重发一下
|
||||
sendFileToDevice(data, token);
|
||||
|
||||
// showBlueConnetctToast();
|
||||
}
|
||||
@ -294,31 +292,6 @@ class LockVoiceSettingLogic extends BaseGetXController {
|
||||
}
|
||||
}
|
||||
|
||||
// 发送获取型号蓝牙命令
|
||||
sendGetDeviceModelBleMessage() {
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(action: () {
|
||||
dismissEasyLoading();
|
||||
});
|
||||
BlueManage().blueSendData(
|
||||
BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||
BlueManage().writeCharacteristicWithResponse(
|
||||
GetDeviceModelCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
).packageData(),
|
||||
);
|
||||
} else if (deviceConnectionState ==
|
||||
BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
showBlueConnetctToast();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _startSendLanguageFile() {
|
||||
if (state.data == null) return;
|
||||
state.voiceSubcontractingIndex = 0;
|
||||
|
||||
@ -37,18 +37,29 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
|
||||
barTitle: '锁语音包设置'.tr,
|
||||
haveBack: false,
|
||||
haveOtherLeftWidget: true,
|
||||
leftWidget: TextButton(
|
||||
onPressed: () {
|
||||
eventBus
|
||||
.fire(RefreshLockListInfoDataEvent(isUnShowLoading: true));
|
||||
Get.offAllNamed(Routers.starLockMain);
|
||||
},
|
||||
child: Text(
|
||||
'跳过'.tr,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
leftWidget: Container(
|
||||
width: 60.w, // 手动扩大leading区域宽度,防止内容换行
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
eventBus
|
||||
.fire(RefreshLockListInfoDataEvent(isUnShowLoading: true));
|
||||
Get.offAllNamed(Routers.starLockMain);
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4), // 减少两侧空白
|
||||
minimumSize: Size.zero, // 避免最小尺寸影响
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap, // 紧凑布局
|
||||
),
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: Text(
|
||||
'跳过'.tr,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24.sp, // 减小字体,防止换行
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -67,111 +78,92 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: _buildBody(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return Obx(
|
||||
() => SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: 1.sw,
|
||||
decoration: BoxDecoration(color: Colors.white),
|
||||
child: ListView.builder(
|
||||
itemCount: state.soundTypeList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||
final isLastItem = index == state.soundTypeList.length - 1;
|
||||
|
||||
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||
final platform = state.soundTypeList.value[index];
|
||||
return CommonItem(
|
||||
leftTitel: state.soundTypeList.value[index],
|
||||
rightTitle: '',
|
||||
isHaveLine: !isLastItem,
|
||||
// 最后一个元素不显示分割线(取反)
|
||||
isHaveDirection: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: Radio<String>(
|
||||
// Radio 的值:使用平台的唯一标识(如 id)
|
||||
value: platform,
|
||||
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||
groupValue: state.soundTypeList
|
||||
.value[state.selectSoundTypeIndex.value],
|
||||
// 选中颜色(可选,默认主题色)
|
||||
activeColor: AppColors.mainColor,
|
||||
// 点击 Radio 时回调(更新选中索引)
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
// 找到当前选中平台的索引(根据 id 匹配)
|
||||
final newIndex = state.soundTypeList.value
|
||||
.indexWhere((p) => p == value);
|
||||
if (newIndex != -1) {
|
||||
state.selectSoundTypeIndex.value = newIndex;
|
||||
body: Obx(
|
||||
() => ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
// 语音类型选择区
|
||||
Container(
|
||||
width: 1.sw,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
children: List.generate(
|
||||
state.soundTypeList.length,
|
||||
(index) {
|
||||
final isLastItem =
|
||||
index == state.soundTypeList.length - 1;
|
||||
final soundType = state.soundTypeList.value[index];
|
||||
return CommonItem(
|
||||
leftTitel: soundType,
|
||||
rightTitle: '',
|
||||
isHaveLine: !isLastItem,
|
||||
isHaveDirection: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: Radio<String>(
|
||||
value: soundType,
|
||||
groupValue: state.soundTypeList
|
||||
.value[state.selectSoundTypeIndex.value],
|
||||
activeColor: AppColors.mainColor,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
final newIndex = state.soundTypeList.value
|
||||
.indexWhere((p) => p == value);
|
||||
if (newIndex != -1) {
|
||||
state.selectSoundTypeIndex.value = newIndex;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
action: () {
|
||||
setState(() {
|
||||
state.selectSoundTypeIndex.value = index;
|
||||
});
|
||||
},
|
||||
),
|
||||
action: () {
|
||||
state.selectSoundTypeIndex.value = index;
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Column(
|
||||
children: _buildList(),
|
||||
),
|
||||
],
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
// 语言包列表区
|
||||
Container(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
children: List.generate(
|
||||
state.languages.length,
|
||||
(index) {
|
||||
final item = state.languages[index];
|
||||
return CommonItem(
|
||||
leftTitel: item.langText,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget:
|
||||
state.selectPassthroughListIndex.value == index
|
||||
? Image(
|
||||
image: const AssetImage(
|
||||
'images/icon_item_checked.png'),
|
||||
width: 30.w,
|
||||
height: 30.w,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: Container(),
|
||||
action: () {
|
||||
state.selectPassthroughListIndex.value = index;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildList() {
|
||||
final appLocalLanguages = state.languages;
|
||||
return List.generate(
|
||||
appLocalLanguages.length,
|
||||
(index) => _buildItem(
|
||||
appLocalLanguages[index],
|
||||
index,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildItem(PassthroughItem passthroughItem, index) {
|
||||
return CommonItem(
|
||||
leftTitel: passthroughItem.langText,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: state.selectPassthroughListIndex.value == index
|
||||
? Image(
|
||||
image: const AssetImage('images/icon_item_checked.png'),
|
||||
width: 30.w,
|
||||
height: 30.w,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: Container(),
|
||||
action: () {
|
||||
state.selectPassthroughListIndex.value = index;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
|
||||
@ -428,11 +428,17 @@ class ApiProvider extends BaseProvider {
|
||||
isUnShowLoading: isUnShowLoading);
|
||||
|
||||
// 获取所有锁设置信息
|
||||
Future<Response> getLockSettingInfoData(String lockId) => post(
|
||||
getLockSettingURL.toUrl,
|
||||
jsonEncode({
|
||||
'lockId': lockId,
|
||||
}));
|
||||
Future<Response> getLockSettingInfoData(
|
||||
String lockId, {
|
||||
bool isUnShowLoading = true,
|
||||
}) =>
|
||||
post(
|
||||
getLockSettingURL.toUrl,
|
||||
jsonEncode({
|
||||
'lockId': lockId,
|
||||
}),
|
||||
isUnShowLoading: isUnShowLoading,
|
||||
);
|
||||
|
||||
// 获取所有锁设置信息
|
||||
Future<Response> getLockSettingInfoDataIsNotLoadingIcon(String lockId) =>
|
||||
@ -2824,9 +2830,9 @@ class ApiProvider extends BaseProvider {
|
||||
|
||||
/// 设置语音包
|
||||
Future<Response> reportBuyRequest(
|
||||
int lockId,
|
||||
String type,
|
||||
) =>
|
||||
int lockId,
|
||||
String type,
|
||||
) =>
|
||||
post(
|
||||
reportBuyRequestURL.toUrl,
|
||||
jsonEncode({
|
||||
@ -2836,8 +2842,6 @@ class ApiProvider extends BaseProvider {
|
||||
isShowNetworkErrorMsg: false,
|
||||
isShowErrMsg: false,
|
||||
isUnShowLoading: true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension ExtensionString on String {
|
||||
|
||||
@ -493,8 +493,11 @@ class ApiRepository {
|
||||
|
||||
// 获取所有锁设置信息
|
||||
Future<LockSetInfoEntity> getLockSettingInfoData(
|
||||
{required String lockId}) async {
|
||||
final res = await apiProvider.getLockSettingInfoData(lockId);
|
||||
{required String lockId, bool isUnShowLoading = false}) async {
|
||||
final res = await apiProvider.getLockSettingInfoData(
|
||||
lockId,
|
||||
isUnShowLoading: isUnShowLoading,
|
||||
);
|
||||
return LockSetInfoEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user