Commit 4b2c2f0785238b0e0fcfdf757590988538a4dd72
1 parent
c61b3c1a
feat: 三种修改密码的类型及接口
Showing
10 changed files
with
117 additions
and
30 deletions
lib/common/request/apis.dart
1 | +part of 'request_client.dart'; | |
2 | + | |
1 | 3 | class Apis { |
2 | 4 | /// app初始化配置信息 |
3 | 5 | // GET /system/app/config |
... | ... | @@ -19,6 +21,15 @@ class Apis { |
19 | 21 | /// 发送验证码 |
20 | 22 | static const String sendSmsCode = 'system/send/code'; |
21 | 23 | |
24 | + /// 初始化密码 | |
25 | + static const String initPassword = 'student/init/password'; | |
26 | + | |
27 | + /// 修改密码 | |
28 | + static const String changePassword = 'student/init/password'; | |
29 | + | |
30 | + /// 忘记密码 | |
31 | + static const String resetPassword = 'student/change/password'; | |
32 | + | |
22 | 33 | /// 课程模块 |
23 | 34 | // GET /home/courseModule |
24 | 35 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897663 | ... | ... |
lib/common/request/dao/home_dao.dart
1 | -import 'package:flutter/foundation.dart'; | |
2 | -import 'package:wow_english/common/request/apis.dart'; | |
3 | 1 | import 'package:wow_english/common/request/request_client.dart'; |
4 | 2 | import 'package:wow_english/models/course_entity.dart'; |
5 | 3 | |
... | ... | @@ -18,10 +16,7 @@ class HomeDao { |
18 | 16 | if (moduleId.isNotEmpty) { |
19 | 17 | mapData['moduleId'] = moduleId; |
20 | 18 | } |
21 | - var data = await requestClient.get<CourseEntity>( | |
22 | - Apis.courseLesson, | |
23 | - queryParameters: mapData | |
24 | - ); | |
19 | + var data = await requestClient.get<CourseEntity>(Apis.courseLesson, queryParameters: mapData); | |
25 | 20 | return data; |
26 | 21 | } |
27 | 22 | } | ... | ... |
lib/common/request/dao/listen_dao.dart
1 | -import 'package:wow_english/common/request/apis.dart'; | |
2 | 1 | import 'package:wow_english/common/request/request_client.dart'; |
3 | 2 | import 'package:wow_english/models/follow_read_entity.dart'; |
4 | 3 | import 'package:wow_english/models/listen_entity.dart'; |
... | ... | @@ -15,4 +14,4 @@ class ListenDao { |
15 | 14 | var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead); |
16 | 15 | return data; |
17 | 16 | } |
18 | -} | |
19 | 17 | \ No newline at end of file |
18 | +} | ... | ... |
lib/common/request/dao/user_dao.dart
1 | 1 | import 'package:wow_english/common/core/user_util.dart'; |
2 | 2 | import 'package:wow_english/models/user_entity.dart'; |
3 | 3 | |
4 | -import '../apis.dart'; | |
5 | 4 | import '../request_client.dart'; |
6 | 5 | |
7 | 6 | class UserDao { |
... | ... | @@ -32,6 +31,27 @@ class UserDao { |
32 | 31 | await requestClient.post(Apis.sendSmsCode, data: params); |
33 | 32 | } |
34 | 33 | |
34 | + /// 设置密码,初始化密码 | |
35 | + /// [password] 密码 | |
36 | + static Future initPassword(String password) async { | |
37 | + final params = {'password': password}; | |
38 | + await requestClient.post(Apis.initPassword, data: params); | |
39 | + } | |
40 | + | |
41 | + /// 修改密码 | |
42 | + /// [password] 密码 | |
43 | + static Future changePassword(String password) async { | |
44 | + final params = {'password': password}; | |
45 | + await requestClient.post(Apis.changePassword, data: params); | |
46 | + } | |
47 | + | |
48 | + /// 忘记密码 | |
49 | + /// [password] 密码 | |
50 | + static Future resetPassword(String phoneNum, String password, String smsCode) async { | |
51 | + final params = {'phoneNum': phoneNum, 'password': password, 'code': smsCode}; | |
52 | + await requestClient.post(Apis.resetPassword, data: params); | |
53 | + } | |
54 | + | |
35 | 55 | /// 获取用户信息 |
36 | 56 | static Future<UserEntity?> getUserInfo() async { |
37 | 57 | return await requestClient.post(Apis.getUserInfo); | ... | ... |
lib/common/request/exception.dart
... | ... | @@ -84,6 +84,11 @@ class ApiException implements Exception { |
84 | 84 | apiException.stackInfo = exception?.toString(); |
85 | 85 | return apiException; |
86 | 86 | } |
87 | + | |
88 | + @override | |
89 | + String toString() { | |
90 | + return 'ApiException{code: $code, message: $message, stackInfo: $stackInfo}'; | |
91 | + } | |
87 | 92 | } |
88 | 93 | |
89 | 94 | /// 请求错误 | ... | ... |
lib/common/request/request_client.dart
lib/pages/login/setpwd/bloc/set_pwd_bloc.dart
1 | 1 | import 'package:flutter/cupertino.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | +import 'package:wow_english/common/request/dao/user_dao.dart'; | |
4 | +import 'package:wow_english/common/request/exception.dart'; | |
5 | +import 'package:wow_english/utils/loading.dart'; | |
3 | 6 | |
4 | 7 | import '../set_pwd_page.dart'; |
5 | 8 | |
... | ... | @@ -7,21 +10,25 @@ part 'set_pwd_event.dart'; |
7 | 10 | part 'set_pwd_state.dart'; |
8 | 11 | |
9 | 12 | class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
10 | - | |
11 | 13 | final String? phoneNumber; |
12 | 14 | final String? smsCode; |
13 | 15 | late final SetPwdPageType pageType; |
14 | 16 | |
15 | 17 | final TextEditingController passWordFirstController = TextEditingController(); |
16 | 18 | final TextEditingController passWordSecondController = TextEditingController(); |
19 | + | |
17 | 20 | ///密码是否符合规则(第一个输入框) |
18 | 21 | bool _passwordEnsure = false; |
22 | + | |
19 | 23 | ///密码是否超过16位(第一个输入框) |
20 | 24 | bool _passwordLarger = false; |
25 | + | |
21 | 26 | ///是否显示Icon(第一个输入框) |
22 | 27 | bool _showPwdIcon = false; |
28 | + | |
23 | 29 | ///是否显示Icon(第二个输入框) |
24 | 30 | bool _showCheckPwdIcon = false; |
31 | + | |
25 | 32 | ///密码是否一致 |
26 | 33 | bool _passwordCheck = true; |
27 | 34 | |
... | ... | @@ -37,14 +44,16 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
37 | 44 | |
38 | 45 | bool get ensure => _passwordCheck && _passwordEnsure; |
39 | 46 | |
47 | + String get passwordText => passWordFirstController.text; | |
48 | + | |
40 | 49 | SetPwdBloc(this.phoneNumber, this.smsCode, this.pageType) : super(SetPwdInitial()) { |
41 | 50 | on<PwdEnsureEvent>(_pwdEnsureTextChange); |
42 | 51 | on<PwdCheckEvent>(_pwdCheckTextChange); |
43 | 52 | on<SetPasswordEvent>(_setPassword); |
44 | 53 | } |
45 | 54 | |
46 | - void _pwdCheckTextChange(PwdCheckEvent event,Emitter<SetPwdState> emitter) async { | |
47 | - if(passWordSecondController.text.isEmpty) { | |
55 | + void _pwdCheckTextChange(PwdCheckEvent event, Emitter<SetPwdState> emitter) async { | |
56 | + if (passWordSecondController.text.isEmpty) { | |
48 | 57 | _showCheckPwdIcon = false; |
49 | 58 | emitter(PasswordCheckIconShowState()); |
50 | 59 | } else { |
... | ... | @@ -53,7 +62,7 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
53 | 62 | emitter(PasswordCheckIconShowState()); |
54 | 63 | } |
55 | 64 | } |
56 | - if(passWordFirstController.text == passWordSecondController.text) { | |
65 | + if (passWordFirstController.text == passWordSecondController.text) { | |
57 | 66 | _passwordCheck = true; |
58 | 67 | emitter(SetCheckPwdState()); |
59 | 68 | } else { |
... | ... | @@ -62,7 +71,7 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
62 | 71 | } |
63 | 72 | } |
64 | 73 | |
65 | - void _pwdEnsureTextChange(PwdEnsureEvent event,Emitter<SetPwdState> emitter) async { | |
74 | + void _pwdEnsureTextChange(PwdEnsureEvent event, Emitter<SetPwdState> emitter) async { | |
66 | 75 | if (passWordFirstController.text.isEmpty) { |
67 | 76 | if (_showPwdIcon) { |
68 | 77 | _showPwdIcon = false; |
... | ... | @@ -73,32 +82,29 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
73 | 82 | _showPwdIcon = true; |
74 | 83 | emitter(PasswordIconShowState()); |
75 | 84 | } |
76 | - if(passWordSecondController.text.isNotEmpty) { | |
85 | + if (passWordSecondController.text.isNotEmpty) { | |
77 | 86 | if (passWordFirstController.text == passWordSecondController.text) { |
78 | 87 | _passwordCheck = true; |
79 | - | |
80 | 88 | } else { |
81 | 89 | _passwordCheck = false; |
82 | 90 | } |
83 | 91 | emitter(SetCheckPwdState()); |
84 | 92 | } |
85 | - if (passWordFirstController.text.length >= 8 && passWordFirstController.text.length <=16) { | |
93 | + if (passWordFirstController.text.length >= 8 && passWordFirstController.text.length <= 16) { | |
86 | 94 | ///符合密码要求 |
87 | - if(!_passwordEnsure) { | |
95 | + if (!_passwordEnsure) { | |
88 | 96 | _passwordEnsure = true; |
89 | 97 | emitter(SetEnsurePwdState()); |
90 | 98 | } |
91 | - if(passWordSecondController.text.isNotEmpty) { | |
92 | - if (passWordFirstController.text == passWordSecondController.text) { | |
93 | - | |
94 | - } | |
99 | + if (passWordSecondController.text.isNotEmpty) { | |
100 | + if (passWordFirstController.text == passWordSecondController.text) {} | |
95 | 101 | } |
96 | 102 | if (_passwordLarger) { |
97 | 103 | _passwordLarger = false; |
98 | 104 | emitter(PasswordLargeState()); |
99 | 105 | } |
100 | 106 | } else { |
101 | - if(passWordFirstController.text.length > 16) { | |
107 | + if (passWordFirstController.text.length > 16) { | |
102 | 108 | ///超过十六位 |
103 | 109 | if (!_passwordLarger) { |
104 | 110 | _passwordLarger = true; |
... | ... | @@ -110,8 +116,9 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
110 | 116 | emitter(PasswordLargeState()); |
111 | 117 | } |
112 | 118 | } |
119 | + | |
113 | 120 | ///密码不符合要求 |
114 | - if(_passwordEnsure) { | |
121 | + if (_passwordEnsure) { | |
115 | 122 | _passwordEnsure = false; |
116 | 123 | emitter(SetEnsurePwdState()); |
117 | 124 | } |
... | ... | @@ -119,7 +126,37 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
119 | 126 | } |
120 | 127 | } |
121 | 128 | |
122 | - void _setPassword(SetPasswordEvent event,Emitter<SetPwdState> emitter) async { | |
123 | - emitter(PasswordSetSuccessState()); | |
129 | + /// 设置密码,调接口 | |
130 | + void _setPassword(SetPasswordEvent event, Emitter<SetPwdState> emitter) async { | |
131 | + try { | |
132 | + await loading(() async { | |
133 | + switch (pageType) { | |
134 | + case SetPwdPageType.changePwd: | |
135 | + await UserDao.changePassword(passwordText); | |
136 | + break; | |
137 | + case SetPwdPageType.initPwd: | |
138 | + await UserDao.initPassword(passwordText); | |
139 | + break; | |
140 | + case SetPwdPageType.resetPwd: | |
141 | + if (phoneNumber == null || phoneNumber!.isEmpty) { | |
142 | + throw ApiException(ApiException.customErrorCode, '手机号为空'); | |
143 | + } | |
144 | + if (smsCode == null || smsCode!.isEmpty) { | |
145 | + throw ApiException(ApiException.customErrorCode, '验证码为空'); | |
146 | + } | |
147 | + await UserDao.resetPassword(phoneNumber!, passwordText, smsCode!); | |
148 | + break; | |
149 | + } | |
150 | + }); | |
151 | + emitter(PasswordSetSuccessState()); | |
152 | + } catch (e) { | |
153 | + String msg; | |
154 | + if (e is ApiException) { | |
155 | + msg = e.message ?? '未知错误'; | |
156 | + } else { | |
157 | + msg = e.toString(); | |
158 | + } | |
159 | + emitter(PasswordSetFailedState(msg)); | |
160 | + } | |
124 | 161 | } |
125 | 162 | } | ... | ... |
lib/pages/login/setpwd/bloc/set_pwd_state.dart
... | ... | @@ -16,3 +16,9 @@ class PasswordIconShowState extends SetPwdState {} |
16 | 16 | class PasswordCheckIconShowState extends SetPwdState {} |
17 | 17 | |
18 | 18 | class PasswordSetSuccessState extends SetPwdState {} |
19 | + | |
20 | +class PasswordSetFailedState extends SetPwdState { | |
21 | + final String message; | |
22 | + | |
23 | + PasswordSetFailedState(this.message); | |
24 | +} | ... | ... |
lib/pages/login/setpwd/set_pwd_page.dart
... | ... | @@ -4,12 +4,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
5 | 5 | import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; |
6 | 6 | import 'package:wow_english/route/route.dart'; |
7 | +import 'package:wow_english/utils/toast_util.dart'; | |
7 | 8 | |
8 | 9 | import 'bloc/set_pwd_bloc.dart'; |
9 | 10 | |
10 | 11 | enum SetPwdPageType { |
11 | 12 | /// 第一次设置密码 |
12 | - setPwd, | |
13 | + initPwd, | |
13 | 14 | |
14 | 15 | /// 忘记重设密码,必传手机号和验证码 |
15 | 16 | resetPwd, |
... | ... | @@ -49,9 +50,16 @@ class _SetPassWordPageView extends StatelessWidget { |
49 | 50 | Widget build(BuildContext context) { |
50 | 51 | bloc = BlocProvider.of<SetPwdBloc>(context); |
51 | 52 | return BlocListener<SetPwdBloc, SetPwdState>( |
52 | - listener: (context, s) { | |
53 | - if (s is PasswordSetSuccessState) { | |
53 | + listener: (context, state) { | |
54 | + if (state is PasswordSetSuccessState) { | |
55 | + if (bloc.pageType == SetPwdPageType.initPwd) { | |
56 | + showToast('密码设置成功'); | |
57 | + } else { | |
58 | + showToast('密码修改成功'); | |
59 | + } | |
54 | 60 | Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); |
61 | + } else if (state is PasswordSetFailedState) { | |
62 | + state.message.toast(); | |
55 | 63 | } |
56 | 64 | }, |
57 | 65 | child: _buildSetPwdView(), |
... | ... | @@ -62,7 +70,7 @@ class _SetPassWordPageView extends StatelessWidget { |
62 | 70 | String text = ''; |
63 | 71 | |
64 | 72 | switch (bloc.pageType) { |
65 | - case SetPwdPageType.setPwd: | |
73 | + case SetPwdPageType.initPwd: | |
66 | 74 | text = '欢迎登录wow english\n接下来请设置一下您的密码吧!'; |
67 | 75 | break; |
68 | 76 | case SetPwdPageType.resetPwd: | ... | ... |
lib/utils/loading.dart
1 | +import 'package:flutter/foundation.dart'; | |
1 | 2 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
2 | 3 | |
3 | 4 | Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) async { |
... | ... | @@ -7,6 +8,9 @@ Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) asy |
7 | 8 | try { |
8 | 9 | return await block(); |
9 | 10 | } catch (e) { |
11 | + if (kDebugMode) { | |
12 | + print("type=${e.runtimeType}, e=${e.toString()}"); | |
13 | + } | |
10 | 14 | rethrow; |
11 | 15 | } finally { |
12 | 16 | dismissLoading(); | ... | ... |