Skip to content

Commit

Permalink
完善登录处理 (#65)
Browse files Browse the repository at this point in the history
* 将用户的信息存储到 shared_preferences 中

* 添加登出按钮

* 修复 A RenderFlex overflowed 错误
  • Loading branch information
he0119 authored Aug 8, 2020
1 parent f9c0f96 commit 1ea5110
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 57 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/

## [Unreleased]

### Changed

- 优化表单验证
- 完善主页面的显示

## [0.5.4] - 2020-08-07

### Added
Expand Down
18 changes: 18 additions & 0 deletions lib/blocs/app_preferences/app_preferences_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';

import 'package:bloc/bloc.dart';
import 'package:enum_to_string/enum_to_string.dart';
Expand All @@ -7,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smart_home/models/app_tab.dart';
import 'package:smart_home/models/user.dart';

part 'app_preferences_event.dart';
part 'app_preferences_state.dart';
Expand All @@ -31,13 +33,18 @@ class AppPreferencesBloc
String blogAdminUrl = prefs.getString('blogAdminUrl');
AppTab defaultPage = EnumToString.fromString(
AppTab.values, prefs.getString('defaultPage'));
String loginUserJsonString = prefs.getString('loginUser');
User loginUser = loginUserJsonString != null
? User.fromJson(jsonDecode(loginUserJsonString))
: null;
yield state.copyWith(
initialized: true,
apiUrl: apiUrl,
refreshInterval: refreshInterval,
blogUrl: blogUrl,
blogAdminUrl: blogAdminUrl,
defaultPage: defaultPage,
loginUser: loginUser,
);
} catch (e) {
_log.severe('启动失败,无法获取配置');
Expand Down Expand Up @@ -85,5 +92,16 @@ class AppPreferencesBloc
_log.severe('设置默认主页失败');
}
}
if (event is LoginUserChanged) {
try {
final SharedPreferences prefs = await _prefs;
prefs.setString('loginUser', jsonEncode(event.loginUser.toJson()));
yield state.copyWith(
loginUser: event.loginUser,
);
} catch (e) {
_log.severe('设置登录用户失败');
}
}
}
}
15 changes: 15 additions & 0 deletions lib/blocs/app_preferences/app_preferences_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,18 @@ class DefaultPageChanged extends AppPreferencesEvent {
String toString() =>
'DefaultPageChanged { defaultPage: ${defaultPage.name} }';
}

