Showing
15 changed files
with
257 additions
and
77 deletions
| ... | @@ -54,8 +54,8 @@ class MessageLookup extends MessageLookupByLibrary { | ... | @@ -54,8 +54,8 @@ class MessageLookup extends MessageLookupByLibrary { |
| 54 | MessageLookupByLibrary.simpleMessage("Get verification code"), | 54 | MessageLookupByLibrary.simpleMessage("Get verification code"), |
| 55 | "inputEmailHint": | 55 | "inputEmailHint": |
| 56 | MessageLookupByLibrary.simpleMessage("Please enter email address"), | 56 | MessageLookupByLibrary.simpleMessage("Please enter email address"), |
| 57 | - "inputPasswordHint": | 57 | + "inputPasswordHint": MessageLookupByLibrary.simpleMessage( |
| 58 | - MessageLookupByLibrary.simpleMessage("Please enter the password"), | 58 | + "Please enter the password(at least 6)"), |
| 59 | "inputPhoneHint": | 59 | "inputPhoneHint": |
| 60 | MessageLookupByLibrary.simpleMessage("Please enter phone number"), | 60 | MessageLookupByLibrary.simpleMessage("Please enter phone number"), |
| 61 | "inputPhoneInvalid": MessageLookupByLibrary.simpleMessage( | 61 | "inputPhoneInvalid": MessageLookupByLibrary.simpleMessage( | ... | ... |
| ... | @@ -46,7 +46,8 @@ class MessageLookup extends MessageLookupByLibrary { | ... | @@ -46,7 +46,8 @@ class MessageLookup extends MessageLookupByLibrary { |
| 46 | "forgotPasswordLink": MessageLookupByLibrary.simpleMessage("忘记密码"), | 46 | "forgotPasswordLink": MessageLookupByLibrary.simpleMessage("忘记密码"), |
| 47 | "getVerificationCode": MessageLookupByLibrary.simpleMessage("获取验证码"), | 47 | "getVerificationCode": MessageLookupByLibrary.simpleMessage("获取验证码"), |
| 48 | "inputEmailHint": MessageLookupByLibrary.simpleMessage("请输入邮箱地址"), | 48 | "inputEmailHint": MessageLookupByLibrary.simpleMessage("请输入邮箱地址"), |
| 49 | - "inputPasswordHint": MessageLookupByLibrary.simpleMessage("请输入密码"), | 49 | + "inputPasswordHint": |
| 50 | + MessageLookupByLibrary.simpleMessage("请输入密码(至少6位字母和数字组合)"), | ||
| 50 | "inputPhoneHint": MessageLookupByLibrary.simpleMessage("请输入手机号"), | 51 | "inputPhoneHint": MessageLookupByLibrary.simpleMessage("请输入手机号"), |
| 51 | "inputPhoneInvalid": MessageLookupByLibrary.simpleMessage("请输入有效的手机号"), | 52 | "inputPhoneInvalid": MessageLookupByLibrary.simpleMessage("请输入有效的手机号"), |
| 52 | "inputUsernameHint": MessageLookupByLibrary.simpleMessage("请输入账号"), | 53 | "inputUsernameHint": MessageLookupByLibrary.simpleMessage("请输入账号"), | ... | ... |
| ... | @@ -9,6 +9,8 @@ import 'package:Parlando/category/models/category_item_entity.dart'; | ... | @@ -9,6 +9,8 @@ import 'package:Parlando/category/models/category_item_entity.dart'; |
| 9 | import 'package:Parlando/generated/json/category_item_entity.g.dart'; | 9 | import 'package:Parlando/generated/json/category_item_entity.g.dart'; |
| 10 | import 'package:Parlando/home/models/setting_entity.dart'; | 10 | import 'package:Parlando/home/models/setting_entity.dart'; |
| 11 | import 'package:Parlando/generated/json/setting_entity.g.dart'; | 11 | import 'package:Parlando/generated/json/setting_entity.g.dart'; |
| 12 | +import 'package:Parlando/login/models/login_entity.dart'; | ||
| 13 | +import 'package:Parlando/generated/json/login_entity.g.dart'; | ||
| 12 | import 'package:Parlando/poem/models/lang_sort_entity.dart'; | 14 | import 'package:Parlando/poem/models/lang_sort_entity.dart'; |
| 13 | import 'package:Parlando/generated/json/lang_sort_entity.g.dart'; | 15 | import 'package:Parlando/generated/json/lang_sort_entity.g.dart'; |
| 14 | import 'package:Parlando/poem/models/search_entity.dart'; | 16 | import 'package:Parlando/poem/models/search_entity.dart'; |
| ... | @@ -102,6 +104,15 @@ class JsonConvert { | ... | @@ -102,6 +104,15 @@ class JsonConvert { |
| 102 | if (type == (SettingError).toString()) { | 104 | if (type == (SettingError).toString()) { |
| 103 | return SettingError.fromJson(json) as M; | 105 | return SettingError.fromJson(json) as M; |
| 104 | } | 106 | } |
| 107 | + if (type == (LoginEntity).toString()) { | ||
| 108 | + return LoginEntity.fromJson(json) as M; | ||
| 109 | + } | ||
| 110 | + if (type == (LoginData).toString()) { | ||
| 111 | + return LoginData.fromJson(json) as M; | ||
| 112 | + } | ||
| 113 | + if (type == (LoginError).toString()) { | ||
| 114 | + return LoginError.fromJson(json) as M; | ||
| 115 | + } | ||
| 105 | if (type == (LangSortEntity).toString()) { | 116 | if (type == (LangSortEntity).toString()) { |
| 106 | return LangSortEntity.fromJson(json) as M; | 117 | return LangSortEntity.fromJson(json) as M; |
| 107 | } | 118 | } |
| ... | @@ -114,13 +125,13 @@ class JsonConvert { | ... | @@ -114,13 +125,13 @@ class JsonConvert { |
| 114 | if (type == (SearchItemsOwner).toString()) { | 125 | if (type == (SearchItemsOwner).toString()) { |
| 115 | return SearchItemsOwner.fromJson(json) as M; | 126 | return SearchItemsOwner.fromJson(json) as M; |
| 116 | } | 127 | } |
| 117 | - if(type == (SearchItemsLicense).toString()){ | 128 | + if (type == (SearchItemsLicense).toString()) { |
| 118 | return SearchItemsLicense.fromJson(json) as M; | 129 | return SearchItemsLicense.fromJson(json) as M; |
| 119 | } | 130 | } |
| 120 | - if(type == (FriendEntity).toString()){ | 131 | + if (type == (FriendEntity).toString()) { |
| 121 | return FriendEntity.fromJson(json) as M; | 132 | return FriendEntity.fromJson(json) as M; |
| 122 | } | 133 | } |
| 123 | - if(type == (FriendData).toString()){ | 134 | + if (type == (FriendData).toString()) { |
| 124 | return FriendData.fromJson(json) as M; | 135 | return FriendData.fromJson(json) as M; |
| 125 | } | 136 | } |
| 126 | 137 | ||
| ... | @@ -165,6 +176,21 @@ class JsonConvert { | ... | @@ -165,6 +176,21 @@ class JsonConvert { |
| 165 | (Map<String, dynamic> e) => SettingError.fromJson(e)) | 176 | (Map<String, dynamic> e) => SettingError.fromJson(e)) |
| 166 | .toList() as M; | 177 | .toList() as M; |
| 167 | } | 178 | } |
| 179 | + if (<LoginEntity>[] is M) { | ||
| 180 | + return data | ||
| 181 | + .map<LoginEntity>((Map<String, dynamic> e) => LoginEntity.fromJson(e)) | ||
| 182 | + .toList() as M; | ||
| 183 | + } | ||
| 184 | + if (<LoginData>[] is M) { | ||
| 185 | + return data | ||
| 186 | + .map<LoginData>((Map<String, dynamic> e) => LoginData.fromJson(e)) | ||
| 187 | + .toList() as M; | ||
| 188 | + } | ||
| 189 | + if (<LoginError>[] is M) { | ||
| 190 | + return data | ||
| 191 | + .map<LoginError>((Map<String, dynamic> e) => LoginError.fromJson(e)) | ||
| 192 | + .toList() as M; | ||
| 193 | + } | ||
| 168 | if (<LangSortEntity>[] is M) { | 194 | if (<LangSortEntity>[] is M) { |
| 169 | return data | 195 | return data |
| 170 | .map<LangSortEntity>( | 196 | .map<LangSortEntity>( |
| ... | @@ -183,16 +209,27 @@ class JsonConvert { | ... | @@ -183,16 +209,27 @@ class JsonConvert { |
| 183 | .toList() as M; | 209 | .toList() as M; |
| 184 | } | 210 | } |
| 185 | if (<SearchItemsOwner>[] is M) { | 211 | if (<SearchItemsOwner>[] is M) { |
| 186 | - return data.map<SearchItemsOwner>((Map<String, dynamic> e) => SearchItemsOwner.fromJson(e)).toList() as M; | 212 | + return data |
| 213 | + .map<SearchItemsOwner>( | ||
| 214 | + (Map<String, dynamic> e) => SearchItemsOwner.fromJson(e)) | ||
| 215 | + .toList() as M; | ||
| 187 | } | 216 | } |
| 188 | - if(<SearchItemsLicense>[] is M){ | 217 | + if (<SearchItemsLicense>[] is M) { |
| 189 | - return data.map<SearchItemsLicense>((Map<String, dynamic> e) => SearchItemsLicense.fromJson(e)).toList() as M; | 218 | + return data |
| 219 | + .map<SearchItemsLicense>( | ||
| 220 | + (Map<String, dynamic> e) => SearchItemsLicense.fromJson(e)) | ||
| 221 | + .toList() as M; | ||
| 190 | } | 222 | } |
| 191 | - if(<FriendEntity>[] is M){ | 223 | + if (<FriendEntity>[] is M) { |
| 192 | - return data.map<FriendEntity>((Map<String, dynamic> e) => FriendEntity.fromJson(e)).toList() as M; | 224 | + return data |
| 225 | + .map<FriendEntity>( | ||
| 226 | + (Map<String, dynamic> e) => FriendEntity.fromJson(e)) | ||
| 227 | + .toList() as M; | ||
| 193 | } | 228 | } |
| 194 | - if(<FriendData>[] is M){ | 229 | + if (<FriendData>[] is M) { |
| 195 | - return data.map<FriendData>((Map<String, dynamic> e) => FriendData.fromJson(e)).toList() as M; | 230 | + return data |
| 231 | + .map<FriendData>((Map<String, dynamic> e) => FriendData.fromJson(e)) | ||
| 232 | + .toList() as M; | ||
| 196 | } | 233 | } |
| 197 | 234 | ||
| 198 | print("${M.toString()} not found"); | 235 | print("${M.toString()} not found"); | ... | ... |
lib/generated/json/login_entity.g.dart
0 → 100644
| 1 | +import 'package:Parlando/generated/json/base/json_convert_content.dart'; | ||
| 2 | +import 'package:Parlando/login/models/login_entity.dart'; | ||
| 3 | + | ||
| 4 | +LoginEntity $LoginEntityFromJson(Map<String, dynamic> json) { | ||
| 5 | + final LoginEntity loginEntity = LoginEntity(); | ||
| 6 | + final String? status = jsonConvert.convert<String>(json['status']); | ||
| 7 | + if (status != null) { | ||
| 8 | + loginEntity.status = status; | ||
| 9 | + } | ||
| 10 | + final int? code = jsonConvert.convert<int>(json['code']); | ||
| 11 | + if (code != null) { | ||
| 12 | + loginEntity.code = code; | ||
| 13 | + } | ||
| 14 | + final String? message = jsonConvert.convert<String>(json['message']); | ||
| 15 | + if (message != null) { | ||
| 16 | + loginEntity.message = message; | ||
| 17 | + } | ||
| 18 | + final LoginData? data = jsonConvert.convert<LoginData>(json['data']); | ||
| 19 | + if (data != null) { | ||
| 20 | + loginEntity.data = data; | ||
| 21 | + } | ||
| 22 | + final LoginError? error = jsonConvert.convert<LoginError>(json['error']); | ||
| 23 | + if (error != null) { | ||
| 24 | + loginEntity.error = error; | ||
| 25 | + } | ||
| 26 | + return loginEntity; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +Map<String, dynamic> $LoginEntityToJson(LoginEntity entity) { | ||
| 30 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 31 | + data['status'] = entity.status; | ||
| 32 | + data['code'] = entity.code; | ||
| 33 | + data['message'] = entity.message; | ||
| 34 | + data['data'] = entity.data?.toJson(); | ||
| 35 | + data['error'] = entity.error?.toJson(); | ||
| 36 | + return data; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +LoginData $LoginDataFromJson(Map<String, dynamic> json) { | ||
| 40 | + final LoginData loginData = LoginData(); | ||
| 41 | + final String? token = jsonConvert.convert<String>(json['token']); | ||
| 42 | + if (token != null) { | ||
| 43 | + loginData.token = token; | ||
| 44 | + } | ||
| 45 | + return loginData; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +Map<String, dynamic> $LoginDataToJson(LoginData entity) { | ||
| 49 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 50 | + data['token'] = entity.token; | ||
| 51 | + return data; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +LoginError $LoginErrorFromJson(Map<String, dynamic> json) { | ||
| 55 | + final LoginError loginError = LoginError(); | ||
| 56 | + return loginError; | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +Map<String, dynamic> $LoginErrorToJson(LoginError entity) { | ||
| 60 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 61 | + return data; | ||
| 62 | +} |
| ... | @@ -100,12 +100,12 @@ class S { | ... | @@ -100,12 +100,12 @@ class S { |
| 100 | ); | 100 | ); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | - /// `Please enter the password` | 103 | + /// `Please enter the password(at least 6)` |
| 104 | String get inputPasswordHint { | 104 | String get inputPasswordHint { |
| 105 | return Intl.message( | 105 | return Intl.message( |
| 106 | - 'Please enter the password', | 106 | + 'Please enter the password(at least 6)', |
| 107 | name: 'inputPasswordHint', | 107 | name: 'inputPasswordHint', |
| 108 | - desc: 'Please enter the password', | 108 | + desc: 'Please enter the password(at least 6)', |
| 109 | args: [], | 109 | args: [], |
| 110 | ); | 110 | ); |
| 111 | } | 111 | } | ... | ... |
| ... | @@ -30,9 +30,9 @@ | ... | @@ -30,9 +30,9 @@ |
| 30 | "type": "text", | 30 | "type": "text", |
| 31 | "placeholders": {} | 31 | "placeholders": {} |
| 32 | }, | 32 | }, |
| 33 | - "inputPasswordHint": "Please enter the password", | 33 | + "inputPasswordHint": "Please enter the password(at least 6)", |
| 34 | "@inputPasswordHint": { | 34 | "@inputPasswordHint": { |
| 35 | - "description": "Please enter the password", | 35 | + "description": "Please enter the password(at least 6)", |
| 36 | "type": "text", | 36 | "type": "text", |
| 37 | "placeholders": {} | 37 | "placeholders": {} |
| 38 | }, | 38 | }, |
| ... | @@ -137,7 +137,6 @@ | ... | @@ -137,7 +137,6 @@ |
| 137 | "type": "text", | 137 | "type": "text", |
| 138 | "placeholders": {} | 138 | "placeholders": {} |
| 139 | }, | 139 | }, |
| 140 | - | ||
| 141 | "accountEditPageUserInfo": "User Info", | 140 | "accountEditPageUserInfo": "User Info", |
| 142 | "@accountEditPageTitle": { | 141 | "@accountEditPageTitle": { |
| 143 | "description": "User Info", | 142 | "description": "User Info", | ... | ... |
| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | "passwordLogin": "密码登录", | 4 | "passwordLogin": "密码登录", |
| 5 | "login": "登录", | 5 | "login": "登录", |
| 6 | "forgotPasswordLink": "忘记密码", | 6 | "forgotPasswordLink": "忘记密码", |
| 7 | - "inputPasswordHint": "请输入密码", | 7 | + "inputPasswordHint": "请输入密码(至少6位字母和数字组合)", |
| 8 | "inputUsernameHint": "请输入账号", | 8 | "inputUsernameHint": "请输入账号", |
| 9 | "noAccountRegisterLink": "还没账号?快去注册", | 9 | "noAccountRegisterLink": "还没账号?快去注册", |
| 10 | "register": "注册", | 10 | "register": "注册", | ... | ... |
lib/login/models/login_entity.dart
0 → 100644
| 1 | +import 'dart:convert'; | ||
| 2 | +import 'package:Parlando/generated/json/base/json_field.dart'; | ||
| 3 | +import 'package:Parlando/generated/json/login_entity.g.dart'; | ||
| 4 | + | ||
| 5 | +@JsonSerializable() | ||
| 6 | +class LoginEntity { | ||
| 7 | + String? status; | ||
| 8 | + int? code; | ||
| 9 | + String? message; | ||
| 10 | + LoginData? data; | ||
| 11 | + LoginError? error; | ||
| 12 | + | ||
| 13 | + LoginEntity(); | ||
| 14 | + | ||
| 15 | + factory LoginEntity.fromJson(Map<String, dynamic> json) => | ||
| 16 | + $LoginEntityFromJson(json); | ||
| 17 | + | ||
| 18 | + Map<String, dynamic> toJson() => $LoginEntityToJson(this); | ||
| 19 | + | ||
| 20 | + @override | ||
| 21 | + String toString() { | ||
| 22 | + return jsonEncode(this); | ||
| 23 | + } | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +@JsonSerializable() | ||
| 27 | +class LoginData { | ||
| 28 | + String? token; | ||
| 29 | + | ||
| 30 | + LoginData(); | ||
| 31 | + | ||
| 32 | + factory LoginData.fromJson(Map<String, dynamic> json) => | ||
| 33 | + $LoginDataFromJson(json); | ||
| 34 | + | ||
| 35 | + Map<String, dynamic> toJson() => $LoginDataToJson(this); | ||
| 36 | + | ||
| 37 | + @override | ||
| 38 | + String toString() { | ||
| 39 | + return jsonEncode(this); | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +@JsonSerializable() | ||
| 44 | +class LoginError { | ||
| 45 | + LoginError(); | ||
| 46 | + | ||
| 47 | + factory LoginError.fromJson(Map<String, dynamic> json) => | ||
| 48 | + $LoginErrorFromJson(json); | ||
| 49 | + | ||
| 50 | + Map<String, dynamic> toJson() => $LoginErrorToJson(this); | ||
| 51 | + | ||
| 52 | + @override | ||
| 53 | + String toString() { | ||
| 54 | + return jsonEncode(this); | ||
| 55 | + } | ||
| 56 | +} |
| 1 | +import 'package:Parlando/login/models/login_entity.dart'; | ||
| 2 | +import 'package:Parlando/net/dio_utils.dart'; | ||
| 3 | +import 'package:Parlando/net/http_api.dart'; | ||
| 4 | +import 'package:Parlando/util/toast_utils.dart'; | ||
| 1 | import 'package:flustars/flustars.dart'; | 5 | import 'package:flustars/flustars.dart'; |
| 2 | -import 'package:flutter/cupertino.dart'; | ||
| 3 | import 'package:flutter/gestures.dart'; | 6 | import 'package:flutter/gestures.dart'; |
| 4 | import 'package:flutter/material.dart'; | 7 | import 'package:flutter/material.dart'; |
| 5 | import 'package:flutter/services.dart'; | 8 | import 'package:flutter/services.dart'; |
| ... | @@ -16,6 +19,7 @@ import 'package:Parlando/util/other_utils.dart'; | ... | @@ -16,6 +19,7 @@ import 'package:Parlando/util/other_utils.dart'; |
| 16 | import 'package:Parlando/widgets/my_app_bar.dart'; | 19 | import 'package:Parlando/widgets/my_app_bar.dart'; |
| 17 | import 'package:Parlando/widgets/my_button.dart'; | 20 | import 'package:Parlando/widgets/my_button.dart'; |
| 18 | import 'package:Parlando/widgets/my_scroll_view.dart'; | 21 | import 'package:Parlando/widgets/my_scroll_view.dart'; |
| 22 | +import 'package:getwidget/getwidget.dart'; | ||
| 19 | 23 | ||
| 20 | import '../login_router.dart'; | 24 | import '../login_router.dart'; |
| 21 | 25 | ||
| ... | @@ -40,7 +44,7 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -40,7 +44,7 @@ class _LoginPageState extends State<LoginPage> |
| 40 | final FocusNode _nodeText1 = FocusNode(); | 44 | final FocusNode _nodeText1 = FocusNode(); |
| 41 | final FocusNode _nodeText2 = FocusNode(); | 45 | final FocusNode _nodeText2 = FocusNode(); |
| 42 | bool _clickable = false; | 46 | bool _clickable = false; |
| 43 | - bool isLogin = false; | 47 | + bool _isLoading = false; |
| 44 | 48 | ||
| 45 | @override | 49 | @override |
| 46 | Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() { | 50 | Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() { |
| ... | @@ -106,7 +110,7 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -106,7 +110,7 @@ class _LoginPageState extends State<LoginPage> |
| 106 | final String name = _nameController.text; | 110 | final String name = _nameController.text; |
| 107 | final String password = _passwordController.text; | 111 | final String password = _passwordController.text; |
| 108 | bool clickable = true; | 112 | bool clickable = true; |
| 109 | - if (name.isEmpty || name.length < 11) { | 113 | + if (name.isEmpty || name.length < 5) { |
| 110 | clickable = false; | 114 | clickable = false; |
| 111 | } | 115 | } |
| 112 | if (password.isEmpty || password.length < 6) { | 116 | if (password.isEmpty || password.length < 6) { |
| ... | @@ -122,13 +126,28 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -122,13 +126,28 @@ class _LoginPageState extends State<LoginPage> |
| 122 | } | 126 | } |
| 123 | 127 | ||
| 124 | void _login() { | 128 | void _login() { |
| 125 | - isLogin = true; | ||
| 126 | setState(() {}); | 129 | setState(() {}); |
| 127 | - Future.delayed(const Duration(seconds: 2), () { | 130 | + _isLoading = true; |
| 128 | - //TODO 接入接口后获得user token则表明登录成功 | 131 | + setState(() {}); |
| 129 | - SpUtil.putString(Constant.userToken, "this is user token!"); | 132 | + Map<String, String> params = <String, String>{ |
| 133 | + "email": _nameController.text, | ||
| 134 | + "password": _passwordController.text, | ||
| 135 | + }; | ||
| 136 | + DioUtils.instance.asyncRequestNetwork<LoginEntity>( | ||
| 137 | + Method.post, | ||
| 138 | + HttpApi.login, | ||
| 139 | + params: params, | ||
| 140 | + onSuccess: (data) { | ||
| 141 | + SpUtil.putString(Constant.userToken, data!.data!.token!); | ||
| 130 | NavigatorUtils.push(context, Routes.home, clearStack: true); | 142 | NavigatorUtils.push(context, Routes.home, clearStack: true); |
| 131 | - }); | 143 | + _isLoading = false; |
| 144 | + }, | ||
| 145 | + onError: (code, msg) { | ||
| 146 | + Toast.show(msg.toString()); | ||
| 147 | + _isLoading = false; | ||
| 148 | + setState(() {}); | ||
| 149 | + }, | ||
| 150 | + ); | ||
| 132 | } | 151 | } |
| 133 | 152 | ||
| 134 | @override | 153 | @override |
| ... | @@ -167,13 +186,9 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -167,13 +186,9 @@ class _LoginPageState extends State<LoginPage> |
| 167 | ), | 186 | ), |
| 168 | children: _buildBody, | 187 | children: _buildBody, |
| 169 | ), | 188 | ), |
| 170 | - isLogin | 189 | + Container( |
| 171 | - ? const Center( | 190 | + child: _isLoading ? const GFLoader() : null, |
| 172 | - child: CupertinoActivityIndicator( | ||
| 173 | - radius: 16.0, | ||
| 174 | ), | 191 | ), |
| 175 | - ) | ||
| 176 | - : Container(), | ||
| 177 | ], | 192 | ], |
| 178 | ), | 193 | ), |
| 179 | ); | 194 | ); |
| ... | @@ -186,12 +201,12 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -186,12 +201,12 @@ class _LoginPageState extends State<LoginPage> |
| 186 | ), | 201 | ), |
| 187 | Gaps.vGap16, | 202 | Gaps.vGap16, |
| 188 | MyTextField( | 203 | MyTextField( |
| 189 | - key: const Key('phone'), | 204 | + key: const Key('email'), |
| 190 | focusNode: _nodeText1, | 205 | focusNode: _nodeText1, |
| 191 | controller: _nameController, | 206 | controller: _nameController, |
| 192 | - maxLength: 11, | 207 | + maxLength: 100, |
| 193 | - keyboardType: TextInputType.phone, | 208 | + keyboardType: TextInputType.emailAddress, |
| 194 | - hintText: ParlandoLocalizations.of(context).inputUsernameHint, | 209 | + hintText: ParlandoLocalizations.of(context).inputEmailHint, |
| 195 | ), | 210 | ), |
| 196 | Gaps.vGap8, | 211 | Gaps.vGap8, |
| 197 | MyTextField( | 212 | MyTextField( | ... | ... |
| ... | @@ -59,7 +59,7 @@ class _RegisterPageState extends State<RegisterPage> | ... | @@ -59,7 +59,7 @@ class _RegisterPageState extends State<RegisterPage> |
| 59 | final String vCode = _vCodeController.text; | 59 | final String vCode = _vCodeController.text; |
| 60 | final String password = _passwordController.text; | 60 | final String password = _passwordController.text; |
| 61 | bool clickable = true; | 61 | bool clickable = true; |
| 62 | - if (name.isEmpty || name.length < 11) { | 62 | + if (name.isEmpty || name.length < 5) { |
| 63 | clickable = false; | 63 | clickable = false; |
| 64 | } | 64 | } |
| 65 | if (vCode.isEmpty || vCode.length < 6) { | 65 | if (vCode.isEmpty || vCode.length < 6) { |
| ... | @@ -95,6 +95,7 @@ class _RegisterPageState extends State<RegisterPage> | ... | @@ -95,6 +95,7 @@ class _RegisterPageState extends State<RegisterPage> |
| 95 | onError: (code, msg) { | 95 | onError: (code, msg) { |
| 96 | Toast.show(msg); | 96 | Toast.show(msg); |
| 97 | _isLoading = false; | 97 | _isLoading = false; |
| 98 | + setState(() {}); | ||
| 98 | }, | 99 | }, |
| 99 | ); | 100 | ); |
| 100 | } | 101 | } |
| ... | @@ -123,7 +124,7 @@ class _RegisterPageState extends State<RegisterPage> | ... | @@ -123,7 +124,7 @@ class _RegisterPageState extends State<RegisterPage> |
| 123 | ), | 124 | ), |
| 124 | Gaps.vGap16, | 125 | Gaps.vGap16, |
| 125 | MyTextField( | 126 | MyTextField( |
| 126 | - key: const Key('phone'), | 127 | + key: const Key('email'), |
| 127 | focusNode: _nodeText1, | 128 | focusNode: _nodeText1, |
| 128 | controller: _nameController, | 129 | controller: _nameController, |
| 129 | maxLength: 100, | 130 | maxLength: 100, | ... | ... |
| ... | @@ -35,7 +35,6 @@ typedef NetErrorCallback = Function(int code, String msg); | ... | @@ -35,7 +35,6 @@ typedef NetErrorCallback = Function(int code, String msg); |
| 35 | 35 | ||
| 36 | /// @weilu https://github.com/simplezhli | 36 | /// @weilu https://github.com/simplezhli |
| 37 | class DioUtils { | 37 | class DioUtils { |
| 38 | - | ||
| 39 | factory DioUtils() => _singleton; | 38 | factory DioUtils() => _singleton; |
| 40 | 39 | ||
| 41 | DioUtils._() { | 40 | DioUtils._() { |
| ... | @@ -43,6 +42,7 @@ class DioUtils { | ... | @@ -43,6 +42,7 @@ class DioUtils { |
| 43 | connectTimeout: _connectTimeout, | 42 | connectTimeout: _connectTimeout, |
| 44 | receiveTimeout: _receiveTimeout, | 43 | receiveTimeout: _receiveTimeout, |
| 45 | sendTimeout: _sendTimeout, | 44 | sendTimeout: _sendTimeout, |
| 45 | + | ||
| 46 | /// dio默认json解析,这里指定返回UTF8字符串,自己处理解析。(可也以自定义Transformer实现) | 46 | /// dio默认json解析,这里指定返回UTF8字符串,自己处理解析。(可也以自定义Transformer实现) |
| 47 | responseType: ResponseType.plain, | 47 | responseType: ResponseType.plain, |
| 48 | validateStatus: (_) { | 48 | validateStatus: (_) { |
| ... | @@ -53,6 +53,7 @@ class DioUtils { | ... | @@ -53,6 +53,7 @@ class DioUtils { |
| 53 | // contentType: Headers.formUrlEncodedContentType, // 适用于post form表单提交 | 53 | // contentType: Headers.formUrlEncodedContentType, // 适用于post form表单提交 |
| 54 | ); | 54 | ); |
| 55 | _dio = Dio(_options); | 55 | _dio = Dio(_options); |
| 56 | + | ||
| 56 | /// Fiddler抓包代理配置 https://www.jianshu.com/p/d831b1f7c45b | 57 | /// Fiddler抓包代理配置 https://www.jianshu.com/p/d831b1f7c45b |
| 57 | // (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = | 58 | // (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = |
| 58 | // (HttpClient client) { | 59 | // (HttpClient client) { |
| ... | @@ -68,6 +69,7 @@ class DioUtils { | ... | @@ -68,6 +69,7 @@ class DioUtils { |
| 68 | void addInterceptor(Interceptor interceptor) { | 69 | void addInterceptor(Interceptor interceptor) { |
| 69 | _dio.interceptors.add(interceptor); | 70 | _dio.interceptors.add(interceptor); |
| 70 | } | 71 | } |
| 72 | + | ||
| 71 | _interceptors.forEach(addInterceptor); | 73 | _interceptors.forEach(addInterceptor); |
| 72 | } | 74 | } |
| 73 | 75 | ||
| ... | @@ -80,7 +82,9 @@ class DioUtils { | ... | @@ -80,7 +82,9 @@ class DioUtils { |
| 80 | Dio get dio => _dio; | 82 | Dio get dio => _dio; |
| 81 | 83 | ||
| 82 | // 数据返回格式统一,统一处理异常 | 84 | // 数据返回格式统一,统一处理异常 |
| 83 | - Future<BaseEntity<T>> _request<T>(String method, String url, { | 85 | + Future<BaseEntity<T>> _request<T>( |
| 86 | + String method, | ||
| 87 | + String url, { | ||
| 84 | Object? data, | 88 | Object? data, |
| 85 | Map<String, dynamic>? queryParameters, | 89 | Map<String, dynamic>? queryParameters, |
| 86 | CancelToken? cancelToken, | 90 | CancelToken? cancelToken, |
| ... | @@ -95,14 +99,16 @@ class DioUtils { | ... | @@ -95,14 +99,16 @@ class DioUtils { |
| 95 | ); | 99 | ); |
| 96 | try { | 100 | try { |
| 97 | final String data = response.data.toString(); | 101 | final String data = response.data.toString(); |
| 102 | + | ||
| 98 | /// 集成测试无法使用 isolate https://github.com/flutter/flutter/issues/24703 | 103 | /// 集成测试无法使用 isolate https://github.com/flutter/flutter/issues/24703 |
| 99 | /// 使用compute条件:数据大于10KB(粗略使用10 * 1024)且当前不是集成测试(后面可能会根据Web环境进行调整) | 104 | /// 使用compute条件:数据大于10KB(粗略使用10 * 1024)且当前不是集成测试(后面可能会根据Web环境进行调整) |
| 100 | /// 主要目的减少不必要的性能开销 | 105 | /// 主要目的减少不必要的性能开销 |
| 101 | final bool isCompute = !Constant.isDriverTest && data.length > 10 * 1024; | 106 | final bool isCompute = !Constant.isDriverTest && data.length > 10 * 1024; |
| 102 | debugPrint('isCompute:$isCompute'); | 107 | debugPrint('isCompute:$isCompute'); |
| 103 | - final Map<String, dynamic> _map = isCompute ? await compute(parseData, data) : parseData(data); | 108 | + final Map<String, dynamic> _map = |
| 109 | + isCompute ? await compute(parseData, data) : parseData(data); | ||
| 104 | return BaseEntity<T>.fromJson(_map); | 110 | return BaseEntity<T>.fromJson(_map); |
| 105 | - } catch(e) { | 111 | + } catch (e) { |
| 106 | debugPrint(e.toString()); | 112 | debugPrint(e.toString()); |
| 107 | return BaseEntity<T>(ExceptionHandle.parse_error, '数据解析错误!', null); | 113 | return BaseEntity<T>(ExceptionHandle.parse_error, '数据解析错误!', null); |
| 108 | } | 114 | } |
| ... | @@ -114,7 +120,9 @@ class DioUtils { | ... | @@ -114,7 +120,9 @@ class DioUtils { |
| 114 | return options; | 120 | return options; |
| 115 | } | 121 | } |
| 116 | 122 | ||
| 117 | - Future requestNetwork<T>(Method method, String url, { | 123 | + Future requestNetwork<T>( |
| 124 | + Method method, | ||
| 125 | + String url, { | ||
| 118 | NetSuccessCallback<T?>? onSuccess, | 126 | NetSuccessCallback<T?>? onSuccess, |
| 119 | NetErrorCallback? onError, | 127 | NetErrorCallback? onError, |
| 120 | Object? params, | 128 | Object? params, |
| ... | @@ -122,7 +130,9 @@ class DioUtils { | ... | @@ -122,7 +130,9 @@ class DioUtils { |
| 122 | CancelToken? cancelToken, | 130 | CancelToken? cancelToken, |
| 123 | Options? options, | 131 | Options? options, |
| 124 | }) { | 132 | }) { |
| 125 | - return _request<T>(method.value, url, | 133 | + return _request<T>( |
| 134 | + method.value, | ||
| 135 | + url, | ||
| 126 | data: params, | 136 | data: params, |
| 127 | queryParameters: queryParameters, | 137 | queryParameters: queryParameters, |
| 128 | options: options, | 138 | options: options, |
| ... | @@ -141,7 +151,9 @@ class DioUtils { | ... | @@ -141,7 +151,9 @@ class DioUtils { |
| 141 | } | 151 | } |
| 142 | 152 | ||
| 143 | /// 统一处理(onSuccess返回T对象,onSuccessList返回 List<T>) | 153 | /// 统一处理(onSuccess返回T对象,onSuccessList返回 List<T>) |
| 144 | - void asyncRequestNetwork<T>(Method method, String url, { | 154 | + void asyncRequestNetwork<T>( |
| 155 | + Method method, | ||
| 156 | + String url, { | ||
| 145 | NetSuccessCallback<T?>? onSuccess, | 157 | NetSuccessCallback<T?>? onSuccess, |
| 146 | NetErrorCallback? onError, | 158 | NetErrorCallback? onError, |
| 147 | Object? params, | 159 | Object? params, |
| ... | @@ -149,13 +161,14 @@ class DioUtils { | ... | @@ -149,13 +161,14 @@ class DioUtils { |
| 149 | CancelToken? cancelToken, | 161 | CancelToken? cancelToken, |
| 150 | Options? options, | 162 | Options? options, |
| 151 | }) { | 163 | }) { |
| 152 | - Stream.fromFuture(_request<T>(method.value, url, | 164 | + Stream.fromFuture(_request<T>( |
| 165 | + method.value, | ||
| 166 | + url, | ||
| 153 | data: params, | 167 | data: params, |
| 154 | queryParameters: queryParameters, | 168 | queryParameters: queryParameters, |
| 155 | options: options, | 169 | options: options, |
| 156 | cancelToken: cancelToken, | 170 | cancelToken: cancelToken, |
| 157 | - )).asBroadcastStream() | 171 | + )).asBroadcastStream().listen((result) { |
| 158 | - .listen((result) { | ||
| 159 | if (result.code == 0) { | 172 | if (result.code == 0) { |
| 160 | if (onSuccess != null) { | 173 | if (onSuccess != null) { |
| 161 | onSuccess(result.data); | 174 | onSuccess(result.data); |
| ... | @@ -190,14 +203,7 @@ Map<String, dynamic> parseData(String data) { | ... | @@ -190,14 +203,7 @@ Map<String, dynamic> parseData(String data) { |
| 190 | return json.decode(data) as Map<String, dynamic>; | 203 | return json.decode(data) as Map<String, dynamic>; |
| 191 | } | 204 | } |
| 192 | 205 | ||
| 193 | -enum Method { | 206 | +enum Method { get, post, put, patch, delete, head } |
| 194 | - get, | ||
| 195 | - post, | ||
| 196 | - put, | ||
| 197 | - patch, | ||
| 198 | - delete, | ||
| 199 | - head | ||
| 200 | -} | ||
| 201 | 207 | ||
| 202 | /// 使用拓展枚举替代 switch判断取值 | 208 | /// 使用拓展枚举替代 switch判断取值 |
| 203 | /// https://zhuanlan.zhihu.com/p/98545689 | 209 | /// https://zhuanlan.zhihu.com/p/98545689 | ... | ... |
| ... | @@ -2,6 +2,7 @@ class HttpApi { | ... | @@ -2,6 +2,7 @@ class HttpApi { |
| 2 | static const String setting = 'setting'; | 2 | static const String setting = 'setting'; |
| 3 | static const String register = 'register'; | 3 | static const String register = 'register'; |
| 4 | static const String verify = 'verify'; | 4 | static const String verify = 'verify'; |
| 5 | + static const String login = 'login'; | ||
| 5 | static const String search = 'search/repositories'; | 6 | static const String search = 'search/repositories'; |
| 6 | static const String subscriptions = 'users/simplezhli/subscriptions'; | 7 | static const String subscriptions = 'users/simplezhli/subscriptions'; |
| 7 | static const String upload = 'uuc/upload-inco'; | 8 | static const String upload = 'uuc/upload-inco'; | ... | ... |
| ... | @@ -27,28 +27,29 @@ class AuthInterceptor extends Interceptor { | ... | @@ -27,28 +27,29 @@ class AuthInterceptor extends Interceptor { |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | class TokenInterceptor extends Interceptor { | 29 | class TokenInterceptor extends Interceptor { |
| 30 | - | ||
| 31 | Dio? _tokenDio; | 30 | Dio? _tokenDio; |
| 32 | 31 | ||
| 33 | Future<String?> getToken() async { | 32 | Future<String?> getToken() async { |
| 34 | - | ||
| 35 | final Map<String, String> params = <String, String>{}; | 33 | final Map<String, String> params = <String, String>{}; |
| 36 | params['refresh_token'] = SpUtil.getString(Constant.refreshToken).nullSafe; | 34 | params['refresh_token'] = SpUtil.getString(Constant.refreshToken).nullSafe; |
| 37 | try { | 35 | try { |
| 38 | _tokenDio ??= Dio(); | 36 | _tokenDio ??= Dio(); |
| 39 | _tokenDio!.options = DioUtils.instance.dio.options; | 37 | _tokenDio!.options = DioUtils.instance.dio.options; |
| 40 | - final Response response = await _tokenDio!.post<dynamic>('lgn/refreshToken', data: params); | 38 | + final Response response = |
| 39 | + await _tokenDio!.post<dynamic>('lgn/refreshToken', data: params); | ||
| 41 | if (response.statusCode == ExceptionHandle.success) { | 40 | if (response.statusCode == ExceptionHandle.success) { |
| 42 | - return (json.decode(response.data.toString()) as Map<String, dynamic>)['access_token'] as String; | 41 | + return (json.decode(response.data.toString()) |
| 42 | + as Map<String, dynamic>)['access_token'] as String; | ||
| 43 | } | 43 | } |
| 44 | - } catch(e) { | 44 | + } catch (e) { |
| 45 | Log.e('刷新Token失败!'); | 45 | Log.e('刷新Token失败!'); |
| 46 | } | 46 | } |
| 47 | return null; | 47 | return null; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | @override | 50 | @override |
| 51 | - Future<void> onResponse(Response response, ResponseInterceptorHandler handler) async { | 51 | + Future<void> onResponse( |
| 52 | + Response response, ResponseInterceptorHandler handler) async { | ||
| 52 | //401代表token过期 | 53 | //401代表token过期 |
| 53 | if (response.statusCode == ExceptionHandle.unauthorized) { | 54 | if (response.statusCode == ExceptionHandle.unauthorized) { |
| 54 | Log.d('-----------自动刷新Token------------'); | 55 | Log.d('-----------自动刷新Token------------'); |
| ... | @@ -71,8 +72,10 @@ class TokenInterceptor extends Interceptor { | ... | @@ -71,8 +72,10 @@ class TokenInterceptor extends Interceptor { |
| 71 | 72 | ||
| 72 | try { | 73 | try { |
| 73 | Log.e('----------- 重新请求接口 ------------'); | 74 | Log.e('----------- 重新请求接口 ------------'); |
| 75 | + | ||
| 74 | /// 避免重复执行拦截器,使用tokenDio | 76 | /// 避免重复执行拦截器,使用tokenDio |
| 75 | - final Response response = await _tokenDio!.request<dynamic>(request.path, | 77 | + final Response response = await _tokenDio!.request<dynamic>( |
| 78 | + request.path, | ||
| 76 | data: request.data, | 79 | data: request.data, |
| 77 | queryParameters: request.queryParameters, | 80 | queryParameters: request.queryParameters, |
| 78 | cancelToken: request.cancelToken, | 81 | cancelToken: request.cancelToken, |
| ... | @@ -89,8 +92,7 @@ class TokenInterceptor extends Interceptor { | ... | @@ -89,8 +92,7 @@ class TokenInterceptor extends Interceptor { |
| 89 | } | 92 | } |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | -class LoggingInterceptor extends Interceptor{ | 95 | +class LoggingInterceptor extends Interceptor { |
| 93 | - | ||
| 94 | late DateTime _startTime; | 96 | late DateTime _startTime; |
| 95 | late DateTime _endTime; | 97 | late DateTime _endTime; |
| 96 | 98 | ||
| ... | @@ -101,7 +103,8 @@ class LoggingInterceptor extends Interceptor{ | ... | @@ -101,7 +103,8 @@ class LoggingInterceptor extends Interceptor{ |
| 101 | if (options.queryParameters.isEmpty) { | 103 | if (options.queryParameters.isEmpty) { |
| 102 | Log.d('RequestUrl: ${options.baseUrl}${options.path}'); | 104 | Log.d('RequestUrl: ${options.baseUrl}${options.path}'); |
| 103 | } else { | 105 | } else { |
| 104 | - Log.d('RequestUrl: ${options.baseUrl}${options.path}?${Transformer.urlEncodeMap(options.queryParameters)}'); | 106 | + Log.d( |
| 107 | + 'RequestUrl: ${options.baseUrl}${options.path}?${Transformer.urlEncodeMap(options.queryParameters)}'); | ||
| 105 | } | 108 | } |
| 106 | Log.d('RequestMethod: ${options.method}'); | 109 | Log.d('RequestMethod: ${options.method}'); |
| 107 | Log.d('RequestHeaders:${options.headers}'); | 110 | Log.d('RequestHeaders:${options.headers}'); |
| ... | @@ -132,8 +135,7 @@ class LoggingInterceptor extends Interceptor{ | ... | @@ -132,8 +135,7 @@ class LoggingInterceptor extends Interceptor{ |
| 132 | } | 135 | } |
| 133 | } | 136 | } |
| 134 | 137 | ||
| 135 | -class AdapterInterceptor extends Interceptor{ | 138 | +class AdapterInterceptor extends Interceptor { |
| 136 | - | ||
| 137 | static const String _kMsg = 'msg'; | 139 | static const String _kMsg = 'msg'; |
| 138 | static const String _kSlash = "'"; | 140 | static const String _kSlash = "'"; |
| 139 | static const String _kMessage = 'message'; | 141 | static const String _kMessage = 'message'; |
| ... | @@ -161,8 +163,10 @@ class AdapterInterceptor extends Interceptor{ | ... | @@ -161,8 +163,10 @@ class AdapterInterceptor extends Interceptor{ |
| 161 | Response adapterData(Response response) { | 163 | Response adapterData(Response response) { |
| 162 | String result; | 164 | String result; |
| 163 | String content = response.data?.toString() ?? ''; | 165 | String content = response.data?.toString() ?? ''; |
| 166 | + | ||
| 164 | /// 成功时,直接格式化返回 | 167 | /// 成功时,直接格式化返回 |
| 165 | - if (response.statusCode == ExceptionHandle.success || response.statusCode == ExceptionHandle.success_not_content) { | 168 | + if (response.statusCode == ExceptionHandle.success || |
| 169 | + response.statusCode == ExceptionHandle.success_not_content) { | ||
| 166 | if (content.isEmpty) { | 170 | if (content.isEmpty) { |
| 167 | content = _kDefaultText; | 171 | content = _kDefaultText; |
| 168 | } | 172 | } |
| ... | @@ -180,11 +184,8 @@ class AdapterInterceptor extends Interceptor{ | ... | @@ -180,11 +184,8 @@ class AdapterInterceptor extends Interceptor{ |
| 180 | } else { | 184 | } else { |
| 181 | String msg; | 185 | String msg; |
| 182 | try { | 186 | try { |
| 183 | - content = content.replaceAll(r'\', ''); | 187 | + final Map<String, dynamic> map = |
| 184 | - if (_kSlash == content.substring(0, 1)) { | 188 | + json.decode(content) as Map<String, dynamic>; |
| 185 | - content = content.substring(1, content.length - 1); | ||
| 186 | - } | ||
| 187 | - final Map<String, dynamic> map = json.decode(content) as Map<String, dynamic>; | ||
| 188 | if (map.containsKey(_kMessage)) { | 189 | if (map.containsKey(_kMessage)) { |
| 189 | msg = map[_kMessage] as String; | 190 | msg = map[_kMessage] as String; |
| 190 | } else if (map.containsKey(_kMsg)) { | 191 | } else if (map.containsKey(_kMsg)) { |
| ... | @@ -202,7 +203,8 @@ class AdapterInterceptor extends Interceptor{ | ... | @@ -202,7 +203,8 @@ class AdapterInterceptor extends Interceptor{ |
| 202 | } catch (e) { | 203 | } catch (e) { |
| 203 | // Log.d('异常信息:$e'); | 204 | // Log.d('异常信息:$e'); |
| 204 | // 解析异常直接按照返回原数据处理(一般为返回500,503 HTML页面代码) | 205 | // 解析异常直接按照返回原数据处理(一般为返回500,503 HTML页面代码) |
| 205 | - result = sprintf(_kFailureFormat, [response.statusCode, '服务器异常(${response.statusCode})']); | 206 | + result = sprintf(_kFailureFormat, |
| 207 | + [response.statusCode, '服务器异常(${response.statusCode})']); | ||
| 206 | } | 208 | } |
| 207 | } | 209 | } |
| 208 | } | 210 | } | ... | ... |
-
Please register or login to post a comment