Merge pull request #206 from Nealyang/master

登陆
This commit is contained in:
一凨
2019-05-07 19:37:40 +08:00
committed by GitHub
24 changed files with 644 additions and 84 deletions

View File

@ -25,7 +25,7 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
android下载地址:
<img src="https://img.alicdn.com/tfs/TB1jGgfQ7voK1RjSZFNXXcxMVXa-438-426.png" width="200px">
<img src="https://img.alicdn.com/tfs/TB1ylxGTMHqK1RjSZFgXXa7JXXa-436-432.png" width="200px">
iphone下载地址:
暂无

17
android/.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>android</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=
eclipse.preferences.version=1

6
android/app/.classpath Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

23
android/app/.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=..
eclipse.preferences.version=1

Binary file not shown.

BIN
assets/images/FlutterGo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -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;

10
lib/api/api.dart Normal file
View File

@ -0,0 +1,10 @@
class Api{
// 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';//登陆
static const String CHECK_LOGIN = BASE_URL+'checkLogin';//验证登陆
static const String LOGOUT = BASE_URL+'logout';//退出登陆
}

View File

@ -101,7 +101,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
// 插入操作
_collectionControl
.insert(Collection(name: widget.title, router: _router))
.then((result) {
.then((result) {
if (this.mounted) {
setState(() {
_hasCollected = true;

View File

@ -3,36 +3,73 @@ 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';
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;
}
showWelcomePage() {
// 暂时关掉欢迎介绍
return AppPage();
// bool showWelcome = sp.getBool(SharedPreferencesKeys.showWelcome);
// if (showWelcome == null || showWelcome == true) {
// return WelcomePage();
// } else {
// return AppPage();
// }
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _hasLogin = false;
bool _isLoading = true;
@override
void initState() {
super.initState();
DataUtils.checkLogin().then((hasLogin) {
setState(() {
_hasLogin = hasLogin;
_isLoading = false;
});
}).catchError((onError){
setState(() {
_hasLogin = true;
_isLoading = false;
});
print('身份信息验证失败:$onError');
});
}
showWelcomePage() {
if (_isLoading) {
return Container(
color: const Color(ThemeColor),
child: Center(
child: SpinKitPouringHourglass(color: Colors.white),
),
);
} else {
// 判断是否已经登录
if (_hasLogin) {
return AppPage();
} else {
return LoginPage();
}
}
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
@ -50,9 +87,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: <NavigatorObserver>[Analytics.observer],
@ -60,7 +95,6 @@ class MyApp extends StatelessWidget {
}
}
void main() async {
final provider = new Provider();
await provider.init(true);

24
lib/model/user_info.dart Normal file
View File

@ -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<String, dynamic> json) {
return UserInfo(
avatarPic: json['avatar_pic'],
id: int.parse(json['id']),
username: json['name'],
themeColor: json['theme_color'],
urlName: json['url_name']);
}
}

View File

@ -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<List<UserInfo>> getAllInfo() async {
List list = await sql.getByCondition();
List<UserInfo> resultList = [];
list.forEach((item){
print(item);
resultList.add(UserInfo.fromJSON(item));
});
return resultList;
}
// 清空表中数据
Future deleteAll() async{
return await sql.deleteAll();
}
}

View File

@ -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<String, List<String>> params) {
return new WidgetNotFound();
});
var loginPageHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return LoginPage();
});
var fullScreenCodeDialog = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {

View File

@ -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) {

30
lib/utils/data_utils.dart Normal file
View File

@ -0,0 +1,30 @@
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<UserInfo> doLogin(Map<String,String> params) async{
var response = await NetUtils.post(Api.DO_LOGIN, params);
UserInfo userInfo = UserInfo.fromJson(response['data']);
return userInfo;
}
// 验证登陆
static Future<bool> checkLogin() async{
var response = await NetUtils.get(Api.CHECK_LOGIN);
print('验证登陆:$response');
return response['success'];
}
// 退出登陆
static Future<bool> logout() async{
var response = await NetUtils.get(Api.LOGOUT);
print('退出登陆 $response');
return response['success'];
}
}

View File

@ -1,19 +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<String,dynamic> 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<String,dynamic> params}) async{
var response = await dio.get(url, data: params);
return response.data;
static Future get(String url, [Map<String, dynamic> params]) async {
var response;
// 设置代理 便于本地 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;
}
static Future post(String url,Map<String,dynamic> params) async{
static Future post(String url, Map<String, dynamic> params) async {
var response = await dio.post(url, data: params);
return response.data;
}
}
}

View File

@ -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<int> deleteAll() async{
return await this.db.delete(tableName);
}
Future<List> getByCondition({Map<dynamic, dynamic> conditions}) async {
if (conditions == null || conditions.isEmpty) {
return this.get();

View File

@ -57,7 +57,7 @@ class FirstPageState extends State<FirstPage> 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) {

View File

@ -57,7 +57,7 @@ class SubPageState extends State<SubPage> 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) {

View File

@ -0,0 +1,295 @@
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
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
// 利用FocusNode和_focusScopeNode来控制焦点 可以通过FocusNode.of(context)来获取widget树中默认的_focusScopeNode
FocusNode _emailFocusNode = new FocusNode();
FocusNode _passwordFocusNode = new FocusNode();
FocusScopeNode _focusScopeNode = new FocusScopeNode();
UserInfoControlModel _userInfoControlModel = new UserInfoControlModel();
GlobalKey<FormState> _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(
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: <Widget>[
Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 25, right: 25, top: 20, bottom: 20),
child: new TextFormField(
controller: _userNameEditingController,
//关联焦点
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(
controller: _passwordEditingController,
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回调保存表单内容
doLogin();
}
},
);
}
// 登陆操作
doLogin() {
_signInFormKey.currentState.save();
setState(() {
isLoading = true;
});
DataUtils.doLogin({'username': username, 'password': password})
.then((result) {
print(result);
setState(() {
isLoading = false;
});
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;
});
});
}
// 点击控制密码是否显示
void showPassWord() {
setState(() {
isShowPassWord = !isShowPassWord;
});
}
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(
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: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
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: buildLoading(),
)
],
),
),
),
),
),
);
}
}

View File

@ -5,105 +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.0.8"
version: "2.2.0"
bloc:
dependency: "direct main"
description:
name: bloc
url: "https://pub.dartlang.org"
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
dependency: "direct main"
description:
name: cookie_jar
url: "https://pub.dartlang.org"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.0.8"
version: "1.0.0"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
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"
version: "2.1.3"
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:
@ -115,16 +115,23 @@ packages:
dependency: "direct main"
description:
name: flutter_bloc
url: "https://pub.dartlang.org"
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
@ -134,91 +141,98 @@ 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.dartlang.org"
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.3+1"
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"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
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.1"
version: "2.0.3"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
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:
@ -230,79 +244,79 @@ packages:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.4"
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: "1.6.8"
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.2"
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:
dart: ">=2.1.0 <3.0.0"
dart: ">=2.2.0 <3.0.0"
flutter: ">=1.2.1 <2.0.0"

View File

@ -27,8 +27,11 @@ dependencies:
url_launcher: ^5.0.2
# 本地存储、收藏功能
shared_preferences: ^0.4.3
dio: ^1.0.6
flutter_spinkit: "^3.1.0"
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