wangtengyu
2018-11-06 a5a6487bd568fda30c7204ef3e3b7a2ed0a9019c
导入初始代码
119 files added
1674 ■■■■■ changed files
.editorconfig 17 ●●●●● patch | view | raw | blame | history
.gitignore 34 ●●●●● patch | view | raw | blame | history
LICENSE 21 ●●●●● patch | view | raw | blame | history
config.xml 92 ●●●●● patch | view | raw | blame | history
config/optimization.config.js 12 ●●●●● patch | view | raw | blame | history
config/webpack.config.js 12 ●●●●● patch | view | raw | blame | history
ionic.config.json 6 ●●●●● patch | view | raw | blame | history
package.json 46 ●●●●● patch | view | raw | blame | history
resources/android/icon/drawable-hdpi-icon.png patch | view | raw | blame | history
resources/android/icon/drawable-ldpi-icon.png patch | view | raw | blame | history
resources/android/icon/drawable-mdpi-icon.png patch | view | raw | blame | history
resources/android/icon/drawable-xhdpi-icon.png patch | view | raw | blame | history
resources/android/icon/drawable-xxhdpi-icon.png patch | view | raw | blame | history
resources/android/icon/drawable-xxxhdpi-icon.png patch | view | raw | blame | history
resources/android/splash/drawable-land-hdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-land-ldpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-land-mdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-land-xhdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-land-xxhdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-land-xxxhdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-hdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-ldpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-mdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-xhdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-xxhdpi-screen.png patch | view | raw | blame | history
resources/android/splash/drawable-port-xxxhdpi-screen.png patch | view | raw | blame | history
resources/icon.png patch | view | raw | blame | history
resources/ios/icon/icon-40.png patch | view | raw | blame | history
resources/ios/icon/icon-40@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-40@3x.png patch | view | raw | blame | history
resources/ios/icon/icon-50.png patch | view | raw | blame | history
resources/ios/icon/icon-50@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-60.png patch | view | raw | blame | history
resources/ios/icon/icon-60@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-60@3x.png patch | view | raw | blame | history
resources/ios/icon/icon-72.png patch | view | raw | blame | history
resources/ios/icon/icon-72@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-76.png patch | view | raw | blame | history
resources/ios/icon/icon-76@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-83.5@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-small.png patch | view | raw | blame | history
resources/ios/icon/icon-small@2x.png patch | view | raw | blame | history
resources/ios/icon/icon-small@3x.png patch | view | raw | blame | history
resources/ios/icon/icon.png patch | view | raw | blame | history
resources/ios/icon/icon@2x.png patch | view | raw | blame | history
resources/ios/splash/Default-568h@2x~iphone.png patch | view | raw | blame | history
resources/ios/splash/Default-667h.png patch | view | raw | blame | history
resources/ios/splash/Default-736h.png patch | view | raw | blame | history
resources/ios/splash/Default-Landscape-736h.png patch | view | raw | blame | history
resources/ios/splash/Default-Landscape@2x~ipad.png patch | view | raw | blame | history
resources/ios/splash/Default-Landscape~ipad.png patch | view | raw | blame | history
resources/ios/splash/Default-Portrait@2x~ipad.png patch | view | raw | blame | history
resources/ios/splash/Default-Portrait~ipad.png patch | view | raw | blame | history
resources/ios/splash/Default@2x~iphone.png patch | view | raw | blame | history
resources/ios/splash/Default~iphone.png patch | view | raw | blame | history
resources/splash.png patch | view | raw | blame | history
run.bat 1 ●●●● patch | view | raw | blame | history
run.sh 2 ●●●●● patch | view | raw | blame | history
src/app/app.component.ts 30 ●●●●● patch | view | raw | blame | history
src/app/app.html 1 ●●●● patch | view | raw | blame | history
src/app/app.module.ts 36 ●●●●● patch | view | raw | blame | history
src/app/app.scss 34 ●●●●● patch | view | raw | blame | history
src/app/main.ts 5 ●●●●● patch | view | raw | blame | history
src/assets/icon/favicon.ico patch | view | raw | blame | history
src/index.html 55 ●●●●● patch | view | raw | blame | history
src/kl/config/config.prod.ts 4 ●●●● patch | view | raw | blame | history
src/kl/config/config.ts 4 ●●●● patch | view | raw | blame | history
src/kl/config/index.ts 1 ●●●● patch | view | raw | blame | history
src/kl/core/core.module.ts 27 ●●●●● patch | view | raw | blame | history
src/kl/core/index.ts 7 ●●●●● patch | view | raw | blame | history
src/kl/core/rxjs-operators.ts 17 ●●●●● patch | view | raw | blame | history
src/kl/core/services/auth.service.ts 17 ●●●●● patch | view | raw | blame | history
src/kl/core/services/httpclient.ts 89 ●●●●● patch | view | raw | blame | history
src/kl/core/services/loading.service.ts 26 ●●●●● patch | view | raw | blame | history
src/kl/core/services/logger.ts 59 ●●●●● patch | view | raw | blame | history
src/kl/core/services/messagebox.ts 109 ●●●●● patch | view | raw | blame | history
src/kl/core/services/platform.service.ts 169 ●●●●● patch | view | raw | blame | history
src/kl/model/api.result.ts 5 ●●●●● patch | view | raw | blame | history
src/kl/model/index.ts 2 ●●●●● patch | view | raw | blame | history
src/kl/model/user.ts 5 ●●●●● patch | view | raw | blame | history
src/kl/shared/directives/camera.directive.ts 104 ●●●●● patch | view | raw | blame | history
src/kl/shared/index.ts 2 ●●●●● patch | view | raw | blame | history
src/kl/shared/pipes/localdate.pipe.ts 27 ●●●●● patch | view | raw | blame | history
src/kl/shared/shared.module.ts 28 ●●●●● patch | view | raw | blame | history
src/manifest.json 13 ●●●●● patch | view | raw | blame | history
src/pages/access/access.module.ts 11 ●●●●● patch | view | raw | blame | history
src/pages/access/components/forgotpwd/forgotpwd.html 18 ●●●●● patch | view | raw | blame | history
src/pages/access/components/forgotpwd/forgotpwd.module.ts 13 ●●●●● patch | view | raw | blame | history
src/pages/access/components/forgotpwd/forgotpwd.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/access/components/forgotpwd/forgotpwd.ts 27 ●●●●● patch | view | raw | blame | history
src/pages/access/components/login/login.html 12 ●●●●● patch | view | raw | blame | history
src/pages/access/components/login/login.module.ts 15 ●●●●● patch | view | raw | blame | history
src/pages/access/components/login/login.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/access/components/login/login.ts 27 ●●●●● patch | view | raw | blame | history
src/pages/access/components/register/register.html 12 ●●●●● patch | view | raw | blame | history
src/pages/access/components/register/register.module.ts 15 ●●●●● patch | view | raw | blame | history
src/pages/access/components/register/register.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/access/components/register/register.ts 25 ●●●●● patch | view | raw | blame | history
src/pages/access/services/index.ts 1 ●●●● patch | view | raw | blame | history
src/pages/access/services/login.service.ts 15 ●●●●● patch | view | raw | blame | history
src/pages/tabs/about/about.html 12 ●●●●● patch | view | raw | blame | history
src/pages/tabs/about/about.module.ts 13 ●●●●● patch | view | raw | blame | history
src/pages/tabs/about/about.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/tabs/about/about.ts 20 ●●●●● patch | view | raw | blame | history
src/pages/tabs/contact/contact.html 12 ●●●●● patch | view | raw | blame | history
src/pages/tabs/contact/contact.module.ts 13 ●●●●● patch | view | raw | blame | history
src/pages/tabs/contact/contact.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/tabs/contact/contact.ts 20 ●●●●● patch | view | raw | blame | history
src/pages/tabs/home/home.html 12 ●●●●● patch | view | raw | blame | history
src/pages/tabs/home/home.module.ts 13 ●●●●● patch | view | raw | blame | history
src/pages/tabs/home/home.scss 3 ●●●●● patch | view | raw | blame | history
src/pages/tabs/home/home.ts 23 ●●●●● patch | view | raw | blame | history
src/pages/tabs/tabs.html 5 ●●●●● patch | view | raw | blame | history
src/pages/tabs/tabs.module.ts 13 ●●●●● patch | view | raw | blame | history
src/pages/tabs/tabs.ts 20 ●●●●● patch | view | raw | blame | history
src/service-worker.js 31 ●●●●● patch | view | raw | blame | history
src/theme/variables.scss 88 ●●●●● patch | view | raw | blame | history
tsconfig.json 27 ●●●●● patch | view | raw | blame | history
tslint.json 24 ●●●●● patch | view | raw | blame | history
.editorconfig
New file
@@ -0,0 +1,17 @@
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
.gitignore
New file
@@ -0,0 +1,34 @@
# Specifies intentionally untracked files to ignore when using Git
# http://git-scm.com/docs/gitignore
*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.vscode/
npm-debug.log*
.idea/
.sass-cache/
.tmp/
.versions/
coverage/
dist/
node_modules/
tmp/
temp/
hooks/
platforms/
plugins/
plugins/android.json
plugins/ios.json
www/
$RECYCLE.BIN/
.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate
LICENSE
New file
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 kinglionsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
config.xml
New file
@@ -0,0 +1,92 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.ionic.starter" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>ykseed</name>
    <description>An awesome Ionic/Cordova app.</description>
    <author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
    <content src="index.html" />
    <access origin="*" />
    <allow-navigation href="http://ionic.local/*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <preference name="webviewbounce" value="false" />
    <preference name="UIWebViewBounce" value="false" />
    <preference name="DisallowOverscroll" value="true" />
    <preference name="android-minSdkVersion" value="16" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="SplashMaintainAspectRatio" value="true" />
    <preference name="FadeSplashScreenDuration" value="300" />
    <!--
      Change these to configure how the splashscreen displays and fades in/out.
      More info here: https://github.com/apache/cordova-plugin-splashscreen
    -->
    <preference name="SplashShowOnlyFirstTime" value="false" />
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="3000" />
    <platform name="android">
        <allow-intent href="market:*" />
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
        <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
        <icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
        <icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
        <icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
        <splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
        <splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
        <splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
        <splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
        <splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
        <splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
        <splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
        <splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
        <splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
        <splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
        <splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
        <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon height="57" src="resources/ios/icon/icon.png" width="57" />
        <icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
        <icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
        <icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
        <icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
        <icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
        <icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
        <icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
        <icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
        <icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
        <icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
        <icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
        <icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
        <icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
        <icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
        <icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
        <icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
        <icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
        <splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
        <splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
        <splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
        <splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
        <splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
        <splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
        <splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
        <splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
        <splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
        <splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
        <splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
        <splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
    </platform>
    <plugin name="ionic-plugin-keyboard" spec="~2.2.1" />
    <plugin name="cordova-plugin-whitelist" spec="1.3.1" />
    <plugin name="cordova-plugin-console" spec="1.0.5" />
    <plugin name="cordova-plugin-statusbar" spec="2.2.2" />
    <plugin name="cordova-plugin-device" spec="1.1.4" />
    <plugin name="cordova-plugin-splashscreen" spec="~4.0.1" />
    <plugin name="cordova-plugin-camera" spec="~2.4.1" />
