@@ -10,20 +10,22 @@ class UserInfoModel { | |||||
String username; | String username; | ||||
List<String> perms; | List<String> perms; | ||||
String registerInviteCodeEnable; | String registerInviteCodeEnable; | ||||
String bindPhoneEnable; | |||||
bool isTBAuth; // 是否淘宝授权 | bool isTBAuth; // 是否淘宝授权 | ||||
// 获取模糊手机号码 | // 获取模糊手机号码 | ||||
get blurMobile => !EmptyUtil.isEmpty(mobile) ? mobile.length == 11 ? '${mobile.substring(0, 3)}****${mobile.substring(7, mobile.length)}' : mobile : mobile; | get blurMobile => !EmptyUtil.isEmpty(mobile) ? mobile.length == 11 ? '${mobile.substring(0, 3)}****${mobile.substring(7, mobile.length)}' : mobile : mobile; | ||||
UserInfoModel({this.token, this.userId, this.username, this.perms, this.registerInviteCodeEnable, this.isTBAuth = false}); | |||||
UserInfoModel({this.token, this.userId, this.username, this.perms, this.registerInviteCodeEnable, this.isTBAuth = false, this.bindPhoneEnable}); | |||||
UserInfoModel.fromJson(Map<String, dynamic> json) { | UserInfoModel.fromJson(Map<String, dynamic> json) { | ||||
token = json['token']; | token = json['token']; | ||||
userId = json['user_id']; | userId = json['user_id']; | ||||
username = json['username']; | username = json['username']; | ||||
mobile = json['mobile']; | mobile = json['mobile']; | ||||
perms = json['perms']?.cast<String>(); | |||||
registerInviteCodeEnable = json['register_invite_code_enable']; | registerInviteCodeEnable = json['register_invite_code_enable']; | ||||
bindPhoneEnable= json['bind_phone_enable']; | |||||
perms = json['perms']?.cast<String>(); | |||||
isTBAuth = json['isTBAuth'] ?? false; | isTBAuth = json['isTBAuth'] ?? false; | ||||
} | } | ||||
@@ -35,6 +37,7 @@ class UserInfoModel { | |||||
data['perms'] = this.perms; | data['perms'] = this.perms; | ||||
data['mobile'] = this.mobile; | data['mobile'] = this.mobile; | ||||
data['register_invite_code_enable'] = this.registerInviteCodeEnable; | data['register_invite_code_enable'] = this.registerInviteCodeEnable; | ||||
data['bind_phone_enable'] = this.bindPhoneEnable; | |||||
data['isTBAuth'] = this.isTBAuth; | data['isTBAuth'] = this.isTBAuth; | ||||
return data; | return data; | ||||
} | } | ||||
@@ -1,6 +1,7 @@ | |||||
import 'dart:convert'; | import 'dart:convert'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter_alibc/flutter_alibc.dart'; | |||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | import 'package:zhiying_comm/models/user/user_info_model.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
import 'package:zhiying_comm/util/log/let_log.dart'; | import 'package:zhiying_comm/util/log/let_log.dart'; | ||||
@@ -71,6 +72,8 @@ class UserInfoNotifier with ChangeNotifier { | |||||
GlobalConfig.SHARED_KEY_MOBILE, ''); | GlobalConfig.SHARED_KEY_MOBILE, ''); | ||||
await SharedPreferencesUtil.setStringValue( | await SharedPreferencesUtil.setStringValue( | ||||
GlobalConfig.SHARED_KEY_USER_INFO, ''); | GlobalConfig.SHARED_KEY_USER_INFO, ''); | ||||
// 退出淘宝登录 | |||||
FlutterAlibc.loginOut(); | |||||
notifyListeners(); | notifyListeners(); | ||||
} | } | ||||
@@ -1,13 +1,12 @@ | |||||
import 'dart:math'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | ||||
import 'package:zhiying_comm/util/net_util.dart'; | import 'package:zhiying_comm/util/net_util.dart'; | ||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | import 'package:zhiying_comm/models/user/user_info_model.dart'; | ||||
import '../../login_util.dart'; | |||||
import '../../login_style_util.dart'; | |||||
import 'bloc.dart'; | import 'bloc.dart'; | ||||
/// | /// | ||||
@@ -15,8 +14,8 @@ import 'bloc.dart'; | |||||
/// | /// | ||||
class LoginAccountRepository { | class LoginAccountRepository { | ||||
/// 获取数据,如果缓存有,则获取缓存的数据 | /// 获取数据,如果缓存有,则获取缓存的数据 | ||||
Future<LoginModel> fetchData() async { | |||||
var result = await LoginUtil.getLoginModel(); | |||||
Future<LoginStyleModel> fetchData() async { | |||||
var result = await LoginStyleUtil.getLoginModel(); | |||||
if (!EmptyUtil.isEmpty(result)) { | if (!EmptyUtil.isEmpty(result)) { | ||||
return result; | return result; | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | import 'package:zhiying_comm/models/user/user_info_model.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
abstract class LoginAccountState extends Equatable { | abstract class LoginAccountState extends Equatable { | ||||
const LoginAccountState(); | const LoginAccountState(); | ||||
@@ -15,7 +15,7 @@ class LoginAccountInitial extends LoginAccountState {} | |||||
/// 数据加载完毕状态 | /// 数据加载完毕状态 | ||||
class LoginAccountLoadedState extends LoginAccountState { | class LoginAccountLoadedState extends LoginAccountState { | ||||
final LoginModel model; | |||||
final LoginStyleModel model; | |||||
const LoginAccountLoadedState({@required this.model}); | const LoginAccountLoadedState({@required this.model}); | ||||
@@ -55,7 +55,11 @@ class LoginAccountLoginSuccessState extends LoginAccountState { | |||||
/// 登陆失败 | /// 登陆失败 | ||||
class LoginAccountLoginErrorState extends LoginAccountState { | class LoginAccountLoginErrorState extends LoginAccountState { | ||||
final String msg; | |||||
@override | |||||
bool operator ==(Object other) { | |||||
return false; | |||||
} | |||||
const LoginAccountLoginErrorState({this.msg}); | |||||
} | |||||
@override | |||||
int get hashCode => super.hashCode; | |||||
} |
@@ -5,7 +5,7 @@ import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/invite/login_invite_page.dart'; | import 'package:zhiying_comm/pages/login_page/invite/login_invite_page.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'bloc/bloc.dart'; | import 'bloc/bloc.dart'; | ||||
import 'bloc/login_account_repository.dart'; | import 'bloc/login_account_repository.dart'; | ||||
@@ -52,6 +52,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
FocusNode _phoneFN; | FocusNode _phoneFN; | ||||
FocusNode _passFN; | FocusNode _passFN; | ||||
FocusNode _vcodeFN; | FocusNode _vcodeFN; | ||||
// 是否登录中 | // 是否登录中 | ||||
bool _isLogging = false; | bool _isLogging = false; | ||||
@@ -88,11 +89,13 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
_isLogging = true; | _isLogging = true; | ||||
}); | }); | ||||
if (_useVcode) { | if (_useVcode) { | ||||
BlocProvider.of<LoginAccountBloc>(context).add(LoginAccountTypeVcodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '', captcha: _vcodeEdController?.text?.toString()?.trim() ?? '')); | |||||
BlocProvider.of<LoginAccountBloc>(context) | |||||
.add(LoginAccountTypeVcodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '', captcha: _vcodeEdController?.text?.toString()?.trim() ?? '')); | |||||
} else { | } else { | ||||
BlocProvider.of<LoginAccountBloc>(context).add(LoginAccountTypePasswordEvent(username: _phoneEdController?.text?.toString()?.trim() ?? '', password: _passEdController?.text?.toString()?.trim() ?? '')); | |||||
BlocProvider.of<LoginAccountBloc>(context) | |||||
.add(LoginAccountTypePasswordEvent(username: _phoneEdController?.text?.toString()?.trim() ?? '', password: _passEdController?.text?.toString()?.trim() ?? '')); | |||||
} | } | ||||
}else{ | |||||
} else { | |||||
Logger.log('参数有误 或者 正在登录中。。。'); | Logger.log('参数有误 或者 正在登录中。。。'); | ||||
} | } | ||||
} | } | ||||
@@ -277,6 +280,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
Provider.of<UserInfoNotifier>(context, listen: false)?.setUserInfo(current.model); | Provider.of<UserInfoNotifier>(context, listen: false)?.setUserInfo(current.model); | ||||
if (current?.model?.registerInviteCodeEnable != '1') { | if (current?.model?.registerInviteCodeEnable != '1') { | ||||
Fluttertoast.showToast(msg: '登录成功~'); | Fluttertoast.showToast(msg: '登录成功~'); | ||||
_isLogging = true; | |||||
/// 打开也买 | /// 打开也买 | ||||
_openLoginSuccessPage(); | _openLoginSuccessPage(); | ||||
@@ -310,7 +314,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 主页面 | /// 主页面 | ||||
Widget _getMainWidget(LoginModel model) { | |||||
Widget _getMainWidget(LoginStyleModel model) { | |||||
print(model); | print(model); | ||||
return Column( | return Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
@@ -348,7 +352,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// appBar | /// appBar | ||||
Widget _getAppBarWidget(LoginModel model) { | |||||
Widget _getAppBarWidget(LoginStyleModel model) { | |||||
return AppBar( | return AppBar( | ||||
backgroundColor: HexColor.fromHex('#FFFFFF'), | backgroundColor: HexColor.fromHex('#FFFFFF'), | ||||
brightness: Brightness.light, | brightness: Brightness.light, | ||||
@@ -370,7 +374,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// title | /// title | ||||
Widget _getTitleWidget(LoginModel model) { | |||||
Widget _getTitleWidget(LoginStyleModel model) { | |||||
return Align( | return Align( | ||||
alignment: Alignment.centerLeft, | alignment: Alignment.centerLeft, | ||||
child: Text( | child: Text( | ||||
@@ -380,7 +384,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 手机输入框 | /// 手机输入框 | ||||
Widget _getPhoneWidget(LoginModel model) { | |||||
Widget _getPhoneWidget(LoginStyleModel model) { | |||||
return _getCustomInputWidget( | return _getCustomInputWidget( | ||||
hint: model?.mobile?.inputMobileHintText ?? '请输入您的手机号', | hint: model?.mobile?.inputMobileHintText ?? '请输入您的手机号', | ||||
controller: _phoneEdController, | controller: _phoneEdController, | ||||
@@ -393,7 +397,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 验证码输入框 | /// 验证码输入框 | ||||
Widget _getVcodeWidget(LoginModel model) { | |||||
Widget _getVcodeWidget(LoginStyleModel model) { | |||||
return Container( | return Container( | ||||
height: 42, | height: 42, | ||||
child: Stack( | child: Stack( | ||||
@@ -414,7 +418,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 验证码按钮 | /// 验证码按钮 | ||||
Widget _getVcodeButtonWidget(LoginModel model) { | |||||
Widget _getVcodeButtonWidget(LoginStyleModel model) { | |||||
return VcodeWidget( | return VcodeWidget( | ||||
onCallBack: this, | onCallBack: this, | ||||
awaitTime: int.parse(model?.mobile?.vcodeTime ?? '60'), | awaitTime: int.parse(model?.mobile?.vcodeTime ?? '60'), | ||||
@@ -458,11 +462,11 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 密码输入框 | /// 密码输入框 | ||||
Widget _getPassInputWidget(LoginModel model) { | |||||
Widget _getPassInputWidget(LoginStyleModel model) { | |||||
return Container( | return Container( | ||||
height: 42, | height: 42, | ||||
child: _getCustomInputWidget( | child: _getCustomInputWidget( | ||||
obscureText: true, | |||||
obscureText: true, | |||||
keyboardType: TextInputType.text, | keyboardType: TextInputType.text, | ||||
controller: _passEdController, | controller: _passEdController, | ||||
focusNode: _passFN, | focusNode: _passFN, | ||||
@@ -476,7 +480,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 切换登陆方式tip | /// 切换登陆方式tip | ||||
Widget _getChangeTipWidget(LoginModel model) { | |||||
Widget _getChangeTipWidget(LoginStyleModel model) { | |||||
return GestureDetector( | return GestureDetector( | ||||
behavior: HitTestBehavior.opaque, | behavior: HitTestBehavior.opaque, | ||||
onTap: () => _changeLoginTypeOnClick(), | onTap: () => _changeLoginTypeOnClick(), | ||||
@@ -488,7 +492,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 登陆按钮 | /// 登陆按钮 | ||||
Widget _getSubmiBtnWidget(LoginModel model) { | |||||
Widget _getSubmiBtnWidget(LoginStyleModel model) { | |||||
return Material( | return Material( | ||||
child: Container( | child: Container( | ||||
height: 52, | height: 52, | ||||
@@ -512,7 +516,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 协议 | /// 协议 | ||||
Widget _getProtoclWidget(LoginModel model) { | |||||
Widget _getProtoclWidget(LoginStyleModel model) { | |||||
// return Text('同意《嗨如意用户协议》 及《营私政策》', style: TextStyle(fontSize: 11, color: HexColor.fromHex('#C0C0C0'))); | // return Text('同意《嗨如意用户协议》 及《营私政策》', style: TextStyle(fontSize: 11, color: HexColor.fromHex('#C0C0C0'))); | ||||
return Row( | return Row( | ||||
mainAxisAlignment: MainAxisAlignment.center, | mainAxisAlignment: MainAxisAlignment.center, | ||||
@@ -547,7 +551,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
} | } | ||||
/// 底部提示tip | /// 底部提示tip | ||||
Widget _getBottomTipWidget(LoginModel model) { | |||||
Widget _getBottomTipWidget(LoginStyleModel model) { | |||||
return Padding( | return Padding( | ||||
padding: const EdgeInsets.only(bottom: 25), | padding: const EdgeInsets.only(bottom: 25), | ||||
child: Text( | child: Text( | ||||
@@ -596,7 +600,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||||
expands: false, | expands: false, | ||||
style: TextStyle(color: HexColor.fromHex(textColor)), | style: TextStyle(color: HexColor.fromHex(textColor)), | ||||
maxLines: 1, | maxLines: 1, | ||||
keyboardType: keyboardType ?? TextInputType.number, | |||||
keyboardType: keyboardType ?? TextInputType.number, | |||||
decoration: InputDecoration( | decoration: InputDecoration( | ||||
contentPadding: EdgeInsets.only(top: 30, left: 7.5), | contentPadding: EdgeInsets.only(top: 30, left: 7.5), | ||||
hintText: hint, | hintText: hint, | ||||
@@ -0,0 +1,4 @@ | |||||
export 'login_bind_phone_state.dart'; | |||||
export 'login_bind_phone_event.dart'; | |||||
export 'login_bind_phone_repository.dart'; | |||||
export 'login_bind_phone_bloc.dart'; |
@@ -0,0 +1,59 @@ | |||||
import 'dart:async'; | |||||
import 'package:bloc/bloc.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import './bloc.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | |||||
class LoginBindPhoneBloc extends Bloc<LoginBindPhoneEvent, LoginBindPhoneState> { | |||||
LoginBindPhoneRepository repository; | |||||
LoginBindPhoneBloc({@required this.repository}); | |||||
@override | |||||
LoginBindPhoneState get initialState => LoginBindPhoneInitial(); | |||||
@override | |||||
Stream<LoginBindPhoneState> mapEventToState(LoginBindPhoneEvent event) async* { | |||||
/// 获取数据 | |||||
if (event is LoginBindPhoneInitEvent) { | |||||
yield* _mapInitEventToState(); | |||||
} | |||||
/// 获取验证码 | |||||
if (event is LoginBindPhoneGetVCodeEvent) { | |||||
yield* _mapGetVcodeEventToState(event); | |||||
} | |||||
/// 登陆(验证码) | |||||
if (event is LoginBindPhoneTypeVCodeEvent) { | |||||
yield* _mapLoginTypeVcodeEventToState(event); | |||||
} | |||||
} | |||||
/// 获取数据 | |||||
Stream<LoginBindPhoneState> _mapInitEventToState() async* { | |||||
var data = await repository.fetchData(); | |||||
if (!EmptyUtil.isEmpty(data)) | |||||
yield LoginBindPhoneLoadedState(model: data); | |||||
else | |||||
yield LoginBindPhoneErrorState(); | |||||
} | |||||
/// 获取验证码 | |||||
Stream<LoginBindPhoneState> _mapGetVcodeEventToState(LoginBindPhoneGetVCodeEvent event) async* { | |||||
bool result = await repository.fetchGetVcode(event); | |||||
if (result) | |||||
yield LoginBindPhoneGetVCodeSuccessState(); | |||||
else | |||||
yield LoginBindPhoneGetVCodeErrorState(); | |||||
} | |||||
/// 验证码登陆 | |||||
Stream<LoginBindPhoneState> _mapLoginTypeVcodeEventToState(LoginBindPhoneTypeVCodeEvent event) async* { | |||||
var result = await repository.loginTypeVCode(event); | |||||
if (!EmptyUtil.isEmpty(result)) | |||||
yield LoginBindPhoneLoginSuccessState(model: result); | |||||
else | |||||
yield LoginBindPhoneLoginErrorState(); | |||||
} | |||||
} |
@@ -0,0 +1,47 @@ | |||||
import 'package:equatable/equatable.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
abstract class LoginBindPhoneEvent extends Equatable { | |||||
const LoginBindPhoneEvent(); | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 初始化事件 | |||||
class LoginBindPhoneInitEvent extends LoginBindPhoneEvent {} | |||||
/// 获取验证码 | |||||
class LoginBindPhoneGetVCodeEvent extends LoginBindPhoneEvent { | |||||
final String mobile; | |||||
const LoginBindPhoneGetVCodeEvent({@required this.mobile}); | |||||
@override | |||||
List<Object> get props => [mobile]; | |||||
} | |||||
/// 核对验证码 | |||||
class LoginBindPhoneCheckVCodeEvent extends LoginBindPhoneEvent { | |||||
/// 手机号码 | |||||
final String mobile; | |||||
/// 验证码 | |||||
final String captcha; | |||||
const LoginBindPhoneCheckVCodeEvent({@required this.mobile, @required this.captcha}); | |||||
@override | |||||
List<Object> get props => [this.mobile, this.captcha]; | |||||
} | |||||
/// 登陆事件(验证码登陆) | |||||
class LoginBindPhoneTypeVCodeEvent extends LoginBindPhoneEvent { | |||||
final String mobile; | |||||
final String captcha; | |||||
const LoginBindPhoneTypeVCodeEvent({@required this.mobile, @required this.captcha}); | |||||
@override | |||||
List<Object> get props => [this.mobile, this.captcha]; | |||||
} |
@@ -0,0 +1,77 @@ | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | |||||
import 'package:zhiying_comm/util/global_config.dart'; | |||||
import 'package:zhiying_comm/util/log/let_log.dart'; | |||||
import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | |||||
import 'package:zhiying_comm/util/net_util.dart'; | |||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | |||||
import '../../login_style_util.dart'; | |||||
import 'bloc.dart'; | |||||
/// | |||||
/// 账户登陆 | |||||
/// | |||||
class LoginBindPhoneRepository { | |||||
final Map<String, dynamic> data; | |||||
LoginBindPhoneRepository(this.data); | |||||
/// 获取数据,如果缓存有,则获取缓存的数据 | |||||
Future<LoginStyleModel> fetchData() async { | |||||
var result = await LoginStyleUtil.getLoginModel(); | |||||
if (!EmptyUtil.isEmpty(result)) { | |||||
return result; | |||||
} | |||||
return null; | |||||
} | |||||
/// 获取验证码 | |||||
Future<bool> fetchGetVcode(LoginBindPhoneGetVCodeEvent event) async { | |||||
print('mobile = ${event.mobile}'); | |||||
var result = await MobUtil.getTextCode(event?.mobile, smsCodeType: SMSCodeType.AUTO); | |||||
return result; | |||||
} | |||||
/// 验证码登陆 | |||||
Future<UserInfoModel> loginTypeVCode(LoginBindPhoneTypeVCodeEvent event) async { | |||||
try { | |||||
String third = data['thirdType']; | |||||
if (EmptyUtil.isEmpty(third)) return null; | |||||
/// 请求参数 | |||||
Map<String, dynamic> params = {}; | |||||
params['mobile'] = event.mobile; | |||||
params['zone'] = '86'; | |||||
params['captcha'] = event.captcha; | |||||
/// 淘宝登录 | |||||
if (GlobalConfig.LOGIN_THIRD_ALI == third) { | |||||
Map<String, String> taobaoParam = {}; | |||||
taobaoParam['nick_name'] = data['nick']; | |||||
taobaoParam['avatar_url'] = data['avatarUrl']; | |||||
taobaoParam['open_id'] = data['openId']; | |||||
taobaoParam['sid'] = data['openSid']; | |||||
taobaoParam['access_token'] = data['topAccessToken']; | |||||
taobaoParam['auth_code'] = data['topAuthCode']; | |||||
params['taobao'] = taobaoParam; | |||||
} | |||||
/// 苹果登录 | |||||
if(GlobalConfig.LOGIN_THIRD_APPLE == third){ | |||||
} | |||||
var result = await NetUtil.post('/api/v1/sign/fast/in', params: params); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
UserInfoModel loginUser = UserInfoModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
if (null != loginUser) { | |||||
loginUser.mobile = event.mobile; | |||||
return loginUser; | |||||
} | |||||
} | |||||
} catch (e, s) { | |||||
Logger.error(e, s); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,54 @@ | |||||
import 'package:equatable/equatable.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
abstract class LoginBindPhoneState extends Equatable { | |||||
const LoginBindPhoneState(); | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 初始化状态 | |||||
class LoginBindPhoneInitial extends LoginBindPhoneState {} | |||||
/// 数据加载完毕状态 | |||||
class LoginBindPhoneLoadedState extends LoginBindPhoneState { | |||||
final LoginStyleModel model; | |||||
const LoginBindPhoneLoadedState({@required this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 数据加载出错状态 | |||||
class LoginBindPhoneErrorState extends LoginBindPhoneState {} | |||||
/// 验证码下发成功的状态 | |||||
class LoginBindPhoneGetVCodeSuccessState extends LoginBindPhoneState {} | |||||
/// 验证码下发失败的状态 | |||||
class LoginBindPhoneGetVCodeErrorState extends LoginBindPhoneState {} | |||||
/// 登陆成功 | |||||
class LoginBindPhoneLoginSuccessState extends LoginBindPhoneState { | |||||
final UserInfoModel model; | |||||
const LoginBindPhoneLoginSuccessState({@required this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 登陆失败 | |||||
class LoginBindPhoneLoginErrorState extends LoginBindPhoneState { | |||||
@override | |||||
bool operator ==(Object other) { | |||||
return false; | |||||
} | |||||
@override | |||||
int get hashCode => super.hashCode; | |||||
} |
@@ -0,0 +1,555 @@ | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/gestures.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||||
import 'package:provider/provider.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/account/widget/slide_verify_widget.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/account/widget/vcode_widget.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/invite/login_invite_page.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'bloc/bloc.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | |||||
import 'package:fluttertoast/fluttertoast.dart'; | |||||
import 'login_bind_phone_sk.dart'; | |||||
/// | |||||
/// 账号登陆(手机验证码,密码) | |||||
/// | |||||
class LoginBindPhonePage extends StatelessWidget { | |||||
/// | |||||
/// 这里面model 需要带上 thirdType key,作为第三方登录的类型。 | |||||
/// | |||||
final Map<String, dynamic> model; | |||||
const LoginBindPhonePage(this.model, {Key key}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Scaffold( | |||||
resizeToAvoidBottomInset: false, | |||||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||||
body: BlocProvider<LoginBindPhoneBloc>( | |||||
create: (_) => LoginBindPhoneBloc(repository: LoginBindPhoneRepository(model))..add(LoginBindPhoneInitEvent()), | |||||
child: _LoginBindPhonePageContainer(), | |||||
), | |||||
); | |||||
} | |||||
} | |||||
/// 啦啦啦 | |||||
class _LoginBindPhonePageContainer extends StatefulWidget { | |||||
@override | |||||
_LoginBindPhonePageContainerState createState() => _LoginBindPhonePageContainerState(); | |||||
} | |||||
/// | |||||
/// 主体逻辑 | |||||
/// | |||||
class _LoginBindPhonePageContainerState extends State<_LoginBindPhonePageContainer> implements OnClickListener { | |||||
TextEditingController _phoneEdController; | |||||
TextEditingController _vcodeEdController; | |||||
TextEditingController _passEdController; | |||||
FocusNode _phoneFN; | |||||
FocusNode _passFN; | |||||
FocusNode _vcodeFN; | |||||
// 是否登录中 | |||||
bool _isLogging = false; | |||||
/// 跳转到邀请码页面 | |||||
void _openInvitePage() { | |||||
print('跳转到邀请码页面'); | |||||
RouterUtil.hideKeyboard(context); | |||||
Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginInvitePage())); | |||||
} | |||||
/// 登陆成功页面 | |||||
void _openLoginSuccessPage() { | |||||
RouterUtil.hideKeyboard(context); | |||||
RouterUtil.goBackHomePage(context); | |||||
} | |||||
/// 返回上一页 | |||||
void _openPop() { | |||||
if (Navigator.canPop(context)) { | |||||
Navigator.pop(context); | |||||
} | |||||
} | |||||
/// 登陆 | |||||
void _submitOnClick() { | |||||
print('登陆'); | |||||
if (_checkParam(true) && !_isLogging) { | |||||
setState(() { | |||||
_isLogging = true; | |||||
}); | |||||
BlocProvider.of<LoginBindPhoneBloc>(context) | |||||
.add(LoginBindPhoneTypeVCodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '', captcha: _vcodeEdController?.text?.toString()?.trim() ?? '')); | |||||
} else { | |||||
Logger.log('参数有误 或者 正在登录中。。。'); | |||||
} | |||||
} | |||||
/// 同意协议 | |||||
void _agreeOnClick() { | |||||
print('同意协议'); | |||||
setState(() { | |||||
_acceptAgreement = !_acceptAgreement; | |||||
}); | |||||
_checkParam(false); | |||||
} | |||||
/// 打开协议 | |||||
void _openAgreement(String url) { | |||||
if (!EmptyUtil.isEmpty(url)) { | |||||
print('打开协议$url'); | |||||
RouterUtil.openWebview(url, context); | |||||
} | |||||
} | |||||
/// 输入框监听 | |||||
void _onChange(string) { | |||||
print('$string'); | |||||
_checkParam(false); | |||||
} | |||||
/// 校验登陆参数 | |||||
bool _checkParam(bool needToast) { | |||||
// 验证码 | |||||
String phone = _phoneEdController?.text?.toString()?.trim() ?? null; | |||||
String vCode = _vcodeEdController?.text?.toString()?.trim() ?? null; | |||||
if (EmptyUtil.isEmpty(phone)) { | |||||
if (needToast) Fluttertoast.showToast(msg: '手机号不能为空!'); | |||||
return false; | |||||
} | |||||
if (phone.length != 11) { | |||||
if (needToast) Fluttertoast.showToast(msg: '手机号格式有误!'); | |||||
return false; | |||||
} | |||||
if (EmptyUtil.isEmpty(vCode)) { | |||||
if (needToast) Fluttertoast.showToast(msg: '验证码不能为空!'); | |||||
return false; | |||||
} | |||||
if (vCode.length < 4) { | |||||
if (needToast) Fluttertoast.showToast(msg: '验证码号格式有误!'); | |||||
return false; | |||||
} | |||||
if (!_acceptAgreement) { | |||||
if (needToast) Fluttertoast.showToast(msg: '请同意用户协议与隐私政策'); | |||||
return false; | |||||
} | |||||
setState(() { | |||||
_canSubmit = true; | |||||
}); | |||||
return true; | |||||
} | |||||
/// 检测手机号是否合法 | |||||
bool _checkPhoneNumParam(bool needToast) { | |||||
String phone = _phoneEdController?.text?.toString()?.trim() ?? null; | |||||
if (EmptyUtil.isEmpty(phone)) { | |||||
if (needToast) Fluttertoast.showToast(msg: '手机号不能为空!'); | |||||
return false; | |||||
} | |||||
if (phone.length != 11) { | |||||
if (needToast) Fluttertoast.showToast(msg: '手机号格式有误!'); | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
/// 是否可以登陆 | |||||
bool _canSubmit = false; | |||||
/// 是否同意协议 | |||||
bool _acceptAgreement = true; | |||||
/// 是否显示第三方验证码 | |||||
bool _showOtherVcode = false; | |||||
@override | |||||
void initState() { | |||||
_phoneEdController = TextEditingController(); | |||||
_passEdController = TextEditingController(); | |||||
_vcodeEdController = TextEditingController(); | |||||
_vcodeFN = FocusNode(); | |||||
_passFN = FocusNode(); | |||||
_phoneFN = FocusNode(); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
void dispose() { | |||||
_phoneEdController?.dispose(); | |||||
_passEdController?.dispose(); | |||||
_vcodeEdController?.dispose(); | |||||
_phoneFN?.unfocus(); | |||||
_passFN?.unfocus(); | |||||
_vcodeFN?.unfocus(); | |||||
_phoneFN?.dispose(); | |||||
_passFN?.dispose(); | |||||
_vcodeFN?.dispose(); | |||||
super.dispose(); | |||||
} | |||||
@override | |||||
bool onVcodeClick() { | |||||
/// 获取验证码 | |||||
if (_checkPhoneNumParam(true)) { | |||||
BlocProvider.of<LoginBindPhoneBloc>(context).add(LoginBindPhoneGetVCodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '')); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocConsumer<LoginBindPhoneBloc, LoginBindPhoneState>( | |||||
listener: (context, state) { | |||||
if (state is LoginBindPhoneLoginSuccessState) {} | |||||
}, | |||||
buildWhen: (prev, current) { | |||||
// 登陆失败 | |||||
if (current is LoginBindPhoneLoginErrorState) { | |||||
// Fluttertoast.showToast(msg: '登陆失败'); | |||||
setState(() { | |||||
_isLogging = false; | |||||
}); | |||||
return false; | |||||
} | |||||
// 登陆成功 | |||||
if (current is LoginBindPhoneLoginSuccessState) { | |||||
/// 缓存登陆数据 | |||||
Provider.of<UserInfoNotifier>(context, listen: false)?.setUserInfo(current.model); | |||||
if (current?.model?.registerInviteCodeEnable != '1') { | |||||
Fluttertoast.showToast(msg: '登录成功~'); | |||||
_isLogging = true; | |||||
/// 打开也买 | |||||
_openLoginSuccessPage(); | |||||
} else { | |||||
/// 打开邀请页面 | |||||
_openInvitePage(); | |||||
} | |||||
return false; | |||||
} | |||||
// 获取验证码成功 | |||||
if (current is LoginBindPhoneGetVCodeSuccessState) { | |||||
Fluttertoast.showToast(msg: '验证码下发成功'); | |||||
return false; | |||||
} | |||||
// 获取验证码失败 | |||||
if (current is LoginBindPhoneGetVCodeErrorState) { | |||||
Fluttertoast.showToast(msg: '验证码获取失败~'); | |||||
return false; | |||||
} | |||||
return true; | |||||
}, | |||||
builder: (context, state) { | |||||
print('state = $state'); | |||||
if (state is LoginBindPhoneLoadedState) { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
// 返回骨架屏 | |||||
return LoginBindPhoneSkeleton(); | |||||
}, | |||||
); | |||||
} | |||||
/// 主页面 | |||||
Widget _getMainWidget(LoginStyleModel model) { | |||||
print(model); | |||||
return Column( | |||||
children: <Widget>[ | |||||
/// appBar | |||||
_getAppBarWidget(model), | |||||
/// title | |||||
Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 40), child: _getTitleWidget(model)), | |||||
/// 手机输入框 | |||||
Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30), child: _getPhoneWidget(model)), | |||||
/// 验证码 | |||||
Visibility(visible: true, child: Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 15), child: _getVCodeWidget(model))), | |||||
/// 第三方验证码 | |||||
Visibility(visible: _showOtherVcode, child: Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 15), child: _getOtherVcodeInputWidget(model))), | |||||
/// 登录按钮 | |||||
Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30), child: _getSubmitBtnWidget(model)), | |||||
/// 协议 | |||||
Padding(padding: const EdgeInsets.only(top: 15), child: _getProtoclWidget(model)), | |||||
/// 底部提示tip | |||||
Visibility(visible: false, child: Expanded(child: Align(alignment: Alignment.bottomCenter, child: _getBottomTipWidget(model)))) | |||||
], | |||||
); | |||||
} | |||||
/// appBar | |||||
Widget _getAppBarWidget(LoginStyleModel model) { | |||||
return AppBar( | |||||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||||
brightness: Brightness.light, | |||||
elevation: 0, | |||||
title: Text( | |||||
model?.mobile?.thirdPartyLoginAppBarTitle ?? '绑定手机号', | |||||
style: TextStyle(color: HexColor.fromHex(model?.mobile?.appBarTitleColor ?? '#333333')), | |||||
), | |||||
centerTitle: true, | |||||
leading: IconButton( | |||||
icon: Icon( | |||||
Icons.arrow_back_ios, | |||||
size: 22, | |||||
color: HexColor.fromHex('#333333'), | |||||
), | |||||
onPressed: () => _openPop(), | |||||
), | |||||
); | |||||
} | |||||
/// title | |||||
Widget _getTitleWidget(LoginStyleModel model) { | |||||
return Align( | |||||
alignment: Alignment.centerLeft, | |||||
child: Text( | |||||
model?.mobile?.thirdPartyLoginTitle ?? '绑定手机', | |||||
style: TextStyle(color: HexColor.fromHex(model?.mobile?.titleColor ?? '#333333'), fontSize: 25), | |||||
)); | |||||
} | |||||
/// 手机输入框 | |||||
Widget _getPhoneWidget(LoginStyleModel model) { | |||||
return _getCustomInputWidget( | |||||
hint: model?.mobile?.inputMobileHintText ?? '请输入您的手机号', | |||||
controller: _phoneEdController, | |||||
focusNode: _phoneFN, | |||||
onChanged: _onChange, | |||||
hintColor: model?.mobile?.inputHintColor ?? '#999999', | |||||
bgColor: model?.mobile?.inputBgColor ?? '#F7F7F7', | |||||
textColor: model?.mobile?.inputTextColor ?? '#333333', | |||||
iconUrl: model?.mobile?.inputMobileIcon ?? ''); | |||||
} | |||||
/// 验证码输入框 | |||||
Widget _getVCodeWidget(LoginStyleModel model) { | |||||
return Container( | |||||
height: 42, | |||||
child: Stack( | |||||
children: <Widget>[ | |||||
_getCustomInputWidget( | |||||
controller: _vcodeEdController, | |||||
focusNode: _vcodeFN, | |||||
onChanged: _onChange, | |||||
hintColor: model?.mobile?.inputHintColor ?? '#999999', | |||||
hint: model?.mobile?.inputVcodeHintText ?? '请输入您的验证码', | |||||
bgColor: model?.mobile?.inputBgColor ?? '#F7F7F7', | |||||
textColor: model?.mobile?.inputTextColor ?? '#333333', | |||||
iconUrl: model?.mobile?.inputVcodeIcon ?? ''), | |||||
Align(alignment: Alignment.centerRight, child: _getVcodeButtonWidget(model)), | |||||
], | |||||
), | |||||
); | |||||
} | |||||
/// 验证码按钮 | |||||
Widget _getVcodeButtonWidget(LoginStyleModel model) { | |||||
return VcodeWidget( | |||||
onCallBack: this, | |||||
awaitTime: int.parse(model?.mobile?.vcodeTime ?? '60'), | |||||
btnAwaitText: '秒', | |||||
btnText: '获取验证码', | |||||
btnTextColor: model?.mobile?.btnVcodeTextColor ?? '#FFFFFF', | |||||
color: model?.mobile?.btnVcodeBgColor ?? '#FF4343', | |||||
disabledColor: model?.mobile?.btnVcodeBanBgColor ?? '#DDDDDD', | |||||
disabledTextColor: model?.mobile?.btnVcodeBanTextColor ?? '#FFFFFF'); | |||||
} | |||||
/// 第三方验证码输入框 | |||||
Widget _getOtherVcodeInputWidget(var model) { | |||||
return Container( | |||||
width: 240, | |||||
height: 42, | |||||
alignment: Alignment.centerLeft, | |||||
child: SlideVerifyWidget( | |||||
width: 240, | |||||
), | |||||
// child: Row( | |||||
// children: <Widget>[ | |||||
// // 输入框 | |||||
// Expanded( | |||||
// child: _getCustomInputWidget(hint: '请输入右方验证码', hintColor: '#999999', textColor: '#333333', bgColor: '#F7F7F7', iconUrl: null, ) | |||||
// ), | |||||
// // 第三方验证码 | |||||
// Container( | |||||
// margin: const EdgeInsets.only(left: 5), | |||||
// width: 100, | |||||
// height: double.infinity, | |||||
// decoration: BoxDecoration( | |||||
// borderRadius: BorderRadius.circular(8), | |||||
// color: Colors.red | |||||
// ), | |||||
// ), | |||||
// | |||||
// ], | |||||
// ), | |||||
); | |||||
} | |||||
/// 密码输入框 | |||||
Widget _getPassInputWidget(LoginStyleModel model) { | |||||
return Container( | |||||
height: 42, | |||||
child: _getCustomInputWidget( | |||||
obscureText: true, | |||||
keyboardType: TextInputType.text, | |||||
controller: _passEdController, | |||||
focusNode: _passFN, | |||||
onChanged: _onChange, | |||||
hint: model?.mobile?.inputPassHintText ?? '请输入您的密码', | |||||
iconUrl: model?.mobile?.inputPassIcon ?? '', | |||||
hintColor: model?.mobile?.inputHintColor ?? '#999999', | |||||
textColor: model?.mobile?.inputTextColor ?? '#333333', | |||||
bgColor: model?.mobile?.inputBgColor ?? '#F7F7F7'), | |||||
); | |||||
} | |||||
/// 登陆按钮 | |||||
Widget _getSubmitBtnWidget(LoginStyleModel model) { | |||||
return Material( | |||||
child: Container( | |||||
height: 52, | |||||
width: double.infinity, | |||||
color: Colors.white, | |||||
child: RaisedButton( | |||||
child: Text( | |||||
_isLogging ? '登录中...' : model?.mobile?.btnLoginText ?? '立即登录', | |||||
style: TextStyle(fontSize: 15), | |||||
), | |||||
textColor: HexColor.fromHex(model?.mobile?.btnLoginTextColor ?? '#FFFFFF'), | |||||
color: HexColor.fromHex(model?.mobile?.btnLoginBgColor ?? '#FF3939'), | |||||
disabledColor: HexColor.fromHex(model?.mobile?.btnLoginBanBgColor ?? '#F5F5F5'), | |||||
disabledTextColor: HexColor.fromHex(model?.mobile?.btnLoginBanTextColor ?? '#999999'), | |||||
elevation: 5, | |||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(52 / 2)), | |||||
onPressed: _canSubmit ? _submitOnClick : null, | |||||
), | |||||
), | |||||
); | |||||
} | |||||
/// 协议 | |||||
Widget _getProtoclWidget(LoginStyleModel model) { | |||||
// return Text('同意《嗨如意用户协议》 及《营私政策》', style: TextStyle(fontSize: 11, color: HexColor.fromHex('#C0C0C0'))); | |||||
return Row( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
/// 图标 | |||||
GestureDetector( | |||||
behavior: HitTestBehavior.opaque, | |||||
onTap: () => _agreeOnClick(), | |||||
child: Padding( | |||||
padding: const EdgeInsets.all(8.0), | |||||
child: CachedNetworkImage( | |||||
imageUrl: _acceptAgreement ? model?.mobile?.protocolSelectIcon ?? '' : model?.mobile?.protocolUnselectIcon ?? '', | |||||
width: 12, | |||||
))), | |||||
/// 协议文字 | |||||
RichText( | |||||
text: TextSpan( | |||||
text: '', | |||||
children: model.mobile.protocol.map((item) { | |||||
return TextSpan( | |||||
text: item?.text, | |||||
style: TextStyle(color: HexColor.fromHex(item?.textColor), fontSize: 10), | |||||
recognizer: TapGestureRecognizer() | |||||
..onTap = () { | |||||
_openAgreement(item.url); | |||||
}); | |||||
}).toList()), | |||||
) | |||||
], | |||||
); | |||||
} | |||||
/// 底部提示tip | |||||
Widget _getBottomTipWidget(LoginStyleModel model) { | |||||
return Padding( | |||||
padding: const EdgeInsets.only(bottom: 25), | |||||
child: Text( | |||||
model?.mobile?.textBottomTip ?? '未注册过的手机将自动注册', | |||||
style: TextStyle(fontSize: 11, color: HexColor.fromHex(model?.mobile?.textBottomTipColor ?? '#999999')), | |||||
), | |||||
); | |||||
} | |||||
/// 自定义输入框 | |||||
Widget _getCustomInputWidget({ | |||||
String hint, | |||||
String hintColor, | |||||
String bgColor, | |||||
String textColor, | |||||
String iconUrl, | |||||
TextEditingController controller, | |||||
ValueChanged<String> onChanged, | |||||
FocusNode focusNode, | |||||
TextInputType keyboardType, | |||||
bool obscureText = false, | |||||
}) { | |||||
var border = OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide(color: HexColor.fromHex(bgColor), width: 0)); | |||||
return Container( | |||||
height: 42, | |||||
padding: const EdgeInsets.symmetric(horizontal: 15), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(bgColor), | |||||
borderRadius: BorderRadius.circular(8), | |||||
), | |||||
child: Row( | |||||
mainAxisAlignment: MainAxisAlignment.start, | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
children: <Widget>[ | |||||
CachedNetworkImage( | |||||
imageUrl: iconUrl ?? '', | |||||
width: 10, | |||||
), | |||||
Expanded( | |||||
child: TextField( | |||||
obscureText: obscureText ?? false, | |||||
controller: controller, | |||||
focusNode: focusNode, | |||||
onChanged: onChanged, | |||||
expands: false, | |||||
style: TextStyle(color: HexColor.fromHex(textColor)), | |||||
maxLines: 1, | |||||
keyboardType: keyboardType ?? TextInputType.number, | |||||
decoration: InputDecoration( | |||||
contentPadding: EdgeInsets.only(top: 30, left: 7.5), | |||||
hintText: hint, | |||||
hintStyle: TextStyle(fontSize: 13, color: HexColor.fromHex(hintColor)), | |||||
hintMaxLines: 1, | |||||
filled: true, | |||||
fillColor: Colors.transparent, | |||||
border: border, | |||||
focusedBorder: border, | |||||
enabledBorder: border, | |||||
disabledBorder: border, | |||||
errorBorder: border, | |||||
focusedErrorBorder: border, | |||||
), | |||||
), | |||||
), | |||||
], | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
import 'package:shimmer/shimmer.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_comm/util/extension/color.dart'; | |||||
/// | |||||
/// 绑定手机号骨架图 | |||||
/// | |||||
class LoginBindPhoneSkeleton extends StatelessWidget { | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Scaffold( | |||||
appBar: AppBar( | |||||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||||
elevation: 0, | |||||
title: Text( | |||||
'登录', | |||||
style: TextStyle(color: HexColor.fromHex('#333333')), | |||||
), | |||||
centerTitle: true, | |||||
leading: IconButton( | |||||
icon: Icon( | |||||
Icons.arrow_back_ios, | |||||
size: 22, | |||||
color: HexColor.fromHex('#333333'), | |||||
), | |||||
onPressed: () {}, | |||||
), | |||||
), | |||||
body: Container( | |||||
padding: const EdgeInsets.symmetric(horizontal: 27.5), | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
/// 标题 | |||||
Padding(padding: const EdgeInsets.only(top: 40), child: _shimmerWidget(width: 175, height: 20)), | |||||
Padding(padding: const EdgeInsets.only(top: 30), child: _shimmerWidget(width: 320, height: 42)), | |||||
Padding(padding: const EdgeInsets.only(top: 15), child: _shimmerWidget(width: 320, height: 42)), | |||||
Align(alignment: Alignment.center, child: Padding(padding: const EdgeInsets.only(top: 15), child: _shimmerWidget(width: 72, height: 13))), | |||||
Padding(padding: const EdgeInsets.only(top: 30), child: _shimmerWidget(width: 320, height: 52.7, radius: 30)), | |||||
Align(alignment: Alignment.center, child: Padding(padding: const EdgeInsets.only(top: 12.5), child: _shimmerWidget(width: 220, height: 15))), | |||||
Expanded(child: Align(alignment: Alignment.bottomCenter, child: Padding(padding: const EdgeInsets.only(bottom: 25), child: _shimmerWidget(width: 132, height: 15)))) | |||||
], | |||||
), | |||||
), | |||||
); | |||||
} | |||||
Widget _shimmerWidget({double width, double height, double radius = 0}) { | |||||
return Shimmer.fromColors( | |||||
baseColor: Colors.grey[300], | |||||
highlightColor: Colors.grey[100], | |||||
child: Container( | |||||
width: width, | |||||
height: height, | |||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)), | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
class LoginBindPhonUserModel { | |||||
String userId; | |||||
String nickname; | |||||
String appName; | |||||
String nickNameColor; | |||||
String appNameColor; | |||||
String avatar; | |||||
LoginBindPhonUserModel({this.userId, this.nickname, this.appName}); | |||||
LoginBindPhonUserModel.fromJson(Map<String, dynamic> json) { | |||||
userId = json['user_id']?.toString(); | |||||
nickname = json['nickname']?.toString(); | |||||
appName = json['app_name']?.toString(); | |||||
avatar = json['avatar']?.toString(); | |||||
appNameColor = json['app_name_color']?.toString(); | |||||
nickNameColor = json['nickname_color']?.toString(); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['user_id'] = this.userId; | |||||
data['nickname'] = this.nickname; | |||||
data['app_name'] = this.appName; | |||||
data['nickname_color'] = this.nickNameColor; | |||||
data['app_name_color'] = this.appNameColor; | |||||
data['avatar'] = this.avatar; | |||||
return data; | |||||
} | |||||
} |
@@ -1,5 +1,6 @@ | |||||
import 'dart:async'; | import 'dart:async'; | ||||
import 'package:bloc/bloc.dart'; | import 'package:bloc/bloc.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | |||||
import './bloc.dart'; | import './bloc.dart'; | ||||
import 'login_repository.dart'; | import 'login_repository.dart'; | ||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
@@ -16,23 +17,67 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | |||||
Stream<LoginState> mapEventToState( | Stream<LoginState> mapEventToState( | ||||
LoginEvent event, | LoginEvent event, | ||||
) async* { | ) async* { | ||||
// TODO: Add Logic | |||||
final currentState = state; | |||||
/// 初始化 | /// 初始化 | ||||
if (event is LoginInitEvent) { | if (event is LoginInitEvent) { | ||||
yield* _mapLoginInitEventToState(event); | yield* _mapLoginInitEventToState(event); | ||||
} | } | ||||
/// 淘宝登录 | |||||
if (event is LoginThirdAliEvent) { | |||||
yield* _mapLoginAliEventToState(event); | |||||
} | |||||
/// 苹果登录 | |||||
if (event is LoginThirdAppleEvent) { | |||||
yield* _mapLoginAppleEventToState(event); | |||||
} | |||||
/// QQ登录 | |||||
if (event is LoginThirdQQEvent) { | |||||
yield* _mapLoginQQEventToState(event); | |||||
} | |||||
/// 微信登录 | |||||
if (event is LoginThirdWeChatEvent) { | |||||
yield* _mapLoginWeChatEventToState(event); | |||||
} | |||||
} | } | ||||
/// 获取页面数据 | /// 获取页面数据 | ||||
Stream<LoginState> _mapLoginInitEventToState(LoginInitEvent event) async* { | Stream<LoginState> _mapLoginInitEventToState(LoginInitEvent event) async* { | ||||
var cache = await repository.fetchCachePageData(); | var cache = await repository.fetchCachePageData(); | ||||
if (!EmptyUtil.isEmpty(cache)) yield LoginCacheState( model: cache); | |||||
if (!EmptyUtil.isEmpty(cache)) yield LoginCacheState(model: cache); | |||||
var result = await repository.fetchNetPageData(); | var result = await repository.fetchNetPageData(); | ||||
if (!EmptyUtil.isEmpty(result)) | if (!EmptyUtil.isEmpty(result)) | ||||
yield LoginLoadedState(model: result); | yield LoginLoadedState(model: result); | ||||
else | else | ||||
yield LoginErrorState(); | yield LoginErrorState(); | ||||
} | } | ||||
/// 淘宝登录 | |||||
Stream<LoginState> _mapLoginAliEventToState(LoginThirdAliEvent event) async* { | |||||
var result = await repository.aliLogin( | |||||
nick: event.nick, | |||||
avatarUrl: event.avatarUrl, | |||||
openId: event.openId, | |||||
openSid: event.openSid, | |||||
topAccessToken: event.topAccessToken, | |||||
topAuthCode: event.topAuthCode, | |||||
); | |||||
if(!EmptyUtil.isEmpty(result)){ | |||||
yield LoginThirdLoginSuccessState(model: result, thirdType: GlobalConfig.LOGIN_THIRD_ALI); | |||||
}else{ | |||||
yield LoginThirdLoginErrorState(); | |||||
} | |||||
} | |||||
/// 微信登录 | |||||
Stream<LoginState> _mapLoginWeChatEventToState(LoginThirdWeChatEvent event) async* {} | |||||
/// QQ 登录 | |||||
Stream<LoginState> _mapLoginQQEventToState(LoginThirdQQEvent event) async* {} | |||||
/// 苹果登录 | |||||
Stream<LoginState> _mapLoginAppleEventToState(LoginThirdAppleEvent event) async* {} | |||||
} | } |
@@ -2,9 +2,37 @@ import 'package:equatable/equatable.dart'; | |||||
abstract class LoginEvent extends Equatable { | abstract class LoginEvent extends Equatable { | ||||
const LoginEvent(); | const LoginEvent(); | ||||
@override | @override | ||||
List<Object> get props => []; | List<Object> get props => []; | ||||
} | } | ||||
/// 初始化 | /// 初始化 | ||||
class LoginInitEvent extends LoginEvent{} | |||||
class LoginInitEvent extends LoginEvent {} | |||||
/// 第三方登录: 淘宝登录 | |||||
class LoginThirdAliEvent extends LoginEvent { | |||||
// 用户昵称 | |||||
final String nick; | |||||
// 头像地址 | |||||
final String avatarUrl; | |||||
final String openId; | |||||
final String openSid; | |||||
final String topAccessToken; | |||||
final String topAuthCode; | |||||
LoginThirdAliEvent({this.nick, this.avatarUrl, this.openId, this.openSid, this.topAccessToken, this.topAuthCode}); | |||||
@override | |||||
List<Object> get props => [this.nick, this.avatarUrl, this.openId, this.openSid, this.topAccessToken, this.topAuthCode]; | |||||
} | |||||
/// 第三方登录:苹果登录 | |||||
class LoginThirdAppleEvent extends LoginEvent {} | |||||
/// 第三方登录:微信登录 | |||||
class LoginThirdWeChatEvent extends LoginEvent {} | |||||
/// 第三方登录:QQ登录 | |||||
class LoginThirdQQEvent extends LoginEvent {} |
@@ -1,26 +1,59 @@ | |||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import '../login_util.dart'; | |||||
import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import '../login_style_util.dart'; | |||||
class LoginRepository { | class LoginRepository { | ||||
/// 获取页面数据 | /// 获取页面数据 | ||||
Future<LoginModel> fetchNetPageData() async { | |||||
// var result = await NetUtil.post('/api/v1/sign/in', method: NetMethod.GET, cache: true); | |||||
// if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
// LoginModel model = LoginModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
// return model; | |||||
// } | |||||
// return null; | |||||
return await LoginUtil.fetchNetPageData(); | |||||
Future<LoginStyleModel> fetchNetPageData() async { | |||||
return await LoginStyleUtil.fetchNetPageData(); | |||||
} | } | ||||
/// 获取缓存的页面数据 | /// 获取缓存的页面数据 | ||||
Future<LoginModel> fetchCachePageData() async { | |||||
// var result = await NetUtil.getRequestCachedData('/api/v1/sign/in'); | |||||
// if (!EmptyUtil.isEmpty(result)) { | |||||
// LoginModel model = LoginModel.fromJson(result); | |||||
// return model; | |||||
// } | |||||
// return null; | |||||
return await LoginUtil.fetchCachePageData(); | |||||
Future<LoginStyleModel> fetchCachePageData() async { | |||||
return await LoginStyleUtil.fetchCachePageData(); | |||||
} | |||||
/// 淘宝登录 | |||||
Future<UserInfoModel> aliLogin( | |||||
{@required final String nick, @required final String avatarUrl, @required final String openId, final String openSid, final String topAccessToken, final String topAuthCode}) async { | |||||
try { | |||||
Map<String, String> params = {}; | |||||
params['nick_name'] = nick; | |||||
params['avatar_url'] = avatarUrl; | |||||
params['open_id'] = openId; | |||||
params['access_token'] = topAccessToken; | |||||
params['sid'] = openSid; | |||||
params['auth_code'] = topAuthCode; | |||||
var result = await NetUtil.post( | |||||
'/api/v1/sign/fast/in', | |||||
queryParameters: {'third_party_login': 'taobao'}, | |||||
params: {'taobao': params}, | |||||
method: NetMethod.POST, | |||||
); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
return UserInfoModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
} | |||||
} catch (e, s) { | |||||
Logger.error(e, s); | |||||
} | |||||
return null; | |||||
} | |||||
/// 微信登录 | |||||
Future<UserInfoModel> weChatLogin() async { | |||||
return null; | |||||
} | |||||
/// apple 登录 | |||||
Future<UserInfoModel> appleLogin() async { | |||||
return null; | |||||
} | |||||
/// QQ 登录 | |||||
Future<UserInfoModel> qqLogin() async { | |||||
return null; | |||||
} | } | ||||
} | } |
@@ -1,5 +1,7 @@ | |||||
import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
abstract class LoginState extends Equatable { | abstract class LoginState extends Equatable { | ||||
const LoginState(); | const LoginState(); | ||||
@@ -13,19 +15,45 @@ class InitialLoginState extends LoginState {} | |||||
/// 缓存数据状态 | /// 缓存数据状态 | ||||
class LoginCacheState extends LoginState { | class LoginCacheState extends LoginState { | ||||
final LoginModel model; | |||||
final LoginStyleModel model; | |||||
const LoginCacheState({this.model}); | const LoginCacheState({this.model}); | ||||
@override | @override | ||||
List<Object> get props => [this.model]; | List<Object> get props => [this.model]; | ||||
} | } | ||||
/// 数据加载完毕状态 | /// 数据加载完毕状态 | ||||
class LoginLoadedState extends LoginState { | class LoginLoadedState extends LoginState { | ||||
final LoginModel model; | |||||
final LoginStyleModel model; | |||||
const LoginLoadedState({this.model}); | const LoginLoadedState({this.model}); | ||||
@override | @override | ||||
List<Object> get props => [this.model]; | List<Object> get props => [this.model]; | ||||
} | } | ||||
/// 数据加载出错 | /// 数据加载出错 | ||||
class LoginErrorState extends LoginState {} | class LoginErrorState extends LoginState {} | ||||
/// 第三方登录成功 | |||||
class LoginThirdLoginSuccessState extends LoginState { | |||||
String thirdType; | |||||
UserInfoModel model; | |||||
LoginThirdLoginSuccessState({@required this.model, @required this.thirdType}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 第三方登录失败 | |||||
class LoginThirdLoginErrorState extends LoginState { | |||||
@override | |||||
bool operator ==(Object other) { | |||||
return false; | |||||
} | |||||
@override | |||||
int get hashCode => super.hashCode; | |||||
} |
@@ -53,9 +53,11 @@ class LoginInviteBloc extends Bloc<LoginInviteEvent, LoginInviteState> { | |||||
/// 提交 | /// 提交 | ||||
Stream<LoginInviteState> _mapSubmitEventToState(LoginInviteSubmitEvent event) async* { | Stream<LoginInviteState> _mapSubmitEventToState(LoginInviteSubmitEvent event) async* { | ||||
var data = await repostitory.submitInvite(event); | var data = await repostitory.submitInvite(event); | ||||
if (!EmptyUtil.isEmpty(data)) | |||||
if (!EmptyUtil.isEmpty(data)) { | |||||
yield LoginInviteSubmitSuccess(model: data); | yield LoginInviteSubmitSuccess(model: data); | ||||
else | |||||
} else { | |||||
yield LoginInviteSubmitErrorState(); | yield LoginInviteSubmitErrorState(); | ||||
yield LoginInviteQuerySuccessState(model: repostitory?.lastInviteUser, pageMdel: repostitory?.pageModel); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,18 +1,20 @@ | |||||
import 'package:zhiying_comm/pages/login_page/invite/model/login_invite_user.dart'; | import 'package:zhiying_comm/pages/login_page/invite/model/login_invite_user.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/net_util.dart'; | import 'package:zhiying_comm/util/net_util.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | import 'package:zhiying_comm/models/user/user_info_model.dart'; | ||||
import '../../login_util.dart'; | |||||
import 'package:zhiying_comm/util/log/let_log.dart'; | |||||
import '../../login_style_util.dart'; | |||||
import 'bloc.dart'; | import 'bloc.dart'; | ||||
class LoginInviteRepository { | class LoginInviteRepository { | ||||
LoginModel pageModel; | |||||
LoginStyleModel pageModel; | |||||
LoginInviteUser lastInviteUser; | |||||
/// 获取数据,如果缓存有,则获取缓存的数据 | /// 获取数据,如果缓存有,则获取缓存的数据 | ||||
Future<LoginModel> fetchData() async { | |||||
pageModel = await LoginUtil.getLoginModel(); | |||||
Future<LoginStyleModel> fetchData() async { | |||||
pageModel = await LoginStyleUtil.getLoginModel(); | |||||
if (!EmptyUtil.isEmpty(pageModel)) { | if (!EmptyUtil.isEmpty(pageModel)) { | ||||
return pageModel; | return pageModel; | ||||
} | } | ||||
@@ -21,27 +23,36 @@ class LoginInviteRepository { | |||||
/// 获取邀请人信息 | /// 获取邀请人信息 | ||||
Future<LoginInviteUser> fetchInviteUserInfo(LoginInviteQueryEvent event) async { | Future<LoginInviteUser> fetchInviteUserInfo(LoginInviteQueryEvent event) async { | ||||
var result = await NetUtil.post('/api/v1/user/invite/${event.num}', method: NetMethod.GET); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
LoginInviteUser model = LoginInviteUser.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
if(null != model) | |||||
try { | |||||
var result = await NetUtil.post('/api/v1/user/invite/${event.num}', method: NetMethod.GET, showToast: false); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
LoginInviteUser model = LoginInviteUser.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
lastInviteUser = model; | |||||
return model; | return model; | ||||
else return null; | |||||
} else { | |||||
return null; | |||||
} | |||||
} catch (e, s) { | |||||
Logger.error(e, s); | |||||
} | } | ||||
return null; | |||||
} | } | ||||
/// 提交 | /// 提交 | ||||
Future<UserInfoModel> submitInvite(LoginInviteSubmitEvent event) async { | Future<UserInfoModel> submitInvite(LoginInviteSubmitEvent event) async { | ||||
var result = await NetUtil.post('/api/v1/user/invite/ack', params: {'mobile': event.mobile, 'parent_uid': event.num}); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
UserInfoModel model = UserInfoModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
if (null != model) { | |||||
model.mobile = event.mobile; | |||||
return model; | |||||
try { | |||||
var result = await NetUtil.post('/api/v1/user/invite/ack', params: { | |||||
'mobile': event.mobile, | |||||
'zone': '86', | |||||
'parent_uid': event.num, | |||||
}); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
UserInfoModel model = UserInfoModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
if (null != model) { | |||||
model.mobile = event.mobile; | |||||
return model; | |||||
} | |||||
} | } | ||||
return null; | |||||
} catch (e, s) { | |||||
Logger.error(e, s); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
@@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | import 'package:zhiying_comm/models/user/user_info_model.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/invite/model/login_invite_user.dart'; | import 'package:zhiying_comm/pages/login_page/invite/model/login_invite_user.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
abstract class LoginInviteState extends Equatable { | abstract class LoginInviteState extends Equatable { | ||||
const LoginInviteState(); | const LoginInviteState(); | ||||
@@ -16,7 +16,7 @@ class LoginInviteInitial extends LoginInviteState {} | |||||
/// 数据加载完毕状态 | /// 数据加载完毕状态 | ||||
class LoginInviteLoadedState extends LoginInviteState { | class LoginInviteLoadedState extends LoginInviteState { | ||||
final LoginModel model; | |||||
final LoginStyleModel model; | |||||
const LoginInviteLoadedState({@required this.model}); | const LoginInviteLoadedState({@required this.model}); | ||||
@@ -46,18 +46,19 @@ class LoginInviteSubmitSuccess extends LoginInviteState { | |||||
/// 邀请码失败 | /// 邀请码失败 | ||||
class LoginInviteSubmitErrorState extends LoginInviteState { | class LoginInviteSubmitErrorState extends LoginInviteState { | ||||
final String msg; | |||||
const LoginInviteSubmitErrorState({this.msg}); | |||||
@override | |||||
bool operator ==(Object other) { | |||||
return false; | |||||
} | |||||
@override | @override | ||||
List<Object> get props => [this.msg]; | |||||
int get hashCode => super.hashCode; | |||||
} | } | ||||
/// 查询邀请人成功 | /// 查询邀请人成功 | ||||
class LoginInviteQuerySuccessState extends LoginInviteState { | class LoginInviteQuerySuccessState extends LoginInviteState { | ||||
final LoginInviteUser model; | final LoginInviteUser model; | ||||
final LoginModel pageMdel; | |||||
final LoginStyleModel pageMdel; | |||||
const LoginInviteQuerySuccessState({@required this.model, @required this.pageMdel}); | const LoginInviteQuerySuccessState({@required this.model, @required this.pageMdel}); | ||||
@@ -2,7 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
@@ -39,7 +39,6 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
TextEditingController _editingController; | TextEditingController _editingController; | ||||
FocusNode _focusNode; | FocusNode _focusNode; | ||||
bool _showInviteInfo = false; | bool _showInviteInfo = false; | ||||
// 是否登录中 | // 是否登录中 | ||||
bool _isLogging = false; | bool _isLogging = false; | ||||
@@ -80,14 +79,19 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
void _submitOnClick(LoginInviteUser inviteUser) async { | void _submitOnClick(LoginInviteUser inviteUser) async { | ||||
_focusNode.unfocus(); | _focusNode.unfocus(); | ||||
/// 邀请码 | |||||
String inviteNum = inviteUser?.userId ?? ''; | |||||
/// 手机号 | |||||
UserInfoModel model = await Provider.of<UserInfoNotifier>(context, listen: false)?.getUserInfoModel(); | |||||
String mobile = model?.mobile ?? ''; | |||||
if (!EmptyUtil.isEmpty(inviteNum) && !EmptyUtil.isEmpty(mobile)) { | |||||
BlocProvider.of<LoginInviteBloc>(context).add(LoginInviteSubmitEvent(mobile: mobile, num: inviteNum)); | |||||
if (!_isLogging) { | |||||
/// 邀请码 | |||||
String inviteNum = inviteUser?.userId ?? ''; | |||||
/// 手机号 | |||||
UserInfoModel model = await Provider.of<UserInfoNotifier>(context, listen: false)?.getUserInfoModel(); | |||||
String mobile = model?.mobile ?? ''; | |||||
if (!EmptyUtil.isEmpty(inviteNum) && !EmptyUtil.isEmpty(mobile)) { | |||||
setState(() { | |||||
_isLogging = true; | |||||
}); | |||||
BlocProvider.of<LoginInviteBloc>(context).add(LoginInviteSubmitEvent(mobile: mobile, num: inviteNum)); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -125,6 +129,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
buildWhen: (previous, current) { | buildWhen: (previous, current) { | ||||
/// 提交失败 | /// 提交失败 | ||||
if (current is LoginInviteSubmitErrorState) { | if (current is LoginInviteSubmitErrorState) { | ||||
_isLogging = false; | |||||
return false; | return false; | ||||
} | } | ||||
@@ -169,7 +174,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
} | } | ||||
/// 主视图 | /// 主视图 | ||||
Widget _getMainWidget(LoginModel model, LoginInviteUser inviteUser) { | |||||
Widget _getMainWidget(LoginStyleModel model, LoginInviteUser inviteUser) { | |||||
return Column( | return Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
/// appbar | /// appbar | ||||
@@ -191,7 +196,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
} | } | ||||
/// appBar | /// appBar | ||||
Widget _getAppBar(LoginModel model) { | |||||
Widget _getAppBar(LoginStyleModel model) { | |||||
return AppBar( | return AppBar( | ||||
brightness: Brightness.light, | brightness: Brightness.light, | ||||
backgroundColor: HexColor.fromHex('#FFFFFF'), | backgroundColor: HexColor.fromHex('#FFFFFF'), | ||||
@@ -213,7 +218,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
} | } | ||||
/// title | /// title | ||||
Widget _getTitleWidget(LoginModel model) { | |||||
Widget _getTitleWidget(LoginStyleModel model) { | |||||
return Align( | return Align( | ||||
alignment: Alignment.centerLeft, | alignment: Alignment.centerLeft, | ||||
child: Text( | child: Text( | ||||
@@ -223,7 +228,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
} | } | ||||
/// 邀请码输入框 | /// 邀请码输入框 | ||||
Widget _getInviteInputWidget(LoginModel model) { | |||||
Widget _getInviteInputWidget(LoginStyleModel model) { | |||||
return _getCustomInputWidget( | return _getCustomInputWidget( | ||||
hint: model?.invite?.inputInviteText ?? '请输入邀请码', | hint: model?.invite?.inputInviteText ?? '请输入邀请码', | ||||
controller: _editingController, | controller: _editingController, | ||||
@@ -276,7 +281,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
} | } | ||||
/// 按钮 | /// 按钮 | ||||
Widget _getSubmiBtnWidget(LoginModel model, LoginInviteUser inviteUser) { | |||||
Widget _getSubmiBtnWidget(LoginStyleModel model, LoginInviteUser inviteUser) { | |||||
return Material( | return Material( | ||||
child: Container( | child: Container( | ||||
height: 52, | height: 52, | ||||
@@ -284,7 +289,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||||
color: Colors.white, | color: Colors.white, | ||||
child: RaisedButton( | child: RaisedButton( | ||||
child: Text( | child: Text( | ||||
model?.invite?.btnSubmitText ?? '进入智莺生活', | |||||
_isLogging ? '进入...' : model?.invite?.btnSubmitText ?? '进入智莺生活', | |||||
style: TextStyle(fontSize: 15), | style: TextStyle(fontSize: 15), | ||||
), | ), | ||||
textColor: HexColor.fromHex(model?.invite?.btnSubmitTextColor ?? '#FFFFFF'), | textColor: HexColor.fromHex(model?.invite?.btnSubmitTextColor ?? '#FFFFFF'), | ||||
@@ -2,16 +2,22 @@ import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/gestures.dart'; | import 'package:flutter/gestures.dart'; | ||||
import 'package:flutter/material.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:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:fluttertoast/fluttertoast.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/account/login_account_page.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/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | import 'package:zhiying_comm/util/mob_util/mob_util.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:provider/provider.dart'; | |||||
import 'bloc/bloc.dart'; | import 'bloc/bloc.dart'; | ||||
import 'bloc/login_repository.dart'; | import 'bloc/login_repository.dart'; | ||||
import 'login_page_sk.dart'; | import 'login_page_sk.dart'; | ||||
import 'model/login_model.dart'; | |||||
import 'model/login_style_model.dart'; | |||||
/// | /// | ||||
/// 登陆页面 | /// 登陆页面 | ||||
@@ -37,13 +43,15 @@ class LoginPageContainer extends StatefulWidget { | |||||
} | } | ||||
class _LoginPageContainerState extends State<LoginPageContainer> { | class _LoginPageContainerState extends State<LoginPageContainer> { | ||||
LoginModel _taoBao; | |||||
/// 微信or手机登陆 | /// 微信or手机登陆 | ||||
void _loginClick(String type, LoginModel model) { | |||||
void _loginClick(String type, LoginStyleModel model) { | |||||
print('登陆$type'); | print('登陆$type'); | ||||
RouterUtil.hideKeyboard(context); | RouterUtil.hideKeyboard(context); | ||||
if (type == 'mobile') { | if (type == 'mobile') { | ||||
if (model?.flashLoginEnable == '1') { | if (model?.flashLoginEnable == '1') { | ||||
// QuickLoginUtil.getInstance().openQuickLogin(context, model?.quick); | |||||
// mob 一键登录 | |||||
MobUtil.openQuickLoginPage(context, model?.quick); | MobUtil.openQuickLoginPage(context, model?.quick); | ||||
} else { | } else { | ||||
Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null))); | Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null))); | ||||
@@ -51,16 +59,48 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
} | } | ||||
/// 返回上一页 | |||||
void _openPop() { | |||||
if (Navigator.canPop(context)) { | |||||
Navigator.pop(context); | |||||
} | |||||
} | |||||
/// 第三方登陆 | /// 第三方登陆 | ||||
void _otherLoginClick(BottomIcons model) { | |||||
void _otherLoginClick(BottomIcons model) async { | |||||
print('第三方登陆${model.type}'); | print('第三方登陆${model.type}'); | ||||
if (EmptyUtil.isEmpty(model) || EmptyUtil.isEmpty(model.type)) { | |||||
Fluttertoast.showToast(msg: '暂不支持~'); | |||||
return; | |||||
} | |||||
Loading.show(context); | |||||
/// 淘宝登录 | |||||
if ('taobao' == model.type) { | |||||
_taoBao = await FlutterAlibc.loginTaoBao(); | |||||
if (!EmptyUtil.isEmpty(_taoBao) && !EmptyUtil.isEmpty(_taoBao?.errorCode) && _taoBao.errorCode == '0') { | |||||
BlocProvider.of<LoginBloc>(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}'); | |||||
} | |||||
} | |||||
/// QQ登录 | |||||
if ('qq' == model.type) { | |||||
Fluttertoast.showToast(msg: '暂不支持~'); | |||||
} | |||||
/// 微信登录 | |||||
if ('wechat' == model.type) { | |||||
Fluttertoast.showToast(msg: '暂不支持~'); | |||||
} | |||||
/// 苹果登录 | |||||
if ('apple' == model.type) { | |||||
Fluttertoast.showToast(msg: '暂不支持~'); | |||||
} | |||||
Loading.dismiss(); | |||||
} | } | ||||
/// 跳到用户协议 | /// 跳到用户协议 | ||||
@@ -71,8 +111,32 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
} | } | ||||
/// 跳到绑定手机号 | |||||
void _jumpBindPhonePage(String thirdType) { | |||||
/// 如果是淘宝登录 | |||||
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, | |||||
}))); | |||||
} | |||||
} | |||||
/// 跳到首页 | |||||
void _jumpHomePage() { | |||||
RouterUtil.goBackHomePage(context); | |||||
} | |||||
/// 展开关闭其它登陆 | /// 展开关闭其它登陆 | ||||
void _showOrColoseOtherLogin() { | |||||
void _showOrCloseOtherLogin() { | |||||
setState(() { | setState(() { | ||||
_showOther = !_showOther; | _showOther = !_showOther; | ||||
}); | }); | ||||
@@ -94,6 +158,28 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
if (current is LoginErrorState) { | if (current is LoginErrorState) { | ||||
return false; | return false; | ||||
} | } | ||||
/// 登录失败 | |||||
if (current is LoginThirdLoginErrorState) { | |||||
return false; | |||||
} | |||||
/// 登录成功 | |||||
if (current is LoginThirdLoginSuccessState) { | |||||
// 需要绑定手机号 | |||||
if (current.model.bindPhoneEnable == '1') { | |||||
// 打开绑定手机号页面 | |||||
_jumpBindPhonePage(current.thirdType); | |||||
} else { | |||||
// 更新登录数据 | |||||
Provider.of<UserInfoNotifier>(context, listen: false)?.setUserInfo(current.model); | |||||
// 直接打开首页 | |||||
_jumpHomePage(); | |||||
Fluttertoast.showToast(msg: '登录成功~'); | |||||
} | |||||
return false; | |||||
} | |||||
return true; | return true; | ||||
}, | }, | ||||
builder: (context, state) { | builder: (context, state) { | ||||
@@ -109,7 +195,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 主视图 | /// 主视图 | ||||
Widget _getMainWidget(LoginModel model) { | |||||
Widget _getMainWidget(LoginStyleModel model) { | |||||
return Column( | return Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
/// 头部 | /// 头部 | ||||
@@ -130,7 +216,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 头部Widget | /// 头部Widget | ||||
Widget _headWidget(LoginModel model) { | |||||
Widget _headWidget(LoginStyleModel model) { | |||||
return Container( | return Container( | ||||
height: 228 + MediaQuery.of(context).padding.top, | height: 228 + MediaQuery.of(context).padding.top, | ||||
width: double.infinity, | width: double.infinity, | ||||
@@ -152,7 +238,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
size: 22, | size: 22, | ||||
color: HexColor.fromHex('#333333'), | color: HexColor.fromHex('#333333'), | ||||
), | ), | ||||
onPressed: () => _openPop(), | |||||
onPressed: () => Navigator.maybePop(context), | |||||
), | ), | ||||
), | ), | ||||
Column( | Column( | ||||
@@ -187,7 +273,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 按钮 | /// 按钮 | ||||
Widget _buttonsWidget(LoginModel model) { | |||||
Widget _buttonsWidget(LoginStyleModel model) { | |||||
return Container( | return Container( | ||||
padding: const EdgeInsets.symmetric(horizontal: 27.5), | padding: const EdgeInsets.symmetric(horizontal: 27.5), | ||||
child: Column( | child: Column( | ||||
@@ -209,7 +295,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 协议 | /// 协议 | ||||
Widget _protocolWidget(LoginModel model) { | |||||
Widget _protocolWidget(LoginStyleModel model) { | |||||
return RichText( | return RichText( | ||||
text: TextSpan( | text: TextSpan( | ||||
text: '', | text: '', | ||||
@@ -226,7 +312,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 其它登陆方式 | /// 其它登陆方式 | ||||
Widget _otherLoginWidget(LoginModel model) { | |||||
Widget _otherLoginWidget(LoginStyleModel model) { | |||||
return Expanded( | return Expanded( | ||||
child: Column( | child: Column( | ||||
mainAxisAlignment: MainAxisAlignment.end, | mainAxisAlignment: MainAxisAlignment.end, | ||||
@@ -241,10 +327,10 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 其它登陆方式的title | /// 其它登陆方式的title | ||||
Widget _getOtherLoginTitle(LoginModel model) { | |||||
Widget _getOtherLoginTitle(LoginStyleModel model) { | |||||
return GestureDetector( | return GestureDetector( | ||||
behavior: HitTestBehavior.opaque, | behavior: HitTestBehavior.opaque, | ||||
onTap: () => _showOrColoseOtherLogin(), | |||||
onTap: () => _showOrCloseOtherLogin(), | |||||
child: Row( | child: Row( | ||||
mainAxisAlignment: MainAxisAlignment.center, | mainAxisAlignment: MainAxisAlignment.center, | ||||
crossAxisAlignment: CrossAxisAlignment.center, | crossAxisAlignment: CrossAxisAlignment.center, | ||||
@@ -261,7 +347,7 @@ class _LoginPageContainerState extends State<LoginPageContainer> { | |||||
} | } | ||||
/// 其它登陆方式的按钮 | /// 其它登陆方式的按钮 | ||||
Widget _getOtherLoginIcons(LoginModel model) { | |||||
Widget _getOtherLoginIcons(LoginStyleModel model) { | |||||
return Row( | return Row( | ||||
mainAxisAlignment: MainAxisAlignment.center, | mainAxisAlignment: MainAxisAlignment.center, | ||||
children: model.main.bottomIcons.map((item) { | children: model.main.bottomIcons.map((item) { | ||||
@@ -3,10 +3,10 @@ import 'package:zhiying_comm/util/shared_prefe_util.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
import 'model/login_model.dart'; | |||||
import 'model/login_style_model.dart'; | |||||
/// 登陆数据管理工具类 | /// 登陆数据管理工具类 | ||||
class LoginUtil { | |||||
class LoginStyleUtil { | |||||
static final String _URL = '/api/v1/sign/in'; | static final String _URL = '/api/v1/sign/in'; | ||||
static void init() async { | static void init() async { | ||||
@@ -17,7 +17,7 @@ class LoginUtil { | |||||
} | } | ||||
/// 获取数据 | /// 获取数据 | ||||
static Future<LoginModel> getLoginModel() async { | |||||
static Future<LoginStyleModel> getLoginModel() async { | |||||
var cache = await fetchCachePageData(); | var cache = await fetchCachePageData(); | ||||
if (!EmptyUtil.isEmpty(cache)) return cache; | if (!EmptyUtil.isEmpty(cache)) return cache; | ||||
var result = await fetchNetPageData(); | var result = await fetchNetPageData(); | ||||
@@ -32,20 +32,20 @@ class LoginUtil { | |||||
} | } | ||||
/// 获取缓存的页面数据 | /// 获取缓存的页面数据 | ||||
static Future<LoginModel> fetchCachePageData() async { | |||||
static Future<LoginStyleModel> fetchCachePageData() async { | |||||
var result = await NetUtil.getRequestCachedData(_URL); | var result = await NetUtil.getRequestCachedData(_URL); | ||||
if (!EmptyUtil.isEmpty(result)) { | if (!EmptyUtil.isEmpty(result)) { | ||||
LoginModel model = LoginModel.fromJson(result); | |||||
LoginStyleModel model = LoginStyleModel.fromJson(result); | |||||
return model; | return model; | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/// 获取页面数据 | /// 获取页面数据 | ||||
static Future<LoginModel> fetchNetPageData() async { | |||||
static Future<LoginStyleModel> fetchNetPageData() async { | |||||
var result = await NetUtil.post(_URL, method: NetMethod.GET, cache: true); | var result = await NetUtil.post(_URL, method: NetMethod.GET, cache: true); | ||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | ||||
LoginModel model = LoginModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
LoginStyleModel model = LoginStyleModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
return model; | return model; | ||||
} | } | ||||
return null; | return null; |
@@ -5,32 +5,36 @@ | |||||
/// invite : {"app_bar_title":"登陆","app_bar_title_color":"#333333","app_bar_bg_color":"#FFFFFF","title":"输入邀请码","title_color":"#333333","input_hint_color":"#999999","input_bg_color":"#F7F7F7","btn_ban_bg_color":"#F5F5F5","btn_ban_text_color":"#999999","input_invite_icon":"http://xxxx","input_invite_text":"请输入邀请码","input_invite_text_color":"#999999","btn_submit_text":"进入智莺生活","btn_submit_text_color":"#FFFFFF","btn_submit_bg_color":"#FF3939","btn_submit_shadow_color":"#FF0000"} | /// invite : {"app_bar_title":"登陆","app_bar_title_color":"#333333","app_bar_bg_color":"#FFFFFF","title":"输入邀请码","title_color":"#333333","input_hint_color":"#999999","input_bg_color":"#F7F7F7","btn_ban_bg_color":"#F5F5F5","btn_ban_text_color":"#999999","input_invite_icon":"http://xxxx","input_invite_text":"请输入邀请码","input_invite_text_color":"#999999","btn_submit_text":"进入智莺生活","btn_submit_text_color":"#FFFFFF","btn_submit_bg_color":"#FF3939","btn_submit_shadow_color":"#FF0000"} | ||||
/// quick : {"app_bar_title":"","app_bar_bg_color":"","app_bar_title_color":"#FFFFFF","account_color":"#333333","text_tip":"切换账号","text_tip_color":"#FF3939","btn_submit_text":"立即登录","btn_submit_text_color":"#FFFFFF","btn_submit_bg_color":"#FF3939","btn_submit_shadow_color":"#FF0000","protocol_select_icon":"http://xxxx","protocol_unselect_icon":"http://xxxxx","text_bottom_tip":"中国电信提供认证服务","text_bottom_tip_color":"#C0C0C0","protocol":[{"text":"同意","text_color":"#C0C0C0","url":""},{"text":"《智莺生活用户协议》","text_color":"#FF3939","url":"http://www.hairuyi.com/?mod=appapi&act=privacy&ctrl=index&type=protocol"},{"text":"及","text_color":"#C0C0C0","url":""},{"text":"《隐私政策》","text_color":"#FF3939","url":"http://www.hairuyi.com/?mod=appapi&act=privacy&ctrl=index&type=privacyPolicy"}]} | /// quick : {"app_bar_title":"","app_bar_bg_color":"","app_bar_title_color":"#FFFFFF","account_color":"#333333","text_tip":"切换账号","text_tip_color":"#FF3939","btn_submit_text":"立即登录","btn_submit_text_color":"#FFFFFF","btn_submit_bg_color":"#FF3939","btn_submit_shadow_color":"#FF0000","protocol_select_icon":"http://xxxx","protocol_unselect_icon":"http://xxxxx","text_bottom_tip":"中国电信提供认证服务","text_bottom_tip_color":"#C0C0C0","protocol":[{"text":"同意","text_color":"#C0C0C0","url":""},{"text":"《智莺生活用户协议》","text_color":"#FF3939","url":"http://www.hairuyi.com/?mod=appapi&act=privacy&ctrl=index&type=protocol"},{"text":"及","text_color":"#C0C0C0","url":""},{"text":"《隐私政策》","text_color":"#FF3939","url":"http://www.hairuyi.com/?mod=appapi&act=privacy&ctrl=index&type=privacyPolicy"}]} | ||||
/// flash_login_enable : "1" | /// flash_login_enable : "1" | ||||
class LoginModel { | |||||
class LoginStyleModel { | |||||
// 返回图标 | |||||
String backImg; | String backImg; | ||||
// logo | |||||
String logoImg; | String logoImg; | ||||
// 登录首页的UI | |||||
Main main; | Main main; | ||||
// 手机绑定 | |||||
Mobile mobile; | Mobile mobile; | ||||
// 邀请好友页面 | |||||
Invite invite; | Invite invite; | ||||
// 一键登录 | |||||
Quick quick; | Quick quick; | ||||
// 是否需要填写邀请码 | |||||
String flashLoginEnable; | String flashLoginEnable; | ||||
LoginModel( | |||||
{this.backImg, | |||||
this.logoImg, | |||||
this.main, | |||||
this.mobile, | |||||
this.invite, | |||||
this.quick, | |||||
this.flashLoginEnable}); | |||||
LoginStyleModel({this.backImg, this.logoImg, this.main, this.mobile, this.invite, this.quick, this.flashLoginEnable}); | |||||
LoginModel.fromJson(Map<String, dynamic> json) { | |||||
LoginStyleModel.fromJson(Map<String, dynamic> json) { | |||||
backImg = json['back_img']; | backImg = json['back_img']; | ||||
logoImg = json['logo_img']; | logoImg = json['logo_img']; | ||||
main = json['main'] != null ? new Main.fromJson(json['main']) : null; | main = json['main'] != null ? new Main.fromJson(json['main']) : null; | ||||
mobile = | |||||
json['mobile'] != null ? new Mobile.fromJson(json['mobile']) : null; | |||||
invite = | |||||
json['invite'] != null ? new Invite.fromJson(json['invite']) : null; | |||||
mobile = json['mobile'] != null ? new Mobile.fromJson(json['mobile']) : null; | |||||
invite = json['invite'] != null ? new Invite.fromJson(json['invite']) : null; | |||||
quick = json['quick'] != null ? new Quick.fromJson(json['quick']) : null; | quick = json['quick'] != null ? new Quick.fromJson(json['quick']) : null; | ||||
flashLoginEnable = json['flash_login_enable']; | flashLoginEnable = json['flash_login_enable']; | ||||
} | } | ||||
@@ -71,16 +75,16 @@ class Main { | |||||
Main( | Main( | ||||
{this.appBarTitle, | {this.appBarTitle, | ||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.appNameImg, | |||||
this.backgroundImg, | |||||
this.agreements, | |||||
this.importanceLogin, | |||||
this.otherIconsTitle, | |||||
this.otherIconsTitleColor, | |||||
this.otherExpansionIcon, | |||||
this.bottomIcons}); | |||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.appNameImg, | |||||
this.backgroundImg, | |||||
this.agreements, | |||||
this.importanceLogin, | |||||
this.otherIconsTitle, | |||||
this.otherIconsTitleColor, | |||||
this.otherExpansionIcon, | |||||
this.bottomIcons}); | |||||
Main.fromJson(Map<String, dynamic> json) { | Main.fromJson(Map<String, dynamic> json) { | ||||
appBarTitle = json['app_bar_title']; | appBarTitle = json['app_bar_title']; | ||||
@@ -122,8 +126,7 @@ class Main { | |||||
data['agreements'] = this.agreements.map((v) => v.toJson()).toList(); | data['agreements'] = this.agreements.map((v) => v.toJson()).toList(); | ||||
} | } | ||||
if (this.importanceLogin != null) { | if (this.importanceLogin != null) { | ||||
data['importance_login'] = | |||||
this.importanceLogin.map((v) => v.toJson()).toList(); | |||||
data['importance_login'] = this.importanceLogin.map((v) => v.toJson()).toList(); | |||||
} | } | ||||
data['other_icons_title'] = this.otherIconsTitle; | data['other_icons_title'] = this.otherIconsTitle; | ||||
data['other_icons_title_color'] = this.otherIconsTitleColor; | data['other_icons_title_color'] = this.otherIconsTitleColor; | ||||
@@ -165,13 +168,7 @@ class ImportanceLogin { | |||||
String btnBgColor; | String btnBgColor; | ||||
String btnMobileIcon; | String btnMobileIcon; | ||||
ImportanceLogin( | |||||
{this.type, | |||||
this.btnText, | |||||
this.btnTextColor, | |||||
this.btnBorderColor, | |||||
this.btnBgColor, | |||||
this.btnMobileIcon}); | |||||
ImportanceLogin({this.type, this.btnText, this.btnTextColor, this.btnBorderColor, this.btnBgColor, this.btnMobileIcon}); | |||||
ImportanceLogin.fromJson(Map<String, dynamic> json) { | ImportanceLogin.fromJson(Map<String, dynamic> json) { | ||||
type = json['type']; | type = json['type']; | ||||
@@ -252,44 +249,50 @@ class Mobile { | |||||
String protocolUnselectIcon; | String protocolUnselectIcon; | ||||
List<Protocol> protocol; | List<Protocol> protocol; | ||||
Mobile( | |||||
{this.vcodeTime, | |||||
this.appBarTitle, | |||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.title, | |||||
this.titleColor, | |||||
this.inputHintColor, | |||||
this.inputTextColor, | |||||
this.inputBgColor, | |||||
this.inputMobileIcon, | |||||
this.inputMobileHintText, | |||||
this.inputVcodeIcon, | |||||
this.inputVcodeHintText, | |||||
this.inputOtherCodeIcon, | |||||
this.inputOtherCodeIconText, | |||||
this.inputPassIcon, | |||||
this.inputPassHintText, | |||||
this.btnLoginText, | |||||
this.btnLoginTextColor, | |||||
this.btnLoginBgColor, | |||||
this.btnLoginShadowColor, | |||||
this.btnLoginBanBgColor, | |||||
this.btnLoginBanTextColor, | |||||
this.btnVcodeText, | |||||
this.btnVcodeTextColor, | |||||
this.btnVcodeBgColor, | |||||
this.btnVcodeBanTextColor, | |||||
this.btnVcodeBanBgColor, | |||||
this.textUsePassTip, | |||||
this.textUseVcodeTip, | |||||
this.textUsePassTipColor, | |||||
this.textUseVcodeTipColor, | |||||
this.textBottomTip, | |||||
this.textBottomTipColor, | |||||
this.protocolSelectIcon, | |||||
this.protocolUnselectIcon, | |||||
this.protocol}); | |||||
String thirdPartyLoginTitle; | |||||
String thirdPartyLoginAppBarTitle; | |||||
Mobile({ | |||||
this.vcodeTime, | |||||
this.appBarTitle, | |||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.title, | |||||
this.titleColor, | |||||
this.inputHintColor, | |||||
this.inputTextColor, | |||||
this.inputBgColor, | |||||
this.inputMobileIcon, | |||||
this.inputMobileHintText, | |||||
this.inputVcodeIcon, | |||||
this.inputVcodeHintText, | |||||
this.inputOtherCodeIcon, | |||||
this.inputOtherCodeIconText, | |||||
this.inputPassIcon, | |||||
this.inputPassHintText, | |||||
this.btnLoginText, | |||||
this.btnLoginTextColor, | |||||
this.btnLoginBgColor, | |||||
this.btnLoginShadowColor, | |||||
this.btnLoginBanBgColor, | |||||
this.btnLoginBanTextColor, | |||||
this.btnVcodeText, | |||||
this.btnVcodeTextColor, | |||||
this.btnVcodeBgColor, | |||||
this.btnVcodeBanTextColor, | |||||
this.btnVcodeBanBgColor, | |||||
this.textUsePassTip, | |||||
this.textUseVcodeTip, | |||||
this.textUsePassTipColor, | |||||
this.textUseVcodeTipColor, | |||||
this.textBottomTip, | |||||
this.textBottomTipColor, | |||||
this.protocolSelectIcon, | |||||
this.protocolUnselectIcon, | |||||
this.protocol, | |||||
this.thirdPartyLoginAppBarTitle, | |||||
this.thirdPartyLoginTitle, | |||||
}); | |||||
Mobile.fromJson(Map<String, dynamic> json) { | Mobile.fromJson(Map<String, dynamic> json) { | ||||
vcodeTime = json['vcode_time']; | vcodeTime = json['vcode_time']; | ||||
@@ -328,6 +331,8 @@ class Mobile { | |||||
textBottomTipColor = json['text_bottom_tip_color']; | textBottomTipColor = json['text_bottom_tip_color']; | ||||
protocolSelectIcon = json['protocol_select_icon']; | protocolSelectIcon = json['protocol_select_icon']; | ||||
protocolUnselectIcon = json['protocol_unselect_icon']; | protocolUnselectIcon = json['protocol_unselect_icon']; | ||||
thirdPartyLoginAppBarTitle = json['third_party_login_app_bar_title']; | |||||
thirdPartyLoginTitle = json['third_party_login_title']; | |||||
if (json['protocol'] != null) { | if (json['protocol'] != null) { | ||||
protocol = new List<Protocol>(); | protocol = new List<Protocol>(); | ||||
json['protocol'].forEach((v) { | json['protocol'].forEach((v) { | ||||
@@ -339,6 +344,8 @@ class Mobile { | |||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['vcode_time'] = this.vcodeTime; | data['vcode_time'] = this.vcodeTime; | ||||
data['third_party_login_app_bar_title'] = this.thirdPartyLoginAppBarTitle; | |||||
data['third_party_login_title'] = this.thirdPartyLoginTitle; | |||||
data['app_bar_title'] = this.appBarTitle; | data['app_bar_title'] = this.appBarTitle; | ||||
data['app_bar_title_color'] = this.appBarTitleColor; | data['app_bar_title_color'] = this.appBarTitleColor; | ||||
data['app_bar_bg_color'] = this.appBarBgColor; | data['app_bar_bg_color'] = this.appBarBgColor; | ||||
@@ -401,21 +408,21 @@ class Invite { | |||||
Invite( | Invite( | ||||
{this.appBarTitle, | {this.appBarTitle, | ||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.title, | |||||
this.titleColor, | |||||
this.inputHintColor, | |||||
this.inputBgColor, | |||||
this.btnBanBgColor, | |||||
this.btnBanTextColor, | |||||
this.inputInviteIcon, | |||||
this.inputInviteText, | |||||
this.inputInviteTextColor, | |||||
this.btnSubmitText, | |||||
this.btnSubmitTextColor, | |||||
this.btnSubmitBgColor, | |||||
this.btnSubmitShadowColor}); | |||||
this.appBarTitleColor, | |||||
this.appBarBgColor, | |||||
this.title, | |||||
this.titleColor, | |||||
this.inputHintColor, | |||||
this.inputBgColor, | |||||
this.btnBanBgColor, | |||||
this.btnBanTextColor, | |||||
this.inputInviteIcon, | |||||
this.inputInviteText, | |||||
this.inputInviteTextColor, | |||||
this.btnSubmitText, | |||||
this.btnSubmitTextColor, | |||||
this.btnSubmitBgColor, | |||||
this.btnSubmitShadowColor}); | |||||
Invite.fromJson(Map<String, dynamic> json) { | Invite.fromJson(Map<String, dynamic> json) { | ||||
appBarTitle = json['app_bar_title']; | appBarTitle = json['app_bar_title']; | ||||
@@ -477,20 +484,20 @@ class Quick { | |||||
Quick( | Quick( | ||||
{this.appBarTitle, | {this.appBarTitle, | ||||
this.appBarBgColor, | |||||
this.appBarTitleColor, | |||||
this.accountColor, | |||||
this.textTip, | |||||
this.textTipColor, | |||||
this.btnSubmitText, | |||||
this.btnSubmitTextColor, | |||||
this.btnSubmitBgColor, | |||||
this.btnSubmitShadowColor, | |||||
this.protocolSelectIcon, | |||||
this.protocolUnselectIcon, | |||||
this.textBottomTip, | |||||
this.textBottomTipColor, | |||||
this.protocol}); | |||||
this.appBarBgColor, | |||||
this.appBarTitleColor, | |||||
this.accountColor, | |||||
this.textTip, | |||||
this.textTipColor, | |||||
this.btnSubmitText, | |||||
this.btnSubmitTextColor, | |||||
this.btnSubmitBgColor, | |||||
this.btnSubmitShadowColor, | |||||
this.protocolSelectIcon, | |||||
this.protocolUnselectIcon, | |||||
this.textBottomTip, | |||||
this.textBottomTipColor, | |||||
this.protocol}); | |||||
Quick.fromJson(Map<String, dynamic> json) { | Quick.fromJson(Map<String, dynamic> json) { | ||||
appBarTitle = json['app_bar_title']; | appBarTitle = json['app_bar_title']; |
@@ -10,6 +10,12 @@ class GlobalConfig { | |||||
/// 通用标志key | /// 通用标志key | ||||
static final String SKIP_IDENTIFIER = 'skip_identifier'; | static final String SKIP_IDENTIFIER = 'skip_identifier'; | ||||
/// ====================== 第三方登录key ====================== /// | |||||
static const String LOGIN_THIRD_ALI = 'taobao'; // 淘宝登录 | |||||
static const String LOGIN_THIRD_WECHAT = 'wechat'; // 微信 | |||||
static const String LOGIN_THIRD_QQ = 'qq'; // QQ | |||||
static const String LOGIN_THIRD_APPLE = 'apple'; // 苹果登录 | |||||
/// ====================== 各个渠道的key ====================== /// | /// ====================== 各个渠道的key ====================== /// | ||||
static const String PROVIDER_TB = 'taobao'; // 淘宝 | static const String PROVIDER_TB = 'taobao'; // 淘宝 | ||||
static const String PROVIDER_TM = 'tianmao'; // 天猫 | static const String PROVIDER_TM = 'tianmao'; // 天猫 | ||||
@@ -35,7 +41,4 @@ class GlobalConfig { | |||||
/// 货币类型 | /// 货币类型 | ||||
static final String MONEY_TYPE = "¥ "; | static final String MONEY_TYPE = "¥ "; | ||||
// /// 天猫 淘宝类型 | |||||
// static final String PROVIDER_TM = 'tianmao'; | |||||
// static final String PROVIDER_TB = 'taobao'; | |||||
} | } |
@@ -1,6 +1,6 @@ | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:mobsms/mobsms.dart'; | import 'package:mobsms/mobsms.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/enum_util.dart'; | import 'package:zhiying_comm/util/enum_util.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
@@ -7,7 +7,7 @@ import 'package:zhiying_comm/models/user/user_info_model.dart'; | |||||
import 'package:zhiying_comm/models/user/user_info_model_notifier.dart'; | import 'package:zhiying_comm/models/user/user_info_model_notifier.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/account/login_account_page.dart'; | import 'package:zhiying_comm/pages/login_page/account/login_account_page.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/invite/login_invite_page.dart'; | import 'package:zhiying_comm/pages/login_page/invite/login_invite_page.dart'; | ||||
import 'package:zhiying_comm/pages/login_page/model/login_model.dart'; | |||||
import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/util/global_config.dart'; | import 'package:zhiying_comm/util/global_config.dart'; | ||||
import 'package:zhiying_comm/util/log/let_log.dart'; | import 'package:zhiying_comm/util/log/let_log.dart'; | ||||
@@ -145,7 +145,10 @@ class NetUtil { | |||||
} | } | ||||
} | } | ||||
// 退出登陆 | |||||
/// | |||||
/// 401003 用户被逼下线 | |||||
/// 退出登陆(清理token等用户信息) | |||||
/// | |||||
if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '401003') { | if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '401003') { | ||||
try { | try { | ||||
Future.delayed(Duration(seconds: 0)).then((onValue) { | Future.delayed(Duration(seconds: 0)).then((onValue) { | ||||
@@ -178,7 +181,7 @@ class NetUtil { | |||||
} | } | ||||
try { | try { | ||||
Map result = await NetUtil.post(path, method: method, params: params, queryParameters: queryParameters, showToast: showToast); | |||||
Map result = await NetUtil.post(path, method: method, params: params, queryParameters: queryParameters, showToast: showToast, cache: onCache != null); | |||||
// TODO 解密? | // TODO 解密? | ||||
if (isSuccess(result)) { | if (isSuccess(result)) { | ||||
if (onSuccess != null) { | if (onSuccess != null) { | ||||
@@ -323,7 +326,7 @@ class NetUtil { | |||||
// 站长ID | // 站长ID | ||||
String masterId = setting['master_id']; | String masterId = setting['master_id']; | ||||
if (null != masterId && masterId != '' && (!params.containsKey('master_id') || params['master_id'] == '')) { | if (null != masterId && masterId != '' && (!params.containsKey('master_id') || params['master_id'] == '')) { | ||||
params['master_id'] = masterId ?? 'template_database'; | |||||
params['master_id'] = masterId; //!EmptyUtil.isEmpty(masterId) ? masterId : 'template_database'; | |||||
} | } | ||||
// token 读取SP缓存中的用户token | // token 读取SP缓存中的用户token | ||||