diff --git a/lib/login/login/starLock_login_logic.dart b/lib/login/login/starLock_login_logic.dart index ba9f7629..570fa80c 100755 --- a/lib/login/login/starLock_login_logic.dart +++ b/lib/login/login/starLock_login_logic.dart @@ -1,6 +1,9 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:star_lock/apm/apm_helper.dart'; +import 'package:jverify/jverify.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/blue/blue_manage.dart'; @@ -17,6 +20,7 @@ import '../../mine/mine/starLockMine_logic.dart'; import '../../network/api_repository.dart'; import '../../tools/dateTool.dart'; import '../../tools/eventBusEventManage.dart'; +import '../../tools/jverify_one_click_login.dart'; import '../../tools/showTipView.dart'; import '../../tools/storage.dart'; import '../register/entity/checkIP_entity.dart'; @@ -97,6 +101,43 @@ class StarLockLoginLogic extends BaseGetXController { } } + Future oneClickLoginAction() async { + await JverifyOneClickLoginManage().loginAuth((e) async { + final int? code = e.code; + final String? content = e.message; + // final String operator = map['operator']; + AppLog.log('1111code:$code content:$content'); + if (code == 6000) { + final LoginEntity entity = await ApiRepository.to.oneClickLogin( + loginType: '3', + loginToken: content ?? '', + deviceInfo: state.deviceInfoMap); + if (entity.errorCode!.codeIsSuccessful) { + ApmHelper.instance.trackEvent('login_result', { + 'account': state.emailOrPhone.value, + 'date': DateTool().getNowDateWithType(1), + 'login_res': '成功', + }); + + Storage.saveLoginData(entity.data); + Storage.setBool(saveIsVip, entity.data!.isVip == 1); + eventBus.fire(MineInfoChangeRefreshUI()); + if (Get.isRegistered()) { + Get.find().getStarLockInfo(isUnShowLoading: true); + } + Get.offNamedUntil(Routers.starLockMain, (Route route) => false); + BlueManage().scanDevices.clear(); //清除设备缓存 + } else { + ApmHelper.instance.trackEvent('login_result', { + 'account': state.emailOrPhone.value, + 'date': DateTool().getNowDateWithType(1), + 'login_res': '${entity.errorCode}--${entity.errorMsg}', + }); + } + } + }); + } + Future checkIpAction() async { final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: ''); if (entity.errorCode!.codeIsSuccessful) { @@ -134,6 +175,16 @@ class StarLockLoginLogic extends BaseGetXController { state.canNext.value = state.pwdIsOK && state.isEmailOrPhone; } + @override + Future onInit() async { + super.onInit(); + + JverifyOneClickLoginManage(); + oneClickLoginAction(); + state.isCheckVerifyEnable.value = + await JverifyOneClickLoginManage().checkVerifyEnable(); + } + @override void onClose() { state.onClose(); diff --git a/lib/login/login/starLock_login_page.dart b/lib/login/login/starLock_login_page.dart index ea0793c0..0c39c91a 100755 --- a/lib/login/login/starLock_login_page.dart +++ b/lib/login/login/starLock_login_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -14,6 +15,7 @@ import '../../appRouters.dart'; import '../../app_settings/app_colors.dart'; import '../../common/XSConstantMacro/XSConstantMacro.dart'; import '../../tools/commonItem.dart'; +import '../../tools/jverify_one_click_login.dart'; import '../../tools/submitBtn.dart'; import '../../tools/tf_loginInput.dart'; import '../../tools/titleAppBar.dart'; @@ -237,6 +239,24 @@ class _StarLockLoginPageState extends State { } } : null)), + // SizedBox(height: 20.w), + // Obx(() => Visibility( + // visible: state.isCheckVerifyEnable.value, + // child: SubmitBtn( + // btnName: '一键登录', + // fontSize: 28.sp, + // borderRadius: 20.w, + // padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + // // isDisabled: state.canNext.value, + // onClick: () { + // if (state.agree.value == false) { + // logic.showToast('请先同意用户协议及隐私政策'.tr); + // return; + // } else { + // logic.oneClickLoginAction(); + // } + // }), + // )), SizedBox(height: 50.w), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -261,24 +281,23 @@ class _StarLockLoginPageState extends State { child: SizedBox( width: 10.sp, )), - if (F.isLite) - Container() - else - GestureDetector( - child: SizedBox( - // width: 150.w, - height: 50.h, - // color: Colors.red, - child: Center( - child: Text('演示模式'.tr, - style: TextStyle( - fontSize: 22.sp, color: AppColors.mainColor)), + Obx(() => Visibility( + visible: state.isCheckVerifyEnable.value, + child: GestureDetector( + child: SizedBox( + // width: 150.w, + height: 50.h, + // color: Colors.red, + child: Center( + child: Text('一键登录'.tr, + style: TextStyle( + fontSize: 22.sp, + color: AppColors.mainColor)), + ), + ), + onTap: logic.oneClickLoginAction, ), - ), - onTap: () { - Get.toNamed(Routers.demoModeLockDetailPage); - }, - ) + )) ], ), ], diff --git a/lib/login/login/starLock_login_state.dart b/lib/login/login/starLock_login_state.dart index 41bc0fef..ec224880 100755 --- a/lib/login/login/starLock_login_state.dart +++ b/lib/login/login/starLock_login_state.dart @@ -45,6 +45,8 @@ class StarLockLoginState { 'deviceType': 0 }.obs; + RxBool isCheckVerifyEnable = false.obs; + void onClose() { // emailOrPhoneController.dispose(); // pwdController.dispose(); diff --git a/lib/login/login/starLock_login_xhj_page.dart b/lib/login/login/starLock_login_xhj_page.dart index 8138db92..b0810366 100755 --- a/lib/login/login/starLock_login_xhj_page.dart +++ b/lib/login/login/starLock_login_xhj_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -186,14 +187,12 @@ class _StarLockLoginPageState extends State { onPressed: () async { final dynamic data = await Get.toNamed(Routers.starLockRegisterPage); - if (data != null) { - state.emailOrPhoneController.text = - data['phoneOrEmailStr']; - logic.checkNext(state.emailOrPhoneController); - state.pwdController.text = data['pwd']; - logic.checkNext(state.pwdController); - setState(() {}); - } + state.emailOrPhoneController.text = + data['phoneOrEmailStr']; + logic.checkNext(state.emailOrPhoneController); + state.pwdController.text = data['pwd']; + logic.checkNext(state.pwdController); + setState(() {}); }, style: ElevatedButton.styleFrom( backgroundColor: AppColors.mainColor), @@ -229,25 +228,25 @@ class _StarLockLoginPageState extends State { child: SizedBox( width: 10.sp, )), - if (F.isLite) - Container() - else - GestureDetector( - child: SizedBox( - // width: 150.w, - height: 50.h, - // color: Colors.red, - child: Center( - child: Text('演示模式'.tr, - style: TextStyle( - fontSize: 22.sp, - color: AppColors.mainColor)), + Obx(() => Visibility( + visible: state.isCheckVerifyEnable.value, + child: GestureDetector( + child: SizedBox( + // width: 150.w, + height: 50.h, + // color: Colors.red, + child: Center( + child: Text('一键登录'.tr, + style: TextStyle( + fontSize: 22.sp, + color: AppColors.mainColor)), + ), + ), + onTap: () async { + logic.oneClickLoginAction(); + }, ), - ), - onTap: () { - Get.toNamed(Routers.demoModeLockDetailPage); - }, - ) + )) ], ), ], diff --git a/lib/main_local.dart b/lib/main_local.dart index 0fe387f7..9e30d007 100755 --- a/lib/main_local.dart +++ b/lib/main_local.dart @@ -4,7 +4,7 @@ import 'flavors.dart'; import 'main.dart' as runner; Future main() async { - F.appFlavor = Flavor.pre; + F.appFlavor = Flavor.xhj; // AppLog.log('local调用了main函数'); await runner.main(); } diff --git a/lib/network/api.dart b/lib/network/api.dart index 8a04dc74..a1be47c2 100755 --- a/lib/network/api.dart +++ b/lib/network/api.dart @@ -5,6 +5,7 @@ abstract class Api { final String getSliderVerifyImgUrl = '/user/getSliderVerifyImg'; final String checkImgUrl = '/user/isSliderValid'; final String loginUrl = '/user/login'; + final String oneClickLoginUrl = '/user/quickLogin'; // 一键登录 final String resetPasswordURL = '/user/resetPassword'; //重置密码 final String getCountryRegionURL = '/system/listCountry'; //获取国家或地区 final String electronicKeyListURL = '/key/listUser'; //电子钥匙列表 diff --git a/lib/network/api_provider.dart b/lib/network/api_provider.dart index 99a05695..cf7b064e 100755 --- a/lib/network/api_provider.dart +++ b/lib/network/api_provider.dart @@ -80,6 +80,17 @@ class ApiProvider extends BaseProvider { 'deviceInfo': deviceInfo, })); + Future oneClickLogin( + String loginType, String loginToken, Map deviceInfo) => + post( + oneClickLoginUrl.toUrl, + jsonEncode({ + 'loginType': loginType, + 'platId': '2', + 'loginToken': loginToken, + 'deviceInfo': deviceInfo, + })); + Future resetPassword( String countryCode, String account, diff --git a/lib/network/api_repository.dart b/lib/network/api_repository.dart index 1bb84daa..c2732880 100755 --- a/lib/network/api_repository.dart +++ b/lib/network/api_repository.dart @@ -146,6 +146,16 @@ class ApiRepository { return LoginEntity.fromJson(res.body); } + //登录 + Future oneClickLogin( + {required String loginType, + required String loginToken, + required Map deviceInfo}) async { + final res = + await apiProvider.oneClickLogin(loginType, loginToken, deviceInfo); + return LoginEntity.fromJson(res.body); + } + //重置密码 Future resetPassword( String countryCode, diff --git a/lib/tools/jverify_one_click_login.dart b/lib/tools/jverify_one_click_login.dart new file mode 100644 index 00000000..94993d6d --- /dev/null +++ b/lib/tools/jverify_one_click_login.dart @@ -0,0 +1,272 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:jverify/jverify.dart'; +import 'package:star_lock/app_settings/app_colors.dart'; + +import '../app_settings/app_settings.dart'; +import '../common/XSConstantMacro/XSConstantMacro.dart'; +import '../flavors.dart'; + +class JverifyOneClickLoginManage { + factory JverifyOneClickLoginManage() => shareManager()!; + + JverifyOneClickLoginManage._init() { + _initSDK(); + } + + static JverifyOneClickLoginManage? _manager; + + static JverifyOneClickLoginManage? shareManager() { + _manager ??= JverifyOneClickLoginManage._init(); + return _manager; + } + + JverifyOneClickLoginManage? get manager => shareManager(); + Jverify jverify = Jverify(); + + /// 统一 key + String f_result_key = 'result'; + + /// 错误码 + String f_code_key = 'code'; + + /// 回调的提示信息,统一返回 flutter 为 message + String f_msg_key = 'message'; + + /// 运营商信息 + String f_opr_key = 'operator'; + + Future _initSDK() async { + try { + await initPlatformState(); + + isInitSuccess(); + + getToken(); + + preLogin(); + } catch (e) { + AppLog.log('SDK 初始化错误: $e'); + } + } + + Future initPlatformState() async { + // 初始化 SDK 之前添加监听 + jverify.addSDKSetupCallBackListener((JVSDKSetupEvent event) { + print('receive sdk setup call back event :${event.toMap()}'); + }); + + jverify.setDebugMode(true); // 打开调试模式 + jverify.setCollectionAuth(true); + String appKey; + if (F.isSKY) { + appKey = '7ff37d174c1a568a89e98dad'; + AppLog.log('appKey:7ff37d174c1a568a89e98dad'); + } else { + appKey = '251fc8074820d122b6de58d2'; + AppLog.log('appKey:251fc8074820d122b6de58d2'); + } + jverify.setup( + appKey: appKey, //"你自己应用的 AppKey", + channel: 'devloper'); + + /// 授权页面点击时间监听 + jverify.addAuthPageEventListener((JVAuthPageEvent event) { + print('receive auth page event :${event.toMap()}'); + }); + } + + /// sdk 初始化是否完成 + void isInitSuccess() { + jverify.isInitSuccess().then((map) { + final bool result = map[f_result_key]; + AppLog.log('sdk 初始化结果:$map'); + if (result) { + AppLog.log('sdk 初始化成功'); + } else { + AppLog.log('sdk 初始化失败'); + } + }); + } + + /// 判断当前网络环境是否可以发起认证 + Future checkVerifyEnable() async { + final Map map = await jverify.checkVerifyEnable(); + final bool result = map[f_result_key]; + return result; + // state.jverify.checkVerifyEnable().then((map) { + // final bool result = map[f_result_key]; + // if (result) { + // AppLog.log('当前网络环境【支持认证】!'); + // } else { + // AppLog.log('当前网络环境【不支持认证】!'); + // } + // return result; + // }); + } + + void getToken() { + jverify.checkVerifyEnable().then((map) { + final bool result = map[f_result_key]; + if (result) { + jverify.getToken().then((map) { + final int code = map[f_code_key]; + final String token = map[f_msg_key]; + final String operator = map[f_opr_key]; + AppLog.log('getToken code:$code token:$token operator:$operator'); + }); + } else { + AppLog.log('[2016],msg = 当前网络环境不支持认证'); + } + }); + } + + /// 登录预取号 + void preLogin() { + jverify.checkVerifyEnable().then((map) { + final bool result = map[f_result_key]; + if (result) { + jverify.preLogin().then((map) { + AppLog.log('预取号接口回调:${map.toString()}'); + final int code = map[f_code_key]; + final String message = map[f_msg_key]; + }); + } else { + AppLog.log('[2016],msg = 当前网络环境不支持认证'); + } + }); + } + + /// SDK 请求授权一键登录 + Future loginAuth( + Function(JVListenerEvent jvListenerEvent) action) async { + Map map = await jverify.checkVerifyEnable(); + final bool result = map[f_result_key]; + print('checkVerifyEnable $map'); + //需要使用sms的时候不检查result + // if (result) { + // return await jverify.loginAuth(true); + // } + // return null; + + if (result) { + bool isiOS = Platform.isIOS; + + /// 自定义授权的 UI 界面,以下设置的图片必须添加到资源文件里, + /// android项目将图片存放至drawable文件夹下,可使用图片选择器的文件名,例如:btn_login.xml,入参为"btn_login"。 + /// ios项目存放在 Assets.xcassets。 + JVUIConfig uiConfig = JVUIConfig(); + // uiConfig.authBGGifPath = "main_gif"; + // uiConfig.authBGVideoPath="main_vi"; + // uiConfig.authBGVideoPath = 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'; + uiConfig.authBackgroundImage = 'images/icon_left_grey.png'; + + // uiConfig.navHidden = !isiOS; + uiConfig.navColor = AppColors.mainColor.value; + uiConfig.navText = '一键登录'.tr; + uiConfig.navTextColor = Colors.white.value; + uiConfig.navReturnImgPath = 'return_bg'; //图片必须存在 + + uiConfig.logoWidth = 100; + uiConfig.logoHeight = 100; + //uiConfig.logoOffsetX = isiOS ? 0 : null;//(screenWidth/2 - uiConfig.logoWidth/2).toInt(); + uiConfig.logoOffsetY = 100; + uiConfig.logoVerticalLayoutItem = JVIOSLayoutItem.ItemSuper; + uiConfig.logoHidden = false; + uiConfig.logoImgPath = 'logo'; + + uiConfig.numberFieldWidth = 200; + uiConfig.numberFieldHeight = 40; + //uiConfig.numFieldOffsetX = isiOS ? 0 : null;//(screenWidth/2 - uiConfig.numberFieldWidth/2).toInt(); + uiConfig.numFieldOffsetY = isiOS ? 120 : 220; + uiConfig.numberVerticalLayoutItem = JVIOSLayoutItem.ItemLogo; + uiConfig.numberColor = AppColors.mainColor.value; + uiConfig.numberSize = 18; + + uiConfig.sloganOffsetY = isiOS ? 120 : 260; + uiConfig.sloganVerticalLayoutItem = JVIOSLayoutItem.ItemNumber; + uiConfig.sloganTextColor = Colors.black.value; + uiConfig.sloganTextSize = 15; +// uiConfig.slogan + //uiConfig.sloganHidden = 0; + + uiConfig.logBtnOffsetX = 20; + uiConfig.logBtnWidth = double.parse('${1.sw - 20 * 2}').toInt(); + uiConfig.logBtnHeight = 50; + //uiConfig.logBtnOffsetX = isiOS ? 0 : null;//(screenWidth/2 - uiConfig.logBtnWidth/2).toInt(); + uiConfig.logBtnOffsetY = isiOS ? 120 : 330; + uiConfig.logBtnVerticalLayoutItem = JVIOSLayoutItem.ItemNumber; + uiConfig.logBtnText = '一键登录'.tr; + uiConfig.logBtnTextColor = Colors.white.value; + uiConfig.logBtnTextSize = 16; + uiConfig.logBtnBackgroundPath = ''; + // uiConfig.logBtnTextBold = true; + // uiConfig.loginBtnNormalImage = 'login_btn_normal'; //图片必须存在 + // uiConfig.loginBtnPressedImage = 'login_btn_press'; //图片必须存在 + // uiConfig.loginBtnUnableImage = 'login_btn_unable'; //图片必须存在 + + uiConfig.privacyHintToast = + true; //only android 设置隐私条款不选中时点击登录按钮默认显示toast。 + + uiConfig.privacyState = false; //设置默认勾选 + uiConfig.privacyCheckboxSize = 20; + uiConfig.checkedImgPath = 'check_image'; //图片必须存在 + uiConfig.uncheckedImgPath = 'uncheck_image'; //图片必须存在 + uiConfig.privacyCheckboxInCenter = true; + uiConfig.privacyCheckboxHidden = false; + uiConfig.isAlertPrivacyVc = true; + + //uiConfig.privacyOffsetX = isiOS ? (20 + uiConfig.privacyCheckboxSize) : null; + uiConfig.privacyOffsetY = 30; // 距离底部距离 + uiConfig.privacyOffsetX = 15; // 距离底部距离 + uiConfig.privacyVerticalLayoutItem = JVIOSLayoutItem.ItemSuper; + uiConfig.clauseName = '协议1'; + uiConfig.clauseUrl = 'http://www.baidu.com'; + uiConfig.clauseBaseColor = Colors.black.value; + uiConfig.clauseNameTwo = '协议二'; + uiConfig.clauseUrlTwo = 'http://www.hao123.com'; + uiConfig.clauseColor = AppColors.mainColor.value; + uiConfig.privacyText = ['我已阅读并同意'.tr]; + uiConfig.privacyTextSize = 13; + uiConfig.privacyItem = [ + JVPrivacy('用户协议'.tr, XSConstantMacro.userAgreementURL, + beforeName: '', afterName: '', separator: ''), + JVPrivacy('隐私政策'.tr, XSConstantMacro.privacyPolicyURL, separator: '') + ]; + uiConfig.textVerAlignment = 1; + //uiConfig.privacyWithBookTitleMark = true; + //uiConfig.privacyTextCenterGravity = false; + uiConfig.authStatusBarStyle = JVIOSBarStyle.StatusBarStyleDarkContent; + uiConfig.privacyStatusBarStyle = JVIOSBarStyle.StatusBarStyleDefault; + uiConfig.modelTransitionStyle = JVIOSUIModalTransitionStyle.CrossDissolve; + + uiConfig.statusBarColorWithNav = true; + // uiConfig.virtualButtonTransparent = true; + + uiConfig.privacyStatusBarColorWithNav = true; + uiConfig.privacyVirtualButtonTransparent = true; + + uiConfig.needStartAnim = true; + uiConfig.needCloseAnim = true; + uiConfig.enterAnim = 'activity_slide_enter_bottom'; + uiConfig.exitAnim = 'activity_slide_exit_bottom'; + + uiConfig.privacyNavColor = AppColors.mainColor.value; + uiConfig.privacyNavTitleTextColor = Colors.white.value; + uiConfig.privacyNavTitleTextSize = 16; + + /// 调用接口设置 UI + jverify.setCustomAuthorizationView(true, uiConfig, + landscapeConfig: uiConfig); + jverify.loginAuthSyncApi2( + autoDismiss: true, + loginAuthcallback: (event) { + action(event); + // AppLog.log('获取到 loginAuthSyncApi 接口返回数据,code=${event.code},message = ${event.message},operator = ${event.operator}'); + }); + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml index c4940ae7..12e5cd85 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -253,6 +253,7 @@ dependencies: flutter_bugly: ^1.0.2 open_filex: ^4.4.0 + jverify: 3.0.0 # umeng_common_sdk: 1.2.8 #