</widget>
config/optimization.config.js
New file
@@ -0,0 +1,12 @@
const path = require('path');
const defaults = require('@ionic/app-scripts/config/optimization.config');
module.exports = function () {
  if (!defaults.resolve.alias) {
    defaults.resolve.alias = {};
  }
  defaults.resolve.alias.kl = path.resolve('src/kl');
  return defaults;
};
config/webpack.config.js
New file
@@ -0,0 +1,12 @@
const path = require('path');
const defaults = require('@ionic/app-scripts/config/webpack.config');
module.exports = function () {
  if (!defaults.resolve.alias) {
    defaults.resolve.alias = {};
  }
  defaults.resolve.alias.kl = path.resolve('src/kl');
  return defaults;
};
ionic.config.json
New file
@@ -0,0 +1,6 @@
{
  "name": "ionic-seed3",
  "app_id": "",
  "type": "ionic-angular",
  "integrations": {}
}
package.json
New file
@@ -0,0 +1,46 @@
{
  "name": "xsmax-app",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "config": {
    "ionic_webpack": "./config/webpack.config.js",
    "ionic_optimization": "./config/optimization.config.js"
  },
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/compiler-cli": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "4.1.3",
    "@angular/http": "4.1.3",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@ionic-native/camera": "^3.12.1",
    "@ionic-native/core": "3.12.1",
    "@ionic-native/splash-screen": "3.12.1",
    "@ionic-native/status-bar": "3.12.1",
    "@ionic/storage": "2.0.1",
    "ionic-angular": "3.6.0",
    "ionicons": "3.0.0",
    "moment": "^2.18.1",
    "rxjs": "5.4.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.12"
  },
  "devDependencies": {
    "@ionic/app-scripts": "2.1.3",
    "ionic": "^3.9.2",
    "tslint-ionic-rules": "^0.0.11",
    "typescript": "2.3.4"
  },
  "description": "ykseed: An Ionic project@3.6.0"
}
resources/android/icon/drawable-hdpi-icon.png
resources/android/icon/drawable-ldpi-icon.png
resources/android/icon/drawable-mdpi-icon.png
resources/android/icon/drawable-xhdpi-icon.png
resources/android/icon/drawable-xxhdpi-icon.png
resources/android/icon/drawable-xxxhdpi-icon.png
resources/android/splash/drawable-land-hdpi-screen.png
resources/android/splash/drawable-land-ldpi-screen.png
resources/android/splash/drawable-land-mdpi-screen.png
resources/android/splash/drawable-land-xhdpi-screen.png
resources/android/splash/drawable-land-xxhdpi-screen.png
resources/android/splash/drawable-land-xxxhdpi-screen.png
resources/android/splash/drawable-port-hdpi-screen.png
resources/android/splash/drawable-port-ldpi-screen.png
resources/android/splash/drawable-port-mdpi-screen.png
resources/android/splash/drawable-port-xhdpi-screen.png
resources/android/splash/drawable-port-xxhdpi-screen.png
resources/android/splash/drawable-port-xxxhdpi-screen.png
resources/icon.png
resources/ios/icon/icon-40.png
resources/ios/icon/icon-40@2x.png
resources/ios/icon/icon-40@3x.png
resources/ios/icon/icon-50.png
resources/ios/icon/icon-50@2x.png
resources/ios/icon/icon-60.png
resources/ios/icon/icon-60@2x.png
resources/ios/icon/icon-60@3x.png
resources/ios/icon/icon-72.png
resources/ios/icon/icon-72@2x.png
resources/ios/icon/icon-76.png
resources/ios/icon/icon-76@2x.png
resources/ios/icon/icon-83.5@2x.png
resources/ios/icon/icon-small.png
resources/ios/icon/icon-small@2x.png
resources/ios/icon/icon-small@3x.png
resources/ios/icon/icon.png
resources/ios/icon/icon@2x.png
resources/ios/splash/Default-568h@2x~iphone.png
resources/ios/splash/Default-667h.png
resources/ios/splash/Default-736h.png
resources/ios/splash/Default-Landscape-736h.png
resources/ios/splash/Default-Landscape@2x~ipad.png
resources/ios/splash/Default-Landscape~ipad.png
resources/ios/splash/Default-Portrait@2x~ipad.png
resources/ios/splash/Default-Portrait~ipad.png
resources/ios/splash/Default@2x~iphone.png
resources/ios/splash/Default~iphone.png
resources/splash.png
run.bat
New file
@@ -0,0 +1 @@
ionic serve
run.sh
New file
@@ -0,0 +1,2 @@
#!/bin/bash
ionic serve
src/app/app.component.ts
New file
@@ -0,0 +1,30 @@
import { Component, ViewChild } from '@angular/core';
import { Platform, Nav } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { PlatformService } from 'kl/core';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any = 'maintabs';
  @ViewChild(Nav) nav: Nav;
  constructor(
    platform: Platform,
    private statusBar: StatusBar,
    private splashScreen: SplashScreen,
    private platformService: PlatformService) {
    platform.ready().then(() => {
      this.splashScreen.hide();
      if (platform.is('ios') || platform.is('android')) {
        this.statusBar.styleDefault();
      }
      // 注册返回按键事件
      this.platformService.rootNav = this.nav;
      this.platformService.registerBackButton();
    });
  }
}
src/app/app.html
New file
@@ -0,0 +1 @@
<ion-nav [root]="rootPage"></ion-nav>
src/app/app.module.ts
New file
@@ -0,0 +1,36 @@
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { KlCoreModule } from 'kl/core';
@NgModule({
  declarations: [
    MyApp
  ],
  imports: [
    BrowserModule,
    HttpModule,
    IonicModule.forRoot(MyApp, {
      backButtonText: '',
      tabsHideOnSubPages: true,
      model: 'ios'
    }),
    KlCoreModule
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: ErrorHandler, useClass: IonicErrorHandler }
  ]
})
export class AppModule { }
src/app/app.scss
New file
@@ -0,0 +1,34 @@
// http://ionicframework.com/docs/theming/
// App Global Sass
// --------------------------------------------------
// Put style rules here that you want to apply globally. These
// styles are for the entire app and not just one component.
// Additionally, this file can be also used as an entry point
// to import other Sass files to be included in the output CSS.
//
// Shared Sass variables, which can be used to adjust Ionic's
// default Sass variables, belong in "theme/variables.scss".
//
// To declare rules for a specific mode, create a child rule
// for the .md, .ios, or .wp mode classes. The mode class is
// automatically applied to the <body> element in the app.
// 1. Wechat
// --------------------------------------------------
.wechat{
  ion-header{
      display: none !important;
  }
  ion-content{
      .fixed-content{
           margin-top: 0 !important;
      }
      .scroll-content{
          margin-top: 0 !important;
      }
  }
}
src/app/main.ts
New file
@@ -0,0 +1,5 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
src/assets/icon/favicon.ico
src/index.html
New file
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="UTF-8">
  <title>Ionic App</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">
  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
  <link rel="manifest" href="manifest.json">
  <meta name="theme-color" content="#4e8ef7">
  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>
  <!-- un-comment this code to enable service worker
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.error('Error', err));
    }
  </script>-->
  <link href="build/main.css" rel="stylesheet">
