import 'dart:convert'; import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_alibc/alibc_model.dart'; import 'package:flutter_alibc/flutter_alibc.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:sharesdk_plugin/sharesdk_plugin.dart'; import 'package:zhiying_comm/pages/login_page/account/login_account_page.dart'; import 'package:zhiying_comm/pages/login_page/bind/login_bind_phone_page.dart'; import 'package:zhiying_comm/util/dialog/loading/loading.dart'; import 'package:zhiying_comm/util/empty_util.dart'; import 'package:zhiying_comm/util/mob_util/mob_util.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:provider/provider.dart'; import 'package:ali_auth_wbq/ali_auth_wbq.dart'; import 'bloc/bloc.dart'; import 'bloc/login_repository.dart'; import 'login_page_sk.dart'; import 'model/login_style_model.dart'; /// /// 登陆页面 /// class LoginPage extends StatelessWidget { const LoginPage({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: HexColor.fromHex('#FFFFFF'), body: BlocProvider( create: (_) => LoginBloc(repository: LoginRepository())..add(LoginInitEvent()), child: LoginPageContainer(), ), ); } } class LoginPageContainer extends StatefulWidget { @override _LoginPageContainerState createState() => _LoginPageContainerState(); } class _LoginPageContainerState extends State { LoginModel _taoBao; var _qqUserData; var _wxUserData; String _appleData; bool checkBool = false; LoginStyleModel loginStyleModel; @override void initState() { // 登录监听 AliAuthPlugin.loginListen(type: false, onEvent: _onAppleLoginEvent); super.initState(); } // 返回授权信息 // returnCode: 200成功 500失败 // returnMsg // user // familyName //可能为 @"" // givenName //可能为 @"" // email //可能为 @"" // identityTokenStr //需要使用的参数 // authorizationCodeStr void _onAppleLoginEvent(event) { var stateCode = event['returnCode']; String stateMsg = event['returnMsg']; // _appleData = event['identityTokenStr']; _appleData = event['user']; Logger.debug('event == ' + event?.toString()); if (stateCode == 200 && !EmptyUtil.isEmpty(_appleData)) { Loading.dismiss(); print("成功------$event"); BlocProvider.of(context).add(LoginThirdAppleEvent(identityToken: _appleData)); } else { Loading.dismiss(); print("失败------$stateMsg"); } } /// 微信or手机登陆 void _loginClick(String type, LoginStyleModel model) { if (!isCheck()) { return; } print('登陆$type'); RouterUtil.hideKeyboard(context); if ('mobile' == type) { if (model?.flashLoginEnable == '1') { // mob 一键登录 // MobUtil.openQuickLoginPage(context, model?.quick); Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null))); } else { Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null))); } } else if ('wechat' == type) { /// 微信登录 Loading.show(context); SharesdkPlugin.getUserInfo(ShareSDKPlatforms.wechatSession, (SSDKResponseState state, Map userdata, SSDKError error) { Logger.log('state = ${state?.toString()}, userInfo = ${userdata?.toString()} , error = ${error?.code}'); if (state == SSDKResponseState.Success) { try { if (Platform.isIOS) { Map credentialDic = userdata['credential']; Map rawDatalDic = userdata['rawData']; var name = userdata['nickname']; var gender = userdata['gender']; var icon = userdata['icon']; var userID = userdata['uid']; var unionid = rawDatalDic['unionid']; var token = credentialDic['token']; Map dbInfoDic = { 'nickname': name, 'gender': gender, 'icon': icon, 'userID': userID, 'unionid': unionid, 'token': token, }; Map tempUserData = {'dbInfo': jsonEncode(dbInfoDic)}; _wxUserData = jsonDecode(tempUserData['dbInfo']); BlocProvider.of(context).add(LoginThirdWeChatEvent(model: tempUserData)); } else if (Platform.isAndroid) { _wxUserData = jsonDecode(userdata['dbInfo']); BlocProvider.of(context).add(LoginThirdWeChatEvent(model: userdata)); } Loading.dismiss(); } catch (e) { Logger.error(e?.toString()); Fluttertoast.showToast(msg: '登录失败'); Loading.dismiss(); } } else { Loading.dismiss(); } }); } } /// 第三方登陆 void _otherLoginClick(BottomIcons model) async { if (!isCheck()) { return; } print('第三方登陆${model.type}'); if (EmptyUtil.isEmpty(model) || EmptyUtil.isEmpty(model.type)) { Fluttertoast.showToast(msg: '暂不支持~'); return; } /// 淘宝登录 if ('taobao' == model.type) { Loading.show(context); _taoBao = await FlutterAlibc.loginTaoBao(); if (!EmptyUtil.isEmpty(_taoBao) && !EmptyUtil.isEmpty(_taoBao?.errorCode) && _taoBao.errorCode == '0') { BlocProvider.of(context).add(LoginThirdAliEvent( nick: _taoBao?.data?.nick, avatarUrl: _taoBao?.data?.avatarUrl, openId: _taoBao?.data?.openId, openSid: _taoBao?.data?.openSid, topAccessToken: _taoBao?.data?.topAccessToken, topAuthCode: _taoBao?.data?.topAuthCode)); // Logger.warn(' tao login = ${_taoBao?.errorCode} , msg = ${_taoBao?.errorMessage}, nick = ${_taoBao?.data?.nick}, ' // 'avatar = ${_taoBao?.data?.avatarUrl}, openId = ${_taoBao?.data?.openId}, openSid = ${_taoBao?.data?.openSid}, ' // 'topAccessToken = ${_taoBao?.data?.topAccessToken}, topAuthCode = ${_taoBao?.data?.topAuthCode}'); } Loading.dismiss(); } /// QQ登录 if ('qq' == model.type) { Loading.show(context); SharesdkPlugin.getUserInfo(ShareSDKPlatforms.qq, (SSDKResponseState state, Map userdata, SSDKError error) { Logger.log('state = ${state?.toString()}\nuserData = ${userdata?.toString()}'); if (state == SSDKResponseState.Success && !EmptyUtil.isEmpty(userdata)) { try { _qqUserData = jsonDecode(userdata['dbInfo']); BlocProvider.of(context).add(LoginThirdQQEvent(model: userdata)); Loading.dismiss(); } catch (e) { Fluttertoast.showToast(msg: '登录失败'); Loading.dismiss(); } } else { Loading.dismiss(); } }); // Fluttertoast.showToast(msg: '暂不支持~'); } /// 苹果登录 if ('apple' == model.type) { if (Platform.isIOS) { Loading.show(context); await AliAuthPlugin.appleLogin; // final appleLogin = await AliAuthPlugin.appleLogin; } else { Fluttertoast.showToast(msg: '暂不支持~'); } } } /// 跳到用户协议 void _jumpUserAgreement(String url) { if (!EmptyUtil.isEmpty(url)) { print('协议'); RouterUtil.openWebview(url, context); } } /// 跳到绑定手机号 void _jumpBindPhonePage(String thirdType) { /// 如果是苹果登录 if (GlobalConfig.LOGIN_THIRD_APPLE == thirdType) { Navigator.push( context, CupertinoPageRoute( builder: (_) => LoginBindPhonePage({ 'thirdType': thirdType, 'identityTokenStr': _appleData, }))); } /// 如果是淘宝登录 if (GlobalConfig.LOGIN_THIRD_ALI == thirdType) { Navigator.push( context, CupertinoPageRoute( builder: (_) => LoginBindPhonePage({ 'thirdType': thirdType, 'nick': _taoBao?.data?.nick, 'avatarUrl': _taoBao?.data?.avatarUrl, 'openId': _taoBao?.data?.openId, 'openSid': _taoBao?.data?.openSid, 'topAccessToken': _taoBao?.data?.topAccessToken, 'topAuthCode': _taoBao?.data?.topAuthCode, }))); } /// 如果是QQ登录 if (GlobalConfig.LOGIN_THIRD_QQ == thirdType) { if (!EmptyUtil.isEmpty(_qqUserData)) { Navigator.push( context, CupertinoPageRoute( builder: (_) => LoginBindPhonePage({ 'thirdType': thirdType, 'nickname': _qqUserData['nickname']?.toString(), 'avatar_url': _qqUserData['icon']?.toString(), 'open_id': _qqUserData['userID']?.toString(), 'gender': _qqUserData['gender']?.toString() == '0' ? '1' : '2', 'unionid': _qqUserData['unionid']?.toString(), 'token': _qqUserData['token']?.toString(), }))); } } /// 微信登录 if (GlobalConfig.LOGIN_THIRD_WECHAT == thirdType) { if (!EmptyUtil.isEmpty(_wxUserData)) { Navigator.push( context, CupertinoPageRoute( builder: (_) => LoginBindPhonePage({ 'thirdType': thirdType, 'nickname': _wxUserData['nickname']?.toString(), 'avatar_url': _wxUserData['icon']?.toString(), 'open_id': _wxUserData['userID']?.toString(), 'gender': _wxUserData['gender']?.toString() == '0' ? '1' : '2', 'unionid': _wxUserData['unionid']?.toString(), 'token': _wxUserData['token']?.toString(), }))); } } } /// 跳到首页 void _jumpHomePage() { RouterUtil.goBackHomePage(context); } /// 展开关闭其它登陆 void _showOrCloseOtherLogin() { setState(() { _showOther = !_showOther; }); } final _sizedHeight50 = const SizedBox(height: 50); final _sizedHeight9 = const SizedBox(height: 9); final _sizedHeight18 = const SizedBox(height: 18); final _sizedHeight21 = const SizedBox(height: 21); bool _showOther = true; @override Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) { // Fluttertoast.showToast(msg: '网络异常'); }, buildWhen: (prev, current) { if (current is LoginErrorState) { return false; } /// 登录失败 if (current is LoginThirdLoginErrorState) { return false; } /// 登录成功 if (current is LoginThirdLoginSuccessState) { // 需要绑定手机号 if (current.model.bindPhoneEnable == '1') { // 打开绑定手机号页面 _jumpBindPhonePage(current.thirdType); } else { // 更新登录数据 Provider.of(context, listen: false)?.setUserInfo(current.model); // 直接打开首页 _jumpHomePage(); Fluttertoast.showToast(msg: '登录成功~'); } return false; } return true; }, builder: (context, state) { if (state is LoginCacheState) { return _getMainWidget(state.model); } if (state is LoginLoadedState) { return _getMainWidget(state.model); } return LoginPageSkeleton(); // 骨架屏幕 }, ); } /// 主视图 Widget _getMainWidget(LoginStyleModel model) { return Column( children: [ /// 头部 _headWidget(model), _sizedHeight50, /// 按钮 _buttonsWidget(model), _sizedHeight9, ///账号密码登录 _buildOrderLogin(), _sizedHeight9, /// 协议 _protocolWidget(model), /// 其它登陆方式 _otherLoginWidget(model), ], ); } /// 头部Widget Widget _headWidget(LoginStyleModel model) { return Container( height: 228 + MediaQuery.of(context).padding.top, width: double.infinity, decoration: BoxDecoration( image: DecorationImage( image: CachedNetworkImageProvider(model?.main?.backgroundImg ?? ''), fit: BoxFit.fill, ), ), child: Stack( alignment: Alignment.center, children: [ AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( icon: Icon( Icons.arrow_back_ios, size: 22, color: HexColor.fromHex('#333333'), ), onPressed: () => Navigator.maybePop(context), ), ), Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ /// logo Container( margin: EdgeInsets.only(bottom: 12, top: MediaQuery.of(context).padding.top), decoration: BoxDecoration( borderRadius: BorderRadius.circular(14), boxShadow: [ BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 10.0, spreadRadius: 1.0), BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)), ], ), height: 80, width: 80, child: CachedNetworkImage(imageUrl: model?.logoImg ?? ''), ), /// logo 名字 // CachedNetworkImage( // imageUrl: model?.main?.appNameImg ?? '', // width: 90, // ), Container( margin: EdgeInsets.only(top: 0, bottom: 6), child: Center( child: Text( model?.main?.appName ?? "", style: TextStyle(color: HexColor.fromHex("#FF333333"), fontSize: 20,fontWeight: FontWeight.bold), )), ) ], ), ], ), ); } /// 按钮 Widget _buttonsWidget(LoginStyleModel model) { return Container( padding: const EdgeInsets.symmetric(horizontal: 27.5), child: Column( children: model.main.importanceLogin.map((item) { if(item?.type=="mobile"){ loginStyleModel=model; } return Padding( padding: const EdgeInsets.only(bottom: 8), child: _customButton( height: 40, text: item?.btnText, iconUrl: item?.btnMobileIcon ?? '', textColor: item?.btnTextColor, bgColor: item?.btnBgColor, borderColor: item?.btnBorderColor, onTap: () => _loginClick(item?.type, model)), ); }).toList(), ), ); } /// 协议 Widget _protocolWidget(LoginStyleModel model) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ InkWell( borderRadius: BorderRadius.circular(20), onTap: () { checkBool = !checkBool; setState(() {}); }, child: Container( width: 32, height: 32, child: Icon( checkBool ? Icons.check_box : Icons.check_box_outline_blank, size: 16, color: checkBool ? Colors.red : Colors.black12, ), ), ), RichText( text: TextSpan( text: '', children: model.main.agreements.map((item) { return TextSpan( text: item?.text, style: TextStyle(color: HexColor.fromHex(item?.textColor), fontSize: 10), recognizer: TapGestureRecognizer() ..onTap = () { _jumpUserAgreement(item?.url); }); }).toList()), ), ], ); } /// 其它登陆方式 Widget _otherLoginWidget(LoginStyleModel model) { return Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ _getOtherLoginTitle(model), _sizedHeight18, Visibility(visible: _showOther, child: _getOtherLoginIcons(model)), Visibility(visible: _showOther, child: _sizedHeight21), ], ), ); } /// 其它登陆方式的title Widget _getOtherLoginTitle(LoginStyleModel model) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => _showOrCloseOtherLogin(), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text('${model?.main?.otherIconsTitle}', style: TextStyle(fontSize: 13, color: HexColor.fromHex(model?.main?.otherIconsTitleColor))), SizedBox(width: 5.5), RotatedBox( quarterTurns: _showOther ? 0 : 2, child: CachedNetworkImage(imageUrl: model?.main?.otherExpansionIcon ?? '', width: 12), ), ], ), ); } /// 其它登陆方式的按钮 Widget _getOtherLoginIcons(LoginStyleModel model) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: model.main.bottomIcons.map((item) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => _otherLoginClick(item), child: Container( width: 30, margin: const EdgeInsets.symmetric(horizontal: 20), child: CachedNetworkImage(imageUrl: item?.img ?? ''), ), ); }).toList(), ); } /// 自定义按钮 Widget _customButton({double height, String text, String iconUrl, String textColor, String bgColor, String borderColor, GestureTapCallback onTap}) { return GestureDetector( onTap: onTap, child: Container( width: double.infinity, height: height ?? 0, decoration: BoxDecoration( border: Border.all(color: HexColor.fromHex(borderColor), width: 0.5), borderRadius: BorderRadius.circular(height ?? 0 / 2), color: HexColor.fromHex(bgColor), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ // icon CachedNetworkImage(imageUrl: iconUrl, width: 12), SizedBox(width: 8), // text Text(text, style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 15)) ], ), ), ); } ///账号密码登录 update:与手机一键登录互换 _buildOrderLogin() { return Center( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (isCheck()) { //Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null))); MobUtil.openQuickLoginPage(context, loginStyleModel?.quick); } }, child: Text( "本机一键登录", style: TextStyle(color: HexColor.fromHex("#FFFF4242"), fontSize: 14), ), ), ); } bool isCheck() { if (!checkBool) { Fluttertoast.showToast(msg: "请阅读并勾选同意用户协议选项"); return false; } else { return true; } } }