├── .DS_Store
├── .gitignore
├── .idea
├── GHMall.iml
├── codeStyles
│ └── Project.xml
├── encodings.xml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ ├── Flutter_Plugins.xml
│ └── KotlinJavaRuntime.xml
├── misc.xml
├── modules.xml
├── runConfigurations
│ └── main_dart.xml
├── vcs.xml
└── workspace.xml
├── .metadata
├── 2f7f1a6d17a91f4167b85af5a47c65b131f3a64268732-eYhpx3_fw658副本.png
├── GHMall.iml
├── LICENSE
├── README.md
├── android
├── .gitignore
├── GHMall_android.iml
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── GHMall
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── ghome_project.iml
├── images
├── .DS_Store
├── 2.0x
│ ├── bg.png
│ ├── logo.png
│ ├── user.png
│ └── user_bg.jpg
├── 3.0x
│ ├── bg.png
│ ├── logo.png
│ ├── user.png
│ └── user_bg.jpg
├── bg.jpg
├── checkNormal.png
├── checkSelected.png
├── collect.png
├── customerService.png
├── down.png
├── downSeletecd.png
├── filter.png
├── filterSeletecd.png
├── goPublic.png
├── logo.png
├── pay_alipay.png
├── pay_wechat.png
├── price.png
├── screen.png
├── serviceIcon.png
├── shop.png
├── shoppingCart.png
├── thickness.png
├── up.png
├── upSeletecd.png
├── user.png
└── user_bg.jpg
├── ios
├── .DS_Store
├── .gitignore
├── Flutter
│ ├── .last_build_id
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── icon-1024.png
│ │ ├── icon-20-ipad.png
│ │ ├── icon-20@2x-ipad.png
│ │ ├── icon-20@2x.png
│ │ ├── icon-20@3x.png
│ │ ├── icon-29-ipad.png
│ │ ├── icon-29.png
│ │ ├── icon-29@2x-ipad.png
│ │ ├── icon-29@2x.png
│ │ ├── icon-29@3x.png
│ │ ├── icon-40.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-76.png
│ │ ├── icon-76@2x.png
│ │ └── icon-83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── .DS_Store
├── generated_plugin_registrant.dart
├── main.dart
├── model
│ ├── .DS_Store
│ ├── GHAddressModel.dart
│ ├── GHCategoryModel.dart
│ ├── GHGoodDetailsModel.dart
│ ├── GHGoodsModel.dart
│ ├── GHGuessLikeModel.dart
│ ├── GHHotGoodsModel.dart
│ └── GHomeCarouselDataModel.dart
├── pages
│ ├── .DS_Store
│ ├── Cart
│ │ └── CartItem.dart
│ ├── GHAddressEdit.dart
│ ├── GHAddressList.dart
│ ├── GHCheckOutPage.dart
│ ├── GHGoodsDetails.dart
│ ├── GHGoodsList.dart
│ ├── GHLoginPage.dart
│ ├── GHOnlinePayments.dart
│ ├── GHOrderList.dart
│ ├── Search.dart
│ ├── Test.dart
│ └── tabs
│ │ ├── GHCategoryPage.dart
│ │ ├── GHHomePage.dart
│ │ ├── GHShopCartPage.dart
│ │ ├── GHUserPage.dart
│ │ └── Tabs.dart
├── provider
│ └── Cart.dart
├── routers
│ └── router.dart
├── services
│ ├── EventBus.dart
│ ├── GHLog.dart
│ ├── GHToast.dart
│ ├── ScreenAdaper.dart
│ ├── SearchServices.dart
│ ├── Storage.dart
│ ├── gh_sqflite.dart
│ └── httptool.dart
└── widget
│ ├── GHButton.dart
│ ├── GHCountItemWidget.dart
│ ├── GHCustomAppbar.dart
│ ├── GHDialog.dart
│ ├── GHLoading.dart
│ ├── GHRichTextPriceWidget.dart
│ ├── GHTextWidget.dart
│ └── LoadingWidget.dart
├── pubspec.yaml
└── test
└── widget_test.dart
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/guides/libraries/private-files
2 |
3 | # Files and directories created by pub
4 | .dart_tool/
5 | .packages
6 | build/
7 | # If you're building an application, you may want to check-in your pubspec.lock
8 | pubspec.lock
9 |
10 | # Directory created by dartdoc
11 | # If you don't generate documentation locally you can remove this line.
12 | doc/api/
13 | *.psd
14 |
15 | # Avoid committing generated Javascript files:
16 | *.dart.js
17 | *.info.json # Produced by the --dump-info flag.
18 | *.js # When generated by dart2js. Don't specify *.js if your
19 | # project includes source files written in JavaScript.
20 | *.js_
21 | *.js.deps
22 | *.js.map
23 |
24 | .flutter-plugins
25 | .flutter-plugins-dependencies
--------------------------------------------------------------------------------
/.idea/GHMall.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/libraries/KotlinJavaRuntime.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 1592740531740
58 |
59 |
60 | 1592740531740
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | file://$PROJECT_DIR$/lib/pages/GHGoodsDetails.dart
107 |
108 |
109 |
110 | file://$PROJECT_DIR$/lib/main.dart
111 | 10
112 |
113 |
114 |
115 | file://$PROJECT_DIR$/lib/pages/tabs/GHCategoryPage.dart
116 | 300
117 |
118 |
119 |
120 | file://$PROJECT_DIR$/lib/widget/GHButton.dart
121 | 6
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/2f7f1a6d17a91f4167b85af5a47c65b131f3a64268732-eYhpx3_fw658副本.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/2f7f1a6d17a91f4167b85af5a47c65b131f3a64268732-eYhpx3_fw658副本.png
--------------------------------------------------------------------------------
/GHMall.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 GHome
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GHMall
2 |
3 | 
4 |
5 | 一个练习的flutter电商项目,基本功能已经完成。
6 |
7 | 环境
8 |
9 | ```
10 | Flutter 2.0.0 • channel stable • https://github.com/flutter/flutter.git
11 | Framework • revision 60bd88df91 (10 hours ago) • 2021-03-03 09:13:17 -0800
12 | Engine • revision 40441def69
13 | Tools • Dart 2.12.0
14 |
15 | ```
16 | 如果还没有配置环境,[跳转](https://github.com/shabake/Configure-the-Flutter-environment)配置`Flutter`环境
17 |
18 |
19 | #### 体验demo
20 | 
21 |
22 |
23 | #### 安装方法:
24 |
25 | ```
26 | cd 你要存放的目录
27 | ```
28 |
29 | ```
30 | git clone https://github.com/shabake/GHMall.git
31 | ```
32 |
33 | ```
34 | flutter pub get
35 | ```
36 |
37 | 如果终端输出
38 |
39 | ```
40 | Waiting for another flutter command to release the startup lock
41 | ```
42 | 找到`flutterSDK`文件夹
43 |
44 | 如`flutter/bin/cache`
45 |
46 | 删除`lockfile`
47 |
48 | 重新执行`flutter pub get `
49 |
50 | 运行一个`iOS`或安卓模拟器
51 |
52 | 如果连接真机`iOS`打开在`GHMall/ios/Runner.xcworkspace`
53 |
54 | 配置开发者账户
55 |
56 | 最后执行`flutter run`
57 |
58 |
59 |
60 | ## 项目中用到的插件
61 |
62 | | 名称 | 描述 |
63 | | ----------------------------- | ------------ |
64 | | dio | 网络请求 |
65 | | fluttertoast | 提示 toast |
66 | | sqflite | 数据持久化 |
67 | | flutter_swiper | 轮播图 |
68 | | flutter_screenutil | 屏幕适配 |
69 | | cached_network_image | 缓存网络图片 |
70 | | shared_preferences | 本地存储 |
71 | | event_bus | 事件通知 |
72 | | provider | 状态管理 |
73 | | flutter_screenutil | 屏幕适配 |
74 | | city_pickers | 城市选择器 |
75 | | flutter_easyrefresh | 刷新控件 |
76 | | transparent_image | 图片动画 |
77 |
78 | ```diff
79 | 已经实现
80 | + 实现用户注册登录
81 | + 商品浏览
82 | + 商品属性筛选
83 | + 添加商品
84 | + 购物车增加减少商品
85 | + 提交订单
86 | + 已经适配iOS,测试模拟器iPhone11
87 |
88 | 计划实现
89 | - 用户登录验证码倒计时
90 | - 用户地址
91 | - 用户订单列表查看
92 | - 用户订单详情
93 |
94 | ```
95 |
96 |
97 |
98 | ### 在使用中如有任何问题欢迎骚扰我,如果对你有帮助请点帮我一个✨,小弟感激不尽:blush:
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/android/GHMall_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 29
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.GHMall"
42 | minSdkVersion 16
43 | targetSdkVersion 29
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
14 |
15 |
22 |
26 |
30 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/GHMall/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.GHMall
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/ghome_project.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/.DS_Store
--------------------------------------------------------------------------------
/images/2.0x/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/2.0x/bg.png
--------------------------------------------------------------------------------
/images/2.0x/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/2.0x/logo.png
--------------------------------------------------------------------------------
/images/2.0x/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/2.0x/user.png
--------------------------------------------------------------------------------
/images/2.0x/user_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/2.0x/user_bg.jpg
--------------------------------------------------------------------------------
/images/3.0x/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/3.0x/bg.png
--------------------------------------------------------------------------------
/images/3.0x/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/3.0x/logo.png
--------------------------------------------------------------------------------
/images/3.0x/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/3.0x/user.png
--------------------------------------------------------------------------------
/images/3.0x/user_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/3.0x/user_bg.jpg
--------------------------------------------------------------------------------
/images/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/bg.jpg
--------------------------------------------------------------------------------
/images/checkNormal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/checkNormal.png
--------------------------------------------------------------------------------
/images/checkSelected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/checkSelected.png
--------------------------------------------------------------------------------
/images/collect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/collect.png
--------------------------------------------------------------------------------
/images/customerService.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/customerService.png
--------------------------------------------------------------------------------
/images/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/down.png
--------------------------------------------------------------------------------
/images/downSeletecd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/downSeletecd.png
--------------------------------------------------------------------------------
/images/filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/filter.png
--------------------------------------------------------------------------------
/images/filterSeletecd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/filterSeletecd.png
--------------------------------------------------------------------------------
/images/goPublic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/goPublic.png
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/logo.png
--------------------------------------------------------------------------------
/images/pay_alipay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/pay_alipay.png
--------------------------------------------------------------------------------
/images/pay_wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/pay_wechat.png
--------------------------------------------------------------------------------
/images/price.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/price.png
--------------------------------------------------------------------------------
/images/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/screen.png
--------------------------------------------------------------------------------
/images/serviceIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/serviceIcon.png
--------------------------------------------------------------------------------
/images/shop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/shop.png
--------------------------------------------------------------------------------
/images/shoppingCart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/shoppingCart.png
--------------------------------------------------------------------------------
/images/thickness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/thickness.png
--------------------------------------------------------------------------------
/images/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/up.png
--------------------------------------------------------------------------------
/images/upSeletecd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/upSeletecd.png
--------------------------------------------------------------------------------
/images/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/user.png
--------------------------------------------------------------------------------
/images/user_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/images/user_bg.jpg
--------------------------------------------------------------------------------
/ios/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/.DS_Store
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/.last_build_id:
--------------------------------------------------------------------------------
1 | a67acd9601eb94d3b5d8b2f461b84a41
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - flutter_webview_plugin (0.0.1):
4 | - Flutter
5 | - fluttertoast (0.0.2):
6 | - Flutter
7 | - FMDB (2.7.5):
8 | - FMDB/standard (= 2.7.5)
9 | - FMDB/standard (2.7.5)
10 | - HandyJSON (5.0.2)
11 | - shared_preferences (0.0.1):
12 | - Flutter
13 | - sqflite (0.0.2):
14 | - Flutter
15 | - FMDB (>= 2.7.5)
16 | - tencent_im_plugin (0.0.1):
17 | - Flutter
18 | - HandyJSON
19 | - TXIMSDK_iOS (= 4.6.58)
20 | - TXIMSDK_iOS (4.6.58)
21 |
22 | DEPENDENCIES:
23 | - Flutter (from `Flutter`)
24 | - flutter_webview_plugin (from `.symlinks/plugins/flutter_webview_plugin/ios`)
25 | - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
26 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
27 | - sqflite (from `.symlinks/plugins/sqflite/ios`)
28 | - tencent_im_plugin (from `.symlinks/plugins/tencent_im_plugin/ios`)
29 |
30 | SPEC REPOS:
31 | trunk:
32 | - FMDB
33 | - HandyJSON
34 | - TXIMSDK_iOS
35 |
36 | EXTERNAL SOURCES:
37 | Flutter:
38 | :path: Flutter
39 | flutter_webview_plugin:
40 | :path: ".symlinks/plugins/flutter_webview_plugin/ios"
41 | fluttertoast:
42 | :path: ".symlinks/plugins/fluttertoast/ios"
43 | shared_preferences:
44 | :path: ".symlinks/plugins/shared_preferences/ios"
45 | sqflite:
46 | :path: ".symlinks/plugins/sqflite/ios"
47 | tencent_im_plugin:
48 | :path: ".symlinks/plugins/tencent_im_plugin/ios"
49 |
50 | SPEC CHECKSUMS:
51 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
52 | flutter_webview_plugin: ed9e8a6a96baf0c867e90e1bce2673913eeac694
53 | fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b
54 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
55 | HandyJSON: 9e4e236f5d2dbefad5155a77417bbea438201c03
56 | shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
57 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
58 | tencent_im_plugin: a055ed155fd2cae7f006e756dbec96255b4aa0a3
59 | TXIMSDK_iOS: d4231ccd8a045f54ca04d008dba46fdbf25687fb
60 |
61 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
62 |
63 | COCOAPODS: 1.9.3
64 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "size": "20x20",
5 | "idiom": "iphone",
6 | "filename": "icon-20@2x.png",
7 | "scale": "2x"
8 | },
9 | {
10 | "size": "20x20",
11 | "idiom": "iphone",
12 | "filename": "icon-20@3x.png",
13 | "scale": "3x"
14 | },
15 | {
16 | "size": "29x29",
17 | "idiom": "iphone",
18 | "filename": "icon-29.png",
19 | "scale": "1x"
20 | },
21 | {
22 | "size": "29x29",
23 | "idiom": "iphone",
24 | "filename": "icon-29@2x.png",
25 | "scale": "2x"
26 | },
27 | {
28 | "size": "29x29",
29 | "idiom": "iphone",
30 | "filename": "icon-29@3x.png",
31 | "scale": "3x"
32 | },
33 | {
34 | "size": "40x40",
35 | "idiom": "iphone",
36 | "filename": "icon-40@2x.png",
37 | "scale": "2x"
38 | },
39 | {
40 | "size": "40x40",
41 | "idiom": "iphone",
42 | "filename": "icon-40@3x.png",
43 | "scale": "3x"
44 | },
45 | {
46 | "size": "60x60",
47 | "idiom": "iphone",
48 | "filename": "icon-60@2x.png",
49 | "scale": "2x"
50 | },
51 | {
52 | "size": "60x60",
53 | "idiom": "iphone",
54 | "filename": "icon-60@3x.png",
55 | "scale": "3x"
56 | },
57 | {
58 | "size": "20x20",
59 | "idiom": "ipad",
60 | "filename": "icon-20-ipad.png",
61 | "scale": "1x"
62 | },
63 | {
64 | "size": "20x20",
65 | "idiom": "ipad",
66 | "filename": "icon-20@2x-ipad.png",
67 | "scale": "2x"
68 | },
69 | {
70 | "size": "29x29",
71 | "idiom": "ipad",
72 | "filename": "icon-29-ipad.png",
73 | "scale": "1x"
74 | },
75 | {
76 | "size": "29x29",
77 | "idiom": "ipad",
78 | "filename": "icon-29@2x-ipad.png",
79 | "scale": "2x"
80 | },
81 | {
82 | "size": "40x40",
83 | "idiom": "ipad",
84 | "filename": "icon-40.png",
85 | "scale": "1x"
86 | },
87 | {
88 | "size": "40x40",
89 | "idiom": "ipad",
90 | "filename": "icon-40@2x.png",
91 | "scale": "2x"
92 | },
93 | {
94 | "size": "76x76",
95 | "idiom": "ipad",
96 | "filename": "icon-76.png",
97 | "scale": "1x"
98 | },
99 | {
100 | "size": "76x76",
101 | "idiom": "ipad",
102 | "filename": "icon-76@2x.png",
103 | "scale": "2x"
104 | },
105 | {
106 | "size": "83.5x83.5",
107 | "idiom": "ipad",
108 | "filename": "icon-83.5@2x.png",
109 | "scale": "2x"
110 | },
111 | {
112 | "size": "1024x1024",
113 | "idiom": "ios-marketing",
114 | "filename": "icon-1024.png",
115 | "scale": "1x"
116 | }
117 | ],
118 | "info": {
119 | "version": 1,
120 | "author": "icon.wuruihong.com"
121 | }
122 | }
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | GHMall
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/lib/.DS_Store
--------------------------------------------------------------------------------
/lib/generated_plugin_registrant.dart:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // ignore_for_file: lines_longer_than_80_chars
6 |
7 | import 'package:shared_preferences_web/shared_preferences_web.dart';
8 |
9 | import 'package:flutter_web_plugins/flutter_web_plugins.dart';
10 |
11 | // ignore: public_member_api_docs
12 | void registerPlugins(Registrar registrar) {
13 | SharedPreferencesPlugin.registerWith(registrar);
14 | registrar.registerMessageHandler();
15 | }
16 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'routers/router.dart';
3 | import 'package:provider/provider.dart';
4 | import 'provider/Cart.dart';
5 | import 'package:flutter/cupertino.dart';
6 |
7 | void main() {
8 | /// 将状态栏设置为白色
9 | // SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
10 |
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatefulWidget {
15 | MyApp({Key key}) : super(key: key);
16 |
17 | _MyAppState createState() => _MyAppState();
18 | }
19 |
20 | class _MyAppState extends State {
21 | @override
22 | Widget build(BuildContext context) {
23 | return MaterialApp(
24 | /// 隐藏debug
25 | debugShowCheckedModeBanner: false,
26 | /// 配置路由
27 | initialRoute: '/',
28 | onGenerateRoute: onGenerateRoute,
29 | /// 设置主题
30 | theme: ThemeData(
31 | primaryColor: Colors.white,
32 | ),
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/model/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/lib/model/.DS_Store
--------------------------------------------------------------------------------
/lib/model/GHAddressModel.dart:
--------------------------------------------------------------------------------
1 |
2 | class GHAddressModel {
3 | List results;
4 |
5 | GHAddressModel({this.results});
6 |
7 | GHAddressModel.fromJson(Map json) {
8 | if (json['results'] != null) {
9 | results = new List();
10 | json['results'].forEach((v) {
11 | results.add(new Results.fromJson(v));
12 | });
13 | }
14 | }
15 |
16 | Map toJson() {
17 | final Map data = new Map();
18 | if (this.results != null) {
19 | data['results'] = this.results.map((v) => v.toJson()).toList();
20 | }
21 | return data;
22 | }
23 | }
24 |
25 | class Results {
26 | String province;
27 | String area;
28 | String city;
29 | String detailsAddress;
30 | String remark;
31 | String zone;
32 | String phone;
33 | String userId;
34 | String objectId;
35 | String updatedAt;
36 | String createdAt;
37 | String name;
38 | String isDefault;
39 | Where where;
40 |
41 | Results(
42 | {this.detailsAddress,
43 | this.remark,
44 | this.province,
45 | this.area,
46 | this.city,
47 | this.zone,
48 | this.phone,
49 | this.userId,
50 | this.objectId,
51 | this.updatedAt,
52 | this.createdAt,
53 | this.name,
54 | this.isDefault,
55 | this.where});
56 |
57 | Results.fromJson(Map json) {
58 | detailsAddress = json['detailsAddress'];
59 | if (detailsAddress == null) {
60 | detailsAddress = "暂无地址";
61 | }
62 | remark = json['remark'];
63 | zone = json['zone'];
64 | if (zone == null) {
65 | zone = "暂无地址";
66 | }
67 | phone = json['phone'];
68 | if (phone == null) {
69 | phone = "13800000000";
70 | }
71 | userId = json['userId'];
72 | objectId = json['objectId'];
73 | updatedAt = json['updatedAt'];
74 | createdAt = json['createdAt'];
75 | province = json['province'];
76 | city = json['city'];
77 | area = json['area'];
78 | name = json['name'];
79 | if (name == null) {
80 | name = "没有设置";
81 | }
82 | isDefault = json['isDefault'];
83 | where = json['where'] != null ? new Where.fromJson(json['where']) : null;
84 | }
85 |
86 | Map toJson() {
87 | final Map data = new Map();
88 | data['detailsAddress'] = this.detailsAddress;
89 | data['remark'] = this.remark;
90 | data['zone'] = this.zone;
91 | data['phone'] = this.phone;
92 | data['userId'] = this.userId;
93 | data['objectId'] = this.objectId;
94 | data['updatedAt'] = this.updatedAt;
95 | data['createdAt'] = this.createdAt;
96 | data['name'] = this.name;
97 | data['isDefault'] = this.isDefault;
98 | data['province'] = this.province;
99 | data['city'] = this.city;
100 | data['area'] = this.area;
101 |
102 |
103 | if (this.where != null) {
104 | data['where'] = this.where.toJson();
105 | }
106 | return data;
107 | }
108 | }
109 |
110 | class Where {
111 | String token;
112 | String userId;
113 |
114 | Where({this.token, this.userId});
115 |
116 | Where.fromJson(Map json) {
117 | token = json['token'];
118 | userId = json['userId'];
119 | }
120 |
121 | Map toJson() {
122 | final Map data = new Map();
123 | data['token'] = this.token;
124 | data['userId'] = this.userId;
125 | return data;
126 | }
127 | }
128 |
129 |
--------------------------------------------------------------------------------
/lib/model/GHCategoryModel.dart:
--------------------------------------------------------------------------------
1 | class GHCategoryModel {
2 | List results;
3 |
4 | GHCategoryModel({this.results});
5 |
6 | GHCategoryModel.fromJson(Map json) {
7 | if (json['results'] != null) {
8 | results = new List();
9 | json['results'].forEach((v) {
10 | results.add(new GHCategoryItemModel.fromJson(v));
11 | });
12 | }
13 | }
14 |
15 | Map toJson() {
16 | final Map data = new Map();
17 | if (this.results != null) {
18 | data['result'] = this.results.map((v) => v.toJson()).toList();
19 | }
20 | return data;
21 | }
22 | }
23 |
24 | class GHCategoryItemModel {
25 |
26 | String categoryName; //所有的类型都继承 Object
27 | String type;
28 | String url;
29 |
30 | GHCategoryItemModel(
31 | {
32 | this.categoryName,
33 | this.type,
34 | this.url,
35 | });
36 |
37 | GHCategoryItemModel.fromJson(Map json) {
38 | categoryName = json['categoryName'];
39 | url = json['url'];
40 | type = json['type'];
41 | }
42 |
43 | Map toJson() {
44 | final Map data = new Map();
45 |
46 | data['categoryName'] = this.categoryName;
47 | data['url'] = this.url;
48 | data['type'] = this.type;
49 |
50 | return data;
51 | }
52 | }
--------------------------------------------------------------------------------
/lib/model/GHGoodDetailsModel.dart:
--------------------------------------------------------------------------------
1 | class GHGoodDetailsModel {
2 | String isSelf;
3 | String description;
4 | List coupons;
5 | List service;
6 | int sales;
7 | List urls;
8 | String receiptTip;
9 | String updatedAt;
10 | String evaluate;
11 | String objectId;
12 | List storeAdvantages;
13 | String createdAt;
14 | String title;
15 | String goodId;
16 | Operators operators;
17 | String url;
18 | Object price;
19 | int count;
20 | String seletecdStrings;
21 | bool check;
22 |
23 | GHGoodDetailsModel(
24 | {this.isSelf,
25 | this.description,
26 | this.coupons,
27 | this.service,
28 | this.sales,
29 | this.urls,
30 | this.receiptTip,
31 | this.updatedAt,
32 | this.evaluate,
33 | this.objectId,
34 | this.goodId,
35 | this.storeAdvantages,
36 | this.createdAt,
37 | this.title,
38 | this.operators,
39 | this.url,
40 | this.count,
41 | this.seletecdStrings,
42 | this.check,
43 | this.price});
44 |
45 | GHGoodDetailsModel.fromJson(Map json) {
46 | isSelf = json['isSelf'];
47 | description = json['description'];
48 | Object tempCoupons = json['coupons'];
49 | if (tempCoupons is List) {
50 | coupons = tempCoupons.cast();
51 | } else {
52 | coupons = [];
53 | }
54 |
55 | Object tempservice = json['service'];
56 | if (tempservice is List) {
57 | service = tempservice.cast();
58 | } else {
59 | service = [];
60 | }
61 |
62 | sales = json['sales'];
63 |
64 | Object tempurls = json['urls'];
65 | if (tempurls is List) {
66 | urls = tempurls.cast();
67 | } else {
68 | urls = [];
69 | }
70 | count = json['count'];
71 | check = json['check'];
72 | goodId = json['goodId'];
73 | receiptTip = json['receiptTip'];
74 | updatedAt = json['updatedAt'];
75 | evaluate = json['evaluate'];
76 | objectId = json['objectId'];
77 | Object tempstoreAdvantages = json['storeAdvantages'];
78 | if (tempstoreAdvantages is List) {
79 | storeAdvantages = tempstoreAdvantages.cast();
80 | } else {
81 | storeAdvantages = [];
82 | }
83 |
84 | createdAt = json['createdAt'];
85 | title = json['title'];
86 | operators = json['operators'] != null
87 | ? new Operators.fromJson(json['operators'])
88 | : null;
89 | url = json['url'];
90 | price = json['price'];
91 | seletecdStrings = json['seletecdStrings'];
92 | }
93 |
94 | Map toJson() {
95 | final Map data = new Map();
96 | data['isSelf'] = this.isSelf;
97 | data['description'] = this.description;
98 | data['coupons'] = this.coupons;
99 | data['service'] = this.service;
100 | data['sales'] = this.sales;
101 | data['urls'] = this.urls;
102 | data['receiptTip'] = this.receiptTip;
103 | data['updatedAt'] = this.updatedAt;
104 | data['evaluate'] = this.evaluate;
105 | data['objectId'] = this.objectId;
106 | data['count'] = this.count;
107 | data['check'] = this.check;
108 | data['storeAdvantages'] = this.storeAdvantages;
109 | data['createdAt'] = this.createdAt;
110 | data['title'] = this.title;
111 | data['goodId'] = this.goodId;
112 |
113 | data['seletecdStrings'] = this.seletecdStrings;
114 | if (this.operators != null) {
115 | data['operators'] = this.operators.toJson();
116 | }
117 | data['url'] = this.url;
118 | data['price'] = this.price;
119 | return data;
120 | }
121 | }
122 |
123 | class Operators {
124 | List operator;
125 |
126 | Operators({this.operator});
127 |
128 | Operators.fromJson(Map json) {
129 | if (json['operator'] != null) {
130 | operator = new List();
131 | json['operator'].forEach((v) {
132 | operator.add(new Operator.fromJson(v));
133 | });
134 | }
135 | }
136 |
137 | Map toJson() {
138 | final Map data = new Map();
139 | if (this.operator != null) {
140 | data['operator'] = this.operator.map((v) => v.toJson()).toList();
141 | }
142 | return data;
143 | }
144 | }
145 |
146 | class Operator {
147 | String title;
148 |
149 | Operator({this.title});
150 | Operator.fromJson(Map json) {
151 | title = json['title'];
152 | }
153 |
154 | Map toJson() {
155 | final Map data = new Map();
156 | data['title'] = this.title;
157 | return data;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/lib/model/GHGoodsModel.dart:
--------------------------------------------------------------------------------
1 | class GHGoodsModel {
2 | List results;
3 |
4 | GHGoodsModel({this.results});
5 |
6 | GHGoodsModel.fromJson(Map json) {
7 | if (json['results'] != null) {
8 | results = new List();
9 | json['results'].forEach((v) {
10 | results.add(new GHGoodsItemModel.fromJson(v));
11 | });
12 | }
13 | }
14 |
15 | Map toJson() {
16 | final Map data = new Map();
17 | if (this.results != null) {
18 | data['results'] = this.results.map((v) => v.toJson()).toList();
19 | }
20 | return data;
21 | }
22 | }
23 |
24 | class GHGoodsItemModel {
25 | String description;
26 | String updatedAt;
27 | String evaluate;
28 | String objectId;
29 | String createdAt;
30 | String title;
31 | String url;
32 | int price;
33 | int sales;
34 | String isSelf;
35 |
36 | GHGoodsItemModel(
37 | {this.description,
38 | this.updatedAt,
39 | this.evaluate,
40 | this.objectId,
41 | this.createdAt,
42 | this.title,
43 | this.url,
44 | this.sales,
45 | this.isSelf,
46 | this.price});
47 |
48 | GHGoodsItemModel.fromJson(Map json) {
49 | description = json['description'];
50 | updatedAt = json['updatedAt'];
51 | evaluate = json['evaluate'];
52 | objectId = json['objectId'];
53 | createdAt = json['createdAt'];
54 | title = json['title'];
55 | url = json['url'];
56 | sales = json['sales'];
57 | isSelf = json['isSelf'];
58 | price = json['price'];
59 | }
60 |
61 | Map toJson() {
62 | final Map data = new Map();
63 | data['description'] = this.description;
64 | data['updatedAt'] = this.updatedAt;
65 | data['evaluate'] = this.evaluate;
66 | data['objectId'] = this.objectId;
67 | data['createdAt'] = this.createdAt;
68 | data['title'] = this.title;
69 | data['url'] = this.url;
70 | data['sales'] = this.sales;
71 | data['price'] = this.price;
72 | data['isSelf'] = this.isSelf;
73 | return data;
74 | }
75 | }
--------------------------------------------------------------------------------
/lib/model/GHGuessLikeModel.dart:
--------------------------------------------------------------------------------
1 | class GHGuessLikeModel {
2 | List results;
3 |
4 | GHGuessLikeModel({this.results});
5 |
6 | GHGuessLikeModel.fromJson(Map json) {
7 | if (json['results'] != null) {
8 | results = new List();
9 | json['results'].forEach((v) {
10 | results.add(new GHGuessLikeItemModel.fromJson(v));
11 | });
12 | }
13 | }
14 |
15 | Map toJson() {
16 | final Map data = new Map();
17 | if (this.results != null) {
18 | data['result'] = this.results.map((v) => v.toJson()).toList();
19 | }
20 | return data;
21 | }
22 | }
23 |
24 | class GHGuessLikeItemModel {
25 |
26 | Object price; //所有的类型都继承 Object
27 | String url;
28 |
29 | GHGuessLikeItemModel(
30 | {
31 | this.price,
32 |
33 | this.url,
34 | });
35 |
36 | GHGuessLikeItemModel.fromJson(Map json) {
37 | url = json['url'];
38 |
39 | price = json['price'];
40 |
41 | }
42 |
43 | Map toJson() {
44 | final Map data = new Map();
45 |
46 | data['price'] = this.price;
47 |
48 | data['url'] = this.url;
49 |
50 | return data;
51 | }
52 | }
--------------------------------------------------------------------------------
/lib/model/GHHotGoodsModel.dart:
--------------------------------------------------------------------------------
1 | class GHHotGoodsModel {
2 | List results;
3 |
4 | GHHotGoodsModel({this.results});
5 |
6 | GHHotGoodsModel.fromJson(Map json) {
7 | if (json['results'] != null) {
8 | results = new List();
9 | json['results'].forEach((v) {
10 | results.add(new GHHotGoodsItemModel.fromJson(v));
11 | });
12 | }
13 | }
14 |
15 | Map toJson() {
16 | final Map data = new Map();
17 | if (this.results != null) {
18 | data['result'] = this.results.map((v) => v.toJson()).toList();
19 | }
20 | return data;
21 | }
22 | }
23 |
24 | class GHHotGoodsItemModel {
25 |
26 | String price; //所有的类型都继承 Object
27 | String url;
28 | String oldPrice;
29 | String title;
30 |
31 | GHHotGoodsItemModel(
32 | {
33 | this.price,
34 | this.oldPrice,
35 | this.title,
36 | this.url,
37 | });
38 |
39 | GHHotGoodsItemModel.fromJson(Map json) {
40 | url = json['url'];
41 | oldPrice = json['oldPrice'];
42 | title = json['title'];
43 | price = json['price'];
44 | }
45 |
46 | Map toJson() {
47 | final Map data = new Map();
48 |
49 | data['price'] = this.price;
50 | data['title'] = this.title;
51 | data['oldPrice'] = this.oldPrice;
52 | data['url'] = this.url;
53 | return data;
54 | }
55 | }
--------------------------------------------------------------------------------
/lib/model/GHomeCarouselDataModel.dart:
--------------------------------------------------------------------------------
1 | class GHomeCarouselDataModel {
2 | List results;
3 |
4 | GHomeCarouselDataModel({this.results});
5 |
6 | GHomeCarouselDataModel.fromJson(Map json) {
7 | if (json['results'] != null) {
8 | results = new List();
9 | json['results'].forEach((v) {
10 | results.add(new GHomeCarouselDataItemModel.fromJson(v));
11 | });
12 | }
13 | }
14 |
15 | Map toJson() {
16 | final Map data = new Map();
17 | if (this.results != null) {
18 | data['results'] = this.results.map((v) => v.toJson()).toList();
19 | }
20 | return data;
21 | }
22 | }
23 |
24 | class GHomeCarouselDataItemModel {
25 | String objectId;
26 | String updatedAt;
27 | String url;
28 | String createdAt;
29 | GHomeCarouselDataItemModel({this.objectId, this.updatedAt, this.url, this.createdAt});
30 |
31 | GHomeCarouselDataItemModel.fromJson(Map json) {
32 | objectId = json['objectId'];
33 | updatedAt = json['updatedAt'];
34 | url = json['url'];
35 | createdAt = json['createdAt'];
36 | }
37 |
38 | Map toJson() {
39 | final Map data = new Map();
40 | data['objectId'] = this.objectId;
41 | data['updatedAt'] = this.updatedAt;
42 | data['url'] = this.url;
43 | data['createdAt'] = this.createdAt;
44 | return data;
45 | }
46 | }
--------------------------------------------------------------------------------
/lib/pages/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shabake/GHMall/a0f38fc75d737377cd14f0950b7aa2fe0b4eae58/lib/pages/.DS_Store
--------------------------------------------------------------------------------
/lib/pages/Cart/CartItem.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:provider/provider.dart';
3 | import '../../provider/Cart.dart';
4 |
5 | class CartItem extends StatefulWidget {
6 |
7 |
8 | /// 数据模型
9 | Map _itemData;
10 |
11 | bool isEnable;
12 |
13 | CartItem(this._itemData, {Key key,this.isEnable = true}) : super(key: key);
14 |
15 | _CartItemState createState() => _CartItemState();
16 | }
17 |
18 | class _CartItemState extends State {
19 | @override
20 | Map _itemData;
21 | var cartProvider;
22 |
23 | void initState() {
24 | super.initState();
25 | this._itemData = widget._itemData;
26 | }
27 |
28 | Widget _cartCenterNumber() {
29 | return Container(
30 | decoration: BoxDecoration(
31 | border: Border.all(
32 | width: 1,
33 | color: Colors.black12,
34 | )),
35 | child: Row(
36 | children: [
37 | Container(
38 | alignment: Alignment.center,
39 | width: 40,
40 | height: 20,
41 | child: Text("${this._itemData["count"]}"),
42 | decoration: BoxDecoration(
43 | border: Border(
44 | left: BorderSide(
45 | width: 0.5,
46 | color: Colors.black12,
47 | ),
48 | right: BorderSide(
49 | width: 1,
50 | color: Colors.black12,
51 | )),
52 | ),
53 | ),
54 | ],
55 | ),
56 | );
57 | }
58 |
59 | Widget _cartRightNumber() {
60 | return InkWell(
61 | onTap: () {
62 | if(!widget.isEnable) {
63 | print("禁止响应");
64 | return;
65 | }
66 | setState(() {
67 |
68 | this._itemData["count"]++;
69 | });
70 | this.cartProvider.changeCartList();
71 | },
72 | child: Container(
73 | decoration: BoxDecoration(
74 | border: Border.all(
75 | width: 1,
76 | color: Colors.black12,
77 | )),
78 | child: Row(
79 | children: [
80 | Container(
81 | alignment: Alignment.center,
82 | width: 20,
83 | height: 20,
84 | child: Text("+"),
85 | ),
86 | ],
87 | ),
88 | ),
89 | );
90 | }
91 |
92 | Widget _cartLeftNumber() {
93 | return InkWell(
94 | onTap: () {
95 | if(!widget.isEnable) {
96 | print("禁止响应");
97 | return;
98 | }
99 | if (this._itemData["count"] > 1) {
100 | setState(() {
101 | this._itemData["count"]--;
102 | });
103 | }
104 | this.cartProvider.changeCartList();
105 | },
106 | child: Container(
107 | decoration: BoxDecoration(
108 | border: Border.all(
109 | width: 1,
110 | color: Colors.black12,
111 | )),
112 | child: Row(
113 | children: [
114 | Container(
115 | alignment: Alignment.center,
116 | width: 20,
117 | height: 20,
118 | child: Text("-"),
119 | ),
120 | ],
121 | ),
122 | ),
123 | );
124 | }
125 |
126 | Widget build(BuildContext context) {
127 | this.cartProvider = Provider.of(context);
128 | return Container(
129 | child: Row(
130 | mainAxisAlignment: MainAxisAlignment.end,
131 | children: [
132 | _cartLeftNumber(),
133 | _cartCenterNumber(),
134 | _cartRightNumber(),
135 | ],
136 | ),
137 | );
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/lib/pages/GHAddressEdit.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../widget/GHButton.dart';
3 | import '../widget/GHTextWidget.dart';
4 | import '../services/ScreenAdaper.dart';
5 | //import 'package:city_pickers/city_pickers.dart';
6 | import '../services/httptool.dart';
7 | import '../widget/GHLoading.dart';
8 | import '../services/GHToast.dart';
9 |
10 | /// 编辑/新增收货地址
11 | class GHAddressEdit extends StatefulWidget {
12 | final Map arguments;
13 |
14 | @override
15 | GHAddressEdit({Key key, this.arguments}) : super(key: key);
16 | _GHAddressEditState createState() => _GHAddressEditState();
17 | }
18 |
19 | class _GHAddressEditState extends State {
20 | /// 收件人姓名
21 | String _name = "";
22 |
23 | /// 收货人电话
24 | String _phoneNumber = "";
25 |
26 | /// 省份
27 | String _province = "省";
28 |
29 | /// 市
30 | String _city = "市";
31 |
32 | /// 区
33 | String _area = "区";
34 |
35 | /// 省编码
36 | String _locationCode = "110000";
37 |
38 | /// 详细地址
39 | String _detailsAddress = "";
40 |
41 | /// 完整地址
42 | String _fullAddress = "";
43 |
44 | TextEditingController _addressController = new TextEditingController();
45 | TextEditingController _nameController = new TextEditingController();
46 | TextEditingController _phoneNumberController = new TextEditingController();
47 | TextEditingController _detailsAddressController = new TextEditingController();
48 |
49 | FocusNode _contentFocusNode = FocusNode();
50 |
51 | void initState() {
52 | super.initState();
53 | if (widget.arguments != null) {
54 | this._nameController.text = widget.arguments["name"];
55 | this._phoneNumberController.text = widget.arguments["phoneNumber"];
56 | this._addressController.text = widget.arguments["address"];
57 | }
58 | }
59 |
60 | _changeAddress() {
61 |
62 | }
63 |
64 | bool _checkAddress(){
65 | if(this._nameController.text.isEmpty
66 | ||this._phoneNumberController.text.isEmpty
67 | ||this._province.isEmpty
68 | ||this._city.isEmpty
69 | ||this._area.isEmpty
70 | ||this._detailsAddressController.text.isEmpty) {
71 | GHToast.showTost("地址信息填写不全");
72 | return false;
73 | }
74 | return true;
75 | }
76 |
77 | _addAddress(BuildContext context) {
78 |
79 | var url =
80 | "https://a4cj1hm5.api.lncld.net/1.1/classes/shopAddress";
81 | Map params ={
82 | 'name':this._nameController.text,
83 | 'phoneNumber':this._phoneNumberController.text,
84 | 'province':this._province,
85 | 'city':this._city,
86 | 'area':this._area,
87 | 'detailsAddress':this._detailsAddressController.text,
88 | };
89 | HttpRequest.request(url, method: 'POST',params:params).then((value) {
90 | var objectId = value["objectId"];
91 | if (objectId != null) {
92 | GHToast.showTost("添加地址成功");
93 | Navigator.pop(context);
94 | }
95 | });
96 | }
97 |
98 | _getAddress() {
99 | var url =
100 | "https://a4cj1hm5.api.lncld.net/1.1/classes/addressDetails/${widget.arguments["objectId"]}";
101 | HttpRequest.request(url, method: 'GET').then((value) {
102 | print(value);
103 | });
104 | }
105 |
106 | _deletecdAddress(BuildContext context) {
107 | var url =
108 | "https://a4cj1hm5.api.lncld.net/1.1/classes/addressDetails/${widget.arguments["objectId"]}";
109 | HttpRequest.request(url, method: 'DELETE').then((value) {
110 | GHToast.showTost("删除成功");
111 | Navigator.pop(context);
112 | });
113 | }
114 |
115 | _showCityPicker(BuildContext context) async {
116 | // Result result = await CityPickers.showCityPicker(
117 | // cancelWidget: Container(
118 | // child: Text(
119 | // "取消",
120 | // style: TextStyle(fontSize: 16),
121 | // ),
122 | // ),
123 | // locationCode: this._locationCode,
124 | // confirmWidget: Container(
125 | // child: Text(
126 | // "确定",
127 | // style: TextStyle(fontSize: 16),
128 | // ),
129 | // ),
130 | // height: 300,
131 | // context: context,
132 | // );
133 | //{"provinceName":"北京市","provinceId":"110000",
134 | // "cityName":"北京城区","cityId":"110100",
135 | // "areaName":"东城区","areaId":"110101"}
136 | // setState(() {
137 | // this._province = result.provinceName;
138 | // this._city = result.cityName;
139 | // this._area = result.areaName;
140 | // this._locationCode = result.provinceId;
141 | // this._fullAddress = _province + _city + _area;
142 | // });
143 | }
144 |
145 | @override
146 |
147 | Widget build(BuildContext context) {
148 | ScreenAdaper.init(context);
149 | return Scaffold(
150 | appBar: AppBar(
151 | actions: [
152 | TextButton(
153 | onPressed: () {
154 | _contentFocusNode.unfocus();
155 | _deletecdAddress(context);
156 | },
157 | child: Text("删除"))
158 | ],
159 | title: widget.arguments == null ? Text("新增收货地址"):Text("新增收货地址"),
160 | ),
161 | body: GestureDetector(
162 | onTap: () {
163 | _contentFocusNode.unfocus();
164 | },
165 | child: Container(
166 | padding: EdgeInsets.all(20),
167 | child: ListView(
168 | children: [
169 | Container(
170 | child: GHTextWidget(
171 | "收件人姓名",
172 | textEditingController: _nameController,
173 | ),
174 | ),
175 | Container(
176 | child: GHTextWidget(
177 | "收件人电话",
178 | textEditingController: _phoneNumberController,
179 | ),
180 | ),
181 | Container(
182 | child: InkWell(
183 | onTap: () {
184 | this._showCityPicker(context);
185 | },
186 | child: Container(
187 | height: 50,
188 | child: Row(
189 | crossAxisAlignment: CrossAxisAlignment.center,
190 | children: [
191 | Icon(
192 | Icons.location_on,
193 | color: Colors.red,
194 | ),
195 | SizedBox(
196 | width: 5,
197 | ),
198 | Text(
199 | "${this._province} /${this._city}/${this._area}",
200 | style: TextStyle(
201 | fontSize: 14,
202 | ),
203 | ),
204 | ],
205 | ),
206 | ),
207 | ),
208 | ),
209 | Divider(
210 | height: 1,
211 | color: Colors.black12,
212 | ),
213 | ListView(
214 | shrinkWrap: true,
215 | physics: NeverScrollableScrollPhysics(),
216 | children: [
217 | Container(
218 | child: TextField(
219 | controller: this._detailsAddressController,
220 | focusNode: this._contentFocusNode,
221 | maxLines: null,
222 | decoration: InputDecoration(
223 | contentPadding: EdgeInsets.only(left: 0, top: 0),
224 | hintText: "详细地址",
225 | border: OutlineInputBorder(
226 | borderRadius: BorderRadius.circular(30),
227 | borderSide: BorderSide.none),
228 | )),
229 | ),
230 | SizedBox(
231 | height: 10,
232 | ),
233 | Container(
234 | child: GHButton(
235 | "确定",
236 | tapAction: () {
237 | _contentFocusNode.unfocus();
238 | if(this._checkAddress()) {
239 | this._addAddress(context);
240 | }
241 | },
242 | ),
243 | )
244 | ],
245 | )
246 | ],
247 | ),
248 | ),
249 | ));
250 | }
251 | }
252 |
--------------------------------------------------------------------------------
/lib/pages/GHAddressList.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../services/ScreenAdaper.dart';
3 | import '../services/httptool.dart';
4 | import 'package:common_utils/common_utils.dart';
5 | import '../model/GHAddressModel.dart';
6 | import 'package:flutter_easyrefresh/easy_refresh.dart';
7 |
8 | /// 收货地址列表
9 | class GHAddressList extends StatefulWidget {
10 | @override
11 | _GHAddressListState createState() => _GHAddressListState();
12 | }
13 |
14 | class _GHAddressListState extends State {
15 | /// 地址列表
16 | var _list = [];
17 |
18 | GlobalKey _easyRefreshKey = new GlobalKey();
19 |
20 | _getAddressList() async {
21 | //addressDetails
22 | //shopAddress
23 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopAddress";
24 | var c = Uri.encodeComponent('-createdAt');
25 | var d = Uri.encodeComponent('李');
26 |
27 | // --data-urlencode 'scan_key=score' \ \
28 | //%7Bname:%20%E6%9D%8E%7D
29 | //%7b%22name%22%3a+%22%e6%9d%8e%22%7d
30 | // var b = Uri.encodeQueryComponent(map.toString());
31 | //where={"score": 100}
32 | // url = url+'?'+ "limit="+c + "&" + "where="+b;
33 |
34 | url = url + '?' + "order=" + c;
35 |
36 | HttpRequest.request(url, method: 'GET').then((res) {
37 | var list = new GHAddressModel.fromJson(res).results;
38 | setState(() {
39 | this._list = list;
40 | });
41 | });
42 | }
43 |
44 | void initState() {
45 | super.initState();
46 | this._easyRefreshKey.currentState;
47 | }
48 |
49 | void deactivate() {
50 | // 返回到当前页刷新
51 | var bool = ModalRoute.of(context).isCurrent;
52 | if (bool) {
53 | this._getAddressList();
54 | }
55 | }
56 |
57 | Widget ListItem(Results results) {
58 | return InkWell(
59 | onTap: () {},
60 | child: Container(
61 | margin: EdgeInsets.only(top: 5, bottom: 5),
62 | width: ScreenAdaper.getScreenWidth(),
63 | child: Column(
64 | children: [
65 | Row(
66 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
67 | children: [
68 | Row (
69 | children: [
70 | Column(
71 | crossAxisAlignment: CrossAxisAlignment.start,
72 | children: [
73 | Container(
74 | child: Row(
75 | children: [
76 | Container(
77 | width:50,
78 | child: Text(
79 | results.name,
80 | overflow: TextOverflow.ellipsis,
81 | style:TextStyle(
82 | fontSize: 18,
83 | fontWeight: FontWeight.bold,
84 | ),
85 | ),
86 | ),
87 | SizedBox(
88 | width: 10,
89 | ),
90 | Container(
91 | child: Text(
92 | results.phone,
93 | style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),
94 | ),
95 | ),
96 | ],
97 | ),
98 | ),
99 | Container(
100 | width: ScreenAdaper.getScreenWidth() - 20 - 20 - 30,
101 | child: Text(
102 | results.province +
103 | results.city +
104 | results.area +
105 | results.detailsAddress,
106 | style: TextStyle(fontSize: 14, color: Colors.black54),
107 | ),
108 | ),
109 |
110 | ],
111 | )
112 | ],
113 | ),
114 | GestureDetector(
115 |
116 | onTap: () {
117 | Navigator.pushNamed(context, '/GHAddressEdit', arguments: {
118 | 'name': "${results.name}",
119 | 'zone': "${results.zone}",
120 | 'detailsAddress': "${results.detailsAddress}",
121 | 'phoneNumber': results.phone,
122 | 'objectId': results.objectId,
123 | });
124 | },
125 | child: Container(
126 | child: Icon(
127 | Icons.edit,
128 | size: 30,
129 | ),
130 | ),
131 | ),
132 | ],
133 | ),
134 | Divider(),
135 | ],
136 | )
137 | ),
138 | );
139 | }
140 |
141 | @override
142 | Widget build(BuildContext context) {
143 | ScreenAdaper.init(context);
144 | ScreenAdaper.init(context);
145 | return Scaffold(
146 | appBar: AppBar(
147 | actions: [
148 | TextButton(
149 | onPressed: () {
150 | Navigator.pushNamed(context, '/GHAddressEdit');
151 | },
152 | child: Icon(Icons.add),
153 | )
154 | ],
155 | title: Text("地址管理"),
156 | ),
157 | body: Container(
158 | padding: EdgeInsets.all(20),
159 | child: EasyRefresh(
160 | firstRefresh: true,
161 | key:_easyRefreshKey,
162 | onRefresh: () async {
163 | await this._getAddressList();
164 | },
165 | onLoad: () async {
166 | await this._getAddressList();
167 | },
168 | child: ListView.builder(
169 | itemBuilder: (context, index) {
170 | return ListItem(this._list[index]);
171 | },
172 | itemCount: this._list.length,
173 | ),
174 | )),
175 | );
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/lib/pages/GHLoginPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../widget/GHTextWidget.dart';
3 | import '../widget/GHButton.dart';
4 | import '../services/GHToast.dart';
5 | import '../services/gh_sqflite.dart';
6 | import '../services/EventBus.dart';
7 | import 'package:flutter/gestures.dart';
8 | import 'dart:core';
9 | import '../services/httptool.dart';
10 |
11 | /// 登录页面
12 | class GHLoginPage extends StatefulWidget {
13 | @override
14 | _GHLoginPageState createState() => _GHLoginPageState();
15 | }
16 |
17 | class _GHLoginPageState extends State {
18 | /// 手机号码
19 | TextEditingController _mobilePhoneNumberEditingController =
20 | TextEditingController();
21 |
22 | /// 验证码
23 | TextEditingController _codeEditingController = TextEditingController();
24 |
25 | @override
26 | void initState() {
27 | super.initState();
28 | }
29 |
30 | /// 注册或登录
31 | void _login(String mobilePhoneNumber, String smsCode) async {
32 | var url = "https://a4cj1hm5.api.lncld.net/1.1/usersByMobilePhone";
33 | Map params = {
34 | "mobilePhoneNumber": "+86${mobilePhoneNumber}",
35 | "smsCode": smsCode,
36 | };
37 | print(params);
38 | await HttpRequest.request(url, method: 'POST', params: params).then((res) {
39 | print(res);
40 | if (res == null) {
41 | GHToast.showTost("登录失败,请重试");
42 | } else {
43 | GHToast.showTost("登录成功");
44 | String objectId = res["objectId"];
45 | String username = res["username"];
46 | String mobilePhone = res["mobilePhoneNumber"];
47 | GHSqflite sqflite = GHSqflite();
48 | sqflite.add(objectId, username, mobilePhone);
49 |
50 | /// 发送广播
51 | eventBus.fire(LoginSuccessEvent('登录成功'));
52 |
53 | /// 返回到根控制器
54 | Navigator.pop(context);
55 | }
56 | });
57 | }
58 |
59 | /// 请求验证码
60 | void _requestSmsCode(String mobilePhoneNumber) async {
61 | var url = "https://a4cj1hm5.api.lncld.net/1.1/requestSmsCode";
62 | Map params = {
63 | "mobilePhoneNumber": mobilePhoneNumber,
64 | };
65 | await HttpRequest.request(url, method: 'POST', params: params).then((res) {
66 | if (res == null) {
67 | GHToast.showTost("请求验证码失败");
68 | } else {
69 | GHToast.showTost("请求验证码成功");
70 | }
71 | });
72 | }
73 |
74 | /// 校验手机号码
75 | bool _checkParameters(String username) {
76 | if (username == null) {
77 | return false;
78 | }
79 | RegExp reg = new RegExp(r"^1\d{10}$");
80 | if (reg.hasMatch(username)) {
81 | return true;
82 | } else {
83 | GHToast.showTost("手机号格式不正确,请重新输入");
84 | return false;
85 | }
86 | }
87 |
88 | Widget build(BuildContext context) {
89 | return Scaffold(
90 | body: GestureDetector(
91 | behavior: HitTestBehavior.translucent,
92 | onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
93 | child: Container(
94 | padding: EdgeInsets.all(20),
95 | child: ListView(
96 | children: [
97 | /// logo
98 | Container(
99 | margin: EdgeInsets.only(top: 30, bottom: 30),
100 | child: Center(
101 | child: Image.asset(
102 | 'images/logo.png',
103 | fit: BoxFit.fill,
104 | width: 100,
105 | height: 100,
106 | ),
107 | )),
108 | SizedBox(
109 | height: 20,
110 | ),
111 | Container(
112 | height: 50,
113 | child: GHTextWidget(
114 | "请输入用户名",
115 | onChanged: (value) {},
116 | textEditingController:
117 | this._mobilePhoneNumberEditingController,
118 | ),
119 | ),
120 | SizedBox(
121 | height: 20,
122 | ),
123 | Container(
124 | child: Row(
125 | children: [
126 | Container(
127 | width: 240,
128 | height: 50,
129 | child: Container(
130 | child: GHTextWidget(
131 | "验证码",
132 | textEditingController: this._codeEditingController,
133 | ),
134 | ),
135 | ),
136 | Container(
137 | width: 10,
138 | child: Text(""),
139 | ),
140 | Expanded(
141 | flex: 1,
142 | child: Container(
143 | decoration: BoxDecoration(
144 | border: Border.all(color: Colors.black12, width: 1)),
145 | child: TextButton(
146 | onPressed: () {
147 | this._requestSmsCode(
148 | this._mobilePhoneNumberEditingController.text);
149 | },
150 | child: Text(
151 | "重新发送",
152 | style: TextStyle(fontSize: 14, color: Colors.black54),
153 | ),
154 | ),
155 | ),
156 | )
157 | ],
158 | )),
159 |
160 | Container(
161 | height: 50,
162 | padding: EdgeInsets.only(top: 10, bottom: 10),
163 | child: Stack(
164 | children: [
165 | InkWell(
166 | onTap: () {
167 | print("忘记密码");
168 | },
169 | child: Align(
170 | alignment: Alignment.centerLeft,
171 | child: Text(
172 | "忘记密码",
173 | style:
174 | TextStyle(fontSize: 14, color: Colors.black54),
175 | ),
176 | ),
177 | ),
178 | ],
179 | )),
180 | Container(
181 | height: 50,
182 | child: GHButton(
183 | "登录",
184 | backGroudColor: Colors.red,
185 | tapAction: () {
186 | FocusScope.of(context).requestFocus(FocusNode());
187 | var username =
188 | this._mobilePhoneNumberEditingController.text.trim();
189 | if (this._checkParameters(username)) {
190 | this._login(this._mobilePhoneNumberEditingController.text,
191 | this._codeEditingController.text);
192 | }
193 | },
194 | ),
195 | ),
196 | SizedBox(
197 | height: 20,
198 | ),
199 | Container(
200 | child: RichText(
201 | text: TextSpan(
202 | text: "登录即代表同意",
203 | style: TextStyle(color: Colors.black),
204 | children: [
205 | TextSpan(
206 | recognizer: TapGestureRecognizer()
207 | ..onTap = () {
208 | print('点击了隐私政策');
209 | },
210 | text: "《隐私协议》",
211 | style: TextStyle(color: Colors.blue)),
212 | ])),
213 | )
214 | ],
215 | ),
216 | ),
217 | ),
218 | appBar: AppBar(
219 | leading: IconButton(
220 | icon: Icon(
221 | Icons.arrow_back_ios,
222 | color: Colors.black38,
223 | ),
224 | onPressed: () {
225 | Navigator.pop(context);
226 | },
227 | ),
228 | actions: [
229 | TextButton(
230 | onPressed: () {
231 | GHToast.showTost("点击了联系客服");
232 | },
233 | child: Text(
234 | "客服",
235 | style: TextStyle(fontSize: 16, color: Colors.black54),
236 | ),
237 | ),
238 | ],
239 | ),
240 | );
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/lib/pages/GHOnlinePayments.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../widget/GHButton.dart';
3 | import '../services/httptool.dart';
4 | import '../widget/GHRichTextPriceWidget.dart';
5 | import '../services/GHToast.dart';
6 |
7 | /// 在线支付
8 | class GHOnlinePayments extends StatefulWidget {
9 | Map arguments;
10 |
11 | @override
12 | GHOnlinePayments({Key key, this.arguments}) : super(key: key);
13 |
14 | _GHOnlinePaymentsState createState() => _GHOnlinePaymentsState();
15 | }
16 |
17 | class _GHOnlinePaymentsState extends State {
18 | /// 支付方式 true 微信 false 支付宝
19 | bool _seletecd = true;
20 | String _orderId = "";
21 | double _total = 0;
22 | List _goodList = [];
23 |
24 | /// 获取订单详情
25 | void _getOrderDetails(String id) async {
26 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopOrderList/${id}";
27 | await HttpRequest.request(url, method: 'GET').then((res) {
28 | print(res);
29 | _goodList = res["goodList"];
30 | double _temptotal = res["total"];
31 | setState(() {
32 | this._total = _temptotal;
33 | });
34 | });
35 | }
36 |
37 | /// 增加用户支付方式
38 | void _addPayway(String id, String payway) async {
39 | Map params = {
40 | "payway": payway,
41 | };
42 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopOrderList/${id}";
43 | await HttpRequest.request(url, method: 'PUT', params: params).then((res) {
44 | String updatedAt = res["updatedAt"];
45 | if (updatedAt != null) {
46 | GHToast.showTost("选择支付方式成功");
47 | List _goodIds = [];
48 | for (var dict in _goodList) {
49 | String goodId = dict["goodId"];
50 | _goodIds.add(goodId);
51 | }
52 | this._deletedGoods(_goodIds);
53 |
54 | } else {
55 | GHToast.showTost("选择支付方式失败");
56 | }
57 | });
58 | }
59 |
60 | /// 批量删除购物车中的商品
61 | void _deletedGoods(List goods) async {
62 | List maps = [];
63 | for (var i = 0; i < goods.length; i++) {
64 | String gooodId = goods[i];
65 | print("商品id是");
66 | print(gooodId);
67 | Map map = {
68 | "method": "DELETE",
69 | "path": "/1.1/classes/shopCartList/${gooodId}"
70 | };
71 | maps.add(map);
72 | }
73 |
74 | print(maps);
75 |
76 | var url = "https://a4cj1hm5.api.lncld.net/1.1/batch";
77 | Map params = {"requests": maps};
78 | HttpRequest.request(url, method: 'POST', params: params).then((value) {
79 | print(value);
80 | if (value != null) {
81 | GHToast.showTost("成功");
82 | Navigator.pushNamed(context, '/', arguments: {
83 | "index": 2,
84 | });
85 | } else {
86 | GHToast.showTost("删除失败");
87 | }
88 | });
89 | }
90 |
91 | @override
92 | void initState() {
93 | super.initState();
94 | this._orderId = widget.arguments["id"];
95 | this._getOrderDetails(this._orderId);
96 | }
97 |
98 | Widget build(BuildContext context) {
99 | return Scaffold(
100 | appBar: AppBar(
101 | title: Text("支付方式"),
102 | ),
103 | body: Container(
104 | padding: EdgeInsets.all(20),
105 | child: ListView(
106 | children: [
107 | Container(
108 | padding: EdgeInsets.only(bottom: 10),
109 | child: Text(
110 | "订单号: ${this._orderId}",
111 | style: TextStyle(fontSize: 16),
112 | ),
113 | ),
114 | Container(
115 | height: 10,
116 | color: Color.fromRGBO(245, 245, 245, 1),
117 | ),
118 | GestureDetector(
119 | behavior: HitTestBehavior.opaque,
120 | onTap: () {
121 | setState(() {
122 | this._seletecd = !this._seletecd;
123 | });
124 | },
125 | child: Container(
126 | height: 60,
127 | child: Row(
128 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
129 | children: [
130 | Row(children: [
131 | Container(
132 | height: 40,
133 | width: 40,
134 | child: Image.asset(
135 | 'images/pay_wechat.png',
136 | fit: BoxFit.cover,
137 | ),
138 | ),
139 | SizedBox(
140 | width: 10,
141 | ),
142 | Container(
143 | child: Text(
144 | "微信",
145 | style: TextStyle(fontSize: 18),
146 | ),
147 | ),
148 | ]),
149 | Container(
150 | width: 20,
151 | height: 20,
152 | child: this._seletecd == true
153 | ? Image.asset('images/checkSelected.png')
154 | : Image.asset('images/checkNormal.png'))
155 | ])),
156 | ),
157 | Divider(),
158 | GestureDetector(
159 | behavior: HitTestBehavior.opaque,
160 | onTap: () {
161 | setState(() {
162 | this._seletecd = !this._seletecd;
163 | });
164 | },
165 | child: Container(
166 | height: 60,
167 | child: Row(
168 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
169 | children: [
170 | Row(children: [
171 | Container(
172 | height: 40,
173 | width: 40,
174 | child: Image.asset(
175 | 'images/pay_alipay.png',
176 | fit: BoxFit.fill,
177 | ),
178 | ),
179 | SizedBox(
180 | width: 10,
181 | ),
182 | Container(
183 | child: Text(
184 | "支付宝",
185 | style: TextStyle(fontSize: 18),
186 | ),
187 | ),
188 | ]),
189 | Container(
190 | width: 20,
191 | height: 20,
192 | child: this._seletecd != true
193 | ? Image.asset('images/checkSelected.png')
194 | : Image.asset('images/checkNormal.png'))
195 | ],
196 | )),
197 | ),
198 | Divider(),
199 | Container(
200 | padding: EdgeInsets.all(10),
201 | child: Row(
202 | mainAxisAlignment: MainAxisAlignment.end,
203 | children: [
204 | Container(
205 | child: GestureDetector(
206 | behavior: HitTestBehavior.opaque,
207 | onTap: () {},
208 | child: Text("待支付金额"),
209 | )),
210 | SizedBox(
211 | width: 5,
212 | ),
213 | Container(
214 | child: GHRichTextPriceWidget(this._total + 10),
215 | ),
216 | ],
217 | ),
218 | ),
219 | Container(
220 | padding: EdgeInsets.all(10),
221 | child: GHButton(
222 | "确定",
223 | tapAction: () {
224 | this._addPayway(widget.arguments["id"],
225 | this._seletecd == true ? "微信" : "支付宝");
226 | },
227 | ),
228 | ),
229 | Container(
230 | alignment: Alignment.centerRight,
231 | padding: EdgeInsets.all(10),
232 | child: Text("线上下单,线下支付")),
233 | ],
234 | ),
235 | ),
236 | );
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/lib/pages/GHOrderList.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../services/httptool.dart';
3 |
4 | class GHOrderListPage extends StatefulWidget {
5 | @override
6 | _GHOrderListPageState createState() => _GHOrderListPageState();
7 | }
8 |
9 | class _GHOrderListPageState extends State {
10 | @override
11 | void initState() {
12 | super.initState();
13 | _getOrderList();
14 | }
15 |
16 | /// 获取订单列表数据
17 | void _getOrderList() async {
18 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopOrderList";
19 | await HttpRequest.request(url, method: 'GET').then((value) {
20 | List results = value["results"];
21 | print(value);
22 | });
23 | }
24 |
25 | Widget _orderListWidget() {
26 | return Container(child: Text("2222"));
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return Scaffold(
32 | appBar: AppBar(
33 | title: Text("订单列表"),
34 | ),
35 | body: _orderListWidget());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib/pages/Search.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../services/ScreenAdaper.dart';
3 | import '../widget/GHButton.dart';
4 | import '../widget/GHCustomAppbar.dart';
5 |
6 | /// 搜索
7 | class SearchPage extends StatefulWidget {
8 | SearchPage({Key key}) : super(key: key);
9 |
10 | _SearchPageState createState() => _SearchPageState();
11 | }
12 |
13 | class _SearchPageState extends State {
14 | @override
15 | final GlobalKey _scaffoldKey = new GlobalKey();
16 |
17 | /// 用户输入的关键字
18 | var _keywors;
19 |
20 | /// 热搜关键字
21 | var _hotwords = [
22 | {"key": "apple", "type": "1"},
23 | {"key": "小米", "type": "1"},
24 | {"key": "华为", "type": "1"},
25 | {"key": "魅族", "type": "1"},
26 | {"key": "iPad", "type": "1"},
27 | {"key": "口罩", "type": "1"}
28 | ];
29 |
30 | Widget build(BuildContext context) {
31 | ScreenAdaper.init(context);
32 | final double topPadding = MediaQuery.of(context).padding.top;
33 | return Scaffold(
34 | key: _scaffoldKey,
35 | drawer: Drawer(
36 | child: Container(
37 | child: Text("22"),
38 | )),
39 | appBar: GHCustomAppbar(
40 | contentHeight: topPadding + 44,
41 | leadingWidget: Container(
42 | padding: EdgeInsets.only(left: 20),
43 | child: InkWell(
44 | onTap: () {
45 | Navigator.pop(context);
46 | },
47 | child: Icon(
48 | Icons.arrow_back_ios,
49 | color: Colors.black38,
50 | size: 20,
51 | ),
52 | ),
53 | ),
54 | titleWidget: Container(
55 | child: Container(
56 | width: ScreenAdaper.getScreenWidth() - 100,
57 | height: ScreenAdaper.height(50),
58 | decoration: BoxDecoration(
59 | color: Color.fromRGBO(233, 233, 233, 0.8),
60 | borderRadius: BorderRadius.circular(30),
61 | ),
62 | child: Row(
63 | children: [
64 | Container(
65 | padding: EdgeInsets.fromLTRB(5, 5, 0, 5),
66 | alignment: Alignment.center,
67 | child: Icon(
68 | Icons.search,
69 | color: Colors.black12,
70 | ),
71 | ),
72 | Container(
73 | alignment: Alignment.center,
74 | height: ScreenAdaper.height(50),
75 | width: ScreenAdaper.width(240),
76 | child: TextField(
77 | maxLength: 30,
78 | cursorColor: Color.fromRGBO(170, 170, 170, 1),
79 | onChanged: (value) {
80 | this._keywors = value;
81 | },
82 | style: TextStyle(fontSize: 14),
83 | autofocus: true,
84 | decoration: InputDecoration(
85 | contentPadding: EdgeInsets.only(left: 0, top: 0),
86 | counterText: '',
87 | hintText: "请输入要搜索的内容",
88 | hintStyle: TextStyle(
89 | color: Color.fromRGBO(170, 170, 170, 0.1),
90 | ),
91 | border: OutlineInputBorder(
92 | borderSide: BorderSide.none,
93 | borderRadius: BorderRadius.circular(30),
94 | )),
95 | ),
96 | ),
97 | ],
98 | ),
99 | ),
100 | ),
101 | trailingWidget: Container(
102 | alignment: Alignment.center,
103 | width: 40,
104 | child: InkWell(
105 | onTap: () {
106 | print("222");
107 | _scaffoldKey.currentState.openDrawer();
108 | },
109 | child: Text(
110 | "搜索",
111 | style: TextStyle(fontSize: 14),
112 | ),
113 | )),
114 | ),
115 | body: ListView(
116 | children: [
117 | _commomTitleWidget("热搜", Icons.whatshot),
118 | Container(
119 | padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
120 | child: Column(
121 | crossAxisAlignment: CrossAxisAlignment.start,
122 | children: [
123 | Wrap(
124 | children: this._hotwords.map((value) {
125 | return Container(
126 | padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
127 | child: Chip(
128 | backgroundColor: Color.fromRGBO(235, 235, 235, 1),
129 | shape: RoundedRectangleBorder(
130 | borderRadius: BorderRadius.circular(5.0)),
131 | label: Text("${value["key"]}"),
132 | ),
133 | );
134 | }).toList(),
135 | ),
136 | ],
137 | ),
138 | ),
139 | _commomTitleWidget("历史记录", Icons.history),
140 | Column(
141 | mainAxisAlignment: MainAxisAlignment.start,
142 | children: [
143 | Container(
144 | padding:
145 | EdgeInsets.only(left: 20, top: 10, right: 10, bottom: 10),
146 | alignment: Alignment.centerLeft,
147 | child: Row(
148 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
149 | children: [
150 | Container(
151 | child: Text(
152 | "apple",
153 | style: TextStyle(
154 | fontSize: 16,
155 | fontWeight: FontWeight.normal,
156 | ),
157 | ),
158 | ),
159 | Container(
160 | child: InkWell(
161 | onTap: () {
162 | print("删除");
163 | },
164 | child: Icon(Icons.delete_outline),
165 | ),
166 | )
167 | ],
168 | )),
169 | Divider(),
170 | Container(
171 | padding: EdgeInsets.only(top: 50),
172 | width: ScreenAdaper.getScreenWidth() - 40,
173 | child: GHButton(
174 | "清空历史记录",
175 | tapAction: () {
176 | print("清空");
177 | },
178 | ),
179 | ),
180 | ],
181 | )
182 | ],
183 | ),
184 | );
185 | }
186 |
187 | Widget _commomTitleWidget(text, iconData) {
188 | return Column(
189 | crossAxisAlignment: CrossAxisAlignment.start,
190 | children: [
191 | Container(
192 | padding: EdgeInsets.fromLTRB(20, 20, 20, 0),
193 | child: Row(
194 | children: [
195 | Container(
196 | child: Icon(
197 | iconData,
198 | color: Colors.red,
199 | ),
200 | ),
201 | SizedBox(
202 | width: 5,
203 | ),
204 | Container(
205 | child: Text(text,
206 | style:
207 | TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
208 | ),
209 | ],
210 | )),
211 | Divider(),
212 | ],
213 | );
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/lib/pages/Test.dart:
--------------------------------------------------------------------------------
1 | //import 'dart:convert';
2 | //
3 | //import 'package:flutter/material.dart';
4 | ////import 'package:sy_flutter_alipay/sy_flutter_alipay.dart';
5 | ////import 'package:dio/dio.dart';
6 | ////import 'package:sy_flutter_wechat/sy_flutter_wechat.dart';
7 | //
8 | //class AliPay extends StatefulWidget {
9 | // @override
10 | // _AliPayState createState() => _AliPayState();
11 | //}
12 | //
13 | //class _AliPayState extends State {
14 | // @override
15 | // void initState() {
16 | // super.initState();
17 | // _register();
18 | // }
19 | //
20 | // _register() async {
21 | // bool result = await SyFlutterWechat.register('wx5881fa2638a2ca60');
22 | // print(result);
23 | // }
24 | // _wxPay() async{
25 | // var apiUrl='http://agent.itying.com/wxpay/';
26 | // var myPayInfo =await Dio().get(apiUrl);
27 | //
28 | // Map myInfo =json.decode(myPayInfo.data);
29 | // print(myInfo);
30 | //
31 | // var payInfo={
32 | // "appid":myInfo["appid"].toString(),
33 | // "partnerid":myInfo["partnerid"].toString(),
34 | // "prepayid":myInfo["prepayid"].toString(),
35 | // "package":myInfo["package"].toString(),
36 | // "noncestr":myInfo["noncestr"].toString(),
37 | // "timestamp":myInfo["timestamp"].toString(),
38 | // "sign":myInfo["sign"].toString(),
39 | // };
40 | // SyPayResult payResult = await SyFlutterWechat.pay(
41 | // SyPayInfo.fromJson(payInfo)
42 | // );
43 | //
44 | // print(payResult);
45 | // }
46 | //
47 | // //支付宝支付
48 | // _doAliPay() async {
49 | // print("支付宝支付...");
50 | // var serverApi = "http://agent.itying.com/alipay/";
51 | //
52 | // var serverData = await Dio().get(serverApi);
53 | //
54 | // var payInfo = serverData.data;
55 | // var result = await SyFlutterAlipay.pay(
56 | // payInfo,
57 | // urlScheme: 'flutteralipay', //前面配置的urlScheme
58 | // // isSandbox: true //是否是沙箱环境,只对android有效
59 | // );
60 | // print(result);
61 | // }
62 | //
63 | // @override
64 | // Widget build(BuildContext context) {
65 | // return Scaffold(
66 | //
67 | // body: Center(
68 | // child: Column(
69 | // mainAxisAlignment: MainAxisAlignment.center,
70 | // children: [
71 | // RaisedButton(
72 | // child: Text('支付宝支付'),
73 | // onPressed: _doAliPay,
74 | // ),
75 | // RaisedButton(
76 | // child: Text('分享文字'),
77 | // onPressed: () async {
78 | // bool res = await SyFlutterWechat.shareText('hello world',
79 | // shareType: SyShareType.session);
80 | // print('分享文字:' + res.toString());
81 | // },
82 | // ),
83 | // RaisedButton(
84 | // child: Text('分享图片'),
85 | // onPressed: () async {
86 | // bool res = await SyFlutterWechat.shareImage(
87 | // 'https://avatars0.githubusercontent.com/u/10024776',
88 | // shareType: SyShareType.timeline);
89 | // print('分享图片:' + res.toString());
90 | // },
91 | // ),
92 | // RaisedButton(
93 | // child: Text('分享网页'),
94 | // onPressed: () async {
95 | // bool res = await SyFlutterWechat.shareWebPage(
96 | // '标题',
97 | // '描述',
98 | // 'https://avatars0.githubusercontent.com/u/10024776',
99 | // 'http://www.example.com',
100 | // shareType: SyShareType.session);
101 | // print('分享网页:' + res.toString());
102 | // },
103 | // ),
104 | // RaisedButton(
105 | // child: Text('支付'),
106 | // onPressed: _wxPay,
107 | // ),
108 | // ],
109 | // ),
110 | // ),
111 | // );
112 | // }
113 | //}
114 | //
115 | //
116 | //
117 | //
118 |
--------------------------------------------------------------------------------
/lib/pages/tabs/GHCategoryPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../../services/ScreenAdaper.dart';
3 | import 'package:flutter_swiper/flutter_swiper.dart';
4 | import '../../widget/LoadingWidget.dart';
5 | import '../../services/httptool.dart';
6 | import '../../model/GHCategoryModel.dart';
7 | import 'dart:convert';
8 | import 'package:transparent_image/transparent_image.dart';
9 | import '../../widget/GHCustomAppbar.dart';
10 | import '../../services/GHToast.dart';
11 | //import 'package:barcode_scan/barcode_scan.dart';
12 |
13 | /// 分类
14 | class GHCategoryPage extends StatefulWidget {
15 | GHCategoryPage({Key key}) : super(key: key);
16 |
17 | _GHCategoryPageState createState() => _GHCategoryPageState();
18 | }
19 |
20 | class _GHCategoryPageState extends State
21 | with AutomaticKeepAliveClientMixin {
22 |
23 | /// 左侧选择序号
24 | int _selectIndex = 0;
25 |
26 | List _leftCateList = [];
27 |
28 | List _urls = [];
29 |
30 | String _firstTitle;
31 |
32 | /// 第一组商品
33 | List _firstGoods = [];
34 |
35 | String _secondTitle;
36 |
37 | /// 第二组商品
38 | List _secondGoods = [];
39 |
40 | // final picker = ImagePicker();
41 | @override
42 |
43 | /// 保持页面状态
44 | bool get wantKeepAlive => true;
45 |
46 | void initState() {
47 | super.initState();
48 | _getLeftCateData();
49 | }
50 |
51 | /// 获取左侧分类
52 | _getLeftCateData() async {
53 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopCategory";
54 | await HttpRequest.request(url, method: 'GET').then((value) {
55 | var list = new GHCategoryModel.fromJson(value).results;
56 | setState(() {
57 | this._leftCateList = list;
58 | });
59 | });
60 | _getRightCateData(this._leftCateList[0].type);
61 | }
62 |
63 | /// 获取右侧分类
64 | _getRightCateData(type) async {
65 | var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopSecondCategory";
66 | //where={"type":"1"}
67 | /// urlEncode编码
68 | var actionString = {"type": type};
69 | var jsonText = jsonEncode(actionString);
70 | var parameter = Uri.encodeFull(jsonText);
71 |
72 | /// 得到最终url
73 | url = url + '?' + "where=" + parameter;
74 |
75 | await HttpRequest.request(url, method: 'GET').then((value) {
76 | print(value);
77 | List results = value["results"];
78 | if (results.isEmpty && results.length == 0) {
79 | GHToast.showTost("获取数据失败,请检查服务器");
80 | return;
81 | }
82 | Map urlMap = results.first["urls"];
83 | List urls = urlMap["url"];
84 | List firstGoods = [];
85 | List secondGoods = [];
86 | List firstgoods = results.first["firstDict"]["goods"];
87 | List secondgoods = results.first["secondDict"]["goods"];
88 | String firstTitle = results.first["firstDict"]["title"];
89 | String secondTitle = results.first["secondDict"]["title"];
90 |
91 | for (var dict in firstgoods) {
92 | var item = new GHCategoryItemModel.fromJson(dict);
93 | firstGoods.add(item);
94 | }
95 |
96 | for (var dict in secondgoods) {
97 | var item = new GHCategoryItemModel.fromJson(dict);
98 | secondGoods.add(item);
99 | }
100 | setState(() {
101 | this._urls = urls;
102 | this._firstTitle = firstTitle;
103 | this._firstGoods = firstGoods;
104 | this._secondTitle = secondTitle;
105 | this._secondGoods = secondGoods;
106 | });
107 | });
108 | }
109 |
110 | /// 左侧列表Widget
111 | Widget _leftCateWidget(leftWidth) {
112 | if (this._leftCateList.length == 0) {
113 | return LoadingWidget();
114 | }
115 | return Container(
116 | width: leftWidth,
117 | height: double.infinity,
118 | child: ListView.builder(
119 | itemCount: this._leftCateList.length,
120 | itemBuilder: (context, index) {
121 | GHCategoryItemModel itemModel = this._leftCateList[index];
122 | return Column(
123 | mainAxisAlignment: MainAxisAlignment.center,
124 | children: [
125 | InkWell(
126 | onTap: () {
127 | setState(() {
128 | this._selectIndex = index;
129 | this._getRightCateData(this._leftCateList[index].type);
130 | });
131 | },
132 | child: Stack(
133 | children: [
134 | Container(
135 | alignment: Alignment.center,
136 | width: double.infinity,
137 | height: ScreenAdaper.height(80),
138 | color: this._selectIndex != index
139 | ? Color.fromRGBO(233, 233, 233, 0.2)
140 | : Colors.white,
141 | child: Text(
142 | "${itemModel.categoryName}",
143 | textAlign: TextAlign.center,
144 | style: TextStyle(
145 | fontSize: this._selectIndex != index ? 14 : 16,
146 | fontWeight: this._selectIndex != index
147 | ? FontWeight.normal
148 | : FontWeight.bold,
149 | ),
150 | ),
151 | ),
152 | Container(
153 | width: double.infinity,
154 | height: ScreenAdaper.height(80),
155 | child: Row(
156 | crossAxisAlignment: CrossAxisAlignment.center,
157 | mainAxisAlignment: MainAxisAlignment.start,
158 | children: [
159 | Container(
160 | height: 18,
161 | width: 3,
162 | color: this._selectIndex != index
163 | ? Colors.transparent
164 | : Colors.red,
165 | )
166 | ],
167 | ),
168 | )
169 | ],
170 | )),
171 | Divider(height: 0.5),
172 | ],
173 | );
174 | },
175 | ),
176 | );
177 | }
178 |
179 | /// 轮播图
180 | Widget _swiperWidget() {
181 | if (this._urls.length == 0) {
182 | return LoadingWidget();
183 | }
184 | return Container(
185 | padding: EdgeInsets.all(10),
186 | height: 150,
187 | child: Swiper(
188 | key: UniqueKey(),
189 | itemBuilder: (BuildContext context, int index) {
190 | return InkWell(
191 | onTap: () {},
192 | child: Image.network(
193 | this._urls[index],
194 | // pic
195 | fit: BoxFit.cover,
196 | ),
197 | );
198 | },
199 | itemCount: this._urls.length,
200 | pagination: new SwiperPagination(),
201 | autoplay: false),
202 | );
203 | }
204 |
205 | Widget _categoryItem(
206 | GHCategoryItemModel categoryItemModel, BuildContext context) {
207 | return InkWell(
208 | onTap: () {
209 | Navigator.pushNamed(context, '/GHGoodsList');
210 | },
211 | child: Container(
212 | width: (ScreenAdaper.getScreenWidth() -
213 | ScreenAdaper.getScreenWidth() / 4 -
214 | 40) /
215 | 3.0,
216 | child: Column(
217 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
218 | children: [
219 | Container(
220 | height: 80,
221 | padding: EdgeInsets.all(10),
222 | child: new FadeInImage.memoryNetwork(
223 | placeholder: kTransparentImage,
224 | image: categoryItemModel.url,
225 | ),
226 | ),
227 | SizedBox(height: 5),
228 | Container(
229 | child: Text(
230 | categoryItemModel.categoryName,
231 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
232 | ),
233 | )
234 | ],
235 | ),
236 | ));
237 | }
238 |
239 | Widget _firstWidget(String title, List list, BuildContext context) {
240 | return ListView(
241 | shrinkWrap: true,
242 | physics: NeverScrollableScrollPhysics(),
243 | children: [
244 | Container(
245 | padding: EdgeInsets.only(left: 10),
246 | alignment: Alignment.centerLeft,
247 | child: Text(
248 | title,
249 | style: TextStyle(fontWeight: FontWeight.bold),
250 | ),
251 | ),
252 | SizedBox(
253 | height: 10,
254 | ),
255 | Container(
256 | padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
257 | child: Wrap(
258 | spacing: 10,
259 | runSpacing: 10,
260 | children: list.map((value) {
261 | return _categoryItem(value, context);
262 | }).toList(),
263 | ),
264 | )
265 | ],
266 | );
267 | }
268 |
269 | /// 右侧分类Widget
270 | Widget _rightCateWidget(rightItemWidth, rightItemHeight, context) {
271 | return Container(
272 | height: ScreenAdaper.getScreenHeight(),
273 | width: ScreenAdaper.getScreenWidth() / 4 * 3.0,
274 | child: ListView(
275 | children: [
276 | _swiperWidget(),
277 | this._firstTitle == null
278 | ? Text("")
279 | : _firstWidget(this._firstTitle, this._firstGoods, context),
280 | this._secondTitle == null
281 | ? Text("")
282 | : _firstWidget(this._secondTitle, this._secondGoods, context),
283 | ],
284 | ),
285 | );
286 | }
287 |
288 | /// 相机拍照
289 | void _takePhoto() async {
290 | // final pickedFile = await picker.getImage(source: ImageSource.camera);
291 | /// 开始二维码扫描
292 | // var result = await BarcodeScanner.scan();
293 | // print(result);
294 | }
295 |
296 | @override
297 | Widget build(BuildContext context) {
298 | ScreenAdaper.init(context);
299 | final double topPadding = MediaQuery.of(context).padding.top;
300 |
301 | var leftWidth = ScreenAdaper.getScreenWidth() / 4;
302 | var rightItemWidth =
303 | (ScreenAdaper.getScreenWidth() - leftWidth - 20 - 20) / 3;
304 | rightItemWidth = ScreenAdaper.width(rightItemWidth);
305 | var rightItemHeight = rightItemWidth + ScreenAdaper.height(28);
306 |
307 | return Scaffold(
308 | appBar: GHCustomAppbar(
309 | contentHeight: topPadding + 20,
310 | leadingWidget: Container(
311 | padding: EdgeInsets.only(left: 20),
312 | child: GestureDetector(
313 | onTap: (){
314 | this._takePhoto();
315 | },
316 | child: Icon(
317 | Icons.center_focus_weak,
318 | color: Colors.black54,
319 | ),
320 | )
321 | ),
322 | trailingWidget: IconButton(icon: Icon(Icons.inbox), onPressed: null),
323 | titleWidget: InkWell(
324 | onTap: () {
325 | Navigator.pushNamed(context, '/search');
326 | },
327 | child: Container(
328 | width: ScreenAdaper.getScreenWidth() - 100,
329 | height: ScreenAdaper.height(50),
330 | padding: EdgeInsets.only(left: 5),
331 | decoration: BoxDecoration(
332 | color: Color.fromRGBO(233, 233, 233, 0.5),
333 | borderRadius: BorderRadius.circular(30),
334 | ),
335 | child: Row(
336 | children: [
337 | Icon(
338 | Icons.search,
339 | color: Colors.black12,
340 | ),
341 | Text(
342 | "618秒杀",
343 | style: TextStyle(fontSize: 14, color: Colors.black12),
344 | ),
345 | ],
346 | ),
347 | ),
348 | ),
349 | ),
350 | body: Container(
351 | width: ScreenAdaper.getScreenWidth(),
352 | height: ScreenAdaper.getScreenHeight(),
353 | child: Row(
354 | children: [
355 | _leftCateWidget(leftWidth),
356 | Expanded(
357 | child: _rightCateWidget(rightItemWidth, rightItemHeight, context),
358 | )
359 | ],
360 | ),
361 | ),
362 | );
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/lib/pages/tabs/GHUserPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../../services/gh_sqflite.dart';
3 | import '../../services/EventBus.dart';
4 | import '../../widget/GHButton.dart';
5 | import '../../services/ScreenAdaper.dart';
6 | import '../../widget/GHDialog.dart';
7 | import '../../widget/GHLoading.dart';
8 | import '../GHOrderList.dart';
9 |
10 | class GHUserPage extends StatefulWidget {
11 | GHUserPage({Key key}) : super(key: key);
12 |
13 | _GHUserPageState createState() => _GHUserPageState();
14 | }
15 |
16 | class _GHUserPageState extends State {
17 | List list = [];
18 | var actionEventBus;
19 |
20 | getUserInfo() {
21 | sq.query().then((value) {
22 | setState(() {
23 | print(value);
24 | this.list = value;
25 | });
26 | });
27 | }
28 |
29 | GHSqflite sq = GHSqflite();
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 | this.actionEventBus = eventBus.on().listen((event) {
35 | this.getUserInfo();
36 | });
37 | this.getUserInfo();
38 | }
39 |
40 | void dispose() {
41 | super.dispose();
42 | this.actionEventBus.cancel();
43 | }
44 |
45 | Widget _header() {
46 | return Container(
47 | decoration: BoxDecoration(
48 | image: DecorationImage(
49 | fit: BoxFit.cover,
50 | image: AssetImage(
51 | "images/bg.jpg",
52 | ),
53 | )),
54 | width: double.infinity,
55 | height: 160,
56 | child: Row(
57 | crossAxisAlignment: CrossAxisAlignment.center,
58 | children: [
59 | Container(
60 | margin: EdgeInsets.fromLTRB(20, 30, 30, 0),
61 | child: Image.asset(
62 | 'images/logo.png',
63 | fit: BoxFit.fill,
64 | width: 80,
65 | height: 60,
66 | ),
67 | ),
68 | this.list.length == 0
69 | ? Container(
70 | child: InkWell(
71 | onTap: () {
72 | Navigator.pushNamed(context, '/login');
73 | },
74 | child: Text(
75 | "登录/注册",
76 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22, color: Colors.white),
77 | ),
78 | ))
79 | : Container(
80 | child: Column(
81 | mainAxisAlignment: MainAxisAlignment.center,
82 | crossAxisAlignment: CrossAxisAlignment.start,
83 | children: [
84 | Text(
85 | "用户名${this.list.last["username"]}",
86 | style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
87 | ),
88 | Text(
89 | "电话${this.list.last["mobilePhone"]}",
90 | style: TextStyle(color: Colors.white, fontSize: 14),
91 | ),
92 | ],
93 | )),
94 | ],
95 | ),
96 | );
97 | }
98 |
99 | Widget build(BuildContext context) {
100 | ScreenAdaper.init(context);
101 | return Container(
102 | child: SafeArea(
103 | top: false,
104 | child: ListView(
105 | padding: EdgeInsets.only(top: 0),
106 | children: [
107 | _header(),
108 | Column(
109 | children: [
110 | Container(
111 | child: ListTile(
112 | onTap: () {
113 | print("点击");
114 | Navigator.pushNamed(context, '/GHOrderListPage');
115 | },
116 | leading: Icon(
117 | Icons.star_border,
118 | color: Colors.red,
119 | ),
120 | title: Text("全部订单"),
121 | ),
122 | ),
123 | ListTile(
124 | leading: Icon(Icons.collections_bookmark, color: Colors.red),
125 | title: Text("我的收藏"),
126 | ),
127 | Container(
128 | height: 10,
129 | color: Color.fromRGBO(245, 245, 245, 1),
130 | ),
131 | ListTile(
132 | leading: Icon(Icons.people, color: Colors.red),
133 | title: Text("在线客服"),
134 | ),
135 | Container(
136 | height: 10,
137 | color: Color.fromRGBO(245, 245, 245, 1),
138 | ),
139 | ListTile(
140 | onTap: () {
141 | Navigator.pushNamed(context, '/GHAddressList');
142 | },
143 | leading: Icon(Icons.room, color: Colors.red),
144 | title: Text("我的地址"),
145 | ),
146 | Container(
147 | height: 20,
148 | color: Color.fromRGBO(245, 245, 245, 1),
149 | ),
150 | this.list.length > 0
151 | ? Container(
152 | width: ScreenAdaper.getScreenWidth() - 60,
153 | child: GHButton(
154 | "退出",
155 | tapAction: () {
156 | showDialog(
157 | context: context,
158 | builder: (BuildContext context) {
159 | return BaseDialog(
160 | Text("22"),
161 | 140,
162 | 300,
163 | sureAction: () {
164 | sq.deletedAllData().then((value) {
165 | Navigator.of(context).pop(this);
166 | this.getUserInfo();
167 | GHLoading.hideLoading(context);
168 | });
169 | },
170 | );
171 | });
172 | },
173 | ),
174 | )
175 | : Text(""),
176 | ],
177 | )
178 | ],
179 | ),
180 | ));
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/lib/pages/tabs/Tabs.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'GHUserPage.dart';
3 | import '../../services/ScreenAdaper.dart';
4 | import '../../services/gh_sqflite.dart';
5 | import 'GHHomePage.dart';
6 | import 'GHCategoryPage.dart';
7 | import 'GHShopCartPage.dart';
8 |
9 | /// tab
10 | class Tabs extends StatefulWidget {
11 | Map arguments;
12 |
13 | Tabs({Key key, this.arguments}) : super(key: key);
14 |
15 | _TabsState createState() => _TabsState();
16 | }
17 |
18 | class _TabsState extends State {
19 | int _currentIndex = 0;
20 | PageController _pageController;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 |
26 | if (widget.arguments != null) {
27 | this._currentIndex = widget.arguments["index"];
28 | } else {
29 | this._currentIndex = 0;
30 | }
31 | this._pageController = new PageController(initialPage: this._currentIndex);
32 |
33 | GHSqflite sq = GHSqflite();
34 | sq.create();
35 | }
36 |
37 | List _pageList = [
38 | GHHomePage(),
39 | GHCategoryPage(),
40 | GHShopCartPage(),
41 | GHUserPage()
42 | ];
43 |
44 | @override
45 | Widget build(BuildContext context) {
46 | ScreenAdaper.init(context);
47 | return Scaffold(
48 | body: PageView(
49 | controller: this._pageController,
50 | children: this._pageList,
51 | physics: NeverScrollableScrollPhysics(), // 禁止滑动
52 | ),
53 | bottomNavigationBar: BottomNavigationBar(
54 | currentIndex: this._currentIndex,
55 | onTap: (index) {
56 | setState(() {
57 | this._currentIndex = index;
58 | this._pageController.jumpToPage(index);
59 | });
60 | },
61 | type: BottomNavigationBarType.fixed,
62 | fixedColor: Colors.red,
63 | items: [
64 | BottomNavigationBarItem(
65 | icon: Icon(Icons.home),
66 | title: Text(
67 | "首页",
68 | style: TextStyle(fontSize: 12),
69 | ),
70 | ),
71 | BottomNavigationBarItem(
72 | icon: Icon(Icons.category),
73 | title: Text(
74 | "分类",
75 | style: TextStyle(fontSize: 12),
76 | ),
77 | ),
78 | BottomNavigationBarItem(
79 | icon: Icon(Icons.shopping_cart),
80 | title: Text(
81 | "购物车",
82 | style: TextStyle(fontSize: 12),
83 | ),
84 | ),
85 | BottomNavigationBarItem(
86 | icon: Icon(Icons.person),
87 | title: Text(
88 | "我的",
89 | style: TextStyle(fontSize: 12),
90 | ),
91 | )
92 | ],
93 | ),
94 | );
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/lib/provider/Cart.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import '../services/Storage.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class Cart with ChangeNotifier {
6 | List _cartList = [];
7 | bool _isCheckAll = false;
8 | double _totalPrice = 0.0;
9 |
10 | List get cartList => this._cartList;
11 |
12 | bool get isCheckAll => this._isCheckAll;
13 |
14 | double get totalPrice => this._totalPrice;
15 |
16 | Cart() {
17 | this.init();
18 | }
19 |
20 | init() async {
21 | try {
22 | List cartListData = json.decode(await Storage.getString('cartList'));
23 | this._cartList = cartListData;
24 | print("初始化");
25 | print(cartListData);
26 | } catch (e) {
27 | this._cartList = [];
28 | }
29 | this.isCheckAllMember();
30 | getTotalPrice();
31 | notifyListeners();
32 | }
33 |
34 | addList(value) {
35 | _cartList.add(value);
36 | notifyListeners();
37 | }
38 |
39 | updataCartList() {
40 | this.init();
41 | }
42 |
43 | changeCartList() {
44 | Storage.setString('cartList', json.encode(this._cartList));
45 | getTotalPrice();
46 | notifyListeners();
47 | }
48 |
49 | check(value) {
50 | for (var i = 0; i < this._cartList.length; i++) {
51 | this._cartList[i]["checked"] = value;
52 | }
53 | this._isCheckAll = value;
54 | Storage.setString('cartList', json.encode(this._cartList));
55 | isCheckAllMember();
56 | getTotalPrice();
57 | notifyListeners();
58 | }
59 |
60 | /// 判断全选按钮状态
61 | isCheckAllMember() async {
62 | List cartListData = json.decode(await Storage.getString('cartList'));
63 | print(cartListData);
64 | if (cartListData.length > 0) {
65 | for (var i = 0; i < cartListData.length; i++) {
66 | if (cartListData[i]["checked"] == false) {
67 | _isCheckAll = false;
68 | print("取消");
69 | break;
70 | }
71 | _isCheckAll = true;
72 | print("轩重工");
73 | }
74 | }
75 | }
76 |
77 | itemChange(value) async {
78 | for (var i = 0; i < this.cartList.length; i++) {
79 | String seletecAttr =
80 | this.cartList[i]["_id"] + this.cartList[i]['seletecAttr'];
81 | String attr = value["_id"] + value['seletecAttr'];
82 |
83 | if (attr == seletecAttr) {
84 | this.cartList[i]["checked"] = value["checked"];
85 | }
86 | }
87 | Storage.setString('cartList', json.encode(this._cartList));
88 | isCheckAllMember();
89 | getTotalPrice();
90 | notifyListeners();
91 | }
92 |
93 | removeAllData() {
94 | Storage.remove("cartList");
95 | getTotalPrice();
96 | this.cartList.clear();
97 | notifyListeners();
98 | }
99 |
100 | getTotalPrice() {
101 | double totalPrice = 0;
102 | for (var i = 0; i < this.cartList.length; i++) {
103 | if (this.cartList[i]["checked"] == true) {
104 | String price = (this.cartList[i]["price"]);
105 | int count = (this.cartList[i]["count"]);
106 | totalPrice = double.parse(price) * count + totalPrice;
107 | }
108 | }
109 | this._totalPrice = totalPrice;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/lib/routers/router.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../pages/tabs/Tabs.dart';
3 | import '../pages/Search.dart';
4 | import '../pages/GHLoginPage.dart';
5 | import '../pages/GHAddressList.dart';
6 | import '../pages/GHAddressEdit.dart';
7 | import '../pages/GHOnlinePayments.dart';
8 | import '../pages/GHGoodsList.dart';
9 | import '../pages/GHGoodsDetails.dart';
10 | import '../pages/Test.dart';
11 | import '../pages/GHCheckOutPage.dart';
12 | import '../pages/GHOrderList.dart';
13 |
14 |
15 | //配置路由
16 | final routes = {
17 | '/': (context,{arguments}) => Tabs(arguments:arguments),
18 | '/search': (context) => SearchPage(),
19 | '/login': (context) => GHLoginPage(),
20 | '/GHAddressList': (context,{arguments}) => GHAddressList(),
21 | '/GHAddressEdit': (context,{arguments}) => GHAddressEdit(arguments:arguments),
22 | '/OnlinePayments': (context,{arguments}) => GHOnlinePayments(arguments:arguments),
23 | '/GHGoodsList': (context,{arguments}) => GHGoodsList(),
24 | '/GHGoodsDetails': (context,{arguments}) => GHGoodsDetails(arguments:arguments),
25 |
26 | /// 订单确认页
27 | '/GHCheckOutPage': (context,{arguments}) => GHCheckOutPage(arguments:arguments),
28 | /// 订单列表
29 | '/GHOrderListPage': (context) => GHOrderListPage(),
30 | };
31 |
32 | /// 固定写法不需要改动
33 | var onGenerateRoute = (RouteSettings settings) {
34 | // 统一处理
35 | final String name = settings.name;
36 | final Function pageContentBuilder = routes[name];
37 | if (pageContentBuilder != null) {
38 | if (settings.arguments != null) {
39 | final Route route = MaterialPageRoute(
40 | builder: (context) =>
41 | pageContentBuilder(context, arguments: settings.arguments));
42 | return route;
43 | } else {
44 | final Route route =
45 | MaterialPageRoute(builder: (context) => pageContentBuilder(context));
46 | return route;
47 | }
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/lib/services/EventBus.dart:
--------------------------------------------------------------------------------
1 | import 'package:event_bus/event_bus.dart';
2 |
3 | EventBus eventBus = EventBus();
4 |
5 | class ProductContentEvent {
6 | String str;
7 |
8 | ProductContentEvent(String str) {
9 | this.str = str;
10 | }
11 | }
12 |
13 |
14 | class LoginSuccessEvent {
15 | String str;
16 |
17 | LoginSuccessEvent(String str) {
18 | this.str = str;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/lib/services/GHLog.dart:
--------------------------------------------------------------------------------
1 |
2 | void GHLog(Object message, StackTrace current) {
3 | GHCustomTrace programInfo = GHCustomTrace(current);
4 | print("所在文件: ${programInfo.fileName}, 所在行: ${programInfo.lineNumber}, 打印信息: $message");
5 | }
6 |
7 |
8 | class GHCustomTrace {
9 | final StackTrace _trace;
10 |
11 | String fileName;
12 | int lineNumber;
13 | int columnNumber;
14 |
15 | GHCustomTrace(this._trace) {
16 | _parseTrace();
17 | }
18 |
19 | void _parseTrace() {
20 | var traceString = this._trace.toString().split("\n")[0];
21 | var indexOfFileName = traceString.indexOf(RegExp(r'[A-Za-z_]+.dart'));
22 | var fileInfo = traceString.substring(indexOfFileName);
23 | var listOfInfos = fileInfo.split(":");
24 | this.fileName = listOfInfos[0];
25 | this.lineNumber = int.parse(listOfInfos[1]);
26 | var columnStr = listOfInfos[2];
27 | columnStr = columnStr.replaceFirst(")", "");
28 | this.columnNumber = int.parse(columnStr);
29 | }
30 | }
--------------------------------------------------------------------------------
/lib/services/GHToast.dart:
--------------------------------------------------------------------------------
1 | import 'package:fluttertoast/fluttertoast.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class GHToast{
5 |
6 | static Future showTost(String toast) {
7 | Fluttertoast.showToast(
8 | msg: toast,
9 | toastLength: Toast.LENGTH_SHORT,
10 | gravity: ToastGravity.CENTER,
11 | timeInSecForIos: 1,
12 | textColor: Colors.white,
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/services/ScreenAdaper.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_screenutil/flutter_screenutil.dart';
2 |
3 | class ScreenAdaper {
4 | static init(context) {
5 | ScreenUtil.init(context, width: 750, height: 1334);
6 | }
7 |
8 | static height(double value) {
9 | return ScreenUtil().setHeight(value);
10 | }
11 |
12 | static width(double value) {
13 | return ScreenUtil().setWidth(value);
14 | }
15 |
16 | static getScreenHeight() {
17 | return ScreenUtil.screenHeight;
18 | }
19 |
20 | static getScreenWidth() {
21 | return ScreenUtil.screenWidth;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/services/SearchServices.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'Storage.dart';
4 |
5 | class SearchServices {
6 | static setHistoryData(keywords) async {
7 | /*
8 | 1、获取本地存储里面的数据 (searchList)
9 |
10 | 2、判断本地存储是否有数据
11 |
12 | 2.1、如果有数据
13 |
14 | 1、读取本地存储的数据
15 | 2、判断本地存储中有没有当前数据,
16 | 如果有不做操作、
17 | 如果没有当前数据,本地存储的数据和当前数据拼接后重新写入
18 |
19 |
20 | 2.2、如果没有数据
21 |
22 | 直接把当前数据放在数组中写入到本地存储
23 |
24 |
25 | */
26 |
27 | try {
28 | List searchListData = json.decode(await Storage.getString('searchList'));
29 |
30 | print(searchListData);
31 | var hasData = searchListData.any((v) {
32 | return v == keywords;
33 | });
34 | if (!hasData) {
35 | searchListData.add(keywords);
36 | await Storage.setString('searchList', json.encode(searchListData));
37 | }
38 | } catch (e) {
39 | List tempList = new List();
40 | tempList.add(keywords);
41 | await Storage.setString('searchList', json.encode(tempList));
42 | }
43 | }
44 | static getHistoryList() async{
45 | try {
46 | List searchListData = json.decode(await Storage.getString('searchList'));
47 | return searchListData;
48 | } catch (e) {
49 | return [];
50 | }
51 | }
52 |
53 | static clearHistoryList() async{
54 | await Storage.remove('searchList');
55 | }
56 | static removeHistoryData(keywords) async{
57 | List searchListData = json.decode(await Storage.getString('searchList'));
58 | searchListData.remove(keywords);
59 | await Storage.setString('searchList', json.encode(searchListData));
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/lib/services/Storage.dart:
--------------------------------------------------------------------------------
1 | import 'package:shared_preferences/shared_preferences.dart';
2 |
3 | class Storage{
4 |
5 | static Future setString(key,value) async{
6 | SharedPreferences sp=await SharedPreferences.getInstance();
7 | sp.setString(key, value);
8 | }
9 | static Future getString(key) async{
10 | SharedPreferences sp=await SharedPreferences.getInstance();
11 | return sp.getString(key);
12 | }
13 | static Future remove(key) async{
14 | SharedPreferences sp=await SharedPreferences.getInstance();
15 | sp.remove(key);
16 | }
17 | static Future clear() async{
18 | SharedPreferences sp=await SharedPreferences.getInstance();
19 | sp.clear();
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/lib/services/gh_sqflite.dart:
--------------------------------------------------------------------------------
1 | import 'package:sqflite/sqflite.dart';
2 | import 'package:path/path.dart';
3 | import 'dart:io';
4 |
5 | String dbPath = "";
6 |
7 | /// 数据库名称
8 | String dbName = "user.db";
9 |
10 | /// 用户表
11 | String userTable = "user";
12 |
13 | /// 用户表SQL
14 | String userTableSQL =
15 | "create table user (id integer primary key, objectId text, username text,mobilePhone text)";
16 |
17 | class GHSqflite {
18 | /// 判断表是否存在
19 | Future isTableExits(String tableName) async {
20 | await getDatabasesPath();
21 | Database db = await openDatabase(dbPath);
22 | var res = await db.rawQuery(
23 | "select * from Sqlite_master where type = 'table' and name = '$tableName'");
24 | return res;
25 | }
26 |
27 | /// 创建数据库
28 | create() async {
29 | dbPath = await createNewDb(dbName);
30 | Database db = await openDatabase(dbPath);
31 | await this.isTableExits("user").then((value) {
32 | if (value.length == 0) {
33 | db.execute(userTableSQL);
34 | }
35 | db.close();
36 | });
37 | }
38 |
39 | /// 打开数据库
40 | open() async {
41 | if (null == dbPath) {
42 | var path = await getDatabasesPath();
43 | dbPath = join(path, dbName);
44 | print('dbPath:' + dbPath);
45 | }
46 | return await openDatabase(dbPath);
47 | }
48 |
49 | /// 创建数据库
50 | Future createNewDb(String dbName) async {
51 | var dbPath = await getDatabasesPath();
52 | String path = join(dbPath, dbName);
53 | if (await new Directory(dirname(path)).exists()) {
54 | print("存在数据库");
55 | } else {
56 | try {
57 | await new Directory(dirname(path)).create(recursive: true);
58 | } catch (e) {
59 | print(e);
60 | }
61 | }
62 | return path;
63 | }
64 |
65 | /// 添加数据
66 | add(String objectId, String username, String mobilePhone) async {
67 | Database db = await open();
68 | String sql =
69 | "insert into user(objectId,username,mobilePhone) values('$objectId', '$username','$mobilePhone')";
70 | await db.transaction((txn) async {
71 | int id = await txn.rawInsert(sql);
72 | print('插入数据成功');
73 | });
74 | await db.close();
75 | }
76 |
77 | /// 查询所有数据
78 | Future query() async {
79 | Database db = await open();
80 | List