</head>
<body>
  <!-- Ionic's root component and where the app will load -->
  <ion-app></ion-app>
  <script>
    var ua = navigator.userAgent.toLowerCase();
    if (/micromessenger/.test(ua)) {
      document.body.classList.add('wechat');
    }
  </script>
  <!-- The polyfills js is generated during the build process -->
  <script src="build/polyfills.js"></script>
  <!-- The vendor js is generated during the build process
       It contains all of the dependencies in node_modules -->
  <script src="build/vendor.js"></script>
  <!-- The main bundle js is generated during the build process -->
  <script src="build/main.js"></script>
</body>
</html>
src/kl/config/config.prod.ts
New file
@@ -0,0 +1,4 @@
export const Config = {
    environment: 'dev',
    host: '/'
};
src/kl/config/config.ts
New file
@@ -0,0 +1,4 @@
export const Config = {
    environment: 'dev',
    host: '/'
};
src/kl/config/index.ts
New file
@@ -0,0 +1 @@
export * from './config';
src/kl/core/core.module.ts
New file
@@ -0,0 +1,27 @@
import { NgModule } from '@angular/core';
import { IonicStorageModule } from '@ionic/storage';
import { HttpClient } from './services/httpclient';
import { Logger } from './services/logger';
import { LoadingService } from './services/loading.service';
import { MessageBox } from './services/messagebox';
import { PlatformService } from './services/platform.service';
import { AuthService } from './services/auth.service';
import './rxjs-operators';
@NgModule({
  imports: [
    IonicStorageModule.forRoot({ name: '_xg', driverOrder: ['sqlite', 'localstorage', 'websql', 'indexeddb'] })
  ],
  exports: [],
  declarations: [],
  providers: [
    Logger,
    LoadingService,
    HttpClient,
    MessageBox,
    PlatformService,
    AuthService
  ]
})
export class KlCoreModule { }
src/kl/core/index.ts
New file
@@ -0,0 +1,7 @@
export * from './core.module';
export * from './services/logger';
export * from './services/loading.service';
export * from './services/httpclient';
export * from './services/messagebox';
export * from './services/platform.service';
export * from './services/auth.service';
src/kl/core/rxjs-operators.ts
New file
@@ -0,0 +1,17 @@
// import 'rxjs/Rx'; // adds ALL RxJS statics & operators to Observable
// See node_module/rxjs/Rxjs.js
// Import just the rxjs statics and operators needed for THIS app.
// Statics
import 'rxjs/add/observable/throw';
// Operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/finally';
import 'rxjs/add/observable/of';
src/kl/core/services/auth.service.ts
New file
@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Storage } from '@ionic/storage';
import { HttpClient } from './httpclient';
import { User } from 'kl/model';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class AuthService {
  // TODO 路由守卫
  private _user: User;
  constructor(private http: HttpClient, private storage: Storage) { }
}
src/kl/core/services/httpclient.ts
New file
@@ -0,0 +1,89 @@
import { Injectable } from '@angular/core';
import { Http, Headers, Response, Request, RequestMethod, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import * as moment from 'moment';
import { LoadingService } from './loading.service';
import { ApiResult } from 'kl/model';
@Injectable()
export class HttpClient {
  constructor(private http: Http, private loading: LoadingService) { }
  get(api: string, fun: Function) {
    this.getResponse(this.http.get(api), fun);
  }
  post (api: string, params: Object, fun: Function) {
    this.getResponse(this.http.post(api, params), fun);
  }
  xhrPost(api, data, fun) {
    let xhr = new XMLHttpRequest();
    xhr.open('POST', api, false);
    xhr.onload = () => fun(JSON.parse(xhr.response));
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.send(JSON.stringify(data) );
  }
  private getResponse(res: Observable<Response>, fun) {
    res.subscribe(response => {
      let json = response.json();
      fun(json);
      }, error => {}
    );
  }
  request<T>(url: string, method: RequestMethod, body?: any, showLoading?: boolean): Observable<ApiResult<T>> {
    let headers = new Headers();
    let options = new RequestOptions();
    options.headers = headers;
    options.url = url;
    options.method = method;
    options.body = body;
    options.withCredentials = true;
    let request = new Request(options);
    if (showLoading !== false) this.loading.show();
    return this.http.request(request)
      .finally(() => {
        if (showLoading !== false) this.loading.hide();
      }).map(r => r.json() as T)
      .catch(x => this.handleError(x));
  }
  /**
   * 将字典转为QueryString
   */
  private _formatUrl(params?: { [key: string]: string }): string {
    if (!params) return '';
    let fegment = [];
    for (let k in params) {
      let v: any = params[k];
      if (v instanceof Date) {
        v = moment(v).format('YYYY-MM-DD HH:mm:SS');
      }
      fegment.push(`${k}=${v}`);
    }
    return '?' + fegment.join('&');
  }
  /**
  * 通用异常处理
  */
  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error ? error.toString() : '服务器发生异常,请稍后再试';
    }
    return Observable.throw(errMsg);
  }
}
src/kl/core/services/loading.service.ts
New file
@@ -0,0 +1,26 @@
import { Injectable } from '@angular/core';
import { LoadingController, Loading } from 'ionic-angular';
@Injectable()
export class LoadingService {
    private loader: Loading;
    private isShow = false;
    constructor(public loadingCtrl: LoadingController) {
    }
    show() {
        if (this.isShow) return;
        this.loader = this.loadingCtrl.create({
            content: '请稍等...'
        });
        this.isShow = true;
        this.loader.present();
    }
    hide() {
        if (!this.isShow) return;
        this.isShow = false;
        this.loader.dismiss();
    }
}
src/kl/core/services/logger.ts
New file
@@ -0,0 +1,59 @@
import { Injectable } from '@angular/core';
import { ToastController } from 'ionic-angular';
@Injectable()
export class Logger {
    constructor(private toastCtrl: ToastController) { }
    /**
     * 显示通知
     * @param msg 显示的内容
     * @param extro 将被保存到日志
     */
    info(msg: string, extro?: any) {
        this._show(msg, 'secondary');
        this.save(extro);
    }
    /**
     * 显示警告
     * @param msg 警告的内容
     * @param extro 将被保存到日志
     */
    warn(msg: string, extro?: any) {
        this._show(msg, 'danger');
        this.save(extro);
    }
    /**
     * 显示错误
     * @param msg 错误的内容
     * @param extro 将被保存到日志
     */
    error(msg: string, extro?: any) {
        this._show(msg, 'danger');
        this.save(extro);
    }
    /**
     * 保存日志
     * @param msg 错误的内容
     * @param extro 将被保存为本地日志
     */
    save(extro?: any) {
        if (!extro) return;
        console.log(JSON.stringify(extro));
    }
    private _show(msg: string, css: string) {
        let toast = this.toastCtrl.create({
            message: msg,
            duration: 3000,
            cssClass: css
        });
        toast.present();
    }
}
src/kl/core/services/messagebox.ts
New file
@@ -0,0 +1,109 @@
import { Injectable } from '@angular/core';
import { AlertController, AlertOptions, ToastController } from 'ionic-angular';
@Injectable()
export class MessageBox {
    constructor(private alertCtrl: AlertController, private toastCtrl: ToastController) { }
    /**
     * Toast提示框
     */
    toast(msg: string, css: string = '') {
        let toast = this.toastCtrl.create({
            message: msg,
            duration: 3000,
            cssClass: css
        });
        toast.present();
    }
    /** 提示框 */
    alert(msg: string) {
        let options: AlertOptions = {
            title: '',
            subTitle: msg,
            buttons: [
                {
                    text: '',
                },
                {
                    text: '确定',
                }
            ]
        };
        this._present(options);
    }
    /**
     * 确认框
     */
    confirm(
        msg: string,
        onOk: () => void,
        onCancel = () => { },
        okText = '确定',
        cancelText = ''
    ) {
        let options: AlertOptions = {
            title: '',
            message: msg,
            buttons: [
                {
                    text: cancelText,
                    role: 'cancel',
                    handler: onCancel
                },
                {
                    text: okText,
                    role: 'ok',
                    handler: onOk
                }
            ]
        };
        this._present(options);
    }
    /**
     * 输入框
     */
    prompt(
        msg: string,
        inputName: string,
        inputPlaceholer: string,
        onOk: (data: any) => void,
        onCancel = (data: any) => { },
        okText = '确定',
        cancelText = ''
    ) {
        this._present({
            title: '请输入',
            subTitle: msg,
            inputs: [
                {
                    name: inputName,
                    placeholder: inputPlaceholer
                }
            ],
            buttons: [
                {
                    text: cancelText,
                    role: 'cancel',
                    handler: onCancel
                },
                {
                    text: okText,
                    role: 'ok',
                    handler: onOk
                }
            ]
        });
    }
    private _present(options: AlertOptions) {
        options.cssClass = 'messagebox';
        let alert = this.alertCtrl.create(options);
        alert.present();
    }
}
src/kl/core/services/platform.service.ts
New file
@@ -0,0 +1,169 @@
import { Injectable } from '@angular/core';
import { Platform, ToastController, Nav, Tab } from 'ionic-angular';
import { TabsPage } from '../../../pages/tabs/tabs';
declare let WeixinJSBridge: any;
@Injectable()
export class PlatformService {
  /**
   * 用于判断返回键是否触发
   *
   * @private
   * @type {boolean}
   * @memberOf PlatformService
   */
  private _backButtonPressed: boolean = false;
  private _rootNav: Nav;
  /**
   * 在首页加载完成后,设置根导航组件
   *
   * @memberOf PlatformService
   */
  public set rootNav(nav: Nav) {
    this._rootNav = nav;
  }
  constructor(
    private platform: Platform,
    private toastCtrl: ToastController
  ) { }
  /**
   * 注册返回键事件
   *
   * @memberOf PlatformService
   */
  registerBackButton() {
    if (this.platform.is('android')) {
      this._registerAndroidExit();
    } else if (this._isWechat()) {
      // 注册返回事件
      this._registerBrowserBack();
    }
  }
  /**
   * 根据UserAgent判断是否微信浏览器
   *
   *
   * @memberOf PlatformService
   */
  private _isWechat() {
    if (this.__isWechat === undefined) {
      let ua = navigator.userAgent.toLowerCase();
      this.__isWechat = /micromessenger/.test(ua);
    }
    return this.__isWechat;
  }
  private __isWechat: boolean = undefined;
  /**
   * 为安卓注册双击返回退出app
   *
   * @private
   *
   * @memberOf MyApp
   */
  private _registerAndroidExit() {
    this.platform.registerBackButtonAction((): any => this._onBackButtonClicked, 101);
  }
  /**
   * 注册浏览器返回事件
   */
  private _registerBrowserBack() {
    window.addEventListener('popstate', () => {
      this._onBackButtonClicked();
    }, false);
  }
  /**
   * 双击退出提示框,这里使用Ionic2的ToastController
   *
   * @private
   *
   * @memberOf MyApp
   */
  private _showExit() {
    if (this._backButtonPressed) {
      // 当触发标志为true时,即2秒内双击返回按键则退出APP
      if (this._isWechat()) {
        WeixinJSBridge.call('closeWindow');
      } else {
        this.platform.exitApp();
      }
    } else {
      let toast = this.toastCtrl.create({
        message: '再按一次退出应用',
        duration: 2000,
        position: 'bottom'
      });
      toast.present();
      this._backButtonPressed = true;
      // 2秒内没有再次点击返回则将触发标志标记为false
      setTimeout(() => {
        this._backButtonPressed = false;
      }, 2000);
    }
  }
  /**
   * 响应返回键点击事件
   *
   * @private
   *
   * @memberOf MyApp
   */
  private _onBackButtonClicked() {
    if (this._isWechat()) {
      if (this._pop) { // 阻止pop()方法引用多次返回
        this._pop = false;
        return;
      }
    }
    let activeVC = this._rootNav.getActive();
    let page = activeVC.instance;
    if (!(page instanceof TabsPage)) {
      if (!this._rootNav.canGoBack()) {
        // 当前页面为tabs,退出APP
        return this._showExit();
      }
      // 当前页面为tabs的子页面,正常返回
      return this._rootNav.pop();
    }
    // 获取主Tab组件
    let tabs = page.tabs;
    let activeNav = tabs.getSelected();
    if (!this._canGoBack(activeNav)) {
      // 当前页面为tab栏,退出APP
      return this._showExit();
    }
    // 当前页面为tab栏的子页面,正常返回
    return activeNav.pop();
  }
  // 解决微信模式下,根页面在页面栈中出现两次而无法返回的问题
  private _canGoBack(tab: Tab): boolean {
    if (!this._isWechat()) {
      return tab.canGoBack();
    }
    const active = tab.getActive();
    if (!active) return false;
    const activeNav = active.getNav();
    if (!activeNav) return false;
    const previous = tab.getPrevious();
    if (!previous) return false;
    if (previous.id === active.id) return false;
    return true;
  }
  private _pop = false;
  pop(nav) {
    this._pop = true;
    nav.pop();
  }
}
src/kl/model/api.result.ts
New file
@@ -0,0 +1,5 @@
export class ApiResult<T> {
  Code: number;
  Message: string;
  Data: T;
}
src/kl/model/index.ts
New file
@@ -0,0 +1,2 @@
export * from './api.result';
export * from './user';
src/kl/model/user.ts
New file
@@ -0,0 +1,5 @@
export class User {
    Id: number;
    Name: string;
    Password: string;
}
src/kl/shared/directives/camera.directive.ts
New file
@@ -0,0 +1,104 @@
import { Directive, Input, Output, HostListener, EventEmitter } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
import { Camera, CameraOptions } from '@ionic-native/camera';
import { ActionSheetController } from 'ionic-angular';
/**
 * 拍照或者从相册中选取一张图片
 * 用法:<span [camera]="options" (completed)="onCameraCompleted($event)"><span>
 *
 * 问题:
 * 1. 安卓机上,completed的绑定方法里设置页面的img的src绑定属性无效,暂时使用js赋值的方式解决
 * onCameraCompleted(fileUrl:string) {
 *  (document.getElementById('img_test') as any).src=fileUrl;
 * }
 */
