├── .editorconfig
├── .gitignore
├── README.md
├── config.xml
├── ionic.config.json
├── package-lock.json
├── package.json
├── resources
├── README.md
├── android
│ ├── icon
│ │ ├── drawable-hdpi-icon.png
│ │ ├── drawable-ldpi-icon.png
│ │ ├── drawable-mdpi-icon.png
│ │ ├── drawable-xhdpi-icon.png
│ │ ├── drawable-xxhdpi-icon.png
│ │ └── drawable-xxxhdpi-icon.png
│ └── splash
│ │ ├── drawable-land-hdpi-screen.png
│ │ ├── drawable-land-ldpi-screen.png
│ │ ├── drawable-land-mdpi-screen.png
│ │ ├── drawable-land-xhdpi-screen.png
│ │ ├── drawable-land-xxhdpi-screen.png
│ │ ├── drawable-land-xxxhdpi-screen.png
│ │ ├── drawable-port-hdpi-screen.png
│ │ ├── drawable-port-ldpi-screen.png
│ │ ├── drawable-port-mdpi-screen.png
│ │ ├── drawable-port-xhdpi-screen.png
│ │ ├── drawable-port-xxhdpi-screen.png
│ │ └── drawable-port-xxxhdpi-screen.png
├── icon.png
├── ios
│ ├── icon
│ │ ├── icon-1024.png
│ │ ├── icon-40.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-50.png
│ │ ├── icon-50@2x.png
│ │ ├── icon-60.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-72.png
│ │ ├── icon-72@2x.png
│ │ ├── icon-76.png
│ │ ├── icon-76@2x.png
│ │ ├── icon-83.5@2x.png
│ │ ├── icon-small.png
│ │ ├── icon-small@2x.png
│ │ ├── icon-small@3x.png
│ │ ├── icon.png
│ │ └── icon@2x.png
│ └── splash
│ │ ├── Default-568h@2x~iphone.png
│ │ ├── Default-667h.png
│ │ ├── Default-736h.png
│ │ ├── Default-Landscape-736h.png
│ │ ├── Default-Landscape@2x~ipad.png
│ │ ├── Default-Landscape@~ipadpro.png
│ │ ├── Default-Landscape~ipad.png
│ │ ├── Default-Portrait@2x~ipad.png
│ │ ├── Default-Portrait@~ipadpro.png
│ │ ├── Default-Portrait~ipad.png
│ │ ├── Default@2x~iphone.png
│ │ ├── Default@2x~universal~anyany.png
│ │ └── Default~iphone.png
└── splash.png
├── src
├── app
│ ├── app.component.ts
│ ├── app.html
│ ├── app.module.ts
│ ├── app.scss
│ └── main.ts
├── assets
│ ├── icon
│ │ └── favicon.ico
│ └── imgs
│ │ └── logo.png
├── core
│ ├── core.module.ts
│ ├── db.ts
│ ├── error.ts
│ ├── http.ts
│ └── utils.ts
├── index.html
├── manifest.json
├── pages
│ ├── about
│ │ ├── about.html
│ │ ├── about.scss
│ │ └── about.ts
│ ├── contact
│ │ ├── contact.html
│ │ ├── contact.scss
│ │ ├── contact.ts
│ │ └── mock-data.ts
│ ├── echarts
│ │ ├── echarts.html
│ │ ├── echarts.module.ts
│ │ ├── echarts.scss
│ │ └── echarts.ts
│ ├── home
│ │ ├── home.html
│ │ ├── home.scss
│ │ └── home.ts
│ ├── login
│ │ ├── login.html
│ │ ├── login.scss
│ │ └── login.ts
│ ├── tabs
│ │ ├── tabs.html
│ │ └── tabs.ts
│ └── user-info
│ │ ├── user-info.html
│ │ ├── user-info.module.ts
│ │ ├── user-info.scss
│ │ └── user-info.ts
├── service-worker.js
└── theme
│ └── variables.scss
├── tsconfig.json
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 |
10 | # We recommend you to keep these unchanged
11 | end_of_line = lf
12 | charset = utf-8
13 | trim_trailing_whitespace = true
14 | insert_final_newline = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | *.log
7 | *.tmp
8 | *.tmp.*
9 | log.txt
10 | *.sublime-project
11 | *.sublime-workspace
12 | .vscode/
13 | npm-debug.log*
14 |
15 | .idea/
16 | .sourcemaps/
17 | .sass-cache/
18 | .tmp/
19 | .versions/
20 | coverage/
21 | dist/
22 | node_modules/
23 | tmp/
24 | temp/
25 | hooks/
26 | platforms/
27 | plugins/
28 | plugins/android.json
29 | plugins/ios.json
30 | www/
31 | $RECYCLE.BIN/
32 |
33 | .DS_Store
34 | Thumbs.db
35 | UserInterfaceState.xcuserstate
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 介绍
2 | 此项目是一个简单的ionic App,包含以下几点常用功能:
3 |
4 | 1. 屏幕适配
5 | 2. 常用工具封装
6 | 3. Tab图标替换
7 | 4. 字体库替换
8 | 5. Echarts使用
9 | 6. 自定义通讯录
10 | 7. 数据库
11 | 8. 版本信息
12 |
13 | 我会抽空将此APP完善,添加更多的功能,供大家参考,假如有任何的建议或者意见,请提issue,我会及时回复。
14 |
15 | 我的博客也放置在 `GitHub` 仓库 [Blog](https://github.com/JerryMissTom/Blog/issues) 上,里面有我在 `ionic` 实践过程中的踩坑心得,可以参考下。
16 |
17 | ## 开发环境
18 | 1. ionic V3.10.3
19 | 2. cordova V7.0.1
20 | 3. npm V5.4.1
21 | 4. node V8.1.4
22 |
23 | ## 用法
24 |
25 | #### 初始化项目
26 | 顺序执行以下操作:
27 | ```
28 | //空白文件夹下
29 | git clone https://github.com/JerryMissTom/HW-basic.git
30 |
31 | // 项目根目录下:
32 | npm install
33 |
34 | //安装 App Version 插件
35 | ionic cordova plugin add cordova-plugin-app-version
36 |
37 | //安装 Keyboard 插件
38 | ionic cordova plugin add ionic-plugin-keyboard
39 |
40 | //安装 Sqlite 插件
41 | ionic cordova plugin add cordova-sqlite-storage
42 | ```
43 | #### 打包
44 | Android环境
45 | 确保已经安装了相应Android SDK,建议通过Android Studio来安装,简单方便
46 | ```
47 | // 添加android平台
48 | ionic cordova platform add android
49 |
50 | // 打包
51 | ionic cordova build android --prod
52 | ```
53 | 然后使用 `Android Studio` 打开项目下 `platform/android` 文件夹进行签名打包
54 |
55 |
56 | iOS 环境
57 | 确保安装Xcode,并配置好相关SDK
58 | ```
59 | // 添加iOS平台
60 | ionic cordova platform add ios
61 |
62 | // 打包
63 | ionic cordova build ios --prod
64 | ```
65 | 然后使用 `Xcode` 打开项目下 `platform/ios` 文件夹进行签名打包
66 |
67 | #### 调试
68 | 浏览器调试,只适合调试界面和接口,无法调试原生功能,代码修改并保存后会自动构建,可以看到结果。
69 | ```
70 | //根目录下执行
71 | ionic serve
72 | ```
73 |
74 | 安卓调试,适合调试原生功能,如数据库,照相机等
75 |
76 | 打开手机的开发者选项和USB调试,手机通过USB与电脑连接,执行`adb devices`可以查看手机是否与电脑连接成功,然后项目根目录下执行 `ionic cordova run android` 将APP安装至手机并运行,打开Chrome浏览器,在地址栏输入 `chrome://inspect`(第一次打开需要翻墙),可以看到需要调试的APP,点击下方的`inspect`可以看到手机的界面,并且在`console`中查看日志。
77 |
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | HW-basic
4 | 简单基础的ionic App
5 | JerryMissTom
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 |
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "HW-basic",
3 | "app_id": "",
4 | "type": "ionic-angular",
5 | "integrations": {
6 | "cordova": {}
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "HW-basic",
3 | "version": "0.0.1",
4 | "author": "JerryMissTom",
5 | "homepage": "https://github.com/JerryMissTom",
6 | "private": true,
7 | "scripts": {
8 | "clean": "ionic-app-scripts clean",
9 | "build": "ionic-app-scripts build",
10 | "lint": "ionic-app-scripts lint",
11 | "ionic:build": "ionic-app-scripts build",
12 | "ionic:serve": "ionic-app-scripts serve"
13 | },
14 | "dependencies": {
15 | "@angular/common": "5.0.0",
16 | "@angular/compiler": "5.0.0",
17 | "@angular/compiler-cli": "5.0.0",
18 | "@angular/core": "5.0.0",
19 | "@angular/forms": "5.0.0",
20 | "@angular/http": "5.0.0",
21 | "@angular/platform-browser": "5.0.0",
22 | "@angular/platform-browser-dynamic": "5.0.0",
23 | "@ionic-native/app-version": "^4.5.2",
24 | "@ionic-native/core": "4.3.2",
25 | "@ionic-native/keyboard": "^4.5.2",
26 | "@ionic-native/splash-screen": "4.3.2",
27 | "@ionic-native/sqlite": "^4.5.2",
28 | "@ionic-native/status-bar": "4.3.2",
29 | "@ionic/storage": "2.1.3",
30 | "cordova-plugin-app-version": "^0.1.9",
31 | "cordova-sqlite-storage": "^2.2.0",
32 | "echarts": "^4.0.2",
33 | "ionic-angular": "3.9.2",
34 | "ionic-plugin-keyboard": "^2.2.1",
35 | "ionicons": "3.0.0",
36 | "rxjs": "5.5.2",
37 | "sw-toolbox": "3.6.0",
38 | "ws": "^3.3.2",
39 | "zone.js": "0.8.18"
40 | },
41 | "devDependencies": {
42 | "@ionic/app-scripts": "3.1.0",
43 | "typescript": "2.4.2"
44 | },
45 | "description": "简单基础的ionic App",
46 | "cordova": {
47 | "plugins": {
48 | "ionic-plugin-keyboard": {},
49 | "cordova-sqlite-storage": {},
50 | "cordova-plugin-app-version": {}
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/resources/README.md:
--------------------------------------------------------------------------------
1 | These are Cordova resources. You can replace icon.png and splash.png and run
2 | `ionic cordova resources` to generate custom icons and splash screens for your
3 | app. See `ionic cordova resources --help` for details.
4 |
5 | Cordova reference documentation:
6 |
7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
9 |
--------------------------------------------------------------------------------
/resources/android/icon/drawable-hdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-hdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-ldpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-ldpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-mdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-mdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-xhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-xxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/icon/drawable-xxxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-land-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/android/splash/drawable-port-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/icon.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-1024.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-40.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-40@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-40@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-50.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-50@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-60.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-60@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-60@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-72.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-72@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-76.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-76@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-83.5@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-small.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-small@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon-small@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/icon/icon@2x.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Landscape@~ipadpro.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Portrait@~ipadpro.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~universal~anyany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default@2x~universal~anyany.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/resources/splash.png
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Platform } from 'ionic-angular';
3 | import { StatusBar } from '@ionic-native/status-bar';
4 | import { SplashScreen } from '@ionic-native/splash-screen';
5 |
6 | import { TabsPage } from '../pages/tabs/tabs';
7 | import { DBService } from '../core/db';
8 | import { LoginComponent } from '../pages/login/login';
9 |
10 | @Component({
11 | templateUrl: 'app.html'
12 | })
13 | export class MyApp {
14 | rootPage: any = LoginComponent;
15 |
16 | constructor(platform: Platform,
17 | statusBar: StatusBar,
18 | splashScreen: SplashScreen,
19 | private db: DBService) {
20 | platform.ready().then(() => {
21 | // Okay, so the platform is ready and our plugins are available.
22 | // Here you can do any higher level native things you might need.
23 | statusBar.styleDefault();
24 | splashScreen.hide();
25 |
26 | // 初始化数据库
27 | this.db.initDB();
28 |
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ErrorHandler } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
4 |
5 | import { StatusBar } from '@ionic-native/status-bar';
6 | import { SplashScreen } from '@ionic-native/splash-screen';
7 | import { AppVersion } from '@ionic-native/app-version';
8 | import { SQLite } from "@ionic-native/sqlite";
9 | import { Keyboard } from '@ionic-native/keyboard';
10 |
11 | import { MyApp } from './app.component';
12 | import { AboutPage } from '../pages/about/about';
13 | import { ContactPage } from '../pages/contact/contact';
14 | import { HomePage } from '../pages/home/home';
15 | import { TabsPage } from '../pages/tabs/tabs';
16 | import { CoreModule } from '../core/core.module';
17 | import { LoginComponent } from '../pages/login/login';
18 |
19 | @NgModule({
20 | declarations: [
21 | MyApp,
22 | LoginComponent,
23 | AboutPage,
24 | ContactPage,
25 | HomePage,
26 | TabsPage
27 | ],
28 | imports: [
29 | CoreModule,
30 | BrowserModule,
31 | // 更多的配置参见:https://ionicframework.com/docs/api/config/Config/
32 | IonicModule.forRoot(MyApp, {
33 | backButtonText: "",
34 | tabsHideOnSubPages: true,
35 | mode: 'ios'
36 | })
37 | ],
38 | bootstrap: [IonicApp],
39 | entryComponents: [
40 | MyApp,
41 | LoginComponent,
42 | AboutPage,
43 | ContactPage,
44 | HomePage,
45 | TabsPage
46 | ],
47 | providers: [
48 | StatusBar,
49 | SplashScreen,
50 | AppVersion,
51 | Keyboard,
52 | SQLite,
53 | { provide: ErrorHandler, useClass: IonicErrorHandler }
54 | ]
55 | })
56 | export class AppModule { }
57 |
--------------------------------------------------------------------------------
/src/app/app.scss:
--------------------------------------------------------------------------------
1 | // http://ionicframework.com/docs/theming/
2 | // App Global Sass
3 | // --------------------------------------------------
4 | // Put style rules here that you want to apply globally. These
5 | // styles are for the entire app and not just one component.
6 | // Additionally, this file can be also used as an entry point
7 | // to import other Sass files to be included in the output CSS.
8 | //
9 | // Shared Sass variables, which can be used to adjust Ionic's
10 | // default Sass variables, belong in "theme/variables.scss".
11 | //
12 | // To declare rules for a specific mode, create a child rule
13 | // for the .md, .ios, or .wp mode classes. The mode class is
14 | // automatically applied to the
element in the app.
15 | // 页面适配
16 | // 根元素大小使用 vw 单位
17 | $vm_fontsize: 36; // 是$vm_design 值得十分之一
18 | $vm_design: 360; // 根据需要替换成设计稿的值,比如设计稿给你的宽度是360px,
19 | html {
20 | font-size: ($vm_fontsize / $vm_design) * 100vw; // 同时,通过Media Queries 限制根元素最大最小值
21 | @media screen and (max-width: 320px) {
22 | font-size: 32px;
23 | }
24 | @media screen and (min-width: 540px) {
25 | font-size: 54px;
26 | }
27 | }
28 |
29 | // body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
30 | body {
31 | max-width: 540px;
32 | min-width: 320px;
33 | }
34 |
35 | html {
36 | width: 100%;
37 | height: 100%;
38 | margin: 0;
39 | padding: 0;
40 | -webkit-text-size-adjust: 100%;
41 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
42 | background: transparent;
43 | box-sizing: border-box;
44 | }
45 |
46 | body {
47 | width: 100%;
48 | height: 100%;
49 | -webkit-overflow-scrolling: touch;
50 | }
51 |
52 | body,
53 | div,
54 | dl,
55 | dt,
56 | dd,
57 | ul,
58 | ol,
59 | li,
60 | h1,
61 | h2,
62 | h3,
63 | h4,
64 | h5,
65 | h6,
66 | pre,
67 | code,
68 | form,
69 | fieldset,
70 | legend,
71 | input,
72 | textarea,
73 | p,
74 | blockquote,
75 | th,
76 | td,
77 | hr,
78 | button,
79 | article,
80 | aside,
81 | details,
82 | figcaption,
83 | figure,
84 | footer,
85 | header,
86 | hgroup,
87 | menu,
88 | nav,
89 | section,
90 | sumary {
91 | margin: 0;
92 | padding: 0;
93 | }
94 |
95 | //清除输入框内阴影
96 | input,
97 | select,
98 | textarea {
99 | border: 0;
100 | -webkit-appearance: none;
101 | appearance: none;
102 | }
103 |
104 | ol,
105 | ul {
106 | list-style: none;
107 | }
108 |
109 | //禁止选中文本内容
110 | *:not(input, select, textArea) {
111 | -webkit-user-select: none;
112 | }
113 |
114 | //禁用长按页面时的弹出菜单(iOS下有效) ,img和a标签都要加
115 | img,
116 | a {
117 | -webkit-touch-callout: none;
118 | }
119 |
120 | a,
121 | a:active,
122 | a:hover {
123 | text-decoration: none;
124 | }
125 |
126 | //去掉点击链接和文本框对象时默认的灰色半透明覆盖层(iOS)或者虚框(Android)
127 | a,
128 | button,
129 | input,
130 | textarea {
131 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
132 | }
133 |
134 | .back-button-icon-md,
135 | .back-button-icon-ios {
136 | font-size: rem(28);
137 | }
138 |
139 | .back-button-ios {
140 | min-height: rem(32);
141 | }
142 |
143 | //icon 定位在页面的右侧,添加在ion-icon 标签上
144 | .icon-right {
145 | position: absolute;
146 | right: 10%;
147 | top: 50%;
148 | transform: translateY(-50%);
149 | }
150 |
151 | //item固有高度
152 | .item-block {
153 | min-height: rem(44);
154 | }
155 |
156 | //checkbox框样式
157 | .checkbox-ios .checkbox-icon {
158 | border-radius: 4px;
159 | }
160 |
161 | .item.item-ios .checkbox-ios {
162 | margin: rem(15) 0;
163 | margin-right: rem(9);
164 | }
165 |
166 | //菜单图标
167 | .bar-button-menutoggle-ios ion-icon {
168 | font-size: rem(24);
169 | }
170 |
171 | //icon
172 | .item>ion-icon,
173 | .item-inner>ion-icon {
174 | font-size: rem(28);
175 | min-height: rem(28);
176 | }
177 |
178 | // 时间选择器配置
179 | .picker-ios .picker-opt {
180 | height: rem(45);
181 | }
182 |
183 | .center {
184 | display: -webkit-box;
185 | display: -moz-box;
186 | display: -ms-flexbox;
187 | display: -webkit-flex;
188 | display: flex;
189 | align-items: center;
190 | justify-content: center;
191 | -webkit-box-pack: center;
192 | -webkit-justify-content: center;
193 | }
194 |
195 | .space-between {
196 | display: -webkit-box;
197 | display: -moz-box;
198 | display: -ms-flexbox;
199 | display: -webkit-flex;
200 | display: flex;
201 | align-items: center;
202 | justify-content: space-between;
203 | }
204 |
205 | .space-around {
206 | display: -webkit-box;
207 | display: -moz-box;
208 | display: -ms-flexbox;
209 | display: -webkit-flex;
210 | display: flex;
211 | align-items: center;
212 | justify-content: space-around;
213 | }
214 |
215 | .toast-middle{
216 | width: 50px;
217 | }
218 | .toast-ios .toast-message{
219 | text-align: center;
220 | }
--------------------------------------------------------------------------------
/src/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/src/assets/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryMissTom/HW-basic/d81dd8db499fad762005f88543cb828d5655108c/src/assets/imgs/logo.png
--------------------------------------------------------------------------------
/src/core/core.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { HttpModule } from '@angular/http';
3 | import { DBService } from './db';
4 | import { Util } from './utils';
5 | import { ErrorService } from './error';
6 | import { HttpService } from './http';
7 |
8 | @NgModule({
9 | imports: [
10 | HttpModule
11 | ],
12 | providers: [
13 | DBService,
14 | Util,
15 | ErrorService,
16 | HttpService
17 | ]
18 | })
19 |
20 | export class CoreModule { }
--------------------------------------------------------------------------------
/src/core/db.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Injectable } from '@angular/core';
3 | import { SQLite, SQLiteObject } from '@ionic-native/sqlite'
4 |
5 | @Injectable()
6 | export class DBService {
7 |
8 | myDataBase: SQLiteObject;
9 |
10 | constructor(
11 | private sqlite: SQLite
12 | ) { }
13 |
14 |
15 | //初始化或打开数据库,建立表
16 | initDB() {
17 | this.sqlite.create({
18 | name: 'basic.db',
19 | location: 'default'
20 | }).then((database: SQLiteObject) => {
21 | // 创建客户信息表
22 | let sqlStr = ' create table if not exists contact ' +
23 | '(' +
24 | 'id INTEGER PRIMARY KEY autoincrement, ' +
25 | 'name text, ' + // 姓名
26 | 'phone text, ' + //号码
27 | 'index text, ' + // 检索字母,即 a-z,#
28 | ')';
29 |
30 | database.executeSql(sqlStr, {}).then(() => {
31 | console.log('创建表成功');
32 |
33 | }).catch(() => {
34 | console.log('创建表失败');
35 | });
36 |
37 | this.myDataBase = database;
38 | }).catch(() => {
39 | console.log('打开数据库失败');
40 | });
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/core/error.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { ToastController, NavController } from 'ionic-angular';
3 |
4 | @Injectable()
5 | export class ErrorService {
6 |
7 | constructor(
8 | private toastCtrl: ToastController
9 | ) {
10 | }
11 |
12 | public handleError(errorCode) {
13 | let errorMessage = this.getErrorMessage(errorCode);
14 | this.toastCtrl.create({
15 | message: errorMessage,
16 | duration: 1300,
17 | position: 'bottom'
18 | }).present();
19 | }
20 |
21 | private getErrorMessage(errorCode: number): string {
22 |
23 | let errorMessage: string;
24 | switch (errorCode) {
25 | case 500:
26 | errorMessage = '服务器开小差了';
27 | break;
28 | case 404:
29 | errorMessage = '未找到该资源';
30 | break;
31 | default:
32 | errorMessage = '服务器错误';
33 |
34 | }
35 | return errorMessage;
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/src/core/http.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Headers, Http, RequestOptions, Response } from '@angular/http';
3 |
4 | import { Observable } from 'rxjs/Observable';
5 | import 'rxjs/add/operator/map';
6 | import 'rxjs/add/operator/catch';
7 | import 'rxjs/add/observable/throw';
8 | import 'rxjs/add/operator/timeout';
9 |
10 | @Injectable()
11 | export class HttpService {
12 |
13 | private environmentUrl = '';
14 |
15 | constructor(
16 | private http: Http
17 | ) { }
18 |
19 | // post 方法
20 | public post(requestUrl, requestJson) {
21 | return this.httpRequestPost(requestUrl, requestJson)
22 | .map(response => response.json())
23 | .catch(this.handlerError)
24 | }
25 |
26 | // get 方法
27 | public get(param: string) {
28 | const header: any = new Headers({ 'Content-type': 'application/json' });
29 | const options: any = new RequestOptions({ headers: header });
30 | return this.http.get(this.environmentUrl + param, options)
31 | .timeout(10000).map(response => response.json()).catch(this.handlerError);
32 | }
33 |
34 | private httpRequestPost(requestUrl, requestJson) {
35 | const body: string = JSON.stringify(requestJson);
36 | const header: any = new Headers({ 'Content-type': 'application/json' });
37 | const options: any = new RequestOptions({ headers: header });
38 | return this.http.post(this.environmentUrl + requestUrl, body, options)
39 | .timeout(10000)
40 | }
41 |
42 | private handlerError(error: Response | any) {
43 | const body = error.json() || {};
44 | return Observable.throw(body);
45 | }
46 | }
--------------------------------------------------------------------------------
/src/core/utils.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@angular/core";
2 | import { Platform } from 'ionic-angular';
3 |
4 | @Injectable()
5 | export class Util {
6 |
7 | constructor(private platform: Platform) {
8 | }
9 |
10 | // 获取平台类型
11 | getNavigator(): string {
12 |
13 | if (this.platform.is('android')) {
14 | return 'android';
15 | }
16 |
17 | if (this.platform.is('ios')) {
18 | return 'ios';
19 | }
20 |
21 | return 'android';
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HW-basic
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "HW-basic",
3 | "short_name": "HW-basic",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/imgs/logo.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#4e8ef7",
12 | "theme_color": "#4e8ef7"
13 | }
--------------------------------------------------------------------------------
/src/pages/about/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | About
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 | 版本号
16 | {{version}}
17 |
18 |
19 | 用户信息
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/pages/about/about.scss:
--------------------------------------------------------------------------------
1 | page-about {
2 | .user-header {
3 | width: 100%;
4 | height: rem(100);
5 | flex-direction: column;
6 | margin: rem(20) 0;
7 | .avatar {
8 | width: rem(80);
9 | height: rem(80);
10 | background: #488aff;
11 | border-radius: 100%;
12 | }
13 | }
14 | .first-item {
15 | border-top: #ececec solid rem(1);
16 | }
17 | .item {
18 | width: 100%;
19 | height: rem(50);
20 | padding: 0 rem(10);
21 | border-bottom: #ececec solid rem(1);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/about/about.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 | import { AppVersion } from '@ionic-native/app-version';
4 |
5 | @Component({
6 | selector: 'page-about',
7 | templateUrl: 'about.html'
8 | })
9 | export class AboutPage {
10 |
11 | private version;
12 | constructor(
13 | public navCtrl: NavController,
14 | private appVersion: AppVersion
15 | ) {
16 | this.version = '';
17 | }
18 |
19 | ionViewDidLoad() {
20 | this.appVersion.getVersionNumber().then(num => {
21 | this.version = this.version + num;
22 | });
23 | }
24 |
25 | private toUserPage() {
26 | this.navCtrl.push('UserInfoPage');
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/pages/contact/contact.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Contact
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 | {{item.index}}
24 |
25 |
26 | {{item.firstLetter}}
27 | {{item.name}}
28 | {{item.phone}}
29 |
30 |
31 |
32 |
33 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/pages/contact/contact.scss:
--------------------------------------------------------------------------------
1 | page-contact {
2 | .search-field {
3 | width: 100%;
4 | height: rem(52);
5 | align-items: center;
6 | flex-direction: column;
7 | padding: rem(6) rem(0);
8 | background: #FFFFFF;
9 | .search {
10 | width: 90%;
11 | height: rem(40);
12 | padding: rem(5) rem(10);
13 | border: rgb(216, 213, 213) solid rem(1);
14 | border-radius: rem(40);
15 | .keyword {
16 | width: 100%;
17 | height: rem(39);
18 | padding: rem(0) rem(6);
19 | background: none;
20 | font-size: rem(15);
21 | }
22 | }
23 | }
24 | .content {
25 | width: 100%;
26 | display: flex;
27 | flex-direction: row;
28 | }
29 | .left {
30 | width: 95%;
31 | .contact-list {
32 | width: 100%;
33 | .index-item {
34 | width: 100%;
35 | height: rem(20);
36 | background: #ececec;
37 | color: black;
38 | font-size: rem(12);
39 | line-height: rem(20);
40 | padding: rem(0) rem(10);
41 | }
42 | .contact-item {
43 | height: rem(60);
44 | width: 100%;
45 | border-bottom: #ececec solid rem(1);
46 | padding: rem(0) rem(10);
47 | align-items: center;
48 | .first-letter {
49 | width: rem(45);
50 | height: rem(45);
51 | border-radius: 100%;
52 | background: #D8D8D8;
53 | text-align: center;
54 | line-height: rem(45);
55 | color: black;
56 | font-family: HoneywellSans-Medium;
57 | font-size: rem(18);
58 | }
59 | .contact-name {
60 | height: rem(45);
61 | line-height: rem(45);
62 | font-size: rem(16);
63 | text-align: left;
64 | width: 40%;
65 | display: -webkit-box;
66 | -webkit-box-orient: vertical;
67 | -webkit-line-clamp: 1;
68 | overflow: hidden;
69 | color: #303030;
70 | letter-spacing: -0.39px;
71 | font-family: HoneywellSans-Medium;
72 | }
73 | .contact-phone {
74 | height: rem(45);
75 | line-height: rem(45);
76 | font-family: HoneywellSans-Medium;
77 | font-size: rem(16);
78 | text-align: right;
79 | width: 40%;
80 | display: -webkit-box;
81 | -webkit-box-orient: vertical;
82 | -webkit-line-clamp: 2;
83 | overflow: hidden;
84 | letter-spacing: -0.39px;
85 | }
86 | }
87 | }
88 | .ios-list-header {
89 | position: sticky;
90 | z-index: 1;
91 | top: 0;
92 | }
93 | .android-list-header {
94 | position: fixed;
95 | z-index: 1;
96 | top: rem(38);
97 | }
98 | .android-list-top {
99 | margin-top: rem(52) !important;
100 | }
101 | .ios-list-bottom {
102 | padding-bottom: rem(34);
103 | }
104 | }
105 | .nav {
106 | width: 5%;
107 | font-size: rem(14);
108 | ul {
109 | width: 100%;
110 | height: 100%;
111 | appearance: none;
112 | padding: 0;
113 | }
114 | li {
115 | width: 100%;
116 | appearance: none;
117 | list-style-type: none;
118 | color: #488aff;
119 | text-align: center;
120 | }
121 | }
122 | .android-nav {
123 | position: fixed;
124 | z-index: 1;
125 | right: 0;
126 | top: rem(70);
127 | height: 85%;
128 | }
129 | .ios-nav {
130 | position: sticky;
131 | z-index: 1;
132 | top: rem(30);
133 | right: 0;
134 | height: 85%;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/pages/contact/contact.ts:
--------------------------------------------------------------------------------
1 | import { Component, ElementRef, ViewChild } from '@angular/core';
2 | import { NavController, LoadingController, Events, Content, ToastController } from 'ionic-angular';
3 | import { Subject } from 'rxjs/Subject';
4 | import 'rxjs/add/operator/debounceTime';
5 | import { Observable } from 'rxjs/Observable';
6 | import { Observer } from 'rxjs/Observer';
7 | import { Subscription } from 'rxjs/Subscription';
8 | import { Keyboard } from '@ionic-native/keyboard';
9 | import { Util } from '../../core/utils';
10 | import { DBService } from '../../core/db';
11 | import { contacts, mockContacts } from './mock-data';
12 |
13 | @Component({
14 | selector: 'page-contact',
15 | templateUrl: 'contact.html'
16 | })
17 | export class ContactPage {
18 |
19 | @ViewChild(Content) content: Content;
20 | private version: string;
21 | private searchWord: string;
22 | private textEmitter: Subject = new Subject();
23 | private eventBus: Observable;
24 | private observer: Observer;
25 | private hideSubscription: Subscription;
26 | private showSubscription: Subscription;
27 | private loading: any;
28 | private contacts;
29 | private letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#'];
30 |
31 |
32 | constructor(
33 | private keyboard: Keyboard,
34 | private event: Events,
35 | private navCtrl: NavController,
36 | private loadingCtrl: LoadingController,
37 | private elementRef: ElementRef,
38 | private util: Util,
39 | private db: DBService,
40 | private toastCtrl: ToastController
41 | ) {
42 | this.version = this.util.getNavigator();
43 | this.searchWord = '';
44 | this.loading = null;
45 | // 真机上调试时将其注释掉
46 | this.contacts = contacts;
47 | // 真机上调试,把下面的注释去掉
48 | // this.initData();
49 | // this.getDataFromDB();
50 | this.eventBus = new Observable(observer =>
51 | this.observer = observer).debounceTime(500);
52 | this.eventBus.subscribe(text => {
53 | if (text) {
54 | this.getDataFromDB(text);
55 | }
56 | });
57 | }
58 |
59 | private initData() {
60 | let sqls = [];
61 | for (let item of mockContacts) {
62 | let childItem = [];
63 | let firstStr = 'replace into contact' +
64 | '(name,' +
65 | 'phone,' +
66 | 'index) ' +
67 | 'values (?,?,?)';
68 | childItem.push(firstStr);
69 | let second = [
70 | item.name, item.phone, item.index,
71 | ];
72 | childItem.push(second);
73 | sqls.push(childItem);
74 | }
75 |
76 | return this.db.myDataBase.sqlBatch(sqls).then(() => {
77 | console.log('批量插入成功');
78 | }).catch(() => {
79 | console.log('批量插入失败');
80 | });
81 | }
82 |
83 | ionViewDidEnter() {
84 | // 注册监听输入法的打开和关闭,然后发射此事件,在Tab.st中执行Tab的打开和关闭
85 | this.hideSubscription = this.keyboard.onKeyboardShow().subscribe(() => this.event.publish('hideTabs'));
86 | this.showSubscription = this.keyboard.onKeyboardHide().subscribe(() => this.event.publish('showTabs'));
87 | }
88 |
89 | private scrollTo(letter) {
90 |
91 | this.toastCtrl.create({
92 | message: letter,
93 | duration: 1000,
94 | position: 'middle'
95 | }).present();
96 |
97 | if (letter === '#') {
98 | letter = '\\#';
99 | }
100 | //获取第一个标签的位置
101 | let topLocation = 0;
102 | for (let item in this.letters) {
103 | let itemDom = this.elementRef.nativeElement.querySelector('div#' + this.letters[item]);
104 | if (itemDom) {
105 | topLocation = itemDom.getBoundingClientRect().top;
106 | break;
107 | }
108 | }
109 |
110 | let ele = this.elementRef.nativeElement.querySelector('div#' + letter);
111 | if (ele) {
112 | let s = ele.getBoundingClientRect();
113 | this.content.scrollTo(0, s.top - topLocation, 300); // 这个是重点,Y轴移动相对第一个标签的位置
114 | }
115 | }
116 |
117 | private getDataFromDB(text?: string) {
118 |
119 | if (text) {
120 | let sql = "select * from contact where name like '%" + text + "%'" + " or phone like '%" + text + "%'" + " order by index";
121 | console.log(sql);
122 | this.db.myDataBase.executeSql(sql, {}).then(data => {
123 | console.log('查询' + text + '数据成功');
124 | this.contacts = this.setContracts(data);
125 | }).catch(erroe => {
126 | console.log('查询' + text + '数据失败');
127 | });
128 | } else {
129 | let sql = "select * from contact order by index";
130 | console.log(sql);
131 | this.db.myDataBase.executeSql(sql, {}).then(data => {
132 | console.log('获取所有数据成功');
133 | this.contacts = this.setContracts(data);
134 | }).catch(erroe => {
135 | console.log('获取所有数据失败');
136 | });
137 | }
138 | }
139 |
140 | private onInput(event) {
141 | this.observer.next(event.target.value.trim());
142 | }
143 |
144 | private onClear(event) {
145 | this.keyboard.close();
146 | this.searchWord = '';
147 | this.presentLoading();
148 | this.getDataFromDB();
149 | this.dismissLoading();
150 | }
151 |
152 | private setContracts(data) {
153 |
154 | const length = data.rows.length;
155 | let showList = []; // 最后的数组
156 | let specialList = []; // 属于#的客户
157 | let rows = data.rows;
158 |
159 | for (let i = 0; i < length; i++) {
160 |
161 | //把属于特殊字符的先提取出来
162 | if (rows.item(i).index.trim() === '#') {
163 | let specialItem = {
164 | name: rows.item(i).name,
165 | phone: rows.item(i).phone,
166 | type: 1, //1 表示是数据
167 | firstLetter: rows.item(i).name.charAt(0),
168 | index: rows.item(i).index
169 | }
170 | specialList.push(specialItem);
171 | continue;
172 | }
173 |
174 | // 前后两个数据的Index不同时,在中间插上索引
175 | if (i === 0 || rows.item(i).index.trim() !== rows.item(i - 1).index.trim()) {
176 | let item = {
177 | type: 0, //0 表示是索引
178 | index: rows.item(i).index.toUpperCase()
179 | }
180 | showList.push(item);
181 | }
182 |
183 | let dataItem = {
184 | name: rows.item(i).name,
185 | phone: rows.item(i).phone,
186 | type: 1, //1 表示是数据
187 | firstLetter: rows.item(i).name.charAt(0),
188 | index: rows.item(i).index
189 | }
190 | showList.push(dataItem);
191 | }
192 |
193 | //把属于#的加上索引,并放置在数组最后
194 | if (specialList.length > 0) {
195 | let item = {
196 | type: 0, //0 表示是索引
197 | index: '#'
198 | }
199 | showList.push(item);
200 | return showList.concat(specialList);
201 | } else {
202 | return showList;
203 | }
204 | }
205 |
206 | private presentLoading() {
207 | if (!this.loading) {
208 | this.loading = this.loadingCtrl.create({
209 | content: '请稍候'
210 | });
211 | this.loading.present();
212 | }
213 | }
214 |
215 | private dismissLoading() {
216 | if (this.loading) {
217 | this.loading.dismiss();
218 | this.loading = null;
219 | }
220 | }
221 |
222 | ionViewWillLeave() {
223 | // 解除监听事件
224 | this.keyboard.close();
225 | if (this.hideSubscription) {
226 | this.hideSubscription.unsubscribe();
227 | this.hideSubscription = null;
228 | }
229 | if (this.showSubscription) {
230 | this.showSubscription.unsubscribe();
231 | this.showSubscription = null;
232 | }
233 | this.dismissLoading();
234 | }
235 |
236 | }
237 |
--------------------------------------------------------------------------------
/src/pages/contact/mock-data.ts:
--------------------------------------------------------------------------------
1 | export const contacts = [
2 | {
3 | type: 0,
4 | index: 'B'
5 | },
6 | {
7 | type: 1,
8 | index: 'A',
9 | firstLetter: '好',
10 | name: '公司',
11 | phone: '1236777'
12 | },
13 | {
14 | type: 1,
15 | index: 'A',
16 | firstLetter: '好',
17 | name: '公司',
18 | phone: '1236777'
19 | },
20 | {
21 | type: 1,
22 | index: 'A',
23 | firstLetter: '好',
24 | name: '公司',
25 | phone: '1236777'
26 | },
27 | {
28 | type: 1,
29 | index: 'A',
30 | firstLetter: '好',
31 | name: '公司',
32 | phone: '1236777'
33 | },
34 | {
35 | type: 0,
36 | index: 'C'
37 | },
38 | {
39 | type: 1,
40 | index: 'A',
41 | firstLetter: '好',
42 | name: '公司',
43 | phone: '1236777'
44 | },
45 | {
46 | type: 1,
47 | index: 'A',
48 | firstLetter: '好',
49 | name: '公司',
50 | phone: '1236777'
51 | },
52 | {
53 | type: 1,
54 | index: 'A',
55 | firstLetter: '好',
56 | name: '公司',
57 | phone: '1236777'
58 | },
59 | {
60 | type: 1,
61 | index: 'A',
62 | firstLetter: '好',
63 | name: '公司',
64 | phone: '1236777'
65 | },
66 | {
67 | type: 0,
68 | index: 'D'
69 | },
70 | {
71 | type: 1,
72 | index: 'A',
73 | firstLetter: '好',
74 | name: '公司',
75 | phone: '1236777'
76 | },
77 | {
78 | type: 1,
79 | index: 'A',
80 | firstLetter: '好',
81 | name: '公司',
82 | phone: '1236777'
83 | },
84 | {
85 | type: 1,
86 | index: 'A',
87 | firstLetter: '好',
88 | name: '公司',
89 | phone: '1236777'
90 | },
91 | {
92 | type: 1,
93 | index: 'A',
94 | firstLetter: '好',
95 | name: '公司',
96 | phone: '1236777'
97 | },
98 | {
99 | type: 0,
100 | index: 'E'
101 | },
102 | {
103 | type: 1,
104 | index: 'A',
105 | firstLetter: '好',
106 | name: '公司',
107 | phone: '1236777'
108 | },
109 | {
110 | type: 1,
111 | index: 'A',
112 | firstLetter: '好',
113 | name: '公司',
114 | phone: '1236777'
115 | },
116 | {
117 | type: 1,
118 | index: 'A',
119 | firstLetter: '好',
120 | name: '公司',
121 | phone: '1236777'
122 | },
123 | {
124 | type: 1,
125 | index: 'A',
126 | firstLetter: '好',
127 | name: '公司',
128 | phone: '1236777'
129 | },
130 | {
131 | type: 0,
132 | index: '#'
133 | },
134 | {
135 | type: 1,
136 | index: 'A',
137 | firstLetter: '好',
138 | name: '公司',
139 | phone: '1236777'
140 | },
141 | {
142 | type: 1,
143 | index: 'A',
144 | firstLetter: '好',
145 | name: '公司',
146 | phone: '1236777'
147 | },
148 | {
149 | type: 1,
150 | index: 'A',
151 | firstLetter: '好',
152 | name: '公司',
153 | phone: '1236777'
154 | },
155 | {
156 | type: 1,
157 | index: 'A',
158 | firstLetter: '好',
159 | name: '公司',
160 | phone: '1236777'
161 | }
162 | ];
163 |
164 | export const mockContacts = [
165 | {
166 | index: 'A',
167 | name: '公司',
168 | phone: '1236777'
169 | },
170 | {
171 | index: 'A',
172 | name: '公司',
173 | phone: '1236777'
174 | },
175 | {
176 | index: 'A',
177 | name: '公司',
178 | phone: '1236777'
179 | },
180 | {
181 | index: 'A',
182 | name: '公司',
183 | phone: '1236777'
184 | },
185 | {
186 | index: 'A',
187 | name: '公司',
188 | phone: '1236777'
189 | },
190 | {
191 | index: 'A',
192 | name: '公司',
193 | phone: '1236777'
194 | },
195 | {
196 | index: 'A',
197 | name: '公司',
198 | phone: '1236777'
199 | },
200 | {
201 | index: 'A',
202 | name: '公司',
203 | phone: '1236777'
204 | },
205 | {
206 | index: 'A',
207 | name: '公司',
208 | phone: '1236777'
209 | },
210 | {
211 | index: 'A',
212 | name: '公司',
213 | phone: '1236777'
214 | },
215 | {
216 | index: 'A',
217 | name: '公司',
218 | phone: '1236777'
219 | },
220 | {
221 | index: 'A',
222 | name: '公司',
223 | phone: '1236777'
224 | },
225 | {
226 | index: 'A',
227 | name: '公司',
228 | phone: '1236777'
229 | },
230 | {
231 | index: 'A',
232 | name: '公司',
233 | phone: '1236777'
234 | },
235 | {
236 | index: 'A',
237 | name: '公司',
238 | phone: '1236777'
239 | },
240 | {
241 | index: 'A',
242 | name: '公司',
243 | phone: '1236777'
244 | },
245 | {
246 | index: 'A',
247 | name: '公司',
248 | phone: '1236777'
249 | },
250 | {
251 | index: 'A',
252 | name: '公司',
253 | phone: '1236777'
254 | },
255 | {
256 | index: 'A',
257 | name: '公司',
258 | phone: '1236777'
259 | },
260 | {
261 | index: 'A',
262 | name: '公司',
263 | phone: '1236777'
264 | },
265 | {
266 | index: 'A',
267 | name: '公司',
268 | phone: '1236777'
269 | },
270 | {
271 | index: 'A',
272 | name: '公司',
273 | phone: '1236777'
274 | },
275 | {
276 | index: 'A',
277 | name: '公司',
278 | phone: '1236777'
279 | }
280 | ];
281 |
--------------------------------------------------------------------------------
/src/pages/echarts/echarts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Echarts
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/pages/echarts/echarts.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { IonicPageModule } from 'ionic-angular';
3 | import { EchartsPage } from './echarts';
4 |
5 | @NgModule({
6 | declarations: [
7 | EchartsPage,
8 | ],
9 | imports: [
10 | IonicPageModule.forChild(EchartsPage),
11 | ],
12 | })
13 | export class EchartsPageModule {}
14 |
--------------------------------------------------------------------------------
/src/pages/echarts/echarts.scss:
--------------------------------------------------------------------------------
1 | page-echarts {
2 | #main{
3 | width: 100%;
4 | height: 300px;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/pages/echarts/echarts.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { IonicPage, NavController, NavParams } from 'ionic-angular';
3 | import echarts from 'echarts';
4 | @IonicPage()
5 | @Component({
6 | selector: 'page-echarts',
7 | templateUrl: 'echarts.html',
8 | })
9 | export class EchartsPage {
10 |
11 | constructor(public navCtrl: NavController, public navParams: NavParams) {
12 | }
13 |
14 | ionViewDidLoad() {
15 | let myChart = echarts.init(document.getElementById('main'));
16 | let option = {
17 | title: {
18 | text: 'ECharts示例'
19 | },
20 | tooltip: {},
21 | legend: {
22 | data: ['销量']
23 | },
24 | xAxis: {
25 | data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
26 | },
27 | yAxis: {},
28 | series: [{
29 | name: '销量',
30 | type: 'bar',
31 | data: [5, 20, 36, 10, 10, 20]
32 | }]
33 | };
34 |
35 | myChart.setOption(option);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/pages/home/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Home
4 |
5 |
6 |
7 |
8 | Hi,HW-basic是一个简单基础的ionic App,里面都是我在真实项目中踩过得坑,实现了以下几个功能:
9 |
10 |
11 | - 1.自定义字体
12 | - 2.自定义Tab图标
13 | - 3.自定义通讯录
14 | - 4.屏幕适配
15 | - 5.数据库
16 | - 6.常用工具封装
17 | - 7.版本信息
18 | - 8.Echarts使用
19 |
20 |
21 | 欢迎star、fork和issue
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/pages/home/home.scss:
--------------------------------------------------------------------------------
1 | page-home {
2 | ul{
3 | margin: rem(10) 0;
4 | }
5 |
6 | button{
7 | width: auto;
8 | height: rem(20);
9 | font-size: 16px;
10 | line-height: rem(20);
11 | background: #488aff;
12 | }
13 | .devide{
14 | margin-top: rem(20);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/pages/home/home.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 |
4 | @Component({
5 | selector: 'page-home',
6 | templateUrl: 'home.html'
7 | })
8 | export class HomePage {
9 |
10 | constructor(public navCtrl: NavController) {
11 |
12 | }
13 |
14 | toEchartsPage() {
15 | this.navCtrl.push('EchartsPage');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pages/login/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 登录
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/pages/login/login.scss:
--------------------------------------------------------------------------------
1 | login {
2 | .login {
3 | width: 50%;
4 | height: rem(30);
5 | margin-top: rem(100);
6 | color: #488aff;
7 | font-size: 20px;
8 | border-radius: 5%;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/login/login.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { TabsPage } from '../tabs/tabs';
3 | import { NavController } from 'ionic-angular';
4 |
5 |
6 | @Component({
7 | selector: 'login',
8 | templateUrl: 'login.html'
9 | })
10 | export class LoginComponent {
11 |
12 |
13 | constructor(private navCtrl: NavController) {
14 |
15 | }
16 |
17 | toHome() {
18 | this.navCtrl.setRoot(TabsPage);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/pages/tabs/tabs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/pages/tabs/tabs.ts:
--------------------------------------------------------------------------------
1 | import { Component, ElementRef, Renderer, ViewChild } from '@angular/core';
2 | import { Keyboard } from '@ionic-native/keyboard';
3 | import { Events, Tabs } from 'ionic-angular';
4 |
5 | import { AboutPage } from '../about/about';
6 | import { ContactPage } from '../contact/contact';
7 | import { HomePage } from '../home/home';
8 |
9 | @Component({
10 | templateUrl: 'tabs.html'
11 | })
12 | export class TabsPage {
13 |
14 | @ViewChild('myTabs') tabRef: Tabs;
15 | mb: any;
16 |
17 | tab1Root = HomePage;
18 | tab2Root = ContactPage;
19 | tab3Root = AboutPage;
20 |
21 | constructor(private elementRef: ElementRef,
22 | private renderer: Renderer,
23 | private keyboard: Keyboard,
24 | private event: Events) {
25 | }
26 |
27 | ionViewDidLoad() {
28 | let tabs = this.queryElement(this.elementRef.nativeElement, '.tabbar');
29 | this.event.subscribe('hideTabs', () => {
30 | console.log('hideTabs');
31 | this.renderer.setElementStyle(tabs, 'display', 'none');
32 | let SelectTab = this.tabRef.getSelected()._elementRef.nativeElement;
33 | let content = this.queryElement(SelectTab, '.scroll-content');
34 | this.mb = content.style['margin-bottom'];
35 | this.renderer.setElementStyle(content, 'margin-bottom', '0')
36 | });
37 |
38 | this.event.subscribe('showTabs', () => {
39 | console.log('showTabs');
40 | this.renderer.setElementStyle(tabs, 'display', '');
41 | let SelectTab = this.tabRef.getSelected()._elementRef.nativeElement;
42 | let content = this.queryElement(SelectTab, '.scroll-content');
43 | this.renderer.setElementStyle(content, 'margin-bottom', this.mb)
44 | });
45 | }
46 |
47 | queryElement(elem: HTMLElement, q: string): HTMLElement {
48 | return elem.querySelector(q);
49 | }
50 |
51 | ionViewWillUnload() {
52 | this.event.unsubscribe('hideTabs');
53 | this.event.unsubscribe('showTabs');
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/pages/user-info/user-info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 用户信息
5 |
6 |
7 |
8 |
9 |
10 |
11 | 用户名
12 | JerryMissTom
13 |
14 |
15 | 联系方式
16 | 582486638@qq.com
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/pages/user-info/user-info.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { IonicPageModule } from 'ionic-angular';
3 | import { UserInfoPage } from './user-info';
4 |
5 | @NgModule({
6 | declarations: [
7 | UserInfoPage,
8 | ],
9 | imports: [
10 | IonicPageModule.forChild(UserInfoPage),
11 | ],
12 | })
13 | export class UserInfoPageModule {}
14 |
--------------------------------------------------------------------------------
/src/pages/user-info/user-info.scss:
--------------------------------------------------------------------------------
1 | page-user-info {
2 | .item {
3 | width: 100%;
4 | height: rem(50);
5 | padding: 0 rem(10);
6 | border-bottom: #ececec solid rem(1);
7 | }
8 |
9 | .login-out {
10 | width: 50%;
11 | height: rem(30);
12 | margin-top: rem(100);
13 | color: #488aff;
14 | font-size: 20px;
15 | border-radius: 5%;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pages/user-info/user-info.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { IonicPage, NavController, NavParams } from 'ionic-angular';
3 | import { App } from 'ionic-angular/components/app/app';
4 | import { LoginComponent } from '../login/login';
5 |
6 | @IonicPage()
7 | @Component({
8 | selector: 'page-user-info',
9 | templateUrl: 'user-info.html',
10 | })
11 | export class UserInfoPage {
12 |
13 | constructor(public navCtrl: NavController,
14 | public navParams: NavParams,
15 | private app: App) {
16 | }
17 |
18 |
19 | loginOut() {
20 | this.app.getRootNavs()[0].setRoot(LoginComponent);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Check out https://googlechromelabs.github.io/sw-toolbox/ for
3 | * more info on how to use sw-toolbox to custom configure your service worker.
4 | */
5 |
6 |
7 | 'use strict';
8 | importScripts('./build/sw-toolbox.js');
9 |
10 | self.toolbox.options.cache = {
11 | name: 'ionic-cache'
12 | };
13 |
14 | // pre-cache our key assets
15 | self.toolbox.precache(
16 | [
17 | './build/main.js',
18 | './build/vendor.js',
19 | './build/main.css',
20 | './build/polyfills.js',
21 | 'index.html',
22 | 'manifest.json'
23 | ]
24 | );
25 |
26 | // dynamically cache any other local assets
27 | self.toolbox.router.any('/*', self.toolbox.fastest);
28 |
29 | // for any other requests go to the network, cache,
30 | // and then only use that cached resource if your user goes offline
31 | self.toolbox.router.default = self.toolbox.networkFirst;
32 |
--------------------------------------------------------------------------------
/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // 页面适配
2 | // 项目的中的所有单位均采用需调用 rem(视觉图的像素值) 方法计算相应的虚拟像素值
3 | $vm_fontsize: 36; // 是$vm_design 值得十分之一
4 | $vm_design: 360; // 根据需要替换成设计稿的值,比如设计稿给你的宽度是360px,
5 | @function rem($px) {
6 | @return ($px / $vm_fontsize) * 1rem;
7 | }
8 |
9 | $action-sheet-ios-button-font-size: rem(20);
10 | $action-sheet-ios-title-font-size: rem(13);
11 | $action-sheet-md-button-font-size: rem(16);
12 | $action-sheet-md-icon-font-size: rem(24);
13 | $action-sheet-md-title-font-size: rem(16);
14 | $action-sheet-wp-button-font-size: rem(15);
15 | $action-sheet-wp-icon-font-size: rem(24);
16 | $action-sheet-wp-title-font-size: rem(20);
17 | $badge-font-size: rem(13);
18 | $button-ios-font-size: rem(16);
19 | $button-ios-large-font-size: rem(20);
20 | $button-ios-small-font-size: rem(13);
21 | $button-ios-small-icon-font-size: rem(13);
22 | $button-md-font-size: rem(14);
23 | $button-md-large-font-size: rem(20);
24 | $button-md-small-font-size: rem(13);
25 | $button-md-small-icon-font-size: rem(14);
26 | $button-wp-font-size: rem(14);
27 | $button-wp-large-font-size: rem(20);
28 | $button-wp-small-font-size: rem(13);
29 | $button-wp-small-icon-font-size: rem(13);
30 | $card-ios-font-size: rem(14);
31 | $card-ios-header-font-size: rem(16);
32 | $card-ios-title-font-size: rem(18);
33 | $card-md-font-size: rem(14);
34 | $card-md-header-font-size: rem(16);
35 | $card-md-title-font-size: rem(24);
36 | $card-wp-font-size: rem(14);
37 | $card-wp-header-font-size: rem(16);
38 | $card-wp-title-font-size: rem(24);
39 | $font-size-base: rem(14);
40 | $font-size-ios-base: $font-size-base;
41 | $font-size-ios-base: $font-size-base;
42 | $font-size-md-base: $font-size-base;
43 | $font-size-md-base: $font-size-base;
44 | $font-size-wp-base: $font-size-base;
45 | $font-size-wp-base: $font-size-base;
46 | $h1-font-size: rem(26);
47 | $h2-font-size: rem(24);
48 | $h3-font-size: rem(22);
49 | $h4-font-size: rem(20);
50 | $h5-font-size: rem(18);
51 | $h6-font-size: rem(16);
52 | $item-ios-body-text-font-size: rem(17);
53 | $item-ios-paragraph-font-size: rem(14);
54 | $item-md-body-text-font-size: rem(14);
55 | $item-md-divider-font-size: $item-md-body-text-font-size;
56 | $item-md-font-size: rem(16);
57 | $item-wp-body-text-font-size: rem(14);
58 | $item-wp-divider-font-size: rem(20);
59 | $item-wp-font-size: rem(16);
60 | $list-ios-header-font-size: rem(12);
61 | $list-md-header-font-size: rem(14);
62 | $list-wp-header-font-size: rem(20);
63 | $searchbar-wp-input-font-size: rem(14);
64 | $segment-button-ios-font-size: rem(13);
65 | $segment-button-ios-toolbar-font-size: rem(12);
66 | $segment-button-md-font-size: rem(12);
67 | $segment-button-wp-font-size: rem(13);
68 | $tabs-md-tab-font-size: rem(12);
69 | $tabs-md-tab-font-size-active: rem(14);
70 | $tabs-wp-tab-font-size: rem(12);
71 | $toast-ios-title-font-size: rem(14);
72 | $toast-md-title-font-size: rem(15);
73 | $toast-wp-title-font-size: rem(14);
74 | $toolbar-ios-button-font-size: rem(17);
75 | $toolbar-ios-title-font-size: rem(17);
76 | $toolbar-md-button-font-size: rem(14);
77 | $toolbar-md-title-font-size: rem(20);
78 | $toolbar-wp-button-font-size: rem(14);
79 | $toolbar-wp-title-font-size: rem(15);
80 | $action-sheet-ios-button-min-height: rem(48);
81 | $action-sheet-ios-title-padding: rem(15);
82 | $action-sheet-md-button-min-height: rem(48);
83 | $action-sheet-md-icon-width: rem(23);
84 | $action-sheet-wp-button-height: rem(48);
85 | $action-sheet-wp-icon-width:rem(23);
86 | $alert-wp-input-line-height:rem(30);
87 | $button-ios-margin-bottom: rem(4);
88 | $button-ios-margin-end: rem(2);
89 | $button-ios-margin-start:rem(2);
90 | $button-ios-margin-top: rem(4);
91 | $button-md-height: rem(36);
92 | $button-md-margin-bottom: rem(4);
93 | $button-md-margin-end: rem(2);
94 | $button-md-margin-start:rem(2);
95 | $button-md-margin-top: rem(4);
96 | $button-round-padding-end: rem(26);
97 | $button-wp-height: rem(36);
98 | $button-wp-margin-bottom :rem(4);
99 | $button-wp-margin-end: rem(2);
100 | $button-wp-margin-start: rem(2);
101 | $button-wp-margin-top:rem(4);
102 | $list-ios-header-letter-spacing:rem(1);
103 | $list-md-header-min-height:rem(45);
104 | $searchbar-ios-input-height:rem(30);
105 | $searchbar-md-input-line-height:rem(30);
106 | $searchbar-wp-input-line-height:rem(30);
107 | $segment-button-ios-height: rem(32);
108 | $segment-button-ios-icon-line-height: rem(28);
109 | $segment-button-ios-icon-size: rem(26);
110 | $segment-button-ios-line-height:rem(30);
111 | $segment-button-ios-toolbar-button-height: rem(26);
112 | $segment-button-ios-toolbar-icon-line-height: rem(24);
113 | $segment-button-ios-toolbar-icon-size:rem(22);
114 | $segment-button-ios-toolbar-line-height: rem(25);
115 | $segment-button-md-font-size: rem(12);
116 | $segment-button-md-height: rem(42);
117 | $segment-button-md-icon-size: rem(26);
118 | $segment-button-md-line-height: rem(40);
119 | $segment-button-wp-height: rem(40);
120 | $segment-button-wp-icon-size: rem(26);
121 | $segment-button-wp-line-height: rem(40);
122 | $tabs-md-tab-font-size-active:rem(14);
123 | $tabs-md-tab-icon-size:rem(24);
124 | $tabs-md-tab-min-height:rem(46);
125 | $tabs-wp-tab-icon-size:rem(24);
126 | $text-input-wp-line-height:rem(30);
127 | $toast-ios-border-radius:rem(6.5);
128 | $toast-ios-title-padding-top:rem(15);
129 | $toast-wp-title-padding-top:rem(15);
130 | $segment-button-ios-icon-line-height:rem(28);
131 | $menu-width:rem(200);
132 | $menu-small-width:rem(200);
133 |
134 |
135 | // Ionic Variables and Theming. For more info, please see:
136 | // http://ionicframework.com/docs/theming/
137 | // Font path is used to include ionicons,
138 | // roboto, and noto sans fonts
139 | $font-path: "../assets/fonts";
140 | // The app direction is used to include
141 | // rtl styles in your app. For more info, please see:
142 | // http://ionicframework.com/docs/theming/rtl-support/
143 | $app-direction: ltr;
144 | @import "ionic.globals";
145 | // Shared Variables
146 | // --------------------------------------------------
147 | // To customize the look and feel of this app, you can override
148 | // the Sass variables found in Ionic's source scss files.
149 | // To view all the possible Ionic variables, see:
150 | // http://ionicframework.com/docs/theming/overriding-ionic-variables/
151 | // Named Color Variables
152 | // --------------------------------------------------
153 | // Named colors makes it easy to reuse colors on various components.
154 | // It's highly recommended to change the default colors
155 | // to match your app's branding. Ionic uses a Sass map of
156 | // colors so you can add, rename and remove colors as needed.
157 | // The "primary" color is the only required color in the map.
158 | $colors: ( primary: #488aff, secondary: #32db64, danger: #f53d3d, light: #f4f4f4, dark: #222);
159 | // App iOS Variables
160 | // --------------------------------------------------
161 | // iOS only Sass variables can go here
162 | // App Material Design Variables
163 | // --------------------------------------------------
164 | // Material Design only Sass variables can go here
165 | // App Windows Variables
166 | // --------------------------------------------------
167 | // Windows only Sass variables can go here
168 | // App Theme
169 | // --------------------------------------------------
170 | // Ionic apps can have different themes applied, which can
171 | // then be future customized. This import comes last
172 | // so that the above variables are used and Ionic's
173 | // default are overridden.
174 | @import "ionic.theme.default";
175 | // Ionicons
176 | // --------------------------------------------------
177 | // The premium icon font for Ionic. For more info, please see:
178 | // http://ionicframework.com/docs/ionicons/
179 | @import "ionic.ionicons";
180 | // Fonts
181 | // --------------------------------------------------
182 | @import "roboto";
183 | @import "noto-sans";
184 |
185 |
186 |
187 | //--------------------------自定义字体示例------------------------
188 | // 把字体文件放在asset中,然后引入
189 | // @font-face {
190 | // font-family: 'Sans';
191 | // src: url('../assets/fonts/Sans.otf') format('opentype');
192 | // }
193 |
194 |
195 | //-------------------------自定义tab图标示例-------------------------
196 | // 修改Tab的图标和颜色
197 | // $iconfont-path: "../assets/fonts";
198 | // @font-face {
199 | // font-family: "iconfont";
200 | // src: url('iconfont.eot?t=1514257834808');
201 | // /* IE9*/
202 | // src: url('iconfont.eot?t=1514257834808#iefix') format('embedded-opentype'), /* IE6-IE8 */
203 | // url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAuQAAsAAAAAEFQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAAQwAAAFZW7kgkY21hcAAAAYAAAACHAAAB4mM80tBnbHlmAAACCAAAB0AAAAl03fTStGhlYWQAAAlIAAAAMQAAADYQkwFwaGhlYQAACXwAAAAgAAAAJAiDBExobXR4AAAJnAAAABsAAAAkJNb//GxvY2EAAAm4AAAAFAAAABQIGAnqbWF4cAAACcwAAAAfAAAAIAEbAO9uYW1lAAAJ7AAAAUUAAAJtPlT+fXBvc3QAAAs0AAAAWgAAAH3UQ2QFeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkkWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGBwYKp6JMTf8b2CIYW5haAAKM4LkANzPC6cAeJzFkdENgzAMRM+QAgJa+IEpGKID9QP1i4lvDXq2+ekEXPQS20rk6AzgAaAWmyiAfWFwfVS1qNfoo17wVt5pVToPTlzPM6KBS0QuixtzRJXeFnVo0KoGa3Cb7L7W/xpj369MruC40Bc5JO4wx8Snw2fiE+Ir8clxSuQwuCTyGlwTdD9DdRo5AHicbVZbbBxXGT6XmTkzuzNndmZ2Znb2MuvZ9e7aXmcX73ovie11NhcLTCqndktt2jSJUQIlIgmXNIpUQVWBUjUVsoAUEUpAqNAXhFRQHxpF5IG26gtCFQ88FAkKRiJC7UNVNX2IJ/wztkuEODvnP//555zzf+fM980sEhG69y69STPIQmNoCh1CRxHCUh2XOCngoDbdIHVsB6LtpjmtlWsBK5cadA67JSnttLrTVVdiko459nE7aHVrDVLDnekBmcEtp4Cxl8uumJW8STdwIlPzvxMukp9ju1jO64M94Wcm59OtEUu+qJqmZ5rPy5IoyoQIOsdfcR1FVBJS+JKoZ+2bxXFSxKpXyx5Z00Zy5slnp88WKq6C8dNPYys3wl+eN7IGXE9lHcv0WEqTM1mtPJrGFzeTGUstVP+BoMiw15/RP9MxRBFDSaTDnl00jjoIWUZg0HKn3dtp8W5bG+Bet1qrwi4dt9XtuZUBdn3MOK418AK+fmxz85XY3v1D3JClIdcFfGp5+asiObU8MusNw/fEmfpknwiz9fpeOhaexD8Nf7f5+E4bXgjX8fXw1uY91Leb3vJ5iZxeBqubc3+D4duThNkIvwT4fysguoZm0afRCjqOzqBz8LQ4dtOOCw+G1TqN3V4jwghIewNcm67Weu0IPMf2dqSBITLADYxL1WiLPnYdyWrE2/WJ5EJ0uhtFObbuG4EDO6DHGjM0yTaUXHpBGD6+D/wrSYc391Fh2AQrCldd3U/OCVgcNpr7CE4lr2Q6c2x49yM7K2DXtHOUuh/v+pL7JwhkzLj/zn9HZO9eo+/dtejnYBWe57d532rNsGGTZ5O/hxzbucAyU347KU8zk0Eucdg0Svyv8sFj3a3Uzpom8PBkvCh0RgsvZwxnJwn+XsaIozBka2kNRVr4Nf0nvbjDjwroAVVgy7u/6IA4ZvGxMDi+Xstxe/GhVbZjsU9+hfvhW7v1i/Tak09eo3h//7mb7nr+3Z9Mn5poZ6Yy/f3h+0tPEPLEUmw/XKnCj7wKQ2HCwsVa850fvHCLZr2HNCtRu7C1Ow4soAPNAg/mkY3qoFiEt3GUAUHasWvM7VU7AyzWmGNDCJ4fQI7gAg9c3O60O+W49moMxtplux1Vwr220x99cOLGHUHg7cv9CfYGeRYa4c3vx3eO1m98JAqYh9X+FSjPTJz/xsQ3r0Ih/2ZsgXPxzg2jbPLhueEDn7/2xl+i5oXXKZMOcy7cuWGWDR6+fqn9UJv/qHr5cnXDBRfBOaN7P6Z36FmkIQP246ECCuDkkULcntE2KiIYAG0D5O3q3tfSO6EQ8n6wiof4s8dGttZW4/LqGpRX1tbwh/hSeHUxv/UWuXT7g60NMuGGi6v/Wv1g7W2w/VXQlHgvvHdd+CX9NvoCuoCeQb9Bf4dgpHjQSDPSSmceDyKvG0X0mABSMRZX2ikSCWoUifq1arfXhRm9aDb4VfDdthsphznwAomI40BXx72KnXbmodftdeJFq1LEox4DmUUqFf/fUtGNndTbibGdluLMu3jnPsFbjQDHKo+z+xHCT/Iz+j6tHzlwaLyTUOycS9UU0VRBlUxznBRy/kphzBE1QaFK0iZYz+sEiD538IEJuk4HX5/tZovCGC8nJFXJ7D/0kprLubO5g3k3ERhlrajtnf/avHByauuWKh8/zpIYJ9mJEyx5drBI9+bz9MTRybGFrTenSGk+KOomcZktUVnS/OxhT9SnzbRKJMqoqmKspGQ/N1qezAiHcGayEuR9OaXgpEolQSJq2pzWRW/BK2qiIkg2c4mpB8X5ElmXT435e4pnSjmvNEf1JM9bhtd/0DYlTMZpodR+zHHEHBc1xj3SLOiZ2dPBWHH8tCirL87lR1Mtf88MzO+a31pZDOg4cQtHflhfGd03Ve4q1cLci6os3D4gy8T1iCIfZArxwGEkEJZqY8wrP2IZs6L0cElPJ3wjV+IZ01cOTAZZMoUNp9BKJoUUl5hGfIOpQc9yU+4MFfa5hmP2g4Ri+ERjEtdFRWsVHANPkWwweUDxzQwv5Qw/YfPSwxLa4e0vhAn6ZbQEX4JH0KNoA4JBrxqzBq5G9JK/j4Lw2IGD5Zgf3Sb5XzpLaaBTaYdTnLLAFgMjwFAjnUV8hGlAyXjZmJFxIvgbAPyLOWlHk2NW7ugBfxweF4Te6UzLM9MUroAlrf7MdxN5z2k7RV3TR4UzuiSoXJJVIUF1nsN5OzuwKmlBZrqHFTvVGMvP9soqrpA9W38kU2ELnwmvPvraa1tPtUixm9XVjKgmqJoglAlSQnUHrsDrmkIY0FfETANgCs45xeKoZXeV53pq3tRKlrMnNXJ05Pzi4YBWiJUprg+PPEbcKjZUjVspuz5MJQkWAsnLVRZtI1FIGAXfMtKd1YJZ9Er6lxaIES7jhXzrnCAtFjWmaCNaLqGYUiqTyH/K8m0ypZuJwNJUmhAYllX4OMhqoZVKa3YT/QcP3Jg3eJxjYGRgYABiiam74uP5bb4ycLMwgMC19HurYPT/f/9nsyxjbgFyORiYQKIAZDsN0wAAAHicY2BkYGBu+N/AEMNy+P+///9ZljEARVAAJwC/+wfWeJxjYWBgYH7JwMDCgAUf/v+PRfP/PwAyxwXzAAAAAAAAdgDWAYYB2gJAAoAD3AS6eJxjYGRgYOBkeMzAwQACTEDMBYQMDP/BfAYAICACCwB4nGWPTU7DMBCFX/oHpBKqqGCH5AViASj9EatuWFRq911036ZOmyqJI8et1ANwHo7ACTgC3IA78EgnmzaWx9+8eWNPANzgBx6O3y33kT1cMjtyDRe4F65TfxBukF+Em2jjVbhF/U3YxzOmwm10YXmD17hi9oR3YQ8dfAjXcI1P4Tr1L+EG+Vu4iTv8CrfQ8erCPuZeV7iNRy/2x1YvnF6p5UHFockikzm/gple75KFrdLqnGtbxCZTg6BfSVOdaVvdU+zXQ+ciFVmTqgmrOkmMyq3Z6tAFG+fyUa8XiR6EJuVYY/62xgKOcQWFJQ6MMUIYZIjK6Og7VWb0r7FDwl57Vj3N53RbFNT/c4UBAvTPXFO6stJ5Ok+BPV8bUnV0K27LnpQ0kV7NSRKyQl7WtlRC6gE2ZVeOEXpc0Yk/KGdI/wAJWm7IAAAAeJxtikEKgDAMBLNqa+3VF6YiaaqkByno7xV6dWAPswwN1In0z4IBIyY4eMwIWBAJtxfWk21OXJNyDUVNnm++fPaoO9rWLB57btLYTl2l9uDKbNI/ohfDuxpuAAA=') format('woff'), url('iconfont.ttf?t=1514257834808') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
204 | // url('iconfont.svg?t=1514257834808#iconfont') format('svg');
205 | // /* iOS 4.1- */
206 | // }
207 |
208 | // .iconfont {
209 | // font-family: "iconfont" !important;
210 | // font-size: rem(24);
211 | // font-style: normal;
212 | // -webkit-font-smoothing: antialiased;
213 | // -moz-osx-font-smoothing: grayscale;
214 | // }
215 |
216 | // .icon-home:before {
217 | // content: "\e60a";
218 | // }
219 |
220 | // .icon-contact:before {
221 | // content: "\e60b";
222 | // }
223 |
224 | // .icon-about:before {
225 | // content: "\e60c";
226 | // }
227 |
228 | // .ion-md-custom-home:before,
229 | // .ion-ios-custom-home:before,
230 | // .ion-ios-custom-home-outline:before,
231 | // .ion-md-custom-contact:before,
232 | // .ion-ios-custom-contact:before,
233 | // .ion-ios-custom-contact-outline:before,
234 | // .ion-md-custom-about:before,
235 | // .ion-ios-custom-about:before,
236 | // .ion-ios-custom-about-outline:before,
237 | // {
238 | // @extend .iconfont;
239 | // }
240 |
241 | // .ion-ios-custom-home:before {
242 | // content: "\e60a";
243 | // }
244 |
245 | // .ion-ios-custom-home-outline:before {
246 | // content: "\e60a";
247 | // }
248 |
249 | // .ion-ios-custom-contact:before {
250 | // content: "\e60b";
251 | // }
252 |
253 | // .ion-ios-custom-contact-outline:before {
254 | // content: "\e60b";
255 | // }
256 |
257 | // .ion-ios-custom-about:before {
258 | // content: "\e60c";
259 | // }
260 |
261 | // .ion-ios-custom-about-outline:before {
262 | // content: "\e60c";
263 | // }
264 |
265 | // // 修改Tab点击选中颜色
266 | // $tabs-ios-tab-text-color-active:#F37021;
267 | // $tabs-ios-tab-icon-color-active:#F37021;
268 | // $tabs-md-tab-text-color-active:#F37021;
269 | // $tabs-md-tab-icon-color-active:#F37021;
270 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "module": "es2015",
12 | "moduleResolution": "node",
13 | "sourceMap": true,
14 | "target": "es5"
15 | },
16 | "include": [
17 | "src/**/*.ts"
18 | ],
19 | "exclude": [
20 | "node_modules"
21 | ],
22 | "compileOnSave": false,
23 | "atom": {
24 | "rewriteTsconfig": false
25 | }
26 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-duplicate-variable": true,
4 | "no-unused-variable": [
5 | true
6 | ]
7 | },
8 | "rulesDirectory": [
9 | "node_modules/tslint-eslint-rules/dist/rules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------