Commit 1892df313e9fe0820ecedc90db7d96f1f28d98f1
1 parent
e12dbc82
优化接口调用
Showing
9 changed files
with
104 additions
and
77 deletions
lib/app/splash_page.dart
1 | import 'dart:async'; | 1 | import 'dart:async'; |
2 | 2 | ||
3 | +import 'package:flutter/foundation.dart'; | ||
3 | import 'package:flutter/material.dart'; | 4 | import 'package:flutter/material.dart'; |
4 | import 'package:flutter_bloc/flutter_bloc.dart'; | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
5 | import 'package:wow_english/common/core/user_util.dart'; | 6 | import 'package:wow_english/common/core/user_util.dart'; |
@@ -32,6 +33,9 @@ class _TransitionViewState extends State<TransitionView> { | @@ -32,6 +33,9 @@ class _TransitionViewState extends State<TransitionView> { | ||
32 | Future startTime() async { | 33 | Future startTime() async { |
33 | // 判断是否登录 | 34 | // 判断是否登录 |
34 | UserEntity? userEntity = UserUtil.getUser(); | 35 | UserEntity? userEntity = UserUtil.getUser(); |
36 | + if (kDebugMode) { | ||
37 | + print('userEntity: $userEntity'); | ||
38 | + } | ||
35 | Timer(const Duration(seconds: 2), () { | 39 | Timer(const Duration(seconds: 2), () { |
36 | if (userEntity != null && userEntity.token.isNotEmpty) { | 40 | if (userEntity != null && userEntity.token.isNotEmpty) { |
37 | context.read<CacheBloc>().add(UserInfoChangeEvent(userEntity)); | 41 | context.read<CacheBloc>().add(UserInfoChangeEvent(userEntity)); |
lib/common/extension/string_extension.dart
lib/common/request/api_response/api_response_entity.g.dart
@@ -16,7 +16,7 @@ ApiResponse<T> $ApiResponseFromJson<T>(Map<String, dynamic> json) { | @@ -16,7 +16,7 @@ ApiResponse<T> $ApiResponseFromJson<T>(Map<String, dynamic> json) { | ||
16 | String type = T.toString(); | 16 | String type = T.toString(); |
17 | T? data; | 17 | T? data; |
18 | if (kDebugMode) { | 18 | if (kDebugMode) { |
19 | - print("ApiResponse <T> type:$type"); | 19 | + print("ApiResponse<T> T-type:$type, data-type:${json['data'].runtimeType}"); |
20 | } | 20 | } |
21 | if (json['data'] != null) { | 21 | if (json['data'] != null) { |
22 | data = jsonConvert.convert<T>(json['data']); | 22 | data = jsonConvert.convert<T>(json['data']); |
lib/common/request/exception.dart
@@ -5,82 +5,84 @@ import 'api_response/api_response_entity.dart'; | @@ -5,82 +5,84 @@ import 'api_response/api_response_entity.dart'; | ||
5 | 5 | ||
6 | class ApiException implements Exception { | 6 | class ApiException implements Exception { |
7 | static const unknownException = "未知错误"; | 7 | static const unknownException = "未知错误"; |
8 | + static const customErrorCode = -1; | ||
8 | final String? message; | 9 | final String? message; |
9 | final int? code; | 10 | final int? code; |
10 | String? stackInfo; | 11 | String? stackInfo; |
11 | 12 | ||
12 | ApiException([this.code, this.message]); | 13 | ApiException([this.code, this.message]); |
13 | 14 | ||
14 | - factory ApiException.fromDioError(DioException error) { | ||
15 | - switch (error.type) { | 15 | + factory ApiException.fromDioException(DioException exception) { |
16 | + if (kDebugMode) { | ||
17 | + print('fromDioException 异常: $exception'); | ||
18 | + } | ||
19 | + switch (exception.type) { | ||
16 | case DioExceptionType.connectionTimeout: | 20 | case DioExceptionType.connectionTimeout: |
17 | - return BadRequestException(-1, "连接超时"); | 21 | + return BadRequestException(customErrorCode, "连接超时"); |
18 | case DioExceptionType.sendTimeout: | 22 | case DioExceptionType.sendTimeout: |
19 | - return BadRequestException(-1, "请求超时"); | 23 | + return BadRequestException(customErrorCode, "请求超时"); |
20 | case DioExceptionType.receiveTimeout: | 24 | case DioExceptionType.receiveTimeout: |
21 | - return BadRequestException(-1, "响应超时"); | 25 | + return BadRequestException(customErrorCode, "响应超时"); |
22 | case DioExceptionType.badCertificate: | 26 | case DioExceptionType.badCertificate: |
23 | - return BadRequestException(-1, "证书错误"); | 27 | + return BadRequestException(customErrorCode, "证书错误"); |
24 | case DioExceptionType.badResponse: | 28 | case DioExceptionType.badResponse: |
25 | - return BadRequestException(-1, "返回错误"); | 29 | + return BadRequestException(customErrorCode, "返回错误"); |
26 | case DioExceptionType.cancel: | 30 | case DioExceptionType.cancel: |
27 | - return BadRequestException(-1, "请求取消"); | 31 | + return BadRequestException(customErrorCode, "请求取消"); |
28 | case DioExceptionType.connectionError: | 32 | case DioExceptionType.connectionError: |
29 | - return BadRequestException(-1, "连接错误"); | 33 | + return BadRequestException(customErrorCode, "连接错误"); |
30 | case DioExceptionType.unknown: | 34 | case DioExceptionType.unknown: |
31 | - try { | ||
32 | - /// http错误码带业务错误信息 | ||
33 | - ApiResponse apiResponse = ApiResponse.fromJson(error.response?.data); | ||
34 | - if (apiResponse.code != null) { | ||
35 | - return ApiException(apiResponse.code, apiResponse.msg); | ||
36 | - } | 35 | + int? errCode = exception.response?.statusCode; |
36 | + switch (errCode) { | ||
37 | + case 400: | ||
38 | + return BadRequestException(errCode, "请求语法错误"); | ||
39 | + case 401: | ||
40 | + return UnauthorisedException(errCode, "没有权限"); | ||
41 | + case 403: | ||
42 | + return UnauthorisedException(errCode, "服务器拒绝执行"); | ||
43 | + case 404: | ||
44 | + return UnauthorisedException(errCode, "无法连接服务器"); | ||
45 | + case 405: | ||
46 | + // 会出发登出的code,这里强制换掉 | ||
47 | + return UnauthorisedException(406, "请求方法被禁止"); | ||
48 | + case 500: | ||
49 | + return UnauthorisedException(errCode, "服务器内部错误"); | ||
50 | + case 502: | ||
51 | + return UnauthorisedException(errCode, "无效的请求"); | ||
52 | + case 503: | ||
53 | + return UnauthorisedException(errCode, "服务器异常"); | ||
54 | + case 505: | ||
55 | + return UnauthorisedException(errCode, "不支持HTTP协议请求"); | ||
56 | + default: | ||
37 | 57 | ||
38 | - int? errCode = error.response?.statusCode; | ||
39 | - switch (errCode) { | ||
40 | - case 400: | ||
41 | - return BadRequestException(errCode, "请求语法错误"); | ||
42 | - case 401: | ||
43 | - return UnauthorisedException(errCode!, "没有权限"); | ||
44 | - case 403: | ||
45 | - return UnauthorisedException(errCode!, "服务器拒绝执行"); | ||
46 | - case 404: | ||
47 | - return UnauthorisedException(errCode!, "无法连接服务器"); | ||
48 | - case 405: | ||
49 | - return UnauthorisedException(errCode!, "请求方法被禁止"); | ||
50 | - case 500: | ||
51 | - return UnauthorisedException(errCode!, "服务器内部错误"); | ||
52 | - case 502: | ||
53 | - return UnauthorisedException(errCode!, "无效的请求"); | ||
54 | - case 503: | ||
55 | - return UnauthorisedException(errCode!, "服务器异常"); | ||
56 | - case 505: | ||
57 | - return UnauthorisedException(errCode!, "不支持HTTP协议请求"); | ||
58 | - default: | ||
59 | - return ApiException(errCode, error.response?.statusMessage ?? '未知错误'); | ||
60 | - } | ||
61 | - } on Exception catch (e) { | ||
62 | - if (kDebugMode) { | ||
63 | - return ApiException(-1, e.toString()); | ||
64 | - } else { | ||
65 | - return ApiException(-1, unknownException); | ||
66 | - } | 58 | + /// 试一下Response能不能解析出业务上的错误码,不能再继续走dio抛出的异常 |
59 | + try { | ||
60 | + ApiResponse apiResponse = ApiResponse.fromJson(exception.response?.data); | ||
61 | + if (apiResponse.code != null) { | ||
62 | + return ApiException(apiResponse.code, apiResponse.msg ?? "错误码:${apiResponse.code}"); | ||
63 | + } | ||
64 | + } catch (e) { | ||
65 | + if (kDebugMode) { | ||
66 | + print('DioExceptionType.unknown 错误: $e'); | ||
67 | + } | ||
68 | + } | ||
67 | } | 69 | } |
68 | - default: | ||
69 | - return ApiException(-1, error.message); | ||
70 | } | 70 | } |
71 | + var errorCode = exception.response?.statusCode ?? customErrorCode; | ||
72 | + var errorMsg = kDebugMode ? (exception.response?.statusMessage ?? exception.message) : unknownException; | ||
73 | + return ApiException(errorCode, errorMsg); | ||
71 | } | 74 | } |
72 | 75 | ||
73 | factory ApiException.from(dynamic exception) { | 76 | factory ApiException.from(dynamic exception) { |
74 | if (exception is DioException) { | 77 | if (exception is DioException) { |
75 | - return ApiException.fromDioError(exception); | 78 | + return ApiException.fromDioException(exception); |
76 | } | 79 | } |
77 | if (exception is ApiException) { | 80 | if (exception is ApiException) { |
78 | return exception; | 81 | return exception; |
79 | - } else { | ||
80 | - var apiException = ApiException(-1, unknownException); | ||
81 | - apiException.stackInfo = exception?.toString(); | ||
82 | - return apiException; | ||
83 | } | 82 | } |
83 | + var apiException = ApiException(-1, unknownException); | ||
84 | + apiException.stackInfo = exception?.toString(); | ||
85 | + return apiException; | ||
84 | } | 86 | } |
85 | } | 87 | } |
86 | 88 | ||
@@ -91,5 +93,5 @@ class BadRequestException extends ApiException { | @@ -91,5 +93,5 @@ class BadRequestException extends ApiException { | ||
91 | 93 | ||
92 | /// 未认证异常 | 94 | /// 未认证异常 |
93 | class UnauthorisedException extends ApiException { | 95 | class UnauthorisedException extends ApiException { |
94 | - UnauthorisedException([int code = -1, String message = '']) : super(code, message); | 96 | + UnauthorisedException([int? code, String? message]) : super(code, message); |
95 | } | 97 | } |
lib/common/request/request.dart
@@ -4,7 +4,7 @@ import 'exception_handler.dart'; | @@ -4,7 +4,7 @@ import 'exception_handler.dart'; | ||
4 | 4 | ||
5 | Future<T?> request<T>( | 5 | Future<T?> request<T>( |
6 | Function() block, { | 6 | Function() block, { |
7 | - String loadingText = '加载中...', | 7 | + String loadingText = '请稍候...', |
8 | bool Function(ApiException)? onError, | 8 | bool Function(ApiException)? onError, |
9 | }) async { | 9 | }) async { |
10 | try { | 10 | try { |
lib/common/request/request_client.dart
@@ -3,6 +3,7 @@ import 'dart:convert'; | @@ -3,6 +3,7 @@ import 'dart:convert'; | ||
3 | import 'package:dio/dio.dart'; | 3 | import 'package:dio/dio.dart'; |
4 | import 'package:pretty_dio_logger/pretty_dio_logger.dart'; | 4 | import 'package:pretty_dio_logger/pretty_dio_logger.dart'; |
5 | 5 | ||
6 | +import '../core/user_util.dart'; | ||
6 | import 'api_response/api_response_entity.dart'; | 7 | import 'api_response/api_response_entity.dart'; |
7 | import 'api_response/raw_data.dart'; | 8 | import 'api_response/raw_data.dart'; |
8 | import 'config.dart'; | 9 | import 'config.dart'; |
@@ -40,6 +41,10 @@ class RequestClient { | @@ -40,6 +41,10 @@ class RequestClient { | ||
40 | 41 | ||
41 | return _handleResponse<T>(response, onResponse); | 42 | return _handleResponse<T>(response, onResponse); |
42 | } catch (e) { | 43 | } catch (e) { |
44 | + if ((e as ApiException?)?.code == 405) { | ||
45 | + UserUtil.logout(); | ||
46 | + return null; | ||
47 | + } | ||
43 | var exception = ApiException.from(e); | 48 | var exception = ApiException.from(e); |
44 | if (onError?.call(exception) != true) { | 49 | if (onError?.call(exception) != true) { |
45 | throw exception; | 50 | throw exception; |
lib/models/user_entity.dart
@@ -5,24 +5,25 @@ import 'package:wow_english/generated/json/user_entity.g.dart'; | @@ -5,24 +5,25 @@ import 'package:wow_english/generated/json/user_entity.g.dart'; | ||
5 | 5 | ||
6 | @JsonSerializable() | 6 | @JsonSerializable() |
7 | class UserEntity { | 7 | class UserEntity { |
8 | - late int id; | ||
9 | - late String name; | ||
10 | - late int? age; | ||
11 | - /// 性别:0, 1 | ||
12 | - late int? gender; | ||
13 | - late String? avatarUrl; | ||
14 | - late String phoneNum; | ||
15 | - late String token; | ||
16 | - late int expireTime; | 8 | + late int id; |
9 | + late String name; | ||
10 | + int? age; | ||
17 | 11 | ||
18 | - UserEntity(); | 12 | + /// 性别:0, 1 |
13 | + int? gender; | ||
14 | + String? avatarUrl; | ||
15 | + late String phoneNum; | ||
16 | + late String token; | ||
17 | + late int expireTime; | ||
19 | 18 | ||
20 | - factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json); | 19 | + UserEntity(); |
21 | 20 | ||
22 | - Map<String, dynamic> toJson() => $UserEntityToJson(this); | 21 | + factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json); |
23 | 22 | ||
24 | - @override | ||
25 | - String toString() { | ||
26 | - return jsonEncode(this); | ||
27 | - } | 23 | + Map<String, dynamic> toJson() => $UserEntityToJson(this); |
24 | + | ||
25 | + @override | ||
26 | + String toString() { | ||
27 | + return jsonEncode(this); | ||
28 | + } | ||
28 | } | 29 | } |
lib/pages/login/loginpage/bloc/login_bloc.dart
1 | import 'package:common_utils/common_utils.dart'; | 1 | import 'package:common_utils/common_utils.dart'; |
2 | import 'package:flutter/cupertino.dart'; | 2 | import 'package:flutter/cupertino.dart'; |
3 | +import 'package:flutter/foundation.dart'; | ||
3 | import 'package:flutter_bloc/flutter_bloc.dart'; | 4 | import 'package:flutter_bloc/flutter_bloc.dart'; |
4 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 5 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
6 | +import 'package:wow_english/common/extension/string_extension.dart'; | ||
5 | import 'package:wow_english/common/request/dao/user_dao.dart'; | 7 | import 'package:wow_english/common/request/dao/user_dao.dart'; |
6 | import 'package:wow_english/common/request/exception.dart'; | 8 | import 'package:wow_english/common/request/exception.dart'; |
9 | +import 'package:wow_english/common/request/request.dart'; | ||
7 | import 'package:wow_english/models/user_entity.dart'; | 10 | import 'package:wow_english/models/user_entity.dart'; |
8 | import 'package:wow_english/utils/loading.dart'; | 11 | import 'package:wow_english/utils/loading.dart'; |
9 | 12 | ||
@@ -70,15 +73,22 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | @@ -70,15 +73,22 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | ||
70 | var checkKey = _isSmsLoginType ? 'smsCode' : 'password'; | 73 | var checkKey = _isSmsLoginType ? 'smsCode' : 'password'; |
71 | var type = _isSmsLoginType ? 'sms_code' : 'pwd'; | 74 | var type = _isSmsLoginType ? 'sms_code' : 'pwd'; |
72 | 75 | ||
76 | + | ||
73 | try { | 77 | try { |
78 | + request(() => null); | ||
79 | + | ||
74 | await loading(() async { | 80 | await loading(() async { |
75 | var user = await UserDao.login(phoneNumber, type, checkKey, checkNumber); | 81 | var user = await UserDao.login(phoneNumber, type, checkKey, checkNumber); |
76 | - print('user=$user'); | 82 | + if (kDebugMode) { |
83 | + print('UserEntity?=$user'); | ||
84 | + } | ||
77 | emitter.call(LoginResultChangeState(user!)); | 85 | emitter.call(LoginResultChangeState(user!)); |
78 | }); | 86 | }); |
79 | } catch (e) { | 87 | } catch (e) { |
80 | - print((e as ApiException).message); | ||
81 | - EasyLoading.showToast('登陆失败'); | 88 | + if (kDebugMode) { |
89 | + print(e); | ||
90 | + } | ||
91 | + EasyLoading.showToast('登陆失败${(e as ApiException?)?.message?.prefixColon}'); | ||
82 | } | 92 | } |
83 | } | 93 | } |
84 | 94 | ||
@@ -95,9 +105,10 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | @@ -95,9 +105,10 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | ||
95 | }); | 105 | }); |
96 | emitter(SmsCodeRequestState()); | 106 | emitter(SmsCodeRequestState()); |
97 | } catch (e) { | 107 | } catch (e) { |
98 | - if (e is ApiException) { | ||
99 | - EasyLoading.showToast(e.message??'请检查网络连接'); | ||
100 | - } | 108 | + if (kDebugMode) { |
109 | + print(e); | ||
110 | + } | ||
111 | + EasyLoading.showToast('获取验证码失败${(e as ApiException?)?.message?.prefixColon}'); | ||
101 | } | 112 | } |
102 | } | 113 | } |
103 | 114 |
lib/utils/loading.dart
1 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 1 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
2 | 2 | ||
3 | -Future<T?> loading<T>(Function block, {String loadingText = '加载中...'}) async { | 3 | +Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) async { |
4 | if (loadingText.isNotEmpty) { | 4 | if (loadingText.isNotEmpty) { |
5 | showLoading(loadingText); | 5 | showLoading(loadingText); |
6 | } | 6 | } |