@Directive({ selector: '[camera]' })
export class CameraDirective {
  private _default: CameraOptions;
  private _options: CameraOptions;
  constructor(
    private actionSheetCtrl: ActionSheetController,
    private cameraPlugin: Camera
  ) {
    this._default = {
      quality: 100,
      destinationType: this.cameraPlugin.DestinationType.FILE_URI,
      sourceType: this.cameraPlugin.PictureSourceType.CAMERA,
      allowEdit: true,
      targetWidth: 100,
      targetHeight: 100,
      mediaType: this.cameraPlugin.MediaType.PICTURE,
      correctOrientation: true,
      saveToPhotoAlbum: false,
      cameraDirection: this.cameraPlugin.Direction.BACK
    };
  }
  @Output() completed = new EventEmitter<string>();
  @Input()
  set camera(options: CameraOptions) {
    this._options = this._extend(options, this._default);
  }
  @HostListener('click')
  onClick() {
    this._presentActionSheet()
      .subscribe(
      type => {
        this._options.sourceType = type;
        this.cameraPlugin.getPicture(this._options).then((imageData) => {
          this.completed.emit(imageData);
        }, (err) => {
          console.error('获取图片失败:' + JSON.stringify(err));
        });
      },
      error => {
        console.error('选择获取头像方式失败:' + error);
      });
  }
  private _extend<T>(left: T, right: T): T {
    if (!(left && left instanceof Object)) return right;
    if (right && right instanceof Object) {
      for (let k in right) {
        if (right[k] && right[k] !== left[k]) {
          left[k] = right[k];
        }
      }
    }
    return left;
  }
  private _presentActionSheet(): Observable<number> {
    let sub = new Subject<number>();
    let actionSheet = this.actionSheetCtrl.create({
      title: '选择头像',
      buttons: [
        {
          text: '拍照',
          role: '1',
          handler: () => sub.next(1)
        },
        {
          text: '相册',
          role: '0',
          handler: () => sub.next(0)
        },
        {
          text: '取消',
          role: 'cancel',
          handler: () => sub.error(-1)
        }
      ]
    });
    actionSheet.present();
    return sub.asObservable();
  }
}
src/kl/shared/index.ts
New file
@@ -0,0 +1,2 @@
export * from './shared.module';
export * from './pipes/localdate.pipe';
src/kl/shared/pipes/localdate.pipe.ts
New file
@@ -0,0 +1,27 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DatePipe } from '@angular/common';
/**
 * 1. 将UTC时间,改为本地时间:2017-1-1T12:01
 * 2. 将json时间,改为本地时间:‘/Date(1472608668000)/’
 */
