7.2 读取用户资料&缓存
实现步骤:
第 1 步:常量定义
lib/common/values/constants.dart
| 12
 3
 4
 5
 6
 
 | class Constants {
 ...
 static const storageToken = 'token';
 static const storageProfile = 'profile';
 }
 
 | 
storageToken 登录成功后 token
storageProfile 用户资料缓存
第 2 步:登录请求 model
lib/common/models/woo/request/user_login.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | class UserLoginReq {
 String? username;
 String? password;
 
 UserLoginReq({
 this.username,
 this.password,
 });
 
 factory UserLoginReq.fromJson(Map<String, dynamic> json) {
 return UserLoginReq(
 username: json['username'] as String?,
 password: json['password'] as String?,
 );
 }
 
 Map<String, dynamic> toJson() => {
 'username': username,
 'password': password,
 };
 }
 
 | 
第 3 步:登录 token 模型
lib/common/models/user_token.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | class UserTokenModel {
 String? token;
 
 UserTokenModel({
 this.token,
 });
 
 factory UserTokenModel.fromJson(Map<String, dynamic> json) {
 return UserTokenModel(
 token: json['token'] as String?,
 );
 }
 
 Map<String, dynamic> toJson() => {
 'token': token,
 };
 }
 
 | 
第 4 步:用户资料 model
直接复制返回 json
 
生成model 类 lib/common/models/woo/user_profile_model
 
用不同的目录进行区分, request response 的模型
第 5 步:api 编写
lib/common/api/user.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | class UserApi {
 ...
 
 
 static Future<UserTokenModel> login(UserLoginReq? req) async {
 var res = await WPHttpService.to.post(
 '/users/login',
 data: req,
 );
 return UserTokenModel.fromJson(res.data);
 }
 
 
 static Future<UserProfileModel> profile() async {
 var res = await WPHttpService.to.get(
 '/users/me',
 );
 return UserProfileModel.fromJson(res.data);
 }
 }
 
 | 
第 6 步:用户服务类
lib/common/services/user.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 
 | import 'dart:convert';import 'package:get/get.dart';
 
 import '../index.dart';
 
 
 class UserService extends GetxService {
 static UserService get to => Get.find();
 
 final _isLogin = false.obs;
 String token = '';
 final _profile = UserProfileModel().obs;
 
 
 bool get isLogin => _isLogin.value;
 
 
 UserProfileModel get profile => _profile.value;
 
 
 bool get hasToken => token.isNotEmpty;
 
 @override
 void onInit() {
 super.onInit();
 
 token = Storage().getString(Constants.storageToken);
 
 var profileOffline = Storage().getString(Constants.storageProfile);
 if (profileOffline.isNotEmpty) {
 _profile(UserProfileModel.fromJson(jsonDecode(profileOffline)));
 }
 }
 
 
 Future<void> setToken(String value) async {
 await Storage().setString(Constants.storageToken, value);
 token = value;
 }
 
 
 Future<void> getProfile() async {
 if (token.isEmpty) return;
 UserProfileModel result = await UserApi.profile();
 _profile(result);
 _isLogin.value = true;
 Storage().setString(Constants.storageProfile, jsonEncode(result));
 }
 
 
 Future<void> setProfile(UserProfileModel profile) async {
 if (token.isEmpty) return;
 _isLogin.value = true;
 _profile(profile);
 Storage().setString(Constants.storageProfile, jsonEncode(profile));
 }
 
 
 Future<void> logout() async {
 
 await Storage().remove(Constants.storageToken);
 _profile(UserProfileModel());
 _isLogin.value = false;
 token = '';
 }
 
 
 Future<bool> checkIsLogin() async {
 if (_isLogin.value == false) {
 await Get.toNamed(RouteNames.systemLogin);
 return false;
 }
 return true;
 }
 }
 
 
 | 
第 7 步:注册 UserService 服务
lib/global.dart
| 1
 | Get.put<UserService>(UserService());
 | 
第 8 步:登录请求
lib/pages/system/login/controller.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | Future<void> onSignIn() async {
 if ((formKey.currentState as FormState).validate()) {
 try {
 Loading.show();
 
 
 UserTokenModel res = await UserApi.login(UserLoginReq(
 username: userNameController.text,
 password: passwordController.text,
 ));
 
 
 await UserService.to.setToken(res.token!);
 
 await UserService.to.getProfile();
 
 Loading.success();
 Get.back(result: true);
 } finally {
 Loading.dismiss();
 }
 }
 }
 
 | 
第 9 步:HTTP 头加入 token 认证
lib/common/services/wp_http.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | class RequestInterceptors extends Interceptor {
 @override
 void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
 
 
 
 if (UserService.to.hasToken) {
 options.headers['Authorization'] = 'Bearer ${UserService.to.token}';
 }
 
 return handler.next(options);
 }
 
 | 
第 10 步:401 错误处理
lib/common/services/wp_http.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | Future<void> _errorNoAuthLogout() async {
 await UserService.to.logout();
 Get.offAndToNamed(RouteNames.systemLogin);
 }
 
 @override
 Future<void> onError(DioError err, ErrorInterceptorHandler handler) async {
 final exception = HttpException(err.message);
 switch (err.type) {
 case DioErrorType.response:
 {
 final response = err.response;
 final errorMessage = ErrorMessage.fromJson(response?.data);
 switch (errorMessage.statusCode) {
 
 case 401:
 
 _errorNoAuthLogout();
 break;
 ...
 
 | 
提交代码到 git