/// 更改登录用户
class LoginUserChanged extends AppPreferencesEvent {
final User loginUser;

LoginUserChanged({
@required this.loginUser,
});

@override
List<Object> get props => [loginUser];

@override
String toString() => 'LoginUserChanged { loginUser: ${loginUser.username} }';
}
6 changes: 6 additions & 0 deletions lib/blocs/app_preferences/app_preferences_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class AppPreferencesState extends Equatable {
final String blogUrl;
final String blogAdminUrl;
final AppTab defaultPage;
final User loginUser;

const AppPreferencesState({
@required this.initialized,
Expand All @@ -15,6 +16,7 @@ class AppPreferencesState extends Equatable {
@required this.blogUrl,
@required this.blogAdminUrl,
@required this.defaultPage,
@required this.loginUser,
});

factory AppPreferencesState.initial() {
Expand All @@ -25,6 +27,7 @@ class AppPreferencesState extends Equatable {
blogUrl: null,
blogAdminUrl: null,
defaultPage: AppTab.storage,
loginUser: null,
);
}

Expand All @@ -35,6 +38,7 @@ class AppPreferencesState extends Equatable {
String blogUrl,
String blogAdminUrl,
AppTab defaultPage,
User loginUser,
}) {
return AppPreferencesState(
initialized: initialized ?? this.initialized,
Expand All @@ -43,6 +47,7 @@ class AppPreferencesState extends Equatable {
blogUrl: blogUrl ?? this.blogUrl,
blogAdminUrl: blogAdminUrl ?? this.blogAdminUrl,
defaultPage: defaultPage ?? this.defaultPage,
loginUser: loginUser ?? this.loginUser,
);
}

Expand All @@ -54,5 +59,6 @@ class AppPreferencesState extends Equatable {
blogUrl,
blogAdminUrl,
defaultPage,
loginUser,
];
}
12 changes: 11 additions & 1 deletion lib/blocs/authentication/authentication_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:smart_home/blocs/app_preferences/app_preferences_bloc.dart';
import 'package:smart_home/models/models.dart';
import 'package:smart_home/repositories/user_repository.dart';

Expand All @@ -10,9 +11,11 @@ part 'authentication_state.dart';
class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
final UserRepository userRepository;
final AppPreferencesBloc appPreferencesBloc;

AuthenticationBloc({
@required this.userRepository,
@required this.appPreferencesBloc,
}) : super(AuthenticationInitial());

@override
Expand All @@ -32,7 +35,13 @@ class AuthenticationBloc
try {
// 检查是否登录
if (await userRepository.isLogin) {
yield AuthenticationSuccess(await userRepository.currentUser());
if (appPreferencesBloc.state.loginUser != null) {
yield AuthenticationSuccess(appPreferencesBloc.state.loginUser);
} else {
User user = await userRepository.currentUser();
appPreferencesBloc.add(LoginUserChanged(loginUser: user));
yield AuthenticationSuccess(user);
}
} else {
yield AuthenticationFailure('未登录,请登录账户');
}
Expand All @@ -49,6 +58,7 @@ class AuthenticationBloc
await userRepository.authenticate(event.username, event.password);
if (result) {
User user = await userRepository.currentUser();
appPreferencesBloc.add(LoginUserChanged(loginUser: user));
yield AuthenticationSuccess(user);
} else {
yield AuthenticationFailure('用户名或密码错误');
Expand Down
1 change: 1 addition & 0 deletions lib/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class HomePage extends StatelessWidget {
return BlocProvider(
create: (context) => AuthenticationBloc(
userRepository: RepositoryProvider.of<UserRepository>(context),
appPreferencesBloc: RepositoryProvider.of<AppPreferencesBloc>(context),
)..add(AuthenticationStarted()),
child: BlocConsumer<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
Expand Down
100 changes: 52 additions & 48 deletions lib/pages/login_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,58 +168,62 @@ class _LoginFormState extends State<LoginForm> {

return BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/icon/icon.png',
width: 100.0,
height: 100.0,
semanticLabel: 'icon',
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
child: AutofillGroup(
child: Column(
children: [
TextFormField(
enableSuggestions: false,
decoration: InputDecoration(labelText: '用户名'),
controller: _usernameController,
autofillHints: <String>[AutofillHints.username],
),
TextFormField(
enableSuggestions: false,
decoration: InputDecoration(labelText: '密码'),
controller: _passwordController,
obscureText: true,
autofillHints: <String>[AutofillHints.password],
return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/icon/icon.png',
width: 100.0,
height: 100.0,
semanticLabel: 'icon',
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
child: AutofillGroup(
child: Column(
children: [
TextFormField(
enableSuggestions: false,
decoration: InputDecoration(labelText: '用户名'),
controller: _usernameController,
autofillHints: <String>[AutofillHints.username],
),
TextFormField(
enableSuggestions: false,
decoration: InputDecoration(labelText: '密码'),
controller: _passwordController,
obscureText: true,
autofillHints: <String>[AutofillHints.password],
),
],
),
],
),
),
),
),
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
onPressed: state is! AuthenticationInProgress
? _onLoginButtonPressed
: null,
child: Text('登录'),
),
FlatButton(
onPressed: widget.onTapBack,
child: Text('返回'),
),
Container(
child: state is AuthenticationInProgress
? CircularProgressIndicator()
: null,
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
onPressed: state is! AuthenticationInProgress
? _onLoginButtonPressed
: null,
child: Text('登录'),
),
FlatButton(
onPressed: widget.onTapBack,
child: Text('返回'),
),
Container(
child: state is AuthenticationInProgress
? CircularProgressIndicator()
: null,
),
],
),
],
),
);
},
);
Expand Down
12 changes: 4 additions & 8 deletions lib/repositories/user_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ class UserRepository {

/// 登出
Future logout() async {
await _clearRefreshToken();
final SharedPreferences prefs = await _prefs;
await prefs.remove('refreshToken');
await prefs.remove('loginUser');
_log.fine('clear refresh token');
}

/// 刷新 Token
Expand Down Expand Up @@ -95,13 +98,6 @@ class UserRepository {
}
}

/// 清除 Refresh Token
Future _clearRefreshToken() async {
final SharedPreferences prefs = await _prefs;
await prefs.remove('refreshToken');
_log.fine('clear refresh token');
}

Future _setRefreshToken(String refreshToken) async {
final SharedPreferences prefs = await _prefs;
await prefs.setString('refreshToken', refreshToken);
Expand Down
28 changes: 28 additions & 0 deletions lib/widgets/drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,34 @@ class MyDrawer extends StatelessWidget {
);
},
),
ListTile(
title: Text('登出'),
onTap: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('登出'),
content: Text('确认登出账户?'),
actions: <Widget>[
FlatButton(
child: Text('否'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('是'),
onPressed: () {
BlocProvider.of<AuthenticationBloc>(context)
.add(AuthenticationLogout());
Navigator.pop(context);
},
),
],
),
);
},
),
],
);
},
Expand Down

0 comments on commit 1ea5110

Please sign in to comment.