@Pipe({
    name: 'date'
})
export class LocalDatePipe implements PipeTransform {
    constructor(private date: DatePipe) { }
    transform(value: any, pattern?: string): string {
        if (value instanceof Date) {
            return this.date.transform(value, pattern);
        }
        if (value.indexOf('T') >= 0) {
            return this.date.transform(value.replace('T', ' '), pattern);
        }
        let myRex = /^\/Date\(\d*\)\/$/;
        if (myRex.test(value)) {
            value = new Date(parseInt(value.replace(/^\/Date\(/, '').replace(/\)\/$/, ''), 10));
        }
        return this.date.transform(value, pattern);
    }
}
src/kl/shared/shared.module.ts
New file
@@ -0,0 +1,28 @@
import { NgModule } from '@angular/core';
import { CameraDirective } from './directives/camera.directive';
import { LocalDatePipe } from './pipes/localdate.pipe';
import { DatePipe } from '@angular/common';
const _PROVIDDERS = [
  DatePipe,
  LocalDatePipe
];
const _DECLARATIONS = [
  CameraDirective,
  LocalDatePipe
];
@NgModule({
  imports: [],
  exports: [
    ..._DECLARATIONS
  ],
  declarations: [
    ..._DECLARATIONS
  ],
  providers: [
    ..._PROVIDDERS
  ],
})
export class KlSharedModule { }
src/manifest.json
New file
@@ -0,0 +1,13 @@
{
  "name": "Ionic",
  "short_name": "Ionic",
  "start_url": "index.html",
  "display": "standalone",
  "icons": [{
    "src": "assets/imgs/logo.png",
    "sizes": "512x512",
    "type": "image/png"
  }],
  "background_color": "#4e8ef7",
  "theme_color": "#4e8ef7"
}
src/pages/access/access.module.ts
New file
@@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { LoginService } from './services';
@NgModule({
  imports: [],
  exports: [],
  declarations: [],
  providers: [LoginService],
})
export class AccessModule { }
src/pages/access/components/forgotpwd/forgotpwd.html
New file
@@ -0,0 +1,18 @@
<!--
  Generated template for the ForgotpwdPage page.
  See http://ionicframework.com/docs/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>
  <ion-navbar>
    <ion-title>forgotpwd</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
