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 | class Apis { | 3 | class Apis { |
2 | /// app初始化配置信息 | 4 | /// app初始化配置信息 |
3 | // GET /system/app/config | 5 | // GET /system/app/config |
@@ -19,6 +21,15 @@ class Apis { | @@ -19,6 +21,15 @@ class Apis { | ||
19 | /// 发送验证码 | 21 | /// 发送验证码 |
20 | static const String sendSmsCode = 'system/send/code'; | 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 | // GET /home/courseModule | 34 | // GET /home/courseModule |
24 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897663 | 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 | import 'package:wow_english/common/request/request_client.dart'; | 1 | import 'package:wow_english/common/request/request_client.dart'; |
4 | import 'package:wow_english/models/course_entity.dart'; | 2 | import 'package:wow_english/models/course_entity.dart'; |
5 | 3 | ||
@@ -18,10 +16,7 @@ class HomeDao { | @@ -18,10 +16,7 @@ class HomeDao { | ||
18 | if (moduleId.isNotEmpty) { | 16 | if (moduleId.isNotEmpty) { |
19 | mapData['moduleId'] = moduleId; | 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 | return data; | 20 | return data; |
26 | } | 21 | } |
27 | } | 22 | } |
lib/common/request/dao/listen_dao.dart
1 | -import 'package:wow_english/common/request/apis.dart'; | ||
2 | import 'package:wow_english/common/request/request_client.dart'; | 1 | import 'package:wow_english/common/request/request_client.dart'; |
3 | import 'package:wow_english/models/follow_read_entity.dart'; | 2 | import 'package:wow_english/models/follow_read_entity.dart'; |
4 | import 'package:wow_english/models/listen_entity.dart'; | 3 | import 'package:wow_english/models/listen_entity.dart'; |
@@ -15,4 +14,4 @@ class ListenDao { | @@ -15,4 +14,4 @@ class ListenDao { | ||
15 | var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead); | 14 | var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead); |
16 | return data; | 15 | return data; |
17 | } | 16 | } |
18 | -} | ||
19 | \ No newline at end of file | 17 | \ No newline at end of file |
18 | +} |
lib/common/request/dao/user_dao.dart
1 | import 'package:wow_english/common/core/user_util.dart'; | 1 | import 'package:wow_english/common/core/user_util.dart'; |
2 | import 'package:wow_english/models/user_entity.dart'; | 2 | import 'package:wow_english/models/user_entity.dart'; |
3 | 3 | ||
4 | -import '../apis.dart'; | ||
5 | import '../request_client.dart'; | 4 | import '../request_client.dart'; |
6 | 5 | ||
7 | class UserDao { | 6 | class UserDao { |
@@ -32,6 +31,27 @@ class UserDao { | @@ -32,6 +31,27 @@ class UserDao { | ||
32 | await requestClient.post(Apis.sendSmsCode, data: params); | 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 | static Future<UserEntity?> getUserInfo() async { | 56 | static Future<UserEntity?> getUserInfo() async { |
37 | return await requestClient.post(Apis.getUserInfo); | 57 | return await requestClient.post(Apis.getUserInfo); |
lib/common/request/exception.dart
@@ -84,6 +84,11 @@ class ApiException implements Exception { | @@ -84,6 +84,11 @@ class ApiException implements Exception { | ||
84 | apiException.stackInfo = exception?.toString(); | 84 | apiException.stackInfo = exception?.toString(); |
85 | return apiException; | 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
@@ -11,6 +11,8 @@ import 'config.dart'; | @@ -11,6 +11,8 @@ import 'config.dart'; | ||
11 | import 'exception.dart'; | 11 | import 'exception.dart'; |
12 | import 'token_interceptor.dart'; | 12 | import 'token_interceptor.dart'; |
13 | 13 | ||
14 | +part 'apis.dart'; | ||
15 | + | ||
14 | RequestClient requestClient = RequestClient(); | 16 | RequestClient requestClient = RequestClient(); |
15 | 17 | ||
16 | class RequestClient { | 18 | class RequestClient { |
lib/pages/login/setpwd/bloc/set_pwd_bloc.dart
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 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 | import '../set_pwd_page.dart'; | 7 | import '../set_pwd_page.dart'; |
5 | 8 | ||
@@ -7,21 +10,25 @@ part 'set_pwd_event.dart'; | @@ -7,21 +10,25 @@ part 'set_pwd_event.dart'; | ||
7 | part 'set_pwd_state.dart'; | 10 | part 'set_pwd_state.dart'; |
8 | 11 | ||
9 | class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | 12 | class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { |
10 | - | ||
11 | final String? phoneNumber; | 13 | final String? phoneNumber; |
12 | final String? smsCode; | 14 | final String? smsCode; |
13 | late final SetPwdPageType pageType; | 15 | late final SetPwdPageType pageType; |
14 | 16 | ||
15 | final TextEditingController passWordFirstController = TextEditingController(); | 17 | final TextEditingController passWordFirstController = TextEditingController(); |
16 | final TextEditingController passWordSecondController = TextEditingController(); | 18 | final TextEditingController passWordSecondController = TextEditingController(); |
19 | + | ||
17 | ///密码是否符合规则(第一个输入框) | 20 | ///密码是否符合规则(第一个输入框) |
18 | bool _passwordEnsure = false; | 21 | bool _passwordEnsure = false; |
22 | + | ||
19 | ///密码是否超过16位(第一个输入框) | 23 | ///密码是否超过16位(第一个输入框) |
20 | bool _passwordLarger = false; | 24 | bool _passwordLarger = false; |
25 | + | ||
21 | ///是否显示Icon(第一个输入框) | 26 | ///是否显示Icon(第一个输入框) |
22 | bool _showPwdIcon = false; | 27 | bool _showPwdIcon = false; |
28 | + | ||
23 | ///是否显示Icon(第二个输入框) | 29 | ///是否显示Icon(第二个输入框) |
24 | bool _showCheckPwdIcon = false; | 30 | bool _showCheckPwdIcon = false; |
31 | + | ||
25 | ///密码是否一致 | 32 | ///密码是否一致 |
26 | bool _passwordCheck = true; | 33 | bool _passwordCheck = true; |
27 | 34 | ||
@@ -37,14 +44,16 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -37,14 +44,16 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | ||
37 | 44 | ||
38 | bool get ensure => _passwordCheck && _passwordEnsure; | 45 | bool get ensure => _passwordCheck && _passwordEnsure; |
39 | 46 | ||
47 | + String get passwordText => passWordFirstController.text; | ||
48 | + | ||
40 | SetPwdBloc(this.phoneNumber, this.smsCode, this.pageType) : super(SetPwdInitial()) { | 49 | SetPwdBloc(this.phoneNumber, this.smsCode, this.pageType) : super(SetPwdInitial()) { |
41 | on<PwdEnsureEvent>(_pwdEnsureTextChange); | 50 | on<PwdEnsureEvent>(_pwdEnsureTextChange); |
42 | on<PwdCheckEvent>(_pwdCheckTextChange); | 51 | on<PwdCheckEvent>(_pwdCheckTextChange); |
43 | on<SetPasswordEvent>(_setPassword); | 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 | _showCheckPwdIcon = false; | 57 | _showCheckPwdIcon = false; |
49 | emitter(PasswordCheckIconShowState()); | 58 | emitter(PasswordCheckIconShowState()); |
50 | } else { | 59 | } else { |
@@ -53,7 +62,7 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -53,7 +62,7 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | ||
53 | emitter(PasswordCheckIconShowState()); | 62 | emitter(PasswordCheckIconShowState()); |
54 | } | 63 | } |
55 | } | 64 | } |
56 | - if(passWordFirstController.text == passWordSecondController.text) { | 65 | + if (passWordFirstController.text == passWordSecondController.text) { |
57 | _passwordCheck = true; | 66 | _passwordCheck = true; |
58 | emitter(SetCheckPwdState()); | 67 | emitter(SetCheckPwdState()); |
59 | } else { | 68 | } else { |
@@ -62,7 +71,7 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -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 | if (passWordFirstController.text.isEmpty) { | 75 | if (passWordFirstController.text.isEmpty) { |
67 | if (_showPwdIcon) { | 76 | if (_showPwdIcon) { |
68 | _showPwdIcon = false; | 77 | _showPwdIcon = false; |
@@ -73,32 +82,29 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -73,32 +82,29 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | ||
73 | _showPwdIcon = true; | 82 | _showPwdIcon = true; |
74 | emitter(PasswordIconShowState()); | 83 | emitter(PasswordIconShowState()); |
75 | } | 84 | } |
76 | - if(passWordSecondController.text.isNotEmpty) { | 85 | + if (passWordSecondController.text.isNotEmpty) { |
77 | if (passWordFirstController.text == passWordSecondController.text) { | 86 | if (passWordFirstController.text == passWordSecondController.text) { |
78 | _passwordCheck = true; | 87 | _passwordCheck = true; |
79 | - | ||
80 | } else { | 88 | } else { |
81 | _passwordCheck = false; | 89 | _passwordCheck = false; |
82 | } | 90 | } |
83 | emitter(SetCheckPwdState()); | 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 | _passwordEnsure = true; | 96 | _passwordEnsure = true; |
89 | emitter(SetEnsurePwdState()); | 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 | if (_passwordLarger) { | 102 | if (_passwordLarger) { |
97 | _passwordLarger = false; | 103 | _passwordLarger = false; |
98 | emitter(PasswordLargeState()); | 104 | emitter(PasswordLargeState()); |
99 | } | 105 | } |
100 | } else { | 106 | } else { |
101 | - if(passWordFirstController.text.length > 16) { | 107 | + if (passWordFirstController.text.length > 16) { |
102 | ///超过十六位 | 108 | ///超过十六位 |
103 | if (!_passwordLarger) { | 109 | if (!_passwordLarger) { |
104 | _passwordLarger = true; | 110 | _passwordLarger = true; |
@@ -110,8 +116,9 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -110,8 +116,9 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | ||
110 | emitter(PasswordLargeState()); | 116 | emitter(PasswordLargeState()); |
111 | } | 117 | } |
112 | } | 118 | } |
119 | + | ||
113 | ///密码不符合要求 | 120 | ///密码不符合要求 |
114 | - if(_passwordEnsure) { | 121 | + if (_passwordEnsure) { |
115 | _passwordEnsure = false; | 122 | _passwordEnsure = false; |
116 | emitter(SetEnsurePwdState()); | 123 | emitter(SetEnsurePwdState()); |
117 | } | 124 | } |
@@ -119,7 +126,37 @@ class SetPwdBloc extends Bloc<SetPwdEvent, SetPwdState> { | @@ -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,3 +16,9 @@ class PasswordIconShowState extends SetPwdState {} | ||
16 | class PasswordCheckIconShowState extends SetPwdState {} | 16 | class PasswordCheckIconShowState extends SetPwdState {} |
17 | 17 | ||
18 | class PasswordSetSuccessState extends SetPwdState {} | 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,12 +4,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
4 | import 'package:wow_english/common/extension/string_extension.dart'; | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
5 | import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; | 5 | import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; |
6 | import 'package:wow_english/route/route.dart'; | 6 | import 'package:wow_english/route/route.dart'; |
7 | +import 'package:wow_english/utils/toast_util.dart'; | ||
7 | 8 | ||
8 | import 'bloc/set_pwd_bloc.dart'; | 9 | import 'bloc/set_pwd_bloc.dart'; |
9 | 10 | ||
10 | enum SetPwdPageType { | 11 | enum SetPwdPageType { |
11 | /// 第一次设置密码 | 12 | /// 第一次设置密码 |
12 | - setPwd, | 13 | + initPwd, |
13 | 14 | ||
14 | /// 忘记重设密码,必传手机号和验证码 | 15 | /// 忘记重设密码,必传手机号和验证码 |
15 | resetPwd, | 16 | resetPwd, |
@@ -49,9 +50,16 @@ class _SetPassWordPageView extends StatelessWidget { | @@ -49,9 +50,16 @@ class _SetPassWordPageView extends StatelessWidget { | ||
49 | Widget build(BuildContext context) { | 50 | Widget build(BuildContext context) { |
50 | bloc = BlocProvider.of<SetPwdBloc>(context); | 51 | bloc = BlocProvider.of<SetPwdBloc>(context); |
51 | return BlocListener<SetPwdBloc, SetPwdState>( | 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 | Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); | 60 | Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); |
61 | + } else if (state is PasswordSetFailedState) { | ||
62 | + state.message.toast(); | ||
55 | } | 63 | } |
56 | }, | 64 | }, |
57 | child: _buildSetPwdView(), | 65 | child: _buildSetPwdView(), |
@@ -62,7 +70,7 @@ class _SetPassWordPageView extends StatelessWidget { | @@ -62,7 +70,7 @@ class _SetPassWordPageView extends StatelessWidget { | ||
62 | String text = ''; | 70 | String text = ''; |
63 | 71 | ||
64 | switch (bloc.pageType) { | 72 | switch (bloc.pageType) { |
65 | - case SetPwdPageType.setPwd: | 73 | + case SetPwdPageType.initPwd: |
66 | text = '欢迎登录wow english\n接下来请设置一下您的密码吧!'; | 74 | text = '欢迎登录wow english\n接下来请设置一下您的密码吧!'; |
67 | break; | 75 | break; |
68 | case SetPwdPageType.resetPwd: | 76 | case SetPwdPageType.resetPwd: |
lib/utils/loading.dart
1 | +import 'package:flutter/foundation.dart'; | ||
1 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 2 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
2 | 3 | ||
3 | Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) async { | 4 | Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) async { |
@@ -7,6 +8,9 @@ Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) asy | @@ -7,6 +8,9 @@ Future<T?> loading<T>(Function block, {String loadingText = '请稍后...'}) asy | ||
7 | try { | 8 | try { |
8 | return await block(); | 9 | return await block(); |
9 | } catch (e) { | 10 | } catch (e) { |
11 | + if (kDebugMode) { | ||
12 | + print("type=${e.runtimeType}, e=${e.toString()}"); | ||
13 | + } | ||
10 | rethrow; | 14 | rethrow; |
11 | } finally { | 15 | } finally { |
12 | dismissLoading(); | 16 | dismissLoading(); |