Commit 39e064868d2afb002d3e50ff011757fdfa078993

Authored by liangchengyou
1 parent 6f836681

feat:获取验证码逻辑处理

lib/common/request/dao/user_dao.dart
@@ -16,4 +16,11 @@ class UserDao { @@ -16,4 +16,11 @@ class UserDao {
16 } 16 }
17 return data; 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 import 'package:flutter/cupertino.dart'; 2 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 3 import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:flutter_easyloading/flutter_easyloading.dart'; 4 import 'package:flutter_easyloading/flutter_easyloading.dart';
@@ -82,7 +83,23 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { @@ -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 void _changeLoginType(ChangeLoginTypeEvent event, Emitter<LoginState> emitter) async { 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,116 +41,114 @@ class _LoginPageView extends StatelessWidget {
41 final bloc = BlocProvider.of<LoginBloc>(context); 41 final bloc = BlocProvider.of<LoginBloc>(context);
42 return Scaffold( 42 return Scaffold(
43 body: SafeArea( 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 child: Container( 132 child: Container(
55 decoration: BoxDecoration( 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 child: Text( 140 child: Text(
60 - bloc.isSmsLoginType ? '密码登陆' : '验证码密码', 141 + '登录',
61 style: TextStyle(fontSize: 16.sp), 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,7 +192,10 @@ class _LoginPageView extends StatelessWidget {
194 }, 192 },
195 controller: bloc.checkNumController, 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 &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;; @@ -5,17 +5,22 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;;
5 import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart'; 5 import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart';
6 import 'package:wow_english/common/extension/string_extension.dart'; 6 import 'package:wow_english/common/extension/string_extension.dart';
7 import 'package:wow_english/common/widgets/timer_ticker.dart'; 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 class TimerWidget extends StatelessWidget { 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 final bool canSendSms; 13 final bool canSendSms;
  14 + final Function()? sendSmsEvent;
13 15
14 @override 16 @override
15 Widget build(BuildContext context) { 17 Widget build(BuildContext context) {
16 return BlocProvider( 18 return BlocProvider(
17 create: (_) => TimerBloc(ticker: const TimerTicker()), 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,13 +32,24 @@ class TimerWidgetView extends StatelessWidget {
27 32
28 @override 33 @override
29 Widget build(BuildContext context) { 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 child: _buildCountdownWidget(), 53 child: _buildCountdownWidget(),
38 ); 54 );
39 } 55 }
@@ -45,7 +61,7 @@ class TimerWidgetView extends StatelessWidget { @@ -45,7 +61,7 @@ class TimerWidgetView extends StatelessWidget {
45 return GestureDetector( 61 return GestureDetector(
46 onTap: () { 62 onTap: () {
47 if (canSendSms && !bloc.isCountTimer ) { 63 if (canSendSms && !bloc.isCountTimer ) {
48 - bloc.add(StartEvent(duration: state.duration)); 64 + sendSmsEvent?.call();
49 } 65 }
50 }, 66 },
51 child: Container( 67 child: Container(