src/pages/access/components/forgotpwd/forgotpwd.module.ts
New file
@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ForgotpwdPage } from './forgotpwd';
@NgModule({
  declarations: [
    ForgotpwdPage,
  ],
  imports: [
    IonicPageModule.forChild(ForgotpwdPage),
  ],
})
export class ForgotpwdPageModule {}
src/pages/access/components/forgotpwd/forgotpwd.scss
New file
@@ -0,0 +1,3 @@
page-forgotpwd {
}
src/pages/access/components/forgotpwd/forgotpwd.ts
New file
@@ -0,0 +1,27 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
/**
 * Generated class for the ForgotpwdPage page.
 *
 * See http://ionicframework.com/docs/components/#navigation for more info
 * on Ionic pages and navigation.
 */
@IonicPage({
  name: 'access-forgorpwd'
})
@Component({
  selector: 'page-forgotpwd',
  templateUrl: 'forgotpwd.html',
})
export class ForgotpwdPage {
  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }
  ionViewDidLoad() {
    console.log('ionViewDidLoad ForgotpwdPage');
  }
}
src/pages/access/components/login/login.html
New file
@@ -0,0 +1,12 @@
<ion-header>
  <ion-navbar>
    <ion-title>login</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <button ion-button (click)="register()">Register</button>
