mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-08-06 17:48:43 +08:00
413 lines
14 KiB
Dart
413 lines
14 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||
import 'package:event_bus/event_bus.dart';
|
||
import 'package:fluttertoast/fluttertoast.dart';
|
||
|
||
import 'package:flutter_go/utils/data_utils.dart';
|
||
import 'package:flutter_go/views/home.dart';
|
||
import 'package:flutter_go/event/event_bus.dart';
|
||
import 'package:flutter_go/event/event_model.dart';
|
||
|
||
import 'package:flutter_go/model/user_info_cache.dart';
|
||
import 'package:flutter_go/routers/application.dart';
|
||
import 'package:flutter_go/routers/routers.dart';
|
||
import 'package:flutter_go/model/user_info.dart';
|
||
|
||
class LoginPage extends StatefulWidget {
|
||
@override
|
||
_LoginPageState createState() => _LoginPageState();
|
||
}
|
||
|
||
class _LoginPageState extends State<LoginPage> {
|
||
_LoginPageState() {
|
||
final eventBus = new EventBus();
|
||
ApplicationEvent.event = eventBus;
|
||
}
|
||
|
||
// 利用FocusNode和_focusScopeNode来控制焦点 可以通过FocusNode.of(context)来获取widget树中默认的_focusScopeNode
|
||
FocusNode _emailFocusNode = new FocusNode();
|
||
FocusNode _passwordFocusNode = new FocusNode();
|
||
FocusScopeNode _focusScopeNode = new FocusScopeNode();
|
||
UserInfoControlModel _userInfoControlModel = new UserInfoControlModel();
|
||
|
||
GlobalKey<FormState> _signInFormKey = new GlobalKey();
|
||
TextEditingController _userNameEditingController =
|
||
new TextEditingController();
|
||
TextEditingController _passwordEditingController =
|
||
new TextEditingController();
|
||
|
||
bool isShowPassWord = false;
|
||
String username = '';
|
||
String password = '';
|
||
bool isLoading = false;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
try {
|
||
_userInfoControlModel.getAllInfo().then((list) {
|
||
if (list.length > 0) {
|
||
UserInfo _userInfo = list[0];
|
||
setState(() {
|
||
_userNameEditingController.text = _userInfo.username;
|
||
_passwordEditingController.text = _userInfo.password;
|
||
username = _userInfo.username;
|
||
password = _userInfo.password;
|
||
});
|
||
}
|
||
});
|
||
} catch (err) {
|
||
print('读取用户本地存储的用户信息出错 $err');
|
||
}
|
||
|
||
ApplicationEvent.event.on<UserGithubOAuthEvent>().listen((event) {
|
||
print('loginName:${event.loginName} token:${event.token} 1234567');
|
||
if (event.isSuccess == true) {
|
||
// oAuth 认证成功
|
||
setState(() {
|
||
isLoading = true;
|
||
});
|
||
DataUtils.getUserInfo(
|
||
{'loginName': event.loginName, 'token': event.token})
|
||
.then((result) {
|
||
setState(() {
|
||
isLoading = false;
|
||
});
|
||
Navigator.of(context).pushAndRemoveUntil(
|
||
MaterialPageRoute(builder: (context) => AppPage(result)),
|
||
(route) => route == null);
|
||
}).catchError((onError) {
|
||
print('获取身份信息 error:::$onError');
|
||
setState(() {
|
||
isLoading = false;
|
||
});
|
||
});
|
||
} else {
|
||
Fluttertoast.showToast(
|
||
msg: '验证失败',
|
||
toastLength: Toast.LENGTH_SHORT,
|
||
gravity: ToastGravity.CENTER,
|
||
timeInSecForIos: 1,
|
||
backgroundColor: Theme.of(context).primaryColor,
|
||
textColor: Colors.white,
|
||
fontSize: 16.0);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 创建登录界面的TextForm
|
||
Widget buildSignInTextForm() {
|
||
return Container(
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||
),
|
||
width: MediaQuery.of(context).size.width * 0.8,
|
||
height: 190,
|
||
// * Flutter提供了一个Form widget,它可以对输入框进行分组,然后进行一些统一操作,如输入内容校验、输入框重置以及输入内容保存。
|
||
child: Form(
|
||
key: _signInFormKey,
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: <Widget>[
|
||
Flexible(
|
||
child: Padding(
|
||
padding: const EdgeInsets.only(
|
||
left: 25, right: 25, top: 20, bottom: 20),
|
||
child: TextFormField(
|
||
controller: _userNameEditingController,
|
||
//关联焦点
|
||
focusNode: _emailFocusNode,
|
||
onEditingComplete: () {
|
||
if (_focusScopeNode == null) {
|
||
_focusScopeNode = FocusScope.of(context);
|
||
}
|
||
_focusScopeNode.requestFocus(_passwordFocusNode);
|
||
},
|
||
|
||
decoration: InputDecoration(
|
||
icon: Icon(
|
||
Icons.email,
|
||
color: Colors.black,
|
||
),
|
||
hintText: "Github 登录名",
|
||
border: InputBorder.none),
|
||
style: TextStyle(fontSize: 16, color: Colors.black),
|
||
//验证
|
||
validator: (value) {
|
||
if (value.isEmpty) {
|
||
return "登录名不可为空!";
|
||
}
|
||
return ' ';
|
||
},
|
||
onSaved: (value) {
|
||
setState(() {
|
||
username = value;
|
||
});
|
||
},
|
||
),
|
||
),
|
||
),
|
||
Container(
|
||
height: 1,
|
||
width: MediaQuery.of(context).size.width * 0.75,
|
||
color: Colors.grey[400],
|
||
),
|
||
Flexible(
|
||
child: Padding(
|
||
padding: const EdgeInsets.only(left: 25, right: 25, top: 20),
|
||
child: TextFormField(
|
||
controller: _passwordEditingController,
|
||
focusNode: _passwordFocusNode,
|
||
decoration: InputDecoration(
|
||
icon: Icon(
|
||
Icons.lock,
|
||
color: Colors.black,
|
||
),
|
||
hintText: "Github 登录密码",
|
||
border: InputBorder.none,
|
||
suffixIcon: IconButton(
|
||
icon: Icon(
|
||
Icons.remove_red_eye,
|
||
color: Colors.black,
|
||
),
|
||
onPressed: showPassWord,
|
||
),
|
||
),
|
||
//输入密码,需要用*****显示
|
||
obscureText: !isShowPassWord,
|
||
style: TextStyle(fontSize: 16, color: Colors.black),
|
||
validator: (value) {
|
||
if (value == null || value.isEmpty) {
|
||
return "密码不可为空!";
|
||
}
|
||
return '';
|
||
},
|
||
onSaved: (value) {
|
||
setState(() {
|
||
password = value;
|
||
});
|
||
},
|
||
),
|
||
),
|
||
),
|
||
Container(
|
||
height: 1,
|
||
width: MediaQuery.of(context).size.width * 0.75,
|
||
color: Colors.grey[400],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildSignInButton() {
|
||
return GestureDetector(
|
||
child: Container(
|
||
padding: EdgeInsets.only(left: 42, right: 42, top: 10, bottom: 10),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(5)),
|
||
color: Theme.of(context).primaryColor),
|
||
child: Text(
|
||
"LOGIN",
|
||
style: TextStyle(fontSize: 25, color: Colors.white),
|
||
),
|
||
),
|
||
onTap: () {
|
||
// 利用key来获取widget的状态FormState,可以用过FormState对Form的子孙FromField进行统一的操作
|
||
if (_signInFormKey.currentState.validate()) {
|
||
// 如果输入都检验通过,则进行登录操作
|
||
// Scaffold.of(context)
|
||
// .showSnackBar(new SnackBar(content: new Text("执行登录操作")));
|
||
//调用所有自孩子<E5ADA9><E5AD90>save回调,保存表单内容
|
||
doLogin();
|
||
}
|
||
},
|
||
);
|
||
}
|
||
|
||
// 登陆操作
|
||
doLogin() {
|
||
print("doLogin");
|
||
_signInFormKey.currentState.save();
|
||
setState(() {
|
||
isLoading = true;
|
||
});
|
||
DataUtils.doLogin({'username': username, 'password': password})
|
||
.then((userResult) {
|
||
setState(() {
|
||
isLoading = false;
|
||
});
|
||
if (userResult.runtimeType == UserInformation) {
|
||
try {
|
||
_userInfoControlModel.deleteAll().then((result) {
|
||
// print('删除结果:$result');
|
||
_userInfoControlModel
|
||
.insert(UserInfo(password: password, username: username))
|
||
.then((value) {
|
||
print('存储成功:$value');
|
||
Navigator.of(context).pushAndRemoveUntil(
|
||
MaterialPageRoute(builder: (context) => AppPage(userResult)),
|
||
(route) => route == null);
|
||
});
|
||
});
|
||
} catch (err) {
|
||
Navigator.of(context).pushAndRemoveUntil(
|
||
MaterialPageRoute(builder: (context) => AppPage(userResult)),
|
||
(route) => route == null);
|
||
}
|
||
}else if(userResult.runtimeType == String){
|
||
Fluttertoast.showToast(
|
||
msg: userResult,
|
||
toastLength: Toast.LENGTH_SHORT,
|
||
gravity: ToastGravity.CENTER,
|
||
timeInSecForIos: 1,
|
||
backgroundColor: Theme.of(context).primaryColor,
|
||
textColor: Colors.white,
|
||
fontSize: 16.0);
|
||
}
|
||
}).catchError((errorMsg) {
|
||
setState(() {
|
||
isLoading = false;
|
||
});
|
||
Fluttertoast.showToast(
|
||
msg: errorMsg.toString(),
|
||
toastLength: Toast.LENGTH_SHORT,
|
||
gravity: ToastGravity.CENTER,
|
||
timeInSecForIos: 1,
|
||
backgroundColor: Theme.of(context).primaryColor,
|
||
textColor: Colors.white,
|
||
fontSize: 16.0);
|
||
});
|
||
}
|
||
|
||
// 点击控制密码是否显示
|
||
void showPassWord() {
|
||
setState(() {
|
||
isShowPassWord = !isShowPassWord;
|
||
});
|
||
}
|
||
|
||
Widget buildLoading() {
|
||
if (isLoading) {
|
||
return Opacity(
|
||
opacity: .5,
|
||
child: Container(
|
||
width: MediaQuery.of(context).size.width * 0.85,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||
color: Colors.black,
|
||
),
|
||
child: SpinKitPouringHourglass(color: Colors.white),
|
||
),
|
||
);
|
||
}
|
||
return Container();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
body: SingleChildScrollView(
|
||
child: Container(
|
||
height: MediaQuery.of(context).size.height,
|
||
width: MediaQuery.of(context).size.width,
|
||
color: Theme.of(context).primaryColor,
|
||
child: Center(
|
||
child: Container(
|
||
width: MediaQuery.of(context).size.width * 0.85,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||
color: Colors.white,
|
||
image: DecorationImage(
|
||
image: AssetImage(
|
||
'assets/images/paimaiLogo.png',
|
||
),
|
||
fit: BoxFit.scaleDown,
|
||
alignment: Alignment.bottomRight,
|
||
),
|
||
),
|
||
child: Stack(
|
||
children: <Widget>[
|
||
Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: <Widget>[
|
||
SizedBox(height: 35.0),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: <Widget>[
|
||
Image.asset(
|
||
'assets/images/gitHub.png',
|
||
fit: BoxFit.contain,
|
||
width: 60.0,
|
||
height: 60.0,
|
||
),
|
||
Image.asset(
|
||
'assets/images/arrow.png',
|
||
fit: BoxFit.contain,
|
||
width: 40.0,
|
||
height: 30.0,
|
||
),
|
||
Image.asset(
|
||
'assets/images/FlutterGo.png',
|
||
fit: BoxFit.contain,
|
||
width: 60.0,
|
||
height: 60.0,
|
||
),
|
||
],
|
||
),
|
||
buildSignInTextForm(),
|
||
buildSignInButton(),
|
||
SizedBox(height: 15.0),
|
||
new Container(
|
||
height: 1,
|
||
width: MediaQuery.of(context).size.width * 0.75,
|
||
color: Colors.grey[400],
|
||
margin: const EdgeInsets.only(bottom: 10.0),
|
||
),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: <Widget>[
|
||
FlatButton(
|
||
child: Text(
|
||
'Github OAuth 认证',
|
||
style: TextStyle(
|
||
color: Theme.of(context).primaryColor,
|
||
decoration: TextDecoration.underline),
|
||
),
|
||
onPressed: () {
|
||
Application.router.navigateTo(context,
|
||
'${Routes.webViewPage}?title=Github&url=${Uri.encodeComponent("https://github.com/login/oauth/authorize?client_id=cfe4795e76382ae8a5bd&scope=user,public_repo")}');
|
||
},
|
||
),
|
||
FlatButton(
|
||
child: Text(
|
||
'游客登录',
|
||
style: TextStyle(
|
||
color: Theme.of(context).primaryColor,
|
||
decoration: TextDecoration.underline),
|
||
),
|
||
onPressed: () {
|
||
Application.router.navigateTo(context, Routes.home, clearStack: true);
|
||
},
|
||
)
|
||
],
|
||
)
|
||
],
|
||
),
|
||
Positioned(
|
||
top: 0,
|
||
left: 0,
|
||
bottom: 0,
|
||
child: buildLoading(),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|