diff --git a/lib/app/app.dart b/lib/app/app.dart index 05a87db..21b16f2 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -16,9 +16,9 @@ class App extends StatelessWidget { Widget build(BuildContext context) { return ScreenUtilInit( designSize: const Size(667, 375), - builder: (_,__) => MultiBlocProvider( + builder: (_, __) => MultiBlocProvider( providers: [ - BlocProvider(create: (_)=> TabBloc()), + BlocProvider(create: (_) => TabBloc()), BlocProvider(create: (_) => CacheBloc()) ], child: HideKeyboard( @@ -30,16 +30,13 @@ class App extends StatelessWidget { useMaterial3: true, ), builder: EasyLoading.init( - builder: (context,child) => ResponsiveBreakpoints( - breakpoints: const [ - Breakpoint(start: 0, end: 450, name: MOBILE), - Breakpoint(start: 0, end: 450, name: PHONE), - Breakpoint(start: 451, end: 800, name: TABLET), - Breakpoint(start: 801, end: 1920, name: DESKTOP), - Breakpoint(start: 1921, end: double.infinity, name: '4K'), - ], - child: child!) - ), + builder: (context, child) => ResponsiveBreakpoints(breakpoints: const [ + Breakpoint(start: 0, end: 450, name: MOBILE), + Breakpoint(start: 0, end: 450, name: PHONE), + Breakpoint(start: 451, end: 800, name: TABLET), + Breakpoint(start: 801, end: 1920, name: DESKTOP), + Breakpoint(start: 1921, end: double.infinity, name: '4K'), + ], child: child!)), initialRoute: AppRouteName.splash, navigatorKey: AppRouter.navigatorKey, onGenerateRoute: AppRouter.generateRoute, diff --git a/lib/common/request/api_response/api_response_entity.g.dart b/lib/common/request/api_response/api_response_entity.g.dart index a5ff0fe..d6295e6 100644 --- a/lib/common/request/api_response/api_response_entity.g.dart +++ b/lib/common/request/api_response/api_response_entity.g.dart @@ -16,7 +16,7 @@ ApiResponse $ApiResponseFromJson(Map json) { String type = T.toString(); T? data; if (kDebugMode) { - print("type:$type"); + print("ApiResponse type:$type"); } if (json['data'] != null) { data = jsonConvert.convert(json['data']); diff --git a/lib/common/request/config.dart b/lib/common/request/config.dart index aa3bba0..963a214 100644 --- a/lib/common/request/config.dart +++ b/lib/common/request/config.dart @@ -1,6 +1,7 @@ ///request config class RequestConfig { static String baseUrl = 'http://wow-app.dev.kouyuxingqiu.com/'; + static String token = ''; static const connectTimeout = Duration(seconds: 15); static const successCode = 200; } diff --git a/lib/common/request/dao/user_dao.dart b/lib/common/request/dao/user_dao.dart index 13394ae..870f1b4 100644 --- a/lib/common/request/dao/user_dao.dart +++ b/lib/common/request/dao/user_dao.dart @@ -1,32 +1,15 @@ -import '../../../models/user_entity.dart'; -import '../api_response/api_response_entity.dart'; +import 'package:wow_english/models/user_entity.dart'; + import '../apis.dart'; -import '../exception.dart'; import '../request_client.dart'; class UserDao { - static loginByPassword( - phoneNumber, - password, - Function(ApiResponse)? onResponse, - bool Function(ApiException)? onError, - ) async { - /*await DioUtil().requestData( - HttpMethod.post, - Api.login, - data: { - 'phoneNum':phoneNumber, - 'type':'pwd', - 'password':password}, - successCallBack: (data){ - emitter(LoginResultChangeState(true)); - }, - errorCallBack: (error){ - emitter(LoginResultChangeState(false)); - });*/ - var params = {'phoneNum': phoneNumber, 'type': 'pwd', 'password': password}; - await requestClient.post(Apis.login, data: params, onResponse: onResponse, onError: onError); + static Future login(phoneNumber, type, checkKey, checkNumber) { + var params = {'phoneNum': phoneNumber, 'type': type, checkKey: checkNumber}; + var data = requestClient.post( + Apis.login, + data: params, + ); + return data; } - - static loginBySmsCode(phoneNumber, smsCode) {} } diff --git a/lib/common/request/exception.dart b/lib/common/request/exception.dart index 6798503..83ac278 100644 --- a/lib/common/request/exception.dart +++ b/lib/common/request/exception.dart @@ -1,4 +1,6 @@ import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; + import 'api_response/api_response_entity.dart'; class ApiException implements Exception { @@ -57,7 +59,11 @@ class ApiException implements Exception { return ApiException(errCode, error.response?.statusMessage ?? '未知错误'); } } on Exception catch (e) { - return ApiException(-1, unknownException); + if (kDebugMode) { + return ApiException(-1, e.toString()); + } else { + return ApiException(-1, unknownException); + } } default: return ApiException(-1, error.message); diff --git a/lib/common/request/exception_handler.dart b/lib/common/request/exception_handler.dart index 1997ed8..348bc60 100644 --- a/lib/common/request/exception_handler.dart +++ b/lib/common/request/exception_handler.dart @@ -2,9 +2,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'exception.dart'; - -bool handleException(ApiException exception, - {bool Function(ApiException)? onError}) { +bool handleException(ApiException exception, {bool Function(ApiException)? onError}) { if (onError?.call(exception) == true) { return true; } @@ -14,6 +12,5 @@ bool handleException(ApiException exception, return true; } EasyLoading.showError(exception.message ?? ApiException.unknownException); - return false; } diff --git a/lib/common/request/request.dart b/lib/common/request/request.dart index a40dfbe..a0337c4 100644 --- a/lib/common/request/request.dart +++ b/lib/common/request/request.dart @@ -2,15 +2,17 @@ import '../../utils/loading.dart'; import 'exception.dart'; import 'exception_handler.dart'; -Future request( +Future request( Function() block, { - bool showLoading = true, + String loadingText = '加载中...', bool Function(ApiException)? onError, }) async { try { - await loading(block, isShowLoading: showLoading); + return await loading(block, loadingText: loadingText); } catch (e) { - handleException(ApiException.from(e), onError: onError); + if (!handleException(ApiException.from(e), onError: onError)) { + rethrow; + } } - return; + return null; } diff --git a/lib/common/request/request_client.dart b/lib/common/request/request_client.dart index 801576f..89961f2 100644 --- a/lib/common/request/request_client.dart +++ b/lib/common/request/request_client.dart @@ -45,7 +45,6 @@ class RequestClient { throw exception; } } - return null; } @@ -132,7 +131,6 @@ class RequestClient { Function(ApiResponse)? onResponse, ) { int statusCode = response.statusCode ?? -1; - print('statusCode=$statusCode'); // 200..299 成功响应 if (statusCode >= 200 && statusCode <= 299) { if (T.toString() == (RawData).toString()) { diff --git a/lib/common/request/token_interceptor.dart b/lib/common/request/token_interceptor.dart index 01ab281..319b207 100644 --- a/lib/common/request/token_interceptor.dart +++ b/lib/common/request/token_interceptor.dart @@ -1,10 +1,13 @@ import 'package:dio/dio.dart'; +import 'package:wow_english/common/request/config.dart'; class TokenInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { - /// todo 判断token不为空插入 - options.headers["Auth-token"] = ''; + // 判断token不为空插入, todo token的取法应该跟user在一起,这里取不到user + if (RequestConfig.token.isNotEmpty) { + options.headers["Auth-token"] = RequestConfig.token; + } options.headers["version"] = '1.0.0'; super.onRequest(options, handler); } diff --git a/lib/pages/login/loginpage/bloc/login_bloc.dart b/lib/pages/login/loginpage/bloc/login_bloc.dart index 4f16abf..dfe9f71 100644 --- a/lib/pages/login/loginpage/bloc/login_bloc.dart +++ b/lib/pages/login/loginpage/bloc/login_bloc.dart @@ -1,14 +1,10 @@ -import 'dart:js'; - import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; - -import '../../../../common/request/api_response/api_response_entity.dart'; -import '../../../../common/request/apis.dart'; -import '../../../../common/request/request.dart'; -import '../../../../common/request/request_client.dart'; -import '../../../../models/user_entity.dart'; +import 'package:wow_english/common/request/config.dart'; +import 'package:wow_english/common/request/dao/user_dao.dart'; +import 'package:wow_english/models/user_entity.dart'; +import 'package:wow_english/utils/loading.dart'; part 'login_event.dart'; part 'login_state.dart'; @@ -73,29 +69,22 @@ class LoginBloc extends Bloc { var checkKey = _isSmsLoginType ? 'smsCode' : 'password'; var type = _isSmsLoginType ? 'sms_code' : 'pwd'; - request(() async { - var params = {'phoneNum': phoneNumber, 'type': type, checkKey: checkNumber}; - await requestClient.post( - Apis.login, - data: params, - onResponse: (ApiResponse response) { - print('response=$response'); - // todo 持久化用户对象 - // todo 写入全局对象 - //emitter.call(LoginResultChangeState()); - }, - onError: (e) { - EasyLoading.showToast('登陆失败:${e.message}'); - return true; - }, - ); - }); + try { + await loading(() async { + var user = await UserDao.login(phoneNumber, type, checkKey, checkNumber); + print('login已执行'); + print('user=$user'); + RequestConfig.token = user!.token; + emitter.call(LoginResultChangeState(user)); + }); + } catch (e) { + print(e); + EasyLoading.showToast('登陆失败'); + } } ///请求验证码 - void _requestSmsCodeApi(RequestSmsCodeEvent event, Emitter emitter) async { - - } + void _requestSmsCodeApi(RequestSmsCodeEvent event, Emitter emitter) async {} ///切换登陆方式 void _changeLoginType(ChangeLoginTypeEvent event, Emitter emitter) async { diff --git a/lib/pages/login/loginpage/bloc/login_state.dart b/lib/pages/login/loginpage/bloc/login_state.dart index 191c310..662bcec 100644 --- a/lib/pages/login/loginpage/bloc/login_state.dart +++ b/lib/pages/login/loginpage/bloc/login_state.dart @@ -16,8 +16,13 @@ class SmsSendTypeChangeState extends LoginState {} ///是否同意协议 class AgreementTypeChangeState extends LoginState {} + ///获取验证码 -class SmsCodeRequestState extends LoginState {} +class SmsCodeRequestState extends LoginState {} ///登陆请求结果 -class LoginResultChangeState extends LoginState {} +class LoginResultChangeState extends LoginState { + final UserEntity userEntity; + + LoginResultChangeState(this.userEntity); +} diff --git a/lib/pages/login/loginpage/login_page.dart b/lib/pages/login/loginpage/login_page.dart index f096e0c..6b1095f 100644 --- a/lib/pages/login/loginpage/login_page.dart +++ b/lib/pages/login/loginpage/login_page.dart @@ -25,169 +25,139 @@ class LoginPage extends StatelessWidget { class _LoginPageView extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocListener( - listener: (context, state){ - if (state is LoginResultChangeState) { - Navigator.of(context).pushNamed(AppRouteName.home); - } - context.read().add(UserInfoChangeEvent(null)); - }, + return BlocListener( + listener: (context, state) { + if (state is LoginResultChangeState) { + context.read().add(UserInfoChangeEvent(state.userEntity)); + Navigator.of(context).pushNamed(AppRouteName.home); + } + }, child: _buildLoginViewWidget(), ); } - Widget _buildLoginViewWidget() => BlocBuilder ( - builder: (context, state) { - final bloc = BlocProvider.of(context); - return Scaffold( - body: SafeArea( - child: ListView( - children: [ - Container( - padding: EdgeInsets.only(top: 25.h), - child: Stack( - children: [ - Positioned( - right: 29.w, - child: GestureDetector( - onTap: () => bloc.add(ChangeLoginTypeEvent()), - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - 'login_logo'.assetPng - ), - fit: BoxFit.fill - ), - ), - padding: EdgeInsets.symmetric(horizontal: 18.w,vertical: 5.h), - child: Text( - bloc.isSmsLoginType?'密码登陆':'验证码密码', - style: TextStyle( - fontSize: 16.sp + Widget _buildLoginViewWidget() => BlocBuilder( + builder: (context, state) { + final bloc = BlocProvider.of(context); + return Scaffold( + body: SafeArea( + child: ListView( + children: [ + Container( + padding: EdgeInsets.only(top: 25.h), + child: Stack( + children: [ + Positioned( + right: 29.w, + child: GestureDetector( + onTap: () => bloc.add(ChangeLoginTypeEvent()), + child: Container( + decoration: BoxDecoration( + image: DecorationImage(image: AssetImage('login_logo'.assetPng), fit: BoxFit.fill), + ), + padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 5.h), + child: Text( + bloc.isSmsLoginType ? '密码登陆' : '验证码密码', + style: TextStyle(fontSize: 16.sp), + ), ), - ), - ), - ) - ), - Center( - child: Column( - children: [ - Image.asset( - 'wow_logo'.assetPng, - height: 81.h, - width: 131.w, - ), - Offstage( - offstage: !bloc.isSmsLoginType, - child: _buildSmsViewWidget(), - ), - Offstage( - offstage: bloc.isSmsLoginType, - child: _buildPwdViewWidget(), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, + )), + Center( + child: Column( children: [ - GestureDetector( - onTap: () => bloc.add(AgreementChangeEvent()), - child: Icon( - bloc.agreement ? Icons.check_circle_outlined:Icons.circle_outlined, - color:bloc.agreement ? Colors.green:Colors.black), + Image.asset( + 'wow_logo'.assetPng, + height: 81.h, + width: 131.w, + ), + Offstage( + offstage: !bloc.isSmsLoginType, + child: _buildSmsViewWidget(), ), - 6.horizontalSpace, - RichText( - text: TextSpan( - children:[ + Offstage( + offstage: bloc.isSmsLoginType, + child: _buildPwdViewWidget(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () => bloc.add(AgreementChangeEvent()), + child: Icon(bloc.agreement ? Icons.check_circle_outlined : Icons.circle_outlined, + color: bloc.agreement ? Colors.green : Colors.black), + ), + 6.horizontalSpace, + RichText( + text: TextSpan(children: [ TextSpan( text: '我已阅读并同意', style: TextStyle( fontSize: 12.sp, color: const Color(0xFF333333), - ) - ), + )), TextSpan( text: '《用户隐私协议》', style: TextStyle( fontSize: 12.sp, color: const Color(0xFF333333), ), - recognizer: TapGestureRecognizer()..onTap = (){ - Navigator.of(context).pushNamed( - AppRouteName.webView, - arguments: { - 'urlStr':'https://www.zhihu.com', - 'webViewTitle':'用户隐私协议' - }); - }), - TextSpan( - text: ',', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF333333) - ) - ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { + 'urlStr': 'https://www.zhihu.com', + 'webViewTitle': '用户隐私协议' + }); + }), + TextSpan( + text: ',', style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333))), TextSpan( text: '《儿童隐私政策》', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF333333) - ), - recognizer: TapGestureRecognizer()..onTap = (){ - Navigator.of(context).pushNamed( - AppRouteName.webView, - arguments: { - 'urlStr':'https://www.zhihu.com', - 'webViewTitle':'儿童隐私协议' - }); - }) - ] + style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333)), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { + 'urlStr': 'https://www.zhihu.com', + 'webViewTitle': '儿童隐私协议' + }); + }) + ]), + ) + ], + ), + GestureDetector( + onTap: () { + if (bloc.canLogin) { + bloc.add(RequestLoginEvent()); + } + }, + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + bloc.canLogin ? 'login_enter'.assetPng : 'login_enter_dis'.assetPng), + fit: BoxFit.fill), + ), + padding: EdgeInsets.symmetric(horizontal: 28.w, vertical: 14.h), + child: Text( + '登录', + style: TextStyle(fontSize: 16.sp), + ), ), ) ], ), - GestureDetector( - onTap: () { - if (bloc.canLogin) { - bloc.add(RequestLoginEvent()); - } - }, - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - bloc.canLogin?'login_enter'.assetPng:'login_enter_dis'.assetPng - ), - fit: BoxFit.fill - ), - ), - padding: EdgeInsets.symmetric( - horizontal: 28.w, - vertical: 14.h - ), - child: Text( - '登录', - style: TextStyle( - fontSize: 16.sp - ), - ), - ), - ) - ], - ), - ) - ], - ), - ) - ], - ), - ), + ) + ], + ), + ) + ], + ), + ), + ); + }, ); - }, - ); - Widget _buildSmsViewWidget()=> BlocBuilder( - builder: (context,state) { + Widget _buildSmsViewWidget() => BlocBuilder(builder: (context, state) { final bloc = BlocProvider.of(context); return Padding( padding: EdgeInsets.symmetric(horizontal: 135.w), @@ -205,27 +175,25 @@ class _LoginPageView extends StatelessWidget { controller: bloc.phoneNumController, ), 6.5.verticalSpace, - Text('未注册用户登录默认注册', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF999999) - ),), + Text( + '未注册用户登录默认注册', + style: TextStyle(fontSize: 12.sp, color: const Color(0xFF999999)), + ), 4.5.verticalSpace, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: TextFieldCustomerWidget( - height: 50.h, - hitText: '请输入验证码', - textInputType: TextInputType.number, - bgImageName: 'Input_layer_down', - onChangeValue: (String value) { - bloc.add(CheckFieldChangeEvent()); - }, - controller: bloc.checkNumController, - ) - ), + height: 50.h, + hitText: '请输入验证码', + textInputType: TextInputType.number, + bgImageName: 'Input_layer_down', + onChangeValue: (String value) { + bloc.add(CheckFieldChangeEvent()); + }, + controller: bloc.checkNumController, + )), TimerWidget(canSendSms: bloc.canSendSms) ], ) @@ -234,8 +202,7 @@ class _LoginPageView extends StatelessWidget { ); }); - Widget _buildPwdViewWidget()=> BlocBuilder( - builder: (context,state){ + Widget _buildPwdViewWidget() => BlocBuilder(builder: (context, state) { final bloc = BlocProvider.of(context); return Padding( padding: EdgeInsets.symmetric(horizontal: 90.w), @@ -253,16 +220,15 @@ class _LoginPageView extends StatelessWidget { 10.5.horizontalSpace, Expanded( child: TextFieldCustomerWidget( - height: 50.h, - hitText: '请输入手机号', - textInputType: TextInputType.phone, - bgImageName: 'Input_layer_up', - onChangeValue: (String value) { - bloc.add(PhoneNumChangeEvent()); - }, - controller: bloc.phoneNumController, - ) - ), + height: 50.h, + hitText: '请输入手机号', + textInputType: TextInputType.phone, + bgImageName: 'Input_layer_up', + onChangeValue: (String value) { + bloc.add(PhoneNumChangeEvent()); + }, + controller: bloc.phoneNumController, + )), 5.horizontalSpace, SizedBox( width: 100.w, @@ -282,14 +248,13 @@ class _LoginPageView extends StatelessWidget { 10.5.horizontalSpace, Expanded( child: TextFieldCustomerWidget( - hitText: '请输入密码', - bgImageName: 'Input_layer_down', - onChangeValue: (String value) { - bloc.add(CheckFieldChangeEvent()); - }, - controller: bloc.checkNumController, - ) - ), + hitText: '请输入密码', + bgImageName: 'Input_layer_down', + onChangeValue: (String value) { + bloc.add(CheckFieldChangeEvent()); + }, + controller: bloc.checkNumController, + )), 5.horizontalSpace, GestureDetector( onTap: () { @@ -301,9 +266,7 @@ class _LoginPageView extends StatelessWidget { alignment: Alignment.centerLeft, child: Text( '忘记密码 ?', - style: TextStyle( - fontSize: 12.sp - ), + style: TextStyle(fontSize: 12.sp), ), ), ) diff --git a/lib/utils/loading.dart b/lib/utils/loading.dart index f63e6aa..76b1427 100644 --- a/lib/utils/loading.dart +++ b/lib/utils/loading.dart @@ -1,21 +1,20 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; -Future loading(Function block, {bool isShowLoading = true}) async { - if (isShowLoading) { - showLoading(); +Future loading(Function block, {String loadingText = '加载中...'}) async { + if (loadingText.isNotEmpty) { + showLoading(loadingText); } try { - await block(); + return await block(); } catch (e) { rethrow; } finally { dismissLoading(); } - return; } -void showLoading() { - EasyLoading.show(status: "加载中..."); +void showLoading(String text) { + EasyLoading.show(status: text); } void dismissLoading() {