</ion-content>
src/pages/access/components/login/login.module.ts
New file
@@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { LoginPage } from './login';
import { AccessModule } from '../../access.module';
@NgModule({
  declarations: [
    LoginPage,
  ],
  imports: [
    AccessModule,
    IonicPageModule.forChild(LoginPage),
  ],
})
export class LoginPageModule { }
src/pages/access/components/login/login.scss
New file
@@ -0,0 +1,3 @@
page-login {
}
src/pages/access/components/login/login.ts
New file
@@ -0,0 +1,27 @@
import { Component } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';
import { LoginService } from '../../services';
@IonicPage({
  name: 'access-login'
})
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
  constructor(
    public navCtrl: NavController,
    private service: LoginService) {
  }
  ionViewDidLoad() {
    this.service.login();
  }
  register() {
    this.navCtrl.push('access-register');
  }
}
src/pages/access/components/register/register.html
New file
@@ -0,0 +1,12 @@
<ion-header>
  <ion-navbar>
    <ion-title>register</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <button ion-button block (click)="back()">Back</button>
</ion-content>
src/pages/access/components/register/register.module.ts
New file
@@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { RegisterPage } from './register';
import { AccessModule } from '../../access.module';
@NgModule({
  declarations: [
    RegisterPage,
  ],
  imports: [
    AccessModule,
    IonicPageModule.forChild(RegisterPage),
  ],
})
export class RegisterPageModule { }
src/pages/access/components/register/register.scss
New file
@@ -0,0 +1,3 @@
page-register {
}
src/pages/access/components/register/register.ts
New file
@@ -0,0 +1,25 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { LoginService } from '../../services';
@IonicPage({
  name: 'access-register'
})
@Component({
  selector: 'page-register',
  templateUrl: 'register.html',
})
export class RegisterPage {
  constructor(public navCtrl: NavController, public navParams: NavParams, private service: LoginService) {
  }
  ionViewDidLoad() {
    this.service.register();
  }
  back() {
    this.navCtrl.pop();
  }
}
src/pages/access/services/index.ts
New file
@@ -0,0 +1 @@
export * from './login.service';
src/pages/access/services/login.service.ts
New file
@@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
@Injectable()
export class LoginService {
  constructor() { }
  login() {
    console.log('login for demo');
  }
  register() {
    console.log('register for demo');
  }
}
src/pages/tabs/about/about.html
New file
@@ -0,0 +1,12 @@
<ion-header>
  <ion-navbar>
    <ion-title>about</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
src/pages/tabs/about/about.module.ts
New file
@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { AboutPage } from './about';
@NgModule({
  declarations: [
    AboutPage,
  ],
  imports: [
    IonicPageModule.forChild(AboutPage),
  ],
})
export class AboutPageModule {}
src/pages/tabs/about/about.scss
New file
@@ -0,0 +1,3 @@
page-about {
}
src/pages/tabs/about/about.ts
New file
@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
@IonicPage({
  name: 'about'
})
@Component({
  selector: 'page-about',
  templateUrl: 'about.html',
})
export class AboutPage {
  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }
  ionViewDidLoad() {
    console.log('ionViewDidLoad AboutPage');
  }
}
src/pages/tabs/contact/contact.html
New file
@@ -0,0 +1,12 @@
<ion-header>
  <ion-navbar>
    <ion-title>contact</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
src/pages/tabs/contact/contact.module.ts
New file
@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ContactPage } from './contact';
@NgModule({
  declarations: [
    ContactPage,
  ],
  imports: [
    IonicPageModule.forChild(ContactPage),
  ],
})
export class ContactPageModule {}
src/pages/tabs/contact/contact.scss
New file
@@ -0,0 +1,3 @@
page-contact {
}
src/pages/tabs/contact/contact.ts
New file
@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
@IonicPage({
  name: 'contact'
})
@Component({
  selector: 'page-contact',
  templateUrl: 'contact.html',
})
export class ContactPage {
  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }
  ionViewDidLoad() {
    console.log('ionViewDidLoad ContactPage');
  }
}
src/pages/tabs/home/home.html
New file
@@ -0,0 +1,12 @@
<ion-header>
  <ion-navbar>
    <ion-title>home</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <button ion-button (click)="go()">Login</button>
</ion-content>
src/pages/tabs/home/home.module.ts
New file
@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HomePage } from './home';
@NgModule({
  declarations: [
    HomePage,
  ],
  imports: [
    IonicPageModule.forChild(HomePage),
  ],
})
export class HomePageModule {}
src/pages/tabs/home/home.scss
New file
@@ -0,0 +1,3 @@
page-home {
}
src/pages/tabs/home/home.ts
New file
@@ -0,0 +1,23 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
@IonicPage({
  name: 'home'
})
@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {
  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }
  ionViewDidLoad() {
    console.log('ionViewDidLoad HomePage');
  }
  go() {
    this.navCtrl.push('access-login');
  }
}
src/pages/tabs/tabs.html
New file
@@ -0,0 +1,5 @@
<ion-tabs #mainTabs>
  <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>
src/pages/tabs/tabs.module.ts
New file
@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TabsPage } from './tabs';
@NgModule({
  declarations: [
    TabsPage,
  ],
  imports: [
    IonicPageModule.forChild(TabsPage),
  ],
})
export class TabsPageModule { }
src/pages/tabs/tabs.ts
New file
@@ -0,0 +1,20 @@
import { Component, ViewChild } from '@angular/core';
import { Tabs, IonicPage } from 'ionic-angular';
@IonicPage({
  name: 'maintabs'
})
@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  tab1Root = 'home';
  tab2Root = 'about';
  tab3Root = 'contact';
  @ViewChild('mainTabs') tabs: Tabs;
  constructor() {
  }
}
src/service-worker.js
New file
@@ -0,0 +1,31 @@
/**
 * Check out https://googlechrome.github.io/sw-toolbox/ for
 * more info on how to use sw-toolbox to custom configure your service worker.
 */
'use strict';
importScripts('./build/sw-toolbox.js');
self.toolbox.options.cache = {
  name: 'ionic-cache'
};
// pre-cache our key assets
self.toolbox.precache(
  [
    './build/main.js',
    './build/vendor.js',
    './build/main.css',
    './build/polyfills.js',
    'index.html',
    'manifest.json'
  ]
);
// dynamically cache any other local assets
self.toolbox.router.any('/*', self.toolbox.cacheFirst);
// for any other requests go to the network, cache,
// and then only use that cached resource if your user goes offline
self.toolbox.router.default = self.toolbox.networkFirst;
src/theme/variables.scss
New file
@@ -0,0 +1,88 @@
// Ionic Variables and Theming. For more info, please see:
// http://ionicframework.com/docs/theming/
// Font path is used to include ionicons,
// roboto, and noto sans fonts
$font-path: "../assets/fonts";
// The app direction is used to include
// rtl styles in your app. For more info, please see:
// http://ionicframework.com/docs/theming/rtl-support/
$app-direction: ltr;
@import "ionic.globals";
// Shared Variables
// --------------------------------------------------
// To customize the look and feel of this app, you can override
// the Sass variables found in Ionic's source scss files.
// To view all the possible Ionic variables, see:
// http://ionicframework.com/docs/theming/overriding-ionic-variables/
// Named Color Variables
// --------------------------------------------------
// Named colors makes it easy to reuse colors on various components.
// It's highly recommended to change the default colors
// to match your app's branding. Ionic uses a Sass map of
// colors so you can add, rename and remove colors as needed.
// The "primary" color is the only required color in the map.
$colors: (
  primary:    #488aff,
  secondary:  #32db64,
  danger:     #f53d3d,
  light:      #f4f4f4,
  dark:       #222
);
// App iOS Variables
// --------------------------------------------------
// iOS only Sass variables can go here
// App Material Design Variables
// --------------------------------------------------
// Material Design only Sass variables can go here
// App Windows Variables
// --------------------------------------------------
// Windows only Sass variables can go here
// App Theme
// --------------------------------------------------
// Ionic apps can have different themes applied, which can
// then be future customized. This import comes last
// so that the above variables are used and Ionic's
// default are overridden.
@import "ionic.theme.default";
// Ionicons
// --------------------------------------------------
// The premium icon font for Ionic. For more info, please see:
// http://ionicframework.com/docs/ionicons/
@import "ionic.ionicons";
// Fonts
// --------------------------------------------------
@import "roboto";
@import "noto-sans";
tsconfig.json
New file
@@ -0,0 +1,27 @@
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es5",
    "baseUrl": "./src"
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}
tslint.json
New file
@@ -0,0 +1,24 @@
{
  "extends": "tslint-ionic-rules",
  "rules": {
    "no-duplicate-variable": true,
    "quotemark": [
      true,
      "single",
      "avoid-escape",
      "avoid-template"
    ],
    "no-unused-variable": [
      true
    ],
    "ordered-imports": {
      "options": {
        "import-sources-order": "any",
        "named-imports-order": "any"
      }
    }
  },
  "rulesDirectory": [
    "node_modules/tslint-eslint-rules/dist/rules"
  ]
}