diff --git a/star_lock/images/icon_email.png b/star_lock/images/icon_email.png new file mode 100644 index 00000000..f8f66993 Binary files /dev/null and b/star_lock/images/icon_email.png differ diff --git a/star_lock/images/icon_message.png b/star_lock/images/icon_message.png new file mode 100644 index 00000000..39971655 Binary files /dev/null and b/star_lock/images/icon_message.png differ diff --git a/star_lock/images/icon_more.png b/star_lock/images/icon_more.png new file mode 100644 index 00000000..e08747b0 Binary files /dev/null and b/star_lock/images/icon_more.png differ diff --git a/star_lock/images/icon_wechat.png b/star_lock/images/icon_wechat.png new file mode 100644 index 00000000..2efccd6f Binary files /dev/null and b/star_lock/images/icon_wechat.png differ diff --git a/star_lock/ios/Runner.xcodeproj/project.pbxproj b/star_lock/ios/Runner.xcodeproj/project.pbxproj index 663b2ef9..75888984 100644 --- a/star_lock/ios/Runner.xcodeproj/project.pbxproj +++ b/star_lock/ios/Runner.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3EF1E85D6F1EE0C0DCF8449F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */; }; - 82BD91202ADA6FBB0018E523 /* SharePasswordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82BD911F2ADA6FBB0018E523 /* SharePasswordViewController.m */; }; + 82BD91202ADA6FBB0018E523 /* XSFlutterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 82BD911F2ADA6FBB0018E523 /* XSFlutterManager.m */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -40,8 +40,8 @@ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 82BD911E2ADA6FBB0018E523 /* SharePasswordViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharePasswordViewController.h; sourceTree = ""; }; - 82BD911F2ADA6FBB0018E523 /* SharePasswordViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharePasswordViewController.m; sourceTree = ""; }; + 82BD911E2ADA6FBB0018E523 /* XSFlutterManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XSFlutterManager.h; sourceTree = ""; }; + 82BD911F2ADA6FBB0018E523 /* XSFlutterManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XSFlutterManager.m; sourceTree = ""; }; 82BD91212ADA72360018E523 /* CommonDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommonDefine.h; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; @@ -78,6 +78,15 @@ path = Pods; sourceTree = ""; }; + 826570C02ADCDD0200A92776 /* XSController */ = { + isa = PBXGroup; + children = ( + 82BD911E2ADA6FBB0018E523 /* XSFlutterManager.h */, + 82BD911F2ADA6FBB0018E523 /* XSFlutterManager.m */, + ); + name = XSController; + sourceTree = ""; + }; 9304F75C378DB3447BB2408C /* Frameworks */ = { isa = PBXGroup; children = ( @@ -119,6 +128,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 826570C02ADCDD0200A92776 /* XSController */, 33BF41252A96174D009D92E2 /* Runner.entitlements */, 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, @@ -129,8 +139,6 @@ 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 82BD911E2ADA6FBB0018E523 /* SharePasswordViewController.h */, - 82BD911F2ADA6FBB0018E523 /* SharePasswordViewController.m */, 82BD91212ADA72360018E523 /* CommonDefine.h */, ); path = Runner; @@ -180,6 +188,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1430; }; }; }; @@ -294,7 +303,7 @@ buildActionMask = 2147483647; files = ( 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 82BD91202ADA6FBB0018E523 /* SharePasswordViewController.m in Sources */, + 82BD91202ADA6FBB0018E523 /* XSFlutterManager.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); @@ -379,6 +388,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -393,6 +403,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.lock"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -510,6 +522,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -524,6 +537,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.lock"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -534,6 +550,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -548,6 +565,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.lock"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/star_lock/ios/Runner/AppDelegate.m b/star_lock/ios/Runner/AppDelegate.m index 2a2ad731..9156fe49 100644 --- a/star_lock/ios/Runner/AppDelegate.m +++ b/star_lock/ios/Runner/AppDelegate.m @@ -1,21 +1,16 @@ #import "AppDelegate.h" #import "GeneratedPluginRegistrant.h" -#import "SharePasswordViewController.h" +#import "XSFlutterManager.h" #import "CommonDefine.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - /** 设置主控制器继承FlutterViewController*/ - SharePasswordViewController * VC = [[SharePasswordViewController alloc]init]; - UINavigationController * NVC = [[UINavigationController alloc]initWithRootViewController:VC]; - [self.window setRootViewController:NVC]; - /** flutter插件通道代理*/ - [GeneratedPluginRegistrant registerWithRegistry:self]; - - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; + XSFlutterManager * VC = [[XSFlutterManager alloc]init]; + self.window.rootViewController = VC; + [self.window makeKeyAndVisible]; + return YES; } @end diff --git a/star_lock/ios/Runner/Info.plist b/star_lock/ios/Runner/Info.plist index d317c6fe..ec207f04 100644 --- a/star_lock/ios/Runner/Info.plist +++ b/star_lock/ios/Runner/Info.plist @@ -57,6 +57,11 @@ UILaunchStoryboardName LaunchScreen + UIApplicationSceneManifest + + UISceneConfigurations + + UIMainStoryboardFile Main UISupportedInterfaceOrientations diff --git a/star_lock/ios/Runner/SharePasswordViewController.h b/star_lock/ios/Runner/XSFlutterManager.h similarity index 73% rename from star_lock/ios/Runner/SharePasswordViewController.h rename to star_lock/ios/Runner/XSFlutterManager.h index dd0348d0..2be71177 100644 --- a/star_lock/ios/Runner/SharePasswordViewController.h +++ b/star_lock/ios/Runner/XSFlutterManager.h @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface SharePasswordViewController : FlutterViewController +@interface XSFlutterManager : FlutterViewController @end diff --git a/star_lock/ios/Runner/SharePasswordViewController.m b/star_lock/ios/Runner/XSFlutterManager.m similarity index 94% rename from star_lock/ios/Runner/SharePasswordViewController.m rename to star_lock/ios/Runner/XSFlutterManager.m index 11a147f1..8d037ec6 100644 --- a/star_lock/ios/Runner/SharePasswordViewController.m +++ b/star_lock/ios/Runner/XSFlutterManager.m @@ -1,23 +1,23 @@ // -// SharePasswordViewController.m +// XSFlutterManager.m // Runner // // Created by DaisyWu on 2023/10/14. // -#import "SharePasswordViewController.h" +#import "XSFlutterManager.h" #include "GeneratedPluginRegistrant.h" #import "CommonDefine.h" -@interface SharePasswordViewController () +@interface XSFlutterManager () @property(nonatomic,strong) FlutterMethodChannel* methodChannel; @property (nonatomic, copy) NSString *textToShare; @end -@implementation SharePasswordViewController +@implementation XSFlutterManager - (void)viewDidLoad { [super viewDidLoad]; @@ -34,6 +34,7 @@ [self.methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { // TODO NSString *method=call.method; + //调用系统分享 if ([method isEqualToString:flutterMethodSharePassword]) { id params = call.arguments; self.textToShare = @"您好,您的密码是:"; @@ -59,7 +60,7 @@ if (completed) { NSLog(@"completed"); - + //分享 成功 } else { 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 9079f6f9..c0768789 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 { - String? receiverUid; + int? receiverUid; ReceiverUser? receiverUser; int? keyId; @@ -105,7 +105,7 @@ class Phone { int? userId; String? phoneNumberHash; String? phoneNumberEncrypt; - String? countryCode; + int? countryCode; String? phoneNumberVerifiedAt; String? updatedAt; String? createdAt; @@ -149,7 +149,7 @@ class Phone { class Cloud { String? username; String? password; - String? cloudUid; + int? cloudUid; int? userId; String? updatedAt; String? createdAt; diff --git a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_logic.dart b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_logic.dart index 38ca6395..c489ea16 100644 --- a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_logic.dart +++ b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_logic.dart @@ -1,7 +1,11 @@ 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/appRouters.dart'; import 'package:star_lock/blue/io_type.dart'; +import 'package:star_lock/translations/trans_lib.dart'; import '../../../../blue/blue_manage.dart'; import '../../../../blue/io_protocol/io_addUser.dart'; @@ -23,7 +27,8 @@ class AuthorizedAdminLogic extends BaseGetXController { // 监听设备返回的数据 late StreamSubscription _replySubscription; void _initReplySubscription() { - _replySubscription = EventBusManager().eventBus!.on().listen((reply) async { + _replySubscription = + EventBusManager().eventBus!.on().listen((reply) async { // 转移权限 if (reply is TransferPermissionsReply) { var token = reply.data.sublist(2, 6); @@ -73,7 +78,7 @@ class AuthorizedAdminLogic extends BaseGetXController { break; case 0x14: - // 权限校验错误 + // 权限校验错误 print("${reply.commandType!.typeValue} 用户已存在"); break; @@ -85,7 +90,7 @@ class AuthorizedAdminLogic extends BaseGetXController { } } - if(reply is AddUserReply) { + if (reply is AddUserReply) { _replyAddUserKey(reply); } }); @@ -105,16 +110,16 @@ class AuthorizedAdminLogic extends BaseGetXController { // userNo = reply.data[46]; // print("status:$status"); - switch(status){ + switch (status) { case 0x00: - //成功 + //成功 print("添加用户数据解析成功"); state.isSendSuccess.value = true; Toast.show(msg: "添加成功"); // bindBlueAdmin(); break; case 0x06: - //无权限 + //无权限 print("需要鉴权"); var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -124,33 +129,32 @@ class AuthorizedAdminLogic extends BaseGetXController { IoSenderManage.senderAddUser( lockID: BlueManage().connectDeviceName, - authUserID:await Storage.getUid(), - keyID:"1", - userID:state.addUserId.value, - openMode:1, - keyType:(state.type.value == "1") ? 0 : 1, - startDate:state.effectiveDateTime.value.millisecondsSinceEpoch, - expireDate:state.failureDateTime.value.millisecondsSinceEpoch, - role:0, - password:"123456", - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: token - ); + authUserID: await Storage.getUid(), + keyID: "1", + userID: state.addUserId.value, + openMode: 1, + keyType: (state.type.value == "1") ? 0 : 1, + startDate: state.effectiveDateTime.value.millisecondsSinceEpoch, + expireDate: state.failureDateTime.value.millisecondsSinceEpoch, + role: 0, + password: "123456", + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: token); break; case 0x07: - //无权限 + //无权限 print("用户无权限"); break; case 0x09: - // 权限校验错误 + // 权限校验错误 print("添加用户权限校验错误"); break; default: - //失败 + //失败 print("领锁失败"); break; @@ -190,8 +194,10 @@ class AuthorizedAdminLogic extends BaseGetXController { // 添加用户 Future addUserConnectBlue(String receiveId) async { // 进来之后首先连接 - BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState connecteState) async { - if (connecteState == DeviceConnectionState.connected){ + BlueManage().judgeReconnect( + BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, + (DeviceConnectionState connecteState) async { + if (connecteState == DeviceConnectionState.connected) { // 私钥 var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -200,59 +206,60 @@ class AuthorizedAdminLogic 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:receiveId, - openMode:1, - keyType:(state.type.value == "1") ? 0 : 1, - startDate:state.effectiveDateTime.value.millisecondsSinceEpoch, - expireDate:state.failureDateTime.value.millisecondsSinceEpoch, - role:0, - password:"123456", - needAuthor:1, - publicKey:publicKeyDataList, - privateKey:getPrivateKeyList, - token: getTokenList - ); + authUserID: await Storage.getUid(), + keyID: "1", + userID: receiveId, + openMode: 1, + keyType: (state.type.value == "1") ? 0 : 1, + startDate: state.effectiveDateTime.value.millisecondsSinceEpoch, + expireDate: state.failureDateTime.value.millisecondsSinceEpoch, + role: 0, + password: "123456", + needAuthor: 1, + publicKey: publicKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList); } }); } //发送授权管理员列表请求 - Future sendElectronicKeyRequest() async { + Future sendElectronicKeyRequest(BuildContext widgetContext) async { String getFailureDateTime = '0'; String getEffectiveDateTime = '0'; String lockID = state.keyInfo.value.lockId.toString(); String getKeyType = (int.parse(state.type.value) + 1).toString(); if (state.type.value == '0') { - getFailureDateTime = state.failureDateTime.value.millisecondsSinceEpoch.toString(); + getFailureDateTime = + state.failureDateTime.value.millisecondsSinceEpoch.toString(); getEffectiveDateTime = state.effectiveDateTime.value.millisecondsSinceEpoch.toString(); } + var entity = await ApiRepository.to.sendElectronicKey( - state.isCreateUser.value ? "1" : "0", - state.countryCode.value, - '1', - getFailureDateTime, - state.isAuthentication.value == true ? '1' : '2', - '2', - '2', - state.keyNameController.text, - '1', - getKeyType, - lockID, - '', - state.emailOrPhoneController.text, - '', - getEffectiveDateTime, - state.weekdaysList); + createUser: state.isCreateUser.value ? "1" : "0", + countryCode: state.countryCode.value, + usernameType: '1', + endDate: getFailureDateTime, + faceAuthentication: state.isAuthentication.value == true ? '1' : '2', + isCameraEnable: '2', + isRemoteUnlock: '2', + keyNameForAdmin: state.keyNameController.text, + keyRight: '1', + keyType: getKeyType, + lockId: lockID, + operatorUid: '', + receiverUsername: state.emailOrPhoneController.text, + remarks: '', + startDate: getEffectiveDateTime, + weekDays: state.weekdaysList); if (entity.errorCode!.codeIsSuccessful) { print('发送电子钥匙成功'); state.isSendSuccess.value = true; @@ -260,15 +267,48 @@ class AuthorizedAdminLogic extends BaseGetXController { state.addUserId.value = entity.data!.receiverUser!.id.toString(); addUserConnectBlue(state.addUserId.value); } else { - // Toast.show(msg: '${entity.errorMsg}'); if (entity.errorCode == 425) { //用户未注册 - state.isCreateUser.value = true; - sendElectronicKeyRequest(); + _showDialog(widgetContext, '${entity.errorMsg}'); } } } + //用户未注册确认弹窗 + void _showDialog(widgetContext, String errMsg) { + showCupertinoDialog( + context: widgetContext, + builder: (context) { + return CupertinoAlertDialog( + title: const Text('接收者号码未注册,请选择号码所在的国家并重新发送'), + actions: [ + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.cancel!.tr), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.selet!.tr), + onPressed: () async { + //选择国家代码 + state.isCreateUser.value = true; + Navigator.of(context).pop(); + + var result = await Get.toNamed(Routers.seletCountryRegionPage); + if (result != null) { + result as Map; + state.countryCode.value = result['code']; + state.countryName.value = result['countryName']; + } + }, + ), + ], + ); + }, + ); + } + @override void onReady() { // TODO: implement onReady 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 85e53505..ba059f08 100644 --- a/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart +++ b/star_lock/lib/main/lockDetail/authorizedAdmin/authorizedAdmin/authorizedAdmin_page.dart @@ -202,7 +202,7 @@ class _AuthorizedAdminPageState extends State { if (state.emailOrPhoneController.text.isNotEmpty && state.keyNameController.value.text.isNotEmpty) { // logic.addUserConnectBlue(); - logic.sendElectronicKeyRequest(); + logic.sendElectronicKeyRequest(context); } }), Container( @@ -358,11 +358,15 @@ class _AuthorizedAdminPageState extends State { alignment: Alignment.center, child: InkWell( onTap: () async { - Contact? contact = + Contact? currentContact = await state.contactPicker.selectContact(); setState(() { - state.contact = contact!; - // print("object111111111111 ${_contact.fullName} ${_contact.phoneNumbers}"); + state.contact = currentContact!; + if (currentContact.phoneNumbers!.isNotEmpty) { + state.emailOrPhoneController.text = currentContact + .phoneNumbers![0] + .replaceAll(RegExp(r"\s+\b|\b\s"), ""); + } }); }, ), diff --git a/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart b/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart index 507674c6..ff2d1e9f 100644 --- a/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart +++ b/star_lock/lib/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get_utils/get_utils.dart'; import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserListEntity.dart'; @@ -9,6 +10,8 @@ class MassSendReceiverCell extends StatelessWidget { final int currentIndex; LockUserData userData; final VoidCallback clickDeleteUser; + final FlutterContactPicker contactPicker = FlutterContactPicker(); + late Contact contact; MassSendReceiverCell(int index, {Key? key, @@ -138,10 +141,14 @@ class MassSendReceiverCell extends StatelessWidget { child: InkWell( onTap: () async { // Contact? currentContact = - // await _contactPicker.selectContact(); + // await contactPicker.selectContact(); // setState(() { - // _contact = currentContact!; - // // print("object111111111111 ${_contact.fullName} ${_contact.phoneNumbers}"); + // state.contact = currentContact!; + // if (currentContact.phoneNumbers!.isNotEmpty) { + // state.emailOrPhoneController.text = currentContact + // .phoneNumbers![0] + // .replaceAll(RegExp(r"\s+\b|\b\s"), ""); + // } // }); }, ), 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 c5f0ade9..71b58301 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,13 +1,18 @@ +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/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 { final SendElectronicKeyState state = SendElectronicKeyState(); //发送钥匙请求 - Future sendElectronicKeyRequest() async { + Future sendElectronicKeyRequest(BuildContext widgetContext) async { String getFailureDateTime = '0'; String getEffectiveDateTime = '0'; String lockID = state.keyInfo.value.lockId.toString(); @@ -18,33 +23,67 @@ class SendElectronicKeyLogic extends BaseGetXController { getEffectiveDateTime = state.effectiveDateTime.value.millisecondsSinceEpoch.toString(); } + var entity = await ApiRepository.to.sendElectronicKey( - state.isCreateUser.value ? "1" : "0", - state.countryCode.value, - '1', - getFailureDateTime, - state.isAuthentication.value == true ? '1' : '2', - '2', - state.isRemoteUnlock.value == true ? '1' : '2', - state.keyNameController.text, - '0', - getKeyType, - lockID, - '', - state.emailOrPhoneController.text, - '', - getEffectiveDateTime, - state.weekdaysList); + createUser: state.isCreateUser.value ? "1" : "0", + countryCode: state.countryCode.value, + usernameType: '1', + endDate: getFailureDateTime, + faceAuthentication: state.isAuthentication.value == true ? '1' : '2', + isCameraEnable: '2', + isRemoteUnlock: state.isRemoteUnlock.value == true ? '1' : '2', + keyNameForAdmin: state.keyNameController.text, + keyRight: '0', + keyType: getKeyType, + lockId: lockID, + operatorUid: '', + receiverUsername: state.emailOrPhoneController.text, + remarks: '', + startDate: getEffectiveDateTime, + weekDays: state.weekdaysList); if (entity.errorCode!.codeIsSuccessful) { print('发送电子钥匙成功'); state.isSendSuccess.value = true; } else { - Toast.show(msg: '${entity.errorMsg}'); if (entity.errorCode == 425) { //用户未注册 - state.isCreateUser.value = true; - sendElectronicKeyRequest(); + _showDialog(widgetContext, '${entity.errorMsg}'); } } } + + //用户未注册确认弹窗 + void _showDialog(widgetContext, String errMsg) { + showCupertinoDialog( + context: widgetContext, + builder: (context) { + return CupertinoAlertDialog( + title: const Text('接收者号码未注册,请选择号码所在的国家并重新发送'), + actions: [ + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.cancel!.tr), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + CupertinoDialogAction( + child: Text(TranslationLoader.lanKeys!.selet!.tr), + onPressed: () async { + //选择国家代码 + state.isCreateUser.value = true; + Navigator.of(context).pop(); + + var result = await Get.toNamed(Routers.seletCountryRegionPage); + if (result != null) { + result as Map; + state.countryCode.value = result['code']; + state.countryName.value = result['countryName']; + } + }, + ), + ], + ); + }, + ); + } } 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 abfdff73..3fa0163b 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 @@ -260,12 +260,12 @@ class _SendElectronicKeyPageState extends State { if (state.failureDateTime.value .compareTo(state.effectiveDateTime.value) == 1) { - logic.sendElectronicKeyRequest(); + logic.sendElectronicKeyRequest(context); } else { Toast.show(msg: '失效时间需大于生效时间'); } } else { - logic.sendElectronicKeyRequest(); + logic.sendElectronicKeyRequest(context); } } else { Toast.show(msg: '请完善信息'); @@ -428,7 +428,11 @@ class _SendElectronicKeyPageState extends State { await state.contactPicker.selectContact(); setState(() { state.contact = currentContact!; - // print("object111111111111 ${_contact.fullName} ${_contact.phoneNumbers}"); + if (currentContact.phoneNumbers!.isNotEmpty) { + state.emailOrPhoneController.text = currentContact + .phoneNumbers![0] + .replaceAll(RegExp(r"\s+\b|\b\s"), ""); + } }); }, ), 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 ff67f08a..d82bd6fa 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart @@ -1,3 +1,4 @@ +import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -37,15 +38,6 @@ class _PasswordKeyDetailPageState extends State { _inputNameController = TextEditingController(); } - static Future tokNative(String method, - {required Map arguments}) async { - if (arguments == null) { - return await methodChannel.invokeMethod(method); - } else { - return await methodChannel.invokeMethod(method, arguments); - } - } - @override Widget build(BuildContext context) { dynamic obj = ModalRoute.of(context)?.settings.arguments; @@ -66,36 +58,7 @@ class _PasswordKeyDetailPageState extends State { width: 30.w, ), onPressed: () { - String pwdShareStr = - '您好,您的密码是:${itemData.keyboardPwd}\n生效时间:${itemData.startDate}\n类型:永久\n锁名:${itemData.keyboardPwdName}'; - tokNative('flutter_sharePassword_to_ios', - arguments: {'pwdShareStr': pwdShareStr}).then((result) { - print('$result'); - }); - print('与原生交互'); - /* - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (context) { - return Container( - decoration: const BoxDecoration( - color: Colors.white, - ), - constraints: const BoxConstraints(maxHeight: 700), - child: Row( - children: [ - Image.asset( - 'images/icon_wechat.png', - width: 50.0, - height: 50.0, - fit: BoxFit.fill, - ) - ], - ), - ); //设置maxHeight为你想要的数字就行 - }); - */ + _openModalBottomSheet(); }, ), ], @@ -361,91 +324,124 @@ class _PasswordKeyDetailPageState extends State { ); } - Widget _shareWidget(BuildContext context) { - List nameItems = [ - '微信', - '朋友圈', - 'QQ', - 'QQ空间', - '微博', - 'FaceBook', - '邮件', - '链接' - ]; - List urlItems = [ - 'icon_wechat.png', - 'icon_wechat_moments.png', - 'icon_qq.png', - 'icon_qzone.png', - 'icon_sina.png', - 'icon_facebook.png', - 'icon_email.png', - 'icon_copylink.png' - ]; - - return Container( - color: Colors.red, - height: 250.0, - child: GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, mainAxisSpacing: 5.0, childAspectRatio: 1.0), - itemBuilder: (BuildContext context, int index) { - return Image.asset( - 'images/${urlItems[index]}', - width: 50.0, - height: 50.0, - fit: BoxFit.fill, - ); - }, - itemCount: nameItems.length, - ), - /* - child: Column( - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0), - child: SizedBox( - height: 190.0, - child: GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - mainAxisSpacing: 5.0, - childAspectRatio: 1.0), - itemBuilder: (BuildContext context, int index) { - return Column( - children: [ - Padding( - padding: - const EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 6.0), - child: Image.asset( - 'images/${urlItems[index]}', - width: 50.0, - height: 50.0, - fit: BoxFit.fill, - )), - Text(nameItems[index]) - ], - ); - }, - itemCount: nameItems.length, + Future _openModalBottomSheet() async { + showModalBottomSheet( + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadiusDirectional.circular(10)), + constraints: BoxConstraints(maxHeight: 260.h), + builder: (BuildContext context) { + return Column( + children: [ + SizedBox( + width: ScreenUtil().screenWidth, + height: 180.h, + child: ListView( + scrollDirection: Axis.horizontal, //横向滚动 + children: initBottomSheetList()), ), - ), - ), - Container( - height: 0.5, - color: Colors.blueGrey, - ), - const Center( - child: Padding( - padding: EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0), + Container( + height: 8.h, + color: AppColors.greyBackgroundColor, + ), + TextButton( + style: ButtonStyle( + overlayColor: + MaterialStateProperty.all(Colors.white)), child: Text( - '取 消', - style: TextStyle(fontSize: 18.0, color: Colors.blueGrey), - )), - ) - ], + '取消', + style: TextStyle( + color: Colors.black, fontSize: ScreenUtil().setSp(24)), + ), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ); + }); + } + + List initBottomSheetList() { + List widgetList = []; + + widgetList.add(buildCenter3('images/icon_wechat.png', '微信好友', 0)); + widgetList.add(buildCenter3('images/icon_message.png', '短信', 1)); + widgetList.add(buildCenter3('images/icon_email.png', '邮件', 2)); + widgetList.add(buildCenter3('images/icon_more.png', '更多', 3)); + + return widgetList; + } + + GestureDetector buildCenter3( + String imageName, String titleStr, int itemIndex) { + return GestureDetector( + child: Container( + width: 120.w, + // height: 64.h, + margin: + EdgeInsets.only(top: 20.w, bottom: 20.w, left: 10.w, right: 10.w), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + imageName, + width: 50.w, + height: 50.h, + ), + SizedBox( + height: 16.w, + ), + Text( + titleStr, + style: TextStyle( + fontSize: ScreenUtil().setSp(20), color: Colors.black), + ), + ], + ), ), - */ + onTap: () => _jumpSmartDeviceRoute(itemIndex), ); } + + _jumpSmartDeviceRoute(int itemIndex) { + switch (itemIndex) { + case 0: + //微信好友 + { + String pwdShareStr = + '您好,您的密码是:${itemData.keyboardPwd}\n生效时间:${itemData.startDate}\n类型:永久\n锁名:${itemData.keyboardPwdName}'; + tokNative('flutter_sharePassword_to_ios', + arguments: {'pwdShareStr': pwdShareStr}).then((result) { + print('$result'); + }); + print('与原生交互'); + } + break; + case 1: + //短信 + {} + break; + case 2: + //邮件 + { + Navigator.pushNamed(context, Routers.sendEmailNotificationPage); + } + break; + case 3: + //更多 + {} + break; + default: + } + } + + static Future tokNative(String method, + {required Map arguments}) async { + if (arguments == null) { + return await methodChannel.invokeMethod(method); + } else { + return await methodChannel.invokeMethod(method, arguments); + } + } } 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 f2fa3b17..e992b02b 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 @@ -1,11 +1,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/main/lockMian/entity/lockInfoEntity.dart'; import 'package:star_lock/network/api_repository.dart'; @@ -37,6 +39,7 @@ class _PasswordKeyPerpetualPageState extends State { final TextEditingController _nameController = TextEditingController(); final TextEditingController _pwdController = TextEditingController(); final logic = Get.put(PasswordKeyPerpetualLogic()); + static const methodChannel = MethodChannel('flutter_native_ios'); late bool _isSendSuccess; //是否发送成功 late bool _isPermanent; //是否永久 @@ -581,7 +584,7 @@ class _PasswordKeyPerpetualPageState extends State { OutLineBtn( btnName: '分享', onClick: () { - Navigator.pushNamed(context, Routers.sendEmailNotificationPage); + _openModalBottomSheet(); }, ), SizedBox( @@ -644,4 +647,125 @@ class _PasswordKeyPerpetualPageState extends State { String intToStr(int v) { return (v < 10) ? "0$v" : "$v"; } + + Future _openModalBottomSheet() async { + showModalBottomSheet( + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadiusDirectional.circular(10)), + constraints: BoxConstraints(maxHeight: 260.h), + builder: (BuildContext context) { + return Column( + children: [ + SizedBox( + width: ScreenUtil().screenWidth, + height: 180.h, + child: ListView( + scrollDirection: Axis.horizontal, //横向滚动 + children: initBottomSheetList()), + ), + Container( + height: 8.h, + color: AppColors.greyBackgroundColor, + ), + TextButton( + style: ButtonStyle( + overlayColor: + MaterialStateProperty.all(Colors.white)), + child: Text( + '取消', + style: TextStyle( + color: Colors.black, fontSize: ScreenUtil().setSp(24)), + ), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ); + }); + } + + List initBottomSheetList() { + List widgetList = []; + + widgetList.add(buildCenter3('images/icon_wechat.png', '微信好友', 0)); + widgetList.add(buildCenter3('images/icon_message.png', '短信', 1)); + widgetList.add(buildCenter3('images/icon_email.png', '邮件', 2)); + widgetList.add(buildCenter3('images/icon_more.png', '更多', 3)); + + return widgetList; + } + + GestureDetector buildCenter3( + String imageName, String titleStr, int itemIndex) { + return GestureDetector( + child: Container( + width: 120.w, + // height: 64.h, + margin: + EdgeInsets.only(top: 20.w, bottom: 20.w, left: 10.w, right: 10.w), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + imageName, + width: 50.w, + height: 50.h, + ), + SizedBox( + height: 16.w, + ), + Text( + titleStr, + style: TextStyle( + fontSize: ScreenUtil().setSp(20), color: Colors.black), + ), + ], + ), + ), + onTap: () => _jumpSmartDeviceRoute(itemIndex), + ); + } + +//\n生效时间:${itemData.startDate}\n类型:永久\n锁名:${itemData.keyboardPwdName} + _jumpSmartDeviceRoute(int itemIndex) { + switch (itemIndex) { + case 0: + //微信好友 + { + String pwdShareStr = '您好,您的密码是:$_getPwdStr'; + tokNative('flutter_sharePassword_to_ios', + arguments: {'pwdShareStr': pwdShareStr}).then((result) { + print('$result'); + }); + print('与原生交互'); + } + break; + case 1: + //短信 + {} + break; + case 2: + //邮件 + { + Navigator.pushNamed(context, Routers.sendEmailNotificationPage); + } + break; + case 3: + //更多 + {} + break; + default: + } + } + + static Future tokNative(String method, + {required Map arguments}) async { + if (arguments == null) { + return await methodChannel.invokeMethod(method); + } else { + return await methodChannel.invokeMethod(method, arguments); + } + } } diff --git a/star_lock/lib/network/api_provider_base.dart b/star_lock/lib/network/api_provider_base.dart index 648e868d..f8ebd259 100644 --- a/star_lock/lib/network/api_provider_base.dart +++ b/star_lock/lib/network/api_provider_base.dart @@ -74,9 +74,10 @@ class BaseProvider extends GetConnect with Api { case 430: //与葛工约定弹出ErrorMsg Toast.show(msg: T["errorMsg"]); break; - case 425: - Toast.show(msg: "用户不存在"); - break; + //已单独处理,暂不做全局弹窗 + // case 425: + // Toast.show(msg: "用户不存在"); + // break; case 10001: Toast.show(msg: "数据不存在"); break; diff --git a/star_lock/lib/network/api_repository.dart b/star_lock/lib/network/api_repository.dart index 32e5abcf..fb8e57bf 100644 --- a/star_lock/lib/network/api_repository.dart +++ b/star_lock/lib/network/api_repository.dart @@ -136,22 +136,22 @@ class ApiRepository { //发送电子钥匙 Future sendElectronicKey( - String createUser, - String countryCode, - String usernameType, - String endDate, - String faceAuthentication, - String isCameraEnable, - String isRemoteUnlock, - String keyNameForAdmin, - String keyRight, - String keyType, - String lockId, - String operatorUid, - String receiverUsername, - String remarks, - String startDate, - List weekDays) async { + {required String createUser, + required String countryCode, + required String usernameType, + required String endDate, + required String faceAuthentication, + required String isCameraEnable, + required String isRemoteUnlock, + required String keyNameForAdmin, + required String keyRight, + required String keyType, + required String lockId, + required String operatorUid, + required String receiverUsername, + required String remarks, + required String startDate, + required List weekDays}) async { final res = await apiProvider.sendElectronicKey( createUser, countryCode,