diff --git a/star_lock/ios/Podfile.lock b/star_lock/ios/Podfile.lock index 856b71dd..f7ddce61 100644 --- a/star_lock/ios/Podfile.lock +++ b/star_lock/ios/Podfile.lock @@ -306,7 +306,7 @@ SPEC CHECKSUMS: AMapLocation: 5248aec2455ebb5d104b367813c946430a2ee033 app_settings: 017320c6a680cdc94c799949d95b84cb69389ebc audio_service: f509d65da41b9521a61f1c404dd58651f265a567 - audio_session: 4f3e461722055d21515cf3261b64c973c062f345 + audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207 audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d camera_avfoundation: 8b8d780bcfb6a4a02b0fbe2b4bd17b5b71946e68 @@ -322,7 +322,7 @@ SPEC CHECKSUMS: flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907 flutter_pcm_sound: de0572ca4f99091cc2abfcc31601b8a4ddd33c0e flutter_voice_processor: 2b89b93d69b02227ae3fd58589ee0bcfa3ca2a82 - fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c + fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 fluwx: daa284756ce53442b3d0417ceeda66e981906811 google_maps_flutter_ios: d1318b4ff711612cab16862d7a87e31a7403d458 GoogleMaps: 20d7b12be49a14287f797e88e0e31bc4156aaeb4 @@ -351,4 +351,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 317f9473a5705c6fe4d79d95e81676f248048fdc -COCOAPODS: 1.12.1 +COCOAPODS: 1.14.3 diff --git a/star_lock/lib/blue/entity/lock_user_no_list_entity.dart b/star_lock/lib/blue/entity/lock_user_no_list_entity.dart new file mode 100644 index 00000000..513cf90f --- /dev/null +++ b/star_lock/lib/blue/entity/lock_user_no_list_entity.dart @@ -0,0 +1,49 @@ +class LockUserNoListEntity { + int? errorCode; + String? description; + String? errorMsg; + Data? data; + + LockUserNoListEntity( + {this.errorCode, this.description, this.errorMsg, this.data}); + + LockUserNoListEntity.fromJson(Map json) { + errorCode = json['errorCode']; + description = json['description']; + errorMsg = json['errorMsg']; + if (json['data'] is Map) { + data = Data.fromJson(json['data']); + } + } + + Map toJson() { + final Map data = {}; + data['errorCode'] = errorCode; + data['description'] = description; + data['errorMsg'] = errorMsg; + data['data'] = this.data; + return data; + } +} + +class Data { + List? userNos = []; + + Data({ + this.userNos, + }); + + Data.fromJson(Map json) { + if (json['userNos'] is List) { + json['userNos'].forEach((element) { + userNos?.add(element); + }); + } + } + + Map toJson() { + final Map data = {}; + data['userNos'] = userNos; + return data; + } +} diff --git a/star_lock/lib/blue/io_protocol/io_addUser.dart b/star_lock/lib/blue/io_protocol/io_addUser.dart index 194dcc26..bdb023a7 100644 --- a/star_lock/lib/blue/io_protocol/io_addUser.dart +++ b/star_lock/lib/blue/io_protocol/io_addUser.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:get/get.dart'; import 'package:star_lock/tools/dateTool.dart'; @@ -21,6 +22,15 @@ class AddUserCommand extends SenderProtocol { int? keyType; int? startDate; int? expireDate; + + int? useCountLimit; + int? isRound; + int? weekRound; + int? startHour; + int? startMin; + int? endHour; + int? endMin; + int? role; String? password; int? needAuthor; @@ -37,6 +47,13 @@ class AddUserCommand extends SenderProtocol { this.keyType, this.startDate, this.expireDate, + this.useCountLimit, + this.isRound, + this.weekRound, + this.startHour, + this.startMin, + this.endHour, + this.endMin, this.role, this.password, this.needAuthor, @@ -47,13 +64,17 @@ class AddUserCommand extends SenderProtocol { @override String toString() { - return 'AddUserCommand{lockID: $lockID, authUserID: $authUserID, ' + return 'AddUserCommand{lockID: $lockID, authUserID: $authUserID,' 'keyID: $keyID, userID: $userID, openMode: $openMode, ' 'keyType: $keyType, ' 'startDate:${DateTool().dateIntToYMDHNString(startDate)} , ' 'expireDate: ${DateTool().dateIntToYMDHNString(expireDate)} , ' - 'role: $role, password: $password, needAuthor: $needAuthor, ' - 'publicKey: $publicKey, privateKey: $privateKey, token: $token}'; + 'useCountLimit: $useCountLimit, isRound: $isRound, ' + 'weekRound: $weekRound, startHour: $startHour, ' + 'startMin: $startMin, endHour: $endHour, ' + 'endMin: $endMin, role: $role, password: $password, ' + 'needAuthor: $needAuthor, publicKey: $publicKey, ' + 'privateKey: $privateKey, token: $token}'; } @override @@ -116,6 +137,20 @@ class AddUserCommand extends SenderProtocol { data.add((d2 & 0xff00) >> 8); data.add((d2 & 0xff)); + //useCountLimit 2 + double useCountLimitDouble = useCountLimit! / 256; + int useCountLimit1 = useCountLimitDouble.toInt(); + int useCountLimit2 = useCountLimit! % 256; + data.add(useCountLimit1); + data.add(useCountLimit2); + + data.add(isRound!); + data.add(weekRound!); + data.add(startHour!); + data.add(startMin!); + data.add(endHour!); + data.add(endMin!); + // role 长度1 用户角色,0:普通用户,1:管理员,0xff:超级管理员 data.add(role!); @@ -169,7 +204,7 @@ class AddUserReply extends Reply { AddUserReply.parseData(CommandType commandType, List dataDetail) : super.parseData(commandType, dataDetail) { data = dataDetail; - int status = data[46]; + status = data[46]; errorWithStstus(status); } } diff --git a/star_lock/lib/blue/io_protocol/io_cleanUpUsers.dart b/star_lock/lib/blue/io_protocol/io_cleanUpUsers.dart new file mode 100644 index 00000000..2e8fa383 --- /dev/null +++ b/star_lock/lib/blue/io_protocol/io_cleanUpUsers.dart @@ -0,0 +1,137 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:get/get.dart'; +import 'package:star_lock/tools/dateTool.dart'; + +import '../../app_settings/app_settings.dart'; +import '../io_tool/io_tool.dart'; +import '../sm4Encipher/sm4.dart'; +import '../io_reply.dart'; +import '../io_sender.dart'; +import '../io_type.dart'; +import 'package:crypto/crypto.dart' as crypto; + +//清理用户 +class CleanUpUsersCommand extends SenderProtocol { + String? lockID; + String? authUserID; + String? keyID; + String? userID; + + List? userNoList; + List? token; + + int? needAuthor; + List? publicKey; + List? privateKey; + + CleanUpUsersCommand({ + this.lockID, + this.authUserID, + this.keyID, + this.userID, + this.needAuthor, + this.publicKey, + this.privateKey, + this.userNoList, + this.token, + }) : super(CommandType.cleanUpUsers); + + @override + String toString() { + return 'CleanUpUsersCommand{lockID: $lockID, authUserID: $authUserID, ' + 'keyID: $keyID, userID: $userID, userNoList: $userNoList, ' + 'token: $token, needAuthor: $needAuthor, publicKey: $publicKey, ' + 'privateKey: $privateKey}'; + } + + @override + List messageDetail() { + List data = []; + List ebcData = []; + + // 指令类型 + int type = commandType!.typeValue; + double typeDouble = type / 256; + int type1 = typeDouble.toInt(); + int type2 = type % 256; + data.add(type1); + data.add(type2); + + // 锁id 40 + int lockIDLength = utf8.encode(lockID!).length; + data.addAll(utf8.encode(lockID!)); + data = getFixedLengthList(data, 40 - lockIDLength); + + //authUserID 20 + int authUserIDLength = utf8.encode(authUserID!).length; + data.addAll(utf8.encode(authUserID!)); + data = getFixedLengthList(data, 20 - authUserIDLength); + + //KeyID 40 + int keyIDLength = utf8.encode(keyID!).length; + data.addAll(utf8.encode(keyID!)); + data = getFixedLengthList(data, 40 - keyIDLength); + + //userID 要接受钥匙的用户的useid 20 + int userIDLength = utf8.encode(userID!).length; + data.addAll(utf8.encode(userID!)); + data = getFixedLengthList(data, 20 - userIDLength); + + ByteData indexBytes = ByteData(2); // 创建一个长度为2的字节数据 + indexBytes.setInt16(0, userNoList!.length); + List indexList = indexBytes.buffer.asUint8List(); + data.addAll(indexList); + + data.addAll(userNoList!); + + // token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0 + data.addAll(token!); + + if (needAuthor == 0) { + //AuthCodeLen 1 + data.add(0); + } else { + List authCodeData = []; + + //authUserID + authCodeData.addAll(utf8.encode(authUserID!)); + + //KeyID + authCodeData.addAll(utf8.encode(keyID!)); + + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + authCodeData.addAll(token!); + + authCodeData.addAll(publicKey!); + + // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode + var authCode = crypto.md5.convert(authCodeData); + + data.add(authCode.bytes.length); + data.addAll(authCode.bytes); + } + + if ((data.length % 16) != 0) { + int add = (16 - data.length % 16); + for (int i = 0; i < add; i++) { + data.add(0); + } + } + + printLog(data); + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; + } +} + +class CleanUpUsersReply extends Reply { + CleanUpUsersReply.parseData(CommandType commandType, List dataDetail) + : super.parseData(commandType, dataDetail) { + data = dataDetail; + status = data[6]; + errorWithStstus(status); + } +} diff --git a/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart b/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart index 3d358a74..bb02f62d 100644 --- a/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart +++ b/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart @@ -183,7 +183,7 @@ class OTAUpgradeReply extends Reply { data = dataDetail; token = data.sublist(2, 6); status = data[6]; - AppLog.log('--->2' + data.toString()); + // AppLog.log('--->2' + data.toString()); errorWithStstus(status); } } diff --git a/star_lock/lib/blue/io_sender.dart b/star_lock/lib/blue/io_sender.dart index 045b46d9..3d98678d 100644 --- a/star_lock/lib/blue/io_sender.dart +++ b/star_lock/lib/blue/io_sender.dart @@ -35,7 +35,7 @@ abstract class SenderProtocol extends IOData { void printLog(List data) { AppLog.log( - "App -> 锁,指令类型:${commandType!.typeName} \n\n参数是:\n${toString()} \n\n加密之前数据是:\n$data"); + "App -> 锁,指令类型:${commandType!.typeName} \n参数是:\n${toString()} \n加密之前数据是:\n$data 长度是:${data.length}"); } //TODO:拼装数据Ï diff --git a/star_lock/lib/blue/io_type.dart b/star_lock/lib/blue/io_type.dart index c2cd45f8..384e6198 100644 --- a/star_lock/lib/blue/io_type.dart +++ b/star_lock/lib/blue/io_type.dart @@ -7,6 +7,7 @@ enum CommandType { openLock, //开门 = 0x3005 readLockStatusInfo, //读取锁状态信息 = 0x300A transferPermissions, //转移权限 = 0x300B + cleanUpUsers, //转移权限 = 0x300C reportDoorOpenRecord, //开门记录上报 = 0x3020 getLockPublicKey, // 获取锁公钥 = 0x3090 getLockPrivateKey, // 获取锁私钥 = 0x3091 @@ -72,6 +73,11 @@ extension ExtensionCommandType on CommandType { type = CommandType.openLock; } break; + case 0x300C: + { + type = CommandType.cleanUpUsers; + } + break; case 0x300A: { type = CommandType.readLockStatusInfo; @@ -154,6 +160,9 @@ extension ExtensionCommandType on CommandType { case CommandType.openLock: type = 0x3005; break; + case CommandType.cleanUpUsers: + type = 0x300C; + break; case CommandType.readLockStatusInfo: type = 0x300A; break; @@ -233,6 +242,9 @@ extension ExtensionCommandType on CommandType { case 0x3005: t = '开门'; break; + case 0x300C: + t = '清理用户'; + break; case 0x300A: t = '读取锁状态信息'; break; diff --git a/star_lock/lib/blue/sender_beforeDataManage.dart b/star_lock/lib/blue/sender_beforeDataManage.dart index ebed1de5..be66ce05 100644 --- a/star_lock/lib/blue/sender_beforeDataManage.dart +++ b/star_lock/lib/blue/sender_beforeDataManage.dart @@ -1,10 +1,12 @@ - - import 'dart:async'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; import 'package:star_lock/blue/sender_manage.dart'; +import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart'; +import 'package:star_lock/network/api_provider.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/dateTool.dart'; import 'package:star_lock/tools/eventBusEventManage.dart'; import '../app_settings/app_settings.dart'; @@ -20,6 +22,7 @@ import 'io_tool/manager_event_bus.dart'; class SenderBeforeDataManage { static SenderBeforeDataManage? _manager; + SenderBeforeDataManage._init(); static SenderBeforeDataManage? shareManager() { @@ -29,6 +32,7 @@ class SenderBeforeDataManage { } factory SenderBeforeDataManage() => shareManager()!; + SenderBeforeDataManage? get manager => shareManager(); void _init() { @@ -37,9 +41,10 @@ class SenderBeforeDataManage { // 监听设备返回的数据 StreamSubscription? _replySubscription; - void _initReplySubscription() { - _replySubscription ??= EventBusManager().eventBus!.on().listen((reply) async { + void _initReplySubscription() { + _replySubscription ??= + EventBusManager().eventBus!.on().listen((reply) async { // 添加用户 if ((reply is AddUserReply)) { _replyAddUserKey(reply); @@ -54,11 +59,12 @@ class SenderBeforeDataManage { case 0x00: //成功 CommonDataManage().currentLockUserNo = reply.data[47]; - CommonDataManage().currentKeyInfo.lockUserNo = CommonDataManage().currentLockUserNo; + CommonDataManage().currentKeyInfo.lockUserNo = + CommonDataManage().currentLockUserNo; _updateLockUserNo(); break; case 0x06: - //无权限 + //无权限 var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -84,24 +90,78 @@ class SenderBeforeDataManage { // publicKey: publicKeyDataList, // privateKey: getPrivateKeyList, // token: token); - AppLog.log("startDate111:${CommonDataManage().currentKeyInfo.startDate} endDate:${CommonDataManage().currentKeyInfo.endDate}"); - + LockListInfoItemEntity currentKeyInfo = + CommonDataManage().currentKeyInfo; + AppLog.log( + "startDate111:${currentKeyInfo.startDate} endDate:${currentKeyInfo.endDate}"); + DateTime startTime = DateTime.fromMillisecondsSinceEpoch( + currentKeyInfo.startDate! ~/ 1000); + DateTime endTime = DateTime.fromMillisecondsSinceEpoch( + currentKeyInfo.endDate! ~/ 1000); + bool isRound = currentKeyInfo.keyType == 2; var addUserData = AddUserCommand( lockID: BlueManage().connectDeviceName, - authUserID: CommonDataManage().currentKeyInfo.senderUserId!.toString(), - keyID: CommonDataManage().currentKeyInfo.keyId.toString(), + authUserID: currentKeyInfo.senderUserId!.toString(), + keyID: currentKeyInfo.keyId.toString(), userID: await Storage.getUid(), openMode: 1, keyType: 0, - startDate: CommonDataManage().currentKeyInfo.startDate!~/1000, - expireDate: CommonDataManage().currentKeyInfo.endDate!~/1000, - role: CommonDataManage().currentKeyInfo.keyRight == 1 ? 1 : 0, + startDate: currentKeyInfo.startDate! ~/ 1000, + expireDate: currentKeyInfo.endDate! ~/ 1000, + useCountLimit: 0xFFFF, + // useCountLimit: 1, + isRound: isRound ? 1 : 0, + weekRound: isRound + ? DateTool().accordingTheCycleIntoTheCorrespondingNumber( + currentKeyInfo.weekDays!) + : 0, + startHour: isRound ? startTime.hour : 0, + startMin: isRound ? startTime.minute : 0, + endHour: isRound ? endTime.hour : 0, + endMin: isRound ? endTime.minute : 0, + role: currentKeyInfo.keyRight == 1 ? 1 : 0, password: "123456", needAuthor: 1, publicKey: publicKeyDataList, privateKey: getPrivateKeyList, token: token); eventBus.fire(LockAddUserSucceedEvent(addUserData.packageData(), 1)); + break; + case 0x0c: + //锁设备用户超过 32个,需要同步锁用户列表刷新 + var entity = await ApiRepository.to.getLockUserNoList( + lockId: CommonDataManage().currentKeyInfo.lockId!); + if (!entity.errorCode!.codeIsSuccessful && + (entity.data?.userNos ?? []).isNotEmpty) { + return; + } + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var tokenKey = await Storage.getStringList(saveBlueToken); + List tokenList = changeStringListToIntList(tokenKey!); + AppLog.log('---> ${entity.data?.userNos}'); + + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState connectionState) async { + if (connectionState == BluetoothConnectionState.connected) { + IoSenderManage.senderCleanUpUsersCommand( + lockID: BlueManage().connectDeviceName, + authUserID: + CommonDataManage().currentKeyInfo.senderUserId!.toString(), + keyID: CommonDataManage().currentKeyInfo.keyId.toString(), + userID: await Storage.getUid(), + userNoList: entity.data!.userNos!, + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: tokenList); + } + }); + break; default: //失败 @@ -112,23 +172,38 @@ class SenderBeforeDataManage { Future> getAddUserKeyData() async { var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); - var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); - var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); + LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo; + DateTime startTime = + DateTime.fromMillisecondsSinceEpoch(currentKeyInfo.startDate! ~/ 1000); + DateTime endTime = + DateTime.fromMillisecondsSinceEpoch(currentKeyInfo.endDate! ~/ 1000); + bool isRound = currentKeyInfo.keyType == 2; var addUserData = AddUserCommand( lockID: BlueManage().connectDeviceName, - authUserID: CommonDataManage().currentKeyInfo.senderUserId!.toString(), - keyID: CommonDataManage().currentKeyInfo.keyId.toString(), + authUserID: currentKeyInfo.senderUserId!.toString(), + keyID: currentKeyInfo.keyId.toString(), userID: await Storage.getUid(), openMode: 1, keyType: 0, - startDate: CommonDataManage().currentKeyInfo.startDate!~/1000, - expireDate: CommonDataManage().currentKeyInfo.endDate!~/1000, - role: CommonDataManage().currentKeyInfo.keyRight == 1 ? 1 : 0, + startDate: currentKeyInfo.startDate! ~/ 1000, + expireDate: currentKeyInfo.endDate! ~/ 1000, + useCountLimit: 0xFFFF, + // useCountLimit: 1, + isRound: isRound ? 1 : 0, + weekRound: isRound + ? DateTool().accordingTheCycleIntoTheCorrespondingNumber( + currentKeyInfo.weekDays!) + : 0, + startHour: isRound ? startTime.hour : 0, + startMin: isRound ? startTime.minute : 0, + endHour: isRound ? endTime.hour : 0, + endMin: isRound ? endTime.minute : 0, + role: currentKeyInfo.keyRight == 1 ? 1 : 0, password: "123456", needAuthor: 1, publicKey: publicKeyDataList, @@ -141,8 +216,7 @@ class SenderBeforeDataManage { void _updateLockUserNo() async { LockNetTokenEntity entity = await ApiRepository.to.updateLockUserNo( keyId: CommonDataManage().currentKeyInfo.keyId.toString(), - lockUserNo: CommonDataManage().currentKeyInfo.lockUserNo.toString() - ); + lockUserNo: CommonDataManage().currentKeyInfo.lockUserNo.toString()); if (entity.errorCode!.codeIsSuccessful) { eventBus.fire(LockAddUserSucceedEvent([0], 0)); } @@ -151,4 +225,4 @@ class SenderBeforeDataManage { dispose() { _replySubscription!.cancel(); } -} \ No newline at end of file +} diff --git a/star_lock/lib/blue/sender_manage.dart b/star_lock/lib/blue/sender_manage.dart index 09b035bb..2be99dfd 100644 --- a/star_lock/lib/blue/sender_manage.dart +++ b/star_lock/lib/blue/sender_manage.dart @@ -3,6 +3,7 @@ import 'package:star_lock/blue/io_protocol/io_addFace.dart'; // import 'package:star_lock/blue/io_protocol/io_addICCard.dart'; // import 'package:star_lock/blue/io_protocol/io_addStressICCard.dart'; import 'package:star_lock/blue/io_protocol/io_changeAdministratorPassword.dart'; +import 'package:star_lock/blue/io_protocol/io_cleanUpUsers.dart'; import 'package:star_lock/blue/io_protocol/io_deletUser.dart'; import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart'; import 'package:star_lock/blue/io_protocol/io_otaUpgrade.dart'; @@ -83,13 +84,20 @@ class IoSenderManage { int? keyType, int? startDate, int? expireDate, + int? useCountLimit, + int? isRound, + int? weekRound, + int? startHour, + int? startMin, + int? endHour, + int? endMin, int? role, String? password, int? needAuthor, List? publicKey, List? privateKey, List? token, - bool? isBeforeAddUser, + bool? isBeforeAddUser, CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: AddUserCommand( @@ -101,13 +109,20 @@ class IoSenderManage { keyType: keyType, startDate: startDate, expireDate: expireDate, + useCountLimit: useCountLimit, + isRound: isRound, + weekRound: weekRound, + startHour: startHour, + startMin: startMin, + endHour: endHour, + endMin: endMin, role: role, password: password, needAuthor: needAuthor, publicKey: publicKey, privateKey: privateKey, token: token), - isBeforeAddUser: isBeforeAddUser!, + isBeforeAddUser: isBeforeAddUser ?? false, callBack: callBack); } @@ -218,7 +233,7 @@ class IoSenderManage { {String? lockID, String? userID, List? privateKey, - bool? isBeforeAddUser, + bool? isBeforeAddUser, CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: GetStarLockStatuInfoCommand( @@ -283,7 +298,7 @@ class IoSenderManage { {required String? keyID, required String? userID, required int? pwdNo, - required int? operate, + required int? operate, required int? isAdmin, required String? pwd, required int? useCountLimit, @@ -326,7 +341,7 @@ class IoSenderManage { required int? startTime, required int? endTime, required int? needAuthor, - required bool? isBeforeAddUser, + required bool? isBeforeAddUser, required List? signKey, required List? privateKey, CommandSendCallBack? callBack}) { @@ -423,12 +438,12 @@ class IoSenderManage { //todo:取消添加指纹 static void senderCancelAddFingerprintCommand( {required String? keyID, - required String? userID, - required List? token, - required int? needAuthor, - required List? signKey, - required List? privateKey, - CommandSendCallBack? callBack}) { + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: SenderCancelAddFingerprintCommand( keyID: keyID, @@ -516,12 +531,12 @@ class IoSenderManage { //todo:取消添加指纹 static void senderCancelAddCardCommand( {required String? keyID, - required String? userID, - required List? token, - required int? needAuthor, - required List? signKey, - required List? privateKey, - CommandSendCallBack? callBack}) { + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: SenderCancelAddCardCommand( keyID: keyID, @@ -580,12 +595,12 @@ class IoSenderManage { //todo:取消添加人脸 static void senderCancelAddFaceCommand( {required String? keyID, - required String? userID, - required List? token, - required int? needAuthor, - required List? signKey, - required List? privateKey, - CommandSendCallBack? callBack}) { + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: SenderCancelAddFaceCommand( keyID: keyID, @@ -1120,4 +1135,31 @@ class IoSenderManage { ), callBack: callBack); } + + //清理清理用户 + static void senderCleanUpUsersCommand( + {required String? lockID, + required String? userID, + required String? keyID, + required String? authUserID, + required int? needAuthor, + required List? userNoList, + required List? token, + required List? publicKey, + required List? privateKey, + CommandSendCallBack? callBack}) { + CommandSenderManager().managerSendData( + command: CleanUpUsersCommand( + lockID: lockID, + authUserID: authUserID, + keyID: keyID, + userID: userID, + needAuthor: needAuthor, + publicKey: publicKey, + privateKey: privateKey, + userNoList: userNoList, + token: token, + ), + callBack: callBack); + } } diff --git a/star_lock/lib/debug/controller.dart b/star_lock/lib/debug/controller.dart index 176b0b59..1d87cccb 100644 --- a/star_lock/lib/debug/controller.dart +++ b/star_lock/lib/debug/controller.dart @@ -1,18 +1,33 @@ import 'dart:async'; +import 'dart:math'; +import 'package:date_format/date_format.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:star_lock/app_settings/app_colors.dart'; +import 'package:star_lock/blue/blue_manage.dart'; +import 'package:star_lock/blue/io_tool/io_tool.dart'; +import 'package:star_lock/blue/sender_manage.dart'; import 'package:star_lock/debug/log.dart'; - +import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart'; +import 'package:star_lock/tools/commonDataManage.dart'; +import 'package:star_lock/tools/dateTool.dart'; +import 'package:star_lock/tools/storage.dart'; class DebugConsoleController { final List logs; final _streamController = BehaviorSubject>(); - DebugConsoleController({ List? logs }) : logs = logs ?? []; + DebugConsoleController({List? logs}) : logs = logs ?? []; Stream> get stream => _streamController.stream; void close() => _streamController.close(); + void notifyUpdate() => _streamController.add(logs); void log( @@ -21,14 +36,12 @@ class DebugConsoleController { DateTime? timestamp, StackTrace? stackTrace, }) { - logs.add( - DebugConsoleLog( - message: message, - level: level, - timestamp: timestamp, - stackTrace: stackTrace, - ) - ); + logs.add(DebugConsoleLog( + message: message, + level: level, + timestamp: timestamp, + stackTrace: stackTrace, + )); notifyUpdate(); } @@ -40,4 +53,106 @@ class DebugConsoleController { logs.clear(); notifyUpdate(); } -} \ No newline at end of file + + void showMore(BuildContext context) { + showBottomSheet( + context: context, + builder: (context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(width: 1, color: AppColors.btnDisableColor), + borderRadius: BorderRadius.circular(30.w), + ), + height: Get.height * 0.7, + width: Get.width, + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('辅助测试的按钮'), + SizedBox( + height: 25.h, + ), + Expanded( + child: Wrap( + children: [ + ElevatedButton( + onPressed: () { + EasyLoading.show(); + randomlyCreate32Users(0, 33) + .then((value) => EasyLoading.dismiss()) + .catchError(EasyLoading.dismiss); + }, + child: const Text('给锁设备创建 32个用户')), + ], + ), + ), + ], + ), + ); + }); + } + + //随机创建 32个用户 + Future randomlyCreate32Users(int count, int max) async { + if (count >= max) { + return; + } + + BlueManage().bludSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + var token = await Storage.getStringList(saveBlueToken); + List tokenList = changeStringListToIntList(token!); + LockListInfoItemEntity currentKeyInfo = + CommonDataManage().currentKeyInfo; + DateTime startTime = DateTime.fromMillisecondsSinceEpoch( + currentKeyInfo.startDate! ~/ 1000); + DateTime endTime = DateTime.fromMillisecondsSinceEpoch( + currentKeyInfo.endDate! ~/ 1000); + + IoSenderManage.senderAddUser( + lockID: BlueManage().connectDeviceName, + authUserID: + CommonDataManage().currentKeyInfo.senderUserId!.toString(), + keyID: CommonDataManage().currentKeyInfo.keyId.toString(), + userID: generateRandomString(6), + openMode: 1, + keyType: 0, + startDate: CommonDataManage().currentKeyInfo.startDate! ~/ 1000, + expireDate: CommonDataManage().currentKeyInfo.endDate! ~/ 1000, + useCountLimit: 0xFFFF, + isRound: currentKeyInfo.keyType == 2 ? 1 : 0, + weekRound: DateTool().accordingTheCycleIntoTheCorrespondingNumber( + currentKeyInfo.weekDays!), + startHour: startTime.hour, + startMin: startTime.minute, + endHour: endTime.hour, + endMin: endTime.minute, + role: CommonDataManage().currentKeyInfo.keyRight == 1 ? 1 : 0, + password: "123456", + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: tokenList); + } + }); + + await Future.delayed(const Duration(seconds: 2)); + count++; + await randomlyCreate32Users(count, max); + } + + //创建指定的随机字符串 + String generateRandomString(int length) { + const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; + final random = Random(); + return List.generate(length, (index) => chars[random.nextInt(chars.length)]) + .join(); + } +} diff --git a/star_lock/lib/debug/debug_console.dart b/star_lock/lib/debug/debug_console.dart index 77dfd920..aec4e20d 100644 --- a/star_lock/lib/debug/debug_console.dart +++ b/star_lock/lib/debug/debug_console.dart @@ -199,15 +199,14 @@ class DebugConsole extends StatefulWidget { static void listen(void Function() body, {DebugConsoleController? controller}) { controller ??= DebugConsole.instance; - runZoned(body, - zoneSpecification: ZoneSpecification( - handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, - Object error, StackTrace stackTrace) { - controller!.log(error, - level: DebugConsoleLevel.error, stackTrace: stackTrace); - parent.handleUncaughtError(zone, error, stackTrace); - }, - )); + runZoned(body, zoneSpecification: ZoneSpecification( + handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, + Object error, StackTrace stackTrace) { + controller! + .log(error, level: DebugConsoleLevel.error, stackTrace: stackTrace); + parent.handleUncaughtError(zone, error, stackTrace); + }, + )); } } @@ -318,6 +317,10 @@ class _DebugConsoleState extends State { onTap: () => widget.controller.clear(), child: const Text('清除日志'), ), + PopupMenuItem( + onTap: () => widget.controller.showMore(context), + child: const Text('更多'), + ), ], ) ], diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart index 1e6faeba..4be79d3b 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart @@ -232,14 +232,14 @@ class NearbyLockLogic extends BaseGetXController { // AppLog.log("电池剩余电量 battRemCap:$battRemCap"); // 重置次数 - var restoreCounter = reply.data.sublist(133, 135); + var restoreCounter = reply.data.sublist(134, 136); state.lockInfo["restoreCount"] = restoreCounter[0] * 256 + restoreCounter[1]; AppLog.log( "重置次数 restoreCounter:${restoreCounter[0] * 256 + restoreCounter[1]}"); // 重置时间 - var restoreDate = reply.data.sublist(135, 139); + var restoreDate = reply.data.sublist(136, 140); int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | @@ -249,13 +249,13 @@ class NearbyLockLogic extends BaseGetXController { AppLog.log("重置时间 restoreDateValue:$restoreDateValue"); // 主控芯片型号 - var icPartNo = reply.data.sublist(139, 149); + var icPartNo = reply.data.sublist(140, 150); var icPartNoStr = utf8String(icPartNo); state.lockInfo["icPartNo"] = icPartNoStr; AppLog.log("主控芯片型号 icPartNoStr:$icPartNoStr"); // 有效时间 - var indate = reply.data.sublist(149, 153); + var indate = reply.data.sublist(150, 154); int indateValue = ((0xff & indate[(0)]) << 24 | (0xff & indate[1]) << 16 | (0xff & indate[2]) << 8 | @@ -265,12 +265,12 @@ class NearbyLockLogic extends BaseGetXController { AppLog.log("有效时间 indateValue:$indateValue"); // mac地址 - var macAddress = reply.data.sublist(153, 173); + var macAddress = reply.data.sublist(154, 174); var macAddressStr = utf8String(macAddress); state.lockInfo["mac"] = macAddressStr; AppLog.log("mac地址 macAddressStr:$macAddressStr"); - var index = 173; + var index = 174; // 锁特征值字符串长度 var featureValueLength = reply.data[index]; AppLog.log("锁特征值字符串长度 featureValueLength:$featureValueLength"); @@ -598,7 +598,7 @@ class NearbyLockLogic extends BaseGetXController { Uint8List bin = data.sublist(binOffset.toInt(), data.length); //md5 校验有问题,暂时不解析 String md5Str = md5.convert(bin).toString().toUpperCase(); - AppLog.log('---> $md5Str ${meta['fwMd5']}'); + // AppLog.log('---> $md5Str ${meta['fwMd5']}'); if (md5Str != meta['fwMd5']) { showToast('文件校验失败 0x02'.tr); return null; diff --git a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart index 77b63947..8685ebeb 100644 --- a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart +++ b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart @@ -9,6 +9,8 @@ import 'package:get/get.dart'; import 'package:star_lock/blue/io_protocol/io_changeAdministratorPassword.dart'; import 'package:star_lock/blue/io_protocol/io_senderCustomPasswords.dart'; import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart'; +import 'package:star_lock/tools/commonDataManage.dart'; import '../../../blue/blue_manage.dart'; import '../../../blue/io_protocol/io_addUser.dart'; @@ -78,6 +80,13 @@ class SaveLockLogic extends BaseGetXController { keyType: 1, startDate: DateTime.now().millisecondsSinceEpoch, expireDate: 0x11223344, + useCountLimit: 0xFFFF, + isRound:0, + weekRound: 0, + startHour: 0, + startMin: 0, + endHour: 0, + endMin: 0, role: 255, password: "123456", needAuthor: 1, @@ -207,7 +216,6 @@ class SaveLockLogic extends BaseGetXController { if (token != null) { getTokenList = changeStringListToIntList(token); } - IoSenderManage.senderAddUser( lockID: BlueManage().connectDeviceName, authUserID:await Storage.getUid(), @@ -217,6 +225,13 @@ class SaveLockLogic extends BaseGetXController { keyType:1, startDate:DateTime.now().millisecondsSinceEpoch, expireDate:0x11223344, + useCountLimit: 0xFFFF, + isRound:0, + weekRound: 0, + startHour: 0, + startMin: 0, + endHour: 0, + endMin: 0, role:255, password:"123456", needAuthor:1, diff --git a/star_lock/lib/network/api.dart b/star_lock/lib/network/api.dart index bd13cb9e..e6d110b8 100644 --- a/star_lock/lib/network/api.dart +++ b/star_lock/lib/network/api.dart @@ -231,4 +231,7 @@ abstract class Api { final String getlockCloudStorageListURL = '/lockCloudStorage/list'; //获取云存列表 final String deleteLockCloudStorageURL = '/lockCloudStorage/delete'; //删除云存 + + final String getUserNoList = '/key/getUserNoList'; //获取指定锁下所有userNo + } diff --git a/star_lock/lib/network/api_provider.dart b/star_lock/lib/network/api_provider.dart index b49321e7..de000d84 100644 --- a/star_lock/lib/network/api_provider.dart +++ b/star_lock/lib/network/api_provider.dart @@ -2052,6 +2052,10 @@ class ApiProvider extends BaseProvider { 'certifyId': certifyId, 'keyId': keyId, })); + + // 获取指定锁下所有userNo + Future getLockUserNoList(int lockId) => + post(getUserNoList.toUrl, jsonEncode({'lockId': lockId})); } extension ExtensionString on String { diff --git a/star_lock/lib/network/api_repository.dart b/star_lock/lib/network/api_repository.dart index 364b5715..30103a4e 100644 --- a/star_lock/lib/network/api_repository.dart +++ b/star_lock/lib/network/api_repository.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'package:star_lock/blue/entity/lock_user_no_list_entity.dart'; import 'package:star_lock/login/selectCountryRegion/common/countryRegionEntity.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecord/keyOperationRecord_entity.dart'; @@ -2074,4 +2075,12 @@ class ApiRepository { final res = await apiProvider.getServiceCheckCertify(certifyId, keyId); return LockCertifyEntity.fromJson(res.body); } + + // 检测certifyId是否完成认证 + Future getLockUserNoList({ + required int lockId, + }) async { + final res = await apiProvider.getLockUserNoList(lockId); + return LockUserNoListEntity.fromJson(res.body); + } }