Commit 39e064868d2afb002d3e50ff011757fdfa078993
1 parent
6f836681
feat:获取验证码逻辑处理
Showing
4 changed files
with
156 additions
and
115 deletions
lib/common/request/dao/user_dao.dart
... | ... | @@ -16,4 +16,11 @@ class UserDao { |
16 | 16 | } |
17 | 17 | return data; |
18 | 18 | } |
19 | + | |
20 | + static Future sendCode(phoneNumber,{smsType ='login'}) async { | |
21 | + final params = {'phoneNum':phoneNumber,'smsType':smsType}; | |
22 | + await requestClient.post( | |
23 | + Apis.sendSmsCode,data: params | |
24 | + ); | |
25 | + } | |
19 | 26 | } | ... | ... |
lib/pages/login/loginpage/bloc/login_bloc.dart
1 | +import 'package:common_utils/common_utils.dart'; | |
1 | 2 | import 'package:flutter/cupertino.dart'; |
2 | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 4 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
... | ... | @@ -82,7 +83,23 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { |
82 | 83 | } |
83 | 84 | |
84 | 85 | ///请求验证码 |
85 | - void _requestSmsCodeApi(RequestSmsCodeEvent event, Emitter<LoginState> emitter) async {} | |
86 | + void _requestSmsCodeApi(RequestSmsCodeEvent event, Emitter<LoginState> emitter) async { | |
87 | + final phoneNumber = phoneNumController.text; | |
88 | + if (!RegexUtil.isMobileExact(phoneNumber)) { | |
89 | + EasyLoading.showToast('请检查手机号'); | |
90 | + return; | |
91 | + } | |
92 | + try { | |
93 | + await loading(() async { | |
94 | + await UserDao.sendCode(phoneNumber); | |
95 | + }); | |
96 | + emitter(SmsCodeRequestState()); | |
97 | + } catch (e) { | |
98 | + if (e is ApiException) { | |
99 | + EasyLoading.showToast(e.message??'请检查网络连接'); | |
100 | + } | |
101 | + } | |
102 | + } | |
86 | 103 | |
87 | 104 | ///切换登陆方式 |
88 | 105 | void _changeLoginType(ChangeLoginTypeEvent event, Emitter<LoginState> emitter) async { | ... | ... |
lib/pages/login/loginpage/login_page.dart
... | ... | @@ -41,116 +41,114 @@ class _LoginPageView extends StatelessWidget { |
41 | 41 | final bloc = BlocProvider.of<LoginBloc>(context); |
42 | 42 | return Scaffold( |
43 | 43 | body: SafeArea( |
44 | - child: ListView( | |
45 | - children: [ | |
46 | - Container( | |
47 | - padding: EdgeInsets.only(top: 25.h), | |
48 | - child: Stack( | |
49 | - children: [ | |
50 | - Positioned( | |
51 | - right: 29.w, | |
52 | - child: GestureDetector( | |
53 | - onTap: () => bloc.add(ChangeLoginTypeEvent()), | |
44 | + child: SingleChildScrollView( | |
45 | + child: Container( | |
46 | + padding: EdgeInsets.only(top: 25.h), | |
47 | + child: Stack( | |
48 | + children: [ | |
49 | + Positioned( | |
50 | + right: 29.w, | |
51 | + child: GestureDetector( | |
52 | + onTap: () => bloc.add(ChangeLoginTypeEvent()), | |
53 | + child: Container( | |
54 | + decoration: BoxDecoration( | |
55 | + image: DecorationImage(image: AssetImage('login_logo'.assetPng), fit: BoxFit.fill), | |
56 | + ), | |
57 | + padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 5.h), | |
58 | + child: Text( | |
59 | + bloc.isSmsLoginType ? '密码登陆' : '验证码密码', | |
60 | + style: TextStyle(fontSize: 16.sp), | |
61 | + ), | |
62 | + ), | |
63 | + )), | |
64 | + Center( | |
65 | + child: Column( | |
66 | + children: [ | |
67 | + Image.asset( | |
68 | + 'wow_logo'.assetPng, | |
69 | + height: 81.h, | |
70 | + width: 131.w, | |
71 | + ), | |
72 | + Offstage( | |
73 | + offstage: !bloc.isSmsLoginType, | |
74 | + child: _buildSmsViewWidget(), | |
75 | + ), | |
76 | + Offstage( | |
77 | + offstage: bloc.isSmsLoginType, | |
78 | + child: _buildPwdViewWidget(), | |
79 | + ), | |
80 | + Row( | |
81 | + mainAxisAlignment: MainAxisAlignment.center, | |
82 | + children: [ | |
83 | + GestureDetector( | |
84 | + onTap: () => bloc.add(AgreementChangeEvent()), | |
85 | + child: Icon(bloc.agreement ? Icons.check_circle_outlined : Icons.circle_outlined, | |
86 | + color: bloc.agreement ? Colors.green : Colors.black), | |
87 | + ), | |
88 | + 6.horizontalSpace, | |
89 | + RichText( | |
90 | + text: TextSpan(children: [ | |
91 | + TextSpan( | |
92 | + text: '我已阅读并同意', | |
93 | + style: TextStyle( | |
94 | + fontSize: 12.sp, | |
95 | + color: const Color(0xFF333333), | |
96 | + )), | |
97 | + TextSpan( | |
98 | + text: '《用户隐私协议》', | |
99 | + style: TextStyle( | |
100 | + fontSize: 12.sp, | |
101 | + color: const Color(0xFF333333), | |
102 | + ), | |
103 | + recognizer: TapGestureRecognizer() | |
104 | + ..onTap = () { | |
105 | + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { | |
106 | + 'urlStr': 'https://www.zhihu.com', | |
107 | + 'webViewTitle': '用户隐私协议' | |
108 | + }); | |
109 | + }), | |
110 | + TextSpan( | |
111 | + text: ',', style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333))), | |
112 | + TextSpan( | |
113 | + text: '《儿童隐私政策》', | |
114 | + style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333)), | |
115 | + recognizer: TapGestureRecognizer() | |
116 | + ..onTap = () { | |
117 | + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { | |
118 | + 'urlStr': 'https://www.zhihu.com', | |
119 | + 'webViewTitle': '儿童隐私协议' | |
120 | + }); | |
121 | + }) | |
122 | + ]), | |
123 | + ) | |
124 | + ], | |
125 | + ), | |
126 | + GestureDetector( | |
127 | + onTap: () { | |
128 | + if (bloc.canLogin) { | |
129 | + bloc.add(RequestLoginEvent()); | |
130 | + } | |
131 | + }, | |
54 | 132 | child: Container( |
55 | 133 | decoration: BoxDecoration( |
56 | - image: DecorationImage(image: AssetImage('login_logo'.assetPng), fit: BoxFit.fill), | |
134 | + image: DecorationImage( | |
135 | + image: AssetImage( | |
136 | + bloc.canLogin ? 'login_enter'.assetPng : 'login_enter_dis'.assetPng), | |
137 | + fit: BoxFit.fill), | |
57 | 138 | ), |
58 | - padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 5.h), | |
139 | + padding: EdgeInsets.symmetric(horizontal: 28.w, vertical: 14.h), | |
59 | 140 | child: Text( |
60 | - bloc.isSmsLoginType ? '密码登陆' : '验证码密码', | |
141 | + '登录', | |
61 | 142 | style: TextStyle(fontSize: 16.sp), |
62 | 143 | ), |
63 | 144 | ), |
64 | - )), | |
65 | - Center( | |
66 | - child: Column( | |
67 | - children: [ | |
68 | - Image.asset( | |
69 | - 'wow_logo'.assetPng, | |
70 | - height: 81.h, | |
71 | - width: 131.w, | |
72 | - ), | |
73 | - Offstage( | |
74 | - offstage: !bloc.isSmsLoginType, | |
75 | - child: _buildSmsViewWidget(), | |
76 | - ), | |
77 | - Offstage( | |
78 | - offstage: bloc.isSmsLoginType, | |
79 | - child: _buildPwdViewWidget(), | |
80 | - ), | |
81 | - Row( | |
82 | - mainAxisAlignment: MainAxisAlignment.center, | |
83 | - children: [ | |
84 | - GestureDetector( | |
85 | - onTap: () => bloc.add(AgreementChangeEvent()), | |
86 | - child: Icon(bloc.agreement ? Icons.check_circle_outlined : Icons.circle_outlined, | |
87 | - color: bloc.agreement ? Colors.green : Colors.black), | |
88 | - ), | |
89 | - 6.horizontalSpace, | |
90 | - RichText( | |
91 | - text: TextSpan(children: [ | |
92 | - TextSpan( | |
93 | - text: '我已阅读并同意', | |
94 | - style: TextStyle( | |
95 | - fontSize: 12.sp, | |
96 | - color: const Color(0xFF333333), | |
97 | - )), | |
98 | - TextSpan( | |
99 | - text: '《用户隐私协议》', | |
100 | - style: TextStyle( | |
101 | - fontSize: 12.sp, | |
102 | - color: const Color(0xFF333333), | |
103 | - ), | |
104 | - recognizer: TapGestureRecognizer() | |
105 | - ..onTap = () { | |
106 | - Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { | |
107 | - 'urlStr': 'https://www.zhihu.com', | |
108 | - 'webViewTitle': '用户隐私协议' | |
109 | - }); | |
110 | - }), | |
111 | - TextSpan( | |
112 | - text: ',', style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333))), | |
113 | - TextSpan( | |
114 | - text: '《儿童隐私政策》', | |
115 | - style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333)), | |
116 | - recognizer: TapGestureRecognizer() | |
117 | - ..onTap = () { | |
118 | - Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { | |
119 | - 'urlStr': 'https://www.zhihu.com', | |
120 | - 'webViewTitle': '儿童隐私协议' | |
121 | - }); | |
122 | - }) | |
123 | - ]), | |
124 | - ) | |
125 | - ], | |
126 | - ), | |
127 | - GestureDetector( | |
128 | - onTap: () { | |
129 | - if (bloc.canLogin) { | |
130 | - bloc.add(RequestLoginEvent()); | |
131 | - } | |
132 | - }, | |
133 | - child: Container( | |
134 | - decoration: BoxDecoration( | |
135 | - image: DecorationImage( | |
136 | - image: AssetImage( | |
137 | - bloc.canLogin ? 'login_enter'.assetPng : 'login_enter_dis'.assetPng), | |
138 | - fit: BoxFit.fill), | |
139 | - ), | |
140 | - padding: EdgeInsets.symmetric(horizontal: 28.w, vertical: 14.h), | |
141 | - child: Text( | |
142 | - '登录', | |
143 | - style: TextStyle(fontSize: 16.sp), | |
144 | - ), | |
145 | - ), | |
146 | - ) | |
147 | - ], | |
148 | - ), | |
149 | - ) | |
150 | - ], | |
151 | - ), | |
152 | - ) | |
153 | - ], | |
145 | + ) | |
146 | + ], | |
147 | + ), | |
148 | + ) | |
149 | + ], | |
150 | + ), | |
151 | + ), | |
154 | 152 | ), |
155 | 153 | ), |
156 | 154 | ); |
... | ... | @@ -194,7 +192,10 @@ class _LoginPageView extends StatelessWidget { |
194 | 192 | }, |
195 | 193 | controller: bloc.checkNumController, |
196 | 194 | )), |
197 | - TimerWidget(canSendSms: bloc.canSendSms) | |
195 | + TimerWidget( | |
196 | + canSendSms: bloc.canSendSms, | |
197 | + sendSmsEvent: () => bloc.add(RequestSmsCodeEvent()), | |
198 | + ) | |
198 | 199 | ], |
199 | 200 | ) |
200 | 201 | ], | ... | ... |
lib/pages/login/loginpage/time_widget.dart
... | ... | @@ -5,17 +5,22 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; |
5 | 5 | import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart'; |
6 | 6 | import 'package:wow_english/common/extension/string_extension.dart'; |
7 | 7 | import 'package:wow_english/common/widgets/timer_ticker.dart'; |
8 | +import 'package:wow_english/pages/login/loginpage/bloc/login_bloc.dart'; | |
8 | 9 | |
9 | 10 | class TimerWidget extends StatelessWidget { |
10 | - const TimerWidget({super.key, required this.canSendSms}); | |
11 | + const TimerWidget({super.key, required this.canSendSms,this.sendSmsEvent}); | |
11 | 12 | |
12 | 13 | final bool canSendSms; |
14 | + final Function()? sendSmsEvent; | |
13 | 15 | |
14 | 16 | @override |
15 | 17 | Widget build(BuildContext context) { |
16 | 18 | return BlocProvider( |
17 | 19 | create: (_) => TimerBloc(ticker: const TimerTicker()), |
18 | - child: TimerWidgetView(canSendSms: canSendSms,), | |
20 | + child: TimerWidgetView( | |
21 | + canSendSms: canSendSms, | |
22 | + sendSmsEvent: sendSmsEvent, | |
23 | + ), | |
19 | 24 | ); |
20 | 25 | } |
21 | 26 | } |
... | ... | @@ -27,13 +32,24 @@ class TimerWidgetView extends StatelessWidget { |
27 | 32 | |
28 | 33 | @override |
29 | 34 | Widget build(BuildContext context) { |
30 | - return BlocListener<TimerBloc,TimerState>( | |
31 | - listener: (context, s) { | |
32 | - if (s is FinishedState) { | |
33 | - ///重置计时器 | |
34 | - context.read<TimerBloc>().add(ResetEvent()); | |
35 | - } | |
36 | - }, | |
35 | + return MultiBlocListener( | |
36 | + listeners: [ | |
37 | + BlocListener<TimerBloc,TimerState>( | |
38 | + listener: (context, s) { | |
39 | + if (s is FinishedState) { | |
40 | + ///重置计时器 | |
41 | + context.read<TimerBloc>().add(ResetEvent()); | |
42 | + } | |
43 | + }), | |
44 | + BlocListener<LoginBloc,LoginState>( | |
45 | + listener: (context, s) { | |
46 | + if (s is SmsCodeRequestState) { | |
47 | + final bloc = BlocProvider.of<TimerBloc>(context); | |
48 | + ///开始倒计时 | |
49 | + bloc.add(StartEvent(duration: bloc.state.duration)); | |
50 | + } | |
51 | + }), | |
52 | + ], | |
37 | 53 | child: _buildCountdownWidget(), |
38 | 54 | ); |
39 | 55 | } |
... | ... | @@ -45,7 +61,7 @@ class TimerWidgetView extends StatelessWidget { |
45 | 61 | return GestureDetector( |
46 | 62 | onTap: () { |
47 | 63 | if (canSendSms && !bloc.isCountTimer ) { |
48 | - bloc.add(StartEvent(duration: state.duration)); | |
64 | + sendSmsEvent?.call(); | |
49 | 65 | } |
50 | 66 | }, |
51 | 67 | child: Container( | ... | ... |