From 1aa74c13544002987dcff29927d65421bd909926 Mon Sep 17 00:00:00 2001 From: Fiona <408232927@qq.com> Date: Tue, 30 Apr 2019 21:21:11 +0800 Subject: [PATCH 1/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fac5cda3..665c52a6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en. android下载地址: - + iphone下载地址: 暂无 From edfe2cac20a43d4c9da649516c13eb67e0cf9764 Mon Sep 17 00:00:00 2001 From: Fiona <408232927@qq.com> Date: Tue, 30 Apr 2019 21:21:11 +0800 Subject: [PATCH 2/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fac5cda3..665c52a6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en. android下载地址: - + iphone下载地址: 暂无 From 0ea68adb10dde02c1dce2c214b6a89df9a2716b6 Mon Sep 17 00:00:00 2001 From: "yifeng.yl" Date: Mon, 6 May 2019 21:42:49 +0800 Subject: [PATCH 3/6] add login --- android/.project | 17 ++ .../org.eclipse.buildship.core.prefs | 2 + assets/images/FlutterGo.png | Bin 0 -> 1067 bytes ios/Runner.xcodeproj/project.pbxproj | 5 +- lib/main.dart | 4 +- lib/routers/router_handler.dart | 5 + lib/routers/routers.dart | 2 + lib/views/login_page/login_page.dart | 218 ++++++++++++++++++ pubspec.lock | 116 +++++++--- pubspec.yaml | 1 + 10 files changed, 330 insertions(+), 40 deletions(-) create mode 100644 android/.project create mode 100644 android/.settings/org.eclipse.buildship.core.prefs create mode 100644 assets/images/FlutterGo.png create mode 100644 lib/views/login_page/login_page.dart diff --git a/android/.project b/android/.project new file mode 100644 index 00000000..3964dd3f --- /dev/null +++ b/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..e8895216 --- /dev/null +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/assets/images/FlutterGo.png b/assets/images/FlutterGo.png new file mode 100644 index 0000000000000000000000000000000000000000..319ea85858c3e419ba5a0a81decf7996bd5ca939 GIT binary patch literal 1067 zcmeAS@N?(olHy`uVBq!ia0vp^PeGW48A!%G*HvX;VD!!mi71Ki^|4CM&(%vz$xlkv ztH>-n*TA>HIW;5GqpB!1xXLdi zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}lpi<;HsXMd|v6mX?kcwMx zZ=dyhY#?ypV@}YeY~TIsG?@x>%{%sPvSEyjTOfLAo}tHwUl(eoY>}M4?bM8=zvl}# zK8Tl5m#gM#{3y4VK^Qyuyy8sa2LCw;Ng$ACdOY1#C3N${nIfLE(?rduTHgMa>;nO3 z>JQ26f0kG~OUsl8A|e{x!K$YA?7MOM%T0U|ORvqZ+-vnXtJ0$Cf6}6CzUNzmm0ll? zQEpb)CU@rNG0%znDsNl7epC>=BAEN-TK$+?Uk^UZ`&s;Ihicce6;emyPw&lqbyR0} zWt<$JP;GI5ovFOO-=e&GQ}f;5Y6<0TX4v#=d)$<>`$C*&zM9p4HZLrBP1>`|aqczK zww~E&qu6J1Hpyabg=W;V#TD7zYFo}o?{t0^a&gZ4ty8m(PiYUndd9w&@9#T%_Swa2 z**EWx|F}ccxc>X@y0gK@R~O}^y)hk*>z{}1p1~LEaO1WeekWv@Wnaz+KJIcw_X}E++9DUvxnP*}?7`xU=wtHFo$pVJyn1j^ z&fZg!Qm)0J*L*&&3A$ROZ|b{qon%yK@s48K-L{u)OzW2>PdS@bXtV9rvu6|9W?nSE zUM-b=tUYsH_(_cli3ual6BV?eSHJUU%fbKv literal 0 HcmV?d00001 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 1301f46b..263c2ab2 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -353,7 +353,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework", + "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -511,6 +511,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2; + CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 4WLT68XRNA; @@ -527,7 +528,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "FlutterGO-alibaba-develop"; + PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_app_store; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; diff --git a/lib/main.dart b/lib/main.dart index 5c6a8c1f..e89af7f8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,6 +9,7 @@ import 'package:flutter_go/utils/shared_preferences.dart'; import 'package:flutter_go/views/home.dart'; import 'package:flutter_go/model/search_history.dart'; import 'package:flutter_go/utils/analytics.dart' as Analytics; +import 'package:flutter_go/views/login_page/login_page.dart'; //import 'views/welcome_page/index.dart'; const int ThemeColor = 0xFFC91B3A; @@ -25,7 +26,8 @@ class MyApp extends StatelessWidget { } showWelcomePage() { // 暂时关掉欢迎介绍 - return AppPage(); + // return AppPage(); + return LoginPage(); // bool showWelcome = sp.getBool(SharedPreferencesKeys.showWelcome); // if (showWelcome == null || showWelcome == true) { // return WelcomePage(); diff --git a/lib/routers/router_handler.dart b/lib/routers/router_handler.dart index 6105301c..4491ebcb 100644 --- a/lib/routers/router_handler.dart +++ b/lib/routers/router_handler.dart @@ -6,6 +6,7 @@ import '../widgets/404.dart'; import 'package:flutter_go/components/full_screen_code_dialog.dart'; import 'package:flutter_go/views/web_page/web_view_page.dart'; import 'package:flutter_go/views/home.dart'; +import 'package:flutter_go/views/login_page/login_page.dart'; // app的首页 var homeHandler = new Handler( @@ -26,6 +27,10 @@ var widgetNotFoundHandler = new Handler( handlerFunc: (BuildContext context, Map> params) { return new WidgetNotFound(); }); +var loginPageHandler = new Handler( + handlerFunc: (BuildContext context, Map> params) { + return LoginPage(); +}); var fullScreenCodeDialog = new Handler( handlerFunc: (BuildContext context, Map> params) { diff --git a/lib/routers/routers.dart b/lib/routers/routers.dart index 7715b2bf..b433d69c 100644 --- a/lib/routers/routers.dart +++ b/lib/routers/routers.dart @@ -12,6 +12,7 @@ class Routes { static String widgetDemo = '/widget-demo'; static String codeView = '/code-view'; static String webViewPage = '/web-view-page'; + static String loginPage = '/loginpage'; static void configureRoutes(Router router) { List widgetDemosList = new WidgetDemoList().getDemos(); @@ -22,6 +23,7 @@ class Routes { router.define('/category/:type', handler: categoryHandler); router.define('/category/error/404', handler: widgetNotFoundHandler); + router.define(loginPage, handler: loginPageHandler); router.define(codeView,handler:fullScreenCodeDialog); router.define(webViewPage,handler:webViewPageHand); widgetDemosList.forEach((demo) { diff --git a/lib/views/login_page/login_page.dart b/lib/views/login_page/login_page.dart new file mode 100644 index 00000000..2b24b476 --- /dev/null +++ b/lib/views/login_page/login_page.dart @@ -0,0 +1,218 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; + +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + // 利用FocusNode和_focusScopeNode来控制焦点 可以通过FocusNode.of(context)来获取widget树中默认的_focusScopeNode + FocusNode _emailFocusNode = new FocusNode(); + FocusNode _passwordFocusNode = new FocusNode(); + FocusScopeNode _focusScopeNode = new FocusScopeNode(); + + GlobalKey _signInFormKey = new GlobalKey(); + + bool isShowPassWord = false; + String username = ''; + String password = ''; + +// 创建登录界面的TextForm + Widget buildSignInTextForm() { + return new Container( + decoration: new BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + width: MediaQuery.of(context).size.width * 0.8, + height: 190, + // * Flutter提供了一个Form widget,它可以对输入框进行分组,然后进行一些统一操作,如输入内容校验、输入框重置以及输入内容保存。 + child: new Form( + key: _signInFormKey, + child: new Column( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: Padding( + padding: const EdgeInsets.only( + left: 25, right: 25, top: 20, bottom: 20), + child: new TextFormField( + //关联焦点 + focusNode: _emailFocusNode, + onEditingComplete: () { + if (_focusScopeNode == null) { + _focusScopeNode = FocusScope.of(context); + } + _focusScopeNode.requestFocus(_passwordFocusNode); + }, + + decoration: new InputDecoration( + icon: new Icon( + Icons.email, + color: Colors.black, + ), + hintText: "Github 登录名", + border: InputBorder.none), + style: new TextStyle(fontSize: 16, color: Colors.black), + //验证 + validator: (value) { + if (value.isEmpty) { + return "登录名不可为空!"; + } + }, + onSaved: (value) { + setState(() { + username = value; + }); + }, + ), + ), + ), + new Container( + height: 1, + width: MediaQuery.of(context).size.width * 0.75, + color: Colors.grey[400], + ), + Flexible( + child: Padding( + padding: const EdgeInsets.only(left: 25, right: 25, top: 20), + child: new TextFormField( + focusNode: _passwordFocusNode, + decoration: new InputDecoration( + icon: new Icon( + Icons.lock, + color: Colors.black, + ), + hintText: "Github 登录密码", + border: InputBorder.none, + suffixIcon: new IconButton( + icon: new Icon( + Icons.remove_red_eye, + color: Colors.black, + ), + onPressed: showPassWord, + ), + ), + //输入密码,需要用*****显示 + obscureText: !isShowPassWord, + style: new TextStyle(fontSize: 16, color: Colors.black), + validator: (value) { + if (value == null || value.isEmpty) { + return "密码不可为空!"; + } + }, + onSaved: (value) { + setState(() { + password = value; + }); + }, + ), + ), + ), + new Container( + height: 1, + width: MediaQuery.of(context).size.width * 0.75, + color: Colors.grey[400], + ), + ], + ), + ), + ); + } + + Widget buildSignInButton() { + return new GestureDetector( + child: new Container( + padding: EdgeInsets.only(left: 42, right: 42, top: 10, bottom: 10), + decoration: new BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5)), + color: Theme.of(context).primaryColor), + child: new Text( + "LOGIN", + style: new TextStyle(fontSize: 25, color: Colors.white), + ), + ), + onTap: () { + // 利用key来获取widget的状态FormState,可以用过FormState对Form的子孙FromField进行统一的操作 + if (_signInFormKey.currentState.validate()) { + // 如果输入都检验通过,则进行登录操作 + Scaffold.of(context) + .showSnackBar(new SnackBar(content: new Text("执行登录操作"))); + //调用所有自孩子的save回调,保存表单内容 + _signInFormKey.currentState.save(); + } + }, + ); + } + +// 点击控制密码是否显示 + void showPassWord() { + setState(() { + isShowPassWord = !isShowPassWord; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + color: Theme.of(context).primaryColor, + child: Center( + child: Container( + width: MediaQuery.of(context).size.width * 0.85, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8.0)), + color: Colors.white, + image: DecorationImage( + image: AssetImage( + 'assets/images/paimaiLogo.png', + ), + fit: BoxFit.scaleDown, + alignment: Alignment.bottomRight, + ), + ), + child: Stack( + children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 35.0), + Image.asset( + 'assets/images/FlutterGo.png', + fit: BoxFit.contain, + width: 100.0, + height: 100.0, + ), + buildSignInTextForm(), + buildSignInButton(), + SizedBox(height: 35.0), + ], + ), + Positioned( + top: 0, + left: 0, + bottom: 0, + child: Opacity( + opacity: .5, + child: Container( + width: MediaQuery.of(context).size.width * 0.85, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8.0)), + color: Colors.black, + ), + child: SpinKitPouringHourglass(color: Colors.white), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 9e9bcdd5..572ec55d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,91 +5,105 @@ packages: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.5.1" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.0" + bloc: + dependency: "direct main" + description: + name: bloc + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" charcode: dependency: transitive description: name: charcode - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" city_pickers: dependency: "direct main" description: name: city_pickers - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.0.4" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.14.11" cookie_jar: dependency: transitive description: name: cookie_jar - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.0.8" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.16.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.2" dio: dependency: "direct main" description: name: dio - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.17" event_bus: dependency: "direct main" description: name: event_bus - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" firebase_analytics: dependency: "direct main" description: name: firebase_analytics - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0+1" firebase_core: dependency: "direct main" description: name: firebase_core - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.4" fluro: dependency: "direct main" description: name: fluro - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" flutter: @@ -97,13 +111,27 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.11.1" flutter_markdown: dependency: "direct main" description: name: flutter_markdown - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" + flutter_spinkit: + dependency: "direct main" + description: + name: flutter_spinkit + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.0" flutter_test: dependency: "direct dev" description: flutter @@ -113,77 +141,91 @@ packages: dependency: "direct main" description: name: flutter_webview_plugin - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.4" + html: + dependency: "direct main" + description: + name: html + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.14.0+2" image_picker: dependency: "direct main" description: name: image_picker - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.6.0+1" + version: "0.6.0+2" intl: dependency: "direct main" description: name: intl - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.15.7" lpinyin: dependency: transitive description: name: lpinyin - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.7" markdown: dependency: transitive description: name: markdown - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.5" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.6" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.6.2" pedantic: dependency: transitive description: name: pedantic - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.5.0" quiver: dependency: transitive description: name: quiver - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.21.0" shared_preferences: dependency: "direct main" description: name: shared_preferences - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.4.3" sky_engine: @@ -195,77 +237,77 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.5.5" sqflite: dependency: "direct main" description: name: sqflite - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.5" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.3" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" synchronized: dependency: transitive description: name: synchronized - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.5" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.6" url_launcher: dependency: "direct main" description: name: url_launcher - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.2" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.8" sdks: diff --git a/pubspec.yaml b/pubspec.yaml index 85ab1bfb..08d953de 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,6 +27,7 @@ dependencies: url_launcher: ^5.0.2 # 本地存储、收藏功能 shared_preferences: ^0.4.3 + flutter_spinkit: "^3.1.0" dio: ^1.0.6 flutter_webview_plugin: ^0.3.4 # 日期格式化 From 4df528894074b43827470709662922f97416b220 Mon Sep 17 00:00:00 2001 From: "yifeng.yl" Date: Tue, 7 May 2019 00:04:00 +0800 Subject: [PATCH 4/6] =?UTF-8?q?Login=20=E7=99=BB=E9=99=86=E7=95=8C?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api/api.dart | 5 +++ lib/model/user_info.dart | 24 ++++++++++++ lib/utils/data_utils.dart | 16 ++++++++ lib/views/login_page/login_page.dart | 56 +++++++++++++++++++++------- 4 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 lib/api/api.dart create mode 100644 lib/model/user_info.dart create mode 100644 lib/utils/data_utils.dart diff --git a/lib/api/api.dart b/lib/api/api.dart new file mode 100644 index 00000000..62f4fb6c --- /dev/null +++ b/lib/api/api.dart @@ -0,0 +1,5 @@ +class Api{ + static const String BASE_URL = 'http://127.0.0.1:6001/'; + + static const String DO_LOGIN = BASE_URL+'doLogin'; +} \ No newline at end of file diff --git a/lib/model/user_info.dart b/lib/model/user_info.dart new file mode 100644 index 00000000..b96485a0 --- /dev/null +++ b/lib/model/user_info.dart @@ -0,0 +1,24 @@ +class UserInfo { + String username; + int id; + String avatarPic; + String themeColor; + String urlName; + + UserInfo({ + this.avatarPic, + this.id, + this.themeColor, + this.urlName, + this.username, + }); + + factory UserInfo.fromJson(Map json) { + return UserInfo( + avatarPic: json['avatar_pic'], + id: json['id'], + username: json['username'], + themeColor: json['theme_color'], + urlName: json['url_name']); + } +} diff --git a/lib/utils/data_utils.dart b/lib/utils/data_utils.dart new file mode 100644 index 00000000..533848b1 --- /dev/null +++ b/lib/utils/data_utils.dart @@ -0,0 +1,16 @@ +import 'dart:async' show Future; + +import './net_utils.dart'; +import '../model/user_info.dart'; +import 'package:flutter_go/api/api.dart'; + + +class DataUtils{ + // 登陆获取用户信息 + static Future doLogin(Map params) async{ + var response = await NetUtils.post(Api.DO_LOGIN, params); + print('url:${Api.DO_LOGIN} $response'); + UserInfo userInfo = UserInfo.fromJson(response['data']); + return userInfo; + } +} \ No newline at end of file diff --git a/lib/views/login_page/login_page.dart b/lib/views/login_page/login_page.dart index 2b24b476..b8933087 100644 --- a/lib/views/login_page/login_page.dart +++ b/lib/views/login_page/login_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:flutter_go/utils/data_utils.dart'; class LoginPage extends StatefulWidget { @override @@ -17,6 +18,7 @@ class _LoginPageState extends State { bool isShowPassWord = false; String username = ''; String password = ''; + bool isLoading = false; // 创建登录界面的TextForm Widget buildSignInTextForm() { @@ -136,15 +138,34 @@ class _LoginPageState extends State { // 利用key来获取widget的状态FormState,可以用过FormState对Form的子孙FromField进行统一的操作 if (_signInFormKey.currentState.validate()) { // 如果输入都检验通过,则进行登录操作 - Scaffold.of(context) - .showSnackBar(new SnackBar(content: new Text("执行登录操作"))); + // Scaffold.of(context) + // .showSnackBar(new SnackBar(content: new Text("执行登录操作"))); //调用所有自孩子的save回调,保存表单内容 - _signInFormKey.currentState.save(); + doLogin(); } }, ); } + // 登陆操作 + doLogin() { + _signInFormKey.currentState.save(); + setState(() { + isLoading = true; + }); + DataUtils.doLogin({'username':username,'password':password}).then((result){ + print(result.username); + setState(() { + isLoading = false; + }); + }).catchError((onError){ + print(onError); + setState(() { + isLoading = false; + }); + }); + } + // 点击控制密码是否显示 void showPassWord() { setState(() { @@ -152,6 +173,23 @@ class _LoginPageState extends State { }); } + Widget buildLoading() { + if (isLoading) { + return Opacity( + opacity: .5, + child: Container( + width: MediaQuery.of(context).size.width * 0.85, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8.0)), + color: Colors.black, + ), + child: SpinKitPouringHourglass(color: Colors.white), + ), + ); + } + return Container(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -195,17 +233,7 @@ class _LoginPageState extends State { top: 0, left: 0, bottom: 0, - child: Opacity( - opacity: .5, - child: Container( - width: MediaQuery.of(context).size.width * 0.85, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8.0)), - color: Colors.black, - ), - child: SpinKitPouringHourglass(color: Colors.white), - ), - ), + child: buildLoading(), ) ], ), From 4ac0bc2ed689ced3b114a4f39a1118622f61733a Mon Sep 17 00:00:00 2001 From: "yifeng.yl" Date: Tue, 7 May 2019 15:41:22 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E7=99=BB=E9=99=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/app.db | Bin 53248 -> 57344 bytes lib/api/api.dart | 6 ++- lib/components/widget_demo.dart | 2 +- lib/main.dart | 43 +++++++++++++------ lib/model/user_info.dart | 4 +- lib/model/user_info_cache.dart | 62 +++++++++++++++++++++++++++ lib/utils/data_utils.dart | 16 ++++++- lib/utils/net_utils.dart | 10 ++++- lib/utils/sql.dart | 6 ++- lib/views/first_page/first_page.dart | 2 +- lib/views/first_page/sub_page.dart | 2 +- lib/views/login_page/login_page.dart | 56 ++++++++++++++++++++++-- 12 files changed, 181 insertions(+), 28 deletions(-) create mode 100644 lib/model/user_info_cache.dart diff --git a/assets/app.db b/assets/app.db index 70bb8d873fb6907fed6bd99fdc041a55285e1501..a6752d63f5404e90cbf59b9ad76cc1a52908ecdb 100644 GIT binary patch delta 293 zcmZozz}#?vd4jayH3kL-J|Knx^NBjfiq{zQWH#_}zh&U!3T5S6$h{X$&bU4te&@=JUA`G+X@h5Gm?g!*{~hPvv2Rpuq;rYZon`zUCb z8fYrO)aWP_Bo-H!=NF|wC5?>`l9PXNeP-ctU{IR;kz0;U-I@<(pD$vV8!QmoEFu8twD3L%b8 hKCTMIg*llesl_F1`fLoFU3m6v-Yj_FJ^#cBf&fIACqV!J diff --git a/lib/api/api.dart b/lib/api/api.dart index 62f4fb6c..c4672887 100644 --- a/lib/api/api.dart +++ b/lib/api/api.dart @@ -1,5 +1,9 @@ class Api{ static const String BASE_URL = 'http://127.0.0.1:6001/'; - static const String DO_LOGIN = BASE_URL+'doLogin'; + static const String DO_LOGIN = BASE_URL+'doLogin';//登陆 + + static const String CHECK_LOGIN = BASE_URL+'checkLogin';//验证登陆 + + static const String LOGOUT = BASE_URL+'logout';//退出登陆 } \ No newline at end of file diff --git a/lib/components/widget_demo.dart b/lib/components/widget_demo.dart index ecdec4b4..bbce9f51 100644 --- a/lib/components/widget_demo.dart +++ b/lib/components/widget_demo.dart @@ -101,7 +101,7 @@ class _WidgetDemoState extends State { // 插入操作 _collectionControl .insert(Collection(name: widget.title, router: _router)) - .then((result) { + .then((result) { if (this.mounted) { setState(() { _hasCollected = true; diff --git a/lib/main.dart b/lib/main.dart index e89af7f8..1d66ca15 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,31 +10,49 @@ import 'package:flutter_go/views/home.dart'; import 'package:flutter_go/model/search_history.dart'; import 'package:flutter_go/utils/analytics.dart' as Analytics; import 'package:flutter_go/views/login_page/login_page.dart'; +import 'package:flutter_go/utils/data_utils.dart'; + //import 'views/welcome_page/index.dart'; const int ThemeColor = 0xFFC91B3A; SpUtil sp; var db; -class MyApp extends StatelessWidget { - MyApp() { +class MyApp extends StatefulWidget { + MyApp() { final router = new Router(); Routes.configureRoutes(router); Application.router = router; } + + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + bool _hasLogin = false; + + @override + void initState() { + super.initState(); + DataUtils.checkLogin().then((hasLogin) { + setState(() { + _hasLogin = hasLogin; + }); + }); + } + showWelcomePage() { // 暂时关掉欢迎介绍 - // return AppPage(); - return LoginPage(); -// bool showWelcome = sp.getBool(SharedPreferencesKeys.showWelcome); -// if (showWelcome == null || showWelcome == true) { -// return WelcomePage(); -// } else { -// return AppPage(); -// } + if (_hasLogin) { + return AppPage(); + } else { + return LoginPage(); + } } + @override Widget build(BuildContext context) { return new MaterialApp( @@ -52,9 +70,7 @@ class MyApp extends StatelessWidget { size: 35.0, ), ), - home: new Scaffold( - body: showWelcomePage() - ), + home: new Scaffold(body: showWelcomePage()), debugShowCheckedModeBanner: false, onGenerateRoute: Application.router.generator, navigatorObservers: [Analytics.observer], @@ -62,7 +78,6 @@ class MyApp extends StatelessWidget { } } - void main() async { final provider = new Provider(); await provider.init(true); diff --git a/lib/model/user_info.dart b/lib/model/user_info.dart index b96485a0..b47b08a3 100644 --- a/lib/model/user_info.dart +++ b/lib/model/user_info.dart @@ -16,8 +16,8 @@ class UserInfo { factory UserInfo.fromJson(Map json) { return UserInfo( avatarPic: json['avatar_pic'], - id: json['id'], - username: json['username'], + id: int.parse(json['id']), + username: json['name'], themeColor: json['theme_color'], urlName: json['url_name']); } diff --git a/lib/model/user_info_cache.dart b/lib/model/user_info_cache.dart new file mode 100644 index 00000000..e2045f92 --- /dev/null +++ b/lib/model/user_info_cache.dart @@ -0,0 +1,62 @@ +/// @Author: 一凨 +/// @Date: 2019-01-07 16:24:42 +/// @Last Modified by: 一凨 +/// @Last Modified time: 2019-01-08 17:37:42 + +import 'dart:async'; + +import 'package:flutter_go/utils/sql.dart'; + +abstract class UserInfoInterface { + String get username; + String get password; +} + +class UserInfo implements UserInfoInterface { + String username; + String password; + + UserInfo({this.username, this.password}); + + factory UserInfo.fromJSON(Map json){ + return UserInfo(username: json['username'],password: json['password']); + } + + Object toMap() { + return {'username': username, 'password': password}; + } +} + +class UserInfoControlModel { + final String table = 'userInfo'; + Sql sql; + + UserInfoControlModel() { + sql = Sql.setTable(table); + } + + // 获取所有的收藏 + + // 插入新的缓存 + Future insert(UserInfo userInfo) { + var result = + sql.insert({'username': userInfo.username, 'password': userInfo.password}); + return result; + } + + // 获取用户信息 + Future> getAllInfo() async { + List list = await sql.getByCondition(); + List resultList = []; + list.forEach((item){ + print(item); + resultList.add(UserInfo.fromJSON(item)); + }); + return resultList; + } + + // 清空表中数据 + Future deleteAll() async{ + return await sql.deleteAll(); + } +} diff --git a/lib/utils/data_utils.dart b/lib/utils/data_utils.dart index 533848b1..97858111 100644 --- a/lib/utils/data_utils.dart +++ b/lib/utils/data_utils.dart @@ -9,8 +9,22 @@ class DataUtils{ // 登陆获取用户信息 static Future doLogin(Map params) async{ var response = await NetUtils.post(Api.DO_LOGIN, params); - print('url:${Api.DO_LOGIN} $response'); UserInfo userInfo = UserInfo.fromJson(response['data']); return userInfo; } + + // 验证登陆 + + static Future checkLogin() async{ + var response = await NetUtils.get(Api.CHECK_LOGIN); + print('验证登陆:$response'); + return response['success']; + } + + // 退出登陆 + static Future logout() async{ + var response = await NetUtils.get(Api.LOGOUT); + print('退出登陆 $response'); + return response['success']; + } } \ No newline at end of file diff --git a/lib/utils/net_utils.dart b/lib/utils/net_utils.dart index 764fed18..af2eda80 100644 --- a/lib/utils/net_utils.dart +++ b/lib/utils/net_utils.dart @@ -7,8 +7,14 @@ var dio = new Dio(); class NetUtils { - static Future get(String url,{Map params}) async{ - var response = await dio.get(url, data: params); + static Future get(String url,[Map params]) async{ + var response; + if(params != null){ + response = await dio.get(url, data: params); + }else{ + response = await dio.get(url); + } + return response.data; } diff --git a/lib/utils/sql.dart b/lib/utils/sql.dart index 8568fcb4..d932415b 100644 --- a/lib/utils/sql.dart +++ b/lib/utils/sql.dart @@ -1,4 +1,4 @@ -import 'dart:async'; + import 'package:sqflite/sqflite.dart'; @@ -31,6 +31,10 @@ class Sql extends BaseModel { return await this.db.delete(tableName,where:'$key = ?',whereArgs:[value]); } + Future deleteAll() async{ + return await this.db.delete(tableName); + } + Future getByCondition({Map conditions}) async { if (conditions == null || conditions.isEmpty) { return this.get(); diff --git a/lib/views/first_page/first_page.dart b/lib/views/first_page/first_page.dart index 1fded132..be9de1e5 100644 --- a/lib/views/first_page/first_page.dart +++ b/lib/views/first_page/first_page.dart @@ -57,7 +57,7 @@ class FirstPageState extends State with AutomaticKeepAliveClientMixin var pageTotal = 0; try{ - var response = await NetUtils.get(juejin_flutter, params: _param); + var response = await NetUtils.get(juejin_flutter, _param); responseList = response['d']['entrylist']; pageTotal = response['d']['total']; if (!(pageTotal is int) || pageTotal <= 0) { diff --git a/lib/views/first_page/sub_page.dart b/lib/views/first_page/sub_page.dart index 387b55bf..22325f97 100644 --- a/lib/views/first_page/sub_page.dart +++ b/lib/views/first_page/sub_page.dart @@ -57,7 +57,7 @@ class SubPageState extends State with AutomaticKeepAliveClientMixin{ var pageTotal = 0; try{ - var response = await NetUtils.get(juejin_flutter, params: _param); + var response = await NetUtils.get(juejin_flutter, _param); responseList = response['d']['entrylist']; pageTotal = response['d']['total']; if (!(pageTotal is int) || pageTotal <= 0) { diff --git a/lib/views/login_page/login_page.dart b/lib/views/login_page/login_page.dart index b8933087..db895693 100644 --- a/lib/views/login_page/login_page.dart +++ b/lib/views/login_page/login_page.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_go/utils/data_utils.dart'; +import 'package:flutter_go/views/home.dart'; + +import 'package:flutter_go/model/user_info_cache.dart'; class LoginPage extends StatefulWidget { @override @@ -12,14 +15,40 @@ class _LoginPageState extends State { FocusNode _emailFocusNode = new FocusNode(); FocusNode _passwordFocusNode = new FocusNode(); FocusScopeNode _focusScopeNode = new FocusScopeNode(); + UserInfoControlModel _userInfoControlModel = new UserInfoControlModel(); GlobalKey _signInFormKey = new GlobalKey(); + TextEditingController _userNameEditingController = + new TextEditingController(); + TextEditingController _passwordEditingController = + new TextEditingController(); bool isShowPassWord = false; String username = ''; String password = ''; bool isLoading = false; + @override + void initState() { + super.initState(); + try { + _userInfoControlModel.getAllInfo().then((list) { + if (list.length > 0) { + UserInfo _userInfo = list[0]; + print('获取的数据:${_userInfo.username} ${_userInfo.password}'); + setState(() { + _userNameEditingController.text = _userInfo.username; + _passwordEditingController.text = _userInfo.password; + username = _userInfo.username; + password = _userInfo.password; + }); + } + }); + } catch (err) { + print('读取用户本地存储的用户信息出错 $err'); + } + } + // 创建登录界面的TextForm Widget buildSignInTextForm() { return new Container( @@ -39,6 +68,7 @@ class _LoginPageState extends State { padding: const EdgeInsets.only( left: 25, right: 25, top: 20, bottom: 20), child: new TextFormField( + controller: _userNameEditingController, //关联焦点 focusNode: _emailFocusNode, onEditingComplete: () { @@ -79,6 +109,7 @@ class _LoginPageState extends State { child: Padding( padding: const EdgeInsets.only(left: 25, right: 25, top: 20), child: new TextFormField( + controller: _passwordEditingController, focusNode: _passwordFocusNode, decoration: new InputDecoration( icon: new Icon( @@ -148,17 +179,34 @@ class _LoginPageState extends State { } // 登陆操作 - doLogin() { + doLogin() { _signInFormKey.currentState.save(); setState(() { isLoading = true; }); - DataUtils.doLogin({'username':username,'password':password}).then((result){ - print(result.username); + DataUtils.doLogin({'username': username, 'password': password}) + .then((result) { setState(() { isLoading = false; }); - }).catchError((onError){ + try { + _userInfoControlModel.deleteAll().then((result) { + // print('删除结果:$result'); + _userInfoControlModel + .insert(UserInfo(password: password, username: username)) + .then((value) { + // print('存储成功:$value'); + Navigator.of(context).pushAndRemoveUntil( + new MaterialPageRoute(builder: (context) => AppPage()), + (route) => route == null); + }); + }); + } catch (err) { + Navigator.of(context).pushAndRemoveUntil( + new MaterialPageRoute(builder: (context) => AppPage()), + (route) => route == null); + } + }).catchError((onError) { print(onError); setState(() { isLoading = false; From 58ef9c685623e1e517767f822a46b43892484f20 Mon Sep 17 00:00:00 2001 From: "yifeng.yl" Date: Tue, 7 May 2019 19:31:41 +0800 Subject: [PATCH 6/6] =?UTF-8?q?cookie=20=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/.classpath | 6 +++ android/app/.project | 23 ++++++++++ .../org.eclipse.buildship.core.prefs | 2 + lib/api/api.dart | 3 +- lib/main.dart | 27 +++++++++--- lib/utils/net_utils.dart | 42 ++++++++++++++----- lib/views/login_page/login_page.dart | 1 + pubspec.yaml | 4 +- 8 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 android/app/.classpath create mode 100644 android/app/.project create mode 100644 android/app/.settings/org.eclipse.buildship.core.prefs diff --git a/android/app/.classpath b/android/app/.classpath new file mode 100644 index 00000000..eb19361b --- /dev/null +++ b/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/app/.project b/android/app/.project new file mode 100644 index 00000000..ac485d7c --- /dev/null +++ b/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/app/.settings/org.eclipse.buildship.core.prefs b/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..b1886adb --- /dev/null +++ b/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/lib/api/api.dart b/lib/api/api.dart index c4672887..93d4f6b8 100644 --- a/lib/api/api.dart +++ b/lib/api/api.dart @@ -1,5 +1,6 @@ class Api{ - static const String BASE_URL = 'http://127.0.0.1:6001/'; + // static const String BASE_URL = 'http://127.0.0.1:6001/'; + static const String BASE_URL = 'http://flutter-go.alibaba.net/'; static const String DO_LOGIN = BASE_URL+'doLogin';//登陆 diff --git a/lib/main.dart b/lib/main.dart index 1d66ca15..fdcee399 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,7 @@ import 'package:fluro/fluro.dart'; import 'package:flutter/rendering.dart'; import 'routers/routers.dart'; import 'routers/application.dart'; - +import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_go/utils/provider.dart'; import 'package:flutter_go/utils/shared_preferences.dart'; import 'package:flutter_go/views/home.dart'; @@ -33,6 +33,7 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { bool _hasLogin = false; + bool _isLoading = true; @override void initState() { @@ -40,16 +41,32 @@ class _MyAppState extends State { DataUtils.checkLogin().then((hasLogin) { setState(() { _hasLogin = hasLogin; + _isLoading = false; + }); + }).catchError((onError){ + setState(() { + _hasLogin = true; + _isLoading = false; }); + print('身份信息验证失败:$onError'); }); } showWelcomePage() { - // 暂时关掉欢迎介绍 - if (_hasLogin) { - return AppPage(); + if (_isLoading) { + return Container( + color: const Color(ThemeColor), + child: Center( + child: SpinKitPouringHourglass(color: Colors.white), + ), + ); } else { - return LoginPage(); + // 判断是否已经登录 + if (_hasLogin) { + return AppPage(); + } else { + return LoginPage(); + } } } diff --git a/lib/utils/net_utils.dart b/lib/utils/net_utils.dart index af2eda80..2f39746c 100644 --- a/lib/utils/net_utils.dart +++ b/lib/utils/net_utils.dart @@ -1,25 +1,45 @@ import 'dart:async'; - +import 'dart:io'; +import 'package:cookie_jar/cookie_jar.dart'; import 'package:dio/dio.dart'; +import 'package:path_provider/path_provider.dart'; +Map optHeader = { + 'accept-language':'zh-cn', + 'content-type':'application/json' +}; -var dio = new Dio(); +var dio = new Dio(BaseOptions(connectTimeout: 30000,headers: optHeader)); class NetUtils { - - static Future get(String url,[Map params]) async{ + + static Future get(String url, [Map params]) async { var response; - if(params != null){ - response = await dio.get(url, data: params); - }else{ + + // 设置代理 便于本地 charles 抓包 + // (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = + // (HttpClient client) { + // client.findProxy = (uri) { + // return "PROXY 30.10.26.193:8888"; + // }; + // }; + + Directory documentsDir = await getApplicationDocumentsDirectory(); + String documentsPath = documentsDir.path; + var dir = new Directory("$documentsPath/cookies"); + await dir.create(); + // print('documentPath:${dir.path}'); + dio.interceptors.add(CookieManager(PersistCookieJar(dir: dir.path))); + if (params != null) { + response = await dio.get(url, queryParameters: params); + } else { response = await dio.get(url); } - - return response.data; + return response.data; } - static Future post(String url,Map params) async{ + static Future post(String url, Map params) async { var response = await dio.post(url, data: params); return response.data; } -} \ No newline at end of file +} diff --git a/lib/views/login_page/login_page.dart b/lib/views/login_page/login_page.dart index db895693..0e658ec8 100644 --- a/lib/views/login_page/login_page.dart +++ b/lib/views/login_page/login_page.dart @@ -186,6 +186,7 @@ class _LoginPageState extends State { }); DataUtils.doLogin({'username': username, 'password': password}) .then((result) { + print(result); setState(() { isLoading = false; }); diff --git a/pubspec.yaml b/pubspec.yaml index 08d953de..d85a81e9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,8 +28,10 @@ dependencies: # 本地存储、收藏功能 shared_preferences: ^0.4.3 flutter_spinkit: "^3.1.0" - dio: ^1.0.6 + path_provider: ^1.0.0 + dio: ^2.0.15 flutter_webview_plugin: ^0.3.4 + cookie_jar: ^1.0.0 # 日期格式化 intl: 0.15.7 city_pickers: ^0.0.1