diff --git a/star_lock/images/lan/lan_en.json b/star_lock/images/lan/lan_en.json index d37b92df..ad990535 100644 --- a/star_lock/images/lan/lan_en.json +++ b/star_lock/images/lan/lan_en.json @@ -409,6 +409,8 @@ "edit":"Edit", "stressFingerprint":"Stress Fingerprint", "effectiveDay":"Effective Day", + "stressCard":"Stress Card", + "stressPassword":"Stress Password", "whetherTheEmployeeHasPassword":"If The Employee Has A Password", "whetherTheEmployeeHasCard":"If The Employee Has A Card", diff --git a/star_lock/images/lan/lan_keys.json b/star_lock/images/lan/lan_keys.json index 4a2c1ba6..8dbabe4d 100644 --- a/star_lock/images/lan/lan_keys.json +++ b/star_lock/images/lan/lan_keys.json @@ -409,6 +409,8 @@ "edit":"edit", "stressFingerprint":"stressFingerprint", "effectiveDay":"effectiveDay", + "stressPassword":"stressPassword", + "stressCard":"stressCard", "whetherTheEmployeeHasPassword":"whetherTheEmployeeHasPassword", "whetherTheEmployeeHasCard":"whetherTheEmployeeHasCard", diff --git a/star_lock/images/lan/lan_zh.json b/star_lock/images/lan/lan_zh.json index 6c41e023..dee2a389 100644 --- a/star_lock/images/lan/lan_zh.json +++ b/star_lock/images/lan/lan_zh.json @@ -412,6 +412,8 @@ "edit":"编辑", "stressFingerprint":"胁迫指纹", "effectiveDay":"有效日", + "stressCard":"胁迫卡", + "stressPassword":"胁迫密码", "whetherTheEmployeeHasPassword":"员工是否有密码", "whetherTheEmployeeHasCard":"员工是否有卡", diff --git a/star_lock/ios/Podfile.lock b/star_lock/ios/Podfile.lock index 8df8d446..900a4a92 100644 --- a/star_lock/ios/Podfile.lock +++ b/star_lock/ios/Podfile.lock @@ -195,7 +195,7 @@ SPEC CHECKSUMS: google_maps_flutter_ios: abdac20d6ce8931f6ebc5f46616df241bfaa2cfd GoogleMaps: 025272d5876d3b32604e5c080dc25eaf68764693 image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 - network_info_plus: 122280582fe2fa2bbb8681a4269745cd5c3a9b32 + network_info_plus: 6d0c3eb8367b8164fa3fb0c19875e3f59d49697f package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 diff --git a/star_lock/lib/appRouters.dart b/star_lock/lib/appRouters.dart index 31d30827..cfe0564c 100644 --- a/star_lock/lib/appRouters.dart +++ b/star_lock/lib/appRouters.dart @@ -15,7 +15,6 @@ import 'package:star_lock/main/lockDetail/lcokSet/msgNotification/msgNotificatio import 'package:star_lock/main/lockDetail/lcokSet/notificationMode/notificationMode_page.dart'; import 'package:star_lock/main/lockDetail/lcokSet/openDoorDirection/openDoorDirection_page.dart'; import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_main_page.dart'; -import 'package:star_lock/main/lockDetail/otherTypeKey/addFace/addFace_page.dart'; import 'package:star_lock/mine/about/webviewShow_page.dart'; import 'package:star_lock/mine/mine/safeVerify/safeVerify_page.dart'; import 'package:star_lock/mine/minePersonInfo/minePersonInfoEmail/mineBindPhoneOrEmail_page.dart'; @@ -37,6 +36,12 @@ import 'login/forgetPassword/starLock_forgetPassword_page.dart'; import 'login/login/starLock_login_page.dart'; import 'login/register/starLock_register_page.dart'; import 'login/seletCountryRegion/seletCountryRegion_page.dart'; +import 'main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_page.dart'; +import 'main/lockDetail/card/addICCard/addICCard_page.dart'; +import 'main/lockDetail/card/cardDetail/cardDetail_page.dart'; +import 'main/lockDetail/card/cardList/cardList_page.dart'; +import 'main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart'; +import 'main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart'; import 'main/lockDetail/checkingIn/checkingInDetail/checkingInDetail_page.dart'; import 'main/lockDetail/checkingIn/checkingInHolidays/checkingInAddHolidays/checkingInAddHolidays_page.dart'; import 'main/lockDetail/checkingIn/checkingInHolidays/checkingInDeletHolidays/checkingInDeletHolidays_page.dart'; @@ -49,6 +54,14 @@ import 'main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkin import 'main/lockDetail/checkingIn/checkingInStaff/checkingInSetStaffList/checkingInStaffList_page.dart'; import 'main/lockDetail/checkingIn/checkingInStaff/checkingInStaffDetail/checkingInStaffDetail_page.dart'; import 'main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecord_page.dart'; +import 'main/lockDetail/face/addFace/addFace_page.dart'; +import 'main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_page.dart'; +import 'main/lockDetail/face/faceList/faceList_page.dart'; +import 'main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart'; +import 'main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_page.dart'; +import 'main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_page.dart'; +import 'main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_page.dart'; +import 'main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart'; import 'main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_page.dart'; import 'main/lockDetail/lcokSet/basicInformation/adminOpenLockPassword/adminOpenLockPassword_page.dart'; import 'main/lockDetail/lcokSet/basicInformation/basicInformation/basicInformation_page.dart'; @@ -86,11 +99,8 @@ import 'main/lockDetail/lcokSet/wirelessKeyboard/seletWirelessKeyboard/seletWire import 'main/lockDetail/lcokSet/wirelessKeyboard/wirelessKeyboardList/wirelessKeyboard_page.dart'; import 'main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart'; import 'main/lockDetail/monitoring/monitoringRealTimeScreen/monitoringRealTimeScreen_page.dart'; -import 'main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_page.dart'; -import 'main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_page.dart'; -import 'main/lockDetail/otherTypeKey/addICCard/addICCard_page.dart'; -import 'main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart'; -import 'main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart'; +import 'main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_page.dart'; +import 'main/lockDetail/remoteControl/remoteControlList/remoteControlList_page.dart'; import 'main/lockDetail/videoLog/editVideoLog/editVideoLog_page.dart'; import 'main/lockDetail/videoLog/videoLog/videoLog_page.dart'; import 'main/lockDetail/videoLog/videoLogDetail/videoLogDetail_page.dart'; @@ -111,9 +121,6 @@ import 'main/lockDetail/electronicKey/massSendElectronicKey/massSendElectronicMa import 'main/lockDetail/electronicKey/sendElectronicKey/sendElectronicManageKey/sendElectronicKeyManage_page.dart'; import 'main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_page.dart'; import 'main/lockDetail/lockOperatingRecord/lockOperatingRecord_page.dart'; -import 'main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_page.dart'; -import 'main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_page.dart'; -import 'main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_page.dart'; import 'main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart'; import 'main/lockDetail/passwordKey/passwordKeyList/passwordKeyList_page.dart'; import 'main/lockDetail/passwordKey/passwordKeyManage/passwordKeyManage_page.dart'; @@ -190,11 +197,9 @@ abstract class Routers { static const passwordKeyListPage = '/PasswordKeyListPage'; // 密码钥匙列表 static const passwordKeyManagePage = '/PasswordKeyManagePage'; // 密码钥匙 static const passwordKeyDetailPage = '/PasswordKeyDetailPage'; // 密码钥匙详情 - static const otherTypeKeyListPage = '/OtherTypeKeyListPage'; // 卡、指纹、遥控钥匙列表 - static const otherTypeKeyDetailPage = - '/OtherTypeKeyDetailPage'; // 卡、指纹、遥控钥匙详情 - static const otherTypeKeyManagePage = - '/OtherTypeKeyManagePage'; // 卡、指纹、遥控钥匙添加 + // static const otherTypeKeyListPage = '/OtherTypeKeyListPage'; // 卡、指纹、遥控钥匙列表 + // static const otherTypeKeyDetailPage = '/OtherTypeKeyDetailPage'; // 卡、指纹、遥控钥匙详情 + // static const otherTypeKeyManagePage = '/OtherTypeKeyManagePage'; // 卡、指纹、遥控钥匙添加 static const otherTypeKeyChangeDatePage = '/OtherTypeKeyChangeDatePage'; // 卡、指纹、遥控钥匙详情修改日期 static const otherTypeKeyChangeValidityDatePage = @@ -383,6 +388,18 @@ abstract class Routers { static const editVideoLogPage = '/EditVideoLogPage'; // 编辑视频日志 static const videoLogDetailPage = '/VideoLogDetailPage'; // 视频日志详情 static const videoLogDownLoadPage = '/VideoLogDownLoadPage'; // 视频下载列表 + + static const remoteControlListPage = '/RemoteControlListPage'; // 遥控列表 + static const addRemoteControlManagePage = '/AddRemoteControlManagePage'; // 添加遥控 + + static const cardListPage = '/CardListPage'; // 卡列表 + static const addCardTypeManagePage = '/AddCardTypeManagePage'; // 添加卡 + static const cardDetailPage = '/CardDetailPage'; // 卡详情 + static const fingerprintListPage = '/FingerprintListPage'; // 指纹列表 + static const addFingerprintTypeManagePage = '/AddFingerprintTypeManagePage'; // 添加指纹 + static const fingerprintDetailPage = '/FingerprintDetailPage'; // 指纹详情 + static const faceList = '/FaceList'; // 人脸列表 + static const addFaceTypeManagePage = '/AddFaceTypeManagePage'; // 添加人脸 } abstract class AppRouters { @@ -459,18 +476,18 @@ abstract class AppRouters { name: Routers.passwordKeyDetailPage, page: () => const PasswordKeyDetailPage(), ), - GetPage( - name: Routers.otherTypeKeyListPage, - page: () => const OtherTypeKeyListPage(), - ), - GetPage( - name: Routers.otherTypeKeyDetailPage, - page: () => const OtherTypeKeyDetailPage(), - ), - GetPage( - name: Routers.otherTypeKeyManagePage, - page: () => const OtherTypeKeyManagePage(), - ), + // GetPage( + // name: Routers.otherTypeKeyListPage, + // page: () => const OtherTypeKeyListPage(), + // ), + // GetPage( + // name: Routers.otherTypeKeyDetailPage, + // page: () => const OtherTypeKeyDetailPage(), + // ), + // GetPage( + // name: Routers.otherTypeKeyManagePage, + // page: () => const OtherTypeKeyManagePage(), + // ), GetPage( name: Routers.authorizedAdminListPage, page: () => const AuthorizedAdminListPage(), @@ -942,5 +959,35 @@ abstract class AppRouters { GetPage( name: Routers.videoLogDownLoadPage, page: () => const VideoLogDownLoadPage()), + GetPage( + name: Routers.remoteControlListPage, + page: () => const RemoteControlListPage()), + GetPage( + name: Routers.addRemoteControlManagePage, + page: () => const AddRemoteControlManagePage()), + GetPage( + name: Routers.cardListPage, + page: () => const CardListPage()), + GetPage( + name: Routers.addCardTypeManagePage, + page: () => const AddCardTypeManagePage()), + GetPage( + name: Routers.cardDetailPage, + page: () => const CardDetailPage()), + GetPage( + name: Routers.fingerprintListPage, + page: () => const FingerprintListPage()), + GetPage( + name: Routers.addFingerprintTypeManagePage, + page: () => const AddFingerprintTypeManagePage()), + GetPage( + name: Routers.fingerprintDetailPage, + page: () => const FingerprintDetailPage()), + GetPage( + name: Routers.faceList, + page: () => const FaceList()), + GetPage( + name: Routers.addFaceTypeManagePage, + page: () => const AddFaceTypeManagePage()), ]; } diff --git a/star_lock/lib/blue/blue_manage.dart b/star_lock/lib/blue/blue_manage.dart index 9e1e6d5f..43923d2a 100644 --- a/star_lock/lib/blue/blue_manage.dart +++ b/star_lock/lib/blue/blue_manage.dart @@ -32,6 +32,7 @@ class BlueManage{ // 监听发送事件 StreamSubscription? _sendStreamSubscription; StreamSubscription? _scanSubscription; + StreamSubscription? _currentConnectionStream; // 监听蓝牙连接状态 DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected; @@ -126,7 +127,7 @@ class BlueManage{ if(deviceConnectionState == DeviceConnectionState.connected){ return; } - _flutterReactiveBle!.connectToDevice(id: connectDeviceMacAddress, connectionTimeout: const Duration(seconds: 100000)).listen((connectionStateUpdate) async { + _currentConnectionStream = _flutterReactiveBle!.connectToDevice(id: connectDeviceMacAddress, connectionTimeout: const Duration(seconds: 100000)).listen((connectionStateUpdate) async { // 获取状态 deviceConnectionState = connectionStateUpdate.connectionState; print('ConnectionState for device $deviceMAC : ${connectionStateUpdate.connectionState}'); @@ -206,16 +207,15 @@ class BlueManage{ // 断开连接 Future disconnect(String deviceMAC) async { + try { + _currentConnectionStream?.cancel(); print('disconnecting to device: $deviceMAC'); } on Exception catch (e, _) { print("Error disconnecting from a device: $e"); } finally { - // EventBusManager().eventBusFir(ConnectionStateUpdate( - // deviceId: deviceMAC, - // connectionState: DeviceConnectionState.disconnected, - // failure: null, - // )); + deviceConnectionState = DeviceConnectionState.disconnected; + // _currentConnectionStream = null; } } @@ -394,5 +394,6 @@ class BlueManage{ disposed(){ _sendStreamSubscription?.cancel(); + _currentConnectionStream?.cancel(); } } \ No newline at end of file diff --git a/star_lock/lib/blue/io_protocol/io_addStressFingerprint.dart b/star_lock/lib/blue/io_protocol/io_addStressFingerprint.dart index 397b3ebb..75b567c5 100644 --- a/star_lock/lib/blue/io_protocol/io_addStressFingerprint.dart +++ b/star_lock/lib/blue/io_protocol/io_addStressFingerprint.dart @@ -18,6 +18,7 @@ class SenderAddStressFingerprintCommand extends SenderProtocol { String? keyID; String? userID; int? fingerNo; + int? fingerType; int? useCountLimit; List? token; int? startTime; @@ -25,11 +26,13 @@ class SenderAddStressFingerprintCommand extends SenderProtocol { int? needAuthor; List? publicKey; List? privateKey; + List? signKey; SenderAddStressFingerprintCommand({ this.keyID, this.userID, this.fingerNo, + this.fingerType, this.useCountLimit, this.token, this.startTime, @@ -37,6 +40,7 @@ class SenderAddStressFingerprintCommand extends SenderProtocol { this.needAuthor, this.publicKey, this.privateKey, + this.signKey }) : super(CommandType.generalExtendedCommond); @override @@ -71,8 +75,11 @@ class SenderAddStressFingerprintCommand extends SenderProtocol { // PwdNo subData.add(fingerNo!); + // fingerType + subData.add(fingerType!); + // UseCountLimit - subData.add(0xff); + subData.add(255); // token subData.addAll(token!); @@ -95,22 +102,21 @@ class SenderAddStressFingerprintCommand extends SenderProtocol { } else { List authCodeData = []; - //authUserID - authCodeData.addAll(utf8.encode(userID!)); - //KeyID authCodeData.addAll(utf8.encode(keyID!)); + //authUserID + authCodeData.addAll(utf8.encode(userID!)); + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 authCodeData.addAll(token!); - authCodeData.addAll(publicKey!); + authCodeData.addAll(signKey!); print("${commandType!.typeValue}-authCodeData:$authCodeData"); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode var authCode = crypto.md5.convert(authCodeData); - subData.add(authCode.bytes.length); subData.addAll(authCode.bytes); } diff --git a/star_lock/lib/blue/io_protocol/io_addStressICCard.dart b/star_lock/lib/blue/io_protocol/io_addStressICCard.dart index e67f4eda..5c9671e2 100644 --- a/star_lock/lib/blue/io_protocol/io_addStressICCard.dart +++ b/star_lock/lib/blue/io_protocol/io_addStressICCard.dart @@ -18,6 +18,7 @@ class SenderAddStressICCardCommand extends SenderProtocol { String? keyID; String? userID; int? icCardNo; + int? cardType; int? useCountLimit; List? token; int? startTime; @@ -25,11 +26,13 @@ class SenderAddStressICCardCommand extends SenderProtocol { int? needAuthor; List? publicKey; List? privateKey; + List? signKey; SenderAddStressICCardCommand({ this.keyID, this.userID, this.icCardNo, + this.cardType, this.useCountLimit, this.token, this.startTime, @@ -37,6 +40,7 @@ class SenderAddStressICCardCommand extends SenderProtocol { this.needAuthor, this.publicKey, this.privateKey, + this.signKey }) : super(CommandType.generalExtendedCommond); @override @@ -68,9 +72,12 @@ class SenderAddStressICCardCommand extends SenderProtocol { subData.addAll(utf8.encode(userID!)); subData = getFixedLengthList(subData, 20 - userIDLength); - // PwdNo + // icCardNo subData.add(icCardNo!); + // cardType + subData.add(cardType!); + // UseCountLimit subData.add(0xff); @@ -95,16 +102,16 @@ class SenderAddStressICCardCommand extends SenderProtocol { } else { List authCodeData = []; - //authUserID - authCodeData.addAll(utf8.encode(userID!)); - //KeyID authCodeData.addAll(utf8.encode(keyID!)); + //authUserID + authCodeData.addAll(utf8.encode(userID!)); + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 authCodeData.addAll(token!); - authCodeData.addAll(publicKey!); + authCodeData.addAll(signKey!); print("${commandType!.typeValue}-authCodeData:$authCodeData"); diff --git a/star_lock/lib/blue/reciver_data.dart b/star_lock/lib/blue/reciver_data.dart index 4f3c34f3..4f961968 100644 --- a/star_lock/lib/blue/reciver_data.dart +++ b/star_lock/lib/blue/reciver_data.dart @@ -58,12 +58,12 @@ class CommandReciverManager { print("appDataReceiveData:$data"); // &&(data[4] == 0x11) if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){ var tmpType = (data[7] & 0x0f);// 包标识 - print("temType:$tmpType"); + // print("temType:$tmpType"); var dataLen = data[8] * 256 + data[9];// 高16位用来指示后面数据块内容的长度 var oriLen = data[10] * 256 + data[11];// 低16位用来指示数据加密前的原长度 - print("dataLen:$dataLen oriLen:$oriLen"); - List dataList = []; + // print("dataLen:$dataLen oriLen:$oriLen"); + // List dataList = []; List oriDataList = []; switch(tmpType){ case 0: //不加密 diff --git a/star_lock/lib/blue/sender_manage.dart b/star_lock/lib/blue/sender_manage.dart index 2c993a92..e1df2776 100644 --- a/star_lock/lib/blue/sender_manage.dart +++ b/star_lock/lib/blue/sender_manage.dart @@ -548,6 +548,7 @@ class IoSenderManage { required String? keyID, required String? userID, required int? fingerNo, + required int? fingerType, required int? useCountLimit, required List? token, required int? startTime, @@ -555,12 +556,14 @@ class IoSenderManage { required int? needAuthor, required List? publicKey, required List? privateKey, + required List? signKey, CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: SenderAddStressFingerprintCommand( keyID: keyID, userID: userID, fingerNo: fingerNo, + fingerType: fingerType, useCountLimit: useCountLimit, token: token, startTime: startTime, @@ -568,6 +571,7 @@ class IoSenderManage { needAuthor: needAuthor, publicKey: publicKey, privateKey: privateKey, + signKey: signKey ), callBack:callBack); } @@ -576,6 +580,7 @@ class IoSenderManage { required String? keyID, required String? userID, required int? icCardNo, + required int? cardType, required int? useCountLimit, required List? token, required int? startTime, @@ -583,12 +588,14 @@ class IoSenderManage { required int? needAuthor, required List? publicKey, required List? privateKey, + required List? signKey, CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData( command: SenderAddStressICCardCommand( keyID: keyID, userID: userID, icCardNo: icCardNo, + cardType: cardType, useCountLimit: useCountLimit, token: token, startTime: startTime, @@ -596,6 +603,7 @@ class IoSenderManage { needAuthor: needAuthor, publicKey: publicKey, privateKey: privateKey, + signKey: signKey ), callBack:callBack); } diff --git a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_entity.dart b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_entity.dart index 9761cefb..fd9a1ad7 100644 --- a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_entity.dart +++ b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_entity.dart @@ -27,7 +27,7 @@ class AuthorizedAdminSendEntity { } class Data { - int? receiverUid; + String? receiverUid; ReceiverUser? receiverUser; int? keyId; @@ -149,15 +149,16 @@ class Phone { class Cloud { String? username; String? password; - int? cloudUid; + // String? cloudUid; int? userId; String? updatedAt; String? createdAt; int? id; - Cloud({this.username, + Cloud( + {this.username, this.password, - this.cloudUid, + // this.cloudUid, this.userId, this.updatedAt, this.createdAt, @@ -166,7 +167,7 @@ class Cloud { Cloud.fromJson(Map json) { username = json['username']; password = json['password']; - cloudUid = json['cloud_uid']; + // cloudUid = json['cloud_uid']; userId = json['user_id']; updatedAt = json['updated_at']; createdAt = json['created_at']; @@ -177,7 +178,7 @@ class Cloud { final Map data = {}; data['username'] = username; data['password'] = password; - data['cloud_uid'] = cloudUid; + // data['cloud_uid'] = cloudUid; data['user_id'] = userId; data['updated_at'] = updatedAt; data['created_at'] = createdAt; diff --git a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart index a3dfa961..fd4d5b61 100644 --- a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart +++ b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart @@ -1,12 +1,14 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/toast.dart'; @@ -327,9 +329,9 @@ class _AuthorizedAdminPageState extends State { var entity = await ApiRepository.to.setRoomStatusData( lockId: state.keyInfo.value.lockId!, - roomStatus:1, + roomStatus: 1, ); - if(entity.errorCode!.codeIsSuccessful){ + if (entity.errorCode!.codeIsSuccessful) { print("标记为已入住成功啦啦啦啦啦"); Toast.show(msg: "标记成功"); setState(() {}); diff --git a/star_lock/lib/main/lockDetail/authorizedAdmin/volumeAuthorizationLock/volumeAuthorizationLock_page.dart b/star_lock/lib/main/lockDetail/authorizedAdmin/volumeAuthorizationLock/volumeAuthorizationLock_page.dart index 968e1d8b..7d69352d 100644 --- a/star_lock/lib/main/lockDetail/authorizedAdmin/volumeAuthorizationLock/volumeAuthorizationLock_page.dart +++ b/star_lock/lib/main/lockDetail/authorizedAdmin/volumeAuthorizationLock/volumeAuthorizationLock_page.dart @@ -1,13 +1,15 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../appRouters.dart'; diff --git a/star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_page.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_page.dart new file mode 100644 index 00000000..21cbb218 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_page.dart @@ -0,0 +1,46 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; +import 'addCardTypeManage_tabbar.dart'; + +class AddCardTypeManagePage extends StatefulWidget { + const AddCardTypeManagePage({Key? key}) : super(key: key); + + @override + State createState() => _AddCardTypeManagePageState(); +} + +class _AddCardTypeManagePageState extends State { + var index = 0; + + @override + Widget build(BuildContext context) { + // 0卡 1指纹 2钥匙 + 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}${TranslationLoader.lanKeys!.card!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: Column( + children: [ + AddCardManageTabbar(initialIndex: index, lockId: lockId, fromType: fromType, fromTypeTwoStaffName:fromTypeTwoStaffName), + ], + ), + ); + } + +} diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_tabbar.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_tabbar.dart similarity index 67% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_tabbar.dart rename to star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_tabbar.dart index 5f479f0a..de380cbb 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_tabbar.dart +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardManage/addCardTypeManage_tabbar.dart @@ -1,29 +1,28 @@ + import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import '../../../../app_settings/app_colors.dart'; -import '../../../../tools/CustomUnderlineTabIndicator.dart'; -import '../../../../translations/trans_lib.dart'; -import '../otherTypeAddKey/otherTypeAddKey_page.dart'; +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/CustomUnderlineTabIndicator.dart'; +import '../../../../../translations/trans_lib.dart'; +import '../addCardType_page.dart'; -class OtherTypeKeyManageTabbar extends StatefulWidget { +class AddCardManageTabbar extends StatefulWidget { var initialIndex = 1; - var lockType = 0; var lockId = 0; var fromType = 0; // 1从添加钥匙列表进入 2从考勤添加员工入口进入 var fromTypeTwoStaffName = "";// 从添加员工进入 传入员工名字 - OtherTypeKeyManageTabbar( - {Key? key, required this.initialIndex, required this.lockType, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) + + AddCardManageTabbar( + {Key? key, required this.initialIndex, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) : super(key: key); @override - State createState() => - _OtherTypeKeyManageTabbarState(); + State createState() => _AddCardManageTabbarState(); } -class _OtherTypeKeyManageTabbarState extends State - with SingleTickerProviderStateMixin { +class _AddCardManageTabbarState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final List _itemTabs = [ @@ -36,6 +35,7 @@ class _OtherTypeKeyManageTabbarState extends State void initState() { // TODO: implement initState super.initState(); + _tabController = TabController( vsync: this, length: _itemTabs.length, @@ -46,11 +46,11 @@ class _OtherTypeKeyManageTabbarState extends State Widget build(BuildContext context) { return Expanded( child: Column( - children: [ - _tabBar(), - _pageWidget(), - ], - )); + children: [ + _tabBar(), + _pageWidget(), + ], + )); } TabBar _tabBar() { @@ -89,13 +89,12 @@ class _OtherTypeKeyManageTabbarState extends State child: TabBarView( controller: _tabController, children: _itemTabs - .map((ItemView item) => OtherTypeAddKeyPage( - seletType: item.seletType, - lockType: widget.lockType, - lockId: widget.lockId, - fromType: widget.fromType, - fromTypeTwoStaffName:widget.fromTypeTwoStaffName - )) + .map((ItemView item) => AddCardPage( + seletType: item.seletType, + lockId: widget.lockId, + fromType: widget.fromType, + fromTypeTwoStaffName:widget.fromTypeTwoStaffName + )) .toList(), ), ); diff --git a/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart new file mode 100644 index 00000000..c61adf59 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart @@ -0,0 +1,98 @@ + +import 'dart:math'; + +import 'package:get/get.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; + +import '../../../../appRouters.dart'; +import '../../../../tools/toast.dart'; +import 'addCardType_state.dart'; + +class AddCardTypeLogic extends BaseGetXController{ + AddCardTypeState state = AddCardTypeState(); + + // 添加卡数据 + void addCardData() async { + var fingerprintType = 0; // 永久:1;限时2,单次3,循环:4 + var startDate = ""; + var endDate = ""; + if (state.seletType.value == "0") { + fingerprintType = 1; + startDate = "0"; + endDate = "0"; + } else if (state.seletType.value == "1") { + fingerprintType = 2; + if (state.beginTimeTimestamp.value.isEmpty) { + Toast.show(msg: "请选择开始时间"); + return; + } + if (state.endTimeTimestamp.value.isEmpty) { + Toast.show(msg: "请选择开始时间"); + 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)) { + Toast.show(msg: "失效时间要大于生效时间"); + return; + } + + startDate = state.beginTimeTimestamp.value; + endDate = state.endTimeTimestamp.value; + } else if (state.seletType.value == "2") { + if (state.effectiveDateTime.value <= 0) { + Toast.show(msg: "请选择生效时间"); + return; + } + if (state.failureDateTime.value <= 0) { + Toast.show(msg: "请选择失效时间"); + return; + } + + if (state.weekdaysList.value.isEmpty) { + Toast.show(msg: "请选择有效日"); + return; + } + + // if(DateTime.now().millisecondsSinceEpoch >= state.effectiveDateTime.value){ + // Toast.show(msg: "生效时间要大于当前时间"); + // return; + // } + + if (state.effectiveDateTime.value >= state.failureDateTime.value) { + Toast.show(msg: "失效时间要大于生效时间"); + return; + } + startDate = state.effectiveDateTime.value.toString(); + endDate = state.failureDateTime.value.toString(); + fingerprintType = 4; + } + + var isCoerced = state.isStressFingerprint.value == false ? "1" : "2"; // 1:非胁迫卡 2:胁迫卡 + print("addOtherType startDate:$startDate endDate:$endDate"); + Get.toNamed(Routers.addICCardPage, arguments: { + "lockId": state.lockId.value, + "endDate": endDate, + "addType": "1", + "cardName": state.nameController.text, + "cardNumber": "123456", + "cardType": fingerprintType.toString(), + "isCoerced": isCoerced, + "startDate": startDate, + "weekDay": state.weekdaysList.value, + "fromType": state.fromType.value, + }); + } + + @override + void onInit() { + super.onInit(); + } + + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_page.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_page.dart similarity index 63% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_page.dart rename to star_lock/lib/main/lockDetail/card/addCardType/addCardType_page.dart index 7fd5bcf4..a0f2b691 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_page.dart +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_page.dart @@ -1,44 +1,52 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:star_lock/appRouters.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 '../../../../tools/toast.dart'; import '../../../../translations/trans_lib.dart'; -import 'otherTypeAddKey_logic.dart'; +import 'addCardType_logic.dart'; -class OtherTypeAddKeyPage extends StatefulWidget { - final String seletType; - final int lockType; // 0卡 1指纹 2钥匙 +class AddCardPage extends StatefulWidget { + final String seletType; // 永久限时循环下标 final int lockId; - final int fromType;// // 1从添加钥匙列表进入 2从考勤添加员工入口进入 - final String fromTypeTwoStaffName;// 从添加员工进入 传入员工名字 - const OtherTypeAddKeyPage( - {Key? key, required this.seletType, required this.lockType, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) : super(key: key); + final int fromType; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + final String fromTypeTwoStaffName; // 从添加员工进入 传入员工名字 + + const AddCardPage( + {Key? key, + required this.seletType, + required this.lockId, + required this.fromType, + required this.fromTypeTwoStaffName}) + : super(key: key); @override - State createState() => _OtherTypeAddKeyPageState(); + State createState() => _AddCardPageState(); } -class _OtherTypeAddKeyPageState extends State { - final logic = Get.put(OtherTypeAddKeyLogic()); - final state = Get.find().state; +class _AddCardPageState extends State { + final logic = Get.put(AddCardTypeLogic()); + final state = Get.find().state; @override Widget build(BuildContext context) { state.seletType.value = widget.seletType; - state.lockType.value = widget.lockType; state.lockId.value = widget.lockId; - state.nameController.text = widget.fromTypeTwoStaffName; + // state.nameController.text = widget.fromTypeTwoStaffName; + WidgetsBinding.instance.addPostFrameCallback((_) { + // Your code here + }); return indexChangeWidget(); } @@ -50,8 +58,10 @@ class _OtherTypeAddKeyPageState extends State { // return sendElectronicKeySucceed(); return Column( children: [ - perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr, - TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController), + perpetualKeyWidget( + TranslationLoader.lanKeys!.name!.tr, + TranslationLoader.lanKeys!.pleaseEnter!.tr, + state.nameController), keyBottomWidget() ], ); @@ -61,8 +71,10 @@ class _OtherTypeAddKeyPageState extends State { // 限时 return Column( children: [ - perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr, - TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController), + perpetualKeyWidget( + TranslationLoader.lanKeys!.name!.tr, + TranslationLoader.lanKeys!.pleaseEnter!.tr, + state.nameController), keyTimeLimitWidget(), SizedBox(height: 10.h), keyBottomWidget() @@ -74,18 +86,24 @@ class _OtherTypeAddKeyPageState extends State { // 循环 return Column( children: [ - perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr, - TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController), + 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); + 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}'); + 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() @@ -125,13 +143,17 @@ class _OtherTypeAddKeyPageState extends State { action: () async { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - setState(() { - 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(); - }); - }); + setState(() { + setState(() { + 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, @@ -140,13 +162,17 @@ class _OtherTypeAddKeyPageState extends State { action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - setState(() { - 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(); - }); - }); + setState(() { + setState(() { + 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), ], @@ -157,29 +183,30 @@ class _OtherTypeAddKeyPageState extends State { return Column( children: [ CommonItem( - leftTitel: TranslationLoader.lanKeys!.stressFingerprint!.tr, + leftTitel: TranslationLoader.lanKeys!.stressCard!.tr, rightTitle: "", isTipsImg: false, isHaveRightWidget: true, rightWidget: SizedBox( width: 60.w, height: 50.h, child: _isStressFingerprint())), SizedBox(height: 30.h), - SubmitBtn(btnName: TranslationLoader.lanKeys!.next!.tr, onClick: () async { + SubmitBtn( + btnName: TranslationLoader.lanKeys!.next!.tr, + onClick: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // print("state.seletType:${state.seletType.value}"); + if (state.nameController.text.isEmpty) { + Toast.show(msg: "请输入姓名"); + return; + } - var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); - if(isDemoMode == false){ - if(state.nameController.text.isEmpty){ - Toast.show(msg: "请输入姓名"); - return; - } - - logic.addFingerprintsData(); - }else{ - // Get.toNamed(Routers.seletLockTypePage); - Toast.show(msg: "演示模式"); - } - - }), + logic.addCardData(); + } else { + // Get.toNamed(Routers.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }), ], ); } @@ -258,10 +285,10 @@ class _OtherTypeAddKeyPageState extends State { String title; switch (type) { case 0: - title = TranslationLoader.lanKeys!.card!.tr; + title = TranslationLoader.lanKeys!.stressCard!.tr; break; case 1: - title = TranslationLoader.lanKeys!.fingerprint!.tr; + title = TranslationLoader.lanKeys!.stressFingerprint!.tr; break; case 2: title = TranslationLoader.lanKeys!.remoteControl!.tr; @@ -319,5 +346,4 @@ class _OtherTypeAddKeyPageState extends State { }, ); } - } diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_state.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_state.dart similarity index 88% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_state.dart rename to star_lock/lib/main/lockDetail/card/addCardType/addCardType_state.dart index c0e25752..caa9da92 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_state.dart +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_state.dart @@ -1,12 +1,11 @@ - import 'package:flutter/material.dart'; import 'package:get/get.dart'; -class OtherTypeAddKeyState{ +class AddCardTypeState{ + final lockId = 0.obs; final seletType = "0".obs;// 0永久 1显示 2循环 - final lockType = 0.obs;// 0卡 1指纹 2钥匙 final fromType = 1.obs; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 final isStressFingerprint = false.obs; @@ -20,7 +19,7 @@ class OtherTypeAddKeyState{ var weekdaysList = [].obs; final TextEditingController nameController = TextEditingController(); - OtherTypeAddKeyState() { + AddCardTypeState() { // Map map = Get.arguments; // lockId.value = map["lockId"]; // fromType.value = map["fromType"]; diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_entity.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_entity.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_entity.dart rename to star_lock/lib/main/lockDetail/card/addICCard/addICCard_entity.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_logic.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart similarity index 73% rename from star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_logic.dart rename to star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart index d98a6aa6..f0ba5332 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_logic.dart +++ b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart @@ -45,11 +45,6 @@ class AddICCardLogic extends BaseGetXController{ } Future _replyAddICCardBegin(Reply reply) async { - var token = reply.data.sublist(2, 6); - var saveStrList = changeIntListToStringList(token); - print("_replyAddFingerprintReplyToken:$token"); - Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("_replyAddFingerprintStatus:$status"); @@ -69,13 +64,20 @@ class AddICCardLogic extends BaseGetXController{ var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + print("_replyAddFingerprintReplyToken:$token"); + Storage.setStringList(saveBlueToken, saveStrList); + IoSenderManage.senderAddFingerprintCommand( keyID:"1", userID:await Storage.getUid(), fingerNo:1, useCountLimit:0xff, - startTime:0x11223344, - endTime:0x11223344, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, @@ -101,11 +103,6 @@ class AddICCardLogic extends BaseGetXController{ } Future _replyAddICCardConfirmation(Reply reply) async { - var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyAddICCardConfirmationReplyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("_replyAddFingerprintstatus:$status"); @@ -114,12 +111,12 @@ class AddICCardLogic extends BaseGetXController{ //成功 print("${reply.commandType!.typeValue} 数据解析成功"); // print("添加指纹确认成功,调用添加指纹接口"); - if(state.isCoerced.value == "2"){ - // 非胁迫指纹 + if(state.isCoerced.value == "1"){ + // 非胁迫 int addResultStatus = reply.data[5]; if(addResultStatus == 0){ // 成功更新序列号 - state.cardNumber.value = (reply.data[6]+1).toString(); + state.cardNumber.value = (reply.data[6]).toString(); addICCardData(); }else if(addResultStatus == 255){ // 255 自动退出 @@ -153,10 +150,6 @@ class AddICCardLogic extends BaseGetXController{ } Future _replyAddICStressCard(Reply reply) async { - var token = reply.data.sublist(2, 6); - var saveStrList = changeIntListToStringList(token); - print("_replyAddICCardConfirmationReplyToken:$token"); - Storage.setStringList(saveBlueToken, saveStrList); int status = reply.data[2]; print("_replyAddFingerprintstatus:$status"); @@ -169,8 +162,37 @@ class AddICCardLogic extends BaseGetXController{ addICCardData(); break; case 0x06: - //无权限 + //无权限 + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var signKey = await Storage.getStringList(saveBlueSignKey); + List getSignKeyList = changeStringListToIntList(signKey!); + + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + print("_replyAddICCardConfirmationReplyToken:$token"); + Storage.setStringList(saveBlueToken, saveStrList); + + IoSenderManage.senderAddStressICCardCommand( + keyID:"1", + userID:await Storage.getUid(), + icCardNo:1, + cardType:1, + useCountLimit:1, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: token, + signKey: getSignKeyList, + ); break; case 0x07: //无权限 @@ -190,10 +212,10 @@ class AddICCardLogic extends BaseGetXController{ } } - // 添加卡片开始 + // 添加卡片 Future senderAddICCard() async { - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected){ + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { + if (deviceConnectionState == DeviceConnectionState.connected){ var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); @@ -209,8 +231,10 @@ class AddICCardLogic extends BaseGetXController{ userID:await Storage.getUid(), cardNo:1, useCountLimit:0xff, - startTime:0x11223344, - endTime:0x11223344, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, @@ -222,14 +246,17 @@ class AddICCardLogic extends BaseGetXController{ // 添加胁迫卡片 Future senderAddStressICCard() async { - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected){ + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { + if (deviceConnectionState == DeviceConnectionState.connected){ var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); + var signKey = await Storage.getStringList(saveBlueSignKey); + List getSignKeyList = changeStringListToIntList(signKey!); + var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); print("openDoorTokenPubToken:$getTokenList"); @@ -238,13 +265,17 @@ class AddICCardLogic extends BaseGetXController{ keyID:"1", userID:await Storage.getUid(), icCardNo:1, + cardType:1, useCountLimit:1, startTime:0x11223344, endTime:0x11223344, + // startTime:int.parse(state.startDate.value)~/1000, + // endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, token: getTokenList, + signKey: getSignKeyList, ); } }); @@ -264,6 +295,13 @@ class AddICCardLogic extends BaseGetXController{ ); if (entity.errorCode!.codeIsSuccessful) { Toast.show(msg: "添加成功"); + if(state.fromType.value == 2){ + // 回调指纹号 + eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent(entity.data!.cardId.toString())); + }else if(state.fromType.value == 1){ + eventBus.fire(OtherTypeRefreshListEvent()); + } + Get.close(2); updateIdCardUserNoLoadData(entity.data!.cardId.toString()); } } @@ -275,14 +313,14 @@ class AddICCardLogic extends BaseGetXController{ cardUserNo: state.cardNumber.value, ); if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "添加成功"); - if(state.fromType.value == 2){ - // 回调指纹号 - eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent(cardId)); - }else if(state.fromType.value == 1){ - eventBus.fire(OtherTypeRefreshListEvent()); - } - Get.close(2); + // Toast.show(msg: "添加成功"); + // if(state.fromType.value == 2){ + // // 回调指纹号 + // eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent(cardId)); + // }else if(state.fromType.value == 1){ + // eventBus.fire(OtherTypeRefreshListEvent()); + // } + // Get.close(2); } } diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_page.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_page.dart rename to star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_state.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addICCard/addICCard_state.dart rename to star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart diff --git a/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_logic.dart b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_logic.dart new file mode 100644 index 00000000..366f4d64 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_logic.dart @@ -0,0 +1,175 @@ + +import 'dart:async'; + +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; + +import '../../../../blue/blue_manage.dart'; +import '../../../../blue/io_protocol/io_addICCard.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/storage.dart'; +import '../../../../tools/toast.dart'; +import 'cardDetail_state.dart'; + +class CardDetailLogic extends BaseGetXController{ + CardDetailState state = CardDetailState(); + + // 监听设备返回的数据 + late StreamSubscription _replySubscription; + void _initReplySubscription() { + _replySubscription = EventBusManager().eventBus!.on().listen((reply) async { + // 添加卡片开始(重置锁里面所有卡) + if((reply is SenderAddICCardReply)) { + _replyAddICCardBegin(reply); + } + }); + } + + // 添加卡片开始(此处用作删除卡片) + Future _replyAddICCardBegin(Reply reply) async { + int status = reply.data[2]; + print("_replyAddFingerprintStatus:$status"); + + switch(status){ + case 0x00: + //成功 + print("${reply.commandType!.typeValue} 数据解析成功"); + deletICCardData(); + break; + case 0x06: + //无权限 + print("${reply.commandType!.typeValue} 需要鉴权"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + String? userID = await Storage.getUid(); + IoSenderManage.senderAddICCardCommand( + keyID:state.keyId.value.toString(), + userID:userID, + cardNo:int.parse(state.typeNumber.value), + useCountLimit:0, + startTime:state.effectiveDateTime.value, + endTime:state.failureDateTime.value, + 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} 失败"); + + break; + } + } + + // 删除卡片 + Future senderAddICCard() async { + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { + if (deviceConnectionState == DeviceConnectionState.connected){ + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + print("openDoorTokenPubToken:$getTokenList"); + + String? userID = await Storage.getUid(); + IoSenderManage.senderAddICCardCommand( + keyID:state.keyId.value.toString(), + userID:userID, + cardNo:int.parse(state.typeNumber.value), + useCountLimit:0, + startTime:state.effectiveDateTime.value, + endTime:state.failureDateTime.value, + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList, + ); + } + }); + } + + // 编辑iC卡 + void editICCardData() async{ + var entity = await ApiRepository.to.editICCardData( + cardId: state.keyId.value.toString(), + lockId: state.fingerprintItemData.value.lockId.toString(), + weekDay: state.weekDay.value, + startDate: state.effectiveDateTime.value.toString(), + endDate: state.failureDateTime.value.toString(), + isCoerced: state.isStressFingerprint.value ? "2" : "1", + cardName: state.changeNameController.text, + changeType: "1", + ); + if(entity.errorCode!.codeIsSuccessful){ + Toast.show(msg: "修改成功"); + Get.back(result: "addScuess"); + } + } + + // 删除IC卡 + void deletICCardData() async{ + var entity = await ApiRepository.to.deletIcCardData( + cardId: state.fingerprintItemData.value.cardId.toString(), + lockId: state.fingerprintItemData.value.lockId.toString(), + type: "0", + deleteType:"1" + ); + if(entity.errorCode!.codeIsSuccessful){ + Toast.show(msg: "删除成功"); + Get.back(result: "addScuess"); + } + } + + @override + void onReady() { + // TODO: implement onReady + super.onReady(); + + _initReplySubscription(); + } + + @override + void onInit() { + // TODO: implement onInit + super.onInit(); + + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + + _replySubscription.cancel(); + } + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_page.dart b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_page.dart similarity index 69% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_page.dart rename to star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_page.dart index d29f967a..f1d8c633 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_page.dart +++ b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_page.dart @@ -1,3 +1,4 @@ + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -9,29 +10,30 @@ import '../../../../tools/commonItem.dart'; import '../../../../tools/dateTool.dart'; import '../../../../tools/showIosTipView.dart'; import '../../../../tools/showTFView.dart'; +import '../../../../tools/storage.dart'; import '../../../../tools/submitBtn.dart'; import '../../../../tools/titleAppBar.dart'; import '../../../../tools/toast.dart'; import '../../../../translations/trans_lib.dart'; -import 'otherTypeKeyDetail_logic.dart'; +import 'cardDetail_logic.dart'; -class OtherTypeKeyDetailPage extends StatefulWidget { - const OtherTypeKeyDetailPage({Key? key}) : super(key: key); +class CardDetailPage extends StatefulWidget { + const CardDetailPage({Key? key}) : super(key: key); @override - State createState() => _OtherTypeKeyDetailPageState(); + State createState() => _CardDetailPageState(); } -class _OtherTypeKeyDetailPageState extends State { - final logic = Get.put(OtherTypeKeyDetailLogic()); - final state = Get.find().state; +class _CardDetailPageState extends State { + final logic = Get.put(CardDetailLogic()); + final state = Get.find().state; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.mainBackgroundColor, appBar: TitleAppBar( - barTitle: "${getAppBarTitle(state.type.value)}${TranslationLoader.lanKeys!.number!.tr}", + barTitle: "${TranslationLoader.lanKeys!.card!.tr}${TranslationLoader.lanKeys!.number!.tr}", haveBack: true, backgroundColor: AppColors.mainColor, // actionsList: [ @@ -46,7 +48,7 @@ class _OtherTypeKeyDetailPageState extends State { body: Column( children: [ Obx(() => CommonItem( - leftTitel: "${getAppBarTitle(state.type.value)}${TranslationLoader.lanKeys!.number!.tr}", + leftTitel: "${TranslationLoader.lanKeys!.card!.tr}${TranslationLoader.lanKeys!.number!.tr}", rightTitle: state.typeNumber.value, isHaveDirection: false, isHaveLine: true)), @@ -59,7 +61,7 @@ class _OtherTypeKeyDetailPageState extends State { showCupertinoAlertDialog(context); })), Obx(() => Visibility( - visible: (state.keyType.value == 4 || state.keyType.value == 2) ? true : false, + visible: (state.keyType.value == 4 || state.keyType.value == 2) ? true : false, child: CommonItem( leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, allHeight: 70.h, @@ -74,54 +76,21 @@ class _OtherTypeKeyDetailPageState extends State { // // break; // case 1: - // 当是指纹的时候 - if(state.keyType.value == 2){ - // 限时 - var data = await Get.toNamed(Routers.otherTypeKeyChangeDatePage, arguments: { - "pushType": state.type.value, - "fingerprintItemData": state.fingerprintItemData.value, - }); - if(data != null) { - setState(() { - state.effectiveDateTime.value = data["beginTimeTimestamp"]; - state.failureDateTime.value = data["endTimeTimestamp"]; - }); - } - }else if(state.keyType.value == 4){ - // 循环 - var data = await Get.toNamed(Routers.otherTypeKeyChangeValidityDatePage, arguments: { - "pushType": state.type.value, - "fingerprintItemData": state.fingerprintItemData.value, - }); - if(data != null) { - setState(() { - state.effectiveDateTime.value = data["beginTimeTimestamp"]; - state.failureDateTime.value = data["endTimeTimestamp"]; - state.weekDay.value = data["weekDay"]; - }); - } - } - // break; - // case 2: - // // 遥控 - // - // break; - // } - }))), - Obx(() => Visibility( - visible: state.keyType.value == 4 ? true : false, - child: Obx(() => CommonItem( - leftTitel: TranslationLoader.lanKeys!.effectiveDay!.tr, - rightTitle: state.weekDay.value.join(','), - isHaveDirection: true, - action: () async { - // switch(state.type.value){ - // case 0: - // // 卡 - // - // break; - // case 1: - // 当是指纹的时候 + // 当是指纹的时候 + if(state.keyType.value == 2){ + // 限时 + var data = await Get.toNamed(Routers.otherTypeKeyChangeDatePage, arguments: { + "pushType": state.type.value, + "fingerprintItemData": state.fingerprintItemData.value, + }); + if(data != null) { + setState(() { + state.effectiveDateTime.value = data["beginTimeTimestamp"]; + state.failureDateTime.value = data["endTimeTimestamp"]; + }); + } + }else if(state.keyType.value == 4){ + // 循环 var data = await Get.toNamed(Routers.otherTypeKeyChangeValidityDatePage, arguments: { "pushType": state.type.value, "fingerprintItemData": state.fingerprintItemData.value, @@ -133,13 +102,46 @@ class _OtherTypeKeyDetailPageState extends State { state.weekDay.value = data["weekDay"]; }); } - // break; - // case 2: - // // 遥控 - // - // break; - // } - }))) + } + // break; + // case 2: + // // 遥控 + // + // break; + // } + }))), + Obx(() => Visibility( + visible: state.keyType.value == 4 ? true : false, + child: Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveDay!.tr, + rightTitle: state.weekDay.value.join(','), + isHaveDirection: true, + action: () async { + // switch(state.type.value){ + // case 0: + // // 卡 + // + // break; + // case 1: + // 当是指纹的时候 + var data = await Get.toNamed(Routers.otherTypeKeyChangeValidityDatePage, arguments: { + "pushType": state.type.value, + "fingerprintItemData": state.fingerprintItemData.value, + }); + if(data != null) { + setState(() { + state.effectiveDateTime.value = data["beginTimeTimestamp"]; + state.failureDateTime.value = data["endTimeTimestamp"]; + state.weekDay.value = data["weekDay"]; + }); + } + // break; + // case 2: + // // 遥控 + // + // break; + // } + }))) ), Container(height: 10.h), Obx(() => CommonItem( @@ -156,7 +158,7 @@ class _OtherTypeKeyDetailPageState extends State { })), SizedBox(height: 10.h), Obx(() => CommonItem( - leftTitel: TranslationLoader.lanKeys!.stressFingerprint!.tr, + leftTitel: TranslationLoader.lanKeys!.stressCard!.tr, rightTitle: "", isTipsImg: false, isHaveRightWidget: true, @@ -170,14 +172,14 @@ class _OtherTypeKeyDetailPageState extends State { action: () { switch (state.type.value) { case 0: - // 卡 + // 卡 Get.toNamed(Routers.keyOperationRecordPage, arguments: { 'lockId': state.fingerprintItemData.value.lockId.toString(), 'cardId': state.fingerprintItemData.value.cardId.toString() }); break; case 1: - // 指纹 + // 指纹 Get.toNamed(Routers.keyOperationRecordPage, arguments: { 'lockId': state.fingerprintItemData.value.lockId.toString(), 'fingerprintId': state.fingerprintItemData.value.fingerprintId.toString() @@ -218,21 +220,7 @@ class _OtherTypeKeyDetailPageState extends State { onChanged: (value) { setState(() { state.isStressFingerprint.value = value; - switch(state.type.value){ - case 0: - // 卡 - logic.editICCardData(); - break; - case 1: - // 指纹 - logic.editFingerprintsData(); - break; - case 2: - // 遥控 - - break; - } - + logic.editICCardData(); }); }, ); @@ -328,23 +316,6 @@ class _OtherTypeKeyDetailPageState extends State { // ); // } - String getAppBarTitle(int type) { - String title = ""; - switch (type) { - case 0: - title = TranslationLoader.lanKeys!.card!.tr; - break; - case 1: - title = TranslationLoader.lanKeys!.fingerprint!.tr; - break; - case 2: - title = TranslationLoader.lanKeys!.remoteControl!.tr; - break; - default: - break; - } - return title; - } void showCupertinoAlertDialog(BuildContext context) { showDialog( @@ -360,20 +331,7 @@ class _OtherTypeKeyDetailPageState extends State { return; } Get.back(); - switch(state.type.value){ - case 0: - // 卡 - logic.editICCardData(); - break; - case 1: - // 指纹 - logic.editFingerprintsData(); - break; - case 2: - // 遥控 - - break; - } + logic.editICCardData(); }, cancelClick: () { Get.back(); @@ -388,23 +346,10 @@ class _OtherTypeKeyDetailPageState extends State { return ShowIosTipView( title: "提示", tipTitle: "确定要删除吗?", - sureClick: () { + sureClick: () async { Get.back(); - switch (state.type.value) { - case 0: - // 卡 - logic.deletICCardData(); - break; - case 1: - // 指纹 - logic.deletFingerprintsData(); - break; - case 2: - - break; - default: - break; - } + String? idStr = await Storage.getUid(); + logic.senderAddICCard(); }, cancelClick: () { Get.back(); diff --git a/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_state.dart b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_state.dart new file mode 100644 index 00000000..3fd9f9d7 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/cardDetail/cardDetail_state.dart @@ -0,0 +1,40 @@ + + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../fingerprint/fingerprintList/fingerprintListData_entity.dart'; + +class CardDetailState{ + final fingerprintItemData = FingerprintItemData().obs; + final type = 0.obs;// 0卡 1指纹 2遥控 + + final TextEditingController changeNameController = TextEditingController(); + + final typeNumber = "".obs;// 指纹号 + final typeName = "".obs;// 指纹名字 + var effectiveDateTime = 0.obs;// 生效时间 + var failureDateTime = 0.obs;// 失效时间 + final keyType = 0.obs;// 永久:1;限时2,单次3,循环:4 + var weekDay = [].obs;// 有效日 + var adder = "".obs;// 添加者 + var addTime = 0.obs;// 添加时间 + var keyId = 0.obs;// 卡id + + final isStressFingerprint = false.obs; + CardDetailState() { + Map map = Get.arguments; + fingerprintItemData.value = map["fingerprintItemData"]; + keyId.value = fingerprintItemData.value.cardId!; + typeNumber.value = fingerprintItemData.value.cardNumber!; + typeName.value = fingerprintItemData.value.cardName!; + changeNameController.text = typeName.value; + effectiveDateTime.value = fingerprintItemData.value.startDate!; + failureDateTime.value = fingerprintItemData.value.endDate!; + keyType.value = fingerprintItemData.value.cardType!; + adder.value = fingerprintItemData.value.senderUsername!; + addTime.value = fingerprintItemData.value.createDate!; + isStressFingerprint.value = fingerprintItemData.value.isCoerced! == 2 ? true : false; + weekDay.value = fingerprintItemData.value.weekDay!; + } +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/card/cardList/cardList_logic.dart b/star_lock/lib/main/lockDetail/card/cardList/cardList_logic.dart new file mode 100644 index 00000000..415ed1c1 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/cardList/cardList_logic.dart @@ -0,0 +1,382 @@ + +import 'dart:async'; + +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import '../../../../blue/blue_manage.dart'; +import '../../../../blue/io_protocol/io_addICCard.dart'; +import '../../../../blue/io_protocol/io_checkingCardStatus.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'; +import '../../../../tools/toast.dart'; +import 'cardList_state.dart'; + +class CardListLogic extends BaseGetXController { + CardListState state = CardListState(); + + // 获取解析后的数据 + late StreamSubscription _replySubscription; + void _initReplySubscription() { + _replySubscription = EventBusManager().eventBus!.on().listen((reply) { + + // 添加卡片开始(重置锁里面所有卡) + if((reply is SenderAddICCardReply) && (state.isDeletCardData == true)) { + _replyAddICCardBegin(reply); + } + + if(reply is SenderCheckingCardStatusReply) { + _replyReferEventRecordNumber(reply); + } + + if(reply is SenderCheckingUserInfoCountReply){ + _replyCheckingUserInfoCount(reply); + } + }); + } + + // 添加卡片开始(此处用作删除卡片) + Future _replyAddICCardBegin(Reply reply) async { + int status = reply.data[2]; + print("_replyAddFingerprintStatus:$status"); + + switch(status){ + case 0x00: + //成功 + print("${reply.commandType!.typeValue} 数据解析成功"); + state.isDeletCardData = false; + deletICCardData(); + break; + case 0x06: + //无权限 + print("${reply.commandType!.typeValue} 需要鉴权"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderAddICCardCommand( + keyID:state.deletKeyID, + userID:state.deletUserID, + cardNo:state.deletCardNo, + 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} 失败"); + + break; + } + } + + // 获取卡片状态 + Future _replyReferEventRecordNumber(Reply reply) async { + int status = reply.data[2]; + switch(status){ + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + // _getLockStatus(); + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // 查询用户、指纹、密码、卡片数量(用于判断是否同步) + Future _replyCheckingUserInfoCount(Reply reply) async { + int status = reply.data[2]; + + // 用户数量 + int userNum = reply.data[5]; + // print("userNum:$userNum"); + + // 指纹数量 + int fingerNum = reply.data[6]; + // print("fingerNum:$fingerNum"); + + // 密码数量 + int pwdNum = reply.data[7]; + + // 卡片数量 + int cardNum = reply.data[8]; + + // 记录数量 + int logsNum = reply.data[9]; + + // 版本 + int verNo = reply.data[10]; + + // 最大管理员指纹数量 + int maxAdminFingerNum = reply.data[11]; + + // 最大用户指纹数量 + int maxUserFingerNum = reply.data[12]; + + // 最大管理员密码数量 + int maxAdminPassNum = reply.data[13]; + + // 最大用户密码数量 + int maxUserPassNum = reply.data[14]; + + // 最大管理员卡片数量 + int maxAdminCardNum = reply.data[15]; + + // 最大用户卡片数量 + int maxUserCardNum = reply.data[16]; + + // 序列号 + var serialNo = reply.data.sublist(17, 21); + print("serialNo:$serialNo"); + + switch(status){ + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + // _getLockStatus(); + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // 查询卡片状态 + Future senderCheckingCardStatus() async { + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { + if (state == DeviceConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List getPublicKeyList = changeStringListToIntList(publicKey!); + + IoSenderManage.senderCheckingCardStatusCommand( + keyID:BlueManage().connectDeviceName, + userID:await Storage.getUid(), + role:0xff, + cardCount:20, + cardNo:1, + token:getTokenList, + needAuthor:1, + publicKey:getPublicKeyList, + privateKey:getPrivateKeyList, + ); + } + }); + } + + // 查询用户、指纹、密码、卡片数量(用于判断是否同步) + Future senderCheckingUserInfoCount() async { + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { + if (state == DeviceConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List getPublicKeyList = changeStringListToIntList(publicKey!); + + IoSenderManage.senderCheckingUserInfoCountCommand( + keyID:BlueManage().connectDeviceName, + userID:await Storage.getUid(), + role:0xff, + nowTime:DateTime.now().millisecondsSinceEpoch~/1000, + token:getTokenList, + needAuthor:1, + publicKey:getPublicKeyList, + privateKey:getPrivateKeyList, + ); + } + }, isShowLoading: false); + } + + // 删除卡片 + Future senderAddICCard() async { + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { + if (deviceConnectionState == DeviceConnectionState.connected){ + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + print("openDoorTokenPubToken:$getTokenList"); + + IoSenderManage.senderAddICCardCommand( + keyID:state.deletKeyID, + userID:state.deletUserID, + cardNo:state.deletCardNo, + useCountLimit:0, + startTime:0x11223344, + endTime:0x11223344, + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList, + ); + } + }); + } + + // 获取IC卡列表 + void getICCardListData() async{ + var entity = await ApiRepository.to.getICCardListData( + lockId: state.lockId.value.toString(), + pageNo: '1', + pageSize: '20', + searchStr: state.searchController.text, + ); + if(entity.errorCode!.codeIsSuccessful){ + state.fingerprintItemListData.value = entity.data!.list!; + } + } + + // 删除所有IC卡 + void deletICCardData() async{ + var cardId = ""; + var type = "1"; + if(state.isDeletAll == false){ + cardId = state.deletKeyID; + type = "0"; + } + print("delet fingerprintId $cardId"); + var entity = await ApiRepository.to.deletIcCardData( + cardId: cardId, + lockId: state.lockId.value.toString(), + type: type, + deleteType:"1" + ); + if(entity.errorCode!.codeIsSuccessful){ + if(state.isDeletAll == false){ + Toast.show(msg: "删除成功"); + }else{ + Toast.show(msg: "重置成功"); + } + + state.isDeletCardData = false; + getICCardListData(); + } + } + + // 监听修改完详情之后刷新列表 + late StreamSubscription _teamEvent; + void _initRefreshAction() { + _teamEvent = eventBus.on().listen((event) { + getICCardListData(); + }); + } + + @override + Future onReady() async { + // TODO: implement onReady + super.onReady(); + print("onReady()"); + + // 获取是否是演示模式 演示模式不获取接口 + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + // print("aaaaaaa:$isDemoMode"); + if(isDemoMode == false){ + _initReplySubscription(); + + _initRefreshAction(); + + // 卡 + getICCardListData(); + } + } + + @override + Future onInit() async { + // TODO: implement onInit + super.onInit(); + print("onInit()"); + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if(isDemoMode == false) { + // senderQueryingFingerprintStatus(); + // senderCheckingCardStatus(); + senderCheckingUserInfoCount(); + } + } + + @override + Future onClose() async { + // TODO: implement onClose + super.onClose(); + + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if(isDemoMode == false) { + _replySubscription.cancel(); + _teamEvent.cancel(); + } + } +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/card/cardList/cardList_page.dart b/star_lock/lib/main/lockDetail/card/cardList/cardList_page.dart new file mode 100644 index 00000000..0d8e272c --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/cardList/cardList_page.dart @@ -0,0 +1,304 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../appRouters.dart'; +import '../../../../app_settings/app_colors.dart'; +import '../../../../tools/dateTool.dart'; +import '../../../../tools/left_slide_actions.dart'; +import '../../../../tools/noData.dart'; +import '../../../../tools/showIosTipView.dart'; +import '../../../../tools/storage.dart'; +import '../../../../tools/submitBtn.dart'; +import '../../../../tools/titleAppBar.dart'; +import '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import '../../fingerprint/fingerprintList/fingerprintListData_entity.dart'; +import 'cardList_logic.dart'; + +class CardListPage extends StatefulWidget { + const CardListPage({Key? key}) : super(key: key); + + @override + State createState() => _CardListPageState(); +} + +class _CardListPageState extends State { + final logic = Get.put(CardListLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: TranslationLoader.lanKeys!.card!.tr, + 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.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }, + ), + ], + ), + body: Column( + children: [ + _searchWidget(), + SizedBox(height: 20.h), + Expanded(child: _buildMainUI()), + AddBottomWhiteBtn( + btnName: + '${TranslationLoader.lanKeys!.add!.tr}${TranslationLoader.lanKeys!.card!.tr}', + onClick: () async { + var data = + await Get.toNamed(Routers.addCardTypeManagePage, arguments: { + "lockId": state.lockId.value, + "fromType": 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + }); + if (data != null) { + logic.getICCardListData(); + } + }, + ), + SizedBox( + height: 64.h, + ) + ], + ), + ); + } + + Widget _searchWidget() { + return Container( + height: 60.h, + margin: EdgeInsets.only(top: 20.w, left: 20.w, right: 10.w), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: TextField( + //输入框一行 + maxLines: 1, + controller: state.searchController, + autofocus: false, + onChanged: (value) { + print("onChanged:$value"); + }, + onEditingComplete: () { + print("onEditingComplete:"); + }, + onSubmitted: (value) { + logic.getICCardListData(); + }, + decoration: InputDecoration( + //输入里面输入文字内边距设置 + contentPadding: const EdgeInsets.only( + top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, + hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), + //不需要输入框下划线 + border: InputBorder.none, + //左边图标设置 + icon: Padding( + padding: EdgeInsets.only( + top: 20.h, bottom: 20.h, right: 20.w, left: 10.w), + child: Image.asset( + 'images/main/icon_main_search.png', + width: 40.w, + height: 40.w, + ), + ), + ), + ), + ); + } + + Widget _buildMainUI() { + return Obx(() => state.fingerprintItemListData.value.isNotEmpty + ? ListView.separated( + itemCount: state.fingerprintItemListData.value.length, + itemBuilder: (c, index) { + FingerprintItemData fingerprintItemData = state.fingerprintItemListData.value[index]; + if (index < state.fingerprintItemListData.value.length) { + return LeftSlideActions( + key: Key(fingerprintItemData.cardName!), + actionsWidth: 60, + actions: [ + _buildDeleteBtn(fingerprintItemData), + ], + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(1)), + ), + child: _keyItem( + 'images/icon_card.png', + fingerprintItemData.cardName!, + fingerprintItemData.cardType! == 1 + ? "永久" + : + "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", () async { + var data = await Get.toNamed( + Routers.cardDetailPage, arguments: { + "fingerprintItemData": fingerprintItemData, + }); + if (data != null) { + logic.getICCardListData(); + } + }), + ); + } + return const SizedBox.shrink(); + }, + separatorBuilder: (BuildContext context, int index) { + return const Divider( + height: 1, + color: AppColors.greyLineColor, + ); + }, + ) : const NoData()); + } + + Widget _buildDeleteBtn(FingerprintItemData fingerprintItemData) { + return GestureDetector( + onTap: () { + // 省略: 弹出是否删除的确认对话框。 + state.deletKeyID = fingerprintItemData.cardId.toString(); + state.deletCardNo = int.parse(fingerprintItemData.cardNumber!); + 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.isDeletCardData = true; + state.isDeletAll = false; + state.deletUserID = (await Storage.getUid())!; + logic.senderAddICCard(); + }, + cancelClick: () { + Get.back(); + }, + ); + }, + ); + } + + Widget _keyItem(String lockTypeIcon, String lockTypeTitle, 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.start, + children: [ + Text(lockTypeTitle, + style: TextStyle( + fontSize: 24.sp, color: AppColors.blackColor)), + ], + ), + SizedBox(height: 5.h), + Container( + child: 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.isDeletCardData = true; + state.isDeletAll = true; + state.deletKeyID = "1"; + state.deletUserID = "DeleteAll!@#"; + state.deletCardNo = 255; + logic.senderAddICCard(); + }, + ), + ], + ); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/card/cardList/cardList_state.dart b/star_lock/lib/main/lockDetail/card/cardList/cardList_state.dart new file mode 100644 index 00000000..11c97626 --- /dev/null +++ b/star_lock/lib/main/lockDetail/card/cardList/cardList_state.dart @@ -0,0 +1,23 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../fingerprint/fingerprintList/fingerprintListData_entity.dart'; + +class CardListState { + final lockId = 0.obs; + + // 因为删除跟添加指纹用的同一个协议 所以这里用做判断 + var isDeletCardData = false; + var isDeletAll = false; + var deletKeyID = ""; + var deletUserID = "DeleteAll!@#"; + var deletCardNo = 0; + + final fingerprintItemListData = [].obs; + final TextEditingController searchController = TextEditingController(); + + CardListState() { + Map map = Get.arguments; + lockId.value = map["lockId"]; + } +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart similarity index 97% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart rename to star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart index 2db946c8..c18963b6 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart +++ b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_logic.dart @@ -19,6 +19,7 @@ class OtherTypeKeyChangeDateLogic extends BaseGetXController{ endDate: state.endTimeTimestamp.value.toString(), isCoerced: state.fingerprintItemData.value.isCoerced == 1 ? "2" : "1", fingerprintName: state.fingerprintItemData.value.fingerprintName!, + changeType: "1", ); if(entity.errorCode!.codeIsSuccessful){ Toast.show(msg: "修改成功"); @@ -40,6 +41,7 @@ class OtherTypeKeyChangeDateLogic extends BaseGetXController{ endDate: state.endTimeTimestamp.value.toString(), isCoerced: state.fingerprintItemData.value.isCoerced == 1 ? "2" : "1", cardName: state.fingerprintItemData.value.cardName!, + changeType: '1', ); if(entity.errorCode!.codeIsSuccessful){ Toast.show(msg: "修改成功"); diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart similarity index 61% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart rename to star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart index 84b96760..536fd0a7 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart +++ b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_page.dart @@ -1,9 +1,10 @@ - import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import '../../../../app_settings/app_colors.dart'; import '../../../../tools/commonItem.dart'; @@ -15,10 +16,12 @@ class OtherTypeKeyChangeDatePage extends StatefulWidget { const OtherTypeKeyChangeDatePage({Key? key}) : super(key: key); @override - State createState() => _OtherTypeKeyChangeDatePageState(); + State createState() => + _OtherTypeKeyChangeDatePageState(); } -class _OtherTypeKeyChangeDatePageState extends State { +class _OtherTypeKeyChangeDatePageState + extends State { final logic = Get.put(OtherTypeKeyChangeDateLogic()); final state = Get.find().state; @@ -27,7 +30,8 @@ class _OtherTypeKeyChangeDatePageState extends State return Scaffold( backgroundColor: AppColors.mainBackgroundColor, appBar: TitleAppBar( - barTitle: "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.periodValidity!.tr}", + barTitle: + "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.periodValidity!.tr}", haveBack: true, backgroundColor: AppColors.mainColor, actionsList: [ @@ -48,7 +52,6 @@ class _OtherTypeKeyChangeDatePageState extends State logic.editFingerprintsData(); break; case 2: - break; default: break; @@ -72,12 +75,14 @@ class _OtherTypeKeyChangeDatePageState extends State action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - state.beginTimeTimestamp.value = DateTime.parse( - '${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')}').millisecondsSinceEpoch; - 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')}"; - }); - }); + setState(() { + state.beginTimeTimestamp.value = DateTime.parse( + '${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')}') + .millisecondsSinceEpoch; + 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')}"; + }); + }); })), Obx(() => CommonItem( leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, @@ -86,12 +91,14 @@ class _OtherTypeKeyChangeDatePageState extends State action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - state.endTimeTimestamp.value = DateTime.parse( - '${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')}').millisecondsSinceEpoch; - 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')}"; - }); - }); + setState(() { + state.endTimeTimestamp.value = DateTime.parse( + '${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')}') + .millisecondsSinceEpoch; + 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')}"; + }); + }); })), ], ); diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart similarity index 92% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart rename to star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart index 18dafe75..1dc7721c 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart +++ b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeDate/otherTypeKeyChangeDate_state.dart @@ -1,8 +1,7 @@ import 'package:get/get.dart'; - import '../../../../tools/dateTool.dart'; -import '../otherTypeKeyList/fingerprintListData_entity.dart'; +import '../../fingerprint/fingerprintList/fingerprintListData_entity.dart'; class OtherTypeKeyChangeDateState{ final fingerprintItemData = FingerprintItemData().obs; diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart similarity index 97% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart rename to star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart index 2f38fcea..60056d04 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart +++ b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_logic.dart @@ -20,6 +20,7 @@ class OtherTypeKeyChangeValidityDateLogic extends BaseGetXController{ endDate: state.endTimeTimestamp.value.toString(), isCoerced: state.fingerprintItemData.value.isCoerced == 1 ? "2" : "1", fingerprintName: state.fingerprintItemData.value.fingerprintName!, + changeType: "1", ); if(entity.errorCode!.codeIsSuccessful){ Toast.show(msg: "修改成功"); @@ -42,6 +43,7 @@ class OtherTypeKeyChangeValidityDateLogic extends BaseGetXController{ endDate: state.endTimeTimestamp.value.toString(), isCoerced: state.fingerprintItemData.value.isCoerced == 1 ? "2" : "1", cardName: state.fingerprintItemData.value.cardName!, + changeType: '1', ); if(entity.errorCode!.codeIsSuccessful){ Toast.show(msg: "修改成功"); diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart similarity index 63% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart rename to star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart index 4e109b42..54155847 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart +++ b/star_lock/lib/main/lockDetail/card/otherTypeKeyChangeValidityDate/otherTypeKeyChangeValidityDate_page.dart @@ -1,10 +1,10 @@ - - import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import '../../../../app_settings/app_colors.dart'; import '../../../../tools/commonItem.dart'; @@ -17,10 +17,12 @@ class OtherTypeKeyChangeValidityDatePage extends StatefulWidget { const OtherTypeKeyChangeValidityDatePage({Key? key}) : super(key: key); @override - State createState() => _OtherTypeKeyChangeValidityDatePageState(); + State createState() => + _OtherTypeKeyChangeValidityDatePageState(); } -class _OtherTypeKeyChangeValidityDatePageState extends State { +class _OtherTypeKeyChangeValidityDatePageState + extends State { final logic = Get.put(OtherTypeKeyChangeValidityDateLogic()); final state = Get.find().state; @@ -46,9 +48,9 @@ class _OtherTypeKeyChangeValidityDatePageState extends State Container( - width: 40.w, - height: 40.w, - margin: EdgeInsets.all(10.w), - decoration: BoxDecoration( - color: state.weekDay.value.contains(index) ? AppColors.mainColor :Colors.white, - border: Border.all(width: 1, color: AppColors.btnDisableColor), - borderRadius: BorderRadius.circular(30.w), - ), - child: Center( - child: Text( + width: 40.w, + height: 40.w, + margin: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: state.weekDay.value.contains(index) + ? AppColors.mainColor + : Colors.white, + border: Border.all(width: 1, color: AppColors.btnDisableColor), + borderRadius: BorderRadius.circular(30.w), + ), + child: Center( + child: Text( dateStr, - style: TextStyle(fontSize: 20.sp, color: state.weekDay.value.contains(index) ? Colors.white : AppColors.darkGrayTextColor), + style: TextStyle( + fontSize: 20.sp, + color: state.weekDay.value.contains(index) + ? Colors.white + : AppColors.darkGrayTextColor), )), - )), + )), ); } @@ -153,34 +163,38 @@ class _OtherTypeKeyChangeValidityDatePageState extends State CommonItem( leftTitel: - "${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}", + "${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}", rightTitle: state.beginTime.value, isHaveDirection: true, isHaveLine: true, action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - state.beginTimeTimestamp.value = DateTime.parse( - '${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')}').millisecondsSinceEpoch; - 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')}"; - }); - }); + setState(() { + state.beginTimeTimestamp.value = DateTime.parse( + '${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')}') + .millisecondsSinceEpoch; + 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')}"; + }); + }); })), Obx(() => CommonItem( leftTitel: - "${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}", + "${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}", rightTitle: state.endTime.value, isHaveDirection: true, action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - setState(() { - state.endTimeTimestamp.value = DateTime.parse( - '${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')}').millisecondsSinceEpoch; - 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')}"; - }); - }); + setState(() { + state.endTimeTimestamp.value = DateTime.parse( + '${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')}') + .millisecondsSinceEpoch; + 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')}"; + }); + }); })), Container(height: 10.h), ], @@ -189,5 +203,4 @@ class _OtherTypeKeyChangeValidityDatePageState extends State { actionsList: [ GestureDetector( onTap: () async { - var data = await Get.toNamed(Routers.checkingInAddHolidaysPage, arguments: { - "companyId": state.companyId.value - }); - if(data != null) { + var data = await Get.toNamed( + Routers.checkingInAddHolidaysPage, + arguments: {"companyId": state.companyId.value}); + if (data != null) { logic.editStaffLoadData(); } }, @@ -59,47 +64,60 @@ class _CheckingInSetHolidaysPageState extends State { ], ), body: Obx(() { - return state.holidaysListData.value!.isNotEmpty ? ListView.builder( - itemCount: state.holidaysListData.value!.length, - itemBuilder: (c, index) { - HolidaysMonthListData holidaysMonthListData = state.holidaysListData.value![index]; - return _checkingInListMouthItem(holidaysMonthListData); - }):const NoData(); - }) - ); + return state.holidaysListData.value!.isNotEmpty + ? ListView.builder( + itemCount: state.holidaysListData.value!.length, + itemBuilder: (c, index) { + HolidaysMonthListData holidaysMonthListData = + state.holidaysListData.value![index]; + return _checkingInListMouthItem(holidaysMonthListData); + }) + : const NoData(); + })); } Widget _checkingInListMouthItem(HolidaysMonthListData holidaysMonthListData) { return GestureDetector( child: Container( - height: 140.h*holidaysMonthListData.listItem!.length + 20.w, + height: 140.h * holidaysMonthListData.listItem!.length + 20.w, padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w), child: Row( children: [ Container( - color: colorWithMonth(int.parse(holidaysMonthListData.listItem![0].month.toString())), + color: colorWithMonth(int.parse( + holidaysMonthListData.listItem![0].month.toString())), width: 100.w, - height: 140.h*holidaysMonthListData.listItem!.length, + height: 140.h * holidaysMonthListData.listItem!.length, child: Center( child: Text( - "${holidaysMonthListData.listItem![0].month}\n${TranslationLoader.lanKeys!.month!.tr}", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 28.sp, color: Colors.white), - ))), + "${holidaysMonthListData.listItem![0].month}\n${TranslationLoader.lanKeys!.month!.tr}", + textAlign: TextAlign.center, + style: TextStyle(fontSize: 28.sp, color: Colors.white), + ))), SizedBox( - height: 140.h*holidaysMonthListData.listItem!.length, - width: 1.sw - 100.w - 20.w*2, + height: 140.h * holidaysMonthListData.listItem!.length, + width: 1.sw - 100.w - 20.w * 2, child: ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: holidaysMonthListData.listItem!.length, itemBuilder: (c, index) { ListItem listItem = holidaysMonthListData.listItem![index]; - return _checkingInListItem(index, listItem.vacationName, DateTool().dateToYMDString(listItem.vacationStartDate.toString()), DateTool().dateToYMDString(listItem.vacationEndDate.toString()), listItem.fillClassDate!.isNotEmpty ? DateTool().dateToYMDString(listItem.fillClassDate.toString()):"", () async { - var data = await Get.toNamed(Routers.checkingInDeletHolidaysPage, arguments: { - "listItem": listItem - }); - if(data != null) { + return _checkingInListItem( + index, + listItem.vacationName, + DateTool().dateToYMDString( + listItem.vacationStartDate.toString()), + DateTool().dateToYMDString( + listItem.vacationEndDate.toString()), + listItem.fillClassDate!.isNotEmpty + ? DateTool().dateToYMDString( + listItem.fillClassDate.toString()) + : "", () async { + var data = await Get.toNamed( + Routers.checkingInDeletHolidaysPage, + arguments: {"listItem": listItem}); + if (data != null) { logic.editStaffLoadData(); } }); @@ -111,13 +129,19 @@ class _CheckingInSetHolidaysPageState extends State { ); } - Widget _checkingInListItem(int index, String? lockTypeTitle, String? vacationStartDate, String? vacationEndDate, String? makeUpClass, Function() action) { + Widget _checkingInListItem( + int index, + String? lockTypeTitle, + String? vacationStartDate, + String? vacationEndDate, + String? makeUpClass, + Function() action) { return GestureDetector( onTap: action, child: Column( children: [ Container( - color:Colors.white, + color: Colors.white, height: 140.h, padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 10.h), child: Row( @@ -174,27 +198,27 @@ class _CheckingInSetHolidaysPageState extends State { showListType(); }, child: Obx(() => Container( - width: 300.w, - height: 50.h, - color: AppColors.mainColor, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "${state.seletYear.value}${TranslationLoader.lanKeys!.year!.tr}", - style: TextStyle(color: Colors.white, fontSize: 26.sp), + width: 300.w, + height: 50.h, + color: AppColors.mainColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "${state.seletYear.value}${TranslationLoader.lanKeys!.year!.tr}", + style: TextStyle(color: Colors.white, fontSize: 26.sp), + ), + SizedBox( + width: 5.w, + ), + Image.asset( + 'images/main/icon_lockDetail_checkIn_topTitle.png', + width: 22.w, + height: 16.w, + ) + ], ), - SizedBox( - width: 5.w, - ), - Image.asset( - 'images/main/icon_lockDetail_checkIn_topTitle.png', - width: 22.w, - height: 16.w, - ) - ], - ), - )), + )), ); } @@ -242,9 +266,9 @@ class _CheckingInSetHolidaysPageState extends State { ); } - Color colorWithMonth(int month){ + Color colorWithMonth(int month) { Color colorType; - switch (month){ + switch (month) { case 1: colorType = const Color(0xFFb8d152); break; diff --git a/star_lock/lib/main/lockDetail/checkingIn/checkingInSetWorkTime/checkingInSetWorkTime_page.dart b/star_lock/lib/main/lockDetail/checkingIn/checkingInSetWorkTime/checkingInSetWorkTime_page.dart index d6801b82..1999e94e 100644 --- a/star_lock/lib/main/lockDetail/checkingIn/checkingInSetWorkTime/checkingInSetWorkTime_page.dart +++ b/star_lock/lib/main/lockDetail/checkingIn/checkingInSetWorkTime/checkingInSetWorkTime_page.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../app_settings/app_colors.dart'; @@ -16,7 +18,8 @@ class CheckingInSetWorkTimePage extends StatefulWidget { const CheckingInSetWorkTimePage({Key? key}) : super(key: key); @override - State createState() => _CheckingInSetWorkTimePageState(); + State createState() => + _CheckingInSetWorkTimePageState(); } class _CheckingInSetWorkTimePageState extends State { @@ -27,77 +30,100 @@ class _CheckingInSetWorkTimePageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.mainBackgroundColor, - appBar: TitleAppBar(barTitle: "${TranslationLoader.lanKeys!.work!.tr} ${TranslationLoader.lanKeys!.time!.tr} ${TranslationLoader.lanKeys!.set!.tr}", haveBack:true, backgroundColor: AppColors.mainColor), + appBar: TitleAppBar( + barTitle: + "${TranslationLoader.lanKeys!.work!.tr} ${TranslationLoader.lanKeys!.time!.tr} ${TranslationLoader.lanKeys!.set!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor), body: buildMainUI(), ); } - Widget buildMainUI(){ + Widget buildMainUI() { return Column( children: [ - Obx(() => CommonItem(leftTitel:TranslationLoader.lanKeys!.officeHours!.tr, rightTitle:state.beginTime.value, isHaveDirection: true, isHaveLine: true, action:(){ - Pickers.showDatePicker(context, mode: DateMode.HM, - onConfirm: (p) { + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.officeHours!.tr, + rightTitle: state.beginTime.value, + isHaveDirection: true, + isHaveLine: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.HM, + onConfirm: (p) { setState(() { DateTime today = DateTime.now(); state.beginTimeTimestamp.value = DateTime.parse( - '${today.year}-${today.month.toString().padLeft(2,'0')}-${today.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch.toString(); - state.beginTime.value = "${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}"; + '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}') + .millisecondsSinceEpoch + .toString(); + state.beginTime.value = + "${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}"; }); }); - })), - Obx(() => CommonItem(leftTitel:TranslationLoader.lanKeys!.closingTime!.tr, rightTitle:state.endTime.value, isHaveDirection: true, action:(){ - Pickers.showDatePicker(context, mode: DateMode.HM, - onConfirm: (p) { + })), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.closingTime!.tr, + rightTitle: state.endTime.value, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.HM, + onConfirm: (p) { setState(() { DateTime today = DateTime.now(); state.endTimeTimestamp.value = DateTime.parse( - '${today.year}-${today.month.toString().padLeft(2,'0')}-${today.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch.toString(); - state.endTime.value = "${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}"; + '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}') + .millisecondsSinceEpoch + .toString(); + state.endTime.value = + "${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}"; }); }); - })), - SizedBox(height: 30.h,), - SubmitBtn(btnName: TranslationLoader.lanKeys!.sure!.tr, + })), + SizedBox( + height: 30.h, + ), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.sure!.tr, borderRadius: 20.w, fontSize: 32.sp, margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 20.w), padding: EdgeInsets.only(top: 20.w, bottom: 20.w), onClick: () { - if(state.beginTimeTimestamp.value.isEmpty){ + if (state.beginTimeTimestamp.value.isEmpty) { Toast.show(msg: "请选择开始时间"); return; } - if(state.endTimeTimestamp.value.isEmpty){ + if (state.endTimeTimestamp.value.isEmpty) { Toast.show(msg: "请选择结束时间"); return; } - if(int.parse(state.beginTimeTimestamp.value) > int.parse(state.endTimeTimestamp.value)){ + if (int.parse(state.beginTimeTimestamp.value) > + int.parse(state.endTimeTimestamp.value)) { Toast.show(msg: "结束时间不能大于开始时间"); return; } - if(state.pushType.value == "2"){ + if (state.pushType.value == "2") { logic.editCheckInSetInfoData(); - }else{ + } else { Get.back(result: { - "beginTime":state.beginTime.value, - "beginTimeTimestamp":state.beginTimeTimestamp.value, - "endTime":state.endTime.value, - "endTimeTimestamp":state.endTimeTimestamp.value, + "beginTime": state.beginTime.value, + "beginTimeTimestamp": state.beginTimeTimestamp.value, + "endTime": state.endTime.value, + "endTimeTimestamp": state.endTimeTimestamp.value, }); } - } - ), + }), ], ); } - String getNowDate(){ + String getNowDate() { // 获取当前时间对象 DateTime today = DateTime.now(); - String dateSlug ="${today.hour.toString().padLeft(2,'0')}:${today.minute.toString().padLeft(2,'0')}"; + String dateSlug = + "${today.hour.toString().padLeft(2, '0')}:${today.minute.toString().padLeft(2, '0')}"; // //获取当前时间的年 // int year = now.year; @@ -115,5 +141,4 @@ class _CheckingInSetWorkTimePageState extends State { // print("组合 $year-$month-$day $hour:$minute:$millisecond"); return dateSlug; } - } diff --git a/star_lock/lib/main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkingInAddStaff_page.dart b/star_lock/lib/main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkingInAddStaff_page.dart index 59be558e..ad0db541 100644 --- a/star_lock/lib/main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkingInAddStaff_page.dart +++ b/star_lock/lib/main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkingInAddStaff_page.dart @@ -166,7 +166,7 @@ class _CheckingInAddStaffPageState extends State { } var data = await Get.toNamed( - Routers.otherTypeKeyManagePage, + Routers.addCardTypeManagePage, arguments: { "lockId": state .getKeyInfosData.value.lockId, @@ -187,7 +187,7 @@ class _CheckingInAddStaffPageState extends State { } var data = await Get.toNamed( - Routers.otherTypeKeyManagePage, + Routers.addFingerprintTypeManagePage, arguments: { "lockId": state .getKeyInfosData.value.lockId, diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_logic.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_logic.dart new file mode 100644 index 00000000..217f044b --- /dev/null +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_logic.dart @@ -0,0 +1,34 @@ +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_state.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; +import 'package:star_lock/network/api_repository.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/toast.dart'; + +class ElectronicKeyDetailLogic extends BaseGetXController { + final ElectronicKeyDetailState state = ElectronicKeyDetailState(); + + //修改钥匙名称请求 + Future modifyKeyNameRequest() async { + KeyOperationRecordEntity entity = await ApiRepository.to + .modifyKeyNameForAdmin(state.itemData.value.keyId.toString(), + state.changeNameController.text, ''); + if (entity.errorCode!.codeIsSuccessful) { + print("修改要是名称成功啦啦啦啦啦"); + Toast.show(msg: "修改成功"); + Get.back(); + } + } + + //删除电子钥匙名称请求 + Future deleteKeyRequest() async { + ElectronicKeyListEntity entity = await ApiRepository.to + .deleteElectronicKey(state.itemData.value.keyId.toString()); + if (entity.errorCode!.codeIsSuccessful) { + print("删除电子钥匙成功"); + Toast.show(msg: "删除成功"); + Get.back(); + } + } +} diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_page.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_page.dart index 0852ba7b..2e702252 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_page.dart @@ -3,12 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; -import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_logic.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; -import 'package:star_lock/network/api_repository.dart'; -import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/jh_pop_menus.dart'; -import 'package:star_lock/tools/toast.dart'; import '../../../../../appRouters.dart'; import '../../../../../app_settings/app_colors.dart'; @@ -28,16 +25,11 @@ class ElectronicKeyDetailPage extends StatefulWidget { } class _ElectronicKeyDetailPageState extends State { - final TextEditingController _changeNameController = TextEditingController(); - ElectronicKeyListItem itemData = ElectronicKeyListItem(); + final logic = Get.put(ElectronicKeyDetailLogic()); + final state = Get.find().state; @override Widget build(BuildContext context) { - dynamic obj = ModalRoute.of(context)?.settings.arguments; - if (obj != null && (obj["itemData"] != null)) { - itemData = obj["itemData"]; - } - return Scaffold( resizeToAvoidBottomInset: false, backgroundColor: AppColors.mainBackgroundColor, @@ -68,38 +60,29 @@ class _ElectronicKeyDetailPageState extends State { children: [ CommonItem( leftTitel: TranslationLoader.lanKeys!.name!.tr, - rightTitle: _changeNameController.text.isNotEmpty - ? _changeNameController.text - : itemData.keyName, + rightTitle: state.changeNameController.text.isNotEmpty + ? state.changeNameController.text + : state.itemData.value.keyName, isHaveDirection: true, isHaveLine: true, action: () { showCupertinoAlertDialog(context); }), - CommonItem( - leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, - allHeight: 90.h, - rightTitle: getUseDateStr(itemData), - isHaveDirection: true, - action: () { - Navigator.pushNamed( - context, Routers.electronicKeyDetailChangeDate, - arguments: {"itemData": itemData}); - }), + getPeriodValidityWidget(), Container(height: 10.h), CommonItem( leftTitel: TranslationLoader.lanKeys!.receiver!.tr, - rightTitle: itemData.username, + rightTitle: state.itemData.value.username, action: () {}), const SizedBox(height: 1), CommonItem( leftTitel: TranslationLoader.lanKeys!.sender!.tr, - rightTitle: itemData.senderUsername, + rightTitle: state.itemData.value.senderUsername, action: () {}), const SizedBox(height: 1), CommonItem( leftTitel: TranslationLoader.lanKeys!.senderTime!.tr, - rightTitle: getSenderDate(itemData), + rightTitle: getSenderDate(state.itemData.value), action: () {}), Container(height: 10.h), CommonItem( @@ -108,8 +91,9 @@ class _ElectronicKeyDetailPageState extends State { isHaveRightWidget: true, rightWidget: SizedBox( width: 60.w, - child: - _switch(itemData.faceAuthentication == 1 ? true : false)), + child: _switch(state.itemData.value.faceAuthentication == 1 + ? true + : false)), action: () {}), Container(height: 10.h), CommonItem( @@ -119,8 +103,8 @@ class _ElectronicKeyDetailPageState extends State { action: () { Navigator.pushNamed(context, Routers.keyOperationRecordPage, arguments: { - 'lockId': itemData.lockId.toString(), - 'keyId': itemData.keyId.toString() + 'lockId': state.itemData.value.lockId.toString(), + 'keyId': state.itemData.value.keyId.toString() }); }), Container(height: 40.h), @@ -139,106 +123,136 @@ class _ElectronicKeyDetailPageState extends State { ); } - //使用期限 - String getUseDateStr(ElectronicKeyListItem indexEntity) { - String useDateStr = ''; - if (indexEntity.keyType == XSConstantMacro.keyTypeTime) { - //限期 - DateTime startDateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.startDate!); - DateTime endDateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.endDate!); - useDateStr = - '${startDateStr.toLocal().toString().substring(0, 16)}\n${endDateStr.toLocal().toString().substring(0, 16)}'; - } else if (indexEntity.keyType == XSConstantMacro.keyTypeLong) { - //永久 - // DateTime dateStr = DateTime.fromMillisecondsSinceEpoch(indexEntity.date!); - // useDateStr = '${dateStr.toLocal().toString().substring(0, 16)}\n 永久'; - useDateStr = '永久'; - } else if (indexEntity.keyType == XSConstantMacro.keyTypeOnce) { - //单次 - // DateTime dateStr = DateTime.fromMillisecondsSinceEpoch(indexEntity.date!); - // useDateStr = '${dateStr.toLocal().toString().substring(0, 16)}\n 单次'; - useDateStr = '单次'; - } else if (indexEntity.keyType == XSConstantMacro.keyTypeLoop) { - //循环 - useDateStr = '循环'; +//根据类型获取限时有效期样式 + Widget getPeriodValidityWidget() { + int? dateType = state.itemData.value.keyType; + if (dateType == XSConstantMacro.keyTypeLong) { + return getLongTypeDateWidget(); + } else if (dateType == XSConstantMacro.keyTypeTime) { + return getTimeLimitTypeDateWidget(); + } else if (dateType == XSConstantMacro.keyTypeOnce) { + return getOnceTypeDateWidget(); + } else if (dateType == XSConstantMacro.keyTypeLoop) { + return getLoopTypeDateWidget(); } - return useDateStr; + return Container(); + } + + //永久钥匙 + Widget getLongTypeDateWidget() { + return CommonItem( + leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, + rightTitle: '永久', + isHaveDirection: true, + action: () { + Navigator.pushNamed(context, Routers.electronicKeyDetailChangeDate, + arguments: {"itemData": state.itemData.value}); + }); + } + + //限时钥匙 + Widget getTimeLimitTypeDateWidget() { + DateTime startDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.startDate!); + DateTime endDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.endDate!); + String useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)}\n${endDateStr.toLocal().toString().substring(0, 16)}'; + + return CommonItem( + leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, + allHeight: 90.h, + rightTitle: useDateStr, + isHaveDirection: true, + action: () { + Navigator.pushNamed(context, Routers.electronicKeyDetailChangeDate, + arguments: {"itemData": state.itemData.value}); + }); + } + + //单次钥匙 + Widget getOnceTypeDateWidget() { + return CommonItem( + leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, + rightTitle: '单次', + isHaveDirection: false, + ); + } + + //循环钥匙 + Widget getLoopTypeDateWidget() { + DateTime startDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.startDate!); + DateTime endDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.endDate!); + String useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)} \n ${endDateStr.toLocal().toString().substring(0, 16)}'; + + List getEffectiveDateList = []; + List weekDaysList = state.itemData.value.weekDays!; + if (weekDaysList.isNotEmpty) { + String effectiveDateStr = ''; + for (int i = 0; i < weekDaysList.length; i++) { + if (weekDaysList[i] == 1) { + effectiveDateStr = '一'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 2) { + effectiveDateStr = '二'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 3) { + effectiveDateStr = '三'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 4) { + effectiveDateStr = '四'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 5) { + effectiveDateStr = '五'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 6) { + effectiveDateStr = '六'; + getEffectiveDateList.add(effectiveDateStr); + } else if (weekDaysList[i] == 7) { + effectiveDateStr = '日'; + getEffectiveDateList.add(effectiveDateStr); + } + } + } + + return Column( + children: [ + CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, + allHeight: 90.h, + rightTitle: useDateStr, + isHaveDirection: true, + isHaveLine: true, + action: () { + Navigator.pushNamed( + context, Routers.electronicKeyPeriodValidityPage); + }), + CommonItem( + leftTitel: '有效日', + rightTitle: getEffectiveDateList.map((e) => e.toString()).join(','), + isHaveDirection: true, + isHaveLine: true, + action: () { + Navigator.pushNamed( + context, Routers.electronicKeyPeriodValidityPage); + }), + ], + ); } //发送时间 String getSenderDate(ElectronicKeyListItem indexEntity) { String senderDate = ''; - DateTime dateStr = DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); + DateTime dateStr = + DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); senderDate = dateStr.toLocal().toString().substring(0, 16); return senderDate; } - // Widget commonItem(String leftTitle, String rightTitle, - // {bool isHaveDirection = false, - // bool isHaveLine = false, - // bool isHaveRightWidget = false, - // Widget? rightWidget, - // Function()? action}) { - // return GestureDetector( - // onTap: action, - // child: Column( - // // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Container( - // // height: 80.h, - // color: Colors.white, - // padding: EdgeInsets.only( - // left: 20.w, right: 10.w, top: 20.w, bottom: 20.w), - // child: Row( - // children: [ - // SizedBox(width: 20.w), - // Text( - // leftTitle, - // style: - // TextStyle(fontSize: 28.sp, fontWeight: FontWeight.w500), - // ), - // SizedBox(width: 20.w), - // Expanded( - // child: Row( - // mainAxisAlignment: MainAxisAlignment.end, - // children: [ - // isHaveRightWidget - // ? rightWidget! - // : Text( - // rightTitle, - // textAlign: TextAlign.end, - // style: TextStyle( - // fontSize: 28.sp, fontWeight: FontWeight.w500), - // ) - // ], - // ), - // ), - // SizedBox(width: 5.w), - // isHaveDirection - // ? Image.asset( - // 'images/icon_right.png', - // width: 50.w, - // height: 50.w, - // ) - // : SizedBox(width: 10.w), - // // SizedBox(width:10.w), - // ], - // ), - // ), - // isHaveLine - // ? Container( - // height: 0.5.h, - // color: Colors.grey, - // ) - // : Container() - // ], - // ), - // ); - // } - CupertinoSwitch _switch(isOn) { return CupertinoSwitch( activeColor: CupertinoColors.activeBlue, @@ -253,33 +267,6 @@ class _ElectronicKeyDetailPageState extends State { ); } - //修改钥匙名称请求 - Future modifyKeyNameRequest() async { - KeyOperationRecordEntity entity = await ApiRepository.to - .modifyKeyNameForAdmin( - itemData.keyId.toString(), _changeNameController.text, ''); - if (entity.errorCode!.codeIsSuccessful) { - print("修改要是名称成功啦啦啦啦啦"); - Toast.show(msg: "修改成功"); - setState(() { - Navigator.pop(context); - }); - } - } - - //删除电子钥匙名称请求 - Future deleteKeyRequest() async { - ElectronicKeyListEntity entity = - await ApiRepository.to.deleteElectronicKey(itemData.keyId.toString()); - if (entity.errorCode!.codeIsSuccessful) { - print("删除电子钥匙成功"); - Toast.show(msg: "删除成功"); - setState(() { - Navigator.pop(context, true); - }); - } - } - void showCupertinoAlertDialog(BuildContext context) { showDialog( context: context, @@ -288,11 +275,11 @@ class _ElectronicKeyDetailPageState extends State { title: "${TranslationLoader.lanKeys!.amend!.tr} ${TranslationLoader.lanKeys!.name!.tr}", tipTitle: "请输入", - controller: _changeNameController, + controller: state.changeNameController, sureClick: () { //发送编辑钥匙名称请求 - if (_changeNameController.text.isNotEmpty) { - modifyKeyNameRequest(); + if (state.changeNameController.text.isNotEmpty) { + logic.modifyKeyNameRequest(); } }, cancelClick: () { @@ -304,7 +291,7 @@ class _ElectronicKeyDetailPageState extends State { } void showIosTipViewDialog(BuildContext context) { - showDialog( + showDialog( context: context, builder: (BuildContext context) { return ShowIosTipView( @@ -312,14 +299,12 @@ class _ElectronicKeyDetailPageState extends State { tipTitle: "确定要删除吗?", sureClick: () { Get.back(); - deleteKeyRequest(); + logic.deleteKeyRequest(); }, cancelClick: () { Get.back(); }, ); - } - ); + }); } - } diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_state.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_state.dart new file mode 100644 index 00000000..98c7d383 --- /dev/null +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetail/electronicKeyDetail_state.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; + +class ElectronicKeyDetailState { + final itemData = ElectronicKeyListItem().obs; + final TextEditingController changeNameController = TextEditingController(); + + ElectronicKeyDetailState() { + Map map = Get.arguments; + itemData.value = map["itemData"]; + } +} diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_page.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_page.dart index a58df7b4..125126cf 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; @@ -8,6 +8,8 @@ import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../../app_settings/app_colors.dart'; @@ -36,7 +38,7 @@ class _ElectronicKeyDetailChangeDateState late List weekDays = []; late String pwdId = ''; late String lockId = ''; - late String fromType = '';// 1 从指纹详情进入 + late String fromType = ''; // 1 从指纹详情进入 @override Widget build(BuildContext context) { @@ -67,9 +69,8 @@ class _ElectronicKeyDetailChangeDateState style: TextStyle(color: Colors.white, fontSize: 24.sp), ), onPressed: () { - if(fromType == "1"){ - - }else{ + if (fromType == "1") { + } else { if (lockId.isNotEmpty && pwdId.isNotEmpty) { updatePwdRequest(); } else { @@ -158,7 +159,6 @@ class _ElectronicKeyDetailChangeDateState } } - String intToStr(int v) { return (v < 10) ? "0$v" : "$v"; } diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyList/electronicKeyList_page.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyList/electronicKeyList_page.dart index c779f6a4..8d14efb5 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyList/electronicKeyList_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyList/electronicKeyList_page.dart @@ -85,10 +85,11 @@ class _ElectronicKeyListPageState extends State { btnName: TranslationLoader.lanKeys!.sendKey!.tr, onClick: () { Navigator.pushNamed( - context, Routers.sendElectronicKeyManagePage, arguments: { - // "lockMainEntity": state.lockMainEntity.value, - "keyInfo": state.keyInfo.value - }).then((val) { + context, Routers.sendElectronicKeyManagePage, + arguments: { + // "lockMainEntity": state.lockMainEntity.value, + "keyInfo": state.keyInfo.value + }).then((val) { if (val != null) { logic.mockNetworkDataRequest(); setState(() {}); @@ -145,7 +146,7 @@ class _ElectronicKeyListPageState extends State { decoration: InputDecoration( //输入里面输入文字内边距设置 contentPadding: const EdgeInsets.only( - top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + top: 18.0, left: -19.0, right: -15.0, bottom: 2), hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), //不需要输入框下划线 @@ -161,6 +162,8 @@ class _ElectronicKeyListPageState extends State { ), ), ), + style: + TextStyle(fontSize: 22.sp, textBaseline: TextBaseline.alphabetic), ), ); } @@ -201,14 +204,14 @@ class _ElectronicKeyListPageState extends State { ), child: _electronicKeyItem('images/controls_user.png', indexEntity.keyName!, useDateStr, keyStatus, isAdminKey, () { - Navigator.pushNamed(context, Routers.electronicKeyDetailPage, - arguments: {"itemData": indexEntity}).then((val) { - if (val != null) { - logic.mockNetworkDataRequest(); - setState(() {}); - } - }); - }), + Navigator.pushNamed(context, Routers.electronicKeyDetailPage, + arguments: {"itemData": indexEntity}).then((val) { + if (val != null) { + logic.mockNetworkDataRequest(); + setState(() {}); + } + }); + }), ); } return const SizedBox.shrink(); @@ -267,6 +270,8 @@ class _ElectronicKeyListPageState extends State { //使用期限 String getUseDateStr(ElectronicKeyListItem indexEntity) { String useDateStr = ''; + DateTime sendDateStr = + DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); if (indexEntity.keyType == XSConstantMacro.keyTypeTime) { //限期 DateTime startDateStr = @@ -277,14 +282,11 @@ class _ElectronicKeyListPageState extends State { '${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}'; } else if (indexEntity.keyType == XSConstantMacro.keyTypeLong) { //永久 - // DateTime dateStr = DateTime.fromMillisecondsSinceEpoch(indexEntity.date!); - // useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 永久'; - useDateStr = "永久"; + useDateStr = '${sendDateStr.toLocal().toString().substring(0, 16)} 永久'; } else if (indexEntity.keyType == XSConstantMacro.keyTypeOnce) { //单次 - // DateTime dateStr = DateTime.fromMillisecondsSinceEpoch(indexEntity.date!); - // useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 单次'; useDateStr = "单次"; + useDateStr = '${sendDateStr.toLocal().toString().substring(0, 16)} 单次'; } else if (indexEntity.keyType == XSConstantMacro.keyTypeLoop) { //循环 useDateStr = '循环'; diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart new file mode 100644 index 00000000..858802a3 --- /dev/null +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart @@ -0,0 +1,7 @@ +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_state.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; + +class ElectronicKeyPeriodValidityLogic extends BaseGetXController { + final ElectronicKeyPeriodValidityState state = + ElectronicKeyPeriodValidityState(); +} diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_page.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_page.dart index 80666b96..6ff8ebac 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_page.dart @@ -1,10 +1,12 @@ import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/KeyPeriodValidityModel.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; +import 'package:star_lock/tools/toast.dart'; import '../../../../app_settings/app_colors.dart'; import '../../../../tools/commonItem.dart'; @@ -22,35 +24,22 @@ class ElectronicKeyPeriodValidityPage extends StatefulWidget { class _ElectronicKeyPeriodValidityPageState extends State { - List validityTextList = [ - TranslationLoader.lanKeys!.sundayShort!.tr, - TranslationLoader.lanKeys!.mondayShort!.tr, - TranslationLoader.lanKeys!.tuesdayShort!.tr, - TranslationLoader.lanKeys!.wednesdayShort!.tr, - TranslationLoader.lanKeys!.thursdayShort!.tr, - TranslationLoader.lanKeys!.fridayShort!.tr, - TranslationLoader.lanKeys!.saturdayShort!.tr - ]; - List validityDataList = []; //自定义数据块 - List selectIndexList = []; //选中的有效期数组 - String _selectEffectiveDate = ''; //生效时间 - String _selectFailureDate = ''; //失效时间 - late DateTime _effectiveDateTime; - late DateTime _failureDateTime; + final logic = Get.put(ElectronicKeyPeriodValidityLogic()); + final state = Get.find().state; @override void initState() { super.initState(); - for (var i = 0; i < validityTextList.length; i++) { + for (var i = 0; i < state.validityTextList.value.length; i++) { int validityValue = 0; if (i == 0) { validityValue = 7; } else { validityValue = i; } - KeyPeriodValidityModel model = - KeyPeriodValidityModel(validityTextList[i], i, false, validityValue); - validityDataList.add(model); + KeyPeriodValidityModel model = KeyPeriodValidityModel( + state.validityTextList.value[i], i, false, validityValue); + state.validityDataList.value.add(model); } } @@ -101,7 +90,8 @@ class _ElectronicKeyPeriodValidityPageState itemCount: 7, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { - KeyPeriodValidityModel model = validityDataList[index]; + KeyPeriodValidityModel model = + state.validityDataList.value[index]; return btnItem(model); })) ], @@ -110,112 +100,116 @@ class _ElectronicKeyPeriodValidityPageState } Widget btnItem(KeyPeriodValidityModel model) { - return GestureDetector( - onTap: () { - model.isValidity = !model.isValidity; - if (model.isValidity) { - selectIndexList.add(model.validityValue); - } else { - selectIndexList.remove(model.validityValue); - } - setState(() {}); - }, - child: Container( - width: 40.w, - height: 40.w, - margin: EdgeInsets.all(10.w), - decoration: BoxDecoration( - color: selectIndexList.contains(model.validityValue) - ? Colors.blue - : Colors.white, - border: Border.all(width: 1, color: AppColors.greyBackgroundColor), - borderRadius: BorderRadius.circular(30.w), - ), - child: Center( - child: Text( - model.validityText, - style: TextStyle( - fontSize: 20.sp, - color: selectIndexList.contains(model.validityValue) - ? Colors.white - : AppColors.darkGrayTextColor), - )), - ), - ); + return Obx(() => GestureDetector( + onTap: () { + model.isValidity = !model.isValidity; + if (model.isValidity) { + state.selectIndexList.value.add(model.validityValue); + } else { + state.selectIndexList.value.remove(model.validityValue); + } + setState(() {}); + }, + child: Container( + width: 40.w, + height: 40.w, + margin: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: state.selectIndexList.value.contains(model.validityValue) + ? Colors.blue + : Colors.white, + border: + Border.all(width: 1, color: AppColors.greyBackgroundColor), + borderRadius: BorderRadius.circular(30.w), + ), + child: Center( + child: Text( + model.validityText, + style: TextStyle( + fontSize: 20.sp, + color: + state.selectIndexList.value.contains(model.validityValue) + ? Colors.white + : AppColors.darkGrayTextColor), + )), + ), + )); } Widget bottomWidget() { return Column( children: [ - // CommonItem( - // leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, - // rightTitle: _effectiveTime, - // isHaveDirection: true, - // isHaveLine: true, - // action: () { - // Pickers.showDatePicker(context, mode: DateMode.HM, - // onConfirm: (p) { - // _effectiveTime = '${intToStr(p.hour!)}:${intToStr(p.minute!)}'; - - // setState(() {}); - // }); - // }), - // CommonItem( - // leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, - // rightTitle: _failureTime, - // isHaveDirection: true, - // action: () { - // Pickers.showDatePicker(context, mode: DateMode.HM, - // onConfirm: (p) { - // _failureTime = '${intToStr(p.hour!)}:${intToStr(p.minute!)}'; - - // setState(() {}); - // }); - // }), - // Container(height: 10.h), - CommonItem( + Obx(() => CommonItem( leftTitel: TranslationLoader.lanKeys!.effectiveDate!.tr, - rightTitle: _selectEffectiveDate, + rightTitle: state.selectEffectiveDate.value, isHaveDirection: true, isHaveLine: true, action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - _effectiveDateTime = DateTime.parse( + state.isHaveEffectiveDate.value = true; + state.effectiveDateTime.value = DateTime.parse( '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectEffectiveDate = formatDate(_effectiveDateTime, + state.selectEffectiveDate.value = formatDate( + state.effectiveDateTime.value, [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); - - setState(() {}); }); - }), - CommonItem( + })), + Obx(() => CommonItem( leftTitel: TranslationLoader.lanKeys!.failureDate!.tr, - rightTitle: _selectFailureDate, + rightTitle: state.selectFailureDate.value, isHaveDirection: true, action: () { Pickers.showDatePicker(context, mode: DateMode.YMDHM, onConfirm: (p) { - _failureDateTime = DateTime.parse( + state.isHaveFailureDate.value = true; + state.failureDateTime.value = DateTime.parse( '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectFailureDate = formatDate(_failureDateTime, + state.selectFailureDate.value = formatDate( + state.failureDateTime.value, [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); - setState(() {}); }); - }), + })), Container(height: 40.h), - SubmitBtn( + Obx(() => SubmitBtn( btnName: TranslationLoader.lanKeys!.sure!.tr, borderRadius: 20.w, margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w), padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + isDisabled: (state.selectIndexList.value.isNotEmpty && + state.isHaveEffectiveDate.value == true && + state.isHaveFailureDate.value == true) + ? true + : false, onClick: () { - Map resultMap = {}; - resultMap['validityValue'] = selectIndexList; - resultMap['starDate'] = _effectiveDateTime; - resultMap['endDate'] = _failureDateTime; - Navigator.pop(context, resultMap); - }), + if ((state.selectIndexList.value.isNotEmpty && + state.isHaveEffectiveDate.value == true && + state.isHaveFailureDate.value == true)) { + DateTime startDateTime = DateTime( + state.effectiveDateTime.value.year, + state.effectiveDateTime.value.month, + state.effectiveDateTime.value.day, + state.effectiveDateTime.value.hour, + state.effectiveDateTime.value.minute); + DateTime endDateTime = DateTime( + state.failureDateTime.value.year, + state.failureDateTime.value.month, + state.failureDateTime.value.day, + state.failureDateTime.value.hour, + state.failureDateTime.value.minute); + //时间判断 + if (!startDateTime.isBefore(endDateTime) || + startDateTime.isAtSameMomentAs(endDateTime)) { + Toast.show(msg: '失效时间需大于生效时间'); + } else { + Map resultMap = {}; + resultMap['validityValue'] = state.selectIndexList.value; + resultMap['starDate'] = state.effectiveDateTime.value; + resultMap['endDate'] = state.failureDateTime.value; + Navigator.pop(context, resultMap); + } + } + })), ], ); } diff --git a/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_state.dart b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_state.dart new file mode 100644 index 00000000..8e4027c6 --- /dev/null +++ b/star_lock/lib/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_state.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; +import 'package:star_lock/translations/trans_lib.dart'; + +import '../../../lockMian/entity/lockListInfo_entity.dart'; + +class ElectronicKeyPeriodValidityState { + TextEditingController searchController = TextEditingController(); //邮箱/手机号输入框 + final keyInfo = LockListInfoItemEntity().obs; + // final lockMainEntity = LockMainEntity().obs; + var pageNum = 1.obs; //请求页码 + final pageSize = 20.obs; //请求每页数据条数 + final itemDataList = [].obs; + + final validityTextList = [ + TranslationLoader.lanKeys!.sundayShort!.tr, + TranslationLoader.lanKeys!.mondayShort!.tr, + TranslationLoader.lanKeys!.tuesdayShort!.tr, + TranslationLoader.lanKeys!.wednesdayShort!.tr, + TranslationLoader.lanKeys!.thursdayShort!.tr, + TranslationLoader.lanKeys!.fridayShort!.tr, + TranslationLoader.lanKeys!.saturdayShort!.tr + ].obs; + final validityDataList = [].obs; //自定义数据块 + final selectIndexList = [].obs; //选中的有效期数组 + final selectEffectiveDate = ''.obs; //生效时间 + final selectFailureDate = ''.obs; //失效时间 + DateTime dateTime = DateTime.now(); + final effectiveDateTime = DateTime.now().obs; + final failureDateTime = DateTime.now().obs; + var isHaveEffectiveDate = false.obs; + var isHaveFailureDate = false.obs; +} diff --git a/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendElectronicKey_page.dart b/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendElectronicKey_page.dart index e2c8b141..c9a28952 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendElectronicKey_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendElectronicKey_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; @@ -9,6 +9,8 @@ import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserListEntity.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../../tools/commonItem.dart'; diff --git a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart index d77924e2..65e4e191 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart @@ -1,11 +1,11 @@ import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:get/get_utils/get_utils.dart'; import 'package:star_lock/appRouters.dart'; +import 'package:star_lock/app_settings/app_colors.dart'; +import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; -import 'package:star_lock/tools/toast.dart'; import 'package:star_lock/translations/trans_lib.dart'; class SendElectronicKeyLogic extends BaseGetXController { @@ -14,18 +14,38 @@ class SendElectronicKeyLogic extends BaseGetXController { //发送钥匙请求 Future sendElectronicKeyRequest(BuildContext widgetContext) async { String lockID = state.keyInfo.value.lockId.toString(); - String getKeyType = (int.parse(state.type.value) + 1).toString(); - if (state.type.value == '0') { - state.failureTimestamp.value = - state.failureDateTime.value.millisecondsSinceEpoch; - state.effectiveTimestamp.value = - state.effectiveDateTime.value.millisecondsSinceEpoch; + int typeValue = int.parse(state.type.value); + switch (typeValue) { + case 0: + { + typeValue = XSConstantMacro.keyTypeTime; + state.failureTimestamp.value = + state.failureDateTime.value.millisecondsSinceEpoch; + state.effectiveTimestamp.value = + state.effectiveDateTime.value.millisecondsSinceEpoch; + } + break; + case 1: + typeValue = XSConstantMacro.keyTypeLong; + break; + case 2: + typeValue = XSConstantMacro.keyTypeOnce; + break; + case 3: + typeValue = XSConstantMacro.keyTypeLoop; + break; + default: + typeValue = XSConstantMacro.keyTypeTime; + break; } + String getKeyType = typeValue.toString(); var entity = await ApiRepository.to.sendElectronicKey( - createUser: state.isCreateUser.value ? "1" : "0", + createUser: state.isCreateUser.value == true ? "1" : "0", countryCode: state.countryCode.value, - usernameType: '1', + usernameType: isPhoneNumber(state.emailOrPhoneController.text) == true + ? '1' + : '2', endDate: state.failureTimestamp.value.toString(), faceAuthentication: state.isAuthentication.value == true ? '1' : '2', isCameraEnable: '2', @@ -38,20 +58,37 @@ class SendElectronicKeyLogic extends BaseGetXController { receiverUsername: state.emailOrPhoneController.text, remarks: '', startDate: state.effectiveTimestamp.value.toString(), - weekDays: state.weekdaysList); + weekDays: state.weekdaysList.value); if (entity.errorCode!.codeIsSuccessful) { print('发送电子钥匙成功'); state.isSendSuccess.value = true; } else { if (entity.errorCode == 425) { //用户未注册 - _showDialog(widgetContext, '${entity.errorMsg}'); + if (isPhoneNumber(state.emailOrPhoneController.text) == true) { + _showPhoneDialog(widgetContext, '${entity.errorMsg}'); + } else { + _showEmailDialog(widgetContext); + } } } } + bool isPhoneNumber(String input) { + // 手机号正则表达式,这里简化为11位数字 + final RegExp phoneRegExp = RegExp(r'^\d{11}$'); + return phoneRegExp.hasMatch(input); + } + + bool isEmail(String input) { + // 邮箱正则表达式,这里简化为常见格式 + final RegExp emailRegExp = + RegExp(r'^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$'); + return emailRegExp.hasMatch(input); + } + //用户未注册确认弹窗 - void _showDialog(widgetContext, String errMsg) { + void _showPhoneDialog(widgetContext, String errMsg) { showCupertinoDialog( context: widgetContext, builder: (context) { @@ -59,13 +96,19 @@ class SendElectronicKeyLogic extends BaseGetXController { title: const Text('接收者号码未注册,请选择号码所在的国家并重新发送'), actions: [ CupertinoDialogAction( - child: Text(TranslationLoader.lanKeys!.cancel!.tr), + child: Text( + TranslationLoader.lanKeys!.cancel!.tr, + style: TextStyle(color: AppColors.mainColor), + ), onPressed: () { Navigator.of(context).pop(); }, ), CupertinoDialogAction( - child: Text(TranslationLoader.lanKeys!.selet!.tr), + child: Text( + TranslationLoader.lanKeys!.selet!.tr, + style: TextStyle(color: AppColors.mainColor), + ), onPressed: () async { //选择国家代码 state.isCreateUser.value = true; @@ -84,4 +127,39 @@ class SendElectronicKeyLogic extends BaseGetXController { }, ); } + + //用户未注册确认弹窗---邮箱 + void _showEmailDialog(widgetContext) { + showCupertinoDialog( + context: widgetContext, + builder: (context) { + return CupertinoAlertDialog( + title: Text('是否发送电子钥匙给未注册账号\n${state.emailOrPhoneController.text}'), + actions: [ + CupertinoDialogAction( + child: Text( + TranslationLoader.lanKeys!.cancel!.tr, + style: TextStyle(color: AppColors.mainColor), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + CupertinoDialogAction( + child: Text( + TranslationLoader.lanKeys!.sure!.tr, + style: TextStyle(color: AppColors.mainColor), + ), + onPressed: () { + state.isCreateUser.value = true; + Navigator.of(context).pop(); + + sendElectronicKeyRequest(widgetContext); + }, + ), + ], + ); + }, + ); + } } diff --git a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_page.dart b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_page.dart index 83805758..442f4485 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_page.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_page.dart @@ -1,8 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_colors.dart'; @@ -10,6 +8,8 @@ import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/toast.dart'; @@ -31,10 +31,17 @@ class _SendElectronicKeyPageState extends State { final logic = Get.put(SendElectronicKeyLogic()); final state = Get.find().state; static const methodChannel = MethodChannel('talkPlugin'); + bool isDemoMode = false; @override - void initState() { + initState() { super.initState(); + + getDemoMode(); + } + + Future getDemoMode() async { + isDemoMode = (await Storage.getBool(ifIsDemoModeOrNot))!; } @override @@ -217,11 +224,9 @@ class _SendElectronicKeyPageState extends State { children: [ Obx(() => CommonItem( leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, - rightTitle: state.weekdaysList.isEmpty + rightTitle: state.weekdaysList.value.isEmpty ? '' - : state.weekdaysList - .reduce((value, element) => value + ',' + element) - .toString(), + : state.weekdaysList.value.join(','), isHaveDirection: true, action: () async { var result = await Navigator.pushNamed( @@ -262,21 +267,29 @@ class _SendElectronicKeyPageState extends State { ), SubmitBtn( btnName: TranslationLoader.lanKeys!.send!.tr, - onClick: () async { - // 获取是否是演示模式 演示模式不获取接口 - var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + onClick: () { if (isDemoMode == false) { + DateTime startDateTime = DateTime( + state.effectiveDateTime.value.year, + state.effectiveDateTime.value.month, + state.effectiveDateTime.value.day, + state.effectiveDateTime.value.hour, + state.effectiveDateTime.value.minute); + DateTime endDateTime = DateTime( + state.failureDateTime.value.year, + state.failureDateTime.value.month, + state.failureDateTime.value.day, + state.failureDateTime.value.hour, + state.failureDateTime.value.minute); //发送钥匙请求 if (state.emailOrPhoneController.text.isNotEmpty && state.keyNameController.text.isNotEmpty) { if (int.parse(widget.type) == 0) { - //失效时间大于生效时间 - if (state.failureDateTime.value - .compareTo(state.effectiveDateTime.value) == - 1) { - logic.sendElectronicKeyRequest(context); - } else { + if (!startDateTime.isBefore(endDateTime) || + startDateTime.isAtSameMomentAs(endDateTime)) { Toast.show(msg: '失效时间需大于生效时间'); + } else { + logic.sendElectronicKeyRequest(context); } } else { logic.sendElectronicKeyRequest(context); @@ -285,6 +298,7 @@ class _SendElectronicKeyPageState extends State { Toast.show(msg: '请完善信息'); } } else { + //演示模式不获取接口 Toast.show(msg: '演示模式'); } }), @@ -295,9 +309,8 @@ class _SendElectronicKeyPageState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( - onPressed: () async { + onPressed: () { // 获取是否是演示模式 演示模式不获取接口 - var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); if (isDemoMode == false) { Navigator.pushNamed( context, Routers.massSendElectronicKeyManagePage); @@ -406,9 +419,9 @@ class _SendElectronicKeyPageState extends State { var entity = await ApiRepository.to.setRoomStatusData( lockId: state.keyInfo.value.lockId!, - roomStatus:1, + roomStatus: 1, ); - if(entity.errorCode!.codeIsSuccessful){ + if (entity.errorCode!.codeIsSuccessful) { print("标记为已入住成功啦啦啦啦啦"); Toast.show(msg: "标记成功"); setState(() {}); @@ -440,6 +453,8 @@ class _SendElectronicKeyPageState extends State { //不需要输入框下划线 border: InputBorder.none, ), + style: TextStyle( + fontSize: 22.sp, textBaseline: TextBaseline.alphabetic), ), ), SizedBox( diff --git a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart index 7b2c10ed..ffd62849 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart @@ -12,7 +12,6 @@ class SendElectronicKeyState { final FlutterContactPicker contactPicker = FlutterContactPicker(); late Contact contact; final keyInfo = LockListInfoItemEntity().obs; - // final lockMainEntity = LockMainEntity().obs; final isRemoteUnlock = false.obs; //是否允许远程开锁 final isAuthentication = false.obs; //是否可以实名认证 @@ -38,7 +37,6 @@ class SendElectronicKeyState { SendElectronicKeyState() { Map map = Get.arguments; - // lockMainEntity.value = map["lockMainEntity"]; keyInfo.value = map["keyInfo"]; } } diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFace/addFace_page.dart b/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart similarity index 88% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFace/addFace_page.dart rename to star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart index 4bee1fa4..a544881b 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/addFace/addFace_page.dart +++ b/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart @@ -7,6 +7,7 @@ import '../../../../../app_settings/app_colors.dart'; import '../../../../../tools/submitBtn.dart'; import '../../../../../tools/titleAppBar.dart'; import '../../../../../translations/trans_lib.dart'; +import '../../../../tools/toast.dart'; class AddFaceTipPage extends StatefulWidget { const AddFaceTipPage({Key? key}) : super(key: key); @@ -21,7 +22,7 @@ class _AddFaceTipPageState extends State { return Scaffold( backgroundColor: Colors.white, appBar: TitleAppBar( - barTitle: TranslationLoader.lanKeys!.addLock!.tr, + barTitle: "${TranslationLoader.lanKeys!.addTip!.tr}${TranslationLoader.lanKeys!.face!.tr}", haveBack: true, backgroundColor: AppColors.mainColor), body: ListView( @@ -66,7 +67,9 @@ class _AddFaceTipPageState extends State { child: SubmitBtn( btnName: "开始添加", //TranslationLoader.lanKeys!.next!.tr, borderRadius: 20.w, - onClick: () {}), + onClick: () { + Toast.show(msg: "请确保在设备附近,设备未被连接,设备已打开"); + }), ), ], ), diff --git a/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_page.dart b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_page.dart new file mode 100644 index 00000000..91ea41a4 --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_page.dart @@ -0,0 +1,38 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; +import 'addFaceTypeManage_tabbar.dart'; + +class AddFaceTypeManagePage extends StatefulWidget { + const AddFaceTypeManagePage({Key? key}) : super(key: key); + + @override + State createState() => _AddFaceTypeManagePageState(); +} + +class _AddFaceTypeManagePageState extends State { + var index = 0; + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: + "${TranslationLoader.lanKeys!.addTip!.tr}${TranslationLoader.lanKeys!.face!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: Column( + children: [ + AddFaceTypeManageTabbar(initialIndex: index), + ], + ), + ); + } + +} diff --git a/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_tabbar.dart b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_tabbar.dart new file mode 100644 index 00000000..5fea8222 --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceTypeManage/addFaceTypeManage_tabbar.dart @@ -0,0 +1,98 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/CustomUnderlineTabIndicator.dart'; +import '../../../../../translations/trans_lib.dart'; +import '../addFaceType_page.dart'; + +class AddFaceTypeManageTabbar extends StatefulWidget { + var initialIndex = 1; + + AddFaceTypeManageTabbar({Key? key, required this.initialIndex}) : super(key: key); + + @override + State createState() => _AddFaceTypeManageTabbarState(); +} + +class _AddFaceTypeManageTabbarState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + + final List _itemTabs = [ + ItemView(title: TranslationLoader.lanKeys!.permanent!.tr, seletType: "0"), + ItemView(title: TranslationLoader.lanKeys!.timeLimit!.tr, seletType: "1"), + ItemView(title: TranslationLoader.lanKeys!.circulation!.tr, seletType: "2"), + ]; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _tabController = TabController( + vsync: this, + length: _itemTabs.length, + initialIndex: widget.initialIndex); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Column( + children: [ + _tabBar(), + _pageWidget(), + ], + )); + } + + TabBar _tabBar() { + return TabBar( + controller: _tabController, + tabs: _itemTabs.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: _itemTabs + .map((ItemView item) => AddFaceTypePage(seletType: item.seletType,)) + .toList(), + ), + ); + } +} + +class ItemView { + const ItemView({required this.title, required this.seletType}); + + final String title; + final String seletType; +} diff --git a/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_logic.dart b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_logic.dart new file mode 100644 index 00000000..cb0d1ffd --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_logic.dart @@ -0,0 +1,8 @@ + +import 'package:star_lock/tools/baseGetXController.dart'; +import 'addFaceType_state.dart'; + +class AddFaceTypeLogic extends BaseGetXController{ + AddFaceTypeState state = AddFaceTypeState(); + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_page.dart b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_page.dart new file mode 100644 index 00000000..1ea3ef6e --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_page.dart @@ -0,0 +1,314 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.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 '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'addFaceType_logic.dart'; + +class AddFaceTypePage extends StatefulWidget { + final String seletType; + + const AddFaceTypePage({Key? key, required this.seletType}) : super(key: key); + + @override + State createState() => _AddFaceTypePageState(); +} + +class _AddFaceTypePageState extends State { + final logic = Get.put(AddFaceTypeLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return indexChangeWidget(); + } + + Widget indexChangeWidget() { + switch (int.parse(widget.seletType)) { + 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(), + SizedBox(height: 10.h), + 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) { + setState(() { + setState(() { + 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) { + setState(() { + setState(() { + 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())), + SizedBox(height: 30.h), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.next!.tr, + onClick: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // print("state.seletType:${state.seletType.value}"); + if (state.nameController.text.isEmpty) { + Toast.show(msg: "请输入姓名"); + return; + } + + Get.toNamed(Routers.addFaceTipPage); + } else { + // Get.toNamed(Routers.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }), + ], + ); + } + + // 发送电子钥匙成功 + 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, + ), + ], + ), + ); + } + + //isStressFingerprint false:不是胁迫指纹 ture:胁迫指纹 + CupertinoSwitch _isStressFingerprint() { + return CupertinoSwitch( + activeColor: CupertinoColors.activeBlue, + trackColor: CupertinoColors.systemGrey5, + thumbColor: CupertinoColors.white, + value: true, + onChanged: (value) { + setState(() { + // state.isStressFingerprint.value = value; + }); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_state.dart b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_state.dart new file mode 100644 index 00000000..ea1ddc6c --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/addFaceType/addFaceType_state.dart @@ -0,0 +1,16 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class AddFaceTypeState{ + 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(); +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/face/faceDetail/faceDetail_page.dart b/star_lock/lib/main/lockDetail/face/faceDetail/faceDetail_page.dart new file mode 100644 index 00000000..e69de29b diff --git a/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart b/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart new file mode 100644 index 00000000..00cff678 --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart @@ -0,0 +1,8 @@ + +import 'package:star_lock/tools/baseGetXController.dart'; +import 'faceList_state.dart'; + +class FaceListLogic extends BaseGetXController{ + FaceListState state = FaceListState(); + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart b/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart new file mode 100644 index 00000000..65116205 --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/faceList/faceList_page.dart @@ -0,0 +1,252 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.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 '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'faceList_logic.dart'; + +class FaceList extends StatefulWidget { + const FaceList({Key? key}) : super(key: key); + + @override + State createState() => _FaceListState(); +} + +class _FaceListState extends State { + final logic = Get.put(FaceListLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: TranslationLoader.lanKeys!.face!.tr, + 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.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }, + ), + ], + ), + body: Column( + children: [ + _searchWidget(), + SizedBox( + height: 20.h, + ), + Expanded(child: _buildMainUI()), + AddBottomWhiteBtn( + btnName: + '${TranslationLoader.lanKeys!.add!.tr}${TranslationLoader.lanKeys!.face!.tr}', + onClick: () async { + var data = + await Get.toNamed(Routers.addFaceTypeManagePage); + if (data != null) { + // 遥控添加 + + } + }, + ), + SizedBox( + height: 64.h, + ) + ], + ), + ); + } + + Widget _searchWidget() { + return Container( + height: 60.h, + margin: EdgeInsets.only(top: 20.w, left: 20.w, right: 10.w), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: TextField( + //输入框一行 + maxLines: 1, + controller: state.searchController, + autofocus: false, + onChanged: (value) { + print("onChanged:$value"); + }, + onEditingComplete: () { + print("onEditingComplete:"); + }, + onSubmitted: (value) { + // 调用遥控列表 + + }, + decoration: InputDecoration( + //输入里面输入文字内边距设置 + contentPadding: const EdgeInsets.only( + top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, + hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), + //不需要输入框下划线 + border: InputBorder.none, + //左边图标设置 + icon: Padding( + padding: EdgeInsets.only( + top: 20.h, bottom: 20.h, right: 20.w, left: 10.w), + child: Image.asset( + 'images/main/icon_main_search.png', + width: 40.w, + height: 40.w, + ), + ), + ), + ), + ); + } + + Widget _buildMainUI() { + String typeImgName = 'images/icon_card.png'; + + return const NoData(); + } + + Widget _buildDeleteBtn(String idStr) { + return GestureDetector( + onTap: () { + // 省略: 弹出是否删除的确认对话框。 + showIosTipViewDialog(context, idStr); + }, + 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, String keyId) { + showDialog( + context: context, + builder: (BuildContext context) { + return ShowIosTipView( + title: "提示", + tipTitle: "确定要删除吗?", + sureClick: () async { + // 遥控删除 + + }, + cancelClick: () { + Get.back(); + }, + ); + }, + ); + } + + Widget _keyItem(String lockTypeIcon, String lockTypeTitle, 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.start, + children: [ + Text(lockTypeTitle, + style: TextStyle( + fontSize: 24.sp, color: AppColors.blackColor)), + ], + ), + SizedBox(height: 5.h), + Container( + child: 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: () { + // 遥控重置 + + }, + ), + ], + ); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/face/faceList/faceList_state.dart b/star_lock/lib/main/lockDetail/face/faceList/faceList_state.dart new file mode 100644 index 00000000..be495903 --- /dev/null +++ b/star_lock/lib/main/lockDetail/face/faceList/faceList_state.dart @@ -0,0 +1,6 @@ + +import 'package:flutter/material.dart'; + +class FaceListState{ + final TextEditingController searchController = TextEditingController(); +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_entity.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_entity.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_entity.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_entity.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart similarity index 80% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_logic.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart index 7a753bf1..486589e2 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_logic.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart @@ -51,11 +51,6 @@ class AddFingerprintLogic extends BaseGetXController { } Future _replyAddFingerprintBegin(Reply reply) async { - // var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyAddFingerprintReplyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("status:$status"); @@ -64,7 +59,7 @@ class AddFingerprintLogic extends BaseGetXController { //成功 print("${reply.commandType!.typeValue} 数据解析成功"); state.ifConnectScuess.value = true; - state.fingerprintNumber.value = reply.data.last.toString(); + // state.fingerprintNumber.value = reply.data.last.toString(); break; case 0x06: //无权限 @@ -75,20 +70,24 @@ class AddFingerprintLogic extends BaseGetXController { var publicKey = await Storage.getStringList(saveBluePublicKey); List publicKeyDataList = changeStringListToIntList(publicKey!); - var token = await Storage.getStringList(saveBlueToken); - List getTokenList = changeStringListToIntList(token!); + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + print("_replyAddFingerprintReplyToken:$token"); + Storage.setStringList(saveBlueToken, saveStrList); IoSenderManage.senderAddFingerprintCommand( keyID:"1", userID:await Storage.getUid(), fingerNo:1, useCountLimit:0xff, - startTime:0x11223344, - endTime:0x11223344, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, - token: getTokenList, + token: token, ); break; case 0x07: @@ -110,11 +109,6 @@ class AddFingerprintLogic extends BaseGetXController { } Future _replyAddFingerprintProcess(Reply reply) async { - var token = reply.data.sublist(2, 6); - var saveStrList = changeIntListToStringList(token); - print("_replyAddFingerprintReplyToken:$token"); - Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("33 status:$status"); @@ -155,11 +149,6 @@ class AddFingerprintLogic extends BaseGetXController { } Future _replyAddFingerprintConfirmation(Reply reply) async { - // var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyAddFingerprintReplyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("status:$status"); @@ -168,7 +157,7 @@ class AddFingerprintLogic extends BaseGetXController { //成功 print("${reply.commandType!.typeValue} 数据解析成功"); // print("添加指纹确认成功,调用添加指纹接口"); - if(state.isCoerced.value == "2"){ + if(state.isCoerced.value == "1"){ // 非胁迫指纹 addFingerprintsData(reply.data[6].toString()); }else{ @@ -199,11 +188,6 @@ class AddFingerprintLogic extends BaseGetXController { } Future _replyAddStressFingerprint(Reply reply) async { - // var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyAddFingerprintReplyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; print("status:$status"); @@ -217,6 +201,36 @@ class AddFingerprintLogic extends BaseGetXController { case 0x06: //需要权限 + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + var signKey = await Storage.getStringList(saveBlueSignKey); + List getSignKeyList = changeStringListToIntList(signKey!); + + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + print("_replyAddFingerprintReplyToken:$token"); + Storage.setStringList(saveBlueToken, saveStrList); + + IoSenderManage.senderAddStressFingerprintCommand( + keyID:"1", + userID:await Storage.getUid(), + fingerNo:1, + fingerType:1, + useCountLimit:1, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: token, + signKey: getSignKeyList + ); break; case 0x07: //无权限 @@ -255,10 +269,10 @@ class AddFingerprintLogic extends BaseGetXController { userID:await Storage.getUid(), fingerNo:1, useCountLimit:0xff, - startTime:0x11223344, - endTime:0x11223344, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, @@ -278,23 +292,28 @@ class AddFingerprintLogic extends BaseGetXController { var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); + var signKey = await Storage.getStringList(saveBlueSignKey); + List getSignKeyList = changeStringListToIntList(signKey!); + var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); - print("openDoorTokenPubToken:$getTokenList"); + print("StressFingerprintToken:$getTokenList"); IoSenderManage.senderAddStressFingerprintCommand( keyID:"1", userID:await Storage.getUid(), fingerNo:1, + fingerType:1, useCountLimit:1, - startTime:0x11223344, - endTime:0x11223344, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, + // startTime:0x11223344, + // endTime:0x11223344, + startTime:int.parse(state.startDate.value)~/1000, + endTime:int.parse(state.endDate.value)~/1000, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, token: getTokenList, + signKey: getSignKeyList ); } }); @@ -307,14 +326,14 @@ class AddFingerprintLogic extends BaseGetXController { endDate: state.endDate.value, addType:state.addType.value, fingerprintName: state.fingerprintName.value, - fingerprintNumber: "123456", + fingerprintNumber: fingerprintUserNo, fingerprintType: state.fingerprintType.value, isCoerced: state.isCoerced.value, startDate: state.startDate.value, weekDay: state.weekDay.value, ); if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "添加成功"); + // Toast.show(msg: "添加成功"); updateFingerprintUserNoLoadData(entity.data!.fingerprintId.toString(), fingerprintUserNo); } } diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_page.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart similarity index 97% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_page.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart index 939be283..9a3a84f7 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_page.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart @@ -26,7 +26,7 @@ class _AddFingerprintPageState extends State { return Scaffold( backgroundColor: Colors.white, appBar: TitleAppBar( - barTitle: TranslationLoader.lanKeys!.addLock!.tr, + barTitle: "${TranslationLoader.lanKeys!.addTip!.tr}${TranslationLoader.lanKeys!.fingerprint!.tr}", haveBack: true, backgroundColor: AppColors.mainColor), body: ListView( diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_state.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart similarity index 83% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_state.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart index b64e3e69..86f4ce26 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_state.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart @@ -8,7 +8,7 @@ class AddFingerprintState{ final endDate = "".obs; final addType = "".obs; final fingerprintName = "".obs; - final fingerprintNumber = "".obs; + // final fingerprintNumber = "".obs; final fingerprintType = "".obs; final isCoerced = "".obs; final startDate = "".obs; @@ -21,9 +21,10 @@ class AddFingerprintState{ endDate.value = map["endDate"]; addType.value = map["addType"]; fingerprintName.value = map["fingerprintName"]; - fingerprintNumber.value = map["fingerprintNumber"]; + // fingerprintNumber.value = map["fingerprintNumber"]; fingerprintType.value = map["fingerprintType"]; isCoerced.value = map["isCoerced"]; + print("isCoerced.valueisCoerced.value:${isCoerced.value}"); startDate.value = map["startDate"]; lockId.value = map["lockId"]; weekDay.value = map["weekDay"]; diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_page.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_page.dart new file mode 100644 index 00000000..c9578bab --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_page.dart @@ -0,0 +1,45 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; +import 'addFingerprintTypeManage_tabbar.dart'; + +class AddFingerprintTypeManagePage extends StatefulWidget { + const AddFingerprintTypeManagePage({Key? key}) : super(key: key); + + @override + State createState() => _AddFingerprintTypeManagePageState(); +} + +class _AddFingerprintTypeManagePageState extends State { + var index = 0; + + @override + Widget build(BuildContext context) { + Map map = Get.arguments; + var lockId = map["lockId"]; + var fromType = map["fromType"]; // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + var fromTypeTwoStaffName = ""; + if(fromType == 2){ + fromTypeTwoStaffName = map["fromTypeTwoStaffName"]; // 从添加员工进入 传入员工名字 + } + + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: + "${TranslationLoader.lanKeys!.addTip!.tr}${TranslationLoader.lanKeys!.fingerprint!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: Column( + children: [ + AddFingerprintTypeManageTabbar(initialIndex: index, lockId: lockId, fromType: fromType, fromTypeTwoStaffName:fromTypeTwoStaffName), + ], + ), + ); + } +} + diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_tabbar.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_tabbar.dart new file mode 100644 index 00000000..27b19a38 --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintManage/addFingerprintTypeManage_tabbar.dart @@ -0,0 +1,108 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/CustomUnderlineTabIndicator.dart'; +import '../../../../../translations/trans_lib.dart'; +import '../addFingerprintType_page.dart'; + +class AddFingerprintTypeManageTabbar extends StatefulWidget { + var initialIndex = 1; + var lockId = 0; + var fromType = 0; // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + var fromTypeTwoStaffName = "";// 从添加员工进入 传入员工名字 + + AddFingerprintTypeManageTabbar( + {Key? key, required this.initialIndex, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) : super(key: key); + + @override + State createState() => _AddFingerprintTypeManageTabbarState(); +} + +class _AddFingerprintTypeManageTabbarState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + + final List _itemTabs = [ + ItemView(title: TranslationLoader.lanKeys!.permanent!.tr, seletType: "0"), + ItemView(title: TranslationLoader.lanKeys!.timeLimit!.tr, seletType: "1"), + ItemView(title: TranslationLoader.lanKeys!.circulation!.tr, seletType: "2"), + ]; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _tabController = TabController( + vsync: this, + length: _itemTabs.length, + initialIndex: widget.initialIndex); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Column( + children: [ + _tabBar(), + _pageWidget(), + ], + )); + } + + TabBar _tabBar() { + return TabBar( + controller: _tabController, + tabs: _itemTabs.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: _itemTabs + .map((ItemView item) => AddFingerprintTypePage( + seletType: item.seletType, + lockId: widget.lockId, + fromType: widget.fromType, + fromTypeTwoStaffName:widget.fromTypeTwoStaffName + )) + .toList(), + ), + ); + } +} + +class ItemView { + const ItemView({required this.title, required this.seletType}); + + final String title; + final String seletType; +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_logic.dart new file mode 100644 index 00000000..f2d16f53 --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_logic.dart @@ -0,0 +1,90 @@ + +import 'package:get/get.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import '../../../../appRouters.dart'; +import '../../../../tools/toast.dart'; +import 'addFingerprintType_state.dart'; + +class AddFingerprintTypeLogic extends BaseGetXController{ + AddFingerprintState state = AddFingerprintState(); + + // 添加指纹 + void addFingerprintsData() async { + var fingerprintType = 0; // 永久:1;限时2,单次3,循环:4 + var startDate = ""; + var endDate = ""; + if (state.seletType.value == "0") { + fingerprintType = 1; + startDate = "0"; + endDate = "0"; + } else if (state.seletType.value == "1") { + fingerprintType = 2; + if (state.beginTimeTimestamp.value.isEmpty) { + Toast.show(msg: "请选择开始时间"); + return; + } + if (state.endTimeTimestamp.value.isEmpty) { + Toast.show(msg: "请选择开始时间"); + 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)) { + Toast.show(msg: "失效时间要大于生效时间"); + return; + } + + startDate = state.beginTimeTimestamp.value; + endDate = state.endTimeTimestamp.value; + } else if (state.seletType.value == "2") { + if (state.effectiveDateTime.value <= 0) { + Toast.show(msg: "请选择生效时间"); + return; + } + if (state.failureDateTime.value <= 0) { + Toast.show(msg: "请选择失效时间"); + return; + } + + if (state.weekdaysList.value.isEmpty) { + Toast.show(msg: "请选择有效日"); + return; + } + + // if(DateTime.now().millisecondsSinceEpoch >= state.effectiveDateTime.value){ + // Toast.show(msg: "生效时间要大于当前时间"); + // return; + // } + + if (state.effectiveDateTime.value >= state.failureDateTime.value) { + Toast.show(msg: "失效时间要大于生效时间"); + return; + } + startDate = state.effectiveDateTime.value.toString(); + endDate = state.failureDateTime.value.toString(); + fingerprintType = 4; + } + + var isCoerced = state.isStressFingerprint.value == false ? "1" : "2"; // 1:非胁迫指纹 2:胁迫指纹 + print("addOtherType startDate:$startDate endDate:$endDate isCoerced:$isCoerced"); + // 指纹 + Get.toNamed(Routers.addFingerprintPage, arguments: { + "lockId": state.lockId.value, + "endDate": endDate, + "addType": "1", + "fingerprintName": state.nameController.text, + "fingerprintNumber": "123456", + "fingerprintType": fingerprintType.toString(), + "isCoerced": isCoerced, // 1:非胁迫指纹 2:胁迫指纹 + "startDate": startDate, + "weekDay": state.weekdaysList.value, + "fromType": state.fromType.value, + }); + } + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_page.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_page.dart new file mode 100644 index 00000000..2dd6c869 --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_page.dart @@ -0,0 +1,330 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.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 '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'addFingerprintType_logic.dart'; + +class AddFingerprintTypePage extends StatefulWidget { + final String seletType; // 永久限时循环下标 + final int lockId; + final int fromType; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + final String fromTypeTwoStaffName; // 从添加员工进入 传入员工名字 + + const AddFingerprintTypePage( + {Key? key, + required this.seletType, + required this.lockId, + required this.fromType, + required this.fromTypeTwoStaffName}) + : super(key: key); + + @override + State createState() => _AddFingerprintTypePageState(); +} + +class _AddFingerprintTypePageState extends State { + final logic = Get.put(AddFingerprintTypeLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + state.seletType.value = widget.seletType; + state.lockId.value = widget.lockId; + // state.nameController.text = widget.fromTypeTwoStaffName; + + WidgetsBinding.instance.addPostFrameCallback((_) { + // Your code here + }); + return indexChangeWidget(); + } + + Widget indexChangeWidget() { + switch (int.parse(widget.seletType)) { + 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(), + SizedBox(height: 10.h), + 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) { + setState(() { + setState(() { + 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) { + setState(() { + setState(() { + 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!.stressFingerprint!.tr, + rightTitle: "", + isTipsImg: false, + isHaveRightWidget: true, + rightWidget: SizedBox( + width: 60.w, height: 50.h, child: _isStressFingerprint())), + SizedBox(height: 30.h), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.next!.tr, + onClick: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // print("state.seletType:${state.seletType.value}"); + if (state.nameController.text.isEmpty) { + Toast.show(msg: "请输入姓名"); + return; + } + + logic.addFingerprintsData(); + } else { + // Get.toNamed(Routers.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }), + ], + ); + } + + // 发送电子钥匙成功 + 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, + ), + ], + ), + ); + } + + //isStressFingerprint false:不是胁迫指纹 ture:胁迫指纹 + CupertinoSwitch _isStressFingerprint() { + return CupertinoSwitch( + activeColor: CupertinoColors.activeBlue, + trackColor: CupertinoColors.systemGrey5, + thumbColor: CupertinoColors.white, + value: state.isStressFingerprint.value, + onChanged: (value) { + setState(() { + state.isStressFingerprint.value = value; + }); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_state.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_state.dart new file mode 100644 index 00000000..18e3573f --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintSeletType/addFingerprintType_state.dart @@ -0,0 +1,26 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class AddFingerprintState{ + final lockId = 0.obs; + final seletType = "0".obs;// 0永久 1显示 2循环 + final fromType = 1.obs; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + final isStressFingerprint = 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(); + AddFingerprintState() { + // Map map = Get.arguments; + // lockId.value = map["lockId"]; + // fromType.value = map["fromType"]; + } +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_logic.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_logic.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_logic.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_page.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_page.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_page.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_page.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_state.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_state.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/addFingerprint/addFingerprintTip/addFingerprintTip_state.dart rename to star_lock/lib/main/lockDetail/fingerprint/addFingerprintTip/addFingerprintTip_state.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_logic.dart similarity index 66% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_logic.dart rename to star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_logic.dart index a6e46e1e..8aa48c07 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_logic.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_logic.dart @@ -1,52 +1,47 @@ - import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:get/get.dart'; import 'package:star_lock/blue/io_type.dart'; import 'package:star_lock/tools/baseGetXController.dart'; - import '../../../../blue/blue_manage.dart'; import '../../../../blue/io_protocol/io_addFingerprint.dart'; import '../../../../blue/io_reply.dart'; -import '../../../../blue/io_tool/io_manager.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'; import '../../../../tools/toast.dart'; -import 'otherTypeKeyDetail_state.dart'; +import 'fingerprintDetail_state.dart'; -class OtherTypeKeyDetailLogic extends BaseGetXController{ - OtherTypeKeyDetailState state = OtherTypeKeyDetailState(); +class FingerprintDetailLogic extends BaseGetXController{ + FingerprintDetailState state = FingerprintDetailState(); - // 监听设备返回的数据 + // 获取解析后的数据 late StreamSubscription _replySubscription; void _initReplySubscription() { - _replySubscription = EventBusManager().eventBus!.on().listen((reply) async { - // 添加指纹开始(删除单个指纹) - if(reply is SenderAddFingerprintReply) { + _replySubscription = EventBusManager().eventBus!.on().listen((reply) { + // 添加指纹开始(此处用作删除指纹) + if((reply is SenderAddFingerprintReply)) { _replyAddFingerprintBegin(reply); } }); } + // 添加指纹开始 Future _replyAddFingerprintBegin(Reply reply) async { - // var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyAddFingerprintReplyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); int status = reply.data[2]; print("status:$status"); switch(status){ case 0x00: - //成功 + //成功 print("${reply.commandType!.typeValue} 数据解析成功"); - + deletFingerprintsData(); break; case 0x06: //无权限 @@ -60,15 +55,14 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); + String? userID = await Storage.getUid(); IoSenderManage.senderAddFingerprintCommand( - keyID:"1", - userID:await Storage.getUid(), - fingerNo:1, + keyID:state.keyId.value.toString(), + userID:userID, + fingerNo:int.parse(state.typeNumber.value), useCountLimit:0, - startTime:0x11223344, - endTime:0x11223344, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, + startTime:state.effectiveDateTime.value, + endTime:state.failureDateTime.value, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, @@ -93,23 +87,6 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ } } - // 编辑指纹 - void editFingerprintsData() async{ - var entity = await ApiRepository.to.editFingerprintsData( - fingerprintId: state.keyId.value.toString(), - lockId: state.fingerprintItemData.value.lockId.toString(), - weekDay: state.weekDay.value, - startDate: state.effectiveDateTime.value.toString(), - endDate: state.failureDateTime.value.toString(), - isCoerced: state.isStressFingerprint.value ? "2" : "1", - fingerprintName: state.changeNameController.text, - ); - if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "修改成功"); - Get.back(result: "addScuess"); - } - } - // 删除指纹 Future senderAddFingerprint() async { BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { @@ -123,15 +100,15 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ var token = await Storage.getStringList(saveBlueToken); List getTokenList = changeStringListToIntList(token!); + String? userID = await Storage.getUid(); + IoSenderManage.senderAddFingerprintCommand( - keyID:"1", - userID:await Storage.getUid(), - fingerNo:1, + keyID:state.keyId.value.toString(), + userID:userID, + fingerNo:int.parse(state.typeNumber.value), useCountLimit:0, - startTime:0x11223344, - endTime:0x11223344, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, + startTime:state.effectiveDateTime.value, + endTime:state.failureDateTime.value, needAuthor:1, publicKey:publicKeyDataList, privateKey:getPrivateKeyList, @@ -144,38 +121,7 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ // 删除指纹 void deletFingerprintsData() async{ var entity = await ApiRepository.to.deletFingerprintsData( - fingerprintId: state.fingerprintItemData.value.fingerprintId.toString(), - lockId: state.fingerprintItemData.value.lockId.toString(), - type: "0", - deleteType:"1" - ); - if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "删除成功"); - Get.back(result: "addScuess"); - } - } - - // 编辑iC卡 - void editICCardData() async{ - var entity = await ApiRepository.to.editICCardData( - cardId: state.keyId.value.toString(), - lockId: state.fingerprintItemData.value.lockId.toString(), - weekDay: state.weekDay.value, - startDate: state.effectiveDateTime.value.toString(), - endDate: state.failureDateTime.value.toString(), - isCoerced: state.isStressFingerprint.value ? "2" : "1", - cardName: state.changeNameController.text, - ); - if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "修改成功"); - Get.back(result: "addScuess"); - } - } - - // 删除IC卡 - void deletICCardData() async{ - var entity = await ApiRepository.to.deletIcCardData( - cardId: state.fingerprintItemData.value.cardId.toString(), + fingerprintId: state.fingerprintItemData.value.fingerprintId.toString(), lockId: state.fingerprintItemData.value.lockId.toString(), type: "0", deleteType:"1" @@ -186,6 +132,24 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ } } + // 编辑指纹 + void editFingerprintsData() async{ + var entity = await ApiRepository.to.editFingerprintsData( + fingerprintId: state.keyId.value.toString(), + lockId: state.fingerprintItemData.value.lockId.toString(), + weekDay: state.weekDay.value, + startDate: state.effectiveDateTime.value.toString(), + endDate: state.failureDateTime.value.toString(), + isCoerced: state.isStressFingerprint.value ? "2" : "1", + fingerprintName: state.changeNameController.text, + changeType: "1", + ); + if(entity.errorCode!.codeIsSuccessful){ + Toast.show(msg: "修改成功"); + Get.back(result: "addScuess"); + } + } + @override void onReady() { // TODO: implement onReady @@ -199,7 +163,6 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ // TODO: implement onInit super.onInit(); - senderAddFingerprint(); } @override @@ -209,5 +172,4 @@ class OtherTypeKeyDetailLogic extends BaseGetXController{ _replySubscription.cancel(); } - } \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_page.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_page.dart new file mode 100644 index 00000000..4816167e --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_page.dart @@ -0,0 +1,324 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../appRouters.dart'; +import '../../../../app_settings/app_colors.dart'; +import '../../../../tools/commonItem.dart'; +import '../../../../tools/dateTool.dart'; +import '../../../../tools/showIosTipView.dart'; +import '../../../../tools/showTFView.dart'; +import '../../../../tools/submitBtn.dart'; +import '../../../../tools/titleAppBar.dart'; +import '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'fingerprintDetail_logic.dart'; + +class FingerprintDetailPage extends StatefulWidget { + const FingerprintDetailPage({Key? key}) : super(key: key); + + @override + State createState() => _FingerprintDetailPageState(); +} + +class _FingerprintDetailPageState extends State { + final logic = Get.put(FingerprintDetailLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: "${TranslationLoader.lanKeys!.fingerprint!.tr}${TranslationLoader.lanKeys!.number!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor, + // actionsList: [ + // TextButton( + // child: Text(TranslationLoader.lanKeys!.share!.tr, style: TextStyle(color: Colors.white, fontSize: 24.sp),), + // onPressed: () { + // + // }, + // ), + // ], + ), + body: Column( + children: [ + Obx(() => CommonItem( + leftTitel: "${TranslationLoader.lanKeys!.fingerprint!.tr}${TranslationLoader.lanKeys!.number!.tr}", + rightTitle: state.typeNumber.value, + isHaveDirection: false, + isHaveLine: true)), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.name!.tr, + rightTitle: state.typeName.value, + isHaveDirection: true, + isHaveLine: true, + action: () { + showCupertinoAlertDialog(context); + })), + Obx(() => Visibility( + visible: (state.keyType.value == 4 || state.keyType.value == 2) ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr, + allHeight: 70.h, + // rightTitle:"2023.09.19 11:27\n2023.09.25 11:27", + rightTitle: state.keyType.value == 1 ? "永久" : "${DateTool().dateToYMDHNString(state.effectiveDateTime.value.toString())}\n${DateTool().dateToYMDHNString(state.failureDateTime.value.toString())}", + isHaveDirection: true, + isHaveLine: true, + action: () async { + // switch(state.type.value){ + // case 0: + // // 卡 + // + // break; + // case 1: + // 当是指纹的时候 + if(state.keyType.value == 2){ + // 限时 + var data = await Get.toNamed(Routers.otherTypeKeyChangeDatePage, arguments: { + "fingerprintItemData": state.fingerprintItemData.value, + }); + if(data != null) { + setState(() { + state.effectiveDateTime.value = data["beginTimeTimestamp"]; + state.failureDateTime.value = data["endTimeTimestamp"]; + }); + } + }else if(state.keyType.value == 4){ + // 循环 + var data = await Get.toNamed(Routers.otherTypeKeyChangeValidityDatePage, arguments: { + "fingerprintItemData": state.fingerprintItemData.value, + }); + if(data != null) { + setState(() { + state.effectiveDateTime.value = data["beginTimeTimestamp"]; + state.failureDateTime.value = data["endTimeTimestamp"]; + state.weekDay.value = data["weekDay"]; + }); + } + } + + }))), + Obx(() => Visibility( + visible: state.keyType.value == 4 ? true : false, + child: Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveDay!.tr, + rightTitle: state.weekDay.value.join(','), + isHaveDirection: true, + action: () async { + // 当是指纹的时候 + var data = await Get.toNamed(Routers.otherTypeKeyChangeValidityDatePage, arguments: { + "fingerprintItemData": state.fingerprintItemData.value, + }); + if(data != null) { + setState(() { + state.effectiveDateTime.value = data["beginTimeTimestamp"]; + state.failureDateTime.value = data["endTimeTimestamp"]; + state.weekDay.value = data["weekDay"]; + }); + } + }))) + ), + Container(height: 10.h), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.additive!.tr, + rightTitle: state.adder.value, + action: () { + + })), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.addTime!.tr, + rightTitle: DateTool().dateToYMDHNString(state.addTime.value.toString()), + action: () { + + })), + SizedBox(height: 10.h), + Obx(() => CommonItem( + leftTitel: TranslationLoader.lanKeys!.stressFingerprint!.tr, + rightTitle: "", + isTipsImg: false, + isHaveRightWidget: true, + rightWidget: SizedBox( + width: 60.w, height: 50.h, child: _isStressFingerprint()))), + Container(height: 10.h), + CommonItem( + leftTitel: TranslationLoader.lanKeys!.operatingRecord!.tr, + rightTitle: "", + isHaveDirection: true, + action: () { + // 指纹 + Get.toNamed(Routers.keyOperationRecordPage, arguments: { + 'lockId': state.fingerprintItemData.value.lockId.toString(), + 'fingerprintId': state.fingerprintItemData.value.fingerprintId.toString() + }); + }), + // SizedBox(height: 40.h), + // addControlsBtn(type), + SizedBox(height: 30.h), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.delete!.tr, + isDelete: true, + borderRadius: 20.w, + margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w, bottom: 30.w), + padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + onClick: () { + showIosTipViewDialog(context); + }), + ], + ), + ); + } + + //isStressFingerprint false:不是胁迫指纹 ture:胁迫指纹 + CupertinoSwitch _isStressFingerprint() { + return CupertinoSwitch( + activeColor: CupertinoColors.activeBlue, + trackColor: CupertinoColors.systemGrey5, + thumbColor: CupertinoColors.white, + value: state.isStressFingerprint.value, + onChanged: (value) { + setState(() { + state.isStressFingerprint.value = value; + logic.editFingerprintsData(); + }); + }, + ); + } + + // Widget addControlsBtn(int type) { + // List widgetList = []; + // List> routerList = []; + // //卡详情 + // if (type == 0) { + // routerList.add({ + // 'btnTitle': '设置密码', + // 'routerName': Routers.passwordKeyDetailPage, + // 'type': 9 + // }); + // routerList.add({ + // 'btnTitle': '设置指纹', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 1 + // }); + // routerList.add({ + // 'btnTitle': '设置遥控', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 2 + // }); + // } else if (type == 1) { + // //指纹详情 + // routerList.add({ + // 'btnTitle': '设置密码', + // 'routerName': Routers.passwordKeyDetailPage, + // 'type': 9 + // }); + // routerList.add({ + // 'btnTitle': '设置卡', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 0 + // }); + // routerList.add({ + // 'btnTitle': '设置遥控', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 2 + // }); + // } else if (type == 2) { + // //遥控详情 + // routerList.add({ + // 'btnTitle': '设置密码', + // 'routerName': Routers.passwordKeyDetailPage, + // 'type': 9 + // }); + // routerList.add({ + // 'btnTitle': '设置卡', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 0 + // }); + // routerList.add({ + // 'btnTitle': '设置指纹', + // 'routerName': Routers.otherTypeKeyManagePage, + // 'type': 1 + // }); + // } + // + // for (int i = 0; i < routerList.length; i++) { + // widgetList.add(SizedBox( + // width: ScreenUtil().screenWidth - 40.w, + // height: 60.h, + // child: OutlinedButton( + // style: OutlinedButton.styleFrom( + // // backgroundColor: Colors.white, + // side: BorderSide(width: 1, color: AppColors.mainColor)), + // onPressed: () { + // if (routerList[i]['type'] == 9) { + // Navigator.pushNamed(context, Routers.passwordKeyManagePage); + // } else { + // Navigator.pushNamed(context, Routers.otherTypeKeyManagePage, + // arguments: routerList[i]['type']); + // } + // }, + // child: Text( + // routerList[i]['btnTitle'], + // style: TextStyle(color: AppColors.mainColor, fontSize: 24.sp), + // )), + // )); + // + // widgetList.add( + // SizedBox( + // height: 10.h, + // ), + // ); + // } + // + // return Column( + // children: widgetList, + // ); + // } + + void showCupertinoAlertDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return ShowTFView( + title: "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.name!.tr}", + tipTitle: "", + controller: state.changeNameController, + sureClick: () { + if(state.changeNameController.text.isEmpty){ + Toast.show(msg: "请输入姓名"); + return; + } + Get.back(); + // 指纹 + logic.editFingerprintsData(); + }, + cancelClick: () { + Get.back(); + },); + }); + } + + void showIosTipViewDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return ShowIosTipView( + title: "提示", + tipTitle: "确定要删除吗?", + sureClick: () { + Get.back(); + // 指纹 + logic.senderAddFingerprint(); + }, + cancelClick: () { + Get.back(); + }, + ); + } + ); + } + +} diff --git a/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_state.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_state.dart new file mode 100644 index 00000000..a66a59b2 --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintDetail/fingerprintDetail_state.dart @@ -0,0 +1,39 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../fingerprintList/fingerprintListData_entity.dart'; + +class FingerprintDetailState{ + final fingerprintItemData = FingerprintItemData().obs; + + final TextEditingController changeNameController = TextEditingController(); + + final typeNumber = "".obs;// 指纹号 + final typeName = "".obs;// 指纹名字 + var effectiveDateTime = 0.obs;// 生效时间 + var failureDateTime = 0.obs;// 失效时间 + final keyType = 0.obs;// 永久:1;限时2,单次3,循环:4 + var weekDay = [].obs;// 有效日 + var adder = "".obs;// 添加者 + var addTime = 0.obs;// 添加时间 + var keyId = 0.obs; + + final isStressFingerprint = false.obs; + FingerprintDetailState() { + Map map = Get.arguments; + fingerprintItemData.value = map["fingerprintItemData"]; + keyId.value = fingerprintItemData.value.fingerprintId!; + typeNumber.value = fingerprintItemData.value.fingerprintNumber!; + typeName.value = fingerprintItemData.value.fingerprintName!; + changeNameController.text = typeName.value; + effectiveDateTime.value = fingerprintItemData.value.startDate!; + failureDateTime.value = fingerprintItemData.value.endDate!; + keyType.value = fingerprintItemData.value.fingerprintType!; + adder.value = fingerprintItemData.value.senderUsername!; + addTime.value = fingerprintItemData.value.createDate!; + isStressFingerprint.value = fingerprintItemData.value.isCoerced! == 2 ? true : false; + weekDay.value = fingerprintItemData.value.weekDay!; + + } +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/fingerprintListData_entity.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart similarity index 100% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/fingerprintListData_entity.dart rename to star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart similarity index 63% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_logic.dart rename to star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart index 6fc4b274..8d34d2fc 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_logic.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart @@ -2,113 +2,46 @@ import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:star_lock/blue/io_protocol/io_addICCard.dart'; import 'package:star_lock/blue/io_type.dart'; - +import 'package:star_lock/tools/baseGetXController.dart'; import '../../../../blue/blue_manage.dart'; import '../../../../blue/io_protocol/io_addFingerprint.dart'; -import '../../../../blue/io_protocol/io_checkingCardStatus.dart'; import '../../../../blue/io_protocol/io_checkingUserInfoCount.dart'; import '../../../../blue/io_protocol/io_queryingFingerprintStatus.dart'; import '../../../../blue/io_reply.dart'; -import '../../../../blue/io_tool/io_manager.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/eventBusEventManage.dart'; import '../../../../tools/storage.dart'; import '../../../../tools/toast.dart'; -import 'otherTypeKeyList_state.dart'; +import 'fingerprintList_state.dart'; -class OtherTypeKeyListLogic extends BaseGetXController{ - OtherTypeKeyListState state = OtherTypeKeyListState(); +class FingerprintListLogic extends BaseGetXController{ + FingerprintListState state = FingerprintListState(); // 获取解析后的数据 late StreamSubscription _replySubscription; void _initReplySubscription() { _replySubscription = EventBusManager().eventBus!.on().listen((reply) { - // 添加指纹开始(重置锁里面所有指纹) + // 添加指纹开始(此处用作删除指纹) if((reply is SenderAddFingerprintReply) && (state.isDeletFingerprintData == true)) { _replyAddFingerprintBegin(reply); } - // 添加卡片开始(重置锁里面所有卡) - if((reply is SenderAddICCardReply) && (state.isDeletICCardData == true)) { - _replyAddICCardBegin(reply); - } - if(reply is SenderQueryingFingerprintStatusReply) { // 获取指纹状态 _replyQueryingFingerprintStatus(reply); } - if(reply is SenderCheckingCardStatusReply) { - _replyReferEventRecordNumber(reply); - } - if(reply is SenderCheckingUserInfoCountReply){ _replyCheckingUserInfoCount(reply); } }); } - Future _replyAddICCardBegin(Reply reply) async { - int status = reply.data[2]; - print("_replyAddFingerprintStatus:$status"); - - switch(status){ - case 0x00: - //成功 - print("${reply.commandType!.typeValue} 数据解析成功"); - state.isDeletICCardData = false; - deletICCardData(); - break; - case 0x06: - //无权限 - print("${reply.commandType!.typeValue} 需要鉴权"); - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - - var publicKey = await Storage.getStringList(saveBluePublicKey); - List publicKeyDataList = changeStringListToIntList(publicKey!); - - var token = await Storage.getStringList(saveBlueToken); - List getTokenList = changeStringListToIntList(token!); - - IoSenderManage.senderAddICCardCommand( - keyID:"1", - userID:"DeleteAll!@#", - cardNo:255, - 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} 失败"); - - break; - } - } - - // 重置锁里面所有指纹 + // 添加指纹开始 Future _replyAddFingerprintBegin(Reply reply) async { int status = reply.data[2]; @@ -116,13 +49,13 @@ class OtherTypeKeyListLogic extends BaseGetXController{ switch(status){ case 0x00: - //成功 + //成功 print("${reply.commandType!.typeValue} 数据解析成功"); state.isDeletFingerprintData = false; deletAllFingerprintsData(); break; case 0x06: - //无权限 + //无权限 print("${reply.commandType!.typeValue} 需要鉴权"); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -134,9 +67,9 @@ class OtherTypeKeyListLogic extends BaseGetXController{ List getTokenList = changeStringListToIntList(token!); IoSenderManage.senderAddFingerprintCommand( - keyID:"1", - userID:"DeleteAll!@#", - fingerNo:255, + keyID:state.deletKeyID, + userID:state.deletUserID, + fingerNo:state.deletFingerNo, useCountLimit:0, startTime:0x11223344, endTime:0x11223344, @@ -331,34 +264,6 @@ class OtherTypeKeyListLogic extends BaseGetXController{ }); } - // 查询卡片状态 - Future senderCheckingCardStatus() async { - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected) { - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - - var token = await Storage.getStringList(saveBlueToken); - List getTokenList = changeStringListToIntList(token!); - - var publicKey = await Storage.getStringList(saveBluePublicKey); - List getPublicKeyList = changeStringListToIntList(publicKey!); - - IoSenderManage.senderCheckingCardStatusCommand( - keyID:BlueManage().connectDeviceName, - userID:await Storage.getUid(), - role:0xff, - cardCount:20, - cardNo:1, - token:getTokenList, - needAuthor:1, - publicKey:getPublicKeyList, - privateKey:getPrivateKeyList, - ); - } - }); - } - // 查询用户、指纹、密码、卡片数量(用于判断是否同步) Future senderCheckingUserInfoCount() async { BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { @@ -386,8 +291,8 @@ class OtherTypeKeyListLogic extends BaseGetXController{ }, isShowLoading: false); } - // 重置所有指纹 - Future senderAddFingerprint(String keyId, String userID, int cardNo) async { + // 删除指纹 + Future senderAddFingerprint() async { BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { if (deviceConnectionState == DeviceConnectionState.connected){ var publicKey = await Storage.getStringList(saveBluePublicKey); @@ -400,45 +305,9 @@ class OtherTypeKeyListLogic extends BaseGetXController{ List getTokenList = changeStringListToIntList(token!); IoSenderManage.senderAddFingerprintCommand( - // keyID:"1", - // userID:"DeleteAll!@#", - // fingerNo:255, - keyID:keyId, - userID:userID, - fingerNo:cardNo, - useCountLimit:0, - startTime:0x11223344, - endTime:0x11223344, - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: getTokenList, - ); - } - }); - } - - // 删除卡片 - Future senderAddICCard(String keyId, String userID, int cardNo) async { - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected){ - var publicKey = await Storage.getStringList(saveBluePublicKey); - List publicKeyDataList = changeStringListToIntList(publicKey!); - - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - - var token = await Storage.getStringList(saveBlueToken); - List getTokenList = changeStringListToIntList(token!); - print("openDoorTokenPubToken:$getTokenList"); - - IoSenderManage.senderAddICCardCommand( - // keyID:"1", - // userID:"DeleteAll!@#", - // cardNo:255, - keyID:keyId, - userID:userID, - cardNo:cardNo, + keyID:state.deletKeyID, + userID:state.deletUserID, + fingerNo:state.deletFingerNo, useCountLimit:0, startTime:0x11223344, endTime:0x11223344, @@ -466,66 +335,36 @@ class OtherTypeKeyListLogic extends BaseGetXController{ // 重置所有的指纹 void deletAllFingerprintsData() async{ + var fingerprintId = ""; + var type = "1"; + if(state.isDeletAll == false){ + fingerprintId = state.deletKeyID; + type = "0"; + } + print("delet fingerprintId $fingerprintId"); var entity = await ApiRepository.to.deletFingerprintsData( - fingerprintId: "", + fingerprintId: fingerprintId, lockId: state.lockId.value.toString(), - type: "1", + type: type, deleteType:"1" ); if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "重置成功"); + if(state.isDeletAll == false){ + Toast.show(msg: "删除成功"); + }else{ + Toast.show(msg: "重置成功"); + } + state.isDeletFingerprintData = false; getFingerprintsListData(); } } - // 获取IC卡列表 - void getICCardListData() async{ - var entity = await ApiRepository.to.getICCardListData( - lockId: state.lockId.value.toString(), - pageNo: '1', - pageSize: '20', - searchStr: state.searchController.text, - ); - if(entity.errorCode!.codeIsSuccessful){ - state.fingerprintItemListData.value = entity.data!.list!; - } - } - - // 删除所有IC卡 - void deletICCardData() async{ - var entity = await ApiRepository.to.deletIcCardData( - cardId: "", - lockId: state.lockId.value.toString(), - type: "1", - deleteType:"1" - ); - if(entity.errorCode!.codeIsSuccessful){ - Toast.show(msg: "重置成功"); - getICCardListData(); - } - } - // 监听修改完详情之后刷新列表 late StreamSubscription _teamEvent; void _initRefreshAction() { _teamEvent = eventBus.on().listen((event) { - switch (state.fromType.value) { - case 0: - // 卡 - getICCardListData(); - break; - case 1: - // 指纹 - getFingerprintsListData(); - break; - case 2: - // 遥控 - - break; - default: - break; - } + getFingerprintsListData(); }); } @@ -543,22 +382,7 @@ class OtherTypeKeyListLogic extends BaseGetXController{ _initRefreshAction(); - switch (state.fromType.value) { - case 0: - // 卡 - getICCardListData(); - break; - case 1: - // 指纹 - getFingerprintsListData(); - break; - case 2: - // 遥控 - - break; - default: - break; - } + getFingerprintsListData(); } } diff --git a/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart new file mode 100644 index 00000000..7dde045c --- /dev/null +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart @@ -0,0 +1,304 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../appRouters.dart'; +import '../../../../app_settings/app_colors.dart'; +import '../../../../tools/dateTool.dart'; +import '../../../../tools/left_slide_actions.dart'; +import '../../../../tools/noData.dart'; +import '../../../../tools/showIosTipView.dart'; +import '../../../../tools/storage.dart'; +import '../../../../tools/submitBtn.dart'; +import '../../../../tools/titleAppBar.dart'; +import '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'fingerprintListData_entity.dart'; +import 'fingerprintList_logic.dart'; + +class FingerprintListPage extends StatefulWidget { + const FingerprintListPage({Key? key}) : super(key: key); + + @override + State createState() => _FingerprintListPageState(); +} + +class _FingerprintListPageState extends State { + final logic = Get.put(FingerprintListLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: TranslationLoader.lanKeys!.fingerprint!.tr, + 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.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }, + ), + ], + ), + body: Column( + children: [ + _searchWidget(), + SizedBox( + height: 20.h, + ), + Expanded(child: _buildMainUI()), + AddBottomWhiteBtn( + btnName: '${TranslationLoader.lanKeys!.add!.tr}${TranslationLoader.lanKeys!.fingerprint!.tr}', + onClick: () async { + var data = + await Get.toNamed(Routers.addFingerprintTypeManagePage, arguments: { + "lockId": state.lockId.value, + "fromType": 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 + }); + if (data != null) { + logic.getFingerprintsListData(); + } + }, + ), + SizedBox(height: 64.h) + ], + ), + ); + } + + Widget _searchWidget() { + return Container( + height: 60.h, + margin: EdgeInsets.only(top: 20.w, left: 20.w, right: 10.w), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: TextField( + //输入框一行 + maxLines: 1, + controller: state.searchController, + autofocus: false, + onChanged: (value) { + print("onChanged:$value"); + }, + onEditingComplete: () { + print("onEditingComplete:"); + }, + onSubmitted: (value) { + logic.getFingerprintsListData(); + }, + decoration: InputDecoration( + //输入里面输入文字内边距设置 + contentPadding: const EdgeInsets.only( + top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, + hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), + //不需要输入框下划线 + border: InputBorder.none, + //左边图标设置 + icon: Padding( + padding: EdgeInsets.only( + top: 20.h, bottom: 20.h, right: 20.w, left: 10.w), + child: Image.asset( + 'images/main/icon_main_search.png', + width: 40.w, + height: 40.w, + ), + ), + ), + ), + ); + } + + Widget _buildMainUI() { + return Obx(() => state.fingerprintItemListData.value.isNotEmpty + ? ListView.separated( + itemCount: state.fingerprintItemListData.value.length, + itemBuilder: (c, index) { + FingerprintItemData fingerprintItemData = state.fingerprintItemListData.value[index]; + // 指纹 + if (index < state.fingerprintItemListData.value.length) { + return LeftSlideActions( + key: Key(fingerprintItemData.fingerprintName!), + actionsWidth: 60, + actions: [ + _buildDeleteBtn(fingerprintItemData), + ], + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(1)), + ), + child: _keyItem( + 'images/icon_fingerprint.png', + fingerprintItemData.fingerprintName!, + fingerprintItemData.fingerprintType! == 1 + ? "永久" + : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", + () async { + var data = await Get.toNamed( + Routers.fingerprintDetailPage, + arguments: { + "fingerprintItemData": fingerprintItemData, + }); + if (data != null) { + logic.getFingerprintsListData(); + } + }), + ); + } + return const SizedBox.shrink(); + }, + separatorBuilder: (BuildContext context, int index) { + return const Divider( + height: 1, + color: AppColors.greyLineColor, + ); + }, + ) + : const NoData()); + } + + Widget _buildDeleteBtn(FingerprintItemData fingerprintItemData) { + return GestureDetector( + onTap: () { + // 省略: 弹出是否删除的确认对话框。 + state.deletKeyID = fingerprintItemData.fingerprintId.toString(); + state.deletFingerNo = int.parse(fingerprintItemData.fingerprintNumber!); + 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.isDeletFingerprintData = true; + state.isDeletAll = false; + state.deletUserID = (await Storage.getUid())!; + logic.senderAddFingerprint(); + }, + cancelClick: () { + Get.back(); + }, + ); + }, + ); + } + + Widget _keyItem(String lockTypeIcon, String lockTypeTitle, 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.start, + children: [ + Text(lockTypeTitle, + style: TextStyle( + fontSize: 24.sp, color: AppColors.blackColor)), + ], + ), + SizedBox(height: 5.h), + Container( + child: 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.isDeletFingerprintData = true; + state.isDeletAll = true; + state.deletKeyID = "1"; + state.deletUserID = "DeleteAll!@#"; + state.deletFingerNo = 255; + logic.senderAddFingerprint(); + }, + ), + ], + ); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_state.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_state.dart similarity index 61% rename from star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_state.dart rename to star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_state.dart index 5e9b71ed..e0d301fb 100644 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_state.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_state.dart @@ -4,19 +4,21 @@ import 'package:get/get.dart'; import 'fingerprintListData_entity.dart'; -class OtherTypeKeyListState{ +class FingerprintListState{ final lockId = 0.obs; - final fromType = 0.obs; + // 因为删除跟添加指纹用的同一个协议 所以这里用做判断 var isDeletFingerprintData = false; - var isDeletICCardData = false; + var isDeletAll = false; + var deletKeyID = ""; + var deletUserID = "DeleteAll!@#"; + var deletFingerNo = 0; final fingerprintItemListData = [].obs; final TextEditingController searchController = TextEditingController(); - OtherTypeKeyListState() { + FingerprintListState() { Map map = Get.arguments; lockId.value = map["lockId"]; - fromType.value = map["fromType"]; } } \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_page.dart b/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_page.dart index bcb893aa..985c4bd7 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_page.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_page.dart @@ -31,16 +31,18 @@ class _AutomaticBlockingPageState extends State { barTitle: TranslationLoader.lanKeys!.automaticBlocking!.tr, haveBack: true, actionsList: [ - TextButton( + Obx(() => TextButton( child: Text( - TranslationLoader.lanKeys!.save!.tr, + state.isJustForShow.value == true ? "" : TranslationLoader.lanKeys!.save!.tr, style: TextStyle(color: Colors.white, fontSize: 24.sp), ), onPressed: () { - // logic.sendAutoLock(); + if(state.isJustForShow.value == true){ + return; + } logic.sendAutoLock(); }, - ), + )), ], backgroundColor: AppColors.mainColor), body: ListView( @@ -60,6 +62,9 @@ class _AutomaticBlockingPageState extends State { isHaveLine: false, isHaveDirection: true, action: () { + if(state.isJustForShow.value == true){ + return; + } var list = [ "5", "10", @@ -110,11 +115,12 @@ class _AutomaticBlockingPageState extends State { ), ], ), - TextField( + Obx(() => TextField( //输入框一行 maxLines: 1, controller: state.timeController, autofocus: false, + readOnly: state.isJustForShow.value == true ? false : true, decoration: InputDecoration( //输入里面输入文字内边距设置 contentPadding: @@ -125,7 +131,7 @@ class _AutomaticBlockingPageState extends State { //不需要输入框下划线 border: InputBorder.none, ), - ), + )), Container( height: 0.5.h, color: Colors.grey, diff --git a/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_state.dart b/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_state.dart index 4892c72d..80aac784 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_state.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/automaticBlocking/automaticBlocking_state.dart @@ -7,6 +7,9 @@ import '../lockSet/lockSetInfo_entity.dart'; class AutomaticBlockingState { var lockSetInfoData = LockSetInfoData().obs; + final lockBasicInfo = LockBasicInfo().obs; + + var isJustForShow = false.obs;// 是否只是作为展示作用,因为普通用户只是展示,不可修改 var isOpen = false.obs;// 是否开启自动落锁 var autoLockTime = "5".obs; @@ -16,10 +19,17 @@ class AutomaticBlockingState { AutomaticBlockingState() { var map = Get.arguments; lockSetInfoData.value = map["lockSetInfoData"]; + lockBasicInfo.value = map["lockBasicInfo"]; isOpen.value = lockSetInfoData.value.lockSettingInfo!.autoLock! == 1 ? true : false; autoLockTime.value = lockSetInfoData.value.lockSettingInfo!.autoLockSecond!.toString(); + if(lockBasicInfo.value.isLockOwner == 1 || lockBasicInfo.value.keyRight == 1){ + isJustForShow.value = false; + }else{ + isJustForShow.value = true; + } + if((lockSetInfoData.value.lockSettingInfo!.autoLock! > 0) && (lockSetInfoData.value.lockSettingInfo!.autoLockSecond! != 5) && (lockSetInfoData.value.lockSettingInfo!.autoLockSecond! != 10) diff --git a/star_lock/lib/main/lockDetail/lcokSet/basicInformation/basicInformation/basicInformation_page.dart b/star_lock/lib/main/lockDetail/lcokSet/basicInformation/basicInformation/basicInformation_page.dart index e90c047f..a96903b7 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/basicInformation/basicInformation/basicInformation_page.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/basicInformation/basicInformation/basicInformation_page.dart @@ -107,15 +107,17 @@ class _BasicInformationPageState extends State { } }); }), - CommonItem( - leftTitel: TranslationLoader.lanKeys!.adminOpenLockPassword!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Navigator.pushNamed(context, - Routers.adminOpenLockPasswordPage); - }), + Visibility( + visible: (state.lockBasicInfo.value.isLockOwner == 1 || state.lockBasicInfo.value.keyRight == 1) ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.adminOpenLockPassword!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Navigator.pushNamed(context, Routers.adminOpenLockPasswordPage); + }), + ), CommonItem( leftTitel: TranslationLoader.lanKeys!.unlockQRCode!.tr, diff --git a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart index cc2c0212..ee6a22b5 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart @@ -314,6 +314,8 @@ class LockBasicInfo { int? startDate; int? endDate; String? mac; + int? keyRight; + int? senderUserId; LockBasicInfo( {this.keyId, @@ -328,7 +330,9 @@ class LockBasicInfo { this.keyType, this.startDate, this.endDate, - this.mac}); + this.mac, + this.keyRight, + this.senderUserId}); LockBasicInfo.fromJson(Map json) { keyId = json['keyId']; @@ -349,6 +353,9 @@ class LockBasicInfo { startDate = json['startDate']; endDate = json['endDate']; mac = json['mac']; + keyRight = json['keyRight']; + senderUserId = json['senderUserId']; + } Map toJson() { @@ -368,6 +375,8 @@ class LockBasicInfo { data['startDate'] = startDate; data['endDate'] = endDate; data['mac'] = mac; + data['keyRight'] = keyRight; + data['senderUserId'] = senderUserId; return data; } } diff --git a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_logic.dart b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_logic.dart index 08ccd6e6..dc47d650 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_logic.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_logic.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:get/get.dart'; import 'package:star_lock/blue/io_protocol/io_deletUser.dart'; @@ -19,6 +20,7 @@ import '../../../../tools/baseGetXController.dart'; import '../../../../tools/eventBusEventManage.dart'; import '../../../../tools/storage.dart'; import '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; import 'checkingInInfoData_entity.dart'; import 'lockSet_state.dart'; @@ -248,9 +250,7 @@ class LockSetLogic extends BaseGetXController { // 删除用户 Future deletUserAction() async { - BlueManage().judgeReconnect( - BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, - (DeviceConnectionState connectionState) async { + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState connectionState) async { if (connectionState == DeviceConnectionState.connected) { var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -263,13 +263,18 @@ class LockSetLogic extends BaseGetXController { IoSenderManage.deletUser( lockID: BlueManage().connectDeviceName, - authUserID: "100001", - keyID: "1", - delUserID: "100001", + authUserID:state.lockBasicInfo.value.senderUserId.toString(), + keyID:state.lockBasicInfo.value.keyId.toString(), + delUserID:await Storage.getUid(), + // authUserID: "100001", + // keyID: "1", + // delUserID: "100001", needAuthor: 1, publicKey: publicKeyDataList, privateKey: getPrivateKeyList, token: getTokenList); + }else{ + showDeletAlertTipDialog(Get.context!); } }); } @@ -296,6 +301,8 @@ class LockSetLogic extends BaseGetXController { privateKey:getPrivateKeyList, token: getTokenList ); + }else{ + showDeletAlertTipDialog(Get.context!); } }); } @@ -378,6 +385,8 @@ class LockSetLogic extends BaseGetXController { state.lockSettingInfo.value = state.lockSetInfoData.value.lockSettingInfo!; state.lockFeature.value = state.lockSetInfoData.value.lockFeature!; state.lockStatus.value = state.lockSetInfoData.value.lockStatus!; + state.lockBasicInfo.value = state.lockSetInfoData.value.lockBasicInfo!; + state.isAttendance.value = state.lockSettingInfo.value.attendance!; state.isOpenLockNeedOnline.value = state.lockSettingInfo.value.appUnlockOnline!; @@ -395,6 +404,7 @@ class LockSetLogic extends BaseGetXController { lockId: state.lockSetInfoData.value.lockId.toString(), ); if (entity.errorCode!.codeIsSuccessful) { + BlueManage().connectDeviceMacAddress = ""; Get.offAllNamed(Routers.starLockMain); } } @@ -406,6 +416,7 @@ class LockSetLogic extends BaseGetXController { keyId: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(), ); if (entity.errorCode!.codeIsSuccessful) { + BlueManage().connectDeviceMacAddress = ""; Get.offAllNamed(Routers.starLockMain); } } @@ -425,13 +436,23 @@ class LockSetLogic extends BaseGetXController { // } // if(state.currentDeviceUUid.value[31] == "1"){ - // 已配对 + // 判断是否是锁的拥有者 if(state.lockSetInfoData.value.lockBasicInfo!.isLockOwner == 1){ - // 调用删除锁协议 - factoryDataResetAction(); + // 判断是否扫描到当前设备 + if(BlueManage().connectDeviceMacAddress.isNotEmpty){ + // 调用删除锁协议 + factoryDataResetAction(); + }else{ + showDeletAlertTipDialog(Get.context!); + } }else{ - // 调用删除钥匙协议 - deletUserAction(); + // 判断是否扫描到当前设备 + if(BlueManage().connectDeviceMacAddress.isNotEmpty){ + // 调用删除钥匙协议 + deletUserAction(); + }else{ + showDeletAlertTipDialog(Get.context!); + } } // }else if(state.currentDeviceUUid.value[31] == "0"){ @@ -528,6 +549,39 @@ class LockSetLogic extends BaseGetXController { }); } + void showDeletAlertTipDialog(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); + if(state.lockSetInfoData.value.lockBasicInfo!.isLockOwner == 1){ + // 直接调用删除锁接口 + deletLockInfoData(); + }else{ + // 直接调用删除要是接口 + deletKeyData(); + } + }, + ), + ], + ); + }, + ); + } + @override void onReady() { // TODO: implement onReady diff --git a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart index 4c91282e..35e83c87 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart @@ -1,4 +1,3 @@ - import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -48,492 +47,543 @@ class _LockSetPageState extends State with RouteAware { body: Column( children: [ Expanded( - child: ListView( - children: [ - // 基本信息 - CommonItem( - leftTitel: - TranslationLoader.lanKeys!.basicInformation!.tr, - rightTitle: "", - isHaveLine: false, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.basicInformationPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }), - SizedBox(height: 10.h), - // 门磁 - Obx(() => Visibility( - visible: state.lockFeature.value.doorStatus == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.doorMagnetic!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.doorMagneticPage); - // Toast.show(msg: "功能暂未开放"); - }))), - // 无线键盘 - Obx(() => Visibility( - visible: state.lockFeature.value.wirelessKeyboard == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.wirelessKeyboard!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.wirelessKeyboardPage); - // Toast.show(msg: "功能暂未开放"); - }))), - // 照明 - Obx(() => Visibility( - visible: state.lockFeature.value.lightingTime == 1 - ? true - : false, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.illumination!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Toast.show(msg: "功能暂未开放"); - }))), - // 开门器 - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.doorOpener!.tr, - rightTitle: "", - isHaveLine: false, - isHaveDirection: true, - action: () { - Toast.show(msg: "功能暂未开放"); - })), - SizedBox(height: 10.h), - // 自动闭锁 - Obx(() => Visibility( - visible: - state.lockFeature.value.autoLock == 1 ? true : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.automaticBlocking!.tr, - rightTitle: (state.lockSettingInfo.value.autoLock ?? 0) > 0 - ? "${state.lockSetInfoData.value.lockSettingInfo!.autoLockSecond ?? 0}s" - : TranslationLoader.lanKeys!.closed!.tr, - isHaveLine: true, - isHaveDirection: true, - // isHaveRightWidget: true, - // rightWidget: rightText((state.lockSetInfoData.value.lockSetting!.autoLock ?? 0) > 0 - // ? "${state.lockSetInfoData.value.lockSetting!.autoLockSecond ?? 0}s" - // : TranslationLoader.lanKeys!.closed!.tr), - action: () { - Get.toNamed(Routers.automaticBlockingPage, - arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }))), - // 锁声音 - Obx(() { - var titleStr = ""; - if ((state.lockSettingInfo.value.lockSound ?? 0) == 1) { - switch ( - state.lockSettingInfo.value.lockSoundVolume ?? 0) { - case 1: - titleStr = TranslationLoader.lanKeys!.low!.tr; - break; - case 2: - titleStr = TranslationLoader.lanKeys!.lower!.tr; - break; - case 3: - titleStr = TranslationLoader.lanKeys!.medium!.tr; - break; - case 4: - titleStr = TranslationLoader.lanKeys!.high!.tr; - break; - case 5: - titleStr = TranslationLoader.lanKeys!.higher!.tr; - break; - } - } else { - titleStr = TranslationLoader.lanKeys!.closed!.tr; - } - return Visibility( - visible: state.lockFeature.value.lockSound == 1 - ? true - : false, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.lockSound!.tr, - rightTitle: titleStr, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.lockSoundSetPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - })); - }), - // 防撬报警 - Obx(() => Visibility( - visible: state.lockFeature.value.antiPrySwitch == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.burglarAlarm!.tr, - rightTitle: - (state.lockSettingInfo.value.antiPrySwitch ?? 0) == 1 - ? TranslationLoader.lanKeys!.opened!.tr - : TranslationLoader.lanKeys!.closed!.tr, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.burglarAlarmPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }))), - SizedBox(height: 10.h), - // 常开模式 - Obx(() => Visibility( - visible: state.lockFeature.value.passageMode == 1 - ? true - : false, - // visible:true, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.normallyOpenMode!.tr, - rightTitle: - (state.lockSettingInfo.value.passageMode ?? 0) == - 1 - ? TranslationLoader.lanKeys!.opened!.tr - : TranslationLoader.lanKeys!.closed!.tr, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.normallyOpenModePage, - arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }))), - // 远程开锁 - Obx(() => Visibility( - visible: state.lockFeature.value.remoteUnlock == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.remoteUnlocking!.tr, - rightTitle: - (state.lockSettingInfo.value.remoteUnlock ?? 0) == - 1 - ? TranslationLoader.lanKeys!.opened!.tr - : TranslationLoader.lanKeys!.closed!.tr, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.remoteUnlockingPage, - arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }))), - // 重置键 - Obx(() => Visibility( - visible: state.lockFeature.value.resetSwitch == 1 - ? true - : false, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.resetButton!.tr, - rightTitle: - (state.lockSettingInfo.value.resetSwitch ?? 0) == - 1 - ? TranslationLoader.lanKeys!.opened!.tr - : TranslationLoader.lanKeys!.closed!.tr, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.resetButtonPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }))), - SizedBox(height: 10.h), - //---田总新增展示 - // Obx(() => - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.faceUnlocks!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.faceUnlockPage); - })), - // ), - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.messageReminding!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.msgNotificationPage); - })), - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.catEyeSet!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.catEyeSetPage); - })), - // Obx(() => - //自动亮屏已包括至面容开锁模块 - // Visibility( - // visible: true, - // child: CommonItem( - // leftTitel: '自动亮屏', - // rightTitle: "", - // isHaveLine: true, - // isHaveDirection: true, - // action: () {})), - // ), - - // Obx(() => - //感应距离已包括至面容开锁模块 - // Visibility( - // visible: true, - // child: CommonItem( - // leftTitel: '感应距离', - // rightTitle: "", - // isHaveLine: true, - // isHaveDirection: true, - // action: () { - // Toast.show(msg: "功能暂未开放"); - // })), - // ), - // Obx(() => - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.openingDirectionSet!.tr, - rightTitle: "", - isHaveDirection: true, - isHaveLine: true, - action: () { - // Toast.show(msg: "功能暂未开放"); - Get.toNamed(Routers.openDoorDirectionPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - })), - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.motorPowerSetting!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - // Toast.show(msg: "功能暂未开放"); - Get.toNamed(Routers.motorPowerPage); - })), - // 支持蓝牙广播(关闭则不能使用蓝牙主动开锁) - Obx(() => Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.bluetoothBroadcast!.tr, - rightTitle: "", - isHaveLine: true, - isHaveRightWidget: true, - rightWidget: _lockBlueBroadcastSwitch()))), - SizedBox(height: 10.h), - //-----新增至此 - // 标记房态 - Obx(() { - var title = ""; - if (state.lockStatus.value.roomStatus == 1) { - title = TranslationLoader.lanKeys!.checkedIn!.tr; - } else if (state.lockStatus.value.roomStatus == 0) { - title = TranslationLoader.lanKeys!.leisure!.tr; - } - return Visibility( - visible: state.lockStatus.value.roomStatus == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.markedHouseState!.tr, - rightTitle: title, - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.markedHouseStatePage, - arguments: { - 'lockSetInfoData': - state.lockSetInfoData.value - }); - })); - }), - // 考勤 - Obx( - () => Visibility( - visible: state.lockFeature.value.attendance == 1 - ? true - : false, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.checkingIn!.tr, - rightTitle: "", - isHaveLine: true, - isHaveRightWidget: true, - rightWidget: _openCheckInSwitch())), - ), - // 开锁提醒 - Obx( - () => Visibility( - visible: state.lockFeature.value.unlockReminder == 1 ? true : false, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.unlockReminder!.tr, - rightTitle: "", - isHaveLine: false, - isHaveRightWidget: true, - rightWidget: _lockRemindSwitch())), - ), - // APP开锁时是否需联网 - Obx(() => - Visibility( - visible: state.lockFeature.value.appUnlockOnline == 1 ? true : false, - child: - CommonItem( - leftTitel: TranslationLoader.lanKeys!.whetherInternetRequiredWhenUnlocking!.tr, - rightTitle: "", - isHaveLine: false, - isHaveRightWidget: true, - rightWidget: _openLockNeedOnlineSwitch()), - ), - ), - SizedBox(height: 10.h), - // wifi配网 - // Obx( - // () => Visibility( - // visible: - // state.lockFeature.value.wifi == 1 ? true : false, - // child: - CommonItem( - leftTitel: TranslationLoader.lanKeys!.wifiDistributionNetwork!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.configuringWifiPage, - arguments: { - 'lockSetInfoData': - state.lockSetInfoData.value - }); - }), - // ), - // ), - // Obx(() => - // 锁时间 - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.lockTime!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.lockTimePage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - })), - // ), - // Obx(() => - // 诊断 - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.diagnose!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.diagnosePage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - })), - // ), - // Obx(() => - // 上传数据 - Visibility( - visible: true, - child: CommonItem( - leftTitel: TranslationLoader.lanKeys!.uploadData!.tr, - rightTitle: "", - isHaveLine: true, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.uploadDataPage); - })), - // ), - // Obx(() => - // Visibility( - // visible: true, - // child: CommonItem( - // leftTitel: TranslationLoader - // .lanKeys!.importOtherLockData!.tr, - // rightTitle: "", - // isHaveLine: true, - // isHaveDirection: true, - // action: () { - // Get.toNamed(Routers.importOtherLockDataPage); - // })), - // ), - // Obx(() => - // 锁升级 - Visibility( - visible: true, - child: CommonItem( - leftTitel: - TranslationLoader.lanKeys!.lockEscalation!.tr, - rightTitle: "", - isHaveLine: false, - isHaveDirection: true, - action: () { - Get.toNamed(Routers.lockEscalationPage); - })), - // ), - SizedBox(height: 30.h), - Container( - padding: - EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h), - child: SubmitBtn( - btnName: TranslationLoader.lanKeys!.delete!.tr, - isDelete: true, - onClick: () { - // logic.deletUserAction(); - - // logic.deletLockInfoData(); - showDeletAlertDialog(context); - // showDeletPasswordAlertDialog(context); - }), - ), - ], - ), + child: Obx(() => ListView( + children: getListWidget(), + )), ), ], )); } + // 根据权限显示不同的列表 + List getListWidget() { + print( + "state.lockBasicInfo.value.isLockOwner:${state.lockBasicInfo.value.isLockOwner} state.lockBasicInfo.value.keyRight:${state.lockBasicInfo.value.keyRight}"); + if (state.lockBasicInfo.value.isLockOwner == 1 || + state.lockBasicInfo.value.keyRight == 1) { + // 超级管理员、授权管理员 + return getAllWidget(); + } else { + return getNormalWidget(); + } + } + + // 普通用户 + List getNormalWidget() { + var showWidgetArr = [ + // 基本信息 + CommonItem( + leftTitel: TranslationLoader.lanKeys!.basicInformation!.tr, + rightTitle: "", + isHaveLine: false, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.basicInformationPage, + arguments: {'lockSetInfoData': state.lockSetInfoData.value}); + }), + SizedBox(height: 10.h), + // 自动闭锁 + Obx(() => Visibility( + visible: state.lockFeature.value.autoLock == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr, + rightTitle: (state.lockSettingInfo.value.autoLock ?? 0) > 0 + ? "${state.lockSetInfoData.value.lockSettingInfo!.autoLockSecond ?? 0}s" + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + // isHaveRightWidget: true, + // rightWidget: rightText((state.lockSetInfoData.value.lockSetting!.autoLock ?? 0) > 0 + // ? "${state.lockSetInfoData.value.lockSetting!.autoLockSecond ?? 0}s" + // : TranslationLoader.lanKeys!.closed!.tr), + action: () { + Get.toNamed(Routers.automaticBlockingPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value, + 'lockBasicInfo': state.lockBasicInfo.value + }); + }))), + // 常开模式 + Obx(() => Visibility( + visible: state.lockFeature.value.passageMode == 1 ? true : false, + // visible:true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr, + rightTitle: (state.lockSettingInfo.value.passageMode ?? 0) == 1 + ? TranslationLoader.lanKeys!.opened!.tr + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.normallyOpenModePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value, + 'lockBasicInfo': state.lockBasicInfo.value + }); + }))), + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.lockTime!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.lockTimePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })), + SizedBox(height: 30.h), + Container( + padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h), + child: SubmitBtn( + btnName: TranslationLoader.lanKeys!.delete!.tr, + isDelete: true, + onClick: () { + // logic.deletUserAction(); + + // logic.deletLockInfoData(); + showDeletAlertDialog(context); + // showDeletPasswordAlertDialog(context); + }), + ), + ]; + return showWidgetArr; + } + + // 授权管理员、超级管理员字段 + List getAllWidget() { + var showWidgetArr = [ + // 基本信息 + CommonItem( + leftTitel: TranslationLoader.lanKeys!.basicInformation!.tr, + rightTitle: "", + isHaveLine: false, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.basicInformationPage, + arguments: {'lockSetInfoData': state.lockSetInfoData.value}); + }), + SizedBox(height: 10.h), + // 门磁 + Obx(() => Visibility( + visible: state.lockFeature.value.doorStatus == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.doorMagnetic!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.doorMagneticPage); + // Toast.show(msg: "功能暂未开放"); + }))), + // 无线键盘 + Obx(() => Visibility( + visible: state.lockFeature.value.wirelessKeyboard == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.wirelessKeyboard!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.wirelessKeyboardPage); + // Toast.show(msg: "功能暂未开放"); + }))), + // 照明 + Obx(() => Visibility( + visible: state.lockFeature.value.lightingTime == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.illumination!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Toast.show(msg: "功能暂未开放"); + }))), + // 开门器 + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.doorOpener!.tr, + rightTitle: "", + isHaveLine: false, + isHaveDirection: true, + action: () { + Toast.show(msg: "功能暂未开放"); + })), + SizedBox(height: 10.h), + // 自动闭锁 + Obx(() => Visibility( + visible: state.lockFeature.value.autoLock == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr, + rightTitle: (state.lockSettingInfo.value.autoLock ?? 0) > 0 + ? "${state.lockSetInfoData.value.lockSettingInfo!.autoLockSecond ?? 0}s" + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + // isHaveRightWidget: true, + // rightWidget: rightText((state.lockSetInfoData.value.lockSetting!.autoLock ?? 0) > 0 + // ? "${state.lockSetInfoData.value.lockSetting!.autoLockSecond ?? 0}s" + // : TranslationLoader.lanKeys!.closed!.tr), + action: () { + Get.toNamed(Routers.automaticBlockingPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + }))), + // 锁声音 + Obx(() { + var titleStr = ""; + if ((state.lockSettingInfo.value.lockSound ?? 0) == 1) { + switch (state.lockSettingInfo.value.lockSoundVolume ?? 0) { + case 1: + titleStr = TranslationLoader.lanKeys!.low!.tr; + break; + case 2: + titleStr = TranslationLoader.lanKeys!.lower!.tr; + break; + case 3: + titleStr = TranslationLoader.lanKeys!.medium!.tr; + break; + case 4: + titleStr = TranslationLoader.lanKeys!.high!.tr; + break; + case 5: + titleStr = TranslationLoader.lanKeys!.higher!.tr; + break; + } + } else { + titleStr = TranslationLoader.lanKeys!.closed!.tr; + } + return Visibility( + visible: state.lockFeature.value.lockSound == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.lockSound!.tr, + rightTitle: titleStr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.lockSoundSetPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })); + }), + // 防撬报警 + Obx(() => Visibility( + visible: state.lockFeature.value.antiPrySwitch == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.burglarAlarm!.tr, + rightTitle: (state.lockSettingInfo.value.antiPrySwitch ?? 0) == 1 + ? TranslationLoader.lanKeys!.opened!.tr + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.burglarAlarmPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + }))), + SizedBox(height: 10.h), + // 常开模式 + Obx(() => Visibility( + visible: state.lockFeature.value.passageMode == 1 ? true : false, + // visible:true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr, + rightTitle: (state.lockSettingInfo.value.passageMode ?? 0) == 1 + ? TranslationLoader.lanKeys!.opened!.tr + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.normallyOpenModePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + }))), + // 远程开锁 + Obx(() => Visibility( + visible: state.lockFeature.value.remoteUnlock == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.remoteUnlocking!.tr, + rightTitle: (state.lockSettingInfo.value.remoteUnlock ?? 0) == 1 + ? TranslationLoader.lanKeys!.opened!.tr + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.remoteUnlockingPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + }))), + // 重置键 + Obx(() => Visibility( + visible: state.lockFeature.value.resetSwitch == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.resetButton!.tr, + rightTitle: (state.lockSettingInfo.value.resetSwitch ?? 0) == 1 + ? TranslationLoader.lanKeys!.opened!.tr + : TranslationLoader.lanKeys!.closed!.tr, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.resetButtonPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + }))), + SizedBox(height: 10.h), + //---田总新增展示 + // Obx(() => + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.faceUnlocks!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.faceUnlockPage); + })), + // ), + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.messageReminding!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.msgNotificationPage); + })), + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.catEyeSet!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.catEyeSetPage); + })), + // Obx(() => + //自动亮屏已包括至面容开锁模块 + // Visibility( + // visible: true, + // child: CommonItem( + // leftTitel: '自动亮屏', + // rightTitle: "", + // isHaveLine: true, + // isHaveDirection: true, + // action: () {})), + // ), + + // Obx(() => + //感应距离已包括至面容开锁模块 + // Visibility( + // visible: true, + // child: CommonItem( + // leftTitel: '感应距离', + // rightTitle: "", + // isHaveLine: true, + // isHaveDirection: true, + // action: () { + // Toast.show(msg: "功能暂未开放"); + // })), + // ), + // Obx(() => + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.openingDirectionSet!.tr, + rightTitle: "", + isHaveDirection: true, + isHaveLine: true, + action: () { + // Toast.show(msg: "功能暂未开放"); + Get.toNamed(Routers.openDoorDirectionPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })), + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.motorPowerSetting!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + // Toast.show(msg: "功能暂未开放"); + Get.toNamed(Routers.motorPowerPage); + })), + // 支持蓝牙广播(关闭则不能使用蓝牙主动开锁) + Obx(() => Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.bluetoothBroadcast!.tr, + rightTitle: "", + isHaveLine: true, + isHaveRightWidget: true, + rightWidget: _lockBlueBroadcastSwitch()))), + SizedBox(height: 10.h), + //-----新增至此 + // 标记房态 + Obx(() { + var title = ""; + if (state.lockStatus.value.roomStatus == 1) { + title = TranslationLoader.lanKeys!.checkedIn!.tr; + } else if (state.lockStatus.value.roomStatus == 0) { + title = TranslationLoader.lanKeys!.leisure!.tr; + } + return Visibility( + visible: state.lockStatus.value.roomStatus == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.markedHouseState!.tr, + rightTitle: title, + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.markedHouseStatePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })); + }), + // 考勤 + Obx( + () => Visibility( + visible: state.lockFeature.value.attendance == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.checkingIn!.tr, + rightTitle: "", + isHaveLine: true, + isHaveRightWidget: true, + rightWidget: _openCheckInSwitch())), + ), + // 开锁提醒 + Obx( + () => Visibility( + visible: state.lockFeature.value.unlockReminder == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.unlockReminder!.tr, + rightTitle: "", + isHaveLine: false, + isHaveRightWidget: true, + rightWidget: _lockRemindSwitch())), + ), + // APP开锁时是否需联网 + Obx( + () => Visibility( + visible: state.lockFeature.value.appUnlockOnline == 1 ? true : false, + child: CommonItem( + leftTitel: TranslationLoader + .lanKeys!.whetherInternetRequiredWhenUnlocking!.tr, + rightTitle: "", + isHaveLine: false, + isHaveRightWidget: true, + rightWidget: _openLockNeedOnlineSwitch()), + ), + ), + SizedBox(height: 10.h), + // wifi配网 + Obx( + () => Visibility( + visible: state.lockFeature.value.wifi == 1 ? true : false, + child: CommonItem( + leftTitel: + TranslationLoader.lanKeys!.wifiDistributionNetwork!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.configuringWifiPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })), + ), + // Obx(() => + // 锁时间 + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.lockTime!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.lockTimePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })), + // ), + // Obx(() => + // 诊断 + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.diagnose!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.diagnosePage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value + }); + })), + // ), + // Obx(() => + // 上传数据 + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.uploadData!.tr, + rightTitle: "", + isHaveLine: true, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.uploadDataPage); + })), + // ), + // Obx(() => + // Visibility( + // visible: true, + // child: CommonItem( + // leftTitel: TranslationLoader + // .lanKeys!.importOtherLockData!.tr, + // rightTitle: "", + // isHaveLine: true, + // isHaveDirection: true, + // action: () { + // Get.toNamed(Routers.importOtherLockDataPage); + // })), + // ), + // Obx(() => + // 锁升级 + Visibility( + visible: true, + child: CommonItem( + leftTitel: TranslationLoader.lanKeys!.lockEscalation!.tr, + rightTitle: "", + isHaveLine: false, + isHaveDirection: true, + action: () { + Get.toNamed(Routers.lockEscalationPage); + })), + // ), + SizedBox(height: 30.h), + Container( + padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h), + child: SubmitBtn( + btnName: TranslationLoader.lanKeys!.delete!.tr, + isDelete: true, + onClick: () { + // logic.deletUserAction(); + + // logic.deletLockInfoData(); + showDeletAlertDialog(context); + // showDeletPasswordAlertDialog(context); + }), + ), + ]; + + return showWidgetArr; + } + Widget rightText(String rightTitle) { return Text(rightTitle ?? "", textAlign: TextAlign.end, @@ -678,25 +728,7 @@ class _LockSetPageState extends State with RouteAware { ); } - void showDeletAlertDialog( - BuildContext context, - ) { - // showDialog( - // context: context, - // builder: (BuildContext context) { - // return ShowIosTipView( - // title: "提示", - // tipTitle: "删除锁后,所有信息都会一起删除,确定删除锁吗?", - // sureClick: () { - // Navigator.pop(context); - // showDeletPasswordAlertDialog(context); - // }, - // cancelClick: () { - // Navigator.pop(context); - // }, - // ); - // }, - // ); + void showDeletAlertDialog(BuildContext context) { showCupertinoDialog( context: context, builder: (context) { diff --git a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_state.dart b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_state.dart index a49a2fed..a6362fee 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_state.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_state.dart @@ -8,6 +8,7 @@ class LockSetState { final lockFeature = LockFeature().obs; final lockSettingInfo = LockSettingInfo().obs; final lockStatus = LockStatus().obs; + final lockBasicInfo = LockBasicInfo().obs; final lockId = 0.obs; diff --git a/star_lock/lib/main/lockDetail/lcokSet/msgNotification/nDaysUnopened/nDaysUnopened_page.dart b/star_lock/lib/main/lockDetail/lcokSet/msgNotification/nDaysUnopened/nDaysUnopened_page.dart index 241a6716..ea0b3aea 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/msgNotification/nDaysUnopened/nDaysUnopened_page.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/msgNotification/nDaysUnopened/nDaysUnopened_page.dart @@ -1,11 +1,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/style/default_style.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/style/default_style.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/tools/commonItem.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/style/default_style.dart'; import 'package:star_lock/tools/submitBtn.dart'; import '../../../../../app_settings/app_colors.dart'; diff --git a/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_page.dart b/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_page.dart index f807b103..18147155 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_page.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_page.dart @@ -1,9 +1,11 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import '../../../../app_settings/app_colors.dart'; import '../../../../tools/commonItem.dart'; @@ -32,89 +34,91 @@ class _NormallyOpenModePageState extends State { haveBack: true, backgroundColor: AppColors.mainColor), body: Obx(() => ListView( - children: [ - CommonItem( - leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr, - rightTitle: "", - isHaveLine: false, - isHaveRightWidget: true, - rightWidget: - SizedBox(width: 60.w, height: 50.h, child: _normallyOpenModeSwitch())), - SizedBox( - height: 1.h, - ), - Container( - padding: EdgeInsets.only( - left: 30.w, right: 30.w, top: 20.w, bottom: 20.w), - color: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Text( + children: [ + CommonItem( + leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr, + rightTitle: "", + isHaveLine: false, + isHaveRightWidget: true, + rightWidget: SizedBox( + width: 60.w, + height: 50.h, + child: _normallyOpenModeSwitch())), + SizedBox( + height: 1.h, + ), + Container( + padding: EdgeInsets.only( + left: 30.w, right: 30.w, top: 20.w, bottom: 20.w), + color: Colors.white, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Text( TranslationLoader.lanKeys!.normallyOpenModeTip!.tr, style: TextStyle(fontSize: 20.sp), )), - ], - ), - ), - SizedBox( - height: 10.h, - ), - Visibility( - visible: state.isOpenNormallyOpenMode.value, - child: Container( - color: Colors.white, - child: Column( - children: [ - // CommonItem( - // leftTitel: TranslationLoader.lanKeys!.automaticUnLock!.tr, - // rightTitle: "", - // isHaveLine: false, - // isHaveRightWidget: true, - // rightWidget: - // SizedBox(width: 60.w, height: 50.h, child: _autoUnlockSwitch())), - // Container( - // height: 1.h, - // color: AppColors.mainBackgroundColor, - // ), - // Container( - // padding: EdgeInsets.only( - // left: 30.w, right: 30.w, top: 20.w, bottom: 20.w), - // color: Colors.white, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // Expanded( - // child: Text( - // TranslationLoader.lanKeys!.automaticUnLockTip!.tr, - // style: TextStyle(fontSize: 20.sp), - // )), - // ], - // ), - // ), - // Container( - // height: 10.h, - // color: AppColors.mainBackgroundColor, - // ), - topWidget(), - SizedBox( - height: 10.h, - ), - bottomWidget() ], ), + ), + SizedBox( + height: 10.h, + ), + Visibility( + visible: state.isOpenNormallyOpenMode.value, + child: Container( + color: Colors.white, + child: Column( + children: [ + // CommonItem( + // leftTitel: TranslationLoader.lanKeys!.automaticUnLock!.tr, + // rightTitle: "", + // isHaveLine: false, + // isHaveRightWidget: true, + // rightWidget: + // SizedBox(width: 60.w, height: 50.h, child: _autoUnlockSwitch())), + // Container( + // height: 1.h, + // color: AppColors.mainBackgroundColor, + // ), + // Container( + // padding: EdgeInsets.only( + // left: 30.w, right: 30.w, top: 20.w, bottom: 20.w), + // color: Colors.white, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Expanded( + // child: Text( + // TranslationLoader.lanKeys!.automaticUnLockTip!.tr, + // style: TextStyle(fontSize: 20.sp), + // )), + // ], + // ), + // ), + // Container( + // height: 10.h, + // color: AppColors.mainBackgroundColor, + // ), + topWidget(), + SizedBox( + height: 10.h, + ), + bottomWidget() + ], + ), + )), + Obx(() => Container( + margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 30.h), + child: state.isJustForShow.value == true ? Container() :SubmitBtn( + btnName: TranslationLoader.lanKeys!.save!.tr, + onClick: () { + logic.sendAutoLock(); + }), )), - Container( - margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 30.h), - child: SubmitBtn( - btnName: TranslationLoader.lanKeys!.save!.tr, - onClick: () { - logic.sendAutoLock(); - }), - ), - ], - ))); + ], + ))); } Widget topWidget() { @@ -180,9 +184,9 @@ class _NormallyOpenModePageState extends State { } return GestureDetector( onTap: () { - if(state.weekDays.value.contains(index)){ + if (state.weekDays.value.contains(index)) { state.weekDays.value.remove(index); - }else{ + } else { state.weekDays.value.add(index); } state.weekDays.value.sort(); @@ -190,20 +194,26 @@ class _NormallyOpenModePageState extends State { // print("index:$index data:${state.normallyOpenPeriod.value}"); }, child: Obx(() => Container( - width: 40.w, - height: 40.w, - margin: EdgeInsets.all(10.w), - decoration: BoxDecoration( - color: state.weekDays.value.contains(index) ? AppColors.mainColor :Colors.white, - border: Border.all(width: 1, color: AppColors.btnDisableColor), - borderRadius: BorderRadius.circular(30.w), - ), - child: Center( - child: Text( + width: 40.w, + height: 40.w, + margin: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: state.weekDays.value.contains(index) + ? AppColors.mainColor + : Colors.white, + border: Border.all(width: 1, color: AppColors.btnDisableColor), + borderRadius: BorderRadius.circular(30.w), + ), + child: Center( + child: Text( dateStr, - style: TextStyle(fontSize: 20.sp, color: state.weekDays.value.contains(index) ? Colors.white : AppColors.darkGrayTextColor), + style: TextStyle( + fontSize: 20.sp, + color: state.weekDays.value.contains(index) + ? Colors.white + : AppColors.darkGrayTextColor), )), - )), + )), ); } @@ -216,16 +226,16 @@ class _NormallyOpenModePageState extends State { ), Obx(() => CommonItem( leftTitel: - "${TranslationLoader.lanKeys!.normallyOpen!.tr}${TranslationLoader.lanKeys!.time!.tr}", + "${TranslationLoader.lanKeys!.normallyOpen!.tr}${TranslationLoader.lanKeys!.time!.tr}", rightTitle: "", isHaveLine: true, isHaveRightWidget: true, rightWidget: GestureDetector( onTap: () { // 选择全天模式 - if(state.isAllDay.value == 1){ + if (state.isAllDay.value == 1) { state.isAllDay.value = 0; - }else{ + } else { state.isAllDay.value = 1; } setState(() {}); @@ -240,7 +250,9 @@ class _NormallyOpenModePageState extends State { width: 5.w, ), Image.asset( - state.isAllDay.value == 1 ? 'images/icon_round_selet.png': 'images/icon_round_unSelet.png', + state.isAllDay.value == 1 + ? 'images/icon_round_selet.png' + : 'images/icon_round_unSelet.png', width: 30.w, height: 30.w, ), @@ -255,32 +267,34 @@ class _NormallyOpenModePageState extends State { children: [ Obx(() => CommonItem( leftTitel: - "${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}", + "${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}", rightTitle: state.beginTime.value, isHaveDirection: true, isHaveLine: true, action: () { Pickers.showDatePicker(context, mode: DateMode.HM, onConfirm: (p) { - setState(() { - state.beginTimeMinute.value = p.hour!*60 + p.minute!; - state.beginTime.value = "${p.hour}:${p.minute!}"; - }); - }); + setState(() { + state.beginTimeMinute.value = + p.hour! * 60 + p.minute!; + state.beginTime.value = "${p.hour}:${p.minute!}"; + }); + }); })), Obx(() => CommonItem( leftTitel: - "${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}", + "${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}", rightTitle: state.endTime.value, isHaveDirection: true, action: () { Pickers.showDatePicker(context, mode: DateMode.HM, onConfirm: (p) { - setState(() { - state.endTimeMinute.value = p.hour!*60 + p.minute!; - state.endTime.value = "${p.hour}:${p.minute!}"; - }); - }); + setState(() { + state.endTimeMinute.value = + p.hour! * 60 + p.minute!; + state.endTime.value = "${p.hour}:${p.minute!}"; + }); + }); })), Container(height: 10.h), ], diff --git a/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_state.dart b/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_state.dart index c4e9c643..2b5585ba 100644 --- a/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_state.dart +++ b/star_lock/lib/main/lockDetail/lcokSet/normallyOpenMode/normallyOpenMode_state.dart @@ -4,6 +4,8 @@ import '../lockSet/lockSetInfo_entity.dart'; class NormallyOpenModeState{ var lockSetInfoData = LockSetInfoData().obs; + final lockBasicInfo = LockBasicInfo().obs; + var isJustForShow = false.obs;// 是否只是作为展示作用,因为普通用户只是展示,不可修改 // var getPassageModeConfigData = GetPassageModeConfigEntity().obs; var isOpenNormallyOpenMode = false.obs;// 是否开启常开模式 常开模式:1-开启、2-关闭 @@ -20,6 +22,12 @@ class NormallyOpenModeState{ lockSetInfoData.value = map["lockSetInfoData"]; isOpenNormallyOpenMode.value = lockSetInfoData.value.lockSettingInfo!.passageMode! == 1 ? true : false; + if(lockBasicInfo.value.isLockOwner == 1 || lockBasicInfo.value.keyRight == 1){ + isJustForShow.value = false; + }else{ + isJustForShow.value = true; + } + if((isOpenNormallyOpenMode.value == true) && (lockSetInfoData.value.lockSettingInfo!.passageModeConfig!.isNotEmpty)){ isAllDay.value = lockSetInfoData.value.lockSettingInfo!.passageModeConfig![0].isAllDay!; weekDays.value = lockSetInfoData.value.lockSettingInfo!.passageModeConfig![0].weekDays!; diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart index 6f53a39c..bc49eb75 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/blue/io_protocol/io_editUser.dart'; @@ -10,6 +11,7 @@ import 'package:star_lock/blue/io_type.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../blue/blue_manage.dart'; +import '../../../blue/io_protocol/io_addUser.dart'; import '../../../blue/io_protocol/io_getStarLockStatusInfo.dart'; import '../../../blue/io_protocol/io_openLock.dart'; import '../../../blue/io_protocol/io_referEventRecordTime.dart'; @@ -52,6 +54,11 @@ class LockDetailLogic extends BaseGetXController{ if(reply is SenderReferEventRecordTimeReply) { _replyReferEventRecordTime(reply); } + + // 添加用户 + if(reply is AddUserReply) { + _replyAddUserKey(reply); + } }); } @@ -59,7 +66,7 @@ class LockDetailLogic extends BaseGetXController{ Future _replyOpenLock(Reply reply) async { var tokenData = reply.data.sublist(2, 6); var saveStrList = changeIntListToStringList(tokenData); - // print("openDoorToken:$tokenData"); + print("openDoorToken:$tokenData"); Storage.setStringList(saveBlueToken, saveStrList); int status = reply.data[6]; @@ -121,66 +128,6 @@ class LockDetailLogic extends BaseGetXController{ } } - // 编辑用户数据解析 - // Future _replyEditUserKey(Reply reply) async { - // var token = reply.data.sublist(2, 6); - // var saveStrList = changeIntListToStringList(token); - // print("_replyEditUserKeyToken:$token"); - // Storage.setStringList(saveBlueToken, saveStrList); - // - // int status = reply.data[6]; - // print("status:$status"); - // - // switch(status){ - // case 0x00: - // //成功 - // print("${reply.commandType!.typeValue} 数据解析成功"); - // - // break; - // case 0x06: - // //无权限 - // print("${reply.commandType!.typeValue} 需要鉴权"); - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var publicKey = await Storage.getStringList(saveBluePublicKey); - // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // IoSenderManage.senderEditUser( - // lockID:BlueManage().connectDeviceName, - // authUserID:await Storage.getUid(), - // keyID:"1", - // userID:await Storage.getUid(), - // openMode:1, - // keyType:1, - // startDate:0x11223344, - // expireDate:0x11223344, - // role:255, - // password:"123456", - // 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 _replyGetStarLockStatusInfo(Reply reply) async { int status = reply.data[2]; @@ -324,6 +271,78 @@ class LockDetailLogic extends BaseGetXController{ } } + // 添加用户 + Future _replyAddUserKey(Reply reply) async { + var lockId = reply.data.sublist(2, 42); + // print("lockId:$lockId"); + + var token = reply.data.sublist(42, 46); + List strTokenList = changeIntListToStringList(token); + Storage.setStringList(saveBlueToken, strTokenList); + // print("token:$token"); + + int status = reply.data[46]; + // print("status:$status reply.data:${reply.data}"); + + print("status:$status"); + switch(status){ + case 0x00: + //成功 + print("添加用户数据解析成功"); + state.lockUserNo = reply.data[47] + 1; + // updateLockUserNo(); + + if(state.isOpenLockNeedOnline.value == 0){ + openDoorAction(); + }else{ + getLockNetToken(); + } + + break; + case 0x06: + //无权限 + print("需要鉴权"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var publicKey = await Storage.getStringList(saveBluePublicKey); + List publicKeyDataList = changeStringListToIntList(publicKey!); + + IoSenderManage.senderAddUser( + lockID: BlueManage().connectDeviceName, + authUserID:state.senderUserId.toString(), + keyID:state.keyInfos.value.keyId.toString(), + userID:await Storage.getUid(), + openMode:1, + keyType:0, + startDate:DateTime.now().millisecondsSinceEpoch, + expireDate:0x11223344, + role:0, + password:"123456", + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: token + ); + break; + case 0x07: + //无权限 + print("用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("添加用户权限校验错误"); + + break; + default: + //失败 + print("领锁失败"); + + break; + } + } + // 点击开门事件 Future openDoorAction() async { // if(BlueManage().connectDeviceMacAddress.isEmpty){ @@ -365,45 +384,48 @@ class LockDetailLogic extends BaseGetXController{ } // 编辑用户事件 - Future editLockUserAction() async { - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected){ - var publicKey = await Storage.getStringList(saveBluePublicKey); - List publicKeyDataList = changeStringListToIntList(publicKey!); - - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - - var token = await Storage.getStringList(saveBlueToken); - List getTokenList = changeStringListToIntList(token!); - print("openDoorTokenPubToken:$getTokenList"); - - print("publicKey:$publicKey publicKeyDataList:$publicKeyDataList privateKey:$privateKey getPrivateKeyList:$getPrivateKeyList token:$token getTokenList:$getTokenList"); - IoSenderManage.senderEditUser( - lockID:BlueManage().connectDeviceName, - authUserID:await Storage.getUid(), - keyID:"1", - userID:await Storage.getUid(), - openMode:1, - keyType:1, - startDate:0x11223344, - expireDate:0x11223344, - role:255, - password:"123456", - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: getTokenList - ); - } - }); - } + // Future editLockUserAction() async { + // BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { + // if (state == DeviceConnectionState.connected){ + // var publicKey = await Storage.getStringList(saveBluePublicKey); + // List publicKeyDataList = changeStringListToIntList(publicKey!); + // + // var privateKey = await Storage.getStringList(saveBluePrivateKey); + // List getPrivateKeyList = changeStringListToIntList(privateKey!); + // + // var token = await Storage.getStringList(saveBlueToken); + // List getTokenList = changeStringListToIntList(token!); + // print("openDoorTokenPubToken:$getTokenList"); + // + // print("publicKey:$publicKey publicKeyDataList:$publicKeyDataList privateKey:$privateKey getPrivateKeyList:$getPrivateKeyList token:$token getTokenList:$getTokenList"); + // IoSenderManage.senderEditUser( + // lockID:BlueManage().connectDeviceName, + // authUserID:await Storage.getUid(), + // keyID:"1", + // userID:await Storage.getUid(), + // openMode:1, + // keyType:1, + // startDate:0x11223344, + // expireDate:0x11223344, + // role:255, + // password:"123456", + // needAuthor:1, + // publicKey:publicKeyDataList, + // privateKey:getPrivateKeyList, + // token: getTokenList + // ); + // } + // }); + // } // 备用逻辑,进入管理钥匙界面获取锁状态 Future connectBlue(String bluetoothDeviceId, String bluetoothDeviceName) async { // 进来之后首先连接 BlueManage().connect(bluetoothDeviceId, bluetoothDeviceName, connectStateCallBack: (DeviceConnectionState state) async { + if(EasyLoading.isShow){ + EasyLoading.dismiss(); + } if (state == DeviceConnectionState.connected){ var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -449,6 +471,44 @@ class LockDetailLogic extends BaseGetXController{ }, isShowLoading: false); } + // 添加用户(普通用户接收电子钥匙) + Future addUserConnectBlue() async { + // 进来之后首先连接 + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async { + if (deviceConnectionState == DeviceConnectionState.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 getTokenList = [0,0,0,0]; + if(token != null){ + getTokenList = changeStringListToIntList(token); + } + print("BlueManage().connectDeviceName:${BlueManage().connectDeviceName} authUserID:${state.senderUserId.toString()} keyID:${state.keyInfos.value.keyId.toString()} userID:${await Storage.getUid()}"); + IoSenderManage.senderAddUser( + lockID: BlueManage().connectDeviceName, + authUserID:state.senderUserId.toString(), + keyID:state.keyInfos.value.keyId.toString(), + userID:await Storage.getUid(), + openMode:1, + keyType:0, + startDate:DateTime.now().millisecondsSinceEpoch, + expireDate:0x11223344, + role:0, + password:"123456", + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList + ); + } + }, isShowLoading: false); + } + void startScanAction(){ BlueManage().startScan(true, (v){ // print("startScanAllDevice:${v}"); @@ -458,7 +518,7 @@ class LockDetailLogic extends BaseGetXController{ BlueManage().connectDeviceMacAddress = v[knownDeviceIndex].id; connectBlue(v[knownDeviceIndex].id, state.keyInfos.value.bluetooth!.bluetoothDeviceName!); eventBus.fire(ScanAllDeviceFindCurrentDeviceConnectedEvent(v[knownDeviceIndex].serviceUuids[0].toString())); - // BlueManage().stopScan(); + BlueManage().stopScan(); } }); } @@ -468,10 +528,14 @@ class LockDetailLogic extends BaseGetXController{ state.lockState.value = 1; state.animationController.forward(); - if(state.isOpenLockNeedOnline.value == 0){ - openDoorAction(); + if(state.lockUserNo == 0){ + addUserConnectBlue(); }else{ - getLockNetToken(); + if(state.isOpenLockNeedOnline.value == 0){ + openDoorAction(); + }else{ + getLockNetToken(); + } } Future.delayed(const Duration(seconds: 10), () { @@ -500,10 +564,21 @@ class LockDetailLogic extends BaseGetXController{ } } + // 普通用户接收电子钥匙之后 更新锁用户NO + void updateLockUserNo() async { + LockNetTokenEntity entity = await ApiRepository.to.updateLockUserNo(keyId: state.keyInfos.value.keyId.toString(), lockUserNo: state.lockUserNo.toString()); + if (entity.errorCode!.codeIsSuccessful) { + if(state.isOpenLockNeedOnline.value == 0){ + openDoorAction(); + }else{ + getLockNetToken(); + } + } + } + // 查询锁记录最后时间 void getLockRecordLastUploadDataTime() async { - LockOperatingRecordGetLastRecordTimeEntity entity = - await ApiRepository.to.getLockRecordLastUploadDataTime(lockId: state.keyInfos.value.lockId.toString()); + LockOperatingRecordGetLastRecordTimeEntity entity = await ApiRepository.to.getLockRecordLastUploadDataTime(lockId: state.keyInfos.value.lockId.toString()); if (entity.errorCode!.codeIsSuccessful) { senderReferEventRecordTime(entity.data!.operateDate!~/1000); } @@ -542,9 +617,18 @@ class LockDetailLogic extends BaseGetXController{ // TODO: implement onReady super.onReady(); print("onReady()"); + _initReplySubscription(); initLockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceAction(); + EasyLoading.show(status: "正在连接设备,请稍等。", maskType: EasyLoadingMaskType.none, dismissOnTap: true); + Future.delayed(const Duration(seconds: 12), () { + if(EasyLoading.isShow){ + EasyLoading.dismiss(); + Toast.show(msg: "连接设备失败,请确保在设备附近,设备未被连接,设备已打开"); + } + }); + if(Platform.isIOS){ print("有蓝牙权限开始扫描"); startScanAction(); @@ -576,16 +660,6 @@ class LockDetailLogic extends BaseGetXController{ // factoryDataResetAction(); } - - @override - void onClose() { - // TODO: implement onClose - print("锁详情界面销毁了"); - - _replySubscription.cancel(); - _lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent!.cancel(); - } - ///请求录音相机权限 Future getMicrophonePermission() async { // You can request multiple permissions at once. @@ -604,4 +678,12 @@ class LockDetailLogic extends BaseGetXController{ return false; } + @override + void onClose() { + // TODO: implement onClose + print("锁详情界面销毁了"); + + _replySubscription.cancel(); + _lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent!.cancel(); + } } \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_main_page.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_main_page.dart index 2bf1d1e1..aafce16f 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_main_page.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_main_page.dart @@ -3,15 +3,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../app_settings/app_colors.dart'; -import '../../../network/api_repository.dart'; import '../../../tools/titleAppBar.dart'; import '../../../translations/trans_lib.dart'; -// import '../../lockMian/entity/lockInfoEntity.dart'; import '../../lockMian/entity/lockListInfo_entity.dart'; import 'lockDetail_page.dart'; class LockDetailMainPage extends StatefulWidget { - const LockDetailMainPage({Key? key}) : super(key: key); @override @@ -19,19 +16,6 @@ class LockDetailMainPage extends StatefulWidget { } class _LockDetailMainPageState extends State { - - // void getLockInfo() async{ - // var entity = await ApiRepository.to.getLockInfo( - // lastUpdateDate:DateTime.now().millisecondsSinceEpoch.toString(), - // pageNo:"1", - // ); - // if(entity.errorCode!.codeIsSuccessful){ - // - // }else{ - // - // } - // } - @override void initState() { // TODO: implement initState diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart index 9b9eea49..02bfbd1f 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart @@ -25,8 +25,7 @@ class LockDetailPage extends StatefulWidget { State createState() => _LockDetailPageState(); } -class _LockDetailPageState extends State - with TickerProviderStateMixin { +class _LockDetailPageState extends State with TickerProviderStateMixin, RouteAware { // with RouteAware final logic = Get.put(LockDetailLogic()); final state = Get.find().state; @@ -38,6 +37,8 @@ class _LockDetailPageState extends State super.initState(); state.keyInfos.value = widget.lockListInfoItemEntity; + state.lockUserNo = state.keyInfos.value.lockUserNo!; + state.senderUserId = state.keyInfos.value.senderUserId!; state.isAttendance.value = state.keyInfos.value.lockSetting!.attendance!; state.isOpenLockNeedOnline.value = state.keyInfos.value.lockSetting!.appUnlockOnline!; state.electricQuantity.value = state.keyInfos.value.electricQuantity!; @@ -95,10 +96,8 @@ class _LockDetailPageState extends State SizedBox( width: 1.sw - 120.w * 2, child: Center( - child: Text( - widget.lockListInfoItemEntity!.lockAlias!, - style: - TextStyle(fontSize: 22.sp, fontWeight: FontWeight.w400), + child: + Text(widget.lockListInfoItemEntity.lockAlias!, style: TextStyle(fontSize: 22.sp, fontWeight: FontWeight.w400), ))), Positioned( child: Obx(() => Row( @@ -125,14 +124,11 @@ class _LockDetailPageState extends State child: Obx(() => Stack( children: [ Image.asset( - state.lockState.value == 4 - ? 'images/main/icon_main_openLockBtn_grey.png' - : 'images/main/icon_main_openLockBtn_center.png', + state.lockState.value == 4 ? 'images/main/icon_main_openLockBtn_grey.png' : 'images/main/icon_main_openLockBtn_center.png', width: 330.w, height: 330.w, ), - (state.lockState.value == 1 || - state.lockState.value == 3) + (state.lockState.value == 1 || state.lockState.value == 3) ? buildRotationTransition() : Positioned( child: Image.asset( @@ -268,11 +264,42 @@ class _LockDetailPageState extends State crossAxisSpacing: 20.w, mainAxisSpacing: 0.h, physics: const NeverScrollableScrollPhysics(), - children: getShowWidget()), + children: getBottomWidget()), ); } - List getShowWidget() { + // 根据权限显示不同的底部按钮 + List getBottomWidget(){ + if(state.keyInfos.value.isLockOwner == 1 || state.keyInfos.value.keyRight == 1){ + // 超级管理员、授权管理员 + return getAllWidget(); + }else{ + return getNormalWidget(); + } + } + + // 普通用户 + List getNormalWidget() { + var showWidgetArr = [ + // 操作记录 + bottomItem('images/main/icon_main_operatingRecord.png', + TranslationLoader.lanKeys!.operatingRecord!.tr, () { + Get.toNamed(Routers.lockOperatingRecordPage, + arguments: {"keyInfo": widget.lockListInfoItemEntity}); + }), + + // 设置 + bottomItem('images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr, () { + BlueManage().stopScan(); + Get.toNamed(Routers.lockSetPage, + arguments: {"lockId": widget.lockListInfoItemEntity.lockId}); + }), + ]; + return showWidgetArr; + } + + // 授权管理员、超级管理员字段 + List getAllWidget() { var showWidgetArr = []; // 考勤 if (state.isAttendance.value == 1) { @@ -301,9 +328,8 @@ class _LockDetailPageState extends State if (state.keyInfos.value.lockFeature!.icCard == 1) { showWidgetArr.add(bottomItem('images/main/icon_main_icCard.png', TranslationLoader.lanKeys!.card!.tr, () { - Get.toNamed(Routers.otherTypeKeyListPage, arguments: { + Get.toNamed(Routers.cardListPage, arguments: { "lockId": widget.lockListInfoItemEntity.lockId, - "fromType": 0 }); })); } @@ -312,9 +338,8 @@ class _LockDetailPageState extends State if (state.keyInfos.value.lockFeature!.fingerprint == 1) { showWidgetArr.add(bottomItem('images/main/icon_main_fingerprint.png', TranslationLoader.lanKeys!.fingerprint!.tr, () { - Get.toNamed(Routers.otherTypeKeyListPage, arguments: { + Get.toNamed(Routers.fingerprintListPage, arguments: { "lockId": widget.lockListInfoItemEntity.lockId, - "fromType": 1 }); })); } @@ -323,10 +348,7 @@ class _LockDetailPageState extends State if (state.keyInfos.value.lockFeature!.bluetoothRemoteControl == 1) { showWidgetArr.add(bottomItem('images/main/icon_main_remoteControl.png', TranslationLoader.lanKeys!.remoteControl!.tr, () { - Get.toNamed(Routers.otherTypeKeyListPage, arguments: { - "lockId": widget.lockListInfoItemEntity.lockId, - "fromType": 2 - }); + Get.toNamed(Routers.remoteControlListPage); })); } @@ -334,9 +356,8 @@ class _LockDetailPageState extends State if (state.keyInfos.value.lockFeature!.d3Face == 1) { showWidgetArr.add( bottomItem('images/main/icon_face.png', TranslationLoader.lanKeys!.humanFace!.tr, () { - Get.toNamed(Routers.otherTypeKeyListPage, arguments: { + Get.toNamed(Routers.faceList, arguments: { "lockId": widget.lockListInfoItemEntity.lockId, - "fromType": 3 }); // Toast.show(msg: "功能暂未开放"); // tokNative('videoTalk', @@ -477,22 +498,33 @@ class _LockDetailPageState extends State // TODO: implement dispose /// 取消路由订阅 // AppRouteObserver().routeObserver.unsubscribe(this); + state.animationController.dispose(); super.dispose(); + BlueManage().stopScan(); + BlueManage().disconnect(BlueManage().connectDeviceMacAddress); } /// @override - void didPush() {} + void didPush() { + print("LockDetailPage didPush"); + } /// Called when the current route has been popped off. @override - void didPop() {} + void didPop() { + print("LockDetailPage didPop"); + } /// Called when the current route has been popped off. @override - void didPopNext() {} + void didPopNext() { + print("LockDetailPage didPopNext"); + } /// Called when the current route has been popped off. @override - void didPushNext() {} + void didPushNext() { + print("LockDetailPage didPushNext"); + } } diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart index fcb5db03..878d3fde 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart @@ -1,5 +1,4 @@ - import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -18,6 +17,8 @@ class LockDetailState { Rx keyInfos = LockListInfoItemEntity().obs; String lockNetToken = ""; + var lockUserNo = 0; + var senderUserId = 0; var isAttendance = 0.obs;// 是否开启考勤 var isOpenLockNeedOnline = 0.obs; // APP开锁时是否需联网 diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_logic.dart b/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_logic.dart deleted file mode 100644 index 6550e17e..00000000 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeAddKey/otherTypeAddKey_logic.dart +++ /dev/null @@ -1,188 +0,0 @@ -import 'dart:math'; - -import 'package:get/get.dart'; - -import '../../../../appRouters.dart'; -import '../../../../network/api_repository.dart'; -import '../../../../tools/baseGetXController.dart'; -import '../../../../tools/toast.dart'; -import 'otherTypeAddKey_state.dart'; - -class OtherTypeAddKeyLogic extends BaseGetXController { - OtherTypeAddKeyState state = OtherTypeAddKeyState(); - - // 添加指纹 - void addFingerprintsData() async { - var fingerprintType = 0; // 永久:1;限时2,单次3,循环:4 - var startDate = ""; - var endDate = ""; - if (state.seletType.value == "0") { - fingerprintType = 1; - } else if (state.seletType.value == "1") { - fingerprintType = 2; - if (state.beginTimeTimestamp.value.isEmpty) { - Toast.show(msg: "请选择开始时间"); - return; - } - if (state.endTimeTimestamp.value.isEmpty) { - Toast.show(msg: "请选择开始时间"); - return; - } - - // if(DateTime.now().millisecondsSinceEpoch > int.parse(state.beginTimeTimestamp.value)){ - // Toast.show(msg: "生效时间要大于当前时间"); - // return; - // } - - print( - "fasdfasdfasdf:${int.parse(state.beginTimeTimestamp.value)} == ${int.parse(state.endTimeTimestamp.value)}"); - if (int.parse(state.beginTimeTimestamp.value) >= - int.parse(state.endTimeTimestamp.value)) { - Toast.show(msg: "失效时间要大于生效时间"); - return; - } - - startDate = state.beginTimeTimestamp.value; - endDate = state.endTimeTimestamp.value; - } else if (state.seletType.value == "2") { - if (state.effectiveDateTime.value <= 0) { - Toast.show(msg: "请选择生效时间"); - return; - } - if (state.failureDateTime.value <= 0) { - Toast.show(msg: "请选择失效时间"); - return; - } - - if (state.weekdaysList.value.isEmpty) { - Toast.show(msg: "请选择有效日"); - return; - } - - // if(DateTime.now().millisecondsSinceEpoch >= state.effectiveDateTime.value){ - // Toast.show(msg: "生效时间要大于当前时间"); - // return; - // } - - if (state.effectiveDateTime.value >= state.failureDateTime.value) { - Toast.show(msg: "失效时间要大于生效时间"); - return; - } - startDate = state.effectiveDateTime.value.toString(); - endDate = state.failureDateTime.value.toString(); - fingerprintType = 4; - } - - print("addOtherType startDate:$startDate endDate:$endDate"); - switch (state.lockType.value) { - case 0: - // 卡 - Get.toNamed(Routers.addICCardPage, arguments: { - "lockId": state.lockId.value, - "endDate": endDate, - "addType": "1", - "cardName": state.nameController.text, - "cardNumber": - (Random().nextInt(100000000) + 10000000).floor().toString(), - "cardType": fingerprintType.toString(), - "isCoerced": state.isStressFingerprint.value ? "1" : "2", - "startDate": startDate, - "weekDay": state.weekdaysList.value, - "fromType": state.fromType.value, - }); - - // var entity = await ApiRepository.to.addICCardData( - // lockId: state.lockId.value.toString(), - // endDate: endDate, - // cardName: state.nameController.text, - // cardNumber: (Random().nextInt(100000000) + 10000000).floor().toString(), - // cardType: fingerprintType.toString(), - // addType:"1", - // startDate: startDate, - // isCoerced: state.isStressFingerprint.value ? "1" : "2", - // weekDay: state.weekdaysList.value, - // ); - // if(entity.errorCode!.codeIsSuccessful){ - // Toast.show(msg: "添加成功"); - // Get.back(result: "addScuess"); - // } - - break; - case 1: - // 指纹 - Get.toNamed(Routers.addFingerprintPage, arguments: { - "lockId": state.lockId.value, - "endDate": endDate, - "addType": "1", - "fingerprintName": state.nameController.text, - "fingerprintNumber": "123456", - "fingerprintType": fingerprintType.toString(), - "isCoerced": state.isStressFingerprint.value ? "1" : "2", - "startDate": startDate, - "weekDay": state.weekdaysList.value, - "fromType": state.fromType.value, - }); - - /* 根据田总需求 无需tips页面 直接跳转到添加页面 - Get.toNamed(Routers.addFingerprintTipPage, arguments: { - "lockId": state.lockId.value, - "endDate": endDate, - "addType": "1", - "fingerprintName": state.nameController.text, - "fingerprintNumber": "123456", - "fingerprintType": fingerprintType.toString(), - "isCoerced": state.isStressFingerprint.value ? "1" : "2", - "startDate": startDate, - "weekDay": state.weekdaysList.value, - "fromType": state.fromType.value, - }); - */ - - // var entity = await ApiRepository.to.addFingerprintsData( - // lockId: state.lockId.value.toString(), - // endDate: endDate, - // addType:"1", - // fingerprintName: state.nameController.text, - // fingerprintNumber: (Random().nextInt(100000000) + 10000000).floor().toString(), - // fingerprintType: fingerprintType.toString(), - // isCoerced: state.isStressFingerprint.value ? "1" : "2", - // startDate: startDate, - // weekDay: state.weekdaysList.value, - // ); - // if(entity.errorCode!.codeIsSuccessful){ - // Toast.show(msg: "添加成功"); - // Get.back(result: "addScuess"); - // } - break; - case 2: - // 遥控 - - break; - - case 3: - // 人脸 - Get.toNamed(Routers.addFaceTipPage); - - break; - default: - break; - } - } - - @override - void onReady() { - // TODO: implement onReady - super.onReady(); - } - - @override - void onInit() { - // TODO: implement onInit - super.onInit(); - } - - @override - void onClose() { - // TODO: implement onClose - } -} diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_state.dart b/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_state.dart deleted file mode 100644 index 8d2fcb85..00000000 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyDetail/otherTypeKeyDetail_state.dart +++ /dev/null @@ -1,62 +0,0 @@ - -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; - -import '../../../../tools/dateTool.dart'; -import '../otherTypeKeyList/fingerprintListData_entity.dart'; - -class OtherTypeKeyDetailState{ - final fingerprintItemData = FingerprintItemData().obs; - final type = 0.obs;// 0卡 1指纹 2遥控 - - final TextEditingController changeNameController = TextEditingController(); - - final typeNumber = "".obs;// 指纹号 - final typeName = "".obs;// 指纹名字 - var effectiveDateTime = 0.obs;// 生效时间 - var failureDateTime = 0.obs;// 失效时间 - final keyType = 0.obs;// 永久:1;限时2,单次3,循环:4 - var weekDay = [].obs;// 有效日 - var adder = "".obs;// 添加者 - var addTime = 0.obs;// 添加时间 - var keyId = 0.obs;// 添加时间 - - final isStressFingerprint = false.obs; - OtherTypeKeyDetailState() { - Map map = Get.arguments; - type.value = map["type"]; - if(type.value == 0){ - // 0卡 - fingerprintItemData.value = map["fingerprintItemData"]; - keyId.value = fingerprintItemData.value.cardId!; - typeNumber.value = fingerprintItemData.value.cardNumber!; - typeName.value = fingerprintItemData.value.cardName!; - changeNameController.text = typeName.value; - effectiveDateTime.value = fingerprintItemData.value.startDate!; - failureDateTime.value = fingerprintItemData.value.endDate!; - keyType.value = fingerprintItemData.value.cardType!; - adder.value = fingerprintItemData.value.senderUsername!; - addTime.value = fingerprintItemData.value.createDate!; - isStressFingerprint.value = fingerprintItemData.value.isCoerced! == 2 ? true : false; - weekDay.value = fingerprintItemData.value.weekDay!; - }else if(type.value == 1){ - // 1指纹 - fingerprintItemData.value = map["fingerprintItemData"]; - keyId.value = fingerprintItemData.value.fingerprintId!; - typeNumber.value = fingerprintItemData.value.fingerprintNumber!; - typeName.value = fingerprintItemData.value.fingerprintName!; - changeNameController.text = typeName.value; - effectiveDateTime.value = fingerprintItemData.value.startDate!; - failureDateTime.value = fingerprintItemData.value.endDate!; - keyType.value = fingerprintItemData.value.fingerprintType!; - adder.value = fingerprintItemData.value.senderUsername!; - addTime.value = fingerprintItemData.value.createDate!; - isStressFingerprint.value = fingerprintItemData.value.isCoerced! == 2 ? true : false; - weekDay.value = fingerprintItemData.value.weekDay!; - }else if(type.value == 2){ - // 2遥控 - - } - - } -} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_page.dart b/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_page.dart deleted file mode 100644 index 690ab991..00000000 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyList/otherTypeKeyList_page.dart +++ /dev/null @@ -1,486 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:get/get.dart'; - -import '../../../../appRouters.dart'; -import '../../../../app_settings/app_colors.dart'; -import '../../../../tools/dateTool.dart'; -import '../../../../tools/left_slide_actions.dart'; -import '../../../../tools/noData.dart'; -import '../../../../tools/showIosTipView.dart'; -import '../../../../tools/storage.dart'; -import '../../../../tools/submitBtn.dart'; -import '../../../../tools/titleAppBar.dart'; -import '../../../../tools/toast.dart'; -import '../../../../translations/trans_lib.dart'; -import 'fingerprintListData_entity.dart'; -import 'otherTypeKeyList_logic.dart'; - -class OtherTypeKeyListPage extends StatefulWidget { - const OtherTypeKeyListPage({Key? key}) : super(key: key); - - @override - State createState() => _OtherTypeKeyListPageState(); -} - -class _OtherTypeKeyListPageState extends State { - final logic = Get.put(OtherTypeKeyListLogic()); - final state = Get.find().state; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColors.mainBackgroundColor, - appBar: TitleAppBar( - barTitle: getAppBarTitle(state.fromType.value), - 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.seletLockTypePage); - Toast.show(msg: "演示模式"); - } - }, - ), - ], - ), - body: Column( - children: [ - _searchWidget(), - SizedBox( - height: 20.h, - ), - Expanded(child: _buildMainUI(state.fromType.value)), - AddBottomWhiteBtn( - btnName: - '${TranslationLoader.lanKeys!.add!.tr}${getAppBarTitle(state.fromType.value)}', - onClick: () async { - var data = - await Get.toNamed(Routers.otherTypeKeyManagePage, arguments: { - "lockId": state.lockId.value, - "keyType": state.fromType.value, - "fromType": 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 - }); - if (data != null) { - switch (state.fromType.value) { - case 0: - // 卡 - logic.getICCardListData(); - break; - case 1: - // 指纹 - logic.getFingerprintsListData(); - break; - case 2: - // 遥控 - - break; - case 3: - // 人脸 - - break; - default: - break; - } - } - }, - ), - SizedBox( - height: 64.h, - ) - ], - ), - ); - } - - String getAppBarTitle(int type) { - String title = ""; - switch (type) { - case 0: - title = TranslationLoader.lanKeys!.card!.tr; - break; - case 1: - title = TranslationLoader.lanKeys!.fingerprint!.tr; - break; - case 2: - title = TranslationLoader.lanKeys!.remoteControl!.tr; - break; - case 3: - title = TranslationLoader.lanKeys!.face!.tr; - break; - default: - break; - } - return title; - } - - Widget _searchWidget() { - return Container( - height: 60.h, - margin: EdgeInsets.only(top: 20.w, left: 20.w, right: 10.w), - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(5)), - child: TextField( - //输入框一行 - maxLines: 1, - controller: state.searchController, - autofocus: false, - onChanged: (value) { - print("onChanged:$value"); - }, - onEditingComplete: () { - print("onEditingComplete:"); - }, - onSubmitted: (value) { - switch (state.fromType.value) { - case 0: - // 卡 - logic.getICCardListData(); - break; - case 1: - // 指纹 - logic.getFingerprintsListData(); - break; - case 2: - // 遥控 - - break; - case 3: - // 人脸 - - break; - default: - break; - } - }, - decoration: InputDecoration( - //输入里面输入文字内边距设置 - contentPadding: const EdgeInsets.only( - top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), - hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, - hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), - //不需要输入框下划线 - border: InputBorder.none, - //左边图标设置 - icon: Padding( - padding: EdgeInsets.only( - top: 20.h, bottom: 20.h, right: 20.w, left: 10.w), - child: Image.asset( - 'images/main/icon_main_search.png', - width: 40.w, - height: 40.w, - ), - ), - ), - ), - ); - } - - Widget _buildMainUI(int type) { - // String typeImgName = ""; - // if (type == 0) { - // //卡 - // typeImgName = 'images/icon_card.png'; - // } else if (type == 1) { - // //指纹 - // typeImgName = 'images/icon_fingerprint.png'; - // } else if (type == 2) { - // //遥控 - // typeImgName = 'images/icon_card.png'; - // } - - return Obx(() => state.fingerprintItemListData.value.isNotEmpty - ? ListView.separated( - itemCount: state.fingerprintItemListData.value.length, - itemBuilder: (c, index) { - FingerprintItemData fingerprintItemData = - state.fingerprintItemListData.value[index]; - switch (state.fromType.value) { - case 0: - // 卡 - if (index < state.fingerprintItemListData.value.length) { - return LeftSlideActions( - key: Key(fingerprintItemData.cardName!), - actionsWidth: 60, - actions: [ - _buildDeleteBtn(fingerprintItemData.cardId.toString()), - ], - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(1)), - ), - child: _keyItem( - 'images/icon_card.png', - fingerprintItemData.cardName!, - fingerprintItemData.cardType! == 1 - ? "永久" - : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", - () async { - var data = await Get.toNamed( - Routers.otherTypeKeyDetailPage, - arguments: { - "fingerprintItemData": fingerprintItemData, - "type": type, - }); - if (data != null) { - logic.getICCardListData(); - } - }), - ); - } - return const SizedBox.shrink(); - - return _keyItem( - 'images/icon_card.png', - fingerprintItemData.cardName!, - fingerprintItemData.cardType! == 1 - ? "永久" - : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", - () async { - var data = await Get.toNamed(Routers.otherTypeKeyDetailPage, - arguments: { - "fingerprintItemData": fingerprintItemData, - "type": type, - }); - if (data != null) { - logic.getICCardListData(); - } - }); - break; - case 1: - // 指纹 - if (index < state.fingerprintItemListData.value.length) { - return LeftSlideActions( - key: Key(fingerprintItemData.fingerprintName!), - actionsWidth: 60, - actions: [ - _buildDeleteBtn( - fingerprintItemData.fingerprintId.toString()), - ], - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(1)), - ), - child: _keyItem( - 'images/icon_fingerprint.png', - fingerprintItemData.fingerprintName!, - fingerprintItemData.fingerprintType! == 1 - ? "永久" - : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", - () async { - var data = await Get.toNamed( - Routers.otherTypeKeyDetailPage, - arguments: { - "fingerprintItemData": fingerprintItemData, - "type": type, - }); - if (data != null) { - logic.getFingerprintsListData(); - } - }), - ); - } - return const SizedBox.shrink(); - - return _keyItem( - 'images/icon_fingerprint.png', - fingerprintItemData.fingerprintName!, - fingerprintItemData.fingerprintType! == 1 - ? "永久" - : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", - () async { - var data = await Get.toNamed(Routers.otherTypeKeyDetailPage, - arguments: { - "fingerprintItemData": fingerprintItemData, - "type": type, - }); - if (data != null) { - logic.getFingerprintsListData(); - } - }); - break; - case 2: - // 遥控 - - break; - default: - break; - } - }, - separatorBuilder: (BuildContext context, int index) { - return const Divider( - height: 1, - color: AppColors.greyLineColor, - ); - }, - ) - : const NoData()); - } - - Widget _buildDeleteBtn(String idStr) { - return GestureDetector( - onTap: () { - // 省略: 弹出是否删除的确认对话框。 - showIosTipViewDialog(context, idStr); - }, - 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, String keyId) { - showDialog( - context: context, - builder: (BuildContext context) { - return ShowIosTipView( - title: "提示", - tipTitle: "确定要删除吗?", - sureClick: () async { - Get.back(); - String? idStr = await Storage.getUid(); - switch (state.fromType.value) { - case 0: - // 卡 - state.isDeletICCardData = true; - logic.senderAddICCard(keyId, idStr ?? "", 0); - break; - case 1: - // 指纹 - state.isDeletFingerprintData = true; - logic.senderAddFingerprint(keyId, idStr ?? "", 0); - break; - case 2: - // 遥控 - - break; - default: - break; - } - }, - cancelClick: () { - Get.back(); - }, - ); - }, - ); - } - - Widget _keyItem(String lockTypeIcon, String lockTypeTitle, 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.start, - children: [ - Text(lockTypeTitle, - style: TextStyle( - fontSize: 24.sp, color: AppColors.blackColor)), - ], - ), - SizedBox(height: 5.h), - Container( - child: 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); - switch (state.fromType.value) { - case 0: - // 卡 - state.isDeletICCardData = true; - logic.senderAddICCard("1", "DeleteAll!@#", 255); - break; - case 1: - // 指纹 - // logic.deletAllFingerprintsData(); - state.isDeletFingerprintData = true; - logic.senderAddFingerprint("1", "DeleteAll!@#", 255); - break; - case 2: - // 遥控 - - break; - default: - break; - } - }, - ), - ], - ); - }, - ); - } -} diff --git a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_page.dart b/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_page.dart deleted file mode 100644 index e2819ad9..00000000 --- a/star_lock/lib/main/lockDetail/otherTypeKey/otherTypeKeyManage/otherTypeKeyManage_page.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:star_lock/blue/io_tool/io_manager.dart'; - -import '../../../../app_settings/app_colors.dart'; -import '../../../../tools/titleAppBar.dart'; -import '../../../../translations/trans_lib.dart'; -import 'otherTypeKeyManage_tabbar.dart'; - -class OtherTypeKeyManagePage extends StatefulWidget { - const OtherTypeKeyManagePage({Key? key}) : super(key: key); - - @override - State createState() => _OtherTypeKeyManagePageState(); -} - -class _OtherTypeKeyManagePageState extends State { - var index = 0; - - @override - Widget build(BuildContext context) { - // 0卡 1指纹 2钥匙 - Map map = Get.arguments; - var lockId = map["lockId"]; - var lockKeyType = map["keyType"]; - 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}${getAppBarTitle(lockKeyType)}", - haveBack: true, - backgroundColor: AppColors.mainColor), - body: Column( - children: [ - OtherTypeKeyManageTabbar(initialIndex: index, lockType: lockKeyType, lockId: lockId, fromType: fromType, fromTypeTwoStaffName:fromTypeTwoStaffName), - ], - ), - ); - } - - String getAppBarTitle(int type) { - String title = ""; - switch (type) { - case 0: - title = TranslationLoader.lanKeys!.card!.tr; - break; - case 1: - title = TranslationLoader.lanKeys!.fingerprint!.tr; - break; - case 2: - title = TranslationLoader.lanKeys!.remoteControl!.tr; - break; - default: - break; - } - return title; - } -} diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart new file mode 100644 index 00000000..04a6c0d3 --- /dev/null +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart @@ -0,0 +1,38 @@ +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_state.dart'; +import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart'; +import 'package:star_lock/network/api_repository.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/toast.dart'; + +class PasswordKeyDetailLogic extends BaseGetXController { + final PasswordKeyDetailState state = PasswordKeyDetailState(); + + //删除密码请求 deleteType:1-蓝牙 2-网关 + Future deletePwdRequest() async { + PasswordKeyEntity entity = await ApiRepository.to.deleteKeyboardPwd( + state.itemData.value.lockId.toString(), + state.itemData.value.keyboardPwdId.toString(), + 1); + if (entity.errorCode!.codeIsSuccessful) { + Toast.show(msg: "删除成功"); + Get.back(); + } + } + + //更新密码请求 + Future updatePwdRequest() async { + PasswordKeyEntity entity = await ApiRepository.to.updatePasswordKey( + state.itemData.value.lockId.toString(), + state.itemData.value.keyboardPwdId.toString(), + state.inputNameController.text, + state.inputPwdController.text, + '', + '', + ''); + if (entity.errorCode!.codeIsSuccessful) { + Toast.show(msg: "修改成功"); + Get.back(); + } + } +} diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart index 02532b10..a175268a 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart @@ -2,12 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart'; import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyList/passwordKeyListEntity.dart'; -import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart'; -import 'package:star_lock/network/api_repository.dart'; -import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/showTFView.dart'; -import 'package:star_lock/tools/toast.dart'; import '../../../../appRouters.dart'; import '../../../../app_settings/app_colors.dart'; @@ -25,25 +22,12 @@ class PasswordKeyDetailPage extends StatefulWidget { } class _PasswordKeyDetailPageState extends State { - PasswordKeyListItem itemData = PasswordKeyListItem(); - late TextEditingController _inputPwdController; - late TextEditingController _inputNameController; static const methodChannel = MethodChannel('talkPlugin'); - - @override - void initState() { - super.initState(); - - _inputPwdController = TextEditingController(); - _inputNameController = TextEditingController(); - } + final logic = Get.put(PasswordKeyDetailLogic()); + final state = Get.find().state; @override Widget build(BuildContext context) { - dynamic obj = ModalRoute.of(context)?.settings.arguments; - if (obj != null && (obj["itemData"] != null)) { - itemData = obj["itemData"]; - } return Scaffold( backgroundColor: AppColors.mainBackgroundColor, appBar: TitleAppBar( @@ -68,45 +52,52 @@ class _PasswordKeyDetailPageState extends State { children: [ CommonItem( leftTitel: TranslationLoader.lanKeys!.password!.tr, - rightTitle: _inputPwdController.text.isNotEmpty - ? _inputPwdController.text - : itemData.keyboardPwd, + rightTitle: state.inputPwdController.text.isNotEmpty + ? state.inputPwdController.text + : state.itemData.value.keyboardPwd, isHaveDirection: true, isHaveLine: true, action: () { - showCupertinoAlertDialog(context, _inputPwdController); + showCupertinoAlertDialog(context, state.inputPwdController); }), CommonItem( leftTitel: TranslationLoader.lanKeys!.name!.tr, - rightTitle: _inputNameController.text.isNotEmpty - ? _inputNameController.text - : itemData.keyboardPwdName, + rightTitle: state.inputNameController.text.isNotEmpty + ? state.inputNameController.text + : state.itemData.value.keyboardPwdName, isHaveDirection: true, isHaveLine: true, action: () { - showCupertinoAlertDialog(context, _inputNameController); + showCupertinoAlertDialog( + context, state.inputNameController); }), CommonItem( leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, - rightTitle: "永久", + rightTitle: getUseDateStr(), isHaveDirection: true, + allHeight: + state.itemData.value.keyboardPwdType == 3 ? 90.h : 65.h, action: () { + if (state.itemData.value.keyboardPwdType! > 4 && + state.itemData.value.keyboardPwdType! < 15) { + return; + } Navigator.pushNamed( context, Routers.electronicKeyDetailChangeDate, arguments: { - 'lockId': itemData.lockId.toString(), - 'pwdId': itemData.keyboardPwdId.toString() + 'lockId': state.itemData.value.lockId.toString(), + 'pwdId': state.itemData.value.keyboardPwdId.toString() }); }), Container(height: 10.h), CommonItem( leftTitel: TranslationLoader.lanKeys!.sender!.tr, - rightTitle: itemData.senderUsername, + rightTitle: state.itemData.value.senderUsername, isHaveLine: true, action: () {}), CommonItem( leftTitel: TranslationLoader.lanKeys!.senderTime!.tr, - rightTitle: getSenderDate(itemData), + rightTitle: getSenderDate(state.itemData.value), action: () {}), Container(height: 10.h), CommonItem( @@ -116,8 +107,8 @@ class _PasswordKeyDetailPageState extends State { action: () { Navigator.pushNamed(context, Routers.keyOperationRecordPage, arguments: { - 'lockId': itemData.lockId.toString(), - 'keyId': itemData.keyboardPwdId.toString() + 'lockId': state.itemData.value.lockId.toString(), + 'keyId': state.itemData.value.keyboardPwdId.toString() }); }), Container(height: 40.h), @@ -129,10 +120,10 @@ class _PasswordKeyDetailPageState extends State { // backgroundColor: Colors.white, side: BorderSide(width: 1, color: AppColors.mainColor)), onPressed: () { - Navigator.pushNamed(context, Routers.otherTypeKeyManagePage, arguments: { - "lockId": itemData.lockId, - "fromType": 0 - }); + Navigator.pushNamed(context, Routers.cardListPage, + arguments: { + "lockId": state.itemData.value.lockId, + }); }, child: Text( '设置卡', @@ -151,13 +142,15 @@ class _PasswordKeyDetailPageState extends State { // backgroundColor: Colors.white, side: BorderSide(width: 1, color: AppColors.mainColor)), onPressed: () { - Navigator.pushNamed( - context, Routers.otherTypeKeyManagePage,arguments: { - "lockId": itemData.lockId, - "fromType": 1 - }); + Navigator.pushNamed(context, Routers.fingerprintListPage, + arguments: { + "lockId": state.itemData.value.lockId, + }); }, - child: Text('设置指纹', style: TextStyle(color: AppColors.mainColor, fontSize: 24.sp), + child: Text( + '设置指纹', + style: TextStyle( + color: AppColors.mainColor, fontSize: 24.sp), )), ), SizedBox( @@ -171,10 +164,11 @@ class _PasswordKeyDetailPageState extends State { // backgroundColor: Colors.white, side: BorderSide(width: 1, color: AppColors.mainColor)), onPressed: () { - Navigator.pushNamed(context, Routers.otherTypeKeyManagePage, arguments: { - "lockId": itemData.lockId, - "fromType": 2 - }); + Navigator.pushNamed( + context, Routers.remoteControlListPage, + arguments: { + "lockId": state.itemData.value.lockId, + }); }, child: Text( '设置遥控', @@ -200,6 +194,83 @@ class _PasswordKeyDetailPageState extends State { )); } + //使用期限 + String getUseDateStr() { + int? getPwdType = state.itemData.value.keyboardPwdType; + String useDateStr = ''; + DateTime startDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.startDate!); + DateTime endDateStr = + DateTime.fromMillisecondsSinceEpoch(state.itemData.value.endDate!); + int starHour = startDateStr.hour; + int endHour = endDateStr.hour; + + switch (getPwdType) { + case 1: + //单次 1 只能在开始时间后6小时内使用一次 + useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)}\n${endDateStr.toLocal().toString().substring(0, 16)}'; + break; + case 2: + //永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 + useDateStr = '永久'; + break; + case 3: + //限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效 + useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)}\n${endDateStr.toLocal().toString().substring(0, 16)}'; + break; + case 4: + //删除 4 在锁上使用后会删除之前在锁上使用过的密码 + useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)}\n${endDateStr.toLocal().toString().substring(0, 16)}'; + break; + case 5: + //周未循环 5 在周未开始和结束时间指定时间段内有效 + useDateStr = '周末 $starHour:00-$endHour:00'; + break; + case 6: + //每日循环 6 每天开始和结束时间指定时间段内有效 + useDateStr = '周日 $starHour:00-$endHour:00'; + break; + case 7: + //工作日循环 7 工作日开始和结束时间指定的时间段内有效 + useDateStr = '工作日 $starHour:00-$endHour:00'; + break; + case 8: + //周一循环 8 每周一开始和结束时间指定时间段内有效 + useDateStr = '周一 $starHour:00-$endHour:00'; + break; + case 9: + //周二循环 9 每周二开始和结束时间指定时间段内有效 + useDateStr = '周二 $starHour:00-$endHour:00'; + break; + case 10: + //周三循环 10 每周三开始和结束时间指定时间段内有效 + useDateStr = '周三 $starHour:00-$endHour:00'; + break; + case 11: + //周四循环 11 每周四开始和结束时间指定时间段内有效 + useDateStr = '周四 $starHour:00-$endHour:00'; + break; + case 12: + //周五循环 12 每周五开始和结束时间指定时间段内有效 + useDateStr = '周五 $starHour:00-$endHour:00'; + break; + case 13: + //周六循环 13 每周六开始和结束时间指定时间段内有效 + useDateStr = '周六 $starHour:00-$endHour:00'; + break; + case 14: + //周天循环 14 每周日开始和结束时间指定时间段内有效 + useDateStr = '周天 $starHour:00-$endHour:00'; + break; + + default: + } + return useDateStr; + } + //发送时间 String getSenderDate(PasswordKeyListItem indexEntity) { String senderDate = ''; @@ -209,106 +280,13 @@ class _PasswordKeyDetailPageState extends State { return senderDate; } - Widget commonItem(String leftTitle, String rightTitle, - {bool isHaveDirection = false, - bool isHaveLine = false, - bool isHaveRightWidget = false, - Widget? rightWidget, - Function()? action}) { - return GestureDetector( - onTap: action, - child: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - // height: 80.h, - color: Colors.white, - padding: EdgeInsets.only( - left: 20.w, right: 10.w, top: 20.w, bottom: 20.w), - child: Row( - children: [ - SizedBox(width: 20.w), - Text( - leftTitle, - style: - TextStyle(fontSize: 28.sp, fontWeight: FontWeight.w500), - ), - SizedBox(width: 20.w), - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - isHaveRightWidget - ? rightWidget! - : Text( - rightTitle, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 28.sp, fontWeight: FontWeight.w500), - ) - ], - ), - ), - SizedBox(width: 5.w), - isHaveDirection - ? Image.asset( - 'images/icon_right.png', - width: 50.w, - height: 50.w, - ) - : SizedBox(width: 10.w), - // SizedBox(width:10.w), - ], - ), - ), - isHaveLine - ? Container( - height: 0.5.h, - color: Colors.grey, - ) - : Container() - ], - ), - ); - } - - //删除密码请求 deleteType:1-蓝牙 2-网关 - Future deletePwdRequest() async { - PasswordKeyEntity entity = await ApiRepository.to.deleteKeyboardPwd( - itemData.lockId.toString(), itemData.keyboardPwdId.toString(), 1); - if (entity.errorCode!.codeIsSuccessful) { - Toast.show(msg: "删除成功"); - setState(() { - Navigator.pop(context, true); - }); - } - } - - //更新密码请求 - Future updatePwdRequest() async { - PasswordKeyEntity entity = await ApiRepository.to.updatePasswordKey( - itemData.lockId.toString(), - itemData.keyboardPwdId.toString(), - _inputNameController.text, - _inputPwdController.text, - '', - '', - ''); - if (entity.errorCode!.codeIsSuccessful) { - Toast.show(msg: "修改成功"); - setState(() { - Navigator.pop(context); - }); - } - } - void showCupertinoAlertDialog( BuildContext context, TextEditingController inputController) { showDialog( context: context, builder: (BuildContext context) { return ShowTFView( - title: inputController == _inputNameController + title: inputController == state.inputNameController ? "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.name!.tr}" : "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.password!.tr}", tipTitle: "请输入", @@ -316,7 +294,7 @@ class _PasswordKeyDetailPageState extends State { sureClick: () { //发送编辑钥匙名称请求 if (inputController.text.isNotEmpty) { - updatePwdRequest(); + logic.updatePwdRequest(); } }, cancelClick: () { @@ -414,7 +392,7 @@ class _PasswordKeyDetailPageState extends State { { Navigator.pop(context); String pwdShareStr = - '您好,您的密码是:${itemData.keyboardPwd}\n生效时间:${itemData.startDate}\n类型:永久\n锁名:${itemData.keyboardPwdName}'; + '您好,您的密码是:${state.itemData.value.keyboardPwd}\n生效时间:${state.itemData.value.startDate}\n类型:永久\n锁名:${state.itemData.value.keyboardPwdName}'; tokNative('flutter_sharePassword_to_ios', arguments: {'pwdShareStr': pwdShareStr}).then((result) { print('$result'); @@ -459,13 +437,12 @@ class _PasswordKeyDetailPageState extends State { tipTitle: "确定要删除吗?", sureClick: () { Get.back(); - deletePwdRequest(); + logic.deletePwdRequest(); }, cancelClick: () { Get.back(); }, ); - } - ); + }); } } diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_state.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_state.dart new file mode 100644 index 00000000..b838e3c0 --- /dev/null +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_state.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyList/passwordKeyListEntity.dart'; + +class PasswordKeyDetailState { + final itemData = PasswordKeyListItem().obs; + final TextEditingController inputPwdController = TextEditingController(); + final TextEditingController inputNameController = TextEditingController(); + + PasswordKeyDetailState() { + Map map = Get.arguments; + itemData.value = map["itemData"]; + } +} diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyList/passwordKeyList_page.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyList/passwordKeyList_page.dart index 7bbdd9de..d266e6df 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyList/passwordKeyList_page.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyList/passwordKeyList_page.dart @@ -86,9 +86,7 @@ class _PasswordKeyListPageState extends State { btnName: TranslationLoader.lanKeys!.getPassword!.tr, onClick: () { Navigator.pushNamed(context, Routers.passwordKeyManagePage, - arguments: { - "keyInfo": state.keyInfo.value - }).then((val) { + arguments: {"keyInfo": state.keyInfo.value}).then((val) { if (val != null) { logic.mockNetworkDataRequest(); } @@ -143,7 +141,7 @@ class _PasswordKeyListPageState extends State { decoration: InputDecoration( //输入里面输入文字内边距设置 contentPadding: const EdgeInsets.only( - top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + top: 18.0, left: -19.0, right: -15.0, bottom: 2), hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), //不需要输入框下划线 @@ -186,13 +184,13 @@ class _PasswordKeyListPageState extends State { ), child: _electronicKeyItem('images/icon_password.png', passwordKeyListItem.keyboardPwdName!, useDateStr, () { - Navigator.pushNamed(context, Routers.passwordKeyDetailPage, - arguments: {"itemData": passwordKeyListItem}).then((val) { - if (val != null) { - logic.mockNetworkDataRequest(); - } - }); - }), + Navigator.pushNamed(context, Routers.passwordKeyDetailPage, + arguments: {"itemData": passwordKeyListItem}).then((val) { + if (val != null) { + logic.mockNetworkDataRequest(); + } + }); + }), ); } return const SizedBox.shrink(); @@ -229,7 +227,8 @@ class _PasswordKeyListPageState extends State { ); } - void showIosTipViewDialog(BuildContext context, PasswordKeyListItem passwordKeyListItem) { + void showIosTipViewDialog( + BuildContext context, PasswordKeyListItem passwordKeyListItem) { showDialog( context: context, builder: (BuildContext context) { @@ -238,65 +237,100 @@ class _PasswordKeyListPageState extends State { tipTitle: "确定要删除吗?", sureClick: () { Get.back(); - logic.deletePwdRequest(passwordKeyListItem.lockId.toString(), passwordKeyListItem.keyboardPwdId.toString(), 1); + logic.deletePwdRequest(passwordKeyListItem.lockId.toString(), + passwordKeyListItem.keyboardPwdId.toString(), 1); }, cancelClick: () { Get.back(); }, ); - } - ); + }); } //使用期限 - /** -单次 1 只能在开始时间后6小时内使用一次 -永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 -限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效 -删除 4 在锁上使用后会删除之前在锁上使用过的密码 -周未循环 5 在周未开始和结束时间指定时间段内有效 -每日循环 6 每天开始和结束时间指定时间段内有效 -工作日循环 7 工作日开始和结束时间指定的时间段内有效 -周一循环 8 每周一开始和结束时间指定时间段内有效 -周二循环 9 每周二开始和结束时间指定时间段内有效 -周三循环 10 每周三开始和结束时间指定时间段内有效 -周四循环 11 每周四开始和结束时间指定时间段内有效 -周五循环 12 每周五开始和结束时间指定时间段内有效 -周六循环 13 每周六开始和结束时间指定时间段内有效 -周天循环 14 每周日开始和结束时间指定时间段内有效 - */ String getUseDateStr(PasswordKeyListItem indexEntity) { + int? getPwdType = indexEntity.keyboardPwdType; String useDateStr = ''; - if (indexEntity.keyboardPwdType == 3) { - //限期 - DateTime startDateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.startDate!); - DateTime endDateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.endDate!); - useDateStr = - '${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}'; - } else if (indexEntity.keyboardPwdType == 2) { - //永久 - DateTime dateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); - useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 永久'; - } else if (indexEntity.keyboardPwdType == 1) { - //单次 - DateTime dateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); - useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 单次'; - } else if (indexEntity.keyboardPwdType == 4) { - //删除 - DateTime dateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); - useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 清空码'; - } else { - //循环 - DateTime dateStr = - DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); - useDateStr = '${dateStr.toLocal().toString().substring(0, 16)} 循环'; - } + DateTime sendDateStr = + DateTime.fromMillisecondsSinceEpoch(indexEntity.sendDate!); + DateTime startDateStr = + DateTime.fromMillisecondsSinceEpoch(indexEntity.startDate!); + DateTime endDateStr = + DateTime.fromMillisecondsSinceEpoch(indexEntity.endDate!); + int starHour = startDateStr.hour; + int endHour = endDateStr.hour; + switch (getPwdType) { + case 1: + //单次 1 只能在开始时间后6小时内使用一次 + useDateStr = '${sendDateStr.toLocal().toString().substring(0, 16)} 单次'; + break; + case 2: + //永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 + useDateStr = '${sendDateStr.toLocal().toString().substring(0, 16)} 永久'; + break; + case 3: + //限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效 + useDateStr = + '${startDateStr.toLocal().toString().substring(0, 16)} - ${endDateStr.toLocal().toString().substring(0, 16)} 限时'; + break; + case 4: + //删除 4 在锁上使用后会删除之前在锁上使用过的密码 + useDateStr = '${sendDateStr.toLocal().toString().substring(0, 16)} 清空码'; + break; + case 5: + //周未循环 5 在周未开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周末$starHour:00-$endHour:00 循环'; + break; + case 6: + //每日循环 6 每天开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周日$starHour:00-$endHour:00 循环'; + break; + case 7: + //工作日循环 7 工作日开始和结束时间指定的时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 工作日$starHour:00-$endHour:00 循环'; + break; + case 8: + //周一循环 8 每周一开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周一$starHour:00-$endHour:00 循环'; + break; + case 9: + //周二循环 9 每周二开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周二$starHour:00-$endHour:00 循环'; + break; + case 10: + //周三循环 10 每周三开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周三$starHour:00-$endHour:00 循环'; + break; + case 11: + //周四循环 11 每周四开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周四$starHour:00-$endHour:00 循环'; + break; + case 12: + //周五循环 12 每周五开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周五$starHour:00-$endHour:00 循环'; + break; + case 13: + //周六循环 13 每周六开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周六$starHour:00-$endHour:00 循环'; + break; + case 14: + //周天循环 14 每周日开始和结束时间指定时间段内有效 + useDateStr = + '${sendDateStr.toLocal().toString().substring(0, 16)} 周天$starHour:00-$endHour:00 循环'; + break; + + default: + } return useDateStr; } diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart index 41e448ca..9ae822f0 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart @@ -2,6 +2,9 @@ import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_state.dart'; +import 'package:star_lock/network/api_repository.dart'; +import 'package:star_lock/tools/toast.dart'; import '../../../../blue/blue_manage.dart'; import '../../../../blue/io_reply.dart'; @@ -13,6 +16,139 @@ import '../../../../tools/baseGetXController.dart'; import '../../../../tools/storage.dart'; class PasswordKeyPerpetualLogic extends BaseGetXController { + final PasswordKeyPerpetualState state = PasswordKeyPerpetualState(); + + /** +单次 1 只能在开始时间后6小时内使用一次 +永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 +限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效 +删除 4 在锁上使用后会删除之前在锁上使用过的密码 +周未循环 5 在周未开始和结束时间指定时间段内有效 +每日循环 6 每天开始和结束时间指定时间段内有效 +工作日循环 7 工作日开始和结束时间指定的时间段内有效 +周一循环 8 每周一开始和结束时间指定时间段内有效 +周二循环 9 每周二开始和结束时间指定时间段内有效 +周三循环 10 每周三开始和结束时间指定时间段内有效 +周四循环 11 每周四开始和结束时间指定时间段内有效 +周五循环 12 每周五开始和结束时间指定时间段内有效 +周六循环 13 每周六开始和结束时间指定时间段内有效 +周天循环 14 每周日开始和结束时间指定时间段内有效 + */ + //获取密码请求 + Future getKeyboardPwdRequest() async { + String getFailureDateTime = '0'; + String getEffectiveDateTime = '0'; + String lockId = state.keyInfo.value.lockId.toString(); + int passwordType = int.parse(state.widgetType.value); + String getKeyType = passwordType.toString(); + if (passwordType == 0) { + //永久 + getKeyType = '2'; + } else if (passwordType == 1) { + //限时 + getKeyType = '3'; + } else if (passwordType == 2) { + //单次 + getKeyType = '1'; + } else if (passwordType == 3) { + //自定义 + } else if (passwordType == 4) { + //循环 + if (state.loopModeStr.value == '周末') { + getKeyType = '5'; + } else if (state.loopModeStr.value == '每日') { + getKeyType = '6'; + } else if (state.loopModeStr.value == '工作日') { + getKeyType = '7'; + } else if (state.loopModeStr.value == '星期一') { + getKeyType = '8'; + } else if (state.loopModeStr.value == '星期二') { + getKeyType = '9'; + } else if (state.loopModeStr.value == '星期三') { + getKeyType = '10'; + } else if (state.loopModeStr.value == '星期四') { + getKeyType = '11'; + } else if (state.loopModeStr.value == '星期五') { + getKeyType = '12'; + } else if (state.loopModeStr.value == '星期六') { + getKeyType = '13'; + } else if (state.loopModeStr.value == '星期日') { + getKeyType = '14'; + } + } else if (passwordType == 5) { + //清空码 + getKeyType = '4'; + } + print('得到的类型为getKeyType$getKeyType'); + + if (state.widgetType.value != '0' && + state.widgetType.value != '2' && + state.widgetType.value != '5') { + getFailureDateTime = + state.failureDateTime.value.millisecondsSinceEpoch.toString(); + getEffectiveDateTime = + state.effectiveDateTime.value.millisecondsSinceEpoch.toString(); + } + var entity = await ApiRepository.to.getPasswordKey( + getFailureDateTime, + '0', + state.nameController.text, + getKeyType, + '0', + lockId, + '0', + getEffectiveDateTime, + '0', + state.loopStartHours.value, + state.loopEndHours.value, + 1); + if (entity.errorCode!.codeIsSuccessful) { + print('获取密码成功'); + state.isSendSuccess.value = true; + if (entity.data != null) { + state.getPwdStr.value = entity.data!.keyboardPwd!; + } + } else { + Toast.show(msg: '${entity.errorMsg}'); + } + } + + //自定义密码请求 + Future addKeyboardPwdRequest() async { + String getFailureDateTime = '0'; + String getEffectiveDateTime = '0'; + String lockId = state.keyInfo.value.lockId.toString(); + String getKeyType = '3'; + //是否为永久 + if (state.isPermanent.value == false) { + getKeyType = '3'; + getFailureDateTime = DateTime.parse(state.selectFailureDate.value) + .millisecondsSinceEpoch + .toString(); + getEffectiveDateTime = DateTime.parse(state.selectEffectiveDate.value) + .millisecondsSinceEpoch + .toString(); + } else { + getKeyType = '2'; + } + var entity = await ApiRepository.to.addPasswordKey( + lockId, + state.nameController.text, + state.pwdController.text, + getKeyType, + getEffectiveDateTime, + getFailureDateTime, + '0'); + if (entity.errorCode!.codeIsSuccessful) { + print('获取密码成功'); + state.isSendSuccess.value = true; + if (entity.data != null) { + state.getPwdStr.value = entity.data!.keyboardPwd!; + } + } else { + Toast.show(msg: '${entity.errorMsg}'); + } + } late DateTime getStartDateTime; // 监听设备返回的数据 diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_page.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_page.dart index 4b2f271b..3c8f66b9 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_page.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_page.dart @@ -2,15 +2,13 @@ import 'package:date_format/date_format.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/style/default_style.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart'; -import 'package:star_lock/network/api_repository.dart'; -import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/style/default_style.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/toast.dart'; @@ -35,63 +33,36 @@ class PasswordKeyPerpetualPage extends StatefulWidget { } class _PasswordKeyPerpetualPageState extends State { - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _pwdController = TextEditingController(); final logic = Get.put(PasswordKeyPerpetualLogic()); + final state = Get.find().state; + static const methodChannel = MethodChannel('talkPlugin'); - late bool _isSendSuccess; //是否发送成功 - late bool _isPermanent; //是否永久 - late String _getPwdStr; - String _selectEffectiveDate = ''; //生效时间 - String _selectFailureDate = ''; //失效时间 - late DateTime _effectiveDateTime; - late DateTime _failureDateTime; - late String cyclicModeStr; //循环模式 - late String effectiveHourStr; - late String failureHourStr; - int startHours = 0; - int endHours = 0; - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: indexChangeWidget(), - ); - } - @override void initState() { super.initState(); - _isSendSuccess = false; - _isPermanent = false; - DateTime dateTime = DateTime.now(); - _effectiveDateTime = dateTime; - _failureDateTime = dateTime; - if (int.parse(widget.type) == 4) { - cyclicModeStr = '周末'; + initData(); + } - _selectEffectiveDate = "${formatDate(dateTime, [HH])}:00"; //默认为当前时间 - _selectFailureDate = "${formatDate(dateTime, [HH])}:00"; //默认为当前时间 - startHours = _effectiveDateTime.hour; - endHours = _failureDateTime.hour; - } else if (int.parse(widget.type) == 3) { - // 自定义 - _selectEffectiveDate = formatDate( - dateTime, [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 - _selectFailureDate = formatDate( - dateTime, [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 - } else { - _selectEffectiveDate = "${formatDate( - dateTime, [yyyy, '-', mm, '-', dd, ' ', HH])}:00"; //默认为当前时间 - _selectFailureDate = "${formatDate( - dateTime, [yyyy, '-', mm, '-', dd, ' ', HH])}:00"; //默认为当前时间 + void initData() { + if (!state.isInitialized.value) { + state.isInitialized.value = true; + state.keyInfo.value = widget.getKeyInfo; } } + @override + Widget build(BuildContext context) { + state.widgetType.value = widget.type; + + return SingleChildScrollView( + child: Obx(() => indexChangeWidget()), + ); + } + Widget indexChangeWidget() { - if (_isSendSuccess) { + if (state.isSendSuccess.value == true) { return sendElectronicKeySucceed(); } else { switch (int.parse(widget.type)) { @@ -103,7 +74,7 @@ class _PasswordKeyPerpetualPageState extends State { perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip1!.tr) ], ); @@ -117,7 +88,7 @@ class _PasswordKeyPerpetualPageState extends State { perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip2!.tr) ], ); @@ -130,7 +101,7 @@ class _PasswordKeyPerpetualPageState extends State { perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip3!.tr) ], ); @@ -141,13 +112,15 @@ class _PasswordKeyPerpetualPageState extends State { return Column( children: [ keyIfPerpetualWidget(), - _isPermanent == false ? keyTimeLimitWidget() : Container(), + state.isPermanent.value == false + ? keyTimeLimitWidget() + : Container(), perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), perpetualKeyWidget(TranslationLoader.lanKeys!.password!.tr, - "请输入6-9位数字", _pwdController), + "请输入6-9位数字", state.pwdController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip4!.tr) ], ); @@ -161,7 +134,7 @@ class _PasswordKeyPerpetualPageState extends State { perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip5!.tr) ], ); @@ -174,7 +147,7 @@ class _PasswordKeyPerpetualPageState extends State { perpetualKeyWidget( TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseNameYourPassword!.tr, - _nameController), + state.nameController), keyBottomWidget(TranslationLoader.lanKeys!.getPasswordTip6!.tr) ], ); @@ -191,14 +164,11 @@ class _PasswordKeyPerpetualPageState extends State { return Column( children: [ SizedBox(height: 10.h), - Container( - // margin: EdgeInsets.only(left: 20.w, right: 20.w), - child: CommonItem( - leftTitel: titleStr, - rightTitle: "", - isHaveRightWidget: true, - rightWidget: getTFWidget(rightTitle, controller)), - ), + CommonItem( + leftTitel: titleStr, + rightTitle: "", + isHaveRightWidget: true, + rightWidget: getTFWidget(rightTitle, controller)), SizedBox(height: 10.h), ], ); @@ -206,156 +176,203 @@ class _PasswordKeyPerpetualPageState extends State { // 限时顶部选择日期 Widget keyTimeLimitWidget() { - return Container( - // margin: EdgeInsets.only(left: 20.w, right: 20.w), - child: Column( - children: [ - CommonItem( - leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, - rightTitle: _selectEffectiveDate, - isHaveLine: true, - isHaveDirection: true, - action: () { - Pickers.showDatePicker(context, mode: DateMode.YMDHM, - onConfirm: (p) { - setState(() { - if (int.parse(widget.type) == 3) { - // 自定义 - _effectiveDateTime = DateTime.parse( - '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectEffectiveDate = formatDate(_effectiveDateTime, - [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 - } else { - _effectiveDateTime = DateTime.parse( - '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}'); - _selectEffectiveDate = "${formatDate(_effectiveDateTime, - [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn])}00"; //默认为当前时间 - } - }); - }); - }), - CommonItem( - leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, - rightTitle: _selectFailureDate, - isHaveDirection: true, - action: () { - Pickers.showDatePicker(context, mode: DateMode.YMDHM, - onConfirm: (p) { - setState(() { - if (int.parse(widget.type) == 3) { - // 自定义 - _failureDateTime = DateTime.parse( - '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectFailureDate = formatDate(_failureDateTime, - [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 - } else { - _failureDateTime = DateTime.parse( - '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}'); - _selectFailureDate = "${formatDate(_failureDateTime, - [yyyy, '-', mm, '-', dd, ' ', HH])}:00"; - } - }); - }); - }), - Container(height: 10.h), - ], - ), + return Column( + children: [ + CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, + rightTitle: state.selectEffectiveDate.value, + isHaveLine: true, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.YMDH, + onConfirm: (p) { + if (int.parse(widget.type) == 3) { + // 自定义 + state.effectiveDateTime.value = DateTime.parse( + '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); + state.selectEffectiveDate.value = formatDate( + state.effectiveDateTime.value, + [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 + } else { + state.effectiveDateTime.value = DateTime.parse( + '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}'); + state.selectEffectiveDate.value = + "${formatDate(state.effectiveDateTime.value, [ + yyyy, + '-', + mm, + '-', + dd, + ' ', + HH + ])}:00"; //默认为当前时间 + } + }); + }), + CommonItem( + leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, + rightTitle: state.selectFailureDate.value, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.YMDH, + onConfirm: (p) { + if (int.parse(widget.type) == 3) { + // 自定义 + state.failureDateTime.value = DateTime.parse( + '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); + state.selectFailureDate.value = formatDate( + state.failureDateTime.value, + [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn]); //默认为当前时间 + } else { + state.failureDateTime.value = DateTime.parse( + '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}'); + state.selectFailureDate.value = + "${formatDate(state.failureDateTime.value, [ + yyyy, + '-', + mm, + '-', + dd, + ' ', + HH + ])}:00"; + } + }); + }), + Container(height: 10.h), + ], ); } // 自定义是否永久 Widget keyIfPerpetualWidget() { - return Container( - // margin: EdgeInsets.only(left: 20.w, right: 20.w), - child: Column( - children: [ - CommonItem( - leftTitel: TranslationLoader.lanKeys!.permanent!.tr, - rightTitle: "", - isHaveRightWidget: true, - rightWidget: - SizedBox(width: 60.w, height: 50.h, child: _switch()), - action: () {}), - _isPermanent == true - ? Container(height: 10.h) - : Container(height: 1.h), - ], - ), + return Column( + children: [ + CommonItem( + leftTitel: TranslationLoader.lanKeys!.permanent!.tr, + rightTitle: "", + isHaveRightWidget: true, + rightWidget: SizedBox(width: 60.w, height: 50.h, child: _switch()), + action: () {}), + state.isPermanent.value == true + ? Container(height: 10.h) + : Container(height: 1.h), + ], ); } // 循环 Widget keyCirculationWidget() { - return Container( - // margin: EdgeInsets.only(left: 20.w, right: 20.w), - child: Column( - children: [ - CommonItem( - leftTitel: TranslationLoader.lanKeys!.recursiveDevice!.tr, - rightTitle: cyclicModeStr, - isHaveLine: true, - isHaveDirection: true, - action: () { - List pickerDataList = [ - '周末', - '每日', - '工作日', - '星期一', - '星期二', - '星期三', - '星期四', - '星期五', - '星期六', - '星期日' - ]; - showPickerView(context, pickerDataList); - }), - CommonItem( - leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, - rightTitle: _selectEffectiveDate, - isHaveLine: true, - isHaveDirection: true, - action: () { - Pickers.showDatePicker(context, mode: DateMode.H, - onConfirm: (p) { - setState(() { - _effectiveDateTime = DateTime.parse( - '${_effectiveDateTime.year}-${intToStr(_effectiveDateTime.month)}-${intToStr(_effectiveDateTime.day)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectEffectiveDate = - formatDate(_effectiveDateTime, [HH, ':', nn]); - startHours = p.hour!; - }); - }); - }), - CommonItem( - leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, - rightTitle: _selectFailureDate, - isHaveDirection: true, - action: () { - Pickers.showDatePicker(context, mode: DateMode.H, onConfirm: (p) { - setState(() { - _failureDateTime = DateTime.parse( - '${_failureDateTime.year}-${intToStr(_failureDateTime.month)}-${intToStr(_failureDateTime.day)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}'); - _selectFailureDate = - formatDate(_failureDateTime, [HH, ':', nn]); - endHours = p.hour!; - }); - }); - }), - ], - ), + return Column( + children: [ + CommonItem( + leftTitel: TranslationLoader.lanKeys!.recursiveDevice!.tr, + rightTitle: state.loopModeStr.value, + isHaveLine: true, + isHaveDirection: true, + action: () { + List pickerDataList = [ + '周末', + '每日', + '工作日', + '星期一', + '星期二', + '星期三', + '星期四', + '星期五', + '星期六', + '星期日' + ]; + showPickerView(context, pickerDataList); + }), + CommonItem( + leftTitel: '结束日期', + rightTitle: state.selectFailureDate.value, + isHaveLine: true, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.YMDH, + onConfirm: (p) { + state.failureDateTime.value = DateTime.parse( + '${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}'); + state.selectFailureDate.value = + "${formatDate(state.failureDateTime.value, [ + yyyy, + '-', + mm, + '-', + dd, + ' ', + HH + ])}:00"; + }); + }), + CommonItem( + leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr, + rightTitle: state.loopEffectiveDate.value, + isHaveLine: true, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.H, onConfirm: (p) { + DateTime selectedDateTime = DateTime( + DateTime.now().year, + DateTime.now().month, + DateTime.now().day, + p.hour!, + ); + + if (isValidDateTime(selectedDateTime)) { + state.effectiveDateTime.value = selectedDateTime; + state.loopEffectiveDate.value = + "${formatDate(state.effectiveDateTime.value, [HH])}:00"; + state.loopStartHours.value = p.hour!; + // state.selectEffectiveDate.value = + // formatDate(state.effectiveDateTime.value, [HH]); + } else { + // 处理日期不合法的情况,可以使用默认值或者其他策略 + } + }); + }), + CommonItem( + leftTitel: TranslationLoader.lanKeys!.failureTime!.tr, + rightTitle: state.loopFailureDate.value, + isHaveDirection: true, + action: () { + Pickers.showDatePicker(context, mode: DateMode.H, onConfirm: (p) { + DateTime selectedDateTime = DateTime( + DateTime.now().year, + DateTime.now().month, + DateTime.now().day, + p.hour!, + ); + + if (isValidDateTime(selectedDateTime)) { + state.failureDateTime.value = selectedDateTime; + state.loopFailureDate.value = + "${formatDate(state.failureDateTime.value, [HH])}:00"; + state.loopEndHours.value = p.hour!; + } else { + // 处理日期不合法的情况,可以使用默认值或者其他策略 + } + }); + }), + ], ); } + bool isValidDateTime(DateTime dateTime) { + // 在这里添加日期时间合法性检查的逻辑 + // 如果日期时间合法,返回 true,否则返回 false + return true; // 这里先简单返回 true,实际应用中需要根据具体需求来实现 + } + //底部选择pickerView showPickerView(BuildContext context, List dataList) { - Pickers.showSinglePicker(context, data: dataList, pickerStyle: DefaultPickerStyle(), onConfirm: (p, position) { - setState(() { - cyclicModeStr = p; - }); - }, onChanged: (p, position) { - setState(() {}); - }); + Pickers.showSinglePicker(context, + data: dataList, + pickerStyle: DefaultPickerStyle(), onConfirm: (p, position) { + state.loopModeStr.value = p; + }, onChanged: (p, position) {}); } Widget keyBottomWidget(String tipStr) { @@ -381,45 +398,70 @@ class _PasswordKeyPerpetualPageState extends State { SubmitBtn( btnName: TranslationLoader.lanKeys!.getPassword!.tr, onClick: () async { - // logic.senderCustomPasswords(); - - /* - int getWidgetNumber = int.parse(widget.type); - - if (_nameController.text.isEmpty) { - Toast.show(msg: '请输入密码姓名'); - return; - } - if (getWidgetNumber != 0 || - getWidgetNumber != 2 || - getWidgetNumber != 5) { - if (getWidgetNumber == 3 && _pwdController.text.isEmpty) { - Toast.show(msg: '请输入密码'); - return; - } - if (_failureDateTime.compareTo(_effectiveDateTime) != 1) { - Toast.show(msg: '失效时间需大于生效时间'); - return; - } - } - */ var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); if (isDemoMode == false) { - if (_nameController.text.isNotEmpty) { - logic.getStartDate(_effectiveDateTime); - int passwordType = int.parse(widget.type); - if (passwordType == 3) { - if (_pwdController.text.isNotEmpty) { - //自定义密码 - addKeyboardPwdRequest(); - } else { - Toast.show(msg: '请输入密码'); - } - } else { - getKeyboardPwdRequest(); + int getWidgetNumber = int.parse(widget.type); + DateTime startDateTime = DateTime( + state.effectiveDateTime.value.year, + state.effectiveDateTime.value.month, + state.effectiveDateTime.value.day, + state.effectiveDateTime.value.hour); + DateTime endDateTime = DateTime( + state.failureDateTime.value.year, + state.failureDateTime.value.month, + state.failureDateTime.value.day, + state.failureDateTime.value.hour); + + //自定义密码 + if (getWidgetNumber == 3) { + logic.getStartDate(state.effectiveDateTime.value); + if (state.nameController.text.isEmpty) { + Toast.show(msg: '请输入姓名'); + return; } + if (state.pwdController.text.isEmpty) { + Toast.show(msg: '请输入密码'); + return; + } + //非永久 须有时限 + if (state.isPermanent.value == false) { + if (!startDateTime.isBefore(endDateTime) || + startDateTime.isAtSameMomentAs(endDateTime)) { + Toast.show(msg: '失效时间需大于生效时间'); + return; + } + } + + logic.addKeyboardPwdRequest(); } else { - Toast.show(msg: '请给密码命名'); + if (state.nameController.text.isEmpty) { + Toast.show(msg: '请输入姓名'); + return; + } + + //限时 + if (getWidgetNumber == 1) { + if (!startDateTime.isBefore(endDateTime) || + startDateTime.isAtSameMomentAs(endDateTime)) { + Toast.show(msg: '失效时间需大于生效时间'); + return; + } + } + //循环密码 + if (getWidgetNumber == 4) { + if (!startDateTime.isBefore(endDateTime) || + startDateTime.isAtSameMomentAs(endDateTime)) { + Toast.show(msg: '结束时间需大于当前时间'); + return; + } + if (state.loopEndHours.value <= + state.loopStartHours.value) { + Toast.show(msg: '失效时间需大于生效时间'); + return; + } + } + + logic.getKeyboardPwdRequest(); } } else { Toast.show(msg: '演示模式'); @@ -429,132 +471,6 @@ class _PasswordKeyPerpetualPageState extends State { ); } - /** -单次 1 只能在开始时间后6小时内使用一次 -永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 -限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效 -删除 4 在锁上使用后会删除之前在锁上使用过的密码 -周未循环 5 在周未开始和结束时间指定时间段内有效 -每日循环 6 每天开始和结束时间指定时间段内有效 -工作日循环 7 工作日开始和结束时间指定的时间段内有效 -周一循环 8 每周一开始和结束时间指定时间段内有效 -周二循环 9 每周二开始和结束时间指定时间段内有效 -周三循环 10 每周三开始和结束时间指定时间段内有效 -周四循环 11 每周四开始和结束时间指定时间段内有效 -周五循环 12 每周五开始和结束时间指定时间段内有效 -周六循环 13 每周六开始和结束时间指定时间段内有效 -周天循环 14 每周日开始和结束时间指定时间段内有效 - */ - //获取密码请求 - Future getKeyboardPwdRequest() async { - String getFailureDateTime = '0'; - String getEffectiveDateTime = '0'; - String lockId = widget.getKeyInfo.lockId.toString(); - int passwordType = int.parse(widget.type); - String getKeyType = passwordType.toString(); - if (passwordType == 0) { - //永久 - getKeyType = '2'; - } else if (passwordType == 1) { - //限时 - getKeyType = '3'; - } else if (passwordType == 2) { - //单次 - getKeyType = '1'; - } else if (passwordType == 3) { - //自定义 - } else if (passwordType == 4) { - //循环 - if (cyclicModeStr == '每日') { - getKeyType = '6'; - } else if (cyclicModeStr == '工作日') { - getKeyType = '7'; - } else if (cyclicModeStr == '星期一') { - getKeyType = '8'; - } else if (cyclicModeStr == '星期二') { - getKeyType = '9'; - } else if (cyclicModeStr == '星期三') { - getKeyType = '10'; - } else if (cyclicModeStr == '星期四') { - getKeyType = '11'; - } else if (cyclicModeStr == '星期五') { - getKeyType = '12'; - } else if (cyclicModeStr == '星期六') { - getKeyType = '13'; - } else if (cyclicModeStr == '星期日') { - getKeyType = '14'; - } - } else if (passwordType == 5) { - //清空码 - getKeyType = '4'; - } - if (widget.type != '0' && widget.type != '2' && widget.type != '5') { - getFailureDateTime = _failureDateTime.millisecondsSinceEpoch.toString(); - getEffectiveDateTime = - _effectiveDateTime.millisecondsSinceEpoch.toString(); - } - var entity = await ApiRepository.to.getPasswordKey( - getFailureDateTime, - '0', - _nameController.text, - getKeyType, - '0', - lockId, - '0', - getEffectiveDateTime, - '0', - startHours, - endHours, - 1); - if (entity.errorCode!.codeIsSuccessful) { - print('获取密码成功'); - _isSendSuccess = true; - if (entity.data != null) { - _getPwdStr = entity.data!.keyboardPwd!; - setState(() {}); - } - } else { - Toast.show(msg: '${entity.errorMsg}'); - } - } - - //自定义密码请求 - Future addKeyboardPwdRequest() async { - String getFailureDateTime = '0'; - String getEffectiveDateTime = '0'; - String lockId = widget.getKeyInfo.lockId.toString(); - String getKeyType = '3'; - //是否为永久 - if (_isPermanent == false) { - getKeyType = '3'; - getFailureDateTime = - DateTime.parse(_selectFailureDate).millisecondsSinceEpoch.toString(); - getEffectiveDateTime = DateTime.parse(_selectEffectiveDate) - .millisecondsSinceEpoch - .toString(); - } else { - getKeyType = '2'; - } - var entity = await ApiRepository.to.addPasswordKey( - lockId, - _nameController.text, - _pwdController.text, - getKeyType, - getEffectiveDateTime, - getFailureDateTime, - '0'); - if (entity.errorCode!.codeIsSuccessful) { - print('获取密码成功'); - _isSendSuccess = true; - if (entity.data != null) { - _getPwdStr = entity.data!.keyboardPwd!; - setState(() {}); - } - } else { - Toast.show(msg: '${entity.errorMsg}'); - } - } - // 发送电子钥匙成功 Widget sendElectronicKeySucceed() { return Column( @@ -584,7 +500,7 @@ class _PasswordKeyPerpetualPageState extends State { height: 10.h, ), Text( - _getPwdStr, + state.getPwdStr.value, style: TextStyle( fontSize: 40.sp, color: Colors.black, @@ -599,7 +515,7 @@ class _PasswordKeyPerpetualPageState extends State { SubmitBtn( btnName: '完成', onClick: () { - _isSendSuccess = false; + state.isSendSuccess.value = false; Navigator.pop(context, true); }), SizedBox( @@ -654,16 +570,14 @@ class _PasswordKeyPerpetualPageState extends State { ); } - CupertinoSwitch _switch() { + _switch() { return CupertinoSwitch( activeColor: CupertinoColors.activeBlue, trackColor: CupertinoColors.systemGrey5, thumbColor: CupertinoColors.white, - value: _isPermanent, + value: state.isPermanent.value, onChanged: (value) { - setState(() { - _isPermanent = value; - }); + state.isPermanent.value = value; }, ); } @@ -758,7 +672,7 @@ class _PasswordKeyPerpetualPageState extends State { case 0: //微信好友 { - String pwdShareStr = '您好,您的密码是:$_getPwdStr'; + String pwdShareStr = '您好,您的密码是:${state.getPwdStr.value}'; tokNative('flutter_sharePassword_to_ios', arguments: {'pwdShareStr': pwdShareStr}).then((result) { print('$result'); diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_state.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_state.dart new file mode 100644 index 00000000..b598460c --- /dev/null +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_state.dart @@ -0,0 +1,48 @@ +import 'package:date_format/date_format.dart'; +import 'package:flutter/widgets.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart'; + +class PasswordKeyPerpetualState { + final TextEditingController nameController = TextEditingController(); + final TextEditingController pwdController = TextEditingController(); + + final isInitialized = false.obs; + final isSendSuccess = false.obs; //是否发送成功 + final isPermanent = true.obs; //是否永久 + var getPwdStr = ''.obs; + + final effectiveDateTime = DateTime.now().obs; + final failureDateTime = DateTime.now().obs; + + var selectEffectiveDate = "${formatDate(DateTime.now(), [ + yyyy, + '-', + mm, + '-', + dd, + ' ', + HH, + ])}:00" + .obs; //生效时间 + + var selectFailureDate = "${formatDate(DateTime.now(), [ + yyyy, + '-', + mm, + '-', + dd, + ' ', + HH, + ])}:00" + .obs; //失效时间 + + var loopEffectiveDate = "${formatDate(DateTime.now(), [HH])}:00".obs; //生效时间 + var loopFailureDate = "${formatDate(DateTime.now(), [HH])}:00".obs; //失效时间 + var loopStartHours = DateTime.now().hour.obs; + var loopEndHours = DateTime.now().hour.obs; + var loopModeStr = '周末'.obs; //循环模式 + + final widgetType = ''.obs; + final keyInfo = LockListInfoItemEntity().obs; +} diff --git a/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_page.dart b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_page.dart new file mode 100644 index 00000000..c2c5b95a --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_page.dart @@ -0,0 +1,38 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/titleAppBar.dart'; +import '../../../../../translations/trans_lib.dart'; +import 'addRemoteControlManage_tabbar.dart'; + +class AddRemoteControlManagePage extends StatefulWidget { + const AddRemoteControlManagePage({Key? key}) : super(key: key); + + @override + State createState() => _AddRemoteControlManagePageState(); +} + +class _AddRemoteControlManagePageState extends State { + var index = 0; + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: + "${TranslationLoader.lanKeys!.addTip!.tr}${TranslationLoader.lanKeys!.remoteControl!.tr}", + haveBack: true, + backgroundColor: AppColors.mainColor), + body: Column( + children: [ + AddRemoteControlManageTabbar(initialIndex: index), + ], + ), + ); + } + +} diff --git a/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_tabbar.dart b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_tabbar.dart new file mode 100644 index 00000000..c0efdb5d --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControlManage/addRemoteControlManage_tabbar.dart @@ -0,0 +1,100 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../../../../../app_settings/app_colors.dart'; +import '../../../../../tools/CustomUnderlineTabIndicator.dart'; +import '../../../../../translations/trans_lib.dart'; +import '../addRemoteControl_page.dart'; + +class AddRemoteControlManageTabbar extends StatefulWidget { + var initialIndex = 1; + + AddRemoteControlManageTabbar({Key? key, required this.initialIndex}) : super(key: key); + + @override + State createState() => _AddRemoteControlManageTabbarState(); +} + +class _AddRemoteControlManageTabbarState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + + final List _itemTabs = [ + ItemView(title: TranslationLoader.lanKeys!.permanent!.tr, seletType: "0"), + ItemView(title: TranslationLoader.lanKeys!.timeLimit!.tr, seletType: "1"), + ItemView(title: TranslationLoader.lanKeys!.circulation!.tr, seletType: "2"), + ]; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _tabController = TabController( + vsync: this, + length: _itemTabs.length, + initialIndex: widget.initialIndex); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Column( + children: [ + _tabBar(), + _pageWidget(), + ], + )); + } + + TabBar _tabBar() { + return TabBar( + controller: _tabController, + tabs: _itemTabs.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: _itemTabs + .map((ItemView item) => AddRemoteControlPage(seletType: item.seletType,)) + .toList(), + ), + ); + } +} + +class ItemView { + const ItemView({required this.title, required this.seletType}); + + final String title; + final String seletType; +} + diff --git a/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_logic.dart b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_logic.dart new file mode 100644 index 00000000..0ee20ef7 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_logic.dart @@ -0,0 +1,14 @@ + +import 'package:star_lock/tools/baseGetXController.dart'; + +import 'addRemoteControl_state.dart'; + +class AddRemoteControlLoigc extends BaseGetXController{ + AddRemoteControlState state = AddRemoteControlState(); + + @override + void onInit() { + + } + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_page.dart b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_page.dart new file mode 100644 index 00000000..2b7a9fc3 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_page.dart @@ -0,0 +1,315 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.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 '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'addRemoteControl_logic.dart'; + +class AddRemoteControlPage extends StatefulWidget { + final String seletType; + + const AddRemoteControlPage({Key? key, required this.seletType}) + : super(key: key); + + @override + State createState() => _AddRemoteControlPageState(); +} + +class _AddRemoteControlPageState extends State { + final logic = Get.put(AddRemoteControlLoigc()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return indexChangeWidget(); + } + + Widget indexChangeWidget() { + switch (int.parse(widget.seletType)) { + 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(), + SizedBox(height: 10.h), + 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) { + setState(() { + setState(() { + 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) { + setState(() { + setState(() { + 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!.remoteControl!.tr, + // rightTitle: "", + // isTipsImg: false, + // isHaveRightWidget: true, + // rightWidget: SizedBox( + // width: 60.w, height: 50.h, child: _isStressFingerprint())), + SizedBox(height: 30.h), + SubmitBtn( + btnName: TranslationLoader.lanKeys!.next!.tr, + onClick: () async { + var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); + if (isDemoMode == false) { + // print("state.seletType:${state.seletType.value}"); + if (state.nameController.text.isEmpty) { + Toast.show(msg: "请输入姓名"); + return; + } + Toast.show(msg: "请确保在设备附近"); + // logic.addFingerprintsData(); + } else { + // Get.toNamed(Routers.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }), + ], + ); + } + + // 发送电子钥匙成功 + 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, + ), + ], + ), + ); + } + + //isStressFingerprint false:不是胁迫指纹 ture:胁迫指纹 + CupertinoSwitch _isStressFingerprint() { + return CupertinoSwitch( + activeColor: CupertinoColors.activeBlue, + trackColor: CupertinoColors.systemGrey5, + thumbColor: CupertinoColors.white, + value: true, + onChanged: (value) { + setState(() { + // state.isStressFingerprint.value = value; + }); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_state.dart b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_state.dart new file mode 100644 index 00000000..58817080 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/addRemoteControl/addRemoteControl_state.dart @@ -0,0 +1,17 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class AddRemoteControlState{ + + 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(); +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/remoteControl/remoteControlDetail/remoteControlDetail_page.dart b/star_lock/lib/main/lockDetail/remoteControl/remoteControlDetail/remoteControlDetail_page.dart new file mode 100644 index 00000000..e69de29b diff --git a/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_logic.dart b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_logic.dart new file mode 100644 index 00000000..ecb67297 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_logic.dart @@ -0,0 +1,20 @@ + + +import 'package:star_lock/tools/baseGetXController.dart'; + +import 'remoteControlList_state.dart'; + +class RemoteControlListLogic extends BaseGetXController{ + RemoteControlListState state = RemoteControlListState(); + + @override + void onInit() { + super.onInit(); + } + + @override + void onClose() { + super.onClose(); + } + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_page.dart b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_page.dart new file mode 100644 index 00000000..02f406a5 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_page.dart @@ -0,0 +1,275 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.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 '../../../../tools/toast.dart'; +import '../../../../translations/trans_lib.dart'; +import 'remoteControlList_logic.dart'; + +class RemoteControlListPage extends StatefulWidget { + const RemoteControlListPage({Key? key}) : super(key: key); + + @override + State createState() => _RemoteControlListPageState(); +} + +class _RemoteControlListPageState extends State { + final logic = Get.put(RemoteControlListLogic()); + final state = Get.find().state; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.mainBackgroundColor, + appBar: TitleAppBar( + barTitle: TranslationLoader.lanKeys!.remoteControl!.tr, + 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.seletLockTypePage); + Toast.show(msg: "演示模式"); + } + }, + ), + ], + ), + body: Column( + children: [ + _searchWidget(), + SizedBox( + height: 20.h, + ), + Expanded(child: _buildMainUI()), + AddBottomWhiteBtn( + btnName: + '${TranslationLoader.lanKeys!.add!.tr}${TranslationLoader.lanKeys!.remoteControl!.tr}', + onClick: () async { + var data = + await Get.toNamed(Routers.addRemoteControlManagePage); + if (data != null) { + // 遥控添加 + + } + }, + ), + SizedBox( + height: 64.h, + ) + ], + ), + ); + } + + // String getAppBarTitle(int type) { + // String title = ""; + // switch (type) { + // case 0: + // title = TranslationLoader.lanKeys!.card!.tr; + // break; + // case 1: + // title = TranslationLoader.lanKeys!.fingerprint!.tr; + // break; + // case 2: + // title = TranslationLoader.lanKeys!.remoteControl!.tr; + // break; + // case 3: + // title = TranslationLoader.lanKeys!.face!.tr; + // break; + // default: + // break; + // } + // return title; + // } + + Widget _searchWidget() { + return Container( + height: 60.h, + margin: EdgeInsets.only(top: 20.w, left: 20.w, right: 10.w), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: TextField( + //输入框一行 + maxLines: 1, + controller: state.searchController, + autofocus: false, + onChanged: (value) { + print("onChanged:$value"); + }, + onEditingComplete: () { + print("onEditingComplete:"); + }, + onSubmitted: (value) { + // 调用遥控列表 + + }, + decoration: InputDecoration( + //输入里面输入文字内边距设置 + contentPadding: const EdgeInsets.only( + top: 12.0, left: -19.0, right: -15.0, bottom: 8.0), + hintText: TranslationLoader.lanKeys!.pleaseEnter!.tr, + hintStyle: TextStyle(fontSize: 22.sp, height: 3.0), + //不需要输入框下划线 + border: InputBorder.none, + //左边图标设置 + icon: Padding( + padding: EdgeInsets.only( + top: 20.h, bottom: 20.h, right: 20.w, left: 10.w), + child: Image.asset( + 'images/main/icon_main_search.png', + width: 40.w, + height: 40.w, + ), + ), + ), + ), + ); + } + + Widget _buildMainUI() { + String typeImgName = 'images/icon_card.png'; + + return const NoData(); + } + + Widget _buildDeleteBtn(String idStr) { + return GestureDetector( + onTap: () { + // 省略: 弹出是否删除的确认对话框。 + showIosTipViewDialog(context, idStr); + }, + 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, String keyId) { + showDialog( + context: context, + builder: (BuildContext context) { + return ShowIosTipView( + title: "提示", + tipTitle: "确定要删除吗?", + sureClick: () async { + // 遥控删除 + + }, + cancelClick: () { + Get.back(); + }, + ); + }, + ); + } + + Widget _keyItem(String lockTypeIcon, String lockTypeTitle, 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.start, + children: [ + Text(lockTypeTitle, + style: TextStyle( + fontSize: 24.sp, color: AppColors.blackColor)), + ], + ), + SizedBox(height: 5.h), + Container( + child: 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: () { + // 遥控重置 + + }, + ), + ], + ); + }, + ); + } +} diff --git a/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_state.dart b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_state.dart new file mode 100644 index 00000000..42112431 --- /dev/null +++ b/star_lock/lib/main/lockDetail/remoteControl/remoteControlList/remoteControlList_state.dart @@ -0,0 +1,7 @@ + +import 'package:flutter/material.dart'; + +class RemoteControlListState{ + final TextEditingController searchController = TextEditingController(); + +} \ No newline at end of file diff --git a/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart b/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart index c1cedd85..8da69913 100644 --- a/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart +++ b/star_lock/lib/main/lockMian/demoMode/demoModeLockDetail/demoModeLockDetail_page.dart @@ -262,8 +262,8 @@ class _DemoModeLockDetailPageState extends State { TranslationLoader.lanKeys!.card!.tr, () { // gotoLogin(); - Get.toNamed(Routers.otherTypeKeyListPage, - arguments: {"lockId": 0, "fromType": 0}); + Get.toNamed(Routers.cardListPage, + arguments: {"lockId": 0}); }), // 指纹 @@ -271,7 +271,7 @@ class _DemoModeLockDetailPageState extends State { TranslationLoader.lanKeys!.fingerprint!.tr, () { // gotoLogin(); - Get.toNamed(Routers.otherTypeKeyListPage, + Get.toNamed(Routers.fingerprintDetailPage, arguments: {"lockId": 1, "fromType": 1}); }), diff --git a/star_lock/lib/main/lockMian/entity/lockListInfo_entity.dart b/star_lock/lib/main/lockMian/entity/lockListInfo_entity.dart index e87b6e0e..944571eb 100644 --- a/star_lock/lib/main/lockMian/entity/lockListInfo_entity.dart +++ b/star_lock/lib/main/lockMian/entity/lockListInfo_entity.dart @@ -115,6 +115,8 @@ class LockListInfoItemEntity { int? keyStatus; int? isLockOwner; int? sendDate; + int? lockUserNo; + int? senderUserId; Bluetooth? bluetooth; LockFeature? lockFeature; LockSetting? lockSetting; @@ -142,7 +144,9 @@ class LockListInfoItemEntity { this.bluetooth, this.lockFeature, this.lockSetting, - this.sendDate}); + this.sendDate, + this.lockUserNo, + this.senderUserId}); LockListInfoItemEntity.fromJson(Map json) { keyId = json['keyId']; @@ -165,6 +169,8 @@ class LockListInfoItemEntity { keyStatus = json['keyStatus']; isLockOwner = json['isLockOwner']; sendDate = json['sendDate']; + lockUserNo = json['lockUserNo']; + senderUserId = json['senderUserId']; bluetooth = json['bluetooth'] != null ? Bluetooth.fromJson(json['bluetooth']) : null; @@ -198,6 +204,8 @@ class LockListInfoItemEntity { data['keyStatus'] = keyStatus; data['isLockOwner'] = isLockOwner; data['sendDate'] = sendDate; + data['lockUserNo'] = lockUserNo; + data['senderUserId'] = senderUserId; if (bluetooth != null) { data['bluetooth'] = bluetooth!.toJson(); } diff --git a/star_lock/lib/mine/about/about_page.dart b/star_lock/lib/mine/about/about_page.dart index 960de892..50c7bc18 100644 --- a/star_lock/lib/mine/about/about_page.dart +++ b/star_lock/lib/mine/about/about_page.dart @@ -38,7 +38,7 @@ class _AbountPageState extends State { ), SizedBox(height: 20.h), Text( - "星锁 1.0.0.02(preRelease-20231124)", + "星锁 1.0.0.03(preRelease-20231216)", style: TextStyle(fontSize: 24.sp, color: AppColors.blackColor), ), SizedBox( diff --git a/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_page.dart b/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_page.dart index c98a3820..76ff55af 100644 --- a/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_page.dart +++ b/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_page.dart @@ -127,6 +127,10 @@ class _AddLockSeletCountryPageState extends State { Get.toNamed(Routers.saveLockPage, arguments: { "addressInfo": {}, "pwdTimestamp": state.pwdTimestamp.value, + "lockInfo": state.lockInfo, + "featureValue": state.featureValue, + "featureSettingValue": state.featureSettingValue, + "featureSettingParams": state.featureSettingParams, }); }, ), @@ -144,6 +148,10 @@ class _AddLockSeletCountryPageState extends State { Get.toNamed(Routers.saveLockPage, arguments: { "addressInfo": {"country":model.name}, "pwdTimestamp": state.pwdTimestamp.value, + "lockInfo": state.lockInfo, + "featureValue": state.featureValue, + "featureSettingValue": state.featureSettingValue, + "featureSettingParams": state.featureSettingParams, }); // Navigator.pushNamed(context, Routers.saveLockPage); }, diff --git a/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_state.dart b/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_state.dart index c6bd1c92..e04acc2d 100644 --- a/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_state.dart +++ b/star_lock/lib/mine/addLock/addLockSeletCountry/addLockSeletCountry_state.dart @@ -4,8 +4,16 @@ import 'package:get/get.dart'; class AddLockSeletCountryState{ var pwdTimestamp= 0.obs; + var lockInfo = {}; + var featureValue = ''; + var featureSettingValue = ''; + var featureSettingParams = []; AddLockSeletCountryState() { Map map = Get.arguments; pwdTimestamp.value = map["pwdTimestamp"]; + lockInfo = map["lockInfo"]; + featureValue = map["featureValue"]; + featureSettingValue = map["featureSettingValue"]; + featureSettingParams = map["featureSettingParams"]; } } diff --git a/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart b/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart index a561527c..45c01d98 100644 --- a/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart +++ b/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart @@ -238,6 +238,10 @@ class _LockAddressGaoDePageState extends State{ Get.toNamed(Routers.addLockSeletCountryPage, arguments: { "addressInfo": {}, "pwdTimestamp": state.pwdTimestamp.value, + "lockInfo": state.lockInfo, + "featureValue": state.featureValue, + "featureSettingValue": state.featureSettingValue, + "featureSettingParams": state.featureSettingParams, }); }, ), @@ -254,6 +258,10 @@ class _LockAddressGaoDePageState extends State{ Get.toNamed(Routers.saveLockPage, arguments: { "addressInfo": addressInfo, "pwdTimestamp": state.pwdTimestamp.value, + "lockInfo": state.lockInfo, + "featureValue": state.featureValue, + "featureSettingValue": state.featureSettingValue, + "featureSettingParams": state.featureSettingParams, }); // Navigator.pushNamed(context, Routers.saveLockPage); }, diff --git a/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_state.dart b/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_state.dart index 58c56fc4..b0c8f76f 100644 --- a/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_state.dart +++ b/star_lock/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_state.dart @@ -8,8 +8,17 @@ import 'package:permission_handler/permission_handler.dart'; class LockAddressGaoDeState{ var pwdTimestamp= 0.obs; + var lockInfo = {}; + var featureValue = ''; + var featureSettingValue = ''; + var featureSettingParams = []; + LockAddressGaoDeState() { Map map = Get.arguments; pwdTimestamp.value = map["pwdTimestamp"]; + lockInfo = map["lockInfo"]; + featureValue = map["featureValue"]; + featureSettingValue = map["featureSettingValue"]; + featureSettingParams = map["featureSettingParams"]; } } \ No newline at end of file diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart index 9a3d6623..7fe6f5e2 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart @@ -12,6 +12,7 @@ import 'package:star_lock/tools/baseGetXController.dart'; import '../../../appRouters.dart'; import '../../../blue/blue_manage.dart'; import '../../../blue/io_protocol/io_addUser.dart'; +import '../../../blue/io_protocol/io_getStarLockStatusInfo.dart'; import '../../../blue/io_reply.dart'; import '../../../blue/io_tool/io_manager.dart'; import '../../../blue/io_tool/io_model.dart'; @@ -48,6 +49,11 @@ class NearbyLockLogic extends BaseGetXController{ if(reply is GetPrivateKeyReply) { _replyGetPrivateKeyKey(reply); } + + // 获取锁状态信息 + if(reply is GetStarLockStatuInfoReply) { + _replyGetStarLockStatusInfo(reply); + } }); } @@ -107,17 +113,15 @@ class NearbyLockLogic extends BaseGetXController{ // 时间戳 List timestamp = reply.data.sublist(32, 36); - int timestampValue = ( + state.timestampValue = ( (0xff & timestamp[(0)]) << 24 | (0xff & timestamp[1]) << 16 | (0xff & timestamp[2]) << 8 | (0xFF & timestamp[3])); - String timestampValueStr = DateTool().dateToYMDHNSString(timestampValue.toString()); - print("timestamp:$timestamp timestampValue:$timestampValue timestampValueStr:$timestampValueStr"); + // String timestampValueStr = DateTool().dateToYMDHNSString(timestampValue.toString()); + // print("timestamp:$timestamp timestampValue:$timestampValue timestampValueStr:$timestampValueStr"); - Get.toNamed(Routers.lockAddressGaoDePage, arguments: { - "pwdTimestamp": timestampValue*1000, - }); + _getStarLockStatus(); break; case 0x07: //无权限 @@ -135,6 +139,198 @@ class NearbyLockLogic extends BaseGetXController{ } } + // 获取星锁状态 + Future _replyGetStarLockStatusInfo(Reply reply) async { + int status = reply.data[2]; + switch(status){ + case 0x00: + //成功 + print("${reply.commandType}数据解析成功"); + + // 厂商名称 + var vendor = reply.data.sublist(3, 23); + print("vendor:$vendor reply.data:${reply.data}"); + var vendorStr = utf8String(vendor); + state.lockInfo["vendor"] = vendorStr; + // print("vendor:$vendor vendorStr:$vendorStr vendorStr.length${vendorStr.length}"); + + // 锁设备类型 + var product = reply.data[23]; + state.lockInfo["product"] = product; + // print("product:$product"); + + // 产品名称 + var model = reply.data.sublist(24, 44); + var modelStr = utf8String(model); + state.lockInfo["model"] = modelStr; + // print("model:$model modelStr:$modelStr modelStr:${modelStr.length}"); + + // 软件版本 + var fwVersion = reply.data.sublist(44, 64); + var fwVersionStr = utf8String(fwVersion); + state.lockInfo["fwVersion"] = fwVersionStr; + // print("fwVersion:$fwVersion fwVersionStr:$fwVersionStr fwVersionStr:${fwVersionStr.length}"); + + // 硬件版本 + var hwVersion = reply.data.sublist(64, 84); + var hwVersionStr = utf8String(hwVersion); + state.lockInfo["hwVersion"] = hwVersionStr; + // print("hwVersion:$hwVersion hwVersionStr:${hwVersionStr.length}"); + + // 厂商序列号 + var serialNum0 = reply.data.sublist(84, 100); + var serialNum0Str = utf8String(serialNum0); + // state.lockInfo["serialNum0"] = serialNum0Str; + state.lockInfo["serialNum0"] = "${DateTime.now().millisecondsSinceEpoch~/10}"; + // print("serialNum0Str:$serialNum0Str serialNum0Str:${serialNum0Str.length}"); + + // 成品商序列号 + var serialNum1 = reply.data.sublist(100, 116); + var serialNum1Str = utf8String(serialNum1); + state.lockInfo["serialNum1"] = serialNum1Str; + // print("serialNum1Str:$serialNum1Str serialNum1Str:${serialNum1Str.length}"); + + // 蓝牙名称 + var btDeviceName = reply.data.sublist(116, 132); + var btDeviceNameStr = utf8String(btDeviceName); + state.lockInfo["btDeviceName"] = btDeviceNameStr; + // print("btDeviceName:$btDeviceName btDeviceNameStr:$btDeviceNameStr btDeviceNameStr:${btDeviceNameStr.length}"); + + // 电池剩余电量 + var battRemCap = reply.data[132]; + state.lockInfo["electricQuantity"] = battRemCap; + // print("battRemCap:$battRemCap"); + + // 重置次数 + var restoreCounter = reply.data.sublist(133, 135); + state.lockInfo["restoreCount"] = restoreCounter[0] * 256 + restoreCounter[1]; + // print("restoreCounter:$restoreCounter"); + + // 重置时间 + var restoreDate = reply.data.sublist(135, 139); + int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | (0xFF & restoreDate[3])); + // String restoreDateStr = DateTool().dateToYMDHNSString(restoreDateValue.toString()); + state.lockInfo["restoreDate"] = restoreDateValue*1000; + // print("restoreDate:$restoreDate restoreDateValue:$restoreDateValue"); + + // 主控芯片型号 + var icPartNo = reply.data.sublist(139, 149); + var icPartNoStr = utf8String(icPartNo); + state.lockInfo["icPartNo"] = icPartNoStr; + // print("icPartNo:$icPartNo icPartNoStr:$icPartNoStr"); + + // 有效时间 + var indate = reply.data.sublist(149, 153); + int indateValue = ((0xff & indate[(0)]) << 24 | (0xff & indate[1]) << 16 | (0xff & indate[2]) << 8 | (0xFF & indate[3])); + // String indateStr = DateTool().dateToYMDHNSString("$indateValue"); + state.lockInfo["indate"] = indateValue*1000; + // print("indate:$indate indateValue:$indateValue"); + + // mac地址 + var macAddress = reply.data.sublist(153, 173); + var macAddressStr = utf8String(macAddress); + state.lockInfo["mac"] = macAddressStr; + print("macAddress:$macAddress macAddressStr:$macAddressStr"); + + var index = 173; + // 锁特征值字符串长度 + var featureValueLength = reply.data[173]; + // 锁特征值说明(本机能支持的功能) + // 获取到锁给的字符数组 + var featureValue = reply.data.sublist(index+1, index + featureValueLength+1); + String featureValueStr = asciiString(featureValue); + state.featureValue = featureValueStr; + // List allFeatureValueTwoList = charListChangeIntList(featureValue); + // print("featureValueLength:$featureValueLength featureValue:$featureValue \n featureValueStr:$featureValueStr"); + index = index + featureValueLength + 1; + + // 使能特征值字符串长度 + var featureEnValLength = reply.data[index]; + // 使能锁特征值说明(本机启用的功能) + var featureEnVal = reply.data.sublist(index+1, index + featureEnValLength+1); + String featureEnValStr = asciiString(featureValue); + state.featureSettingValue = featureEnValStr; + // List allFeatureEnValTwoList = charListChangeIntList(featureEnVal); + // print("featureEnValLength:$featureEnValLength featureEnVal:$featureEnVal \n featureEnValStr:$featureEnValStr"); + index = index + featureEnValLength + 1; + + // 支持的带参数特征值的总条目数 + // var featureParaTotal = reply.data[index]; + + var featureParaTotalList = reply.data.sublist(index); + state.featureSettingParams = featureParaTotalList; + // print("featureParaTotalList:$featureParaTotalList"); + + Get.toNamed(Routers.lockAddressGaoDePage, arguments: { + "pwdTimestamp": state.timestampValue*1000, + "lockInfo": state.lockInfo, + "featureValue": state.featureValue, + "featureSettingValue": state.featureSettingValue, + "featureSettingParams": state.featureSettingParams, + }); + + break; + case 0x06: + //无权限 + print("${reply.commandType}需要鉴权"); + + break; + case 0x07: + //无权限 + print("${reply.commandType}用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("${reply.commandType}权限校验错误"); + + break; + default: + //失败 + print("${reply.commandType}失败"); + + break; + } + } + + // List charListChangeIntList(List featureValue){ + // // 字符数组转化为16进制字符串 + // String featureValueStr = asciiString(featureValue); + // // 16进制字符串转化为2进制的字符串 获取的是逆序的需要倒序 前面有0会消失 需要自动补全 暂时定位57个功能 要补全60 + // String featureValueTwoStr = int.parse(featureValueStr,radix: 16).toRadixString(2); + // List featureValueTwoList = []; + // for(int i = 0;i _getStarLockStatus() async { + // print("connectDeviceMacAddress:${BlueManage().connectDeviceMacAddress} connectDeviceName:${BlueManage().connectDeviceName}"); + // 进来之后首先连接 + BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { + if (state == DeviceConnectionState.connected) { + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + // IoSenderManage.senderGetLockStatu( + // lockID:BlueManage().connectDeviceName, + // userID:await Storage.getUid(), + // privateKey:getPrivateKeyList, + // ); + IoSenderManage.senderGetStarLockStatuInfo( + lockID:BlueManage().connectDeviceName, + userID:await Storage.getUid(), + privateKey:getPrivateKeyList, + ); + } + }, isShowLoading: false); + } + @override void onReady() { // TODO: implement onReady diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart index 508ac241..256477d5 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart @@ -8,4 +8,11 @@ class NearbyLockState { RxList devices = [].obs; var seletLockName = "".obs; + + var timestampValue = 0; + var lockInfo = {}; + var featureValue = ''; + var featureSettingValue = ''; + var featureSettingParams = []; + } \ No newline at end of file diff --git a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart index 255a9842..ed578367 100644 --- a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart +++ b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart @@ -1,4 +1,3 @@ - import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; @@ -24,15 +23,11 @@ class SaveLockLogic extends BaseGetXController { // 获取解析后的数据 late StreamSubscription _replySubscription; void _initReplySubscription() { - _replySubscription = EventBusManager().eventBus!.on().listen((reply) { - if(reply is AddUserReply) { + _replySubscription = + EventBusManager().eventBus!.on().listen((reply) { + if (reply is AddUserReply) { _replyAddUserKey(reply); } - - // 获取锁状态信息 - if(reply is GetStarLockStatuInfoReply) { - _replyGetStarLockStatusInfo(reply); - } }); } @@ -50,16 +45,16 @@ class SaveLockLogic extends BaseGetXController { // print("status:$status reply.data:${reply.data}"); print("status:$status"); - switch(status){ + switch (status) { case 0x00: - //成功 + //成功 print("添加用户数据解析成功"); - state.lockUserNo = reply.data[47]; + state.lockUserNo = reply.data[47] + 1; bindBlueAdmin(); break; case 0x06: - //无权限 + //无权限 print("需要鉴权"); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -68,212 +63,51 @@ class SaveLockLogic extends BaseGetXController { List publicKeyDataList = changeStringListToIntList(publicKey!); IoSenderManage.senderAddUser( - lockID:BlueManage().connectDeviceName, - authUserID:await Storage.getUid(), - keyID:"1", - userID:await Storage.getUid(), - openMode:1, - keyType:1, - startDate:0x11223344, - expireDate:0x11223344, - role:255, - password:"123456", - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: token - ); + lockID: BlueManage().connectDeviceName, + authUserID: await Storage.getUid(), + keyID: "1", + userID: await Storage.getUid(), + openMode: 1, + keyType: 1, + startDate: DateTime.now().millisecondsSinceEpoch, + expireDate: 0x11223344, + role: 255, + password: "123456", + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: token); break; case 0x07: - //无权限 + //无权限 print("用户无权限"); break; case 0x09: - // 权限校验错误 + // 权限校验错误 print("添加用户权限校验错误"); break; default: - //失败 + //失败 print("领锁失败"); break; } } - // 获取星锁状态 - Future _replyGetStarLockStatusInfo(Reply reply) async { - int status = reply.data[2]; - switch(status){ - case 0x00: - //成功 - print("${reply.commandType}数据解析成功"); - - // 厂商名称 - var vendor = reply.data.sublist(3, 23); - print("vendor:$vendor reply.data:${reply.data}"); - var vendorStr = utf8String(vendor); - state.lockInfo["vendor"] = vendorStr; - // print("vendor:$vendor vendorStr:$vendorStr vendorStr.length${vendorStr.length}"); - - // 锁设备类型 - var product = reply.data[23]; - state.lockInfo["product"] = product; - // print("product:$product"); - - // 产品名称 - var model = reply.data.sublist(24, 44); - var modelStr = utf8String(model); - state.lockInfo["model"] = modelStr; - // print("model:$model modelStr:$modelStr modelStr:${modelStr.length}"); - - // 软件版本 - var fwVersion = reply.data.sublist(44, 64); - var fwVersionStr = utf8String(fwVersion); - state.lockInfo["fwVersion"] = fwVersionStr; - // print("fwVersion:$fwVersion fwVersionStr:$fwVersionStr fwVersionStr:${fwVersionStr.length}"); - - // 硬件版本 - var hwVersion = reply.data.sublist(64, 84); - var hwVersionStr = utf8String(hwVersion); - state.lockInfo["hwVersion"] = hwVersionStr; - // print("hwVersion:$hwVersion hwVersionStr:${hwVersionStr.length}"); - - // 厂商序列号 - var serialNum0 = reply.data.sublist(84, 100); - var serialNum0Str = utf8String(serialNum0); - // state.lockInfo["serialNum0"] = serialNum0Str; - state.lockInfo["serialNum0"] = "${DateTime.now().millisecondsSinceEpoch~/10}"; - // print("serialNum0Str:$serialNum0Str serialNum0Str:${serialNum0Str.length}"); - - // 成品商序列号 - var serialNum1 = reply.data.sublist(100, 116); - var serialNum1Str = utf8String(serialNum1); - state.lockInfo["serialNum1"] = serialNum1Str; - // print("serialNum1Str:$serialNum1Str serialNum1Str:${serialNum1Str.length}"); - - // 蓝牙名称 - var btDeviceName = reply.data.sublist(116, 132); - var btDeviceNameStr = utf8String(btDeviceName); - state.lockInfo["btDeviceName"] = btDeviceNameStr; - // print("btDeviceName:$btDeviceName btDeviceNameStr:$btDeviceNameStr btDeviceNameStr:${btDeviceNameStr.length}"); - - // 电池剩余电量 - var battRemCap = reply.data[132]; - state.lockInfo["electricQuantity"] = battRemCap; - // print("battRemCap:$battRemCap"); - - // 重置次数 - var restoreCounter = reply.data.sublist(133, 135); - state.lockInfo["restoreCount"] = restoreCounter[0] * 256 + restoreCounter[1]; - // print("restoreCounter:$restoreCounter"); - - // 重置时间 - var restoreDate = reply.data.sublist(135, 139); - int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | (0xFF & restoreDate[3])); - // String restoreDateStr = DateTool().dateToYMDHNSString(restoreDateValue.toString()); - state.lockInfo["restoreDate"] = restoreDateValue*1000; - // print("restoreDate:$restoreDate restoreDateValue:$restoreDateValue"); - - // 主控芯片型号 - var icPartNo = reply.data.sublist(139, 149); - var icPartNoStr = utf8String(icPartNo); - state.lockInfo["icPartNo"] = icPartNoStr; - // print("icPartNo:$icPartNo icPartNoStr:$icPartNoStr"); - - // 有效时间 - var indate = reply.data.sublist(149, 153); - int indateValue = ((0xff & indate[(0)]) << 24 | (0xff & indate[1]) << 16 | (0xff & indate[2]) << 8 | (0xFF & indate[3])); - // String indateStr = DateTool().dateToYMDHNSString("$indateValue"); - state.lockInfo["indate"] = indateValue*1000; - // print("indate:$indate indateValue:$indateValue"); - - // mac地址 - var macAddress = reply.data.sublist(153, 173); - var macAddressStr = utf8String(macAddress); - state.lockInfo["mac"] = macAddressStr; - print("macAddress:$macAddress macAddressStr:$macAddressStr"); - - var index = 173; - // 锁特征值字符串长度 - var featureValueLength = reply.data[173]; - // 锁特征值说明(本机能支持的功能) - // 获取到锁给的字符数组 - var featureValue = reply.data.sublist(index+1, index + featureValueLength+1); - String featureValueStr = asciiString(featureValue); - state.featureValue = featureValueStr; - // List allFeatureValueTwoList = charListChangeIntList(featureValue); - print("featureValueLength:$featureValueLength featureValue:$featureValue \n featureValueStr:$featureValueStr"); - index = index + featureValueLength + 1; - - // 使能特征值字符串长度 - var featureEnValLength = reply.data[index]; - // 使能锁特征值说明(本机启用的功能) - var featureEnVal = reply.data.sublist(index+1, index + featureEnValLength+1); - String featureEnValStr = asciiString(featureValue); - state.featureSettingValue = featureEnValStr; - // List allFeatureEnValTwoList = charListChangeIntList(featureEnVal); - print("featureEnValLength:$featureEnValLength featureEnVal:$featureEnVal \n featureEnValStr:$featureEnValStr"); - index = index + featureEnValLength + 1; - - // 支持的带参数特征值的总条目数 - // var featureParaTotal = reply.data[index]; - - var featureParaTotalList = reply.data.sublist(index); - state.featureSettingParams = featureParaTotalList; - // print("featureParaTotalList:$featureParaTotalList"); - - break; - case 0x06: - //无权限 - print("${reply.commandType}需要鉴权"); - - break; - case 0x07: - //无权限 - print("${reply.commandType}用户无权限"); - - break; - case 0x09: - // 权限校验错误 - print("${reply.commandType}权限校验错误"); - - break; - default: - //失败 - print("${reply.commandType}失败"); - - break; - } - } - - List charListChangeIntList(List featureValue){ - // 字符数组转化为16进制字符串 - String featureValueStr = asciiString(featureValue); - // 16进制字符串转化为2进制的字符串 获取的是逆序的需要倒序 前面有0会消失 需要自动补全 暂时定位57个功能 要补全60 - String featureValueTwoStr = int.parse(featureValueStr,radix: 16).toRadixString(2); - List featureValueTwoList = []; - for(int i = 0;i addUserConnectBlue() async { // 进来之后首先连接 - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected){ + BlueManage().judgeReconnect( + BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, + (DeviceConnectionState state) async { + if (state == DeviceConnectionState.connected) { // 私钥 var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -282,32 +116,31 @@ class SaveLockLogic extends BaseGetXController { List publicKeyDataList = changeStringListToIntList(publicKey!); var token = await Storage.getStringList(saveBlueToken); - List getTokenList = [0,0,0,0]; - if(token != null){ + List getTokenList = [0, 0, 0, 0]; + if (token != null) { getTokenList = changeStringListToIntList(token); } IoSenderManage.senderAddUser( lockID: BlueManage().connectDeviceName, - authUserID:await Storage.getUid(), - keyID:"1", - userID:await Storage.getUid(), - openMode:1, - keyType:1, - startDate:DateTime.now().millisecondsSinceEpoch, - expireDate:0x11223344, - role:255, - password:"123456", - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: getTokenList - ); + authUserID: await Storage.getUid(), + keyID: "1", + userID: await Storage.getUid(), + openMode: 1, + keyType: 1, + startDate: DateTime.now().millisecondsSinceEpoch, + expireDate: 0x11223344, + role: 255, + password: "123456", + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList); } }); } - void bindBlueAdmin() async{ + void bindBlueAdmin() async { print("state.lockInfo:${state.lockInfo}"); var positionMap = {}; @@ -339,44 +172,22 @@ class SaveLockLogic extends BaseGetXController { // print("addUser:publicKeyDataList$publicKeyDataList getPrivateKeyList:$getPrivateKeyList signKeyDataList:$signKeyDataList"); var entity = await ApiRepository.to.bindingBlueAdmin( - lockAlias:state.aliName.value, - position:positionMap, - bluetooth:bluetooth, - lockInfo: state.lockInfo, - lockUserNo:state.lockUserNo.toString(), - pwdTimestamp:state.pwdTimestamp.value.toString(), - featureValue:state.featureValue, - featureSettingValue:state.featureSettingValue, - featureSettingParams:state.featureSettingParams, + lockAlias: state.aliName.value, + position: positionMap, + bluetooth: bluetooth, + lockInfo: state.lockInfo, + lockUserNo: state.lockUserNo.toString(), + pwdTimestamp: state.pwdTimestamp.value.toString(), + featureValue: state.featureValue, + featureSettingValue: state.featureSettingValue, + featureSettingParams: state.featureSettingParams, ); - if(entity.errorCode!.codeIsSuccessful){ + if (entity.errorCode!.codeIsSuccessful) { eventBus.fire(RefreshLockListInfoDataEvent()); Get.offAllNamed(Routers.starLockMain); } } - // 获取锁状态 - Future _getStarLockStatus() async { - // print("connectDeviceMacAddress:${BlueManage().connectDeviceMacAddress} connectDeviceName:${BlueManage().connectDeviceName}"); - // 进来之后首先连接 - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async { - if (state == DeviceConnectionState.connected) { - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - // IoSenderManage.senderGetLockStatu( - // lockID:BlueManage().connectDeviceName, - // userID:await Storage.getUid(), - // privateKey:getPrivateKeyList, - // ); - IoSenderManage.senderGetStarLockStatuInfo( - lockID:BlueManage().connectDeviceName, - userID:await Storage.getUid(), - privateKey:getPrivateKeyList, - ); - } - }, isShowLoading: false); - } - @override void onReady() { // TODO: implement onReady @@ -384,8 +195,6 @@ class SaveLockLogic extends BaseGetXController { print("onReady()"); _initReplySubscription(); - - _getStarLockStatus(); } @override @@ -393,7 +202,6 @@ class SaveLockLogic extends BaseGetXController { // TODO: implement onInit super.onInit(); print("onInit()"); - } @override @@ -402,5 +210,4 @@ class SaveLockLogic extends BaseGetXController { super.onClose(); _replySubscription.cancel(); } - -} \ No newline at end of file +} diff --git a/star_lock/lib/mine/addLock/saveLock/saveLock_state.dart b/star_lock/lib/mine/addLock/saveLock/saveLock_state.dart index 1907d811..55fa4f21 100644 --- a/star_lock/lib/mine/addLock/saveLock/saveLock_state.dart +++ b/star_lock/lib/mine/addLock/saveLock/saveLock_state.dart @@ -24,6 +24,10 @@ class SaveLockState { Map map = Get.arguments; pwdTimestamp.value = map["pwdTimestamp"]; addressInfo.value = map["addressInfo"]; + lockInfo = map["lockInfo"]; + featureValue = map["featureValue"]; + featureSettingValue = map["featureSettingValue"]; + featureSettingParams = map["featureSettingParams"]; } void onClose() { diff --git a/star_lock/lib/mine/mineSet/addAuthorizedAdministrator/addAuthorizedAdministrator_page.dart b/star_lock/lib/mine/mineSet/addAuthorizedAdministrator/addAuthorizedAdministrator_page.dart index ef820af2..a42b2904 100644 --- a/star_lock/lib/mine/mineSet/addAuthorizedAdministrator/addAuthorizedAdministrator_page.dart +++ b/star_lock/lib/mine/mineSet/addAuthorizedAdministrator/addAuthorizedAdministrator_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get_utils/get_utils.dart'; import 'package:star_lock/appRouters.dart'; @@ -10,6 +10,8 @@ import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/commonItem.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/submitBtn.dart'; import 'package:star_lock/tools/toast.dart'; import 'package:star_lock/translations/trans_lib.dart'; diff --git a/star_lock/lib/mine/mineSet/authorizedAdministrator/administratorDetails/adminDetailChangeDate_page.dart b/star_lock/lib/mine/mineSet/authorizedAdministrator/administratorDetails/adminDetailChangeDate_page.dart index 0535d515..ec95a42e 100644 --- a/star_lock/lib/mine/mineSet/authorizedAdministrator/administratorDetails/adminDetailChangeDate_page.dart +++ b/star_lock/lib/mine/mineSet/authorizedAdministrator/administratorDetails/adminDetailChangeDate_page.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; import 'package:star_lock/mine/mineSet/authorizedAdministrator/authorizedAdminListEntity.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../../app_settings/app_colors.dart'; diff --git a/star_lock/lib/mine/mineSet/lockUserManage/expireLockList/expireLockChangeDate_page.dart b/star_lock/lib/mine/mineSet/lockUserManage/expireLockList/expireLockChangeDate_page.dart index c71279e9..102064af 100644 --- a/star_lock/lib/mine/mineSet/lockUserManage/expireLockList/expireLockChangeDate_page.dart +++ b/star_lock/lib/mine/mineSet/lockUserManage/expireLockList/expireLockChangeDate_page.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:flutter_pickers/pickers.dart'; -import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/pickers.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; import 'package:star_lock/mine/mineSet/lockUserManage/expireLockList/expireLockListEntity.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/pickers/pickers.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; import 'package:star_lock/tools/toast.dart'; import '../../../../../app_settings/app_colors.dart'; diff --git a/star_lock/lib/mine/mineSet/mineSet/mineSet_logic.dart b/star_lock/lib/mine/mineSet/mineSet/mineSet_logic.dart index a8831ed0..6b758a3c 100644 --- a/star_lock/lib/mine/mineSet/mineSet/mineSet_logic.dart +++ b/star_lock/lib/mine/mineSet/mineSet/mineSet_logic.dart @@ -7,6 +7,7 @@ import 'package:star_lock/mine/mineSet/mineSet/mineSet_state.dart'; import 'package:star_lock/tools/storage.dart'; import '../../../../network/api_repository.dart'; import '../../../../tools/baseGetXController.dart'; +import '../../../blue/blue_manage.dart'; import '../../../tools/eventBusEventManage.dart'; import '../../../tools/toast.dart'; @@ -52,13 +53,16 @@ class MineSetLogic extends BaseGetXController { LoginEntity entity = await ApiRepository.to.userLogout(); if (entity.errorCode!.codeIsSuccessful) { logOut(); + BlueManage().stopScan(); + BlueManage().disconnect(BlueManage().connectDeviceMacAddress); Get.offNamedUntil(Routers.starLockLoginPage, (route) => false); } } ///退出登录 void logOut() async { - await Storage.setString('userLoginData', ''); + Storage.clearAll(); + // await Storage.setString('userLoginData', ''); } //更新触摸开锁 diff --git a/star_lock/lib/network/api.dart b/star_lock/lib/network/api.dart index f561dd85..a150c7c7 100644 --- a/star_lock/lib/network/api.dart +++ b/star_lock/lib/network/api.dart @@ -29,6 +29,7 @@ abstract class Api { final String getLockRecordLastUploadDataTimeURL = '/lockRecords/getLastRecordTime'; //查询锁记录最后时间 final String getLockNetTokenURL = '/lock/getLockNetToken'; //获取手机联网token + final String updateLockUserNoURL = '/key/updateLockUserNo'; //更新锁用户NO final String bindingBlueAdminURL = '/lock/bindAdmin'; //绑定蓝牙管理员 final String modifyKeyNameURL = '/key/modifyKeyName'; //修改锁名称 diff --git a/star_lock/lib/network/api_provider.dart b/star_lock/lib/network/api_provider.dart index c48dd407..af5e9971 100644 --- a/star_lock/lib/network/api_provider.dart +++ b/star_lock/lib/network/api_provider.dart @@ -279,6 +279,15 @@ class ApiProvider extends BaseProvider { }), isUnShowLoading: true); + // 更新锁用户NO + Future updateLockUserNo(String keyId, String lockUserNo) => post( + updateLockUserNoURL.toUrl, + jsonEncode({ + 'keyId': keyId, + 'lockUserNo': lockUserNo, + }), + isUnShowLoading: true); + // 绑定蓝牙管理员 Future bindingBlueAdmin( String lockAlias, @@ -336,7 +345,7 @@ class ApiProvider extends BaseProvider { // 删除拥有的当前钥匙 Future deletOwnerKeyInfo(String lockId, String keyId) => post( - deletLockURL.toUrl, + deleteElectronicKeyURL.toUrl, jsonEncode({ 'lockId': lockId, 'keyId': keyId @@ -958,7 +967,8 @@ class ApiProvider extends BaseProvider { String startDate, String endDate, String isCoerced, - String fingerprintName) => + String fingerprintName, + String changeType) => post( editFingerprintURL.toUrl, jsonEncode({ @@ -968,7 +978,8 @@ class ApiProvider extends BaseProvider { 'startDate': startDate, 'endDate': endDate, 'isCoerced': isCoerced, - 'fingerprintName': fingerprintName + 'fingerprintName': fingerprintName, + 'changeType': changeType })); // 删除指纹 @@ -1034,7 +1045,7 @@ class ApiProvider extends BaseProvider { // 编辑ICCard Future editICCardData(String lockId, String cardId, String cardName, - String startDate, String endDate, String isCoerced, List weekDay) => + String startDate, String endDate, String isCoerced, List weekDay, String changeType) => post( editICCardURL.toUrl, jsonEncode({ @@ -1044,7 +1055,8 @@ class ApiProvider extends BaseProvider { 'startDate': startDate, 'endDate': endDate, 'isCoerced': isCoerced, - 'weekDay': weekDay + 'weekDay': weekDay, + 'changeType': changeType })); // 删除卡 diff --git a/star_lock/lib/network/api_provider_base.dart b/star_lock/lib/network/api_provider_base.dart index cfd44cec..796d5700 100644 --- a/star_lock/lib/network/api_provider_base.dart +++ b/star_lock/lib/network/api_provider_base.dart @@ -56,9 +56,7 @@ class BaseProvider extends GetConnect with Api { body: rs as T, statusText: res.statusText, ); - }else{ - - } + } else {} // print('得到的数据======>bodyString:${res.bodyString} body:${res.body} bodyBytes:${res.bodyBytes} status:${res.status} statusText:${res.statusText} statusCode:${res.statusCode}'); getDataResult(res.body); return res; diff --git a/star_lock/lib/network/api_repository.dart b/star_lock/lib/network/api_repository.dart index f3faf500..ee55448d 100644 --- a/star_lock/lib/network/api_repository.dart +++ b/star_lock/lib/network/api_repository.dart @@ -22,6 +22,7 @@ import '../common/safetyVerification/entity/SafetyVerificationEntity.dart'; import '../login/login/entity/LoginEntity.dart'; import '../login/register/entity/SendValidationCodeEntity.dart'; import '../main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_entity.dart'; +import '../main/lockDetail/card/addICCard/addICCard_entity.dart'; import '../main/lockDetail/checkingIn/checkingInDetail/checkingInDetail_entity.dart'; import '../main/lockDetail/checkingIn/checkingInHolidays/checkingInSetHolidays/checkingInSetHolidays_entity.dart'; import '../main/lockDetail/checkingIn/checkingInList/checkingInListDay_entity.dart'; @@ -29,15 +30,14 @@ import '../main/lockDetail/checkingIn/checkingInList/checkingInListMonth_entity. import '../main/lockDetail/checkingIn/checkingInSet/checkingInSet_entity.dart'; import '../main/lockDetail/checkingIn/checkingInStaff/checkingInSetAddStaff/checkingInAddStaffSeletKey_entity.dart'; import '../main/lockDetail/checkingIn/checkingInStaff/checkingInSetStaffList/checkingInStaffList_entity.dart'; +import '../main/lockDetail/fingerprint/addFingerprint/addFingerprint_entity.dart'; +import '../main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; import '../main/lockDetail/lcokSet/configuringWifi/configuringWifiEntity.dart'; import '../main/lockDetail/lcokSet/lockSet/checkingInInfoData_entity.dart'; import '../main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart'; import '../main/lockDetail/lcokSet/lockTime/getServerDatetime_entity.dart'; import '../main/lockDetail/lockDetail/lockNetToken_entity.dart'; import '../main/lockDetail/lockOperatingRecord/lockOperatingRecordGetLastRecordTime_entity.dart'; -import '../main/lockDetail/otherTypeKey/addFingerprint/addFingerprint/addFingerprint_entity.dart'; -import '../main/lockDetail/otherTypeKey/addICCard/addICCard_entity.dart'; -import '../main/lockDetail/otherTypeKey/otherTypeKeyList/fingerprintListData_entity.dart'; import '../main/lockMian/entity/lockListInfo_entity.dart'; import '../mine/addLock/saveLock/entity/SaveLockEntity.dart'; import '../mine/minePersonInfo/minePersonInfoPage/minePersonGetUploadFileInfo_entity.dart'; @@ -217,8 +217,7 @@ class ApiRepository { } //操作记录上传 - Future lockRecordUploadData( - {required String lockId, required List records}) async { + Future lockRecordUploadData({required String lockId, required List records}) async { final res = await apiProvider.lockRecordUploadData(lockId, records); return KeyOperationRecordEntity.fromJson(res.body); } @@ -236,6 +235,12 @@ class ApiRepository { return LockNetTokenEntity.fromJson(res.body); } + // 更新锁用户NO + Future updateLockUserNo({required String keyId, required String lockUserNo}) async { + final res = await apiProvider.updateLockUserNo(keyId, lockUserNo); + return LockNetTokenEntity.fromJson(res.body); + } + // 绑定蓝牙管理员 Future bindingBlueAdmin( { required String lockAlias, @@ -1115,9 +1120,10 @@ class ApiRepository { required String startDate, required String endDate, required String isCoerced, - required String fingerprintName}) async { + required String fingerprintName, + required String changeType}) async { final res = await apiProvider.editFingerprintsData(fingerprintId, lockId, - weekDay, startDate, endDate, isCoerced, fingerprintName); + weekDay, startDate, endDate, isCoerced, fingerprintName, changeType); return LoginEntity.fromJson(res.body); } @@ -1179,9 +1185,10 @@ class ApiRepository { required String startDate, required String endDate, required String isCoerced, - required List weekDay}) async { + required List weekDay, + required String changeType}) async { final res = await apiProvider.editICCardData( - lockId, cardId, cardName, startDate, endDate, isCoerced, weekDay); + lockId, cardId, cardName, startDate, endDate, isCoerced, weekDay, changeType); return LoginEntity.fromJson(res.body); } diff --git a/star_lock/lib/network/response_interceptor_log.dart b/star_lock/lib/network/response_interceptor_log.dart index 13e111a4..6b7a5e43 100644 --- a/star_lock/lib/network/response_interceptor_log.dart +++ b/star_lock/lib/network/response_interceptor_log.dart @@ -4,8 +4,7 @@ import 'package:get/get.dart'; import 'package:get/get_connect/http/src/request/request.dart'; FutureOr responseLogInterceptor(Request request, Response response) { - Get.log( - 'HTTP RESPONSE =>\n stataCode:${response.statusCode} ${response.body} ${response.headers}'); + Get.log('HTTP request:${request.url}\n RESPONSE => stataCode:${response.statusCode} ${response.body} ${response.headers}'); EasyLoading.dismiss(animation: true); return response; } diff --git a/star_lock/lib/tools/commonItem.dart b/star_lock/lib/tools/commonItem.dart index 4f0790a8..e75edfdf 100644 --- a/star_lock/lib/tools/commonItem.dart +++ b/star_lock/lib/tools/commonItem.dart @@ -59,18 +59,24 @@ class CommonItem extends StatelessWidget { children: [ isHaveRightWidget! ? rightWidget! - : Text(rightTitle ?? "", textAlign: TextAlign.end, + : Text( + rightTitle ?? "", + textAlign: TextAlign.right, overflow: TextOverflow.ellipsis, - maxLines: 1, + maxLines: 2, style: TextStyle( fontSize: 22.sp, color: AppColors.darkGrayTextColor), - ) + ), ], ), isHaveDirection! ? SizedBox(width: 3.w) : Container(), isHaveDirection! - ? Image.asset('images/icon_right_grey.png', width: 12.w, height: 21.w,) + ? Image.asset( + 'images/icon_right_grey.png', + width: 12.w, + height: 21.w, + ) : SizedBox(width: 10.w), isHaveDirection! ? SizedBox(width: 5.w) : Container(), ], diff --git a/star_lock/lib/tools/pickers/address_picker/locations_data.dart b/star_lock/lib/tools/pickers/address_picker/locations_data.dart new file mode 100644 index 00000000..89484820 --- /dev/null +++ b/star_lock/lib/tools/pickers/address_picker/locations_data.dart @@ -0,0 +1,4311 @@ +import '../utils/check.dart'; + +/// 数据地址:https://github.com/airyland/china-area-data/blob/master/data.json +const locations = { + "86": { + "110000": "北京市", + "120000": "天津市", + "130000": "河北省", + "140000": "山西省", + "150000": "内蒙古自治区", + "210000": "辽宁省", + "220000": "吉林省", + "230000": "黑龙江省", + "310000": "上海市", + "320000": "江苏省", + "330000": "浙江省", + "340000": "安徽省", + "350000": "福建省", + "360000": "江西省", + "370000": "山东省", + "410000": "河南省", + "420000": "湖北省", + "430000": "湖南省", + "440000": "广东省", + "450000": "广西壮族自治区", + "460000": "海南省", + "500000": "重庆市", + "510000": "四川省", + "520000": "贵州省", + "530000": "云南省", + "540000": "西藏自治区", + "610000": "陕西省", + "620000": "甘肃省", + "630000": "青海省", + "640000": "宁夏回族自治区", + "650000": "新疆维吾尔自治区", + "710000": "台湾省", + "810000": "香港特别行政区", + "820000": "澳门特别行政区" + }, + "110000": {"110100": "市辖区"}, + "110100": { + "110101": "东城区", + "110102": "西城区", + "110105": "朝阳区", + "110106": "丰台区", + "110107": "石景山区", + "110108": "海淀区", + "110109": "门头沟区", + "110111": "房山区", + "110112": "通州区", + "110113": "顺义区", + "110114": "昌平区", + "110115": "大兴区", + "110116": "怀柔区", + "110117": "平谷区", + "110118": "密云区", + "110119": "延庆区" + }, + "120000": {"120100": "市辖区"}, + "120100": { + "120101": "和平区", + "120102": "河东区", + "120103": "河西区", + "120104": "南开区", + "120105": "河北区", + "120106": "红桥区", + "120110": "东丽区", + "120111": "西青区", + "120112": "津南区", + "120113": "北辰区", + "120114": "武清区", + "120115": "宝坻区", + "120116": "滨海新区", + "120117": "宁河区", + "120118": "静海区", + "120119": "蓟州区" + }, + "130000": { + "130100": "石家庄市", + "130200": "唐山市", + "130300": "秦皇岛市", + "130400": "邯郸市", + "130500": "邢台市", + "130600": "保定市", + "130700": "张家口市", + "130800": "承德市", + "130900": "沧州市", + "131000": "廊坊市", + "131100": "衡水市" + }, + "130100": { + "130101": "市辖区", + "130102": "长安区", + "130104": "桥西区", + "130105": "新华区", + "130107": "井陉矿区", + "130108": "裕华区", + "130109": "藁城区", + "130110": "鹿泉区", + "130111": "栾城区", + "130121": "井陉县", + "130123": "正定县", + "130125": "行唐县", + "130126": "灵寿县", + "130127": "高邑县", + "130128": "深泽县", + "130129": "赞皇县", + "130130": "无极县", + "130131": "平山县", + "130132": "元氏县", + "130133": "赵县", + "130171": "石家庄高新技术产业开发区", + "130172": "石家庄循环化工园区", + "130181": "辛集市", + "130183": "晋州市", + "130184": "新乐市" + }, + "130200": { + "130201": "市辖区", + "130202": "路南区", + "130203": "路北区", + "130204": "古冶区", + "130205": "开平区", + "130207": "丰南区", + "130208": "丰润区", + "130209": "曹妃甸区", + "130224": "滦南县", + "130225": "乐亭县", + "130227": "迁西县", + "130229": "玉田县", + "130271": "河北唐山芦台经济开发区", + "130272": "唐山市汉沽管理区", + "130273": "唐山高新技术产业开发区", + "130274": "河北唐山海港经济开发区", + "130281": "遵化市", + "130283": "迁安市", + "130284": "滦州市" + }, + "130300": { + "130301": "市辖区", + "130302": "海港区", + "130303": "山海关区", + "130304": "北戴河区", + "130306": "抚宁区", + "130321": "青龙满族自治县", + "130322": "昌黎县", + "130324": "卢龙县", + "130371": "秦皇岛市经济技术开发区", + "130372": "北戴河新区" + }, + "130400": { + "130401": "市辖区", + "130402": "邯山区", + "130403": "丛台区", + "130404": "复兴区", + "130406": "峰峰矿区", + "130407": "肥乡区", + "130408": "永年区", + "130423": "临漳县", + "130424": "成安县", + "130425": "大名县", + "130426": "涉县", + "130427": "磁县", + "130430": "邱县", + "130431": "鸡泽县", + "130432": "广平县", + "130433": "馆陶县", + "130434": "魏县", + "130435": "曲周县", + "130471": "邯郸经济技术开发区", + "130473": "邯郸冀南新区", + "130481": "武安市" + }, + "130500": { + "130501": "市辖区", + "130502": "桥东区", + "130503": "桥西区", + "130521": "邢台县", + "130522": "临城县", + "130523": "内丘县", + "130524": "柏乡县", + "130525": "隆尧县", + "130526": "任县", + "130527": "南和县", + "130528": "宁晋县", + "130529": "巨鹿县", + "130530": "新河县", + "130531": "广宗县", + "130532": "平乡县", + "130533": "威县", + "130534": "清河县", + "130535": "临西县", + "130571": "河北邢台经济开发区", + "130581": "南宫市", + "130582": "沙河市" + }, + "130600": { + "130601": "市辖区", + "130602": "竞秀区", + "130606": "莲池区", + "130607": "满城区", + "130608": "清苑区", + "130609": "徐水区", + "130623": "涞水县", + "130624": "阜平县", + "130626": "定兴县", + "130627": "唐县", + "130628": "高阳县", + "130629": "容城县", + "130630": "涞源县", + "130631": "望都县", + "130632": "安新县", + "130633": "易县", + "130634": "曲阳县", + "130635": "蠡县", + "130636": "顺平县", + "130637": "博野县", + "130638": "雄县", + "130671": "保定高新技术产业开发区", + "130672": "保定白沟新城", + "130681": "涿州市", + "130682": "定州市", + "130683": "安国市", + "130684": "高碑店市" + }, + "130700": { + "130701": "市辖区", + "130702": "桥东区", + "130703": "桥西区", + "130705": "宣化区", + "130706": "下花园区", + "130708": "万全区", + "130709": "崇礼区", + "130722": "张北县", + "130723": "康保县", + "130724": "沽源县", + "130725": "尚义县", + "130726": "蔚县", + "130727": "阳原县", + "130728": "怀安县", + "130730": "怀来县", + "130731": "涿鹿县", + "130732": "赤城县", + "130771": "张家口经济开发区", + "130772": "张家口市察北管理区", + "130773": "张家口市塞北管理区" + }, + "130800": { + "130801": "市辖区", + "130802": "双桥区", + "130803": "双滦区", + "130804": "鹰手营子矿区", + "130821": "承德县", + "130822": "兴隆县", + "130824": "滦平县", + "130825": "隆化县", + "130826": "丰宁满族自治县", + "130827": "宽城满族自治县", + "130828": "围场满族蒙古族自治县", + "130871": "承德高新技术产业开发区", + "130881": "平泉市" + }, + "130900": { + "130901": "市辖区", + "130902": "新华区", + "130903": "运河区", + "130921": "沧县", + "130922": "青县", + "130923": "东光县", + "130924": "海兴县", + "130925": "盐山县", + "130926": "肃宁县", + "130927": "南皮县", + "130928": "吴桥县", + "130929": "献县", + "130930": "孟村回族自治县", + "130971": "河北沧州经济开发区", + "130972": "沧州高新技术产业开发区", + "130973": "沧州渤海新区", + "130981": "泊头市", + "130982": "任丘市", + "130983": "黄骅市", + "130984": "河间市" + }, + "131000": { + "131001": "市辖区", + "131002": "安次区", + "131003": "广阳区", + "131022": "固安县", + "131023": "永清县", + "131024": "香河县", + "131025": "大城县", + "131026": "文安县", + "131028": "大厂回族自治县", + "131071": "廊坊经济技术开发区", + "131081": "霸州市", + "131082": "三河市" + }, + "131100": { + "131101": "市辖区", + "131102": "桃城区", + "131103": "冀州区", + "131121": "枣强县", + "131122": "武邑县", + "131123": "武强县", + "131124": "饶阳县", + "131125": "安平县", + "131126": "故城县", + "131127": "景县", + "131128": "阜城县", + "131171": "河北衡水高新技术产业开发区", + "131172": "衡水滨湖新区", + "131182": "深州市" + }, + "140000": { + "140100": "太原市", + "140200": "大同市", + "140300": "阳泉市", + "140400": "长治市", + "140500": "晋城市", + "140600": "朔州市", + "140700": "晋中市", + "140800": "运城市", + "140900": "忻州市", + "141000": "临汾市", + "141100": "吕梁市" + }, + "140100": { + "140101": "市辖区", + "140105": "小店区", + "140106": "迎泽区", + "140107": "杏花岭区", + "140108": "尖草坪区", + "140109": "万柏林区", + "140110": "晋源区", + "140121": "清徐县", + "140122": "阳曲县", + "140123": "娄烦县", + "140171": "山西转型综合改革示范区", + "140181": "古交市" + }, + "140200": { + "140201": "市辖区", + "140212": "新荣区", + "140213": "平城区", + "140214": "云冈区", + "140215": "云州区", + "140221": "阳高县", + "140222": "天镇县", + "140223": "广灵县", + "140224": "灵丘县", + "140225": "浑源县", + "140226": "左云县", + "140271": "山西大同经济开发区" + }, + "140300": {"140301": "市辖区", "140302": "城区", "140303": "矿区", "140311": "郊区", "140321": "平定县", "140322": "盂县"}, + "140400": { + "140401": "市辖区", + "140403": "潞州区", + "140404": "上党区", + "140405": "屯留区", + "140406": "潞城区", + "140423": "襄垣县", + "140425": "平顺县", + "140426": "黎城县", + "140427": "壶关县", + "140428": "长子县", + "140429": "武乡县", + "140430": "沁县", + "140431": "沁源县", + "140471": "山西长治高新技术产业园区" + }, + "140500": { + "140501": "市辖区", + "140502": "城区", + "140521": "沁水县", + "140522": "阳城县", + "140524": "陵川县", + "140525": "泽州县", + "140581": "高平市" + }, + "140600": { + "140601": "市辖区", + "140602": "朔城区", + "140603": "平鲁区", + "140621": "山阴县", + "140622": "应县", + "140623": "右玉县", + "140671": "山西朔州经济开发区", + "140681": "怀仁市" + }, + "140700": { + "140701": "市辖区", + "140702": "榆次区", + "140721": "榆社县", + "140722": "左权县", + "140723": "和顺县", + "140724": "昔阳县", + "140725": "寿阳县", + "140726": "太谷县", + "140727": "祁县", + "140728": "平遥县", + "140729": "灵石县", + "140781": "介休市" + }, + "140800": { + "140801": "市辖区", + "140802": "盐湖区", + "140821": "临猗县", + "140822": "万荣县", + "140823": "闻喜县", + "140824": "稷山县", + "140825": "新绛县", + "140826": "绛县", + "140827": "垣曲县", + "140828": "夏县", + "140829": "平陆县", + "140830": "芮城县", + "140881": "永济市", + "140882": "河津市" + }, + "140900": { + "140901": "市辖区", + "140902": "忻府区", + "140921": "定襄县", + "140922": "五台县", + "140923": "代县", + "140924": "繁峙县", + "140925": "宁武县", + "140926": "静乐县", + "140927": "神池县", + "140928": "五寨县", + "140929": "岢岚县", + "140930": "河曲县", + "140931": "保德县", + "140932": "偏关县", + "140971": "五台山风景名胜区", + "140981": "原平市" + }, + "141000": { + "141001": "市辖区", + "141002": "尧都区", + "141021": "曲沃县", + "141022": "翼城县", + "141023": "襄汾县", + "141024": "洪洞县", + "141025": "古县", + "141026": "安泽县", + "141027": "浮山县", + "141028": "吉县", + "141029": "乡宁县", + "141030": "大宁县", + "141031": "隰县", + "141032": "永和县", + "141033": "蒲县", + "141034": "汾西县", + "141081": "侯马市", + "141082": "霍州市" + }, + "141100": { + "141101": "市辖区", + "141102": "离石区", + "141121": "文水县", + "141122": "交城县", + "141123": "兴县", + "141124": "临县", + "141125": "柳林县", + "141126": "石楼县", + "141127": "岚县", + "141128": "方山县", + "141129": "中阳县", + "141130": "交口县", + "141181": "孝义市", + "141182": "汾阳市" + }, + "150000": { + "150100": "呼和浩特市", + "150200": "包头市", + "150300": "乌海市", + "150400": "赤峰市", + "150500": "通辽市", + "150600": "鄂尔多斯市", + "150700": "呼伦贝尔市", + "150800": "巴彦淖尔市", + "150900": "乌兰察布市", + "152200": "兴安盟", + "152500": "锡林郭勒盟", + "152900": "阿拉善盟" + }, + "150100": { + "150101": "市辖区", + "150102": "新城区", + "150103": "回民区", + "150104": "玉泉区", + "150105": "赛罕区", + "150121": "土默特左旗", + "150122": "托克托县", + "150123": "和林格尔县", + "150124": "清水河县", + "150125": "武川县", + "150171": "呼和浩特金海工业园区", + "150172": "呼和浩特经济技术开发区" + }, + "150200": { + "150201": "市辖区", + "150202": "东河区", + "150203": "昆都仑区", + "150204": "青山区", + "150205": "石拐区", + "150206": "白云鄂博矿区", + "150207": "九原区", + "150221": "土默特右旗", + "150222": "固阳县", + "150223": "达尔罕茂明安联合旗", + "150271": "包头稀土高新技术产业开发区" + }, + "150300": {"150301": "市辖区", "150302": "海勃湾区", "150303": "海南区", "150304": "乌达区"}, + "150400": { + "150401": "市辖区", + "150402": "红山区", + "150403": "元宝山区", + "150404": "松山区", + "150421": "阿鲁科尔沁旗", + "150422": "巴林左旗", + "150423": "巴林右旗", + "150424": "林西县", + "150425": "克什克腾旗", + "150426": "翁牛特旗", + "150428": "喀喇沁旗", + "150429": "宁城县", + "150430": "敖汉旗" + }, + "150500": { + "150501": "市辖区", + "150502": "科尔沁区", + "150521": "科尔沁左翼中旗", + "150522": "科尔沁左翼后旗", + "150523": "开鲁县", + "150524": "库伦旗", + "150525": "奈曼旗", + "150526": "扎鲁特旗", + "150571": "通辽经济技术开发区", + "150581": "霍林郭勒市" + }, + "150600": { + "150601": "市辖区", + "150602": "东胜区", + "150603": "康巴什区", + "150621": "达拉特旗", + "150622": "准格尔旗", + "150623": "鄂托克前旗", + "150624": "鄂托克旗", + "150625": "杭锦旗", + "150626": "乌审旗", + "150627": "伊金霍洛旗" + }, + "150700": { + "150701": "市辖区", + "150702": "海拉尔区", + "150703": "扎赉诺尔区", + "150721": "阿荣旗", + "150722": "莫力达瓦达斡尔族自治旗", + "150723": "鄂伦春自治旗", + "150724": "鄂温克族自治旗", + "150725": "陈巴尔虎旗", + "150726": "新巴尔虎左旗", + "150727": "新巴尔虎右旗", + "150781": "满洲里市", + "150782": "牙克石市", + "150783": "扎兰屯市", + "150784": "额尔古纳市", + "150785": "根河市" + }, + "150800": { + "150801": "市辖区", + "150802": "临河区", + "150821": "五原县", + "150822": "磴口县", + "150823": "乌拉特前旗", + "150824": "乌拉特中旗", + "150825": "乌拉特后旗", + "150826": "杭锦后旗" + }, + "150900": { + "150901": "市辖区", + "150902": "集宁区", + "150921": "卓资县", + "150922": "化德县", + "150923": "商都县", + "150924": "兴和县", + "150925": "凉城县", + "150926": "察哈尔右翼前旗", + "150927": "察哈尔右翼中旗", + "150928": "察哈尔右翼后旗", + "150929": "四子王旗", + "150981": "丰镇市" + }, + "152200": { + "152201": "乌兰浩特市", + "152202": "阿尔山市", + "152221": "科尔沁右翼前旗", + "152222": "科尔沁右翼中旗", + "152223": "扎赉特旗", + "152224": "突泉县" + }, + "152500": { + "152501": "二连浩特市", + "152502": "锡林浩特市", + "152522": "阿巴嘎旗", + "152523": "苏尼特左旗", + "152524": "苏尼特右旗", + "152525": "东乌珠穆沁旗", + "152526": "西乌珠穆沁旗", + "152527": "太仆寺旗", + "152528": "镶黄旗", + "152529": "正镶白旗", + "152530": "正蓝旗", + "152531": "多伦县", + "152571": "乌拉盖管委会" + }, + "152900": {"152921": "阿拉善左旗", "152922": "阿拉善右旗", "152923": "额济纳旗", "152971": "内蒙古阿拉善经济开发区"}, + "210000": { + "210100": "沈阳市", + "210200": "大连市", + "210300": "鞍山市", + "210400": "抚顺市", + "210500": "本溪市", + "210600": "丹东市", + "210700": "锦州市", + "210800": "营口市", + "210900": "阜新市", + "211000": "辽阳市", + "211100": "盘锦市", + "211200": "铁岭市", + "211300": "朝阳市", + "211400": "葫芦岛市" + }, + "210100": { + "210101": "市辖区", + "210102": "和平区", + "210103": "沈河区", + "210104": "大东区", + "210105": "皇姑区", + "210106": "铁西区", + "210111": "苏家屯区", + "210112": "浑南区", + "210113": "沈北新区", + "210114": "于洪区", + "210115": "辽中区", + "210123": "康平县", + "210124": "法库县", + "210181": "新民市" + }, + "210200": { + "210201": "市辖区", + "210202": "中山区", + "210203": "西岗区", + "210204": "沙河口区", + "210211": "甘井子区", + "210212": "旅顺口区", + "210213": "金州区", + "210214": "普兰店区", + "210224": "长海县", + "210281": "瓦房店市", + "210283": "庄河市" + }, + "210300": { + "210301": "市辖区", + "210302": "铁东区", + "210303": "铁西区", + "210304": "立山区", + "210311": "千山区", + "210321": "台安县", + "210323": "岫岩满族自治县", + "210381": "海城市" + }, + "210400": { + "210401": "市辖区", + "210402": "新抚区", + "210403": "东洲区", + "210404": "望花区", + "210411": "顺城区", + "210421": "抚顺县", + "210422": "新宾满族自治县", + "210423": "清原满族自治县" + }, + "210500": { + "210501": "市辖区", + "210502": "平山区", + "210503": "溪湖区", + "210504": "明山区", + "210505": "南芬区", + "210521": "本溪满族自治县", + "210522": "桓仁满族自治县" + }, + "210600": { + "210601": "市辖区", + "210602": "元宝区", + "210603": "振兴区", + "210604": "振安区", + "210624": "宽甸满族自治县", + "210681": "东港市", + "210682": "凤城市" + }, + "210700": { + "210701": "市辖区", + "210702": "古塔区", + "210703": "凌河区", + "210711": "太和区", + "210726": "黑山县", + "210727": "义县", + "210781": "凌海市", + "210782": "北镇市" + }, + "210800": { + "210801": "市辖区", + "210802": "站前区", + "210803": "西市区", + "210804": "鲅鱼圈区", + "210811": "老边区", + "210881": "盖州市", + "210882": "大石桥市" + }, + "210900": { + "210901": "市辖区", + "210902": "海州区", + "210903": "新邱区", + "210904": "太平区", + "210905": "清河门区", + "210911": "细河区", + "210921": "阜新蒙古族自治县", + "210922": "彰武县" + }, + "211000": { + "211001": "市辖区", + "211002": "白塔区", + "211003": "文圣区", + "211004": "宏伟区", + "211005": "弓长岭区", + "211011": "太子河区", + "211021": "辽阳县", + "211081": "灯塔市" + }, + "211100": {"211101": "市辖区", "211102": "双台子区", "211103": "兴隆台区", "211104": "大洼区", "211122": "盘山县"}, + "211200": { + "211201": "市辖区", + "211202": "银州区", + "211204": "清河区", + "211221": "铁岭县", + "211223": "西丰县", + "211224": "昌图县", + "211281": "调兵山市", + "211282": "开原市" + }, + "211300": { + "211301": "市辖区", + "211302": "双塔区", + "211303": "龙城区", + "211321": "朝阳县", + "211322": "建平县", + "211324": "喀喇沁左翼蒙古族自治县", + "211381": "北票市", + "211382": "凌源市" + }, + "211400": { + "211401": "市辖区", + "211402": "连山区", + "211403": "龙港区", + "211404": "南票区", + "211421": "绥中县", + "211422": "建昌县", + "211481": "兴城市" + }, + "220000": { + "220100": "长春市", + "220200": "吉林市", + "220300": "四平市", + "220400": "辽源市", + "220500": "通化市", + "220600": "白山市", + "220700": "松原市", + "220800": "白城市", + "222400": "延边朝鲜族自治州" + }, + "220100": { + "220101": "市辖区", + "220102": "南关区", + "220103": "宽城区", + "220104": "朝阳区", + "220105": "二道区", + "220106": "绿园区", + "220112": "双阳区", + "220113": "九台区", + "220122": "农安县", + "220171": "长春经济技术开发区", + "220172": "长春净月高新技术产业开发区", + "220173": "长春高新技术产业开发区", + "220174": "长春汽车经济技术开发区", + "220182": "榆树市", + "220183": "德惠市" + }, + "220200": { + "220201": "市辖区", + "220202": "昌邑区", + "220203": "龙潭区", + "220204": "船营区", + "220211": "丰满区", + "220221": "永吉县", + "220271": "吉林经济开发区", + "220272": "吉林高新技术产业开发区", + "220273": "吉林中国新加坡食品区", + "220281": "蛟河市", + "220282": "桦甸市", + "220283": "舒兰市", + "220284": "磐石市" + }, + "220300": { + "220301": "市辖区", + "220302": "铁西区", + "220303": "铁东区", + "220322": "梨树县", + "220323": "伊通满族自治县", + "220381": "公主岭市", + "220382": "双辽市" + }, + "220400": {"220401": "市辖区", "220402": "龙山区", "220403": "西安区", "220421": "东丰县", "220422": "东辽县"}, + "220500": { + "220501": "市辖区", + "220502": "东昌区", + "220503": "二道江区", + "220521": "通化县", + "220523": "辉南县", + "220524": "柳河县", + "220581": "梅河口市", + "220582": "集安市" + }, + "220600": { + "220601": "市辖区", + "220602": "浑江区", + "220605": "江源区", + "220621": "抚松县", + "220622": "靖宇县", + "220623": "长白朝鲜族自治县", + "220681": "临江市" + }, + "220700": { + "220701": "市辖区", + "220702": "宁江区", + "220721": "前郭尔罗斯蒙古族自治县", + "220722": "长岭县", + "220723": "乾安县", + "220771": "吉林松原经济开发区", + "220781": "扶余市" + }, + "220800": { + "220801": "市辖区", + "220802": "洮北区", + "220821": "镇赉县", + "220822": "通榆县", + "220871": "吉林白城经济开发区", + "220881": "洮南市", + "220882": "大安市" + }, + "222400": { + "222401": "延吉市", + "222402": "图们市", + "222403": "敦化市", + "222404": "珲春市", + "222405": "龙井市", + "222406": "和龙市", + "222424": "汪清县", + "222426": "安图县" + }, + "230000": { + "230100": "哈尔滨市", + "230200": "齐齐哈尔市", + "230300": "鸡西市", + "230400": "鹤岗市", + "230500": "双鸭山市", + "230600": "大庆市", + "230700": "伊春市", + "230800": "佳木斯市", + "230900": "七台河市", + "231000": "牡丹江市", + "231100": "黑河市", + "231200": "绥化市", + "232700": "大兴安岭地区" + }, + "230100": { + "230101": "市辖区", + "230102": "道里区", + "230103": "南岗区", + "230104": "道外区", + "230108": "平房区", + "230109": "松北区", + "230110": "香坊区", + "230111": "呼兰区", + "230112": "阿城区", + "230113": "双城区", + "230123": "依兰县", + "230124": "方正县", + "230125": "宾县", + "230126": "巴彦县", + "230127": "木兰县", + "230128": "通河县", + "230129": "延寿县", + "230183": "尚志市", + "230184": "五常市" + }, + "230200": { + "230201": "市辖区", + "230202": "龙沙区", + "230203": "建华区", + "230204": "铁锋区", + "230205": "昂昂溪区", + "230206": "富拉尔基区", + "230207": "碾子山区", + "230208": "梅里斯达斡尔族区", + "230221": "龙江县", + "230223": "依安县", + "230224": "泰来县", + "230225": "甘南县", + "230227": "富裕县", + "230229": "克山县", + "230230": "克东县", + "230231": "拜泉县", + "230281": "讷河市" + }, + "230300": { + "230301": "市辖区", + "230302": "鸡冠区", + "230303": "恒山区", + "230304": "滴道区", + "230305": "梨树区", + "230306": "城子河区", + "230307": "麻山区", + "230321": "鸡东县", + "230381": "虎林市", + "230382": "密山市" + }, + "230400": { + "230401": "市辖区", + "230402": "向阳区", + "230403": "工农区", + "230404": "南山区", + "230405": "兴安区", + "230406": "东山区", + "230407": "兴山区", + "230421": "萝北县", + "230422": "绥滨县" + }, + "230500": { + "230501": "市辖区", + "230502": "尖山区", + "230503": "岭东区", + "230505": "四方台区", + "230506": "宝山区", + "230521": "集贤县", + "230522": "友谊县", + "230523": "宝清县", + "230524": "饶河县" + }, + "230600": { + "230601": "市辖区", + "230602": "萨尔图区", + "230603": "龙凤区", + "230604": "让胡路区", + "230605": "红岗区", + "230606": "大同区", + "230621": "肇州县", + "230622": "肇源县", + "230623": "林甸县", + "230624": "杜尔伯特蒙古族自治县", + "230671": "大庆高新技术产业开发区" + }, + "230700": { + "230701": "市辖区", + "230717": "伊美区", + "230718": "乌翠区", + "230719": "友好区", + "230722": "嘉荫县", + "230723": "汤旺县", + "230724": "丰林县", + "230725": "大箐山县", + "230726": "南岔县", + "230751": "金林区", + "230781": "铁力市" + }, + "230800": { + "230801": "市辖区", + "230803": "向阳区", + "230804": "前进区", + "230805": "东风区", + "230811": "郊区", + "230822": "桦南县", + "230826": "桦川县", + "230828": "汤原县", + "230881": "同江市", + "230882": "富锦市", + "230883": "抚远市" + }, + "230900": {"230901": "市辖区", "230902": "新兴区", "230903": "桃山区", "230904": "茄子河区", "230921": "勃利县"}, + "231000": { + "231001": "市辖区", + "231002": "东安区", + "231003": "阳明区", + "231004": "爱民区", + "231005": "西安区", + "231025": "林口县", + "231071": "牡丹江经济技术开发区", + "231081": "绥芬河市", + "231083": "海林市", + "231084": "宁安市", + "231085": "穆棱市", + "231086": "东宁市" + }, + "231100": { + "231101": "市辖区", + "231102": "爱辉区", + "231123": "逊克县", + "231124": "孙吴县", + "231181": "北安市", + "231182": "五大连池市", + "231183": "嫩江市" + }, + "231200": { + "231201": "市辖区", + "231202": "北林区", + "231221": "望奎县", + "231222": "兰西县", + "231223": "青冈县", + "231224": "庆安县", + "231225": "明水县", + "231226": "绥棱县", + "231281": "安达市", + "231282": "肇东市", + "231283": "海伦市" + }, + "232700": { + "232701": "漠河市", + "232721": "呼玛县", + "232722": "塔河县", + "232761": "加格达奇区", + "232762": "松岭区", + "232763": "新林区", + "232764": "呼中区" + }, + "310000": {"310100": "市辖区"}, + "310100": { + "310101": "黄浦区", + "310104": "徐汇区", + "310105": "长宁区", + "310106": "静安区", + "310107": "普陀区", + "310109": "虹口区", + "310110": "杨浦区", + "310112": "闵行区", + "310113": "宝山区", + "310114": "嘉定区", + "310115": "浦东新区", + "310116": "金山区", + "310117": "松江区", + "310118": "青浦区", + "310120": "奉贤区", + "310151": "崇明区" + }, + "320000": { + "320100": "南京市", + "320200": "无锡市", + "320300": "徐州市", + "320400": "常州市", + "320500": "苏州市", + "320600": "南通市", + "320700": "连云港市", + "320800": "淮安市", + "320900": "盐城市", + "321000": "扬州市", + "321100": "镇江市", + "321200": "泰州市", + "321300": "宿迁市" + }, + "320100": { + "320101": "市辖区", + "320102": "玄武区", + "320104": "秦淮区", + "320105": "建邺区", + "320106": "鼓楼区", + "320111": "浦口区", + "320113": "栖霞区", + "320114": "雨花台区", + "320115": "江宁区", + "320116": "六合区", + "320117": "溧水区", + "320118": "高淳区" + }, + "320200": { + "320201": "市辖区", + "320205": "锡山区", + "320206": "惠山区", + "320211": "滨湖区", + "320213": "梁溪区", + "320214": "新吴区", + "320281": "江阴市", + "320282": "宜兴市" + }, + "320300": { + "320301": "市辖区", + "320302": "鼓楼区", + "320303": "云龙区", + "320305": "贾汪区", + "320311": "泉山区", + "320312": "铜山区", + "320321": "丰县", + "320322": "沛县", + "320324": "睢宁县", + "320371": "徐州经济技术开发区", + "320381": "新沂市", + "320382": "邳州市" + }, + "320400": { + "320401": "市辖区", + "320402": "天宁区", + "320404": "钟楼区", + "320411": "新北区", + "320412": "武进区", + "320413": "金坛区", + "320481": "溧阳市" + }, + "320500": { + "320501": "市辖区", + "320505": "虎丘区", + "320506": "吴中区", + "320507": "相城区", + "320508": "姑苏区", + "320509": "吴江区", + "320571": "苏州工业园区", + "320581": "常熟市", + "320582": "张家港市", + "320583": "昆山市", + "320585": "太仓市" + }, + "320600": { + "320601": "市辖区", + "320602": "崇川区", + "320611": "港闸区", + "320612": "通州区", + "320623": "如东县", + "320671": "南通经济技术开发区", + "320681": "启东市", + "320682": "如皋市", + "320684": "海门市", + "320685": "海安市" + }, + "320700": { + "320701": "市辖区", + "320703": "连云区", + "320706": "海州区", + "320707": "赣榆区", + "320722": "东海县", + "320723": "灌云县", + "320724": "灌南县", + "320771": "连云港经济技术开发区", + "320772": "连云港高新技术产业开发区" + }, + "320800": { + "320801": "市辖区", + "320803": "淮安区", + "320804": "淮阴区", + "320812": "清江浦区", + "320813": "洪泽区", + "320826": "涟水县", + "320830": "盱眙县", + "320831": "金湖县", + "320871": "淮安经济技术开发区" + }, + "320900": { + "320901": "市辖区", + "320902": "亭湖区", + "320903": "盐都区", + "320904": "大丰区", + "320921": "响水县", + "320922": "滨海县", + "320923": "阜宁县", + "320924": "射阳县", + "320925": "建湖县", + "320971": "盐城经济技术开发区", + "320981": "东台市" + }, + "321000": { + "321001": "市辖区", + "321002": "广陵区", + "321003": "邗江区", + "321012": "江都区", + "321023": "宝应县", + "321071": "扬州经济技术开发区", + "321081": "仪征市", + "321084": "高邮市" + }, + "321100": { + "321101": "市辖区", + "321102": "京口区", + "321111": "润州区", + "321112": "丹徒区", + "321171": "镇江新区", + "321181": "丹阳市", + "321182": "扬中市", + "321183": "句容市" + }, + "321200": { + "321201": "市辖区", + "321202": "海陵区", + "321203": "高港区", + "321204": "姜堰区", + "321271": "泰州医药高新技术产业开发区", + "321281": "兴化市", + "321282": "靖江市", + "321283": "泰兴市" + }, + "321300": { + "321301": "市辖区", + "321302": "宿城区", + "321311": "宿豫区", + "321322": "沭阳县", + "321323": "泗阳县", + "321324": "泗洪县", + "321371": "宿迁经济技术开发区" + }, + "330000": { + "330100": "杭州市", + "330200": "宁波市", + "330300": "温州市", + "330400": "嘉兴市", + "330500": "湖州市", + "330600": "绍兴市", + "330700": "金华市", + "330800": "衢州市", + "330900": "舟山市", + "331000": "台州市", + "331100": "丽水市" + }, + "330100": { + "330101": "市辖区", + "330102": "上城区", + "330103": "下城区", + "330104": "江干区", + "330105": "拱墅区", + "330106": "西湖区", + "330108": "滨江区", + "330109": "萧山区", + "330110": "余杭区", + "330111": "富阳区", + "330112": "临安区", + "330122": "桐庐县", + "330127": "淳安县", + "330182": "建德市" + }, + "330200": { + "330201": "市辖区", + "330203": "海曙区", + "330205": "江北区", + "330206": "北仑区", + "330211": "镇海区", + "330212": "鄞州区", + "330213": "奉化区", + "330225": "象山县", + "330226": "宁海县", + "330281": "余姚市", + "330282": "慈溪市" + }, + "330300": { + "330301": "市辖区", + "330302": "鹿城区", + "330303": "龙湾区", + "330304": "瓯海区", + "330305": "洞头区", + "330324": "永嘉县", + "330326": "平阳县", + "330327": "苍南县", + "330328": "文成县", + "330329": "泰顺县", + "330371": "温州经济技术开发区", + "330381": "瑞安市", + "330382": "乐清市", + "330383": "龙港市" + }, + "330400": { + "330401": "市辖区", + "330402": "南湖区", + "330411": "秀洲区", + "330421": "嘉善县", + "330424": "海盐县", + "330481": "海宁市", + "330482": "平湖市", + "330483": "桐乡市" + }, + "330500": {"330501": "市辖区", "330502": "吴兴区", "330503": "南浔区", "330521": "德清县", "330522": "长兴县", "330523": "安吉县"}, + "330600": { + "330601": "市辖区", + "330602": "越城区", + "330603": "柯桥区", + "330604": "上虞区", + "330624": "新昌县", + "330681": "诸暨市", + "330683": "嵊州市" + }, + "330700": { + "330701": "市辖区", + "330702": "婺城区", + "330703": "金东区", + "330723": "武义县", + "330726": "浦江县", + "330727": "磐安县", + "330781": "兰溪市", + "330782": "义乌市", + "330783": "东阳市", + "330784": "永康市" + }, + "330800": { + "330801": "市辖区", + "330802": "柯城区", + "330803": "衢江区", + "330822": "常山县", + "330824": "开化县", + "330825": "龙游县", + "330881": "江山市" + }, + "330900": {"330901": "市辖区", "330902": "定海区", "330903": "普陀区", "330921": "岱山县", "330922": "嵊泗县"}, + "331000": { + "331001": "市辖区", + "331002": "椒江区", + "331003": "黄岩区", + "331004": "路桥区", + "331022": "三门县", + "331023": "天台县", + "331024": "仙居县", + "331081": "温岭市", + "331082": "临海市", + "331083": "玉环市" + }, + "331100": { + "331101": "市辖区", + "331102": "莲都区", + "331121": "青田县", + "331122": "缙云县", + "331123": "遂昌县", + "331124": "松阳县", + "331125": "云和县", + "331126": "庆元县", + "331127": "景宁畲族自治县", + "331181": "龙泉市" + }, + "340000": { + "340100": "合肥市", + "340200": "芜湖市", + "340300": "蚌埠市", + "340400": "淮南市", + "340500": "马鞍山市", + "340600": "淮北市", + "340700": "铜陵市", + "340800": "安庆市", + "341000": "黄山市", + "341100": "滁州市", + "341200": "阜阳市", + "341300": "宿州市", + "341500": "六安市", + "341600": "亳州市", + "341700": "池州市", + "341800": "宣城市" + }, + "340100": { + "340101": "市辖区", + "340102": "瑶海区", + "340103": "庐阳区", + "340104": "蜀山区", + "340111": "包河区", + "340121": "长丰县", + "340122": "肥东县", + "340123": "肥西县", + "340124": "庐江县", + "340171": "合肥高新技术产业开发区", + "340172": "合肥经济技术开发区", + "340173": "合肥新站高新技术产业开发区", + "340181": "巢湖市" + }, + "340200": { + "340201": "市辖区", + "340202": "镜湖区", + "340203": "弋江区", + "340207": "鸠江区", + "340208": "三山区", + "340221": "芜湖县", + "340222": "繁昌县", + "340223": "南陵县", + "340225": "无为县", + "340271": "芜湖经济技术开发区", + "340272": "安徽芜湖长江大桥经济开发区" + }, + "340300": { + "340301": "市辖区", + "340302": "龙子湖区", + "340303": "蚌山区", + "340304": "禹会区", + "340311": "淮上区", + "340321": "怀远县", + "340322": "五河县", + "340323": "固镇县", + "340371": "蚌埠市高新技术开发区", + "340372": "蚌埠市经济开发区" + }, + "340400": { + "340401": "市辖区", + "340402": "大通区", + "340403": "田家庵区", + "340404": "谢家集区", + "340405": "八公山区", + "340406": "潘集区", + "340421": "凤台县", + "340422": "寿县" + }, + "340500": { + "340501": "市辖区", + "340503": "花山区", + "340504": "雨山区", + "340506": "博望区", + "340521": "当涂县", + "340522": "含山县", + "340523": "和县" + }, + "340600": {"340601": "市辖区", "340602": "杜集区", "340603": "相山区", "340604": "烈山区", "340621": "濉溪县"}, + "340700": {"340701": "市辖区", "340705": "铜官区", "340706": "义安区", "340711": "郊区", "340722": "枞阳县"}, + "340800": { + "340801": "市辖区", + "340802": "迎江区", + "340803": "大观区", + "340811": "宜秀区", + "340822": "怀宁县", + "340825": "太湖县", + "340826": "宿松县", + "340827": "望江县", + "340828": "岳西县", + "340871": "安徽安庆经济开发区", + "340881": "桐城市", + "340882": "潜山市" + }, + "341000": { + "341001": "市辖区", + "341002": "屯溪区", + "341003": "黄山区", + "341004": "徽州区", + "341021": "歙县", + "341022": "休宁县", + "341023": "黟县", + "341024": "祁门县" + }, + "341100": { + "341101": "市辖区", + "341102": "琅琊区", + "341103": "南谯区", + "341122": "来安县", + "341124": "全椒县", + "341125": "定远县", + "341126": "凤阳县", + "341171": "苏滁现代产业园", + "341172": "滁州经济技术开发区", + "341181": "天长市", + "341182": "明光市" + }, + "341200": { + "341201": "市辖区", + "341202": "颍州区", + "341203": "颍东区", + "341204": "颍泉区", + "341221": "临泉县", + "341222": "太和县", + "341225": "阜南县", + "341226": "颍上县", + "341271": "阜阳合肥现代产业园区", + "341272": "阜阳经济技术开发区", + "341282": "界首市" + }, + "341300": { + "341301": "市辖区", + "341302": "埇桥区", + "341321": "砀山县", + "341322": "萧县", + "341323": "灵璧县", + "341324": "泗县", + "341371": "宿州马鞍山现代产业园区", + "341372": "宿州经济技术开发区" + }, + "341500": { + "341501": "市辖区", + "341502": "金安区", + "341503": "裕安区", + "341504": "叶集区", + "341522": "霍邱县", + "341523": "舒城县", + "341524": "金寨县", + "341525": "霍山县" + }, + "341600": {"341601": "市辖区", "341602": "谯城区", "341621": "涡阳县", "341622": "蒙城县", "341623": "利辛县"}, + "341700": {"341701": "市辖区", "341702": "贵池区", "341721": "东至县", "341722": "石台县", "341723": "青阳县"}, + "341800": { + "341801": "市辖区", + "341802": "宣州区", + "341821": "郎溪县", + "341823": "泾县", + "341824": "绩溪县", + "341825": "旌德县", + "341871": "宣城市经济开发区", + "341881": "宁国市", + "341882": "广德市" + }, + "350000": { + "350100": "福州市", + "350200": "厦门市", + "350300": "莆田市", + "350400": "三明市", + "350500": "泉州市", + "350600": "漳州市", + "350700": "南平市", + "350800": "龙岩市", + "350900": "宁德市" + }, + "350100": { + "350101": "市辖区", + "350102": "鼓楼区", + "350103": "台江区", + "350104": "仓山区", + "350105": "马尾区", + "350111": "晋安区", + "350112": "长乐区", + "350121": "闽侯县", + "350122": "连江县", + "350123": "罗源县", + "350124": "闽清县", + "350125": "永泰县", + "350128": "平潭县", + "350181": "福清市" + }, + "350200": { + "350201": "市辖区", + "350203": "思明区", + "350205": "海沧区", + "350206": "湖里区", + "350211": "集美区", + "350212": "同安区", + "350213": "翔安区" + }, + "350300": {"350301": "市辖区", "350302": "城厢区", "350303": "涵江区", "350304": "荔城区", "350305": "秀屿区", "350322": "仙游县"}, + "350400": { + "350401": "市辖区", + "350402": "梅列区", + "350403": "三元区", + "350421": "明溪县", + "350423": "清流县", + "350424": "宁化县", + "350425": "大田县", + "350426": "尤溪县", + "350427": "沙县", + "350428": "将乐县", + "350429": "泰宁县", + "350430": "建宁县", + "350481": "永安市" + }, + "350500": { + "350501": "市辖区", + "350502": "鲤城区", + "350503": "丰泽区", + "350504": "洛江区", + "350505": "泉港区", + "350521": "惠安县", + "350524": "安溪县", + "350525": "永春县", + "350526": "德化县", + "350527": "金门县", + "350581": "石狮市", + "350582": "晋江市", + "350583": "南安市" + }, + "350600": { + "350601": "市辖区", + "350602": "芗城区", + "350603": "龙文区", + "350622": "云霄县", + "350623": "漳浦县", + "350624": "诏安县", + "350625": "长泰县", + "350626": "东山县", + "350627": "南靖县", + "350628": "平和县", + "350629": "华安县", + "350681": "龙海市" + }, + "350700": { + "350701": "市辖区", + "350702": "延平区", + "350703": "建阳区", + "350721": "顺昌县", + "350722": "浦城县", + "350723": "光泽县", + "350724": "松溪县", + "350725": "政和县", + "350781": "邵武市", + "350782": "武夷山市", + "350783": "建瓯市" + }, + "350800": { + "350801": "市辖区", + "350802": "新罗区", + "350803": "永定区", + "350821": "长汀县", + "350823": "上杭县", + "350824": "武平县", + "350825": "连城县", + "350881": "漳平市" + }, + "350900": { + "350901": "市辖区", + "350902": "蕉城区", + "350921": "霞浦县", + "350922": "古田县", + "350923": "屏南县", + "350924": "寿宁县", + "350925": "周宁县", + "350926": "柘荣县", + "350981": "福安市", + "350982": "福鼎市" + }, + "360000": { + "360100": "南昌市", + "360200": "景德镇市", + "360300": "萍乡市", + "360400": "九江市", + "360500": "新余市", + "360600": "鹰潭市", + "360700": "赣州市", + "360800": "吉安市", + "360900": "宜春市", + "361000": "抚州市", + "361100": "上饶市" + }, + "360100": { + "360101": "市辖区", + "360102": "东湖区", + "360103": "西湖区", + "360104": "青云谱区", + "360105": "湾里区", + "360111": "青山湖区", + "360112": "新建区", + "360121": "南昌县", + "360123": "安义县", + "360124": "进贤县" + }, + "360200": {"360201": "市辖区", "360202": "昌江区", "360203": "珠山区", "360222": "浮梁县", "360281": "乐平市"}, + "360300": {"360301": "市辖区", "360302": "安源区", "360313": "湘东区", "360321": "莲花县", "360322": "上栗县", "360323": "芦溪县"}, + "360400": { + "360401": "市辖区", + "360402": "濂溪区", + "360403": "浔阳区", + "360404": "柴桑区", + "360423": "武宁县", + "360424": "修水县", + "360425": "永修县", + "360426": "德安县", + "360428": "都昌县", + "360429": "湖口县", + "360430": "彭泽县", + "360481": "瑞昌市", + "360482": "共青城市", + "360483": "庐山市" + }, + "360500": {"360501": "市辖区", "360502": "渝水区", "360521": "分宜县"}, + "360600": {"360601": "市辖区", "360602": "月湖区", "360603": "余江区", "360681": "贵溪市"}, + "360700": { + "360701": "市辖区", + "360702": "章贡区", + "360703": "南康区", + "360704": "赣县区", + "360722": "信丰县", + "360723": "大余县", + "360724": "上犹县", + "360725": "崇义县", + "360726": "安远县", + "360727": "龙南县", + "360728": "定南县", + "360729": "全南县", + "360730": "宁都县", + "360731": "于都县", + "360732": "兴国县", + "360733": "会昌县", + "360734": "寻乌县", + "360735": "石城县", + "360781": "瑞金市" + }, + "360800": { + "360801": "市辖区", + "360802": "吉州区", + "360803": "青原区", + "360821": "吉安县", + "360822": "吉水县", + "360823": "峡江县", + "360824": "新干县", + "360825": "永丰县", + "360826": "泰和县", + "360827": "遂川县", + "360828": "万安县", + "360829": "安福县", + "360830": "永新县", + "360881": "井冈山市" + }, + "360900": { + "360901": "市辖区", + "360902": "袁州区", + "360921": "奉新县", + "360922": "万载县", + "360923": "上高县", + "360924": "宜丰县", + "360925": "靖安县", + "360926": "铜鼓县", + "360981": "丰城市", + "360982": "樟树市", + "360983": "高安市" + }, + "361000": { + "361001": "市辖区", + "361002": "临川区", + "361003": "东乡区", + "361021": "南城县", + "361022": "黎川县", + "361023": "南丰县", + "361024": "崇仁县", + "361025": "乐安县", + "361026": "宜黄县", + "361027": "金溪县", + "361028": "资溪县", + "361030": "广昌县" + }, + "361100": { + "361101": "市辖区", + "361102": "信州区", + "361103": "广丰区", + "361104": "广信区", + "361123": "玉山县", + "361124": "铅山县", + "361125": "横峰县", + "361126": "弋阳县", + "361127": "余干县", + "361128": "鄱阳县", + "361129": "万年县", + "361130": "婺源县", + "361181": "德兴市" + }, + "370000": { + "370100": "济南市", + "370200": "青岛市", + "370300": "淄博市", + "370400": "枣庄市", + "370500": "东营市", + "370600": "烟台市", + "370700": "潍坊市", + "370800": "济宁市", + "370900": "泰安市", + "371000": "威海市", + "371100": "日照市", + "371300": "临沂市", + "371400": "德州市", + "371500": "聊城市", + "371600": "滨州市", + "371700": "菏泽市" + }, + "370100": { + "370101": "市辖区", + "370102": "历下区", + "370103": "市中区", + "370104": "槐荫区", + "370105": "天桥区", + "370112": "历城区", + "370113": "长清区", + "370114": "章丘区", + "370115": "济阳区", + "370116": "莱芜区", + "370117": "钢城区", + "370124": "平阴县", + "370126": "商河县", + "370171": "济南高新技术产业开发区" + }, + "370200": { + "370201": "市辖区", + "370202": "市南区", + "370203": "市北区", + "370211": "黄岛区", + "370212": "崂山区", + "370213": "李沧区", + "370214": "城阳区", + "370215": "即墨区", + "370271": "青岛高新技术产业开发区", + "370281": "胶州市", + "370283": "平度市", + "370285": "莱西市" + }, + "370300": { + "370301": "市辖区", + "370302": "淄川区", + "370303": "张店区", + "370304": "博山区", + "370305": "临淄区", + "370306": "周村区", + "370321": "桓台县", + "370322": "高青县", + "370323": "沂源县" + }, + "370400": { + "370401": "市辖区", + "370402": "市中区", + "370403": "薛城区", + "370404": "峄城区", + "370405": "台儿庄区", + "370406": "山亭区", + "370481": "滕州市" + }, + "370500": { + "370501": "市辖区", + "370502": "东营区", + "370503": "河口区", + "370505": "垦利区", + "370522": "利津县", + "370523": "广饶县", + "370571": "东营经济技术开发区", + "370572": "东营港经济开发区" + }, + "370600": { + "370601": "市辖区", + "370602": "芝罘区", + "370611": "福山区", + "370612": "牟平区", + "370613": "莱山区", + "370634": "长岛县", + "370671": "烟台高新技术产业开发区", + "370672": "烟台经济技术开发区", + "370681": "龙口市", + "370682": "莱阳市", + "370683": "莱州市", + "370684": "蓬莱市", + "370685": "招远市", + "370686": "栖霞市", + "370687": "海阳市" + }, + "370700": { + "370701": "市辖区", + "370702": "潍城区", + "370703": "寒亭区", + "370704": "坊子区", + "370705": "奎文区", + "370724": "临朐县", + "370725": "昌乐县", + "370772": "潍坊滨海经济技术开发区", + "370781": "青州市", + "370782": "诸城市", + "370783": "寿光市", + "370784": "安丘市", + "370785": "高密市", + "370786": "昌邑市" + }, + "370800": { + "370801": "市辖区", + "370811": "任城区", + "370812": "兖州区", + "370826": "微山县", + "370827": "鱼台县", + "370828": "金乡县", + "370829": "嘉祥县", + "370830": "汶上县", + "370831": "泗水县", + "370832": "梁山县", + "370871": "济宁高新技术产业开发区", + "370881": "曲阜市", + "370883": "邹城市" + }, + "370900": { + "370901": "市辖区", + "370902": "泰山区", + "370911": "岱岳区", + "370921": "宁阳县", + "370923": "东平县", + "370982": "新泰市", + "370983": "肥城市" + }, + "371000": { + "371001": "市辖区", + "371002": "环翠区", + "371003": "文登区", + "371071": "威海火炬高技术产业开发区", + "371072": "威海经济技术开发区", + "371073": "威海临港经济技术开发区", + "371082": "荣成市", + "371083": "乳山市" + }, + "371100": {"371101": "市辖区", "371102": "东港区", "371103": "岚山区", "371121": "五莲县", "371122": "莒县", "371171": "日照经济技术开发区"}, + "371300": { + "371301": "市辖区", + "371302": "兰山区", + "371311": "罗庄区", + "371312": "河东区", + "371321": "沂南县", + "371322": "郯城县", + "371323": "沂水县", + "371324": "兰陵县", + "371325": "费县", + "371326": "平邑县", + "371327": "莒南县", + "371328": "蒙阴县", + "371329": "临沭县", + "371371": "临沂高新技术产业开发区", + "371372": "临沂经济技术开发区", + "371373": "临沂临港经济开发区" + }, + "371400": { + "371401": "市辖区", + "371402": "德城区", + "371403": "陵城区", + "371422": "宁津县", + "371423": "庆云县", + "371424": "临邑县", + "371425": "齐河县", + "371426": "平原县", + "371427": "夏津县", + "371428": "武城县", + "371471": "德州经济技术开发区", + "371472": "德州运河经济开发区", + "371481": "乐陵市", + "371482": "禹城市" + }, + "371500": { + "371501": "市辖区", + "371502": "东昌府区", + "371503": "茌平区", + "371521": "阳谷县", + "371522": "莘县", + "371524": "东阿县", + "371525": "冠县", + "371526": "高唐县", + "371581": "临清市" + }, + "371600": { + "371601": "市辖区", + "371602": "滨城区", + "371603": "沾化区", + "371621": "惠民县", + "371622": "阳信县", + "371623": "无棣县", + "371625": "博兴县", + "371681": "邹平市" + }, + "371700": { + "371701": "市辖区", + "371702": "牡丹区", + "371703": "定陶区", + "371721": "曹县", + "371722": "单县", + "371723": "成武县", + "371724": "巨野县", + "371725": "郓城县", + "371726": "鄄城县", + "371728": "东明县", + "371771": "菏泽经济技术开发区", + "371772": "菏泽高新技术开发区" + }, + "410000": { + "410100": "郑州市", + "410200": "开封市", + "410300": "洛阳市", + "410400": "平顶山市", + "410500": "安阳市", + "410600": "鹤壁市", + "410700": "新乡市", + "410800": "焦作市", + "410900": "濮阳市", + "411000": "许昌市", + "411100": "漯河市", + "411200": "三门峡市", + "411300": "南阳市", + "411400": "商丘市", + "411500": "信阳市", + "411600": "周口市", + "411700": "驻马店市", + "419000": "省直辖县级行政区划" + }, + "410100": { + "410101": "市辖区", + "410102": "中原区", + "410103": "二七区", + "410104": "管城回族区", + "410105": "金水区", + "410106": "上街区", + "410108": "惠济区", + "410122": "中牟县", + "410171": "郑州经济技术开发区", + "410172": "郑州高新技术产业开发区", + "410173": "郑州航空港经济综合实验区", + "410181": "巩义市", + "410182": "荥阳市", + "410183": "新密市", + "410184": "新郑市", + "410185": "登封市" + }, + "410200": { + "410201": "市辖区", + "410202": "龙亭区", + "410203": "顺河回族区", + "410204": "鼓楼区", + "410205": "禹王台区", + "410212": "祥符区", + "410221": "杞县", + "410222": "通许县", + "410223": "尉氏县", + "410225": "兰考县" + }, + "410300": { + "410301": "市辖区", + "410302": "老城区", + "410303": "西工区", + "410304": "瀍河回族区", + "410305": "涧西区", + "410306": "吉利区", + "410311": "洛龙区", + "410322": "孟津县", + "410323": "新安县", + "410324": "栾川县", + "410325": "嵩县", + "410326": "汝阳县", + "410327": "宜阳县", + "410328": "洛宁县", + "410329": "伊川县", + "410371": "洛阳高新技术产业开发区", + "410381": "偃师市" + }, + "410400": { + "410401": "市辖区", + "410402": "新华区", + "410403": "卫东区", + "410404": "石龙区", + "410411": "湛河区", + "410421": "宝丰县", + "410422": "叶县", + "410423": "鲁山县", + "410425": "郏县", + "410471": "平顶山高新技术产业开发区", + "410472": "平顶山市城乡一体化示范区", + "410481": "舞钢市", + "410482": "汝州市" + }, + "410500": { + "410501": "市辖区", + "410502": "文峰区", + "410503": "北关区", + "410505": "殷都区", + "410506": "龙安区", + "410522": "安阳县", + "410523": "汤阴县", + "410526": "滑县", + "410527": "内黄县", + "410571": "安阳高新技术产业开发区", + "410581": "林州市" + }, + "410600": { + "410601": "市辖区", + "410602": "鹤山区", + "410603": "山城区", + "410611": "淇滨区", + "410621": "浚县", + "410622": "淇县", + "410671": "鹤壁经济技术开发区" + }, + "410700": { + "410701": "市辖区", + "410702": "红旗区", + "410703": "卫滨区", + "410704": "凤泉区", + "410711": "牧野区", + "410721": "新乡县", + "410724": "获嘉县", + "410725": "原阳县", + "410726": "延津县", + "410727": "封丘县", + "410771": "新乡高新技术产业开发区", + "410772": "新乡经济技术开发区", + "410773": "新乡市平原城乡一体化示范区", + "410781": "卫辉市", + "410782": "辉县市", + "410783": "长垣市" + }, + "410800": { + "410801": "市辖区", + "410802": "解放区", + "410803": "中站区", + "410804": "马村区", + "410811": "山阳区", + "410821": "修武县", + "410822": "博爱县", + "410823": "武陟县", + "410825": "温县", + "410871": "焦作城乡一体化示范区", + "410882": "沁阳市", + "410883": "孟州市" + }, + "410900": { + "410901": "市辖区", + "410902": "华龙区", + "410922": "清丰县", + "410923": "南乐县", + "410926": "范县", + "410927": "台前县", + "410928": "濮阳县", + "410971": "河南濮阳工业园区", + "410972": "濮阳经济技术开发区" + }, + "411000": { + "411001": "市辖区", + "411002": "魏都区", + "411003": "建安区", + "411024": "鄢陵县", + "411025": "襄城县", + "411071": "许昌经济技术开发区", + "411081": "禹州市", + "411082": "长葛市" + }, + "411100": { + "411101": "市辖区", + "411102": "源汇区", + "411103": "郾城区", + "411104": "召陵区", + "411121": "舞阳县", + "411122": "临颍县", + "411171": "漯河经济技术开发区" + }, + "411200": { + "411201": "市辖区", + "411202": "湖滨区", + "411203": "陕州区", + "411221": "渑池县", + "411224": "卢氏县", + "411271": "河南三门峡经济开发区", + "411281": "义马市", + "411282": "灵宝市" + }, + "411300": { + "411301": "市辖区", + "411302": "宛城区", + "411303": "卧龙区", + "411321": "南召县", + "411322": "方城县", + "411323": "西峡县", + "411324": "镇平县", + "411325": "内乡县", + "411326": "淅川县", + "411327": "社旗县", + "411328": "唐河县", + "411329": "新野县", + "411330": "桐柏县", + "411371": "南阳高新技术产业开发区", + "411372": "南阳市城乡一体化示范区", + "411381": "邓州市" + }, + "411400": { + "411401": "市辖区", + "411402": "梁园区", + "411403": "睢阳区", + "411421": "民权县", + "411422": "睢县", + "411423": "宁陵县", + "411424": "柘城县", + "411425": "虞城县", + "411426": "夏邑县", + "411471": "豫东综合物流产业聚集区", + "411472": "河南商丘经济开发区", + "411481": "永城市" + }, + "411500": { + "411501": "市辖区", + "411502": "浉河区", + "411503": "平桥区", + "411521": "罗山县", + "411522": "光山县", + "411523": "新县", + "411524": "商城县", + "411525": "固始县", + "411526": "潢川县", + "411527": "淮滨县", + "411528": "息县", + "411571": "信阳高新技术产业开发区" + }, + "411600": { + "411601": "市辖区", + "411602": "川汇区", + "411603": "淮阳区", + "411621": "扶沟县", + "411622": "西华县", + "411623": "商水县", + "411624": "沈丘县", + "411625": "郸城县", + "411627": "太康县", + "411628": "鹿邑县", + "411671": "河南周口经济开发区", + "411681": "项城市" + }, + "411700": { + "411701": "市辖区", + "411702": "驿城区", + "411721": "西平县", + "411722": "上蔡县", + "411723": "平舆县", + "411724": "正阳县", + "411725": "确山县", + "411726": "泌阳县", + "411727": "汝南县", + "411728": "遂平县", + "411729": "新蔡县", + "411771": "河南驻马店经济开发区" + }, + "419000": {"419001": "济源市"}, + "420000": { + "420100": "武汉市", + "420200": "黄石市", + "420300": "十堰市", + "420500": "宜昌市", + "420600": "襄阳市", + "420700": "鄂州市", + "420800": "荆门市", + "420900": "孝感市", + "421000": "荆州市", + "421100": "黄冈市", + "421200": "咸宁市", + "421300": "随州市", + "422800": "恩施土家族苗族自治州", + "429000": "省直辖县级行政区划" + }, + "420100": { + "420101": "市辖区", + "420102": "江岸区", + "420103": "江汉区", + "420104": "硚口区", + "420105": "汉阳区", + "420106": "武昌区", + "420107": "青山区", + "420111": "洪山区", + "420112": "东西湖区", + "420113": "汉南区", + "420114": "蔡甸区", + "420115": "江夏区", + "420116": "黄陂区", + "420117": "新洲区" + }, + "420200": { + "420201": "市辖区", + "420202": "黄石港区", + "420203": "西塞山区", + "420204": "下陆区", + "420205": "铁山区", + "420222": "阳新县", + "420281": "大冶市" + }, + "420300": { + "420301": "市辖区", + "420302": "茅箭区", + "420303": "张湾区", + "420304": "郧阳区", + "420322": "郧西县", + "420323": "竹山县", + "420324": "竹溪县", + "420325": "房县", + "420381": "丹江口市" + }, + "420500": { + "420501": "市辖区", + "420502": "西陵区", + "420503": "伍家岗区", + "420504": "点军区", + "420505": "猇亭区", + "420506": "夷陵区", + "420525": "远安县", + "420526": "兴山县", + "420527": "秭归县", + "420528": "长阳土家族自治县", + "420529": "五峰土家族自治县", + "420581": "宜都市", + "420582": "当阳市", + "420583": "枝江市" + }, + "420600": { + "420601": "市辖区", + "420602": "襄城区", + "420606": "樊城区", + "420607": "襄州区", + "420624": "南漳县", + "420625": "谷城县", + "420626": "保康县", + "420682": "老河口市", + "420683": "枣阳市", + "420684": "宜城市" + }, + "420700": {"420701": "市辖区", "420702": "梁子湖区", "420703": "华容区", "420704": "鄂城区"}, + "420800": {"420801": "市辖区", "420802": "东宝区", "420804": "掇刀区", "420822": "沙洋县", "420881": "钟祥市", "420882": "京山市"}, + "420900": { + "420901": "市辖区", + "420902": "孝南区", + "420921": "孝昌县", + "420922": "大悟县", + "420923": "云梦县", + "420981": "应城市", + "420982": "安陆市", + "420984": "汉川市" + }, + "421000": { + "421001": "市辖区", + "421002": "沙市区", + "421003": "荆州区", + "421022": "公安县", + "421023": "监利县", + "421024": "江陵县", + "421071": "荆州经济技术开发区", + "421081": "石首市", + "421083": "洪湖市", + "421087": "松滋市" + }, + "421100": { + "421101": "市辖区", + "421102": "黄州区", + "421121": "团风县", + "421122": "红安县", + "421123": "罗田县", + "421124": "英山县", + "421125": "浠水县", + "421126": "蕲春县", + "421127": "黄梅县", + "421171": "龙感湖管理区", + "421181": "麻城市", + "421182": "武穴市" + }, + "421200": { + "421201": "市辖区", + "421202": "咸安区", + "421221": "嘉鱼县", + "421222": "通城县", + "421223": "崇阳县", + "421224": "通山县", + "421281": "赤壁市" + }, + "421300": {"421301": "市辖区", "421303": "曾都区", "421321": "随县", "421381": "广水市"}, + "422800": { + "422801": "恩施市", + "422802": "利川市", + "422822": "建始县", + "422823": "巴东县", + "422825": "宣恩县", + "422826": "咸丰县", + "422827": "来凤县", + "422828": "鹤峰县" + }, + "429000": {"429004": "仙桃市", "429005": "潜江市", "429006": "天门市", "429021": "神农架林区"}, + "430000": { + "430100": "长沙市", + "430200": "株洲市", + "430300": "湘潭市", + "430400": "衡阳市", + "430500": "邵阳市", + "430600": "岳阳市", + "430700": "常德市", + "430800": "张家界市", + "430900": "益阳市", + "431000": "郴州市", + "431100": "永州市", + "431200": "怀化市", + "431300": "娄底市", + "433100": "湘西土家族苗族自治州" + }, + "430100": { + "430101": "市辖区", + "430102": "芙蓉区", + "430103": "天心区", + "430104": "岳麓区", + "430105": "开福区", + "430111": "雨花区", + "430112": "望城区", + "430121": "长沙县", + "430181": "浏阳市", + "430182": "宁乡市" + }, + "430200": { + "430201": "市辖区", + "430202": "荷塘区", + "430203": "芦淞区", + "430204": "石峰区", + "430211": "天元区", + "430212": "渌口区", + "430223": "攸县", + "430224": "茶陵县", + "430225": "炎陵县", + "430271": "云龙示范区", + "430281": "醴陵市" + }, + "430300": { + "430301": "市辖区", + "430302": "雨湖区", + "430304": "岳塘区", + "430321": "湘潭县", + "430371": "湖南湘潭高新技术产业园区", + "430372": "湘潭昭山示范区", + "430373": "湘潭九华示范区", + "430381": "湘乡市", + "430382": "韶山市" + }, + "430400": { + "430401": "市辖区", + "430405": "珠晖区", + "430406": "雁峰区", + "430407": "石鼓区", + "430408": "蒸湘区", + "430412": "南岳区", + "430421": "衡阳县", + "430422": "衡南县", + "430423": "衡山县", + "430424": "衡东县", + "430426": "祁东县", + "430471": "衡阳综合保税区", + "430472": "湖南衡阳高新技术产业园区", + "430473": "湖南衡阳松木经济开发区", + "430481": "耒阳市", + "430482": "常宁市" + }, + "430500": { + "430501": "市辖区", + "430502": "双清区", + "430503": "大祥区", + "430511": "北塔区", + "430522": "新邵县", + "430523": "邵阳县", + "430524": "隆回县", + "430525": "洞口县", + "430527": "绥宁县", + "430528": "新宁县", + "430529": "城步苗族自治县", + "430581": "武冈市", + "430582": "邵东市" + }, + "430600": { + "430601": "市辖区", + "430602": "岳阳楼区", + "430603": "云溪区", + "430611": "君山区", + "430621": "岳阳县", + "430623": "华容县", + "430624": "湘阴县", + "430626": "平江县", + "430671": "岳阳市屈原管理区", + "430681": "汨罗市", + "430682": "临湘市" + }, + "430700": { + "430701": "市辖区", + "430702": "武陵区", + "430703": "鼎城区", + "430721": "安乡县", + "430722": "汉寿县", + "430723": "澧县", + "430724": "临澧县", + "430725": "桃源县", + "430726": "石门县", + "430771": "常德市西洞庭管理区", + "430781": "津市市" + }, + "430800": {"430801": "市辖区", "430802": "永定区", "430811": "武陵源区", "430821": "慈利县", "430822": "桑植县"}, + "430900": { + "430901": "市辖区", + "430902": "资阳区", + "430903": "赫山区", + "430921": "南县", + "430922": "桃江县", + "430923": "安化县", + "430971": "益阳市大通湖管理区", + "430972": "湖南益阳高新技术产业园区", + "430981": "沅江市" + }, + "431000": { + "431001": "市辖区", + "431002": "北湖区", + "431003": "苏仙区", + "431021": "桂阳县", + "431022": "宜章县", + "431023": "永兴县", + "431024": "嘉禾县", + "431025": "临武县", + "431026": "汝城县", + "431027": "桂东县", + "431028": "安仁县", + "431081": "资兴市" + }, + "431100": { + "431101": "市辖区", + "431102": "零陵区", + "431103": "冷水滩区", + "431121": "祁阳县", + "431122": "东安县", + "431123": "双牌县", + "431124": "道县", + "431125": "江永县", + "431126": "宁远县", + "431127": "蓝山县", + "431128": "新田县", + "431129": "江华瑶族自治县", + "431171": "永州经济技术开发区", + "431172": "永州市金洞管理区", + "431173": "永州市回龙圩管理区" + }, + "431200": { + "431201": "市辖区", + "431202": "鹤城区", + "431221": "中方县", + "431222": "沅陵县", + "431223": "辰溪县", + "431224": "溆浦县", + "431225": "会同县", + "431226": "麻阳苗族自治县", + "431227": "新晃侗族自治县", + "431228": "芷江侗族自治县", + "431229": "靖州苗族侗族自治县", + "431230": "通道侗族自治县", + "431271": "怀化市洪江管理区", + "431281": "洪江市" + }, + "431300": {"431301": "市辖区", "431302": "娄星区", "431321": "双峰县", "431322": "新化县", "431381": "冷水江市", "431382": "涟源市"}, + "433100": { + "433101": "吉首市", + "433122": "泸溪县", + "433123": "凤凰县", + "433124": "花垣县", + "433125": "保靖县", + "433126": "古丈县", + "433127": "永顺县", + "433130": "龙山县", + "433173": "湖南永顺经济开发区" + }, + "440000": { + "440100": "广州市", + "440200": "韶关市", + "440300": "深圳市", + "440400": "珠海市", + "440500": "汕头市", + "440600": "佛山市", + "440700": "江门市", + "440800": "湛江市", + "440900": "茂名市", + "441200": "肇庆市", + "441300": "惠州市", + "441400": "梅州市", + "441500": "汕尾市", + "441600": "河源市", + "441700": "阳江市", + "441800": "清远市", + "441900": "东莞市", + "442000": "中山市", + "445100": "潮州市", + "445200": "揭阳市", + "445300": "云浮市" + }, + "440100": { + "440101": "市辖区", + "440103": "荔湾区", + "440104": "越秀区", + "440105": "海珠区", + "440106": "天河区", + "440111": "白云区", + "440112": "黄埔区", + "440113": "番禺区", + "440114": "花都区", + "440115": "南沙区", + "440117": "从化区", + "440118": "增城区" + }, + "440200": { + "440201": "市辖区", + "440203": "武江区", + "440204": "浈江区", + "440205": "曲江区", + "440222": "始兴县", + "440224": "仁化县", + "440229": "翁源县", + "440232": "乳源瑶族自治县", + "440233": "新丰县", + "440281": "乐昌市", + "440282": "南雄市" + }, + "440300": { + "440301": "市辖区", + "440303": "罗湖区", + "440304": "福田区", + "440305": "南山区", + "440306": "宝安区", + "440307": "龙岗区", + "440308": "盐田区", + "440309": "龙华区", + "440310": "坪山区", + "440311": "光明区" + }, + "440400": {"440401": "市辖区", "440402": "香洲区", "440403": "斗门区", "440404": "金湾区"}, + "440500": { + "440501": "市辖区", + "440507": "龙湖区", + "440511": "金平区", + "440512": "濠江区", + "440513": "潮阳区", + "440514": "潮南区", + "440515": "澄海区", + "440523": "南澳县" + }, + "440600": {"440601": "市辖区", "440604": "禅城区", "440605": "南海区", "440606": "顺德区", "440607": "三水区", "440608": "高明区"}, + "440700": { + "440701": "市辖区", + "440703": "蓬江区", + "440704": "江海区", + "440705": "新会区", + "440781": "台山市", + "440783": "开平市", + "440784": "鹤山市", + "440785": "恩平市" + }, + "440800": { + "440801": "市辖区", + "440802": "赤坎区", + "440803": "霞山区", + "440804": "坡头区", + "440811": "麻章区", + "440823": "遂溪县", + "440825": "徐闻县", + "440881": "廉江市", + "440882": "雷州市", + "440883": "吴川市" + }, + "440900": {"440901": "市辖区", "440902": "茂南区", "440904": "电白区", "440981": "高州市", "440982": "化州市", "440983": "信宜市"}, + "441200": { + "441201": "市辖区", + "441202": "端州区", + "441203": "鼎湖区", + "441204": "高要区", + "441223": "广宁县", + "441224": "怀集县", + "441225": "封开县", + "441226": "德庆县", + "441284": "四会市" + }, + "441300": {"441301": "市辖区", "441302": "惠城区", "441303": "惠阳区", "441322": "博罗县", "441323": "惠东县", "441324": "龙门县"}, + "441400": { + "441401": "市辖区", + "441402": "梅江区", + "441403": "梅县区", + "441422": "大埔县", + "441423": "丰顺县", + "441424": "五华县", + "441426": "平远县", + "441427": "蕉岭县", + "441481": "兴宁市" + }, + "441500": {"441501": "市辖区", "441502": "城区", "441521": "海丰县", "441523": "陆河县", "441581": "陆丰市"}, + "441600": { + "441601": "市辖区", + "441602": "源城区", + "441621": "紫金县", + "441622": "龙川县", + "441623": "连平县", + "441624": "和平县", + "441625": "东源县" + }, + "441700": {"441701": "市辖区", "441702": "江城区", "441704": "阳东区", "441721": "阳西县", "441781": "阳春市"}, + "441800": { + "441801": "市辖区", + "441802": "清城区", + "441803": "清新区", + "441821": "佛冈县", + "441823": "阳山县", + "441825": "连山壮族瑶族自治县", + "441826": "连南瑶族自治县", + "441881": "英德市", + "441882": "连州市" + }, + "441900": { + "441900003": "东城街道", + "441900004": "南城街道", + "441900005": "万江街道", + "441900006": "莞城街道", + "441900101": "石碣镇", + "441900102": "石龙镇", + "441900103": "茶山镇", + "441900104": "石排镇", + "441900105": "企石镇", + "441900106": "横沥镇", + "441900107": "桥头镇", + "441900108": "谢岗镇", + "441900109": "东坑镇", + "441900110": "常平镇", + "441900111": "寮步镇", + "441900112": "樟木头镇", + "441900113": "大朗镇", + "441900114": "黄江镇", + "441900115": "清溪镇", + "441900116": "塘厦镇", + "441900117": "凤岗镇", + "441900118": "大岭山镇", + "441900119": "长安镇", + "441900121": "虎门镇", + "441900122": "厚街镇", + "441900123": "沙田镇", + "441900124": "道滘镇", + "441900125": "洪梅镇", + "441900126": "麻涌镇", + "441900127": "望牛墩镇", + "441900128": "中堂镇", + "441900129": "高埗镇", + "441900401": "松山湖", + "441900402": "东莞港", + "441900403": "东莞生态园" + }, + "442000": { + "442000001": "石岐街道", + "442000002": "东区街道", + "442000003": "中山港街道", + "442000004": "西区街道", + "442000005": "南区街道", + "442000006": "五桂山街道", + "442000100": "小榄镇", + "442000101": "黄圃镇", + "442000102": "民众镇", + "442000103": "东凤镇", + "442000104": "东升镇", + "442000105": "古镇镇", + "442000106": "沙溪镇", + "442000107": "坦洲镇", + "442000108": "港口镇", + "442000109": "三角镇", + "442000110": "横栏镇", + "442000111": "南头镇", + "442000112": "阜沙镇", + "442000113": "南朗镇", + "442000114": "三乡镇", + "442000115": "板芙镇", + "442000116": "大涌镇", + "442000117": "神湾镇" + }, + "445100": {"445101": "市辖区", "445102": "湘桥区", "445103": "潮安区", "445122": "饶平县"}, + "445200": {"445201": "市辖区", "445202": "榕城区", "445203": "揭东区", "445222": "揭西县", "445224": "惠来县", "445281": "普宁市"}, + "445300": {"445301": "市辖区", "445302": "云城区", "445303": "云安区", "445321": "新兴县", "445322": "郁南县", "445381": "罗定市"}, + "450000": { + "450100": "南宁市", + "450200": "柳州市", + "450300": "桂林市", + "450400": "梧州市", + "450500": "北海市", + "450600": "防城港市", + "450700": "钦州市", + "450800": "贵港市", + "450900": "玉林市", + "451000": "百色市", + "451100": "贺州市", + "451200": "河池市", + "451300": "来宾市", + "451400": "崇左市" + }, + "450100": { + "450101": "市辖区", + "450102": "兴宁区", + "450103": "青秀区", + "450105": "江南区", + "450107": "西乡塘区", + "450108": "良庆区", + "450109": "邕宁区", + "450110": "武鸣区", + "450123": "隆安县", + "450124": "马山县", + "450125": "上林县", + "450126": "宾阳县", + "450127": "横县" + }, + "450200": { + "450201": "市辖区", + "450202": "城中区", + "450203": "鱼峰区", + "450204": "柳南区", + "450205": "柳北区", + "450206": "柳江区", + "450222": "柳城县", + "450223": "鹿寨县", + "450224": "融安县", + "450225": "融水苗族自治县", + "450226": "三江侗族自治县" + }, + "450300": { + "450301": "市辖区", + "450302": "秀峰区", + "450303": "叠彩区", + "450304": "象山区", + "450305": "七星区", + "450311": "雁山区", + "450312": "临桂区", + "450321": "阳朔县", + "450323": "灵川县", + "450324": "全州县", + "450325": "兴安县", + "450326": "永福县", + "450327": "灌阳县", + "450328": "龙胜各族自治县", + "450329": "资源县", + "450330": "平乐县", + "450332": "恭城瑶族自治县", + "450381": "荔浦市" + }, + "450400": { + "450401": "市辖区", + "450403": "万秀区", + "450405": "长洲区", + "450406": "龙圩区", + "450421": "苍梧县", + "450422": "藤县", + "450423": "蒙山县", + "450481": "岑溪市" + }, + "450500": {"450501": "市辖区", "450502": "海城区", "450503": "银海区", "450512": "铁山港区", "450521": "合浦县"}, + "450600": {"450601": "市辖区", "450602": "港口区", "450603": "防城区", "450621": "上思县", "450681": "东兴市"}, + "450700": {"450701": "市辖区", "450702": "钦南区", "450703": "钦北区", "450721": "灵山县", "450722": "浦北县"}, + "450800": {"450801": "市辖区", "450802": "港北区", "450803": "港南区", "450804": "覃塘区", "450821": "平南县", "450881": "桂平市"}, + "450900": { + "450901": "市辖区", + "450902": "玉州区", + "450903": "福绵区", + "450921": "容县", + "450922": "陆川县", + "450923": "博白县", + "450924": "兴业县", + "450981": "北流市" + }, + "451000": { + "451001": "市辖区", + "451002": "右江区", + "451003": "田阳区", + "451022": "田东县", + "451023": "平果县", + "451024": "德保县", + "451026": "那坡县", + "451027": "凌云县", + "451028": "乐业县", + "451029": "田林县", + "451030": "西林县", + "451031": "隆林各族自治县", + "451081": "靖西市" + }, + "451100": {"451101": "市辖区", "451102": "八步区", "451103": "平桂区", "451121": "昭平县", "451122": "钟山县", "451123": "富川瑶族自治县"}, + "451200": { + "451201": "市辖区", + "451202": "金城江区", + "451203": "宜州区", + "451221": "南丹县", + "451222": "天峨县", + "451223": "凤山县", + "451224": "东兰县", + "451225": "罗城仫佬族自治县", + "451226": "环江毛南族自治县", + "451227": "巴马瑶族自治县", + "451228": "都安瑶族自治县", + "451229": "大化瑶族自治县" + }, + "451300": { + "451301": "市辖区", + "451302": "兴宾区", + "451321": "忻城县", + "451322": "象州县", + "451323": "武宣县", + "451324": "金秀瑶族自治县", + "451381": "合山市" + }, + "451400": { + "451401": "市辖区", + "451402": "江州区", + "451421": "扶绥县", + "451422": "宁明县", + "451423": "龙州县", + "451424": "大新县", + "451425": "天等县", + "451481": "凭祥市" + }, + "460000": {"460100": "海口市", "460200": "三亚市", "460300": "三沙市", "460400": "儋州市", "469000": "省直辖县级行政区划"}, + "460100": {"460101": "市辖区", "460105": "秀英区", "460106": "龙华区", "460107": "琼山区", "460108": "美兰区"}, + "460200": {"460201": "市辖区", "460202": "海棠区", "460203": "吉阳区", "460204": "天涯区", "460205": "崖州区"}, + "460300": {"460321": "西沙群岛", "460322": "南沙群岛", "460323": "中沙群岛的岛礁及其海域"}, + "460400": { + "460400100": "那大镇", + "460400101": "和庆镇", + "460400102": "南丰镇", + "460400103": "大成镇", + "460400104": "雅星镇", + "460400105": "兰洋镇", + "460400106": "光村镇", + "460400107": "木棠镇", + "460400108": "海头镇", + "460400109": "峨蔓镇", + "460400111": "王五镇", + "460400112": "白马井镇", + "460400113": "中和镇", + "460400114": "排浦镇", + "460400115": "东成镇", + "460400116": "新州镇", + "460400499": "洋浦经济开发区", + "460400500": "华南热作学院" + }, + "469000": { + "469001": "五指山市", + "469002": "琼海市", + "469005": "文昌市", + "469006": "万宁市", + "469007": "东方市", + "469021": "定安县", + "469022": "屯昌县", + "469023": "澄迈县", + "469024": "临高县", + "469025": "白沙黎族自治县", + "469026": "昌江黎族自治县", + "469027": "乐东黎族自治县", + "469028": "陵水黎族自治县", + "469029": "保亭黎族苗族自治县", + "469030": "琼中黎族苗族自治县" + }, + "500000": {"500100": "市辖区", "500200": "县"}, + "500100": { + "500101": "万州区", + "500102": "涪陵区", + "500103": "渝中区", + "500104": "大渡口区", + "500105": "江北区", + "500106": "沙坪坝区", + "500107": "九龙坡区", + "500108": "南岸区", + "500109": "北碚区", + "500110": "綦江区", + "500111": "大足区", + "500112": "渝北区", + "500113": "巴南区", + "500114": "黔江区", + "500115": "长寿区", + "500116": "江津区", + "500117": "合川区", + "500118": "永川区", + "500119": "南川区", + "500120": "璧山区", + "500151": "铜梁区", + "500152": "潼南区", + "500153": "荣昌区", + "500154": "开州区", + "500155": "梁平区", + "500156": "武隆区" + }, + "500200": { + "500229": "城口县", + "500230": "丰都县", + "500231": "垫江县", + "500233": "忠县", + "500235": "云阳县", + "500236": "奉节县", + "500237": "巫山县", + "500238": "巫溪县", + "500240": "石柱土家族自治县", + "500241": "秀山土家族苗族自治县", + "500242": "酉阳土家族苗族自治县", + "500243": "彭水苗族土家族自治县" + }, + "510000": { + "510100": "成都市", + "510300": "自贡市", + "510400": "攀枝花市", + "510500": "泸州市", + "510600": "德阳市", + "510700": "绵阳市", + "510800": "广元市", + "510900": "遂宁市", + "511000": "内江市", + "511100": "乐山市", + "511300": "南充市", + "511400": "眉山市", + "511500": "宜宾市", + "511600": "广安市", + "511700": "达州市", + "511800": "雅安市", + "511900": "巴中市", + "512000": "资阳市", + "513200": "阿坝藏族羌族自治州", + "513300": "甘孜藏族自治州", + "513400": "凉山彝族自治州" + }, + "510100": { + "510101": "市辖区", + "510104": "锦江区", + "510105": "青羊区", + "510106": "金牛区", + "510107": "武侯区", + "510108": "成华区", + "510112": "龙泉驿区", + "510113": "青白江区", + "510114": "新都区", + "510115": "温江区", + "510116": "双流区", + "510117": "郫都区", + "510121": "金堂县", + "510129": "大邑县", + "510131": "蒲江县", + "510132": "新津县", + "510181": "都江堰市", + "510182": "彭州市", + "510183": "邛崃市", + "510184": "崇州市", + "510185": "简阳市" + }, + "510300": { + "510301": "市辖区", + "510302": "自流井区", + "510303": "贡井区", + "510304": "大安区", + "510311": "沿滩区", + "510321": "荣县", + "510322": "富顺县" + }, + "510400": {"510401": "市辖区", "510402": "东区", "510403": "西区", "510411": "仁和区", "510421": "米易县", "510422": "盐边县"}, + "510500": { + "510501": "市辖区", + "510502": "江阳区", + "510503": "纳溪区", + "510504": "龙马潭区", + "510521": "泸县", + "510522": "合江县", + "510524": "叙永县", + "510525": "古蔺县" + }, + "510600": { + "510601": "市辖区", + "510603": "旌阳区", + "510604": "罗江区", + "510623": "中江县", + "510681": "广汉市", + "510682": "什邡市", + "510683": "绵竹市" + }, + "510700": { + "510701": "市辖区", + "510703": "涪城区", + "510704": "游仙区", + "510705": "安州区", + "510722": "三台县", + "510723": "盐亭县", + "510725": "梓潼县", + "510726": "北川羌族自治县", + "510727": "平武县", + "510781": "江油市" + }, + "510800": { + "510801": "市辖区", + "510802": "利州区", + "510811": "昭化区", + "510812": "朝天区", + "510821": "旺苍县", + "510822": "青川县", + "510823": "剑阁县", + "510824": "苍溪县" + }, + "510900": {"510901": "市辖区", "510903": "船山区", "510904": "安居区", "510921": "蓬溪县", "510923": "大英县", "510981": "射洪市"}, + "511000": { + "511001": "市辖区", + "511002": "市中区", + "511011": "东兴区", + "511024": "威远县", + "511025": "资中县", + "511071": "内江经济开发区", + "511083": "隆昌市" + }, + "511100": { + "511101": "市辖区", + "511102": "市中区", + "511111": "沙湾区", + "511112": "五通桥区", + "511113": "金口河区", + "511123": "犍为县", + "511124": "井研县", + "511126": "夹江县", + "511129": "沐川县", + "511132": "峨边彝族自治县", + "511133": "马边彝族自治县", + "511181": "峨眉山市" + }, + "511300": { + "511301": "市辖区", + "511302": "顺庆区", + "511303": "高坪区", + "511304": "嘉陵区", + "511321": "南部县", + "511322": "营山县", + "511323": "蓬安县", + "511324": "仪陇县", + "511325": "西充县", + "511381": "阆中市" + }, + "511400": { + "511401": "市辖区", + "511402": "东坡区", + "511403": "彭山区", + "511421": "仁寿县", + "511423": "洪雅县", + "511424": "丹棱县", + "511425": "青神县" + }, + "511500": { + "511501": "市辖区", + "511502": "翠屏区", + "511503": "南溪区", + "511504": "叙州区", + "511523": "江安县", + "511524": "长宁县", + "511525": "高县", + "511526": "珙县", + "511527": "筠连县", + "511528": "兴文县", + "511529": "屏山县" + }, + "511600": { + "511601": "市辖区", + "511602": "广安区", + "511603": "前锋区", + "511621": "岳池县", + "511622": "武胜县", + "511623": "邻水县", + "511681": "华蓥市" + }, + "511700": { + "511701": "市辖区", + "511702": "通川区", + "511703": "达川区", + "511722": "宣汉县", + "511723": "开江县", + "511724": "大竹县", + "511725": "渠县", + "511771": "达州经济开发区", + "511781": "万源市" + }, + "511800": { + "511801": "市辖区", + "511802": "雨城区", + "511803": "名山区", + "511822": "荥经县", + "511823": "汉源县", + "511824": "石棉县", + "511825": "天全县", + "511826": "芦山县", + "511827": "宝兴县" + }, + "511900": { + "511901": "市辖区", + "511902": "巴州区", + "511903": "恩阳区", + "511921": "通江县", + "511922": "南江县", + "511923": "平昌县", + "511971": "巴中经济开发区" + }, + "512000": {"512001": "市辖区", "512002": "雁江区", "512021": "安岳县", "512022": "乐至县"}, + "513200": { + "513201": "马尔康市", + "513221": "汶川县", + "513222": "理县", + "513223": "茂县", + "513224": "松潘县", + "513225": "九寨沟县", + "513226": "金川县", + "513227": "小金县", + "513228": "黑水县", + "513230": "壤塘县", + "513231": "阿坝县", + "513232": "若尔盖县", + "513233": "红原县" + }, + "513300": { + "513301": "康定市", + "513322": "泸定县", + "513323": "丹巴县", + "513324": "九龙县", + "513325": "雅江县", + "513326": "道孚县", + "513327": "炉霍县", + "513328": "甘孜县", + "513329": "新龙县", + "513330": "德格县", + "513331": "白玉县", + "513332": "石渠县", + "513333": "色达县", + "513334": "理塘县", + "513335": "巴塘县", + "513336": "乡城县", + "513337": "稻城县", + "513338": "得荣县" + }, + "513400": { + "513401": "西昌市", + "513422": "木里藏族自治县", + "513423": "盐源县", + "513424": "德昌县", + "513425": "会理县", + "513426": "会东县", + "513427": "宁南县", + "513428": "普格县", + "513429": "布拖县", + "513430": "金阳县", + "513431": "昭觉县", + "513432": "喜德县", + "513433": "冕宁县", + "513434": "越西县", + "513435": "甘洛县", + "513436": "美姑县", + "513437": "雷波县" + }, + "520000": { + "520100": "贵阳市", + "520200": "六盘水市", + "520300": "遵义市", + "520400": "安顺市", + "520500": "毕节市", + "520600": "铜仁市", + "522300": "黔西南布依族苗族自治州", + "522600": "黔东南苗族侗族自治州", + "522700": "黔南布依族苗族自治州" + }, + "520100": { + "520101": "市辖区", + "520102": "南明区", + "520103": "云岩区", + "520111": "花溪区", + "520112": "乌当区", + "520113": "白云区", + "520115": "观山湖区", + "520121": "开阳县", + "520122": "息烽县", + "520123": "修文县", + "520181": "清镇市" + }, + "520200": {"520201": "钟山区", "520203": "六枝特区", "520221": "水城县", "520281": "盘州市"}, + "520300": { + "520301": "市辖区", + "520302": "红花岗区", + "520303": "汇川区", + "520304": "播州区", + "520322": "桐梓县", + "520323": "绥阳县", + "520324": "正安县", + "520325": "道真仡佬族苗族自治县", + "520326": "务川仡佬族苗族自治县", + "520327": "凤冈县", + "520328": "湄潭县", + "520329": "余庆县", + "520330": "习水县", + "520381": "赤水市", + "520382": "仁怀市" + }, + "520400": { + "520401": "市辖区", + "520402": "西秀区", + "520403": "平坝区", + "520422": "普定县", + "520423": "镇宁布依族苗族自治县", + "520424": "关岭布依族苗族自治县", + "520425": "紫云苗族布依族自治县" + }, + "520500": { + "520501": "市辖区", + "520502": "七星关区", + "520521": "大方县", + "520522": "黔西县", + "520523": "金沙县", + "520524": "织金县", + "520525": "纳雍县", + "520526": "威宁彝族回族苗族自治县", + "520527": "赫章县" + }, + "520600": { + "520601": "市辖区", + "520602": "碧江区", + "520603": "万山区", + "520621": "江口县", + "520622": "玉屏侗族自治县", + "520623": "石阡县", + "520624": "思南县", + "520625": "印江土家族苗族自治县", + "520626": "德江县", + "520627": "沿河土家族自治县", + "520628": "松桃苗族自治县" + }, + "522300": { + "522301": "兴义市", + "522302": "兴仁市", + "522323": "普安县", + "522324": "晴隆县", + "522325": "贞丰县", + "522326": "望谟县", + "522327": "册亨县", + "522328": "安龙县" + }, + "522600": { + "522601": "凯里市", + "522622": "黄平县", + "522623": "施秉县", + "522624": "三穗县", + "522625": "镇远县", + "522626": "岑巩县", + "522627": "天柱县", + "522628": "锦屏县", + "522629": "剑河县", + "522630": "台江县", + "522631": "黎平县", + "522632": "榕江县", + "522633": "从江县", + "522634": "雷山县", + "522635": "麻江县", + "522636": "丹寨县" + }, + "522700": { + "522701": "都匀市", + "522702": "福泉市", + "522722": "荔波县", + "522723": "贵定县", + "522725": "瓮安县", + "522726": "独山县", + "522727": "平塘县", + "522728": "罗甸县", + "522729": "长顺县", + "522730": "龙里县", + "522731": "惠水县", + "522732": "三都水族自治县" + }, + "530000": { + "530100": "昆明市", + "530300": "曲靖市", + "530400": "玉溪市", + "530500": "保山市", + "530600": "昭通市", + "530700": "丽江市", + "530800": "普洱市", + "530900": "临沧市", + "532300": "楚雄彝族自治州", + "532500": "红河哈尼族彝族自治州", + "532600": "文山壮族苗族自治州", + "532800": "西双版纳傣族自治州", + "532900": "大理白族自治州", + "533100": "德宏傣族景颇族自治州", + "533300": "怒江傈僳族自治州", + "533400": "迪庆藏族自治州" + }, + "530100": { + "530101": "市辖区", + "530102": "五华区", + "530103": "盘龙区", + "530111": "官渡区", + "530112": "西山区", + "530113": "东川区", + "530114": "呈贡区", + "530115": "晋宁区", + "530124": "富民县", + "530125": "宜良县", + "530126": "石林彝族自治县", + "530127": "嵩明县", + "530128": "禄劝彝族苗族自治县", + "530129": "寻甸回族彝族自治县", + "530181": "安宁市" + }, + "530300": { + "530301": "市辖区", + "530302": "麒麟区", + "530303": "沾益区", + "530304": "马龙区", + "530322": "陆良县", + "530323": "师宗县", + "530324": "罗平县", + "530325": "富源县", + "530326": "会泽县", + "530381": "宣威市" + }, + "530400": { + "530401": "市辖区", + "530402": "红塔区", + "530403": "江川区", + "530422": "澄江县", + "530423": "通海县", + "530424": "华宁县", + "530425": "易门县", + "530426": "峨山彝族自治县", + "530427": "新平彝族傣族自治县", + "530428": "元江哈尼族彝族傣族自治县" + }, + "530500": {"530501": "市辖区", "530502": "隆阳区", "530521": "施甸县", "530523": "龙陵县", "530524": "昌宁县", "530581": "腾冲市"}, + "530600": { + "530601": "市辖区", + "530602": "昭阳区", + "530621": "鲁甸县", + "530622": "巧家县", + "530623": "盐津县", + "530624": "大关县", + "530625": "永善县", + "530626": "绥江县", + "530627": "镇雄县", + "530628": "彝良县", + "530629": "威信县", + "530681": "水富市" + }, + "530700": { + "530701": "市辖区", + "530702": "古城区", + "530721": "玉龙纳西族自治县", + "530722": "永胜县", + "530723": "华坪县", + "530724": "宁蒗彝族自治县" + }, + "530800": { + "530801": "市辖区", + "530802": "思茅区", + "530821": "宁洱哈尼族彝族自治县", + "530822": "墨江哈尼族自治县", + "530823": "景东彝族自治县", + "530824": "景谷傣族彝族自治县", + "530825": "镇沅彝族哈尼族拉祜族自治县", + "530826": "江城哈尼族彝族自治县", + "530827": "孟连傣族拉祜族佤族自治县", + "530828": "澜沧拉祜族自治县", + "530829": "西盟佤族自治县" + }, + "530900": { + "530901": "市辖区", + "530902": "临翔区", + "530921": "凤庆县", + "530922": "云县", + "530923": "永德县", + "530924": "镇康县", + "530925": "双江拉祜族佤族布朗族傣族自治县", + "530926": "耿马傣族佤族自治县", + "530927": "沧源佤族自治县" + }, + "532300": { + "532301": "楚雄市", + "532322": "双柏县", + "532323": "牟定县", + "532324": "南华县", + "532325": "姚安县", + "532326": "大姚县", + "532327": "永仁县", + "532328": "元谋县", + "532329": "武定县", + "532331": "禄丰县" + }, + "532500": { + "532501": "个旧市", + "532502": "开远市", + "532503": "蒙自市", + "532504": "弥勒市", + "532523": "屏边苗族自治县", + "532524": "建水县", + "532525": "石屏县", + "532527": "泸西县", + "532528": "元阳县", + "532529": "红河县", + "532530": "金平苗族瑶族傣族自治县", + "532531": "绿春县", + "532532": "河口瑶族自治县" + }, + "532600": { + "532601": "文山市", + "532622": "砚山县", + "532623": "西畴县", + "532624": "麻栗坡县", + "532625": "马关县", + "532626": "丘北县", + "532627": "广南县", + "532628": "富宁县" + }, + "532800": {"532801": "景洪市", "532822": "勐海县", "532823": "勐腊县"}, + "532900": { + "532901": "大理市", + "532922": "漾濞彝族自治县", + "532923": "祥云县", + "532924": "宾川县", + "532925": "弥渡县", + "532926": "南涧彝族自治县", + "532927": "巍山彝族回族自治县", + "532928": "永平县", + "532929": "云龙县", + "532930": "洱源县", + "532931": "剑川县", + "532932": "鹤庆县" + }, + "533100": {"533102": "瑞丽市", "533103": "芒市", "533122": "梁河县", "533123": "盈江县", "533124": "陇川县"}, + "533300": {"533301": "泸水市", "533323": "福贡县", "533324": "贡山独龙族怒族自治县", "533325": "兰坪白族普米族自治县"}, + "533400": {"533401": "香格里拉市", "533422": "德钦县", "533423": "维西傈僳族自治县"}, + "540000": { + "540100": "拉萨市", + "540200": "日喀则市", + "540300": "昌都市", + "540400": "林芝市", + "540500": "山南市", + "540600": "那曲市", + "542500": "阿里地区" + }, + "540100": { + "540101": "市辖区", + "540102": "城关区", + "540103": "堆龙德庆区", + "540104": "达孜区", + "540121": "林周县", + "540122": "当雄县", + "540123": "尼木县", + "540124": "曲水县", + "540127": "墨竹工卡县", + "540171": "格尔木藏青工业园区", + "540172": "拉萨经济技术开发区", + "540173": "西藏文化旅游创意园区", + "540174": "达孜工业园区" + }, + "540200": { + "540202": "桑珠孜区", + "540221": "南木林县", + "540222": "江孜县", + "540223": "定日县", + "540224": "萨迦县", + "540225": "拉孜县", + "540226": "昂仁县", + "540227": "谢通门县", + "540228": "白朗县", + "540229": "仁布县", + "540230": "康马县", + "540231": "定结县", + "540232": "仲巴县", + "540233": "亚东县", + "540234": "吉隆县", + "540235": "聂拉木县", + "540236": "萨嘎县", + "540237": "岗巴县" + }, + "540300": { + "540302": "卡若区", + "540321": "江达县", + "540322": "贡觉县", + "540323": "类乌齐县", + "540324": "丁青县", + "540325": "察雅县", + "540326": "八宿县", + "540327": "左贡县", + "540328": "芒康县", + "540329": "洛隆县", + "540330": "边坝县" + }, + "540400": { + "540402": "巴宜区", + "540421": "工布江达县", + "540422": "米林县", + "540423": "墨脱县", + "540424": "波密县", + "540425": "察隅县", + "540426": "朗县" + }, + "540500": { + "540501": "市辖区", + "540502": "乃东区", + "540521": "扎囊县", + "540522": "贡嘎县", + "540523": "桑日县", + "540524": "琼结县", + "540525": "曲松县", + "540526": "措美县", + "540527": "洛扎县", + "540528": "加查县", + "540529": "隆子县", + "540530": "错那县", + "540531": "浪卡子县" + }, + "540600": { + "540602": "色尼区", + "540621": "嘉黎县", + "540622": "比如县", + "540623": "聂荣县", + "540624": "安多县", + "540625": "申扎县", + "540626": "索县", + "540627": "班戈县", + "540628": "巴青县", + "540629": "尼玛县", + "540630": "双湖县" + }, + "542500": { + "542521": "普兰县", + "542522": "札达县", + "542523": "噶尔县", + "542524": "日土县", + "542525": "革吉县", + "542526": "改则县", + "542527": "措勤县" + }, + "610000": { + "610100": "西安市", + "610200": "铜川市", + "610300": "宝鸡市", + "610400": "咸阳市", + "610500": "渭南市", + "610600": "延安市", + "610700": "汉中市", + "610800": "榆林市", + "610900": "安康市", + "611000": "商洛市" + }, + "610100": { + "610101": "市辖区", + "610102": "新城区", + "610103": "碑林区", + "610104": "莲湖区", + "610111": "灞桥区", + "610112": "未央区", + "610113": "雁塔区", + "610114": "阎良区", + "610115": "临潼区", + "610116": "长安区", + "610117": "高陵区", + "610118": "鄠邑区", + "610122": "蓝田县", + "610124": "周至县" + }, + "610200": {"610201": "市辖区", "610202": "王益区", "610203": "印台区", "610204": "耀州区", "610222": "宜君县"}, + "610300": { + "610301": "市辖区", + "610302": "渭滨区", + "610303": "金台区", + "610304": "陈仓区", + "610322": "凤翔县", + "610323": "岐山县", + "610324": "扶风县", + "610326": "眉县", + "610327": "陇县", + "610328": "千阳县", + "610329": "麟游县", + "610330": "凤县", + "610331": "太白县" + }, + "610400": { + "610401": "市辖区", + "610402": "秦都区", + "610403": "杨陵区", + "610404": "渭城区", + "610422": "三原县", + "610423": "泾阳县", + "610424": "乾县", + "610425": "礼泉县", + "610426": "永寿县", + "610428": "长武县", + "610429": "旬邑县", + "610430": "淳化县", + "610431": "武功县", + "610481": "兴平市", + "610482": "彬州市" + }, + "610500": { + "610501": "市辖区", + "610502": "临渭区", + "610503": "华州区", + "610522": "潼关县", + "610523": "大荔县", + "610524": "合阳县", + "610525": "澄城县", + "610526": "蒲城县", + "610527": "白水县", + "610528": "富平县", + "610581": "韩城市", + "610582": "华阴市" + }, + "610600": { + "610601": "市辖区", + "610602": "宝塔区", + "610603": "安塞区", + "610621": "延长县", + "610622": "延川县", + "610625": "志丹县", + "610626": "吴起县", + "610627": "甘泉县", + "610628": "富县", + "610629": "洛川县", + "610630": "宜川县", + "610631": "黄龙县", + "610632": "黄陵县", + "610681": "子长市" + }, + "610700": { + "610701": "市辖区", + "610702": "汉台区", + "610703": "南郑区", + "610722": "城固县", + "610723": "洋县", + "610724": "西乡县", + "610725": "勉县", + "610726": "宁强县", + "610727": "略阳县", + "610728": "镇巴县", + "610729": "留坝县", + "610730": "佛坪县" + }, + "610800": { + "610801": "市辖区", + "610802": "榆阳区", + "610803": "横山区", + "610822": "府谷县", + "610824": "靖边县", + "610825": "定边县", + "610826": "绥德县", + "610827": "米脂县", + "610828": "佳县", + "610829": "吴堡县", + "610830": "清涧县", + "610831": "子洲县", + "610881": "神木市" + }, + "610900": { + "610901": "市辖区", + "610902": "汉滨区", + "610921": "汉阴县", + "610922": "石泉县", + "610923": "宁陕县", + "610924": "紫阳县", + "610925": "岚皋县", + "610926": "平利县", + "610927": "镇坪县", + "610928": "旬阳县", + "610929": "白河县" + }, + "611000": { + "611001": "市辖区", + "611002": "商州区", + "611021": "洛南县", + "611022": "丹凤县", + "611023": "商南县", + "611024": "山阳县", + "611025": "镇安县", + "611026": "柞水县" + }, + "620000": { + "620100": "兰州市", + "620200": "嘉峪关市", + "620300": "金昌市", + "620400": "白银市", + "620500": "天水市", + "620600": "武威市", + "620700": "张掖市", + "620800": "平凉市", + "620900": "酒泉市", + "621000": "庆阳市", + "621100": "定西市", + "621200": "陇南市", + "622900": "临夏回族自治州", + "623000": "甘南藏族自治州" + }, + "620100": { + "620101": "市辖区", + "620102": "城关区", + "620103": "七里河区", + "620104": "西固区", + "620105": "安宁区", + "620111": "红古区", + "620121": "永登县", + "620122": "皋兰县", + "620123": "榆中县", + "620171": "兰州新区" + }, + "620200": {"620201": "市辖区"}, + "620300": {"620301": "市辖区", "620302": "金川区", "620321": "永昌县"}, + "620400": {"620401": "市辖区", "620402": "白银区", "620403": "平川区", "620421": "靖远县", "620422": "会宁县", "620423": "景泰县"}, + "620500": { + "620501": "市辖区", + "620502": "秦州区", + "620503": "麦积区", + "620521": "清水县", + "620522": "秦安县", + "620523": "甘谷县", + "620524": "武山县", + "620525": "张家川回族自治县" + }, + "620600": {"620601": "市辖区", "620602": "凉州区", "620621": "民勤县", "620622": "古浪县", "620623": "天祝藏族自治县"}, + "620700": { + "620701": "市辖区", + "620702": "甘州区", + "620721": "肃南裕固族自治县", + "620722": "民乐县", + "620723": "临泽县", + "620724": "高台县", + "620725": "山丹县" + }, + "620800": { + "620801": "市辖区", + "620802": "崆峒区", + "620821": "泾川县", + "620822": "灵台县", + "620823": "崇信县", + "620825": "庄浪县", + "620826": "静宁县", + "620881": "华亭市" + }, + "620900": { + "620901": "市辖区", + "620902": "肃州区", + "620921": "金塔县", + "620922": "瓜州县", + "620923": "肃北蒙古族自治县", + "620924": "阿克塞哈萨克族自治县", + "620981": "玉门市", + "620982": "敦煌市" + }, + "621000": { + "621001": "市辖区", + "621002": "西峰区", + "621021": "庆城县", + "621022": "环县", + "621023": "华池县", + "621024": "合水县", + "621025": "正宁县", + "621026": "宁县", + "621027": "镇原县" + }, + "621100": { + "621101": "市辖区", + "621102": "安定区", + "621121": "通渭县", + "621122": "陇西县", + "621123": "渭源县", + "621124": "临洮县", + "621125": "漳县", + "621126": "岷县" + }, + "621200": { + "621201": "市辖区", + "621202": "武都区", + "621221": "成县", + "621222": "文县", + "621223": "宕昌县", + "621224": "康县", + "621225": "西和县", + "621226": "礼县", + "621227": "徽县", + "621228": "两当县" + }, + "622900": { + "622901": "临夏市", + "622921": "临夏县", + "622922": "康乐县", + "622923": "永靖县", + "622924": "广河县", + "622925": "和政县", + "622926": "东乡族自治县", + "622927": "积石山保安族东乡族撒拉族自治县" + }, + "623000": { + "623001": "合作市", + "623021": "临潭县", + "623022": "卓尼县", + "623023": "舟曲县", + "623024": "迭部县", + "623025": "玛曲县", + "623026": "碌曲县", + "623027": "夏河县" + }, + "630000": { + "630100": "西宁市", + "630200": "海东市", + "632200": "海北藏族自治州", + "632300": "黄南藏族自治州", + "632500": "海南藏族自治州", + "632600": "果洛藏族自治州", + "632700": "玉树藏族自治州", + "632800": "海西蒙古族藏族自治州" + }, + "630100": { + "630101": "市辖区", + "630102": "城东区", + "630103": "城中区", + "630104": "城西区", + "630105": "城北区", + "630121": "大通回族土族自治县", + "630122": "湟中县", + "630123": "湟源县" + }, + "630200": { + "630202": "乐都区", + "630203": "平安区", + "630222": "民和回族土族自治县", + "630223": "互助土族自治县", + "630224": "化隆回族自治县", + "630225": "循化撒拉族自治县" + }, + "632200": {"632221": "门源回族自治县", "632222": "祁连县", "632223": "海晏县", "632224": "刚察县"}, + "632300": {"632321": "同仁县", "632322": "尖扎县", "632323": "泽库县", "632324": "河南蒙古族自治县"}, + "632500": {"632521": "共和县", "632522": "同德县", "632523": "贵德县", "632524": "兴海县", "632525": "贵南县"}, + "632600": {"632621": "玛沁县", "632622": "班玛县", "632623": "甘德县", "632624": "达日县", "632625": "久治县", "632626": "玛多县"}, + "632700": {"632701": "玉树市", "632722": "杂多县", "632723": "称多县", "632724": "治多县", "632725": "囊谦县", "632726": "曲麻莱县"}, + "632800": { + "632801": "格尔木市", + "632802": "德令哈市", + "632803": "茫崖市", + "632821": "乌兰县", + "632822": "都兰县", + "632823": "天峻县", + "632857": "大柴旦行政委员会" + }, + "640000": {"640100": "银川市", "640200": "石嘴山市", "640300": "吴忠市", "640400": "固原市", "640500": "中卫市"}, + "640100": { + "640101": "市辖区", + "640104": "兴庆区", + "640105": "西夏区", + "640106": "金凤区", + "640121": "永宁县", + "640122": "贺兰县", + "640181": "灵武市" + }, + "640200": {"640201": "市辖区", "640202": "大武口区", "640205": "惠农区", "640221": "平罗县"}, + "640300": {"640301": "市辖区", "640302": "利通区", "640303": "红寺堡区", "640323": "盐池县", "640324": "同心县", "640381": "青铜峡市"}, + "640400": {"640401": "市辖区", "640402": "原州区", "640422": "西吉县", "640423": "隆德县", "640424": "泾源县", "640425": "彭阳县"}, + "640500": {"640501": "市辖区", "640502": "沙坡头区", "640521": "中宁县", "640522": "海原县"}, + "650000": { + "650100": "乌鲁木齐市", + "650200": "克拉玛依市", + "650400": "吐鲁番市", + "650500": "哈密市", + "652300": "昌吉回族自治州", + "652700": "博尔塔拉蒙古自治州", + "652800": "巴音郭楞蒙古自治州", + "652900": "阿克苏地区", + "653000": "克孜勒苏柯尔克孜自治州", + "653100": "喀什地区", + "653200": "和田地区", + "654000": "伊犁哈萨克自治州", + "654200": "塔城地区", + "654300": "阿勒泰地区", + "659000": "自治区直辖县级行政区划" + }, + "650100": { + "650101": "市辖区", + "650102": "天山区", + "650103": "沙依巴克区", + "650104": "新市区", + "650105": "水磨沟区", + "650106": "头屯河区", + "650107": "达坂城区", + "650109": "米东区", + "650121": "乌鲁木齐县" + }, + "650200": {"650201": "市辖区", "650202": "独山子区", "650203": "克拉玛依区", "650204": "白碱滩区", "650205": "乌尔禾区"}, + "650400": {"650402": "高昌区", "650421": "鄯善县", "650422": "托克逊县"}, + "650500": {"650502": "伊州区", "650521": "巴里坤哈萨克自治县", "650522": "伊吾县"}, + "652300": { + "652301": "昌吉市", + "652302": "阜康市", + "652323": "呼图壁县", + "652324": "玛纳斯县", + "652325": "奇台县", + "652327": "吉木萨尔县", + "652328": "木垒哈萨克自治县" + }, + "652700": {"652701": "博乐市", "652702": "阿拉山口市", "652722": "精河县", "652723": "温泉县"}, + "652800": { + "652801": "库尔勒市", + "652822": "轮台县", + "652823": "尉犁县", + "652824": "若羌县", + "652825": "且末县", + "652826": "焉耆回族自治县", + "652827": "和静县", + "652828": "和硕县", + "652829": "博湖县", + "652871": "库尔勒经济技术开发区" + }, + "652900": { + "652901": "阿克苏市", + "652922": "温宿县", + "652923": "库车县", + "652924": "沙雅县", + "652925": "新和县", + "652926": "拜城县", + "652927": "乌什县", + "652928": "阿瓦提县", + "652929": "柯坪县" + }, + "653000": {"653001": "阿图什市", "653022": "阿克陶县", "653023": "阿合奇县", "653024": "乌恰县"}, + "653100": { + "653101": "喀什市", + "653121": "疏附县", + "653122": "疏勒县", + "653123": "英吉沙县", + "653124": "泽普县", + "653125": "莎车县", + "653126": "叶城县", + "653127": "麦盖提县", + "653128": "岳普湖县", + "653129": "伽师县", + "653130": "巴楚县", + "653131": "塔什库尔干塔吉克自治县" + }, + "653200": { + "653201": "和田市", + "653221": "和田县", + "653222": "墨玉县", + "653223": "皮山县", + "653224": "洛浦县", + "653225": "策勒县", + "653226": "于田县", + "653227": "民丰县" + }, + "654000": { + "654002": "伊宁市", + "654003": "奎屯市", + "654004": "霍尔果斯市", + "654021": "伊宁县", + "654022": "察布查尔锡伯自治县", + "654023": "霍城县", + "654024": "巩留县", + "654025": "新源县", + "654026": "昭苏县", + "654027": "特克斯县", + "654028": "尼勒克县" + }, + "654200": { + "654201": "塔城市", + "654202": "乌苏市", + "654221": "额敏县", + "654223": "沙湾县", + "654224": "托里县", + "654225": "裕民县", + "654226": "和布克赛尔蒙古自治县" + }, + "654300": { + "654301": "阿勒泰市", + "654321": "布尔津县", + "654322": "富蕴县", + "654323": "福海县", + "654324": "哈巴河县", + "654325": "青河县", + "654326": "吉木乃县" + }, + "659000": {"659001": "石河子市", "659002": "阿拉尔市", "659003": "图木舒克市", "659004": "五家渠市", "659006": "铁门关市"}, + "710000": { + "710100": "台北市", + "710200": "高雄市", + "710300": "基隆市", + "710400": "台中市", + "710500": "台南市", + "710600": "新竹市", + "710700": "嘉义市" + }, + "710100": { + "710101": "内湖区", + "710102": "南港区", + "710103": "中正区", + "710104": "松山区", + "710105": "信义区", + "710106": "大安区", + "710107": "中山区", + "710108": "文山区", + "710109": "大同区", + "710110": "万华区", + "710111": "士林区", + "710112": "北投区" + }, + "710200": { + "710201": "新兴区", + "710202": "前金区", + "710203": "芩雅区", + "710204": "盐埕区", + "710205": "鼓山区", + "710206": "旗津区", + "710207": "前镇区", + "710208": "三民区", + "710209": "左营区", + "710210": "楠梓区", + "710211": "小港区" + }, + "710300": {"710301": "仁爱区", "710302": "信义区", "710303": "中正区", "710304": "暖暖区", "710305": "安乐区", "710307": "七堵区"}, + "710400": { + "710301": "中区", + "710302": "东区", + "710303": "南区", + "710304": "西区", + "710305": "北区", + "710306": "北屯区", + "710307": "西屯区", + "710308": "南屯区" + }, + "710500": {"710501": "中西区", "710502": "东区", "710503": "南区", "710504": "北区", "710505": "安平区", "710506": "安南区"}, + "710600": {"710601": "东区", "710602": "北区", "710603": "香山区"}, + "710700": {"710701": "东区", "710702": "西区"}, + "810000": { + "810001": "中西區", + "810002": "灣仔區", + "810003": "東區", + "810004": "南區", + "810005": "油尖旺區", + "810006": "深水埗區", + "810007": "九龍城區", + "810008": "黃大仙區", + "810009": "觀塘區", + "810010": "荃灣區", + "810011": "屯門區", + "810012": "元朗區", + "810013": "北區", + "810014": "大埔區", + "810015": "西貢區", + "810016": "沙田區", + "810017": "葵青區", + "810018": "離島區" + }, + "820000": { + "820001": "花地瑪堂區", + "820002": "花王堂區", + "820003": "望德堂區", + "820004": "大堂區", + "820005": "風順堂區", + "820006": "嘉模堂區", + "820007": "路氹填海區", + "820008": "聖方濟各堂區" + } +}; + +class Address { + static List provinces = locations['86']!.values.toList(); + + // 是否在市、区级添加 全部选项 + static bool addAllItem = true; + + static getCities(String province) { + var emptyData = {'name': "全部", 'cityCode': ''}; + if (province == '全部' && addAllItem) return [emptyData]; + + String code = ''; + locations['86']!.forEach((key, value) { + if (value == province) { + code = key; + } + }); + + Map? areaList = locations[code]; + // print('longer >>>$code 城市数据:$areaList'); + var data = []; + if (areaList != null && addAllItem) data.add(emptyData); + areaList?.forEach((key, value) { + data.add({'name': value, 'cityCode': key}); + }); + + return data; + } + + static getTowns(cityCode) { + if (PicketUtil.strEmpty(cityCode)) return ['']; + + Map? areaList = locations[cityCode]; + if (PicketUtil.mapEmpty(areaList)) { + return ['']; + } else { + var data = areaList!.values.toList(); + if (addAllItem) data.insert(0, '全部'); + return data; + } + } + + // 拼接城市 + static String spliceCityName({String? pname, String? cname, String? tname}) { + if (PicketUtil.strEmpty(pname)) return '不限'; + StringBuffer sb = StringBuffer(); + sb.write(pname); + if (PicketUtil.strEmpty(cname)) return sb.toString(); + sb.write(' - '); + sb.write(cname); + if (PicketUtil.strEmpty(tname)) return sb.toString(); + sb.write(' - '); + sb.write(tname); + return sb.toString(); + } + + /// 根据城市名 找到城市编码 + /// simple use + /// List cityCode = Locations.getTownsCityCode("四川省","成都市","锦江区"); + /// return [510000,510100,510104] or [510000,510000] or [510000] or [] + static List getCityCodeByName({String? provinceName, String? cityName, String? townName}) { + List cityCode = []; + + if (PicketUtil.strEmpty(provinceName)) return cityCode; + String initialProvinceCode = ''; + locations['86']!.forEach((key, value) { + if (value == provinceName) { + initialProvinceCode = key; + } + }); + /////////////////////// + if (PicketUtil.strNoEmpty(initialProvinceCode)) { + cityCode.add(initialProvinceCode); + + // 市级 + if (PicketUtil.strEmpty(cityName)) { + // print('longer 区域代码 >>> $cityCode'); + return cityCode; + } + String initialCityCode = ''; + var initialProvinceList = locations[initialProvinceCode]; + if (initialProvinceList == null) { + // print('longer 区域代码 >>> $cityCode'); + return cityCode; + } + + initialProvinceList.forEach((key, value) { + if (value == cityName) { + initialCityCode = key; + } + }); + + /////////////////////// + if (PicketUtil.strNoEmpty(initialCityCode)) { + cityCode.add(initialCityCode); + + // 区域 + if (PicketUtil.strEmpty(townName)) { + // print('longer 区域代码 >>> $cityCode'); + return cityCode; + } + String initialTownCode = ''; + var initialTownList = locations[initialCityCode]; + if (initialTownList == null) { + // print('longer 区域代码 >>> $cityCode'); + return cityCode; + } + + initialTownList.forEach((key, value) { + if (value == townName) { + initialTownCode = key; + } + }); + + if (PicketUtil.strNoEmpty(initialTownCode)) { + cityCode.add(initialTownCode); + } + } + } + // print('longer 区域代码 >>> $cityCode'); + return cityCode; + } + + /// 通过城市code 返回城市名 + /// simple use + /// List cityName = Address.getCityNameByCode(provinceCode: "510000", cityCode: "510100", townCode: "510104"); + /// return [四川省, 成都市, 锦江区] or [四川省, 成都市] or [四川省] or [] + static List getCityNameByCode({String? provinceCode, String? cityCode, String? townCode}) { + List cityName = []; + + if (PicketUtil.strEmpty(provinceCode)) return cityName; + String provinceName = ''; + locations['86']!.forEach((key, value) { + if (key == provinceCode) { + provinceName = value; + } + }); + if (PicketUtil.strNoEmpty(provinceName)) { + cityName.add(provinceName); + + /////////////////////// + // 市级 + if (PicketUtil.strEmpty(cityCode)) return cityName; + String initialCityName = ''; + var initialProvinceList = locations[provinceCode]; + if (PicketUtil.mapEmpty(initialProvinceList)) { + // print('longer 区域名 >>> $cityName'); + return cityName; + } + + initialProvinceList!.forEach((key, value) { + if (key == cityCode) { + initialCityName = value; + } + }); + if (PicketUtil.strNoEmpty(initialCityName)) { + cityName.add(initialCityName); + + /////////////////////// + // 区域 + if (PicketUtil.strEmpty(townCode)) return cityName; + String initialTownName = ''; + var initialTownList = locations[cityCode]; + if (initialTownList == null) { + // print('longer 区域名 >>> $cityName'); + return cityName; + } + + initialTownList.forEach((key, value) { + if (key == townCode) { + initialTownName = value; + } + }); + + if (PicketUtil.strNoEmpty(initialTownName)) { + cityName.add(initialTownName); + } + } + } + // print('longer 区域名 >>> $cityName'); + return cityName; + } +} diff --git a/star_lock/lib/tools/pickers/address_picker/route/address_picker_route.dart b/star_lock/lib/tools/pickers/address_picker/route/address_picker_route.dart new file mode 100644 index 00000000..f09bad6f --- /dev/null +++ b/star_lock/lib/tools/pickers/address_picker/route/address_picker_route.dart @@ -0,0 +1,462 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; + +import '../locations_data.dart'; + +typedef AddressCallback(String province, String city, String? town); + +/// 自定义 地区选择器 +/// [initProvince] 初始化 省 +/// [initCity] 初始化 市 +/// [initTown] 初始化 区 +/// [onChanged] 选择器发生变动 +/// [onConfirm] 选择器提交 +/// [addAllItem] 市、区是否添加 '全部' 选项 默认:true +class AddressPickerRoute extends PopupRoute { + AddressPickerRoute({ + required this.addAllItem, + required this.pickerStyle, + required this.initProvince, + required this.initCity, + this.initTown, + this.onChanged, + this.onConfirm, + this.onCancel, + this.theme, + this.barrierLabel, + RouteSettings? settings, + }) : super(settings: settings); + + late final String initProvince, initCity; + final String? initTown; + final AddressCallback? onChanged; + final AddressCallback? onConfirm; + final Function(bool isCancel)? onCancel; + final ThemeData? theme; + final bool addAllItem; + + late final PickerStyle pickerStyle; + + @override + Duration get transitionDuration => const Duration(milliseconds: 200); + + @override + bool get barrierDismissible => true; + + @override + bool didPop(T? result) { + if (onCancel != null) { + if (result == null) { + onCancel!(false); + } else if (!(result as bool)) { + onCancel!(true); + } + } + return super.didPop(result); + } + + @override + final String? barrierLabel; + + @override + Color get barrierColor => Colors.black54; + + AnimationController? _animationController; + + @override + AnimationController createAnimationController() { + assert(_animationController == null); + _animationController = + BottomSheet.createAnimationController(navigator!.overlay!); + return _animationController!; + } + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + Widget bottomSheet = MediaQuery.removePadding( + context: context, + removeTop: true, + child: _PickerContentView( + initProvince: initProvince, + initCity: initCity, + initTown: initTown, + addAllItem: addAllItem, + pickerStyle: pickerStyle, + route: this, + ), + ); + if (theme != null) { + bottomSheet = Theme(data: theme!, child: bottomSheet); + } + + return bottomSheet; + } +} + +class _PickerContentView extends StatefulWidget { + _PickerContentView({ + Key? key, + required this.initProvince, + required this.initCity, + this.initTown, + required this.pickerStyle, + required this.addAllItem, + required this.route, + }) : super(key: key); + + final String initProvince, initCity; + final String? initTown; + final AddressPickerRoute route; + final bool addAllItem; + final PickerStyle pickerStyle; + + @override + State createState() => _PickerState(this.initProvince, + this.initCity, this.initTown, this.addAllItem, this.pickerStyle); +} + +class _PickerState extends State<_PickerContentView> { + final PickerStyle _pickerStyle; + late String _currentProvince, _currentCity; + String? _currentTown; + var cities = []; + var towns = []; + var provinces = []; + + // 是否显示县级 + bool hasTown = true; + + // 是否添加全部 + late final bool addAllItem; + + AnimationController? controller; + Animation? animation; + + late FixedExtentScrollController provinceScrollCtrl, + cityScrollCtrl, + townScrollCtrl; + + _PickerState(this._currentProvince, this._currentCity, this._currentTown, + this.addAllItem, this._pickerStyle) { + provinces = Address.provinces; + hasTown = this._currentTown != null; + + _init(); + } + + @override + void dispose() { + provinceScrollCtrl.dispose(); + cityScrollCtrl.dispose(); + townScrollCtrl.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: AnimatedBuilder( + animation: widget.route.animation!, + builder: (BuildContext context, Widget? child) { + return ClipRect( + child: CustomSingleChildLayout( + delegate: _BottomPickerLayout( + widget.route.animation!.value, this._pickerStyle), + child: GestureDetector( + child: Material( + color: Colors.transparent, + child: _renderPickerView(), + ), + ), + ), + ); + }, + ), + ); + } + + _init() { + Address.addAllItem = addAllItem; + int pindex = 0; + int cindex = 0; + int tindex = 0; + pindex = provinces.indexWhere((p) => p == _currentProvince); + pindex = pindex >= 0 ? pindex : 0; + String? selectedProvince = provinces[pindex]; + if (selectedProvince != null) { + _currentProvince = selectedProvince; + + cities = Address.getCities(selectedProvince); + + cindex = cities.indexWhere((c) => c['name'] == _currentCity); + cindex = cindex >= 0 ? cindex : 0; + _currentCity = cities[cindex]['name']; + + // print('longer >>> 外面接到的$cities'); + + if (hasTown) { + towns = Address.getTowns(cities[cindex]['cityCode']); + tindex = towns.indexWhere((t) => t == _currentTown); + tindex = tindex >= 0 ? tindex : 0; + if (towns.length == 0) { + _currentTown = ''; + } else { + _currentTown = towns[tindex]; + } + } + } + + provinceScrollCtrl = new FixedExtentScrollController(initialItem: pindex); + cityScrollCtrl = new FixedExtentScrollController(initialItem: cindex); + townScrollCtrl = new FixedExtentScrollController(initialItem: tindex); + } + + void _setProvince(int index) { + String selectedProvince = provinces[index]; + // print('longer >>> index:$index _currentProvince:$_currentProvince selectedProvince:$selectedProvince '); + + if (_currentProvince != selectedProvince) { + setState(() { + _currentProvince = selectedProvince; + + cities = Address.getCities(selectedProvince); + // print('longer >>> 返回的城市数据:$cities'); + + _currentCity = cities[0]['name']; + cityScrollCtrl.jumpToItem(0); + if (hasTown) { + towns = Address.getTowns(cities[0]['cityCode']); + _currentTown = towns[0]; + townScrollCtrl.jumpToItem(0); + } + }); + + _notifyLocationChanged(); + } + } + + void _setCity(int index) { + index = cities.length > index ? index : 0; + String selectedCity = cities[index]['name']; + if (_currentCity != selectedCity) { + setState(() { + _currentCity = selectedCity; + if (hasTown) { + towns = Address.getTowns(cities[index]['cityCode']); + _currentTown = towns.isNotEmpty ? towns[0] : ''; + townScrollCtrl.jumpToItem(0); + } + }); + + _notifyLocationChanged(); + } + } + + void _setTown(int index) { + index = towns.length > index ? index : 0; + String selectedTown = towns[index]; + if (_currentTown != selectedTown) { + _currentTown = selectedTown; + _notifyLocationChanged(); + } + } + + void _notifyLocationChanged() { + if (widget.route.onChanged != null) { + widget.route.onChanged!(_currentProvince, _currentCity, _currentTown); + } + } + + double _pickerFontSize(String text) { + double ratio = hasTown ? 0.0 : 2.0; + if (text.length <= 6) { + return 18.0; + } else if (text.length < 9) { + return 16.0 + ratio; + } else if (text.length < 13) { + return 12.0 + ratio; + } else { + return 10.0 + ratio; + } + } + + Widget _renderPickerView() { + Widget itemView = _renderItemView(); + + if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) { + return itemView; + } + List viewList = []; + if (_pickerStyle.showTitleBar) { + viewList.add(_titleView()); + } + if (_pickerStyle.menu != null) { + viewList.add(_pickerStyle.menu!); + } + viewList.add(itemView); + + return Column(children: viewList); + } + + Widget _renderItemView() { + return Container( + height: _pickerStyle.pickerHeight, + color: _pickerStyle.backgroundColor, + child: Row( + children: [ + Expanded( + child: Container( + padding: const EdgeInsets.all(8.0), + child: CupertinoPicker.builder( + scrollController: provinceScrollCtrl, + selectionOverlay: _pickerStyle.itemOverlay, + itemExtent: _pickerStyle.pickerItemHeight, + onSelectedItemChanged: (int index) { + _setProvince(index); + }, + childCount: Address.provinces.length, + itemBuilder: (_, index) { + String text = Address.provinces[index]; + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: + _pickerStyle.textSize ?? _pickerFontSize(text), + ), + textAlign: TextAlign.start)); + }, + ), + ), + ), + Expanded( + child: Container( + padding: EdgeInsets.all(8.0), + child: CupertinoPicker.builder( + scrollController: cityScrollCtrl, + selectionOverlay: _pickerStyle.itemOverlay, + itemExtent: _pickerStyle.pickerItemHeight, + onSelectedItemChanged: (int index) { + _setCity(index); + }, + childCount: cities.length, + itemBuilder: (_, index) { + String text = cities[index]['name']; + return Align( + alignment: Alignment.center, + child: Text('$text', + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: + _pickerStyle.textSize ?? _pickerFontSize(text), + ), + textAlign: TextAlign.start), + ); + }, + )), + ), + hasTown + ? Expanded( + child: Container( + padding: EdgeInsets.all(8.0), + child: CupertinoPicker.builder( + scrollController: townScrollCtrl, + selectionOverlay: _pickerStyle.itemOverlay, + itemExtent: _pickerStyle.pickerItemHeight, + onSelectedItemChanged: (int index) { + _setTown(index); + }, + childCount: towns.length, + itemBuilder: (_, index) { + String text = towns[index]; + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: _pickerStyle.textSize ?? + _pickerFontSize(text), + ), + textAlign: TextAlign.start), + ); + }, + )), + ) + : SizedBox() + ], + ), + ); + } + + // 选择器上面的view + Widget _titleView() { + return Container( + height: _pickerStyle.pickerTitleHeight, + decoration: _pickerStyle.headDecoration, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// 取消按钮 + InkWell( + onTap: () => Navigator.pop(context, false), + child: _pickerStyle.cancelButton), + + /// 标题 + Expanded(child: _pickerStyle.title), + + /// 确认按钮 + InkWell( + onTap: () { + if (widget.route.onConfirm != null) { + widget.route.onConfirm!( + _currentProvince, _currentCity, _currentTown); + } + Navigator.pop(context, true); + }, + child: _pickerStyle.commitButton) + ], + ), + ); + } +} + +class _BottomPickerLayout extends SingleChildLayoutDelegate { + _BottomPickerLayout(this.progress, this.pickerStyle); + + final double progress; + final PickerStyle pickerStyle; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + double maxHeight = pickerStyle.pickerHeight; + if (pickerStyle.showTitleBar) { + maxHeight += pickerStyle.pickerTitleHeight; + } + if (pickerStyle.menu != null) { + maxHeight += pickerStyle.menuHeight; + } + + return BoxConstraints( + minWidth: constraints.maxWidth, + maxWidth: constraints.maxWidth, + minHeight: 0.0, + maxHeight: maxHeight); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + double height = size.height - childSize.height * progress; + return Offset(0.0, height); + } + + @override + bool shouldRelayout(_BottomPickerLayout oldDelegate) { + return progress != oldDelegate.progress; + } +} diff --git a/star_lock/lib/tools/pickers/more_pickers/init_data.dart b/star_lock/lib/tools/pickers/more_pickers/init_data.dart new file mode 100644 index 00000000..4154da33 --- /dev/null +++ b/star_lock/lib/tools/pickers/more_pickers/init_data.dart @@ -0,0 +1,76 @@ +enum PickerDataType { + sex, // 性别 + education, // 学历 + subject, // 学科 + constellation, // 星座 + zodiac, // 生肖 + ethnicity, // 名族 +} + +var pickerData = { + PickerDataType.sex: ['不限', '男', '女'], + PickerDataType.education: ["高中以下", "高中", "大专", "本科", "硕士", "博士", "博士后", '其它'], + PickerDataType.subject: ["语文", "数学", "英语", "物理", "化学", "生物", "政治", "地理", "历史"], + PickerDataType.constellation: ["水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"], + PickerDataType.zodiac: ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'], + PickerDataType.ethnicity: [ + '汉族', + '蒙古族', + '回族', + '藏族', + '维吾尔族', + '苗族', + '彝族', + '壮族', + '布依族', + '朝鲜族', + '满族', + '侗族', + '瑶族', + '白族', + '土家族', + '哈尼族', + '哈萨克族', + '傣族', + '黎族', + '傈僳族', + '佤族', + '畲族', + '高山族', + '拉祜族', + '水族', + '东乡族', + '纳西族', + '景颇族', + '柯尔克孜族', + '土族', + '达斡尔族', + '仫佬族', + '羌族', + '布朗族', + '撒拉族', + '毛难族', + '仡佬族', + '锡伯族', + '阿昌族', + '普米族', + '塔吉克族', + '怒族', + '乌孜别克族', + '俄罗斯族', + '鄂温克族', + '崩龙族', + '保安族', + '裕固族', + '京族', + '塔塔尔族', + '独龙族', + '鄂伦春族', + '赫哲族', + '门巴族', + '珞巴族', + '基诺族', + '其他', + '外国血统中国人士' + ], +}; diff --git a/star_lock/lib/tools/pickers/more_pickers/route/multiple_link_picker_route.dart b/star_lock/lib/tools/pickers/more_pickers/route/multiple_link_picker_route.dart new file mode 100644 index 00000000..10f5c35c --- /dev/null +++ b/star_lock/lib/tools/pickers/more_pickers/route/multiple_link_picker_route.dart @@ -0,0 +1,493 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; + +typedef MultipleLinkCallback(List res, List position); + +/// 多项选择器 +/// 有关联 +class MultipleLinkPickerRoute extends PopupRoute { + MultipleLinkPickerRoute({ + required this.pickerStyle, + required this.data, + required this.selectData, + required this.columeNum, + this.suffix, + this.onChanged, + this.onConfirm, + this.onCancel, + this.theme, + this.barrierLabel, + RouteSettings? settings, + }) : super(settings: settings); + + final Map data; + final int columeNum; + final List selectData; + final List? suffix; + final MultipleLinkCallback? onChanged; + final MultipleLinkCallback? onConfirm; + final Function(bool isCancel)? onCancel; + final ThemeData? theme; + + final PickerStyle pickerStyle; + + @override + Duration get transitionDuration => const Duration(milliseconds: 200); + + @override + bool get barrierDismissible => true; + + @override + bool didPop(T? result) { + if (onCancel != null) { + if (result == null) { + onCancel!(false); + } else if (!(result as bool)) { + onCancel!(true); + } + } + return super.didPop(result); + } + + @override + final String? barrierLabel; + + @override + Color get barrierColor => Colors.black54; + + late AnimationController _animationController; + + @override + AnimationController createAnimationController() { + _animationController = + BottomSheet.createAnimationController(navigator!.overlay!); + return _animationController; + } + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + Widget bottomSheet = MediaQuery.removePadding( + context: context, + removeTop: true, + child: _PickerContentView( + data: data, + columeNum: columeNum, + selectData: selectData, + pickerStyle: pickerStyle, + route: this, + ), + ); + if (theme != null) { + bottomSheet = Theme(data: theme!, child: bottomSheet); + } + + return bottomSheet; + } +} + +class _PickerContentView extends StatefulWidget { + _PickerContentView({ + Key? key, + required this.data, + required this.columeNum, + required this.pickerStyle, + required this.selectData, + required this.route, + }) : super(key: key); + + final Map data; + final int columeNum; + final List selectData; + final MultipleLinkPickerRoute route; + final PickerStyle pickerStyle; + + @override + State createState() => _PickerState( + this.data, this.selectData, this.pickerStyle, this.columeNum); +} + +class _PickerState extends State<_PickerContentView> { + final PickerStyle _pickerStyle; + + // 没有数据时占位字符 + static const placeData = ''; + + /// 选中数据 + late List _selectData; + + /// 选中数据下标 + late List _selectDataPosition; + + /// 原始数据 + Map _data; + + /// 有多少列 + final int _columeNum; + + /// 所有item 对应的数据 + late List _columnData = []; + + AnimationController? controller; + Animation? animation; + + List scrollCtrl = []; + + // 选择器 高度 单独提出来,用来解决修改数据 不及时更新的BUG + late double pickerItemHeight; + + _PickerState( + this._data, List mSelectData, this._pickerStyle, this._columeNum) { + this.pickerItemHeight = _pickerStyle.pickerItemHeight; + // 已选择器数据为准,因为初始化数据有可能和选择器对不上 + this._selectData = []; + this._selectDataPosition = []; + for (int i = 0; i < _columeNum; ++i) { + if (i >= mSelectData.length) { + this._selectData.add(''); + } else { + this._selectData.add(mSelectData[i]); + } + this._selectDataPosition.add(0); + } + + _init(mSelectData); + } + + @override + void dispose() { + scrollCtrl.forEach((element) { + element.dispose(); + }); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: AnimatedBuilder( + animation: widget.route.animation!, + builder: (BuildContext context, Widget? child) { + return ClipRect( + child: CustomSingleChildLayout( + delegate: _BottomPickerLayout(widget.route.animation!.value, + pickerStyle: _pickerStyle), + child: GestureDetector( + child: Material( + color: Colors.transparent, + child: _renderPickerView(), + ), + ), + ), + ); + }, + ), + ); + } + + _init(List mSelectData) { + int pindex; + scrollCtrl.clear(); + _columnData.clear(); + + for (int i = 0; i < _columeNum; ++i) { + pindex = 0; + + if (i == 0) { + /// 第一列 + pindex = _data.keys.toList().indexOf(_selectData[i]); + if (pindex < 0) { + _selectData[i] = _data.keys.first; + pindex = 0; + } + _selectDataPosition[i] = pindex; + + _columnData.add(_data.keys.toList()); + } else { + /// 其他列 + dynamic date = findNextData(i); + // print('longer 第$i列 >>> $date'); + + if (date is Map) { + pindex = date.keys.toList().indexOf(_selectData[i]); + if (pindex < 0) { + _selectData[i] = date.keys.first; + pindex = 0; + } + + _columnData.add(date.keys.toList()); + } else if (date is List) { + pindex = date.indexOf(_selectData[i]); + if (pindex < 0) { + _selectData[i] = date.first; + pindex = 0; + } + _columnData.add(date); + } else { + _selectData[i] = date; + pindex = 0; + + _columnData.add([date]); + } + + _selectDataPosition[i] = pindex; + } + + scrollCtrl.add(FixedExtentScrollController(initialItem: pindex)); + } + } + + /// [position] 变动的列 + /// [selectIndex] 对应列选中的index + /// [jump] 是否需要jumpToItem + void _setPicker(int position, int selectIndex, bool jump) { + // 得到新的选中的数据 + var selectValue = _columnData[position][selectIndex]; + // 更新选中数据 + _selectData[position] = selectValue; + _selectDataPosition[position] = selectIndex; + if (jump) { + scrollCtrl[position].jumpToItem(selectIndex); + } + + /// 如果不是最后一列 + /// 数据的变动都会造成剩下列的更新 + if (position < _columeNum - 1) { + // 先更新下一列所有数据 + // 如果这一列的所有数据都为空,下列直接也设为空数据(优化) + if (_columnData[position].length == 1 && + _columnData[position].first == placeData) { + _columnData[position + 1] = [placeData]; + } else { + _columnData[position + 1] = findColumeData(position + 1); + } + + // 再次递归 + _setPicker(position + 1, 0, true); + } else { + _notifyLocationChanged(); + } + } + + /// 找到对应位置的 下一列数据 + /// return map list other + dynamic findNextData(int position) { + dynamic nextData; + + for (int i = 0; i < position; i++) { + if (i == 0) { + // 肯定是map + nextData = _data[_selectData[0]]; + } else { + // 肯定是map + dynamic data = nextData[_selectData[i]]; + + if (data is Map) { + nextData = data; + } else if (data is List) { + nextData = data; + } else { + // 遍历到最后会返回该值 + nextData = [data]; + } + } + // print('longer i:$i >>> $nextData'); + + /// 如果数据 还没有到最后 就 已经不是Map + if (!(nextData is Map) && (i < position - 1)) { + return [placeData]; + } + } + + return nextData; + } + + /// 找到对应位置的数据 + /// 比如 position = 2; + /// 就是找到第2列数据 + /// return list + List findColumeData(int position) { + dynamic nextData; + for (int i = 0; i < position; i++) { + if (i == 0) { + // 肯定是map + nextData = _data[_selectData[0]]; + } else { + // print( + // 'longer 选中 >>> ${_selectData.join('-')} 当前选中: ${_selectData[i]}'); + // 肯定是map + dynamic data = nextData[_selectData[i]]; + + if (data is Map) { + nextData = data; + } else if (data is List) { + nextData = data; + } else { + // 遍历到最后会返回该值 + nextData = [data]; + } + } + // print('longer i:$i >>> $nextData'); + + /// 如果是map 并且是最后一列 返回他的key + if ((nextData is Map) && (i == position - 1)) { + return nextData.keys.toList(); + } + + /// 如果数据 还没有到最后 就 已经不是Map + if (!(nextData is Map) && (i < position - 1)) { + // print('longer2 第:$position列之前返回数据 >>> $nextData'); + return [placeData]; + } + } + + // print('longer 第:$position列返回数据 >>> $nextData'); + return nextData; + } + + void _notifyLocationChanged() { + setState(() { + /// FIX:https://github.com/flutter/flutter/issues/22999 + pickerItemHeight = + _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000; + }); + if (widget.route.onChanged != null) { + widget.route.onChanged!(_selectData, _selectDataPosition); + } + } + + Widget _renderPickerView() { + Widget itemView = _renderItemView(); + + if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) { + return itemView; + } + List viewList = []; + if (_pickerStyle.showTitleBar) { + viewList.add(_titleView()); + } + if (_pickerStyle.menu != null) { + viewList.add(_pickerStyle.menu!); + } + viewList.add(itemView); + + return Column(children: viewList); + } + + Widget _renderItemView() { + // 选择器 + List pickerList = + List.generate(_columeNum, (index) => pickerView(index)).toList(); + + return Container( + height: _pickerStyle.pickerHeight, + color: _pickerStyle.backgroundColor, + child: Row(children: pickerList), + ); + } + + Widget pickerView(int position) { + return Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 2), + child: CupertinoPicker.builder( + scrollController: scrollCtrl[position], + itemExtent: pickerItemHeight, + selectionOverlay: _pickerStyle.itemOverlay, + onSelectedItemChanged: (int selectIndex) { + _setPicker(position, selectIndex, false); + }, + childCount: _columnData[position].length, + itemBuilder: (_, index) { + // String text = _data[position][index].toString(); + String suffix = ''; + if (widget.route.suffix != null && + position < widget.route.suffix!.length) { + suffix = widget.route.suffix![position]; + } + + String text = '${_columnData[position][index]}$suffix'; + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: _pickerStyle.textSize ?? 18.0, + ), + textAlign: TextAlign.start)); + }, + ), + ), + ); + } + + // 选择器上面的view + Widget _titleView() { + return Container( + height: _pickerStyle.pickerTitleHeight, + decoration: _pickerStyle.headDecoration, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// 取消按钮 + InkWell( + onTap: () => Navigator.pop(context, false), + child: _pickerStyle.cancelButton), + + /// 标题 + Expanded(child: _pickerStyle.title), + + /// 确认按钮 + InkWell( + onTap: () { + if (widget.route.onConfirm != null) { + widget.route.onConfirm!(_selectData, _selectDataPosition); + } + Navigator.pop(context, true); + }, + child: _pickerStyle.commitButton) + ], + ), + ); + } +} + +class _BottomPickerLayout extends SingleChildLayoutDelegate { + _BottomPickerLayout(this.progress, {required this.pickerStyle}); + + final double progress; + final PickerStyle pickerStyle; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + double maxHeight = pickerStyle.pickerHeight; + if (pickerStyle.showTitleBar) { + maxHeight += pickerStyle.pickerTitleHeight; + } + if (pickerStyle.menu != null) { + maxHeight += pickerStyle.menuHeight; + } + + return BoxConstraints( + minWidth: constraints.maxWidth, + maxWidth: constraints.maxWidth, + minHeight: 0.0, + maxHeight: maxHeight); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + double height = size.height - childSize.height * progress; + return Offset(0.0, height); + } + + @override + bool shouldRelayout(_BottomPickerLayout oldDelegate) { + return progress != oldDelegate.progress; + } +} diff --git a/star_lock/lib/tools/pickers/more_pickers/route/multiple_picker_route.dart b/star_lock/lib/tools/pickers/more_pickers/route/multiple_picker_route.dart new file mode 100644 index 00000000..9ff6e06d --- /dev/null +++ b/star_lock/lib/tools/pickers/more_pickers/route/multiple_picker_route.dart @@ -0,0 +1,332 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; + +typedef MultipleCallback(List res, List position); + +/// 多项选择器 +/// 无关联 +class MultiplePickerRoute extends PopupRoute { + MultiplePickerRoute({ + required this.pickerStyle, + required this.data, + required this.selectData, + this.suffix, + this.onChanged, + this.onConfirm, + this.onCancel, + this.theme, + this.barrierLabel, + RouteSettings? settings, + }) : super(settings: settings); + + final List data; + final List selectData; + final List? suffix; + final MultipleCallback? onChanged; + final MultipleCallback? onConfirm; + final Function(bool isCancel)? onCancel; + final ThemeData? theme; + + final PickerStyle pickerStyle; + + @override + Duration get transitionDuration => const Duration(milliseconds: 200); + + @override + bool get barrierDismissible => true; + + @override + bool didPop(T? result) { + if (onCancel != null) { + if (result == null) { + onCancel!(false); + } else if (!(result as bool)) { + onCancel!(true); + } + } + return super.didPop(result); + } + + @override + final String? barrierLabel; + + @override + Color get barrierColor => Colors.black54; + + late AnimationController _animationController; + + @override + AnimationController createAnimationController() { + _animationController = + BottomSheet.createAnimationController(navigator!.overlay!); + return _animationController; + } + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + Widget bottomSheet = MediaQuery.removePadding( + context: context, + removeTop: true, + child: _PickerContentView( + data: data, + selectData: selectData, + pickerStyle: pickerStyle, + route: this, + ), + ); + if (theme != null) { + bottomSheet = Theme(data: theme!, child: bottomSheet); + } + + return bottomSheet; + } +} + +class _PickerContentView extends StatefulWidget { + _PickerContentView({ + Key? key, + required this.data, + required this.pickerStyle, + required this.selectData, + required this.route, + }) : super(key: key); + + final List data; + final List selectData; + final MultiplePickerRoute route; + final PickerStyle pickerStyle; + + @override + State createState() => + _PickerState(this.data, this.selectData, this.pickerStyle); +} + +class _PickerState extends State<_PickerContentView> { + final PickerStyle _pickerStyle; + late List _selectData; + late List _selectDataPosition; + List _data; + + AnimationController? controller; + Animation? animation; + + List scrollCtrl = []; + + _PickerState(this._data, List mSelectData, this._pickerStyle) { + // 已选择器数据为准,因为初始化数据有可能和选择器对不上 + this._selectData = []; + this._selectDataPosition = []; + this._data.asMap().keys.forEach((index) { + if (index >= mSelectData.length) { + this._selectData.add(''); + } else { + this._selectData.add(mSelectData[index]); + } + this._selectDataPosition.add(0); + }); + + _init(); + } + + @override + void dispose() { + scrollCtrl.forEach((element) { + element.dispose(); + }); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: AnimatedBuilder( + animation: widget.route.animation!, + builder: (BuildContext context, Widget? child) { + return ClipRect( + child: CustomSingleChildLayout( + delegate: _BottomPickerLayout(widget.route.animation!.value, + pickerStyle: _pickerStyle), + child: GestureDetector( + child: Material( + color: Colors.transparent, + child: _renderPickerView(), + ), + ), + ), + ); + }, + ), + ); + } + + _init() { + int pindex; + scrollCtrl.clear(); + + this._data.asMap().keys.forEach((index) { + pindex = 0; + pindex = _data[index].indexWhere( + (element) => element.toString() == _selectData[index].toString()); + // 如果没有匹配到选择器对应数据,我们得修改选择器选中数据 ,不然confirm 返回的事设置的数据 + if (pindex < 0) { + _selectData[index] = _data[index][0]; + pindex = 0; + } + _selectDataPosition[index] = pindex; + + scrollCtrl.add(new FixedExtentScrollController(initialItem: pindex)); + }); + } + + void _setPicker(int index, int selectIndex) { + var selectedName = _data[index][selectIndex]; + + // if (_selectData[index].toString() != selectedName.toString()) { + // setState(() { + // }); + // } + _selectData[index] = selectedName; + _selectDataPosition[index] = selectIndex; + + _notifyLocationChanged(); + } + + void _notifyLocationChanged() { + if (widget.route.onChanged != null) { + widget.route.onChanged!(_selectData, _selectDataPosition); + } + } + + Widget _renderPickerView() { + Widget itemView = _renderItemView(); + + if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) { + return itemView; + } + List viewList = []; + if (_pickerStyle.showTitleBar) { + viewList.add(_titleView()); + } + if (_pickerStyle.menu != null) { + viewList.add(_pickerStyle.menu!); + } + viewList.add(itemView); + + return Column(children: viewList); + } + + Widget _renderItemView() { + // 选择器 + List pickerList = + List.generate(this._data.length, (index) => pickerView(index)).toList(); + + return Container( + height: _pickerStyle.pickerHeight, + color: _pickerStyle.backgroundColor, + child: Row(children: pickerList), + ); + } + + Widget pickerView(int position) { + return Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 2), + child: CupertinoPicker.builder( + scrollController: scrollCtrl[position], + selectionOverlay: _pickerStyle.itemOverlay, + itemExtent: _pickerStyle.pickerItemHeight, + onSelectedItemChanged: (int selectIndex) => + _setPicker(position, selectIndex), + childCount: _data[position].length, + itemBuilder: (_, index) { + // String text = _data[position][index].toString(); + String suffix = ''; + if (widget.route.suffix != null && + position < widget.route.suffix!.length) { + suffix = widget.route.suffix![position]; + } + + String text = '${_data[position][index]}$suffix'; + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: _pickerStyle.textSize ?? 18, + ), + textAlign: TextAlign.start)); + }, + ), + ), + ); + } + + // 选择器上面的view + Widget _titleView() { + return Container( + height: _pickerStyle.pickerTitleHeight, + decoration: _pickerStyle.headDecoration, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// 取消按钮 + InkWell( + onTap: () => Navigator.pop(context, false), + child: _pickerStyle.cancelButton), + + /// 标题 + Expanded(child: _pickerStyle.title), + + /// 确认按钮 + InkWell( + onTap: () { + if (widget.route.onConfirm != null) { + widget.route.onConfirm!(_selectData, _selectDataPosition); + } + Navigator.pop(context, true); + }, + child: _pickerStyle.commitButton) + ], + ), + ); + } +} + +class _BottomPickerLayout extends SingleChildLayoutDelegate { + _BottomPickerLayout(this.progress, {required this.pickerStyle}); + + final double progress; + final PickerStyle pickerStyle; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + double maxHeight = pickerStyle.pickerHeight; + if (pickerStyle.showTitleBar) { + maxHeight += pickerStyle.pickerTitleHeight; + } + if (pickerStyle.menu != null) { + maxHeight += pickerStyle.menuHeight; + } + + return BoxConstraints( + minWidth: constraints.maxWidth, + maxWidth: constraints.maxWidth, + minHeight: 0.0, + maxHeight: maxHeight); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + double height = size.height - childSize.height * progress; + return Offset(0.0, height); + } + + @override + bool shouldRelayout(_BottomPickerLayout oldDelegate) { + return progress != oldDelegate.progress; + } +} diff --git a/star_lock/lib/tools/pickers/more_pickers/route/single_picker_route.dart b/star_lock/lib/tools/pickers/more_pickers/route/single_picker_route.dart new file mode 100644 index 00000000..435f4146 --- /dev/null +++ b/star_lock/lib/tools/pickers/more_pickers/route/single_picker_route.dart @@ -0,0 +1,362 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/more_pickers/init_data.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/more_pickers/init_data.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; + +typedef SingleCallback(var data, int position); + +class SinglePickerRoute extends PopupRoute { + SinglePickerRoute({ + required this.data, + this.selectData, + this.suffix, + this.onChanged, + this.onConfirm, + this.onCancel, + required this.theme, + this.barrierLabel, + required this.pickerStyle, + RouteSettings? settings, + }) : super(settings: settings); + + final dynamic selectData; + final dynamic data; + final SingleCallback? onChanged; + final SingleCallback? onConfirm; + final Function(bool isCancel)? onCancel; + final ThemeData theme; + + final String? suffix; + final PickerStyle pickerStyle; + + @override + Duration get transitionDuration => const Duration(milliseconds: 200); + + @override + bool get barrierDismissible => true; + + @override + final String? barrierLabel; + + @override + bool didPop(T? result) { + if (onCancel != null) { + if (result == null) { + onCancel!(false); + } else if (!(result as bool)) { + onCancel!(true); + } + } + return super.didPop(result); + } + + @override + Color get barrierColor => Colors.black54; + + late AnimationController _animationController; + + @override + AnimationController createAnimationController() { + _animationController = + BottomSheet.createAnimationController(navigator!.overlay!); + return _animationController; + } + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + List mData = []; + // 初始化数据 + if (data is PickerDataType) { + mData = pickerData[data]!; + } else if (data is List) { + mData.addAll(data); + } + + Widget bottomSheet = MediaQuery.removePadding( + context: context, + removeTop: true, + child: _PickerContentView( + data: mData, + selectData: selectData, + pickerStyle: pickerStyle, + route: this, + ), + ); + bottomSheet = Theme(data: theme, child: bottomSheet); + + return bottomSheet; + } +} + +class _PickerContentView extends StatefulWidget { + _PickerContentView({ + Key? key, + required this.data, + this.selectData, + required this.pickerStyle, + required this.route, + }) : super(key: key); + + final List data; + final dynamic selectData; + final SinglePickerRoute route; + final PickerStyle pickerStyle; + + @override + State createState() => + _PickerState(this.data, this.selectData, this.pickerStyle); +} + +class _PickerState extends State<_PickerContentView> { + final PickerStyle _pickerStyle; + + // 选中数据 + var _selectData; + + // 选中数据下标 + int _selectPosition = 0; + + List _data = []; + + late FixedExtentScrollController scrollCtrl; + + // 单位widget Padding left + late double _laberLeft; + + _PickerState(this._data, this._selectData, this._pickerStyle) { + _init(); + } + + @override + void dispose() { + scrollCtrl.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: AnimatedBuilder( + animation: widget.route.animation!, + builder: (BuildContext context, Widget? child) { + return ClipRect( + child: CustomSingleChildLayout( + delegate: _BottomPickerLayout(widget.route.animation!.value, + pickerStyle: _pickerStyle), + child: GestureDetector( + child: Material( + color: Colors.transparent, + child: _renderPickerView(), + ), + ), + ), + ); + }, + ), + ); + } + + _init() { + int pindex = 0; + pindex = _data + .indexWhere((element) => element.toString() == _selectData.toString()); + // 如果没有匹配到选择器对应数据,我们得修改选择器选中数据 ,不然confirm 返回的事设置的数据 + if (pindex < 0) { + _selectData = _data[0]; + pindex = 0; + } + _selectPosition = pindex; + + scrollCtrl = new FixedExtentScrollController(initialItem: pindex); + _laberLeft = _pickerLaberPadding(_data[pindex].toString()); + } + + void _setPicker(int index) { + var selectedProvince = _data[index]; + + // if (_selectData.toString() != selectedProvince.toString()) { + // setState(() { + // }); + _selectData = selectedProvince; + _selectPosition = index; + + _notifyLocationChanged(); + // } + } + + void _notifyLocationChanged() { + if (widget.route.onChanged != null) { + widget.route.onChanged!(_selectData, _selectPosition); + } + } + + double _pickerLaberPadding(String? text) { + double left = 60; + + if (text != null) { + left = left + text.length * 12; + } + return left; + } + + /// 动态计算itemTextSize + double _pickerFontSize(String text) { + if (text.length <= 6) { + return 18.0; + } else if (text.length < 9) { + return 16.0; + } else if (text.length < 13) { + return 12.0; + } else { + return 10.0; + } + } + + Widget _renderPickerView() { + Widget itemView = _renderItemView(); + + if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) { + return itemView; + } + List viewList = []; + if (_pickerStyle.showTitleBar) { + viewList.add(_titleView()); + } + if (_pickerStyle.menu != null) { + viewList.add(_pickerStyle.menu!); + } + viewList.add(itemView); + + return Column(children: viewList); + } + + Widget _renderItemView() { + // 选择器 + Widget cPicker = CupertinoPicker.builder( + scrollController: scrollCtrl, + itemExtent: _pickerStyle.pickerItemHeight, + selectionOverlay: _pickerStyle.itemOverlay, + onSelectedItemChanged: (int index) { + _setPicker(index); + if (widget.route.suffix != null && widget.route.suffix != '') { + // 如果设置了才计算 单位的paddingLeft + double resuleLeft = _pickerLaberPadding(_data[index].toString()); + if (resuleLeft != _laberLeft) { + setState(() { + _laberLeft = resuleLeft; + }); + } + } + }, + childCount: _data.length, + itemBuilder: (_, index) { + String text = _data[index].toString(); + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: _pickerStyle.textSize ?? _pickerFontSize(text), + ), + textAlign: TextAlign.start)); + }, + ); + + Widget view; + // 单位 + if (widget.route.suffix != null && widget.route.suffix != '') { + Widget laberView = Center( + child: AnimatedPadding( + duration: Duration(milliseconds: 100), + padding: EdgeInsets.only(left: _laberLeft), + child: Text(widget.route.suffix!, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: 20, + fontWeight: FontWeight.w500)), + )); + + view = Stack(children: [cPicker, laberView]); + } else { + view = cPicker; + } + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 40), + height: _pickerStyle.pickerHeight, + color: _pickerStyle.backgroundColor, + child: view, + ); + } + + // 选择器上面的view + Widget _titleView() { + return Container( + height: _pickerStyle.pickerTitleHeight, + decoration: _pickerStyle.headDecoration, + child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// 取消按钮 + InkWell( + onTap: () => Navigator.pop(context, false), + child: _pickerStyle.cancelButton), + + /// 标题 + Expanded(child: _pickerStyle.title), + + /// 确认按钮 + InkWell( + onTap: () { + if (widget.route.onConfirm != null) { + print('longer _selectPosition >>> ${_selectPosition}'); + widget.route.onConfirm!(_selectData, _selectPosition); + } + Navigator.pop(context, true); + }, + child: _pickerStyle.commitButton) + ], + ), + ); + } +} + +class _BottomPickerLayout extends SingleChildLayoutDelegate { + _BottomPickerLayout(this.progress, {required this.pickerStyle}); + + final double progress; + final PickerStyle pickerStyle; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + double maxHeight = pickerStyle.pickerHeight; + if (pickerStyle.showTitleBar) { + maxHeight += pickerStyle.pickerTitleHeight; + } + if (pickerStyle.menu != null) { + maxHeight += pickerStyle.menuHeight; + } + + return BoxConstraints( + minWidth: constraints.maxWidth, + maxWidth: constraints.maxWidth, + minHeight: 0.0, + maxHeight: maxHeight); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + double height = size.height - childSize.height * progress; + return Offset(0.0, height); + } + + @override + bool shouldRelayout(_BottomPickerLayout oldDelegate) { + return progress != oldDelegate.progress; + } +} diff --git a/star_lock/lib/tools/pickers/pickers.dart b/star_lock/lib/tools/pickers/pickers.dart new file mode 100644 index 00000000..1930b822 --- /dev/null +++ b/star_lock/lib/tools/pickers/pickers.dart @@ -0,0 +1,252 @@ +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/address_picker/route/address_picker_route.dart'; +import 'package:star_lock/tools/pickers/more_pickers/init_data.dart'; +import 'package:star_lock/tools/pickers/more_pickers/route/multiple_link_picker_route.dart'; +import 'package:star_lock/tools/pickers/more_pickers/route/multiple_picker_route.dart'; +import 'package:star_lock/tools/pickers/more_pickers/route/single_picker_route.dart'; +import 'package:star_lock/tools/pickers/style/default_style.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/suffix.dart'; +import 'package:star_lock/tools/pickers/time_picker/route/date_picker_route.dart'; +// import 'package:flutter_pickers/address_picker/route/address_picker_route.dart'; +// import 'package:flutter_pickers/more_pickers/init_data.dart'; +// import 'package:flutter_pickers/more_pickers/route/multiple_link_picker_route.dart'; +// import 'package:flutter_pickers/more_pickers/route/multiple_picker_route.dart'; +// import 'package:flutter_pickers/more_pickers/route/single_picker_route.dart'; +// import 'package:flutter_pickers/style/default_style.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/time_picker/model/pduration.dart'; +// import 'package:flutter_pickers/time_picker/model/suffix.dart'; +// import 'package:flutter_pickers/time_picker/route/date_picker_route.dart'; + +import 'time_picker/model/date_item_model.dart'; + +/// [onChanged] 选择器发生变动 +/// [onConfirm] 选择器提交 +/// [pickerStyle] 样式 +/// [suffix] 后缀 +class Pickers { + /// 单列 通用选择器 + static void showSinglePicker(BuildContext context, + {required dynamic data, + dynamic selectData, + String? suffix, + PickerStyle? pickerStyle, + SingleCallback? onChanged, + SingleCallback? onConfirm, + Function(bool isCancel)? onCancel, + bool overlapTabBar = false}) { + assert((data is List) || (data is PickerDataType), + 'params : data must List or PickerDataType'); + + if (pickerStyle == null) { + pickerStyle = DefaultPickerStyle(); + } + if (pickerStyle.context == null) { + pickerStyle.context = context; + } + + Navigator.of(context, rootNavigator: overlapTabBar).push(SinglePickerRoute( + data: data, + suffix: suffix, + selectData: selectData, + pickerStyle: pickerStyle, + onChanged: onChanged, + onConfirm: onConfirm, + onCancel: onCancel, + // theme: Theme.of(context, shadowThemeOnly: true), + theme: Theme.of(context), + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + )); + } + + /// 通用 多列选择器 + /// 无关联 + static void showMultiPicker(BuildContext context, + {required List data, + List? selectData, + List? suffix, + PickerStyle? pickerStyle, + MultipleCallback? onChanged, + MultipleCallback? onConfirm, + Function(bool isCancel)? onCancel, + bool overlapTabBar = false}) { + if (selectData == null) { + selectData = []; + } + + if (pickerStyle == null) { + pickerStyle = DefaultPickerStyle(); + } + if (pickerStyle.context == null) { + pickerStyle.context = context; + } + + Navigator.of(context, rootNavigator: overlapTabBar) + .push(MultiplePickerRoute( + data: data, + selectData: selectData, + suffix: suffix, + pickerStyle: pickerStyle, + onChanged: onChanged, + onConfirm: onConfirm, + onCancel: onCancel, + // theme: Theme.of(context, shadowThemeOnly: true), + theme: Theme.of(context), + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + )); + } + + /// 通用 多列选择器 + /// 有关联 + /// [columeNum] 最大的列数 + static void showMultiLinkPicker(BuildContext context, + {required dynamic data, + required int columeNum, + List? selectData, + List? suffix, + PickerStyle? pickerStyle, + MultipleLinkCallback? onChanged, + MultipleLinkCallback? onConfirm, + Function(bool isCancel)? onCancel, + bool overlapTabBar = false}) { + assert(data is Map, 'params : data must Map'); + + if (selectData == null) { + selectData = []; + } + + if (pickerStyle == null) { + pickerStyle = DefaultPickerStyle(); + } + if (pickerStyle.context == null) { + pickerStyle.context = context; + } + + Navigator.of(context, rootNavigator: overlapTabBar) + .push(MultipleLinkPickerRoute( + data: data, + selectData: selectData, + columeNum: columeNum, + suffix: suffix, + pickerStyle: pickerStyle, + onChanged: onChanged, + onConfirm: onConfirm, + onCancel: onCancel, + // theme: Theme.of(context, shadowThemeOnly: true), + theme: Theme.of(context), + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + )); + } + + /// 自定义 地区选择器 + /// [initProvince] 初始化 省 + /// [initCity] 初始化 市 + /// [initTown] 初始化 区 + /// [onChanged] 选择器发生变动 + /// [onConfirm] 选择器提交 + /// [addAllItem] 市、区是否添加 '全部' 选项 默认:true + static void showAddressPicker(BuildContext context, + {PickerStyle? pickerStyle, + String initProvince: '', + String initCity: '', + String? initTown, + bool addAllItem: true, + AddressCallback? onChanged, + AddressCallback? onConfirm, + Function(bool isCancel)? onCancel, + bool overlapTabBar = false}) { + if (pickerStyle == null) { + pickerStyle = DefaultPickerStyle(); + } + if (pickerStyle.context == null) { + pickerStyle.context = context; + } + + Navigator.of(context, rootNavigator: overlapTabBar).push(AddressPickerRoute( + pickerStyle: pickerStyle, + initProvince: initProvince, + initCity: initCity, + initTown: initTown, + onChanged: onChanged, + onConfirm: onConfirm, + onCancel: onCancel, + addAllItem: addAllItem, + theme: Theme.of(context), + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + )); + } + + /// 时间选择器 + /// [Suffix] : 每列时间对应的单位 默认:中文常规 Suffix(years: '年',month: '月'); + /// [selectDate] : 初始化选中时间 默认现在 + /// PDuration.now(); + /// PDuration.parse(DateTime.parse('20210139')); + /// PDuration(year: 2020,month: 2); + /// [maxDate] : 最大时间 用法同上 + /// tip: 当只有单列数据,该限制不产生关联 只针对单列item限制,比如 maxDate>day = 3 minDate>day = 10,那么所有的月份都只显示3-10之间 + /// [minDate] : 最小时间 用法同上 + /// [mode] : 时间选择器所显示样式 16 种时间样式 默认:DateMode.YMD + static void showDatePicker(BuildContext context, + {DateMode mode: DateMode.YMD, + PDuration? selectDate, + PDuration? maxDate, + PDuration? minDate, + Suffix? suffix, + PickerStyle? pickerStyle, + DateCallback? onChanged, + DateCallback? onConfirm, + Function(bool isCancel)? onCancel, + bool overlapTabBar = false}) { + if (pickerStyle == null) { + pickerStyle = DefaultPickerStyle(); + } + if (pickerStyle.context == null) { + pickerStyle.context = context; + } + + if (selectDate == null) selectDate = PDuration.now(); + if (suffix == null) suffix = Suffix.normal(); + + // 解析是否有对应数据 + DateItemModel dateItemModel = DateItemModel.parse(mode); + + if (maxDate == null) maxDate = PDuration(year: 2100); + if (minDate == null) minDate = PDuration(year: 1900); + + if ((dateItemModel.day || dateItemModel.year)) { + if (intEmpty(selectDate.year)) { + print('picker Tip >>> initDate未设置years,默认设置为now().year'); + selectDate.year = DateTime.now().year; + } + + /// 如果有年item ,必须限制 + if (intEmpty(maxDate.year)) maxDate.year = 2100; + if (intEmpty(minDate.year)) minDate.year = 1900; + + // print('longer >>> ${minDate.year}'); + + if (dateItemModel.month || dateItemModel.day) { + assert(minDate.year! > 1582, 'min Date Year must > 1582'); + } + } + + Navigator.of(context, rootNavigator: overlapTabBar).push(DatePickerRoute( + mode: mode, + initDate: selectDate, + maxDate: maxDate, + minDate: minDate, + suffix: suffix, + pickerStyle: pickerStyle, + onChanged: onChanged, + onConfirm: onConfirm, + onCancel: onCancel, + // theme: Theme.of(context, shadowThemeOnly: true), + theme: Theme.of(context), + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + )); + } +} diff --git a/star_lock/lib/tools/pickers/style/default_style.dart b/star_lock/lib/tools/pickers/style/default_style.dart new file mode 100644 index 00000000..56e43d9b --- /dev/null +++ b/star_lock/lib/tools/pickers/style/default_style.dart @@ -0,0 +1,205 @@ +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; + +// 日间圆角 +const headDecorationLight = BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + +/// 无标题样式 +class NoTitleStyle extends PickerStyle { + NoTitleStyle() { + showTitleBar = false; + } + + /// 夜间 + NoTitleStyle.dark() { + showTitleBar = false; + backgroundColor = Colors.grey[800]!; + textColor = Colors.white; + } +} + +/// 默认样式 +class DefaultPickerStyle extends PickerStyle { + DefaultPickerStyle({bool haveRadius = false, String? title}) { + if (haveRadius) { + headDecoration = const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + } + if (title != null && title != '') { + this.title = Center( + child: Text(title, + style: const TextStyle(color: Colors.grey, fontSize: 14))); + } + } + + /// 夜间 + DefaultPickerStyle.dark({bool haveRadius = false, String? title}) { + commitButton = Container( + alignment: Alignment.center, + padding: const EdgeInsets.only(left: 12, right: 22), + child: const Text('确定', + style: TextStyle(color: Colors.white, fontSize: 16.0)), + ); + + cancelButton = Container( + alignment: Alignment.center, + padding: const EdgeInsets.only(left: 22, right: 12), + child: const Text('取消', + style: TextStyle(color: Colors.white, fontSize: 16.0)), + ); + + headDecoration = BoxDecoration( + color: Colors.grey[800], + borderRadius: !haveRadius + ? null + : const BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + + if (title != null && title != '') { + this.title = Center( + child: Text(title, + style: const TextStyle(color: Colors.white, fontSize: 14))); + } + + backgroundColor = Colors.grey[800]!; + textColor = Colors.white; + } +} + +/// 关闭按钮样式 +class ClosePickerStyle extends PickerStyle { + /// 日间 + ClosePickerStyle({bool haveRadius = false, String? title}) { + if (haveRadius) { + headDecoration = const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + } + + cancelButton = const SizedBox(); + if (title != null && title != '') { + this.title = Padding( + padding: const EdgeInsets.only(left: 16), + child: Align( + alignment: Alignment.centerLeft, + child: Text(title, + style: const TextStyle(color: Colors.grey, fontSize: 14))), + ); + } + commitButton = Container( + // padding: const EdgeInsets.all(4), + margin: const EdgeInsets.only(right: 12), + child: const Icon(Icons.close, color: Colors.grey, size: 28), + ); + } + + /// 夜间 + ClosePickerStyle.dark({bool haveRadius = false, String? title}) { + headDecoration = BoxDecoration( + color: Colors.grey[800], + borderRadius: !haveRadius + ? null + : const BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + + cancelButton = const SizedBox(); + commitButton = Container( + margin: const EdgeInsets.only(right: 12), + child: const Icon(Icons.close, color: Colors.white, size: 28), + ); + if (title != null && title != '') { + this.title = Padding( + padding: const EdgeInsets.only(left: 16), + child: Align( + alignment: Alignment.centerLeft, + child: Text(title, + style: const TextStyle(color: Colors.white, fontSize: 14))), + ); + } + + backgroundColor = Colors.grey[800]!; + textColor = Colors.white; + } +} + +/// 圆角按钮样式 +class RaisedPickerStyle extends PickerStyle { + RaisedPickerStyle( + {bool haveRadius = false, String? title, Color color = Colors.blue}) { + if (haveRadius) { + headDecoration = const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + } + commitButton = Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), + margin: const EdgeInsets.only(right: 22), + decoration: + BoxDecoration(color: color, borderRadius: BorderRadius.circular(4)), + child: const Text('确定', + style: TextStyle(color: Colors.white, fontSize: 15.0)), + ); + + cancelButton = Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), + margin: const EdgeInsets.only(left: 22), + decoration: BoxDecoration( + border: Border.all(color: color, width: 1), + borderRadius: BorderRadius.circular(4)), + child: Text('取消', style: TextStyle(color: color, fontSize: 15.0)), + ); + + if (title != null && title != '') { + this.title = Center( + child: Text(title, + style: const TextStyle(color: Colors.grey, fontSize: 14))); + } + } + + /// 夜间 + RaisedPickerStyle.dark( + {bool haveRadius = false, String? title, Color? color}) { + headDecoration = BoxDecoration( + color: Colors.grey[800], + borderRadius: !haveRadius + ? null + : const BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10))); + + commitButton = Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), + margin: const EdgeInsets.only(right: 22), + decoration: BoxDecoration( + color: color ?? Colors.blue, borderRadius: BorderRadius.circular(4)), + child: const Text('确定', + style: TextStyle(color: Colors.white, fontSize: 15.0)), + ); + + cancelButton = Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), + margin: const EdgeInsets.only(left: 22), + decoration: BoxDecoration( + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.circular(4)), + child: const Text('取消', + style: TextStyle(color: Colors.white, fontSize: 15.0)), + ); + + if (title != null && title != '') { + this.title = Center( + child: Text(title, + style: const TextStyle(color: Colors.white, fontSize: 14))); + } + + backgroundColor = Colors.grey[800]!; + textColor = Colors.white; + } +} diff --git a/star_lock/lib/tools/pickers/style/picker_style.dart b/star_lock/lib/tools/pickers/style/picker_style.dart new file mode 100644 index 00000000..f32c87e8 --- /dev/null +++ b/star_lock/lib/tools/pickers/style/picker_style.dart @@ -0,0 +1,186 @@ +import 'package:flutter/material.dart'; + +/// 基础样式 +/// [showTitleBar] 是否显示头部(选择器以上的控件) 默认:true +/// [menu] 头部和选择器之间的菜单widget,默认null 不显示 +/// [title] 头部 中间的标题 默认SizedBox() 不显示 +/// [pickerHeight] 选择器下面 picker 的整体高度 固定高度:220.0 +/// [pickerTitleHeight] 选择器上面 title 确认、取消的整体高度 固定高度:44.0 +/// [pickerItemHeight] 选择器每个被选中item的高度:40.0 +/// [menuHeight] 头部和选择器之间的菜单高度 固定高度:36.0 +/// [cancelButton] 头部的取消按钮 +/// [commitButton] 头部的确认按钮 +/// [textColor] 选择器的文字颜色 默认黑色 +/// [textSize] 选择器的文字大小 +/// [backgroundColor] 选择器的背景颜色 默认白色 +/// [headDecoration] 头部Container 的Decoration 默认:BoxDecoration(color: Colors.white) +/// +class PickerStyle { + BuildContext? _context; + + bool? _showTitleBar; + Widget? _menu; + double? _pickerHeight; + double? _pickerTitleHeight; + double? _pickerItemHeight; + double? _menuHeight; + + Widget? _cancelButton; + Widget? _commitButton; + Widget? _title; + Decoration? _headDecoration; + Color? _backgroundColor; + Color? _textColor; + double? _textSize; + Widget? _itemOverlay; + + PickerStyle({ + BuildContext? context, + bool? showTitleBar, + Widget? menu, + double? pickerHeight, + double? pickerTitleHeight, + double? pickerItemHeight, + double? menuHeight, + Widget? cancelButton, + Widget? commitButton, + Widget? title, + Decoration? headDecoration, + Color? backgroundColor, + Color? textColor, + double? textSize, + Widget? itemOverlay, + }) { + this._context = context; + this._showTitleBar = showTitleBar; + this._menu = menu; + + this._pickerHeight = pickerHeight; + this._pickerTitleHeight = pickerTitleHeight; + this._pickerItemHeight = pickerItemHeight; + this._menuHeight = menuHeight; + + this._cancelButton = cancelButton; + this._commitButton = commitButton; + this._title = title; + this._headDecoration = headDecoration; + this._backgroundColor = backgroundColor; + this._textColor = textColor; + this._textSize = textSize; + this._itemOverlay = itemOverlay; + } + + set context(BuildContext? value) { + _context = value; + } + + set menuHeight(double value) { + _menuHeight = value; + } + + set menu(Widget? value) { + _menu = value; + } + + set pickerHeight(double value) { + _pickerHeight = value; + } + + set pickerTitleHeight(double value) { + _pickerTitleHeight = value; + } + + set pickerItemHeight(double value) { + _pickerItemHeight = value; + } + + set cancelButton(Widget value) { + _cancelButton = value; + } + + set commitButton(Widget value) { + _commitButton = value; + } + + set itemOverlay(Widget? value) { + _itemOverlay = value; + } + + set title(Widget value) { + _title = value; + } + + set headDecoration(Decoration value) { + _headDecoration = value; + } + + set backgroundColor(Color value) { + _backgroundColor = value; + } + + set textColor(Color value) { + _textColor = value; + } + + set textSize(double? value) { + _textSize = value; + } + + set showTitleBar(bool value) { + _showTitleBar = value; + } + + BuildContext? get context => this._context; + + /// 选择器背景色 默认白色 + Color get backgroundColor => this._backgroundColor ?? Colors.white; + + Decoration get headDecoration => + this._headDecoration ?? BoxDecoration(color: Colors.white); + + Widget? get menu => this._menu; + + double get menuHeight => this._menuHeight ?? 36.0; + + double get pickerHeight => this._pickerHeight ?? 220.0; + + double get pickerItemHeight => this._pickerItemHeight ?? 40.0; + + double get pickerTitleHeight => this._pickerTitleHeight ?? 44.0; + + bool get showTitleBar => this._showTitleBar ?? true; + + Color get textColor => this._textColor ?? Colors.black87; + + double? get textSize => this._textSize; + + Widget get title => this._title ?? SizedBox(); + + Widget get commitButton => getCommitButton(); + + Widget get cancelButton => getCancelButton(); + + Widget? get itemOverlay => this._itemOverlay; + + Widget getCommitButton() { + return this._commitButton ?? + Container( + alignment: Alignment.center, + padding: const EdgeInsets.only(left: 12, right: 22), + child: const Text('确定', + style: TextStyle(color: Colors.blue, fontSize: 16.0)), + ); + } + + Widget getCancelButton() { + return this._cancelButton ?? + Container( + alignment: Alignment.center, + padding: const EdgeInsets.only(left: 22, right: 12), + child: Text('取消', + style: TextStyle( + color: Theme.of(context!).unselectedWidgetColor, + fontSize: 16.0)), + ); + } +} diff --git a/star_lock/lib/tools/pickers/time_picker/model/date_item_model.dart b/star_lock/lib/tools/pickers/time_picker/model/date_item_model.dart new file mode 100644 index 00000000..17f5bbe7 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/date_item_model.dart @@ -0,0 +1,57 @@ +// 是否需要 显示/设置 对应的选项 +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; + +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; + +class DateItemModel { + late bool year; + late bool month; + late bool day; + late bool hour; + late bool minute; + late bool second; + + DateItemModel( + this.year, this.month, this.day, this.hour, this.minute, this.second); + + DateItemModel.parse(DateMode dateMode) { + this.year = DateModeMap[dateMode]!.contains('年'); + this.month = DateModeMap[dateMode]!.contains('月'); + this.day = DateModeMap[dateMode]!.contains('日'); + this.hour = DateModeMap[dateMode]!.contains('时'); + this.minute = DateModeMap[dateMode]!.contains('分'); + this.second = DateModeMap[dateMode]!.contains('秒'); + } + + // 返回需要显示多少个picker + int get length { + int i = 0; + if (this.year) ++i; + if (this.month) ++i; + if (this.day) ++i; + if (this.hour) ++i; + if (this.minute) ++i; + if (this.second) ++i; + + return i; + } +} + +const DateModeMap = { + DateMode.YMDHMS: "年月日时分秒", + DateMode.YMDHM: '年月日时分', + DateMode.YMDH: '年月日时', + DateMode.YMD: '年月日', + DateMode.YM: '年月', + DateMode.Y: '年', + DateMode.MDHMS: '月日时分秒', + DateMode.MDHM: '月日时分', + DateMode.MDH: '月日时', + DateMode.MD: '月日', + DateMode.HMS: '时分秒', + DateMode.HM: '时分', + DateMode.MS: '分秒', + DateMode.S: '秒', + DateMode.M: '月', + DateMode.H: '时' +}; diff --git a/star_lock/lib/tools/pickers/time_picker/model/date_mode.dart b/star_lock/lib/tools/pickers/time_picker/model/date_mode.dart new file mode 100644 index 00000000..b5f7806b --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/date_mode.dart @@ -0,0 +1,53 @@ +/// 时间选择器 所显示样式 +/// 16 种时间样式 +/// +enum DateMode { + /// 【yyyy-MM-dd HH:mm:ss】年月日时分秒 + YMDHMS, + + /// 【yyyy-MM-dd HH:mm】年月日时分 + YMDHM, + + /// 【yyyy-MM-dd HH】年月日时 + YMDH, + + /// 【yyyy-MM-dd】年月日 + YMD, + + /// 【yyyy-MM】年月 + YM, + + /// 【yyyy】年 + Y, + + /// 【MM-dd HH:mm:ss】月日时分秒 + MDHMS, + + /// 【MM-dd HH:mm】月日时分 + MDHM, + + /// 【MM-dd HH:mm】月日时 + MDH, + + /// 【MM-dd】月日 + MD, + + /// 【HH:mm:ss】时分秒 + HMS, + + /// 【HH:mm】时分 + HM, + + /// 【mm:ss】分秒 + MS, + + /// 【ss】秒 + S, + + /// 【MM】月 + M, + + /// 【HH】时 + H, +} + diff --git a/star_lock/lib/tools/pickers/time_picker/model/date_time_data.dart b/star_lock/lib/tools/pickers/time_picker/model/date_time_data.dart new file mode 100644 index 00000000..54d41c08 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/date_time_data.dart @@ -0,0 +1,72 @@ +// import 'package:flutter_pickers/time_picker/model/date_type.dart'; + +import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart'; + +/// 时间选择器 item 生成的对应数据 +class DateTimeData { + List _year = []; + List _month = []; + List _day = []; + List _hour = []; + List _minute = []; + List _second = []; + + List getListByName(DateType type) { + switch (type) { + case DateType.Year: + return year; + case DateType.Month: + return month; + case DateType.Day: + return day; + case DateType.Hour: + return hour; + case DateType.Minute: + return minute; + case DateType.Second: + return second; + } + } + + List get year => _year; + + set year(List value) { + _year.clear(); + _year.addAll(value); + } + + List get month => _month; + + set month(List value) { + _month.clear(); + _month.addAll(value); + } + + List get second => _second; + + set second(List value) { + _second.clear(); + _second.addAll(value); + } + + List get minute => _minute; + + set minute(List value) { + _minute.clear(); + _minute.addAll(value); + } + + List get hour => _hour; + + set hour(List value) { + _hour.clear(); + _hour.addAll(value); + } + + List get day => _day; + + set day(List value) { + _day.clear(); + _day.addAll(value); + } +} diff --git a/star_lock/lib/tools/pickers/time_picker/model/date_type.dart b/star_lock/lib/tools/pickers/time_picker/model/date_type.dart new file mode 100644 index 00000000..b07bb7df --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/date_type.dart @@ -0,0 +1,10 @@ + + +enum DateType{ + Year, + Month, + Day, + Hour, + Minute, + Second +} \ No newline at end of file diff --git a/star_lock/lib/tools/pickers/time_picker/model/pduration.dart b/star_lock/lib/tools/pickers/time_picker/model/pduration.dart new file mode 100644 index 00000000..bc89c690 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/pduration.dart @@ -0,0 +1,109 @@ +// import 'package:flutter_pickers/time_picker/model/date_type.dart'; + +import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart'; + +/// 时间选择器 默认 时间设置 +/// +/// +/// var s = PDuration.now(); +/// print('longer1 >>> ${s.toString()}'); +/// {year: 2021, month: 1, day: 5, hour: 17, minute: 17, second: 3} +/// +/// var m = PDuration(year: 2011); +/// print('longer2 >>> ${m.toString()}'); +/// {year: 2011, month: 0, day: 0, hour: 0, minute: 0, second: 0} +/// +/// var d = PDuration.parse(DateTime.parse('20200304')); +/// print('longer3 >>> ${d.toString()}'); +/// {year: 2020, month: 3, day: 4, hour: 0, minute: 0, second: 0} + +bool intEmpty(int? value) { + return (value == null || value == 0); +} + +bool intNotEmpty(int? value) { + return (value != null && value != 0); +} + +class PDuration { + int? year; + int? month; + int? day; + int? hour; + int? minute; + int? second; + + PDuration( + {this.year: 0, + this.month: 0, + this.day: 0, + this.hour: 0, + this.minute: 0, + this.second: 0}); + + // 注意默认会设为0 不是null + PDuration.parse(DateTime dateTime) { + this.year = dateTime.year; + this.month = dateTime.month; + this.day = dateTime.day; + this.hour = dateTime.hour; + this.minute = dateTime.minute; + this.second = dateTime.second; + } + + PDuration.now() { + var thisInstant = new DateTime.now(); + this.year = thisInstant.year; + this.month = thisInstant.month; + this.day = thisInstant.day; + this.hour = thisInstant.hour; + this.minute = thisInstant.minute; + this.second = thisInstant.second; + } + + void setSingle(DateType dateType, var value) { + switch (dateType) { + case DateType.Year: + this.year = value; + break; + case DateType.Month: + this.month = value; + break; + case DateType.Day: + this.day = value; + break; + case DateType.Hour: + this.hour = value; + break; + case DateType.Minute: + this.minute = value; + break; + case DateType.Second: + this.second = value; + break; + } + } + + // 若为null 返回0 + int getSingle(DateType dateType) { + switch (dateType) { + case DateType.Year: + return this.year ?? 0; + case DateType.Month: + return this.month ?? 0; + case DateType.Day: + return this.day ?? 0; + case DateType.Hour: + return this.hour ?? 0; + case DateType.Minute: + return this.minute ?? 0; + case DateType.Second: + return this.second ?? 0; + } + } + + @override + String toString() { + return 'PDuration{year: $year, month: $month, day: $day, hour: $hour, minute: $minute, second: $second}'; + } +} diff --git a/star_lock/lib/tools/pickers/time_picker/model/suffix.dart b/star_lock/lib/tools/pickers/time_picker/model/suffix.dart new file mode 100644 index 00000000..b883ce78 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/model/suffix.dart @@ -0,0 +1,47 @@ +// import 'package:flutter_pickers/time_picker/model/date_type.dart'; + +import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart'; + +/// 后缀标签 +class Suffix { + late String years; + late String month; + late String days; + late String hours; + late String minutes; + late String seconds; + + Suffix.normal() { + this.years = '年'; + this.month = '月'; + this.days = '日'; + this.hours = '时'; + this.minutes = '分'; + this.seconds = '秒'; + } + + Suffix( + {this.years: '', + this.month: '', + this.days: '', + this.hours: '', + this.minutes: '', + this.seconds: ''}); + + String getSingle(DateType dateType) { + switch (dateType) { + case DateType.Year: + return this.years; + case DateType.Month: + return this.month; + case DateType.Day: + return this.days; + case DateType.Hour: + return this.hours; + case DateType.Minute: + return this.minutes; + case DateType.Second: + return this.seconds; + } + } +} diff --git a/star_lock/lib/tools/pickers/time_picker/route/date_picker_route.dart b/star_lock/lib/tools/pickers/time_picker/route/date_picker_route.dart new file mode 100644 index 00000000..ef5f3071 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/route/date_picker_route.dart @@ -0,0 +1,861 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:star_lock/tools/pickers/style/picker_style.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_item_model.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_time_data.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart'; +import 'package:star_lock/tools/pickers/time_picker/model/suffix.dart'; +// import 'package:flutter_pickers/style/picker_style.dart'; +// import 'package:flutter_pickers/time_picker/model/date_item_model.dart'; +// import 'package:flutter_pickers/time_picker/model/date_mode.dart'; +// import 'package:flutter_pickers/time_picker/model/date_time_data.dart'; +// import 'package:flutter_pickers/time_picker/model/date_type.dart'; +// import 'package:flutter_pickers/time_picker/model/pduration.dart'; +// import 'package:flutter_pickers/time_picker/model/suffix.dart'; + +import '../time_utils.dart'; + +typedef DateCallback(PDuration res); + +class DatePickerRoute extends PopupRoute { + DatePickerRoute({ + this.mode, + required this.initDate, + this.pickerStyle, + required this.maxDate, + required this.minDate, + this.suffix, + this.onChanged, + this.onConfirm, + this.onCancel, + this.theme, + this.barrierLabel, + RouteSettings? settings, + }) : super(settings: settings); + + final DateMode? mode; + late final PDuration initDate; + late final PDuration maxDate; + late final PDuration minDate; + final Suffix? suffix; + final ThemeData? theme; + final DateCallback? onChanged; + final DateCallback? onConfirm; + final Function(bool isCancel)? onCancel; + final PickerStyle? pickerStyle; + + @override + Duration get transitionDuration => const Duration(milliseconds: 200); + + @override + bool get barrierDismissible => true; + + @override + bool didPop(T? result) { + if (onCancel != null) { + if (result == null) { + onCancel!(false); + } else if (!(result as bool)) { + onCancel!(true); + } + } + return super.didPop(result); + } + + @override + final String? barrierLabel; + + @override + Color get barrierColor => Colors.black54; + + AnimationController? _animationController; + + @override + AnimationController createAnimationController() { + assert(_animationController == null); + _animationController = + BottomSheet.createAnimationController(navigator!.overlay!); + return _animationController!; + } + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + Widget bottomSheet = MediaQuery.removePadding( + context: context, + removeTop: true, + child: _PickerContentView( + mode: mode, + initData: initDate, + maxDate: maxDate, + minDate: minDate, + pickerStyle: pickerStyle!, + route: this, + ), + ); + if (theme != null) { + bottomSheet = Theme(data: theme!, child: bottomSheet); + } + + return bottomSheet; + } +} + +class _PickerContentView extends StatefulWidget { + _PickerContentView({ + Key? key, + this.mode, + required this.initData, + required this.pickerStyle, + required this.maxDate, + required this.minDate, + required this.route, + }) : super(key: key); + + final DateMode? mode; + late final PDuration initData; + late final DatePickerRoute route; + late final PickerStyle pickerStyle; + + // 限制时间 + late final PDuration maxDate; + late final PDuration minDate; + + @override + State createState() => _PickerState( + this.mode, this.initData, this.maxDate, this.minDate, this.pickerStyle); +} + +class _PickerState extends State<_PickerContentView> { + late final PickerStyle _pickerStyle; + + // 是否显示 [年月日时分秒] + late DateItemModel _dateItemModel; + + // 初始 设置选中的数据 + late final PDuration _initSelectData; + + // 选中的数据 用于回传 + late PDuration _selectData; + + // 所有item 对应的数据 + late DateTimeData _dateTimeData; + + // 限制时间 + late final PDuration maxDate; + late final PDuration minDate; + + Animation? animation; + Map scrollCtrl = {}; + + // 选择器 高度 单独提出来,用来解决修改数据 不及时更新的BUG + late double pickerItemHeight; + + _PickerState(DateMode? mode, this._initSelectData, this.maxDate, this.minDate, + this._pickerStyle) { + this._dateItemModel = DateItemModel.parse(mode!); + this.pickerItemHeight = _pickerStyle.pickerItemHeight; + _init(); + } + + _init() { + scrollCtrl.clear(); + + _dateTimeData = DateTimeData(); + int index = 0; // 初始选中值 Index + _selectData = PDuration(); + + /// minDate 和 maxDate 都初始化了,可以省略很多空判断,直接比较选中值 是否相等 _selectData.month == minDate.month + /// -------年 + if (_dateItemModel.year) { + index = 0; + _dateTimeData.year = + TimeUtils.calcYears(begin: minDate.year!, end: maxDate.year!); + + if (_initSelectData.year != null) { + index = _dateTimeData.year.indexOf(_initSelectData.year); + index = index < 0 ? 0 : index; + } + _selectData.year = _dateTimeData.year[index]; + scrollCtrl[DateType.Year] = + FixedExtentScrollController(initialItem: index); + } + + /// ------月 + // 选中的月 用于之后 day 的计算 + int selectMonth = 1; + if (_dateItemModel.month) { + index = 0; + int begin = 1; + int end = 12; + // 限制区域 + if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) { + begin = minDate.month!; + } + if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) { + end = maxDate.month!; + } + + _dateTimeData.month = TimeUtils.calcMonth(begin: begin, end: end); + + if (_initSelectData.month != null) { + index = _dateTimeData.month.indexOf(_initSelectData.month); + index = index < 0 ? 0 : index; + } + selectMonth = _dateTimeData.month[index]; + _selectData.month = selectMonth; + scrollCtrl[DateType.Month] = + FixedExtentScrollController(initialItem: index); + } + + /// -------日 (有日肯定有 年月数据) + if (_dateItemModel.day) { + index = 0; + int begin = 1; + int end = 31; + // 限制区域 + if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) { + if (_selectData.year == minDate.year && + _selectData.month == minDate.month) { + begin = minDate.day!; + } + if (_selectData.year == maxDate.year && + _selectData.month == maxDate.month) { + end = maxDate.day!; + } + } + + _dateTimeData.day = TimeUtils.calcDay(_initSelectData.year!, selectMonth, + begin: begin, end: end); + + if (_initSelectData.day != null) { + index = _dateTimeData.day.indexOf(_initSelectData.day); + index = index < 0 ? 0 : index; + } + _selectData.day = _dateTimeData.day[index]; + scrollCtrl[DateType.Day] = + FixedExtentScrollController(initialItem: index); + } + + /// ---------时 + if (_dateItemModel.hour) { + index = 0; + int begin = 0; + int end = 23; + // 限制区域 + if (intNotEmpty(minDate.hour)) { + begin = minDate.hour!; + } + if (intNotEmpty(maxDate.hour)) { + end = maxDate.hour!; + } + + _dateTimeData.hour = TimeUtils.calcHour(begin: begin, end: end); + + if (_initSelectData.hour != null) { + index = _dateTimeData.hour.indexOf(_initSelectData.hour); + index = index < 0 ? 0 : index; + } + _selectData.hour = _dateTimeData.hour[index]; + scrollCtrl[DateType.Hour] = + FixedExtentScrollController(initialItem: index); + } + + /// ---------分 + if (_dateItemModel.minute) { + index = 0; + int begin = 0; + int end = 59; + // 限制区域 + if (intNotEmpty(minDate.minute) || intNotEmpty(maxDate.minute)) { + if (_dateItemModel.hour) { + // 如果有上级 还有时,要根据时再判断 + if (_selectData.hour == minDate.hour) { + begin = minDate.minute!; + } + if (_selectData.hour == maxDate.hour) { + end = maxDate.minute!; + } + } else { + // 上级没有时间限制 直接取 + if (intNotEmpty(minDate.minute)) { + begin = minDate.minute!; + } + if (intNotEmpty(maxDate.minute)) { + end = maxDate.minute!; + } + } + } + + _dateTimeData.minute = TimeUtils.calcMinAndSecond(begin: begin, end: end); + + if (_initSelectData.minute != null) { + index = _dateTimeData.minute.indexOf(_initSelectData.minute); + index = index < 0 ? 0 : index; + } + _selectData.minute = _dateTimeData.minute[index]; + scrollCtrl[DateType.Minute] = + FixedExtentScrollController(initialItem: index); + } + + /// --------秒 + if (_dateItemModel.second) { + index = 0; + int begin = 0; + int end = 59; + // 限制区域 + if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) { + if (_dateItemModel.hour && _dateItemModel.minute) { + // 如果有上级 还有时 分,要根据时分再判断 + if (_selectData.hour == minDate.hour && + _selectData.minute == minDate.minute) { + begin = minDate.second!; + } + if (_selectData.hour == maxDate.hour && + _selectData.minute == maxDate.minute) { + end = maxDate.second!; + } + } else if (_dateItemModel.minute) { + /// 上级没有时,只有分限制 + if (_selectData.minute == minDate.minute) { + begin = minDate.second!; + } + if (_selectData.minute == maxDate.minute) { + end = maxDate.second!; + } + } else { + /// 上级没有时间限制 直接取 + if (intNotEmpty(minDate.second)) { + begin = minDate.second!; + } + if (intNotEmpty(maxDate.second)) { + end = maxDate.second!; + } + } + } + + _dateTimeData.second = TimeUtils.calcMinAndSecond(begin: begin, end: end); + + if (_initSelectData.second != null) { + index = _dateTimeData.second.indexOf(_initSelectData.second); + index = index < 0 ? 0 : index; + } + _selectData.second = _dateTimeData.second[index]; + scrollCtrl[DateType.Second] = + FixedExtentScrollController(initialItem: index); + } + } + + @override + void dispose() { + scrollCtrl.forEach((key, value) { + value.dispose(); + }); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: AnimatedBuilder( + animation: widget.route.animation!, + builder: (BuildContext context, Widget? child) { + return ClipRect( + child: CustomSingleChildLayout( + delegate: _BottomPickerLayout( + widget.route.animation!.value, _pickerStyle), + child: GestureDetector( + child: Material( + color: Colors.transparent, + child: _renderPickerView(), + ), + ), + ), + ); + }, + ), + ); + } + + void _setPicker(DateType dateType, int selectIndex) { + // 得到新的选中的数据 + var selectValue = _dateTimeData.getListByName(dateType)[selectIndex]; + // 更新选中数据 + _selectData.setSingle(dateType, selectValue); + + switch (dateType) { + case DateType.Year: + _setYear(); + break; + case DateType.Month: + _setMonth(); + break; + case DateType.Day: + break; + case DateType.Hour: + _setHour(); + break; + case DateType.Minute: + _setMinute(); + break; + case DateType.Second: + break; + } + _notifyLocationChanged(); + } + + // -------------------- set begin ------------ + void _setYear() { + // 可能造成 月 日 list的改变 + if (_dateItemModel.month) { + // 月的数据是否需要更新 + bool updateMonth = false; + bool updateDay = false; + + /// 如果只有月 + int beginMonth = 1; + int endMonth = 12; + // 限制区域 + if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) { + beginMonth = minDate.month!; + } + if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) { + endMonth = maxDate.month!; + } + + var resultMonth = TimeUtils.calcMonth(begin: beginMonth, end: endMonth); + + int jumpToIndexMonth = 0; + + if (!listEquals(_dateTimeData.month, resultMonth)) { + //可能 选中的月份 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.month! > resultMonth.last) { + jumpToIndexMonth = resultMonth.length - 1; + } else { + jumpToIndexMonth = resultMonth.indexOf(_selectData.month); + } + jumpToIndexMonth = jumpToIndexMonth < 0 ? 0 : jumpToIndexMonth; + _selectData.month = resultMonth[jumpToIndexMonth]; + updateMonth = true; + } + + /// 还有 日 + int jumpToIndexDay = 0; + // 新的day 数据 + var resultDay; + if (_dateItemModel.day) { + int beginDay = 1; + int endDay = 31; + // 限制区域 + if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) { + if (_selectData.year == minDate.year && + _selectData.month == minDate.month) { + beginDay = minDate.day!; + } + if (_selectData.year == maxDate.year && + _selectData.month == maxDate.month) { + endDay = maxDate.day!; + } + } + resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!, + begin: beginDay, end: endDay); + + if (!listEquals(_dateTimeData.day, resultDay)) { + //可能 选中的年 月份 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.day! > resultDay.last) { + jumpToIndexDay = resultDay.length - 1; + } else { + jumpToIndexDay = resultDay.indexOf(_selectData.day); + } + jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay; + _selectData.day = resultDay[jumpToIndexDay]; + updateDay = true; + } + } + + if (updateMonth || updateDay) { + setState(() { + if (updateMonth) { + _dateTimeData.month = resultMonth; + scrollCtrl[DateType.Month]?.jumpToItem(jumpToIndexMonth); + } + if (updateDay) { + _dateTimeData.day = resultDay; + scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay); + } + + /// FIX:https://github.com/flutter/flutter/issues/22999 + pickerItemHeight = + _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000; + }); + } + } + } + + void _setMonth() { + // 可能造成 日 list的改变 + bool updateDay = false; + int jumpToIndexDay = 0; + // 新的day 数据 + var resultDay; + if (_dateItemModel.day) { + int beginDay = 1; + int endDay = 31; + // 限制区域 + if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) { + if (_selectData.year == minDate.year && + _selectData.month == minDate.month) { + beginDay = minDate.day!; + } + if (_selectData.year == maxDate.year && + _selectData.month == maxDate.month) { + endDay = maxDate.day!; + } + } + resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!, + begin: beginDay, end: endDay); + + if (!listEquals(_dateTimeData.day, resultDay)) { + //可能 选中的年 月份 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.day! > resultDay.last) { + jumpToIndexDay = resultDay.length - 1; + } else { + jumpToIndexDay = resultDay.indexOf(_selectData.day); + } + jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay; + _selectData.day = resultDay[jumpToIndexDay]; + updateDay = true; + } + } + if (updateDay) { + setState(() { + _dateTimeData.day = resultDay; + scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay); + + /// FIX:https://github.com/flutter/flutter/issues/22999 + pickerItemHeight = + _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000; + }); + } + } + + void _setHour() { + // 可能造成 分 秒 list的改变 + if (_dateItemModel.minute) { + // 月的数据是否需要更新 + bool updateMinute = false; + bool updateSecond = false; + + /// 如果只有分 + int beginMinute = 0; + int endMinute = 59; + // 限制区域 + if (intNotEmpty(minDate.minute) && _selectData.hour == minDate.hour) { + beginMinute = minDate.minute!; + } + if (intNotEmpty(maxDate.minute) && _selectData.hour == maxDate.hour) { + endMinute = maxDate.minute!; + } + + var resultMinute = + TimeUtils.calcMinAndSecond(begin: beginMinute, end: endMinute); + + int jumpToIndexMinute = 0; + + if (!listEquals(_dateTimeData.month, resultMinute)) { + //可能 选中的时间 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.minute! > resultMinute.last) { + jumpToIndexMinute = resultMinute.length - 1; + } else { + jumpToIndexMinute = resultMinute.indexOf(_selectData.minute); + } + jumpToIndexMinute = jumpToIndexMinute < 0 ? 0 : jumpToIndexMinute; + _selectData.minute = resultMinute[jumpToIndexMinute]; + updateMinute = true; + } + + /// 还有 秒 + int jumpToIndexSecond = 0; + // 新的day 数据 + var resultSecond; + if (_dateItemModel.second) { + int beginSecond = 0; + int endSecond = 59; + // 限制区域 + if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) { + if (_selectData.hour == minDate.hour && + _selectData.minute == minDate.minute) { + beginSecond = minDate.second!; + } + if (_selectData.hour == maxDate.hour && + _selectData.minute == maxDate.minute) { + endSecond = maxDate.second!; + } + } + resultSecond = + TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond); + + if (!listEquals(_dateTimeData.second, resultSecond)) { + //可能 选中的时 分 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.second! > resultSecond.last) { + jumpToIndexSecond = resultSecond.length - 1; + } else { + jumpToIndexSecond = resultSecond.indexOf(_selectData.second); + } + jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond; + _selectData.second = resultSecond[jumpToIndexSecond]; + updateSecond = true; + } + } + + if (updateMinute || updateSecond) { + setState(() { + if (updateMinute) { + _dateTimeData.minute = resultMinute; + scrollCtrl[DateType.Minute]?.jumpToItem(jumpToIndexMinute); + } + if (updateSecond) { + _dateTimeData.second = resultSecond; + scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond); + } + + /// FIX:https://github.com/flutter/flutter/issues/22999 + pickerItemHeight = + _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000; + }); + } + } + } + + void _setMinute() { + // 可能造成 秒 list的改变 + bool updateSecond = false; + int jumpToIndexSecond = 0; + // 新的day 数据 + var resultSecond; + if (_dateItemModel.second) { + int beginSecond = 0; + int endSecond = 59; + // 限制区域 + if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) { + if (_dateItemModel.hour) { + // 如果上面还有 时 + if (_selectData.hour == minDate.hour && + _selectData.minute == minDate.minute) { + beginSecond = minDate.second!; + } + if (_selectData.hour == maxDate.hour && + _selectData.minute == maxDate.minute) { + endSecond = maxDate.second!; + } + } else { + // 没有时,分秒 + if (_selectData.minute == minDate.minute) { + beginSecond = minDate.second!; + } + if (_selectData.minute == maxDate.minute) { + endSecond = maxDate.second!; + } + } + } + resultSecond = + TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond); + + if (!listEquals(_dateTimeData.second, resultSecond)) { + //可能 选中的分 由于设置了新数据后没有了 + // 小于不用考虑 会进else + if (_selectData.second! > resultSecond.last) { + jumpToIndexSecond = resultSecond.length - 1; + } else { + jumpToIndexSecond = resultSecond.indexOf(_selectData.second); + } + jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond; + _selectData.second = resultSecond[jumpToIndexSecond]; + updateSecond = true; + } + } + if (updateSecond) { + setState(() { + _dateTimeData.second = resultSecond; + scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond); + + /// FIX:https://github.com/flutter/flutter/issues/22999 + pickerItemHeight = + _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000; + }); + } + } + + // -------------------- set end ------------ + + void _notifyLocationChanged() { + if (widget.route.onChanged != null) { + widget.route.onChanged!(_selectData); + } + } + + double _pickerFontSize(String text) { + if (text == '') return 18.0; + + if (_dateItemModel.length == 6 && (text.length > 4 && text.length <= 6)) { + return 16.0; + } + + if (text.length <= 6) { + return 18.0; + } else if (text.length < 9) { + return 16.0; + } else if (text.length < 13) { + return 12.0; + } else { + return 10.0; + } + } + + Widget _renderPickerView() { + Widget itemView = _renderItemView(); + + if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) { + return itemView; + } + List viewList = []; + if (_pickerStyle.showTitleBar) { + viewList.add(_titleView()); + } + if (_pickerStyle.menu != null) { + viewList.add(_pickerStyle.menu!); + } + viewList.add(itemView); + + return Column(children: viewList); + } + + Widget _renderItemView() { + // 选择器 + List pickerList = []; + if (_dateItemModel.year) pickerList.add(pickerView(DateType.Year)); + if (_dateItemModel.month) pickerList.add(pickerView(DateType.Month)); + if (_dateItemModel.day) pickerList.add(pickerView(DateType.Day)); + if (_dateItemModel.hour) pickerList.add(pickerView(DateType.Hour)); + if (_dateItemModel.minute) pickerList.add(pickerView(DateType.Minute)); + if (_dateItemModel.second) pickerList.add(pickerView(DateType.Second)); + + return Container( + height: _pickerStyle.pickerHeight, + color: _pickerStyle.backgroundColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: pickerList, + ), + ); + } + + /// CupertinoPicker.builder + Widget pickerView(DateType dateType) { + return Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 2), + child: CupertinoPicker.builder( + /// key :年月拼接 就不会重复了 fixme + /// 最好别使用key 会生成新的widget + /// 官方的bug : https://github.com/flutter/flutter/issues/22999 + /// 临时方法 通过修改height + scrollController: scrollCtrl[dateType], + itemExtent: pickerItemHeight, + selectionOverlay: _pickerStyle.itemOverlay, + onSelectedItemChanged: (int selectIndex) => + _setPicker(dateType, selectIndex), + childCount: _dateTimeData.getListByName(dateType).length, + itemBuilder: (_, index) { + String text = + '${_dateTimeData.getListByName(dateType)[index]}${widget.route.suffix?.getSingle(dateType)}'; + return Align( + alignment: Alignment.center, + child: Text(text, + style: TextStyle( + color: _pickerStyle.textColor, + fontSize: _pickerStyle.textSize ?? _pickerFontSize(text), + ), + textAlign: TextAlign.start)); + }, + ), + ), + ); + } + + // 选择器上面的view + Widget _titleView() { + return Container( + height: _pickerStyle.pickerTitleHeight, + decoration: _pickerStyle.headDecoration, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// 取消按钮 + InkWell( + onTap: () => Navigator.pop(context, false), + child: _pickerStyle.cancelButton), + + /// 标题 + Expanded(child: _pickerStyle.title), + + /// 确认按钮 + InkWell( + onTap: () { + if (widget.route.onConfirm != null) { + widget.route.onConfirm!(_selectData); + } + Navigator.pop(context, true); + }, + child: _pickerStyle.commitButton) + ], + ), + ); + } +} + +class _BottomPickerLayout extends SingleChildLayoutDelegate { + _BottomPickerLayout(this.progress, this.pickerStyle); + + final double progress; + final PickerStyle pickerStyle; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + double maxHeight = pickerStyle.pickerHeight; + if (pickerStyle.showTitleBar) { + maxHeight += pickerStyle.pickerTitleHeight; + } + if (pickerStyle.menu != null) { + maxHeight += pickerStyle.menuHeight; + } + + return BoxConstraints( + minWidth: constraints.maxWidth, + maxWidth: constraints.maxWidth, + minHeight: 0.0, + maxHeight: maxHeight); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + double height = size.height - childSize.height * progress; + return Offset(0.0, height); + } + + @override + bool shouldRelayout(_BottomPickerLayout oldDelegate) { + return progress != oldDelegate.progress; + } +} diff --git a/star_lock/lib/tools/pickers/time_picker/time_utils.dart b/star_lock/lib/tools/pickers/time_picker/time_utils.dart new file mode 100644 index 00000000..bcb183e7 --- /dev/null +++ b/star_lock/lib/tools/pickers/time_picker/time_utils.dart @@ -0,0 +1,73 @@ +class TimeUtils { + /// 年 + static List calcYears({int begin = 1900, int end = 2100}) => + _calcCount(begin, end); + + /// 月 + static List calcMonth({int begin = 1, int end = 12}) { + begin = begin < 1 ? 1 : begin; + end = end > 12 ? 12 : end; + return _calcCount(begin, end); + } + + /// 日 + static List calcDay(int year, int month, {int begin = 1, int end = 31}) { + begin = begin < 1 ? 1 : begin; + + int days = _calcDateCount(year, month); + if (end > days) { + end = days; + } + return _calcCount(begin, end); + } + + /// 时 + static List calcHour({int begin = 0, int end = 23}) { + begin = begin < 0 ? 0 : begin; + end = end > 23 ? 23 : end; + return _calcCount(begin, end); + } + + /// 分 和 秒 + static List calcMinAndSecond({int begin = 0, int end = 59}) { + begin = begin < 0 ? 0 : begin; + end = end > 59 ? 59 : end; + return _calcCount(begin, end); + } + + static List _calcCount(begin, end) { + int length = end - begin + 1; + if (length == 0) return [begin]; + if (length < 0) return []; + + return List.generate(length, (index) => begin + index); + } + + // 计算月份所对应天数 + static int _calcDateCount(int year, int month) { + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return 31; + case 2: + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { + return 29; + } + return 28; + } + return 30; + } + + String intToStr(int v) { + return (v < 10) ? "0$v" : "$v"; + } + + // String _checkStr(String v) { + // return v == null ? "" : v; + // } +} diff --git a/star_lock/lib/tools/pickers/utils/check.dart b/star_lock/lib/tools/pickers/utils/check.dart new file mode 100644 index 00000000..ed44592a --- /dev/null +++ b/star_lock/lib/tools/pickers/utils/check.dart @@ -0,0 +1,45 @@ +class PicketUtil { + /// 字符串不为空 + static bool strNoEmpty(String? value) { + if (value == null) return false; + + return value.trim().isNotEmpty; + } + + /// 字符串为空 + static bool strEmpty(String? value) { + if (value == null) return true; + + return value.trim().isEmpty; + } + + /// MAp不为空 + static bool mapNoEmpty(Map? value) { + if (value == null) return false; + return value.isNotEmpty; + } + + /// MAp为空 + static bool mapEmpty(Map? value) { + if (value == null) return true; + return value.isEmpty; + } + + ///判断List是否为空 + static bool listNoEmpty(List? list) { + if (list == null) return false; + + if (list.length == 0) return false; + + return true; + } + + ///判断List是否为空 + static bool listEmpty(List? list) { + if (list == null) return true; + + if (list.length == 0) return true; + + return false; + } +} diff --git a/star_lock/lib/tools/storage.dart b/star_lock/lib/tools/storage.dart index 110da77d..8e98e17e 100644 --- a/star_lock/lib/tools/storage.dart +++ b/star_lock/lib/tools/storage.dart @@ -139,7 +139,7 @@ class Storage { String? userId = ''; final data = await Storage.getString('userLoginData'); if (data != null && data.isNotEmpty) { - userId = LoginData.fromJson(jsonDecode(data)).userid.toString(); + userId = LoginData.fromJson(jsonDecode(data)).uid.toString(); } print("pubUserId:$userId"); return userId; diff --git a/star_lock/lib/translations/lanKeyEntity.dart b/star_lock/lib/translations/lanKeyEntity.dart index 791768c9..e54dff82 100644 --- a/star_lock/lib/translations/lanKeyEntity.dart +++ b/star_lock/lib/translations/lanKeyEntity.dart @@ -449,6 +449,8 @@ class LanKeyEntity { this.openRight, this.judgmentMethod, this.judgmentMethodContent, + this.stressPassword, + this.stressCard, }); LanKeyEntity.fromJson(dynamic json) { @@ -935,6 +937,8 @@ class LanKeyEntity { openRight = json['openRight']; judgmentMethod = json['judgmentMethod']; judgmentMethodContent = json['judgmentMethodContent']; + stressPassword = json['stressPassword']; + stressCard = json['stressCard']; } String? starLock; String? clickUnlockAndHoldDownClose; @@ -1407,6 +1411,8 @@ class LanKeyEntity { String? openRight; String? judgmentMethod; String? judgmentMethodContent; + String? stressPassword; + String? stressCard; Map toJson() { final map = {}; @@ -1890,6 +1896,8 @@ class LanKeyEntity { map['openRight'] = openRight; map['judgmentMethod'] = judgmentMethod; map['judgmentMethodContent'] = judgmentMethodContent; + map['stressPassword'] = stressPassword; + map['stressCard'] = stressCard; return map; } diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index 0b34e7ec..bde1c728 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -64,7 +64,7 @@ dependencies: #生成二维码 qr_flutter: ^4.1.0 #底部选择 - flutter_pickers: ^2.1.9 + #flutter_pickers: ^2.1.9 #万年历 syncfusion_flutter_datepicker: ^22.1.38 #使用相机及相册