Commit 3dd7e4c2 authored by van.chen's avatar van.chen

Initial commit

parents
# 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/
.ionic/
.sourcemaps/
.sass-cache/
.tmp/
.versions/
coverage/
www/
node_modules/
tmp/
temp/
platforms/
plugins/
plugins/android.json
plugins/ios.json
$RECYCLE.BIN/
.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate
{
"version": 1,
"defaultProject": "app",
"newProjectRoot": "projects",
"projects": {
"app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "v",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
},
{
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
}
],
"styles": [
"node_modules/ng-zorro-antd-mobile/src/ng-zorro-antd-mobile.min.css",
"src/assets/icon/iconfont.css",
{
"input": "src/theme/variables.scss"
},
{
"input": "src/global.scss"
}
],
"scripts": [
{
"input": "node_modules/mqtt/dist/mqtt.min.js"
}
],
"es5BrowserSupport": true
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
},
"ci": {
"progress": false
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
},
"ci": {
"progress": false
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [],
"scripts": [],
"assets": [
{
"glob": "favicon.ico",
"input": "src/",
"output": "/"
},
{
"glob": "**/*",
"input": "src/assets",
"output": "/assets"
}
]
},
"configurations": {
"ci": {
"progress": false,
"watch": false
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
"exclude": ["**/node_modules/**"]
}
},
"ionic-cordova-build": {
"builder": "@ionic/angular-toolkit:cordova-build",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
},
"ionic-cordova-serve": {
"builder": "@ionic/angular-toolkit:cordova-serve",
"options": {
"cordovaBuildTarget": "app:ionic-cordova-build",
"devServerTarget": "app:serve"
},
"configurations": {
"production": {
"cordovaBuildTarget": "app:ionic-cordova-build:production",
"devServerTarget": "app:serve:production"
}
}
}
}
},
"app-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "app:serve"
},
"configurations": {
"ci": {
"devServerTarget": "app:serve:ci"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": ["**/node_modules/**"]
}
}
}
}
},
"cli": {
"defaultCollection": "@ionic/angular-toolkit"
},
"schematics": {
"@ionic/angular-toolkit:component": {
"styleext": "scss"
},
"@ionic/angular-toolkit:page": {
"styleext": "scss"
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<widget id="online.hubeidiyi" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>牧场云</name>
<description>牧场物业管理系统</description>
<author email="van_chen@foxmail.com" href="http://hubeidiyi.online/">Van.chen</author>
<content src="index.html" />
<access origin="*" />
<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="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="19" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<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/icon.png" />
<icon density="mdpi" src="resources/android/icon/icon.png" />
<icon density="hdpi" src="resources/android/icon/icon.png" />
<icon density="xhdpi" src="resources/android/icon/icon.png" />
<icon density="xxhdpi" src="resources/android/icon/icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/icon.png" />
<splash density="land-ldpi" src="resources/android/splash/land.png" />
<splash density="land-mdpi" src="resources/android/splash/land.png" />
<splash density="land-hdpi" src="resources/android/splash/land.png" />
<splash density="land-xhdpi" src="resources/android/splash/land.png" />
<splash density="land-xxhdpi" src="resources/android/splash/land.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/land.png" />
<splash density="port-ldpi" src="resources/android/splash/port.png" />
<splash density="port-mdpi" src="resources/android/splash/port.png" />
<splash density="port-hdpi" src="resources/android/splash/port.png" />
<splash density="port-xhdpi" src="resources/android/splash/port.png" />
<splash density="port-xxhdpi" src="resources/android/splash/port.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/port.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" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<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" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="cordova-plugin-ionic-webview" spec="^3.0.0" />
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
<plugin name="cordova-plugin-appminimize" spec="1.0.1" />
<engine name="android" spec="7.1.4" />
<engine name="ios" spec="~4.5.5" />
</widget>
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
import { AppPage } from './app.po';
describe('new App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should be blank', () => {
page.navigateTo();
expect(page.getParagraphText()).toContain('The world is your oyster.');
});
});
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.deepCss('app-root ion-content')).getText();
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
{
"name": "muChang",
"integrations": {
"cordova": {}
},
"type": "angular"
}
{
"name": "Blank Starter",
"baseref": "master",
"tarignore": [
"node_modules",
"package-lock.json",
"www"
],
"scripts": {
"test": "npm run lint && npm run ng -- build --configuration=ci && npm run ng -- build --prod --progress=false && npm run ng -- test --configuration=ci && npm run ng -- e2e --configuration=ci && npm run ng -- g pg my-page --dry-run && npm run ng -- g c my-component --dry-run"
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "muChang",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "https://ionicframework.com/",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.2.2",
"@angular/common": "^7.2.2",
"@angular/core": "^7.2.2",
"@angular/forms": "^7.2.2",
"@angular/http": "^7.2.2",
"@angular/platform-browser": "^7.2.2",
"@angular/platform-browser-dynamic": "^7.2.2",
"@angular/router": "^7.2.2",
"@ionic-native/app-minimize": "^5.5.0",
"@ionic-native/core": "^5.0.0",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
"@ionic/angular": "^4.1.0",
"cordova-android": "7.1.4",
"cordova-ios": "~4.5.5",
"cordova-plugin-appminimize": "1.0.1",
"cordova-plugin-device": "2.0.2",
"cordova-plugin-ionic-keyboard": "^2.0.5",
"cordova-plugin-ionic-webview": "^3.0.0",
"cordova-plugin-screen-orientation": "^3.0.1",
"cordova-plugin-splashscreen": "5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"cordova-plugin-whitelist": "^1.3.3",
"core-js": "^2.5.4",
"es6-promise-plugin": "^4.2.2",
"mqtt": "^2.18.8",
"ng-zorro-antd-mobile": "^0.11.9",
"rxjs": "~6.3.3",
"zone.js": "~0.8.29"
},
"devDependencies": {
"@angular-devkit/architect": "~0.12.3",
"@angular-devkit/build-angular": "^0.13.8",
"@angular-devkit/core": "~7.2.3",
"@angular-devkit/schematics": "~7.2.3",
"@angular/cli": "~7.3.1",
"@angular/compiler": "~7.2.2",
"@angular/compiler-cli": "~7.2.2",
"@angular/language-service": "~7.2.2",
"@ionic/angular-toolkit": "~1.4.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~10.14.2",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.1.4",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~8.0.0",
"tslint": "~5.12.0",
"typescript": "~3.1.6"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-appminimize": {},
"cordova-plugin-screen-orientation": {}
},
"platforms": [
"android",
"ios"
]
}
}
\ No newline at end of file
These are Cordova resources. You can replace icon.png and splash.png and run
`ionic cordova resources` to generate custom icons and splash screens for your
app. See `ionic cordova resources --help` for details.
Cordova reference documentation:
- Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
- Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
// 引入 angular 动画组件
import {trigger, style, state, transition, animate} from '@angular/animations';
export const fadeIn = trigger('fade', [
transition('void => *', [
style({opacity: 0}),
animate('1000ms ease-in', style({opacity: 1}))
]),
transition('* => void', [
animate('1000ms ease-in', style({opacity: 0}))
])
]);
import {trigger, style, state, transition, animate} from '@angular/animations';
export const toLeft = trigger('toLeft', [
state('toLeft', style({
'transform': 'translateX(-80px)'
})),
state('backLeft', style({
'transform': 'translateX(0)'
})),
transition('toLeft => backLeft', animate('150ms')),
transition('backLeft => toLeft', animate('150ms'))
]);
import {trigger, style, state, transition, animate} from '@angular/animations';
export const toRight = trigger('toRight', [
state('toRight', style({
'transform': 'translateX(80px)'
})),
state('backRight', style({
'transform': 'translateX(0)'
})),
transition('toRight => backRight', animate('150ms')),
transition('backRight => toRight', animate('150ms'))
]);
import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
import {HomePage} from './home/home.page';
import {EastPage} from './east/east.page';
import {LoginPage} from './login/login.page';
import {Auth} from './service/auth';
import {WestPage} from './west/west.component';
const routes: Routes = [
{
path: '',
canActivateChild: [Auth],
children: [
{path: '', redirectTo: 'home', pathMatch: 'full'},
{path: 'home', component: HomePage},
{path: 'east', component: EastPage},
{path: 'west', component: WestPage}
]
},
{path: 'login', component: LoginPage}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {preloadingStrategy: PreloadAllModules})
],
exports: [RouterModule]
})
export class AppRoutingModule {
}
<ion-app>
<ion-router-outlet></ion-router-outlet>
</ion-app>
import {Component, AfterViewInit} from '@angular/core';
import {Platform} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {Router, NavigationEnd} from '@angular/router';
import { AppMinimize } from '@ionic-native/app-minimize/ngx';
declare var screen: any;
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent implements AfterViewInit {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private appMinimize: AppMinimize,
private router: Router
) {
this.initializeApp();
}
private backBtnPressed;
private url;
private flag = 0;
initializeApp() {
this.platform.ready().then(() => {
this.flag++;
this.registerBackButtonAction(); // 注册返回按键事件
this.platform.resume.subscribe(); // 弹出框
this.initRouterListen();
screen.orientation.lock('portrait');
if (this.flag === 2) {
this.statusBar.styleLightContent();
this.statusBar.backgroundColorByHexString('#000000');
this.statusBar.show();
this.statusBar.overlaysWebView(false);
this.splashScreen.hide();
}
});
}
ngAfterViewInit(): void {
this.flag++;
if (this.flag === 2) {
this.statusBar.styleLightContent();
this.statusBar.backgroundColorByHexString('#000000');
this.statusBar.show();
this.statusBar.overlaysWebView(false);
this.splashScreen.hide();
}
}
initRouterListen() {
this.router.events.subscribe(event => { // 需要放到最后一个执行
if (event instanceof NavigationEnd) {
this.url = window.location.pathname;
const x = <HTMLBodyElement>document.getElementsByTagName('v' + window.location.pathname.replace(/\//, '-'))[0];
x.style.visibility = 'visible';
}
});
}
registerBackButtonAction() {
this.platform.backButton.subscribe(() => {
const x = <HTMLBodyElement>document.getElementsByTagName('v' + window.location.pathname.replace(/\//, '-'))[0];
x.style.visibility = 'hidden';
if (this.url === '/home' || this.url === '/login') {
if (this.backBtnPressed) {
this.appMinimize.minimize();
this.backBtnPressed = false;
window.history.pushState('forward', null, this.url);
return;
} else {
this.backBtnPressed = true;
setTimeout(() => this.backBtnPressed = false, 2000);
return;
}
} else {
this.backBtnPressed = true;
setTimeout(() => this.backBtnPressed = false, 2000);
return;
}
});
}
}
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {RouteReuseStrategy} from '@angular/router';
import {HttpClientModule} from '@angular/common/http';
import {IonicModule, IonicRouteStrategy} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {FormsModule} from '@angular/forms';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {NgZorroAntdMobileModule} from 'ng-zorro-antd-mobile';
import {AppComponent} from './app.component';
import {AppRoutingModule} from './app-routing.module';
import {SubTitleComponent} from './components/sub-title/sub-title.component';
import {AppMinimize} from '@ionic-native/app-minimize/ngx';
import {HomePage} from './home/home.page';
import {EastPage} from './east/east.page';
import {LoginPage} from './login/login.page';
import {WestPage} from './west/west.component';
import {Api} from './service/api';
import {Auth} from './service/auth';
import {Http} from './service/http';
import {Transfer} from './service/transfer';
import {AuthInterceptor} from './service/token';
@NgModule({
declarations: [AppComponent, SubTitleComponent, HomePage, EastPage, LoginPage, WestPage],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
NgZorroAntdMobileModule
],
providers: [
StatusBar,
SplashScreen,
{provide: RouteReuseStrategy, useClass: IonicRouteStrategy},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},
AppMinimize,
Api,
Auth,
Http,
Transfer
],
bootstrap: [AppComponent]
})
export class AppModule {
}
import {Component, Input, OnInit} from '@angular/core';
@Component({
selector: 'v-sub-title',
template: `<div class="subTitle">{{title}}</div>`,
styles: [`
.subTitle {
font-size: 16px;
padding-left: 5px;
border-left: 5px solid #28c9bd;
line-height: 25px;
margin-bottom: 5px;
}
`]
})
export class SubTitleComponent implements OnInit {
@Input() title: string;
constructor() {
}
ngOnInit() {
}
}
<div class="mainCon">
<Navbar [leftContent]="icon"
(onLeftClick)="onLeftClick()"
style="background-color: #28c9bd"
>
东中转池控制
</Navbar>
<div class="topPart">
<!--<div class="online" *ngFor="let one of items">-->
<!--<div class="label">{{one.label}}</div>-->
<!--<div class="btn">-->
<!--<ion-toggle mode="md" color="primary" (ionChange)="toggle(one.type, $event)"></ion-toggle>-->
<!--</div>-->
<!--</div>-->
<ListItem multipleLine>
当前液位:
<div class="process">
<div class="inlineProcess" [ngStyle]="{width: proc + '%'}"
[ngClass]="{'orange': proc < 4 && proc > 3.5, 'red': proc < 3.5}">
</div>
</div>
{{yewei}}m
</ListItem>
<ListItem multipleLine>
当前温度:
<div style="display: inline-block;margin-left: calc(100% - 135px);vertical-align: middle">
{{temp.value}}℃
</div>
</ListItem>
<ListItem multipleLine [extra]="s1">
南水
</ListItem>
<ListItem multipleLine [extra]="s2">
北水
</ListItem>
</div>
<div class="bottomPart">
<ListItem multipleLine [extra]="s3">
一号搅拌器
</ListItem>
<ListItem multipleLine [extra]="s4">
二号搅拌器
</ListItem>
<!--<ListItem multipleLine [extra]="s5">-->
<!--三号搅拌器-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s6">-->
<!--四号搅拌器-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s7">-->
<!--一号泵-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s8">-->
<!--二号泵-->
<!--</ListItem>-->
</div>
</div>
<ng-template #icon>
<span class="vo v-back"></span>
</ng-template>
<ng-template #s1>
<Switch [platform]="'android'" [disabled]="true" [color]="color[0]" (ngModelChange)="toggle(0)"
[(ngModel)]="value[0]"></Switch>
</ng-template>
<ng-template #s2>
<Switch [platform]="'android'" [disabled]="true" [color]="color[1]" (ngModelChange)="toggle(1)"
[(ngModel)]="value[1]"></Switch>
</ng-template>
<ng-template #s3>
<Switch [platform]="'android'" [disabled]="true" [color]="color[2]" (ngModelChange)="toggle(2)"
[(ngModel)]="value[2]"></Switch>
</ng-template>
<ng-template #s4>
<Switch [platform]="'android'" [disabled]="true" [color]="color[3]" (ngModelChange)="toggle(3)"
[(ngModel)]="value[3]"></Switch>
</ng-template>
<ng-template #s5>
<Switch [platform]="'android'" [disabled]="true" [color]="color[4]" (ngModelChange)="toggle(4)"
[(ngModel)]="value[4]"></Switch>
</ng-template>
<ng-template #s6>
<Switch [platform]="'android'" [disabled]="true" [color]="color[5]" (ngModelChange)="toggle(5)"
[(ngModel)]="value[5]"></Switch>
</ng-template>
<ng-template #s7>
<Switch [platform]="'android'" [disabled]="true" [color]="color[6]" (ngModelChange)="toggle(6)"
[(ngModel)]="value[6]"></Switch>
</ng-template>
<ng-template #s8>
<Switch [platform]="'android'" [disabled]="true" [color]="color[7]" (ngModelChange)="toggle(7)"
[(ngModel)]="value[7]"></Switch>
</ng-template>
// 因为switch左侧有52px的留白,在这52px的地方
// 点击会发生颜色变化但是switch的值没变化的情况
// 这样处理的原因是这个控件的color属性在刚进来
// 的时候哪怕是false也会显示这个颜色,但是按两次
// 就好了,于是我把颜色用点击事件单独拎出来处理了
// 如果后面版本升级,这个问题被修复了你可以直接用
// color属性,而不用这么麻烦
Switch {
margin-left: 52px;
}
.process {
width: calc(100% - 160px);
display: inline-block;
margin: 0 10px;
background-color: #cccccc;
height: 20px;
vertical-align: middle;
position: relative;
border-radius: 10px;
}
.inlineProcess {
display: inline-block;
border-radius: 10px;
background-color: #2ecc71;
height: 20px;
}
.orange {
background-color: #ffa847;
}
.red {
background-color: #f04844;
}
import {Component, OnInit} from '@angular/core';
import {Transfer} from '../service/transfer';
import {Api} from '../service/api';
@Component({
selector: 'v-east',
templateUrl: './east.page.html',
styleUrls: ['./east.page.scss'],
})
export class EastPage implements OnInit {
// 此处处理color原因详见该目录下scss文件
color = ['#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6'];
value = [false, false, false, false, false, false, false];
yewei = '';
temp: any = '';
proc = 0;
constructor(private tf: Transfer, private api: Api) {
}
ngOnInit() {
this.getData();
}
toggle(index) {
this.color[index] = !this.value[index] ? '#28c9bd' : '#a7aaa6';
this.color = [...this.color];
}
onLeftClick() {
this.tf.transfer({url: '/home'});
}
getData() {
// 东中转池 19040001 0号通道为温度
this.api.data.getRealData([{deviceNo: '92489110027112448'}, (data) => {
if (data && data.constructor === Array) {
if (data.length > 0) {
this.temp = data[0];
}
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
// 东中转池 19040003 0号通道为液位
this.api.data.getRealData([{deviceNo: '92489569504727040'}, (data) => {
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0].value) {
this.yewei = Number(data[0].value).toFixed(2);
this.proc = Number(data[0].value) * 100 / 6.5;
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
// 东中转池 19040004 0,1号通道为南水 2,3号通道为北水
this.api.data.getRealData([{deviceNo: '92489787927302144'}, (data) => {
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0] && data[1]) {
this.value[0] = !!(data[0].value === '1.0' && data[1].value === '1.0');
this.color[0] = (data[0].value === '1.0' && data[1].value === '1.0') ? '#28c9bd' : this.color[0];
}
if (data[2] && data[3]) {
this.value[1] = !!(data[2].value === '1.0' && data[3].value === '1.0');
this.color[1] = (data[2].value === '1.0' && data[3].value === '1.0') ? '#28c9bd' : this.color[1];
}
}
this.value = [...this.value];
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
// 东中转池 19040005 0,1号通道为1号搅拌池 2,3号通道为2号搅拌池
this.api.data.getRealData([{deviceNo: '92489949865185280'}, (data) => {
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0] && data[1]) {
this.value[2] = !!(data[0].value === '1.0' && data[1].value === '1.0');
this.color[2] = (data[0].value === '1.0' && data[1].value === '1.0') ? '#28c9bd' : this.color[2];
}
if (data[2] && data[3]) {
this.value[3] = !!(data[2].value === '1.0' && data[3].value === '1.0');
this.color[3] = (data[2].value === '1.0' && data[3].value === '1.0') ? '#28c9bd' : this.color[3];
}
}
this.value = [...this.value];
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
}
}
<div class="mainCon">
<ion-slides style="width: 100%;height: 200px;" mode="ios"
[options]="lunbo" #slide (ionSlideTouchEnd)="slideDidChange()">
<ion-slide class="slideCon" *ngFor="let one of imgs">
<div class="inBox">
<img [src]="'../../../assets/lunbo/' + one">
</div>
</ion-slide>
</ion-slides>
<!--<div class="one" *ngFor="let one of alarms, let i = index">-->
<!--<NoticeBar [option]="{'content': (i + 1) + '. ' + one, 'font': '14px'}">-->
<!--</NoticeBar>-->
<!--</div>-->
<!--<div class="alarmPart">-->
<!--<v-sub-title title="消息提醒"></v-sub-title>-->
<!--<div class="one" *ngFor="let one of alarms, let i = index" [ngClass]="{'redColor': i === 0}">{{i + 1}}-->
<!--.{{one}}</div>-->
<!--</div>-->
<div class="seePart">
<v-sub-title title="监测信息"></v-sub-title>
<div class="item" *ngFor="let item of items">
<div class="left">{{item.name}}</div>
<div class="right">
<div class="block1">液位: {{item.yewei}}m</div>
<div class="block2 canClick" (click)="toControl(item.url)">控制</div>
<div class="gekai"></div>
<div class="block3" *ngIf="item.isNB">
南水 <span [ngClass]="{'sucCir': item.nan, 'errCir': !item.nan}"></span>&nbsp;&nbsp;
北水 <span [ngClass]="{'sucCir': item.bei, 'errCir': !item.bei}"></span>
<!--状态: {{item.nan === 1 ? '开' : '关'}}/{{item.bei === 1 ? '开' : '关'}}-->
</div>
<!--<div class="block4">设备状态 <span [ngClass]="{'sucCir': item.state, 'errCir': !item.state}"></span></div>-->
</div>
</div>
</div>
</div>
.inBox {
width: 100%;
height: 100%;
img {
width: 100% !important;
height: 100%;
}
}
.alarmPart {
padding: 5px;
line-height: 20px;
font-size: 14px;
}
.seePart {
padding: 5px 5px 0 5px;
}
.slideCon {
background-color: lavender;
}
.redColor {
color: red;
}
.left {
width: 25%;
text-align: center;
line-height: 60px;
font-size: 16px;
border-right: 1px solid #28c9bd;
background-color: #28c9bd;
color: #ffffff;
}
.right {
font-size: 14px;
width: 70%;
padding-left: 10px;
}
.left, .right {
display: inline-block;
vertical-align: middle;
}
.item {
border: 2px solid #28c9bd;
border-radius: 5px;
margin-bottom: 5px;
}
.block1, .block2, .block3, .block4 {
display: inline-block;
}
.block1 {
width: calc(100% - 50px);
text-align: left;
line-height: 20px;
}
.block2 {
width: 50px;
text-align: right;
}
.block3 {
width: calc(100% - 78px);
text-align: left;
}
.block4 {
width: 78px;
text-align: right;
}
.gekai {
height: 18px;
width: 100%;
}
import {Component, OnInit, OnDestroy, ViewChild} from '@angular/core';
import {Transfer} from '../service/transfer';
import {ActivatedRoute} from '@angular/router';
import {Api} from '../service/api';
declare var mqtt: any;
@Component({
selector: 'v-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit, OnDestroy {
constructor(private tf: Transfer, private ac: ActivatedRoute, private api: Api) {}
@ViewChild('slide') slide;
// client;
// topic;
// private options = {
// keepalive: 10,
// clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
// protocolId: 'MQTT',
// protocolVersion: 4,
// clean: false,
// connectTimeout: 60000,
// username: 'pasture',
// password: 'Pasture37774020',
// };
imgs = ['1.jpg', '2.jpg', '3.jpg'];
lunbo = {
speed: 1000,
allowTouchMove: true,
effect: 'flip',
autoplay: {
delay: 2000,
},
loop: true,
spaceBetween: 0
};
alarms = [];
items = [{
name: '东中转池',
yewei: '',
nan: false,
bei: false,
isNB: 1,
url: 'east'
}, {
name: '西中转池',
yewei: '',
nan: false,
bei: false,
isNB: 1,
url: 'west'
}
// , {
// name: '沉砂池',
// yewei: 12,
// nan: 1,
// bei: 0,
// isNB: 0,
// state: 1,
// url: 'east'
// }, {
// name: '八角池',
// yewei: 12,
// nan: 1,
// bei: 0,
// isNB: 0,
// state: 1,
// url: 'east'
// }, {
// name: '匀浆池',
// yewei: 12,
// nan: 1,
// bei: 0,
// isNB: 0,
// state: 1,
// url: 'east'
// }, {
// name: '分离池',
// yewei: 12,
// nan: 1,
// bei: 0,
// isNB: 0,
// state: 1,
// url: 'east'
// }, {
// name: '发酵池',
// yewei: 12,
// nan: 1,
// isNB: 0,
// bei: 0,
// state: 1,
// url: 'east'
// }, {
// name: '出料',
// yewei: 12,
// nan: 1,
// isNB: 0,
// bei: 0,
// state: 1,
// url: 'east'
// }
];
ngOnInit(): void {
this.init();
this.ac.queryParams.subscribe((e) => {
this.ionViewWillEnter();
});
}
// ionic的生命周期函数
ionViewWillEnter() {
this.slideDidChange();
this.getData();
}
ngOnDestroy(): void {
this.endMqtt();
}
init() {
this.initMqtt();
this.getData();
}
getData() {
const dong = {
name: '东中转池',
yewei: '',
nan: false,
bei: false,
isNB: 1,
url: 'east'
};
const xi = {
name: '西中转池',
yewei: '',
nan: false,
bei: false,
isNB: 1,
url: 'west'
};
let flagd = 0, flagx = 0;
// 东中转池 19040003 0号通道为液位
this.api.data.getRealData([{deviceNo: '92489569504727040'}, (data) => {
flagd ++;
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0].value) {
dong.yewei = Number(data[0].value).toFixed(2);
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
if (flagd === 2) {
this.items[0] = dong;
this.items = [...this.items];
}
}]);
// 东中转池 19040004 0,1号通道为南水 2,3号通道为北水
this.api.data.getRealData([{deviceNo: '92489787927302144'}, (data) => {
flagd ++;
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0] && data[1]) {
dong.nan = !!(data[0].value === '1.0' && data[1].value === '1.0');
}
if (data[2] && data[3]) {
dong.bei = !!(data[2].value === '1.0' && data[3].value === '1.0');
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
if (flagd === 2) {
this.items[0] = dong;
this.items = [...this.items];
}
}]);
// 西中转池 19040006 0号通道为液位
this.api.data.getRealData([{deviceNo: '92490138428510208'}, (data) => {
flagx ++;
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0].value) {
xi.yewei = Number(data[0].value).toFixed(2);
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
if (flagx === 2) {
this.items[1] = xi;
this.items = [...this.items];
}
}]);
// 西中转池 19040008 0,1号通道为1号搅拌池 2,3号通道为2号搅拌池
this.api.data.getRealData([{deviceNo: '92490309405118464'}, (data) => {
flagx ++;
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0] && data[1]) {
xi.nan = !!(data[0].value === '1.0' && data[1].value === '1.0');
}
if (data[2] && data[3]) {
xi.bei = !!(data[2].value === '1.0' && data[3].value === '1.0');
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
if (flagx === 2) {
this.items[1] = xi;
this.items = [...this.items];
}
}]);
}
initMqtt() {
// this.client = mqtt.connect('ws://120.27.235.39:8083/mqtt', this.options);
// this.topic = 'topic/hello';
//
// this.client.on('connect', () => {
// this.msg = 'mqtt连接成功';
// this.client.subscribe(this.topic);
// this.client.on('message', (a, b) => {
// console.log(a, b);
// });
// });
}
endMqtt() {
// this.client.unsubscribe(this.topic);
// this.client.disconnect();
}
slideDidChange() {
this.slide.startAutoplay();
}
toControl(url) {
this.tf.transfer({
url: '/' + url,
query: '',
hash: ''
});
}
}
<div class="loginPage" @fade>
<div class="topBar">
<div class="title">牧场云</div>
<div class="subTitle">智能·便捷·高效</div>
</div>
<div class="mainBar">
<div class="inputLine" style="margin-top: 15px">
<div class="labelForInput"><i class="vo v-user"></i></div>
<ion-input type="text" [(ngModel)]="req.name" mode="ios" class="input"></ion-input>
</div>
<div class="inputLine">
<div class="labelForInput"><i class="vo v-mima"></i></div>
<ion-input type="password" [(ngModel)]="req.ps" mode="ios" class="input"></ion-input>
</div>
<!--<ion-button mode="ios" color="primary" style="background-color: #28c9bd;color: #ffffff;border: 1px solid #ffffff;" expand="block" class="loginBtn" (click)="login()">Login</ion-button>-->
<div Button class="loginBtn" [disabled]="!req.ps || !req.name" (click)="login()" [type]="'primary'" style="letter-spacing: 2px">立即登录</div>
</div>
</div>
.loginPage{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
text-align: center;
background: url("../../assets/bg/bg3.jpg");
background-size: cover;
}
.topBar{
height: calc(5% + 100px);
padding: 5%;
}
.imgPart{
height: 70%;
//width: calc(100% - 180px);
margin: 0 auto;
font-size: 50px;
line-height: 2;
}
.mainBar {
margin: 0 20px;
background-color: rgba(255,255,255,0.95);
padding: 10px 25px;
border-radius: 7px;
}
.inputLine {
margin: 8% 1%;
height: 40px;
border-bottom: 1px solid #ccc;
}
.labelForInput {
width: 60px;
display: inline-block;
height: 40px;
line-height: 40px;
vertical-align: top;
}
i.vo.v-mima, i.vo.v-user {
font-size: 25px;
color: #777;
}
.input {
width: calc(100% - 60px);
display: inline-block;
text-align: left;
height: 40px;
line-height: 40px;
}
.loginBtn {
margin: 8% 0 0 0;
height: 45px;
line-height: 40px;
background-color: #28c9bd;
color: #ffffff;
border: 2px solid #ffffff !important;
border-radius: 25px;
}
.topBar {
text-align: center;
.title {
margin-top: 5%;
line-height: 75px;
height: 60px;
font-size: 30px;
color: #fff;
letter-spacing: 5px;
}
.subTitle {
font-size: 20px;
letter-spacing: 3px;
height: 40px;
line-height: 30px;
color: rgba(255, 255, 255, 0.85);
}
}
//@media all and (orientation : landscape) {
// .loginPage{
// padding: 0;
// background: url("../../assets/bg/bg3.jpg");
// background-size: cover;
// }
//
// .topBar{
// height: 0;
// padding: 0;
// }
//
// .mainBar{
// padding: 20px;
// margin-top: 5%;
// }
//
// .imgPart{
// line-height: 1.3;
// }
//
// .loginBtn {
// margin: 2% 0 0 0;
// }
// .title{
// margin-top: 1%;
// }
//}
import {Component, OnInit} from '@angular/core';
import {Transfer} from '../service/transfer';
import {Api} from '../service/api';
import {fadeIn} from '../animations/fade-in';
@Component({
selector: 'v-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
animations: [fadeIn]
})
export class LoginPage implements OnInit {
req = {name: '', ps: ''};
constructor(private tf: Transfer, private api: Api) {
}
ngOnInit() {
}
login() {
const req = {
userName: this.req.name,
password: this.req.ps
};
this.api.login.loginForToken([req, (data) => {
if (data.code === 1) {
window.localStorage.setItem('token', data.message);
const query = {refresh: new Date().getTime()};
this.tf.transfer({
url: '/home',
query: query,
hash: ''
});
} else {
this.api.presentMsgToast(data && data.message ? data.message : '登录失败');
}
}]);
}
}
import { Http } from './http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { environment } from '../../environments/environment';
import { ToastController } from '@ionic/angular';
@Injectable()
export class Api {
constructor(private http: Http, private router: Router, private toast: ToastController) {}
tokenLoseflag = 0;
public url = environment.url;
public login = {
loginForToken: (data) => this.trans('post', '/system/login/loginForToken', data),
logout: (data) => this.trans('get', '/system/login/logout', data),
};
public data = {
getRealData: (data) => this.trans('post', '/data/getRealData', data),
};
private trans(type, addr, data) {
this.sendHttpReq(type, addr, data[0], data[1], data[2], data[3]);
}
private sendHttpReq(type, addr, reqB, next, error, complete) {
let nextFunc;
if (addr === '/login/dologin') {
nextFunc = (data: any) => {
next(data);
};
} else {
nextFunc = (data: any) => {
if (this.http.handleToken(data)) {
next(data);
} else {
if (!this.tokenLoseflag) {
this.presentMsgToast('登录失效,请重新登陆');
this.http.toLoginPage(2000);
this.tokenLoseflag = 1;
setTimeout(() => {
this.tokenLoseflag = 0;
}, 5000);
}
}
};
}
if (!error) {
error = (err) => {
let data;
if (err && err.error && err.error.status) {
if (err.error.status === 401) {
data = {code: 0, message: '用户尚未登录'};
this.router.navigate(['/extra']);
} else {
data = {code: 0, message: '服务器异常'};
}
} else {
data = {code: 0, message: '服务器异常'};
}
next(data);
};
}
if (type === 'get') {
this.http.get(this.url + addr, nextFunc, error, complete);
} else {
this.http.post(this.url + addr, reqB, nextFunc, error, complete);
}
}
async presentMsgToast(msg) {
const toast = await this.toast.create({
message: msg,
duration: 2000,
mode: 'ios',
cssClass: 'msgToast'
});
toast.present();
}
async presentBtnToast(msg, btn, position) {
const toast = await this.toast.create({
message: msg,
showCloseButton: true,
position: position,
closeButtonText: btn,
mode: 'ios',
cssClass: 'btnToast'
});
toast.present();
}
}
import {Injectable, OnInit} from '@angular/core';
import {CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {Transfer} from './transfer';
@Injectable()
export class Auth implements CanActivateChild, OnInit {
public login = false;
constructor(private transfer: Transfer) {
}
ngOnInit() {
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (window.localStorage.getItem('token')) {
return true;
} else {
this.transfer.transfer({
url: '/login',
query: '',
hash: ''
});
return false;
}
}
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Response } from '@angular/http';
import { Subscription } from 'rxjs';
import { Transfer } from './transfer';
@Injectable()
export class Http {
constructor(private http: HttpClient, private tf: Transfer) {
this.subs = new Array<Subscription>();
}
private subs: Subscription[];
private header = new HttpHeaders().append('Content-Type', 'application/json').append('Access-Control-Allow-Origin', '*');
postParamObj = {
withCredentials: true,
headers: this.header
};
getParamObj = {
withCredentials: true,
};
// 封装统一的 http 请求方法
get(url: string,
next?: (value: Response) => void,
error?: (error: any) => void,
complete?: () => void): void {
if (url.indexOf('?') > -1) {
// 有参数
url += `&dateStamp=${(new Date).getTime()}`;
} else {
// 无参数
url += `?dateStamp=${(new Date).getTime()}`;
}
this.subs.push(this.http.get(`${url}`, this.getParamObj).subscribe(next, error, complete));
}
post(url: string,
data: any,
next?: (value: Response) => void,
error?: (error: any) => void,
complete?: () => void): void {
if (url.indexOf('?') > -1) {
// 有参数
url += `&dateStamp=${(new Date).getTime()}`;
} else {
// 无参数
url += `?dateStamp=${(new Date).getTime()}`;
}
this.subs.push(this.http.post(url, data, this.postParamObj).subscribe(next, error, complete));
}
// token 失效处理函数
handleToken = (value) => {
if (value && value.code && value.code === 2) {
return false;
} else {
return true;
}
}
// 跳转登录页面
toLoginPage(time) {
window.setTimeout(() => {
this.tf.transfer({url: '/login'});
}, time);
}
}
import {Injectable, OnInit} from '@angular/core';
import {HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
@Injectable()
export class AuthInterceptor implements HttpInterceptor, OnInit {
constructor() {
}
token: string;
ngOnInit() {
}
intercept(req: HttpRequest<any>, next: HttpHandler) {
// 这里的拦截了所有的请求,并且加上了token
// 每次都获取最新的token
this.token = window.localStorage.getItem('token') || '';
const authReq = req.clone({headers: req.headers.set('AccountToken', this.token)});
return next.handle(authReq);
}
}
import { Router } from '@angular/router';
import { Injectable } from '@angular/core';
@Injectable()
export class Transfer {
constructor(private router: Router) {}
transfer(req) {
// 此处为ionic4路由跳转的时候不清空之前的页面组件造成的页面短暂交叠
// ionic4在发生路由跳转的时候是先进行新组件的加载再进行旧组件的隐藏
// 我没有找到相关的api以及解决办法,如果后面的人找到了的话麻烦将这个麻烦的方法给解决掉
if (document.getElementsByTagName('v' + req.url.replace(/\//, '-')).length > 0) {
const y = <HTMLBodyElement>document.getElementsByTagName('v' + req.url.replace(/\//, '-'))[0];
y.style.visibility = 'visible';
}
req.query = req.query ? req.query : {};
req.query.refresh = + new Date();
this.router.navigate([req.url], {queryParams: req.query, fragment: req.hash});
if (document.getElementsByTagName('v' + window.location.pathname.replace(/\//, '-')).length > 0) {
const x = <HTMLBodyElement>document.getElementsByTagName('v' + window.location.pathname.replace(/\//, '-'))[0];
x.style.visibility = 'hidden';
setTimeout(() => {
// 此处是防止移动端自己的back button跳转导致页面空白
x.style.visibility = 'visible';
}, 2000);
}
}
}
<div class="mainCon">
<Navbar [leftContent]="icon"
(onLeftClick)="onLeftClick()"
style="background-color: #28c9bd"
>
西中转池控制
</Navbar>
<div class="topPart">
<!--<div class="online" *ngFor="let one of items">-->
<!--<div class="label">{{one.label}}</div>-->
<!--<div class="btn">-->
<!--<ion-toggle mode="md" color="primary" (ionChange)="toggle(one.type, $event)"></ion-toggle>-->
<!--</div>-->
<!--</div>-->
<ListItem multipleLine>
当前液位:
<div class="process">
<div class="inlineProcess" [ngStyle]="{width: proc + '%'}"
[ngClass]="{'orange': proc < 4 && proc > 3.5, 'red': proc < 3.5}">
</div>
</div>
{{yewei}}m
</ListItem>
<!--<ListItem multipleLine>-->
<!--当前温度:-->
<!--<div style="display: inline-block;margin-left: calc(100% - 135px);vertical-align: middle">-->
<!--{{temp.value}}℃-->
<!--</div>-->
<!--</ListItem>-->
<ListItem multipleLine [extra]="s1">
南水
</ListItem>
<ListItem multipleLine [extra]="s2">
北水
</ListItem>
</div>
<div class="bottomPart">
<ListItem multipleLine [extra]="s3">
一号搅拌器
</ListItem>
<ListItem multipleLine [extra]="s4">
二号搅拌器
</ListItem>
<!--<ListItem multipleLine [extra]="s5">-->
<!--三号搅拌器-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s6">-->
<!--四号搅拌器-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s7">-->
<!--一号泵-->
<!--</ListItem>-->
<!--<ListItem multipleLine [extra]="s8">-->
<!--二号泵-->
<!--</ListItem>-->
</div>
</div>
<ng-template #icon>
<span class="vo v-back"></span>
</ng-template>
<ng-template #s1>
<Switch [platform]="'android'" [disabled]="true" [color]="color[0]" (ngModelChange)="toggle(0)"
[(ngModel)]="value[0]"></Switch>
</ng-template>
<ng-template #s2>
<Switch [platform]="'android'" [disabled]="true" [color]="color[1]" (ngModelChange)="toggle(1)"
[(ngModel)]="value[1]"></Switch>
</ng-template>
<ng-template #s3>
<Switch [platform]="'android'" [disabled]="true" [color]="color[2]" (ngModelChange)="toggle(2)"
[(ngModel)]="value[2]"></Switch>
</ng-template>
<ng-template #s4>
<Switch [platform]="'android'" [disabled]="true" [color]="color[3]" (ngModelChange)="toggle(3)"
[(ngModel)]="value[3]"></Switch>
</ng-template>
<ng-template #s5>
<Switch [platform]="'android'" [disabled]="true" [color]="color[4]" (ngModelChange)="toggle(4)"
[(ngModel)]="value[4]"></Switch>
</ng-template>
<ng-template #s6>
<Switch [platform]="'android'" [disabled]="true" [color]="color[5]" (ngModelChange)="toggle(5)"
[(ngModel)]="value[5]"></Switch>
</ng-template>
<ng-template #s7>
<Switch [platform]="'android'" [disabled]="true" [color]="color[6]" (ngModelChange)="toggle(6)"
[(ngModel)]="value[6]"></Switch>
</ng-template>
<ng-template #s8>
<Switch [platform]="'android'" [disabled]="true" [color]="color[7]" (ngModelChange)="toggle(7)"
[(ngModel)]="value[7]"></Switch>
</ng-template>
// 因为switch左侧有52px的留白,在这52px的地方
// 点击会发生颜色变化但是switch的值没变化的情况
// 这样处理的原因是这个控件的color属性在刚进来
// 的时候哪怕是false也会显示这个颜色,但是按两次
// 就好了,于是我把颜色用点击事件单独拎出来处理了
// 如果后面版本升级,这个问题被修复了你可以直接用
// color属性,而不用这么麻烦
Switch {
margin-left: 52px;
}
.process {
width: calc(100% - 160px);
display: inline-block;
margin: 0 10px;
background-color: #cccccc;
height: 20px;
vertical-align: middle;
position: relative;
border-radius: 10px;
}
.inlineProcess {
display: inline-block;
border-radius: 10px;
background-color: #2ecc71;
height: 20px;
}
.orange {
background-color: #ffa847;
}
.red {
background-color: #f04844;
}
import { Component, OnInit } from '@angular/core';
import {Transfer} from '../service/transfer';
import {Api} from '../service/api';
@Component({
selector: 'v-west',
templateUrl: './west.component.html',
styleUrls: ['./west.component.scss'],
})
export class WestPage implements OnInit {
// 此处处理color原因详见该目录下scss文件
color = ['#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6', '#a7aaa6'];
value = [false, false, false, false, false, false, false];
yewei = '';
temp: any = '';
proc = 0;
constructor(private tf: Transfer, private api: Api) {
}
ngOnInit() {
this.getData();
}
toggle(index) {
this.color[index] = !this.value[index] ? '#28c9bd' : '#a7aaa6';
this.color = [...this.color];
}
onLeftClick() {
this.tf.transfer({url: '/home'});
}
getData() {
// 西中转池 19040001 0号通道为温度
// this.api.data.getRealData([{deviceNo: '92489110027112448'}, (data) => {
// if (data && data.constructor === Array) {
// this.temp = data[0];
// } else {
// this.api.presentMsgToast('获取数据失败');
// }
// }]);
// 西中转池 19040006 0号通道为液位
this.api.data.getRealData([{deviceNo: '92490138428510208'}, (data) => {
if (data && data.constructor === Array) {
if (data[0].value) {
if (data.length > 0) {
this.yewei = Number(data[0].value).toFixed(2);
this.proc = Number(data[0].value) * 100 / 6.5;
}
}
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
// 西中转池 19040004 0,1号通道为南水 2,3号通道为北水
// this.api.data.getRealData([{deviceNo: '92489787927302144'}, (data) => {
// if (data && data.constructor === Array) {
// if (data[0] && data[1]) {
// this.value[0] = !!(data[0].value === '1.0' && data[1].value === '1.0');
// this.color[0] = (data[0].value === '1.0' && data[1].value === '1.0') ? '#28c9bd' : this.color[0];
// }
// if (data[2] && data[3]) {
// this.value[1] = !!(data[2].value === '1.0' && data[3].value === '1.0');
// this.color[1] = (data[2].value === '1.0' && data[3].value === '1.0') ? '#28c9bd' : this.color[1];
// }
// this.value = [...this.value];
// } else {
// this.api.presentMsgToast('获取数据失败');
// }
// }]);
// 西中转池 19040008 0,1号通道为1号搅拌池 2,3号通道为2号搅拌池
this.api.data.getRealData([{deviceNo: '92490309405118464'}, (data) => {
if (data && data.constructor === Array) {
if (data.length > 0) {
if (data[0] && data[1]) {
this.value[2] = !!(data[0].value === '1.0' && data[1].value === '1.0');
this.color[2] = (data[0].value === '1.0' && data[1].value === '1.0') ? '#28c9bd' : this.color[2];
}
if (data[2] && data[3]) {
this.value[3] = !!(data[2].value === '1.0' && data[3].value === '1.0');
this.color[3] = (data[2].value === '1.0' && data[3].value === '1.0') ? '#28c9bd' : this.color[3];
}
}
this.value = [...this.value];
} else {
this.api.presentMsgToast('获取数据失败');
}
}]);
}
}
@font-face {font-family: "vo";
src: url('iconfont.eot?t=1556271947426'); /* IE9 */
src: url('iconfont.eot?t=1556271947426#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAOcAAsAAAAABygAAANNAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDHAqCOIInATYCJAMQCwoABCAFhCUHPBtFBlGU7ckE2RfYNvKZRi0713EUF5zheQHOoyGAG6E2WEgz0AQwACL42g/du3shIAfokvHhSmJL4+tbh0KhsLEVBoViS/L/OffmE7mBXM73oxwgqdJLy2lgBMay8LsJNYfk/g0CuOb995qzRAYcUcLTNpxn6WwDKd7A6XZpv/cokHeBok9hUfSxT/F7dD49TKN7KSvQaoChNHR/3E9dnu8G/OwDQKyCKpNGNrGo0AqhgUzQN+guYmLEpfUkNBpFIbY/Or2MsgLolpDuOZaGspZZiMhXL6ntGRukpxT1eZifQZ7w76ffNIR6ZDUF0PfgxoiJ+r8lvlVOq4EqJWDup0Q0iYJlkCDd6nVfkZAiekJj46R1kHr1MnvV+M2pKinlxjj8yyNLCqkWEN0MVj1r4RtGyHwTIfGtKAU+iKTeE3nPII996vDSWZaabfbm3pt/fxc+/559/D759HP5XNTfzZXQZIRk/yCfNSL2AM816R6W+aIDrIz9+aesuddNt9Laxi80Ji3e8x3Xd7htA88PQb4Yu7//wiUEueCOuSgvFwYEuOiKu93A++dnbcmAcL5l/H7m2GKVY5sQmf136DdaPhXUrztXRk5FCMXL9XjURf35hehBWc+5OsLPuJy/X0z/V5Tt9bl5OR9tcopm91+5M9huayb8pSSa+SneC+7rYVz7FHs5QwSh+knFUgDlf26h2kSNFPsvv/FoM3d+0db9tx6Tga//sXLWPCF6uczZzL+QF4jqL6MxG0gicg5mVNowszopo1GjRAzQd9LcQ9Qzm0YS9WjI6vRBkY0SgzoONZpMQq1sBRotUZ3cpItNCSkMsEjgQBKeQdbqFRThNTGo76FGLzdQK3yARmee5mwyK0w07nHQJJhY38OOQUOC6sv8Nl0Ea8vX+DaFW6wCFw4Ncb1S26ZjEAKfO0BsWw0pCSacBnh00Wbg+xRHnLpgyIotZdRZrZK+E1UMGqC8PRzQSMCE0e3BOAxUiNDBUt4D1CJg2eL7At7CcfoqwAnOvHBMnQo1nzgmCEdK7s0T5SKWBpJEYAiOChzR6GlK4EM3hYn6W7mAQapgr3BGOql61chcQeXWouDl4FEF4JhIoiAJsqAQ9wXwZOAEWlLXDA8hAAAA') format('woff2'),
url('iconfont.woff?t=1556271947426') format('woff'),
url('iconfont.ttf?t=1556271947426') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1556271947426#vo') format('svg'); /* iOS 4.1- */
}
.vo {
font-family: "vo" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.v-user:before {
content: "\e643";
}
.v-mima:before {
content: "\e603";
}
.v-back:before {
content: "\e669";
}
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="vo" horiz-adv-x="1024" >
<font-face
font-family="vo"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="user" unicode="&#58947;" d="M510.82347975 372.20569088c112.28577906 0 203.32433749 91.07232313 203.3243375 203.32433749 0 112.3207077-91.03855843 203.32550258-203.3243375 203.32550258s-203.32433749-91.00479374-203.32433749-203.32550258C307.49914226 463.27685006 398.53886464 372.20569088 510.82347975 372.20569088zM889.43593131 162.99002083000005c-59.89715854 57.25188096-213.50959104 107.55291933-388.67196018 107.55291933-175.16120519 0-320.04375211-50.3010395-379.87571143-107.55291933-13.83415353-13.23803421-16.51552483-31.50465934-16.51552484-50.56649898l0-126.62640185 392.79007175 0 421.05217024 0 0 126.62640185C918.21613966 131.48652430000004 903.20255545 149.82067883000002 889.43593131 162.99002083000005z" horiz-adv-x="1024" />
<glyph glyph-name="mima" unicode="&#58883;" d="M961.536 474.90844445l-101.26222222 102.62755555-96.14222223-97.50755555h-31.97155555l-97.62133333 96.93866666-96.14222222-95.45955556c-35.15733333 112.86755555-138.12622222 194.56-259.6408889 194.56-150.528 0-272.61155555-125.49688889-272.61155555-280.23466666S128.22755555 115.59822222000003 278.75555555 115.59822222000003c122.08355555 0 225.39377778 82.48888889 260.096 196.15288889h394.58133334c44.94222222 0 81.35111111 36.864 81.35111111 82.37511111V397.65333333c0 35.49866667-22.18666667 65.64977778-53.248 77.25511112zM278.75555555 283.98933333c-60.18844445 0-108.99911111 50.176-108.9991111 112.07111112s48.81066667 112.07111111 108.9991111 112.0711111 108.99911111-50.176 108.99911112-112.0711111-48.81066667-112.07111111-108.99911112-112.07111112z" horiz-adv-x="1024" />
<glyph glyph-name="back" unicode="&#58985;" d="M470.57477518 624.7841189000001V767.18332814c-12.94538297 59.54876075-62.13783666 23.30168889-62.13783665 23.30168889L66.67883406 497.91936739c-75.08321963-51.78153074-5.17815296-90.61767851-5.17815296-90.6176785l336.57995151-289.97657259c67.31598962-49.19245483 72.49414371 25.89076594 72.49414257 25.8907648v132.04290447C812.33287851 381.41092295 952.14301184-43.19763001000001 952.14301184-43.19763001000001c12.94538297-23.30168889 20.71261184 0 20.71261298 0 132.04290333 636.91283001-502.28084963 667.98174777-502.28084964 667.98174891z" horiz-adv-x="1024" />
</font>
</defs></svg>
"undefined"==typeof Paho&&(Paho={}),Paho.MQTT=function(e){function t(e,t){var s=t,n=e[t],o=n>>4,r=n&=15;t+=1;var a,h=0,d=1;do{if(t==e.length)return[null,s];a=e[t++],h+=(127&a)*d,d*=128}while(0!=(128&a));var f=t+h;if(f>e.length)return[null,s];var l=new v(o);switch(o){case u.CONNACK:var _=e[t++];1&_&&(l.sessionPresent=!0),l.returnCode=e[t++];break;case u.PUBLISH:var g=r>>1&3,p=i(e,t);t+=2;var I=c(e,t,p);t+=p,g>0&&(l.messageIdentifier=i(e,t),t+=2);var w=new Paho.MQTT.Message(e.subarray(t,f));1==(1&r)&&(w.retained=!0),8==(8&r)&&(w.duplicate=!0),w.qos=g,w.destinationName=I,l.payloadMessage=w;break;case u.PUBACK:case u.PUBREC:case u.PUBREL:case u.PUBCOMP:case u.UNSUBACK:l.messageIdentifier=i(e,t);break;case u.SUBACK:l.messageIdentifier=i(e,t),t+=2,l.returnCode=e.subarray(t,f)}return[l,f]}function s(e,t,s){return t[s++]=e>>8,t[s++]=e%256,s}function n(e,t,n,i){return i=s(t,n,i),a(e,n,i),i+t}function i(e,t){return 256*e[t]+e[t+1]}function o(e){var t=new Array(1),s=0;do{var n=e%128;e>>=7,e>0&&(n|=128),t[s++]=n}while(e>0&&4>s);return t}function r(e){for(var t=0,s=0;s<e.length;s++){var n=e.charCodeAt(s);n>2047?(n>=55296&&56319>=n&&(s++,t++),t+=3):n>127?t+=2:t++}return t}function a(e,t,s){for(var n=s,i=0;i<e.length;i++){var o=e.charCodeAt(i);if(o>=55296&&56319>=o){var r=e.charCodeAt(++i);if(isNaN(r))throw new Error(g(l.MALFORMED_UNICODE,[o,r]));o=(o-55296<<10)+(r-56320)+65536}127>=o?t[n++]=o:2047>=o?(t[n++]=o>>6&31|192,t[n++]=63&o|128):65535>=o?(t[n++]=o>>12&15|224,t[n++]=o>>6&63|128,t[n++]=63&o|128):(t[n++]=o>>18&7|240,t[n++]=o>>12&63|128,t[n++]=o>>6&63|128,t[n++]=63&o|128)}return t}function c(e,t,s){for(var n,i="",o=t;t+s>o;){var r=e[o++];if(128>r)n=r;else{var a=e[o++]-128;if(0>a)throw new Error(g(l.MALFORMED_UTF,[r.toString(16),a.toString(16),""]));if(224>r)n=64*(r-192)+a;else{var c=e[o++]-128;if(0>c)throw new Error(g(l.MALFORMED_UTF,[r.toString(16),a.toString(16),c.toString(16)]));if(240>r)n=4096*(r-224)+64*a+c;else{var h=e[o++]-128;if(0>h)throw new Error(g(l.MALFORMED_UTF,[r.toString(16),a.toString(16),c.toString(16),h.toString(16)]));if(!(248>r))throw new Error(g(l.MALFORMED_UTF,[r.toString(16),a.toString(16),c.toString(16),h.toString(16)]));n=262144*(r-240)+4096*a+64*c+h}}}n>65535&&(n-=65536,i+=String.fromCharCode(55296+(n>>10)),n=56320+(1023&n)),i+=String.fromCharCode(n)}return i}var h="@VERSION@",u={CONNECT:1,CONNACK:2,PUBLISH:3,PUBACK:4,PUBREC:5,PUBREL:6,PUBCOMP:7,SUBSCRIBE:8,SUBACK:9,UNSUBSCRIBE:10,UNSUBACK:11,PINGREQ:12,PINGRESP:13,DISCONNECT:14},d=function(e,t){for(var s in e)if(e.hasOwnProperty(s)){if(!t.hasOwnProperty(s)){var n="Unknown property, "+s+". Valid properties are:";for(var s in t)t.hasOwnProperty(s)&&(n=n+" "+s);throw new Error(n)}if(typeof e[s]!==t[s])throw new Error(g(l.INVALID_TYPE,[typeof e[s],s]))}},f=function(e,t){return function(){return e.apply(t,arguments)}},l={OK:{code:0,text:"AMQJSC0000I OK."},CONNECT_TIMEOUT:{code:1,text:"AMQJSC0001E Connect timed out."},SUBSCRIBE_TIMEOUT:{code:2,text:"AMQJS0002E Subscribe timed out."},UNSUBSCRIBE_TIMEOUT:{code:3,text:"AMQJS0003E Unsubscribe timed out."},PING_TIMEOUT:{code:4,text:"AMQJS0004E Ping timed out."},INTERNAL_ERROR:{code:5,text:"AMQJS0005E Internal error. Error Message: {0}, Stack trace: {1}"},CONNACK_RETURNCODE:{code:6,text:"AMQJS0006E Bad Connack return code:{0} {1}."},SOCKET_ERROR:{code:7,text:"AMQJS0007E Socket error:{0}."},SOCKET_CLOSE:{code:8,text:"AMQJS0008I Socket closed."},MALFORMED_UTF:{code:9,text:"AMQJS0009E Malformed UTF data:{0} {1} {2}."},UNSUPPORTED:{code:10,text:"AMQJS0010E {0} is not supported by this browser."},INVALID_STATE:{code:11,text:"AMQJS0011E Invalid state {0}."},INVALID_TYPE:{code:12,text:"AMQJS0012E Invalid type {0} for {1}."},INVALID_ARGUMENT:{code:13,text:"AMQJS0013E Invalid argument {0} for {1}."},UNSUPPORTED_OPERATION:{code:14,text:"AMQJS0014E Unsupported operation."},INVALID_STORED_DATA:{code:15,text:"AMQJS0015E Invalid data in local storage key={0} value={1}."},INVALID_MQTT_MESSAGE_TYPE:{code:16,text:"AMQJS0016E Invalid MQTT message type {0}."},MALFORMED_UNICODE:{code:17,text:"AMQJS0017E Malformed Unicode string:{0} {1}."}},_={0:"Connection Accepted",1:"Connection Refused: unacceptable protocol version",2:"Connection Refused: identifier rejected",3:"Connection Refused: server unavailable",4:"Connection Refused: bad user name or password",5:"Connection Refused: not authorized"},g=function(e,t){var s=e.text;if(t)for(var n,i,o=0;o<t.length;o++)if(n="{"+o+"}",i=s.indexOf(n),i>0){var r=s.substring(0,i),a=s.substring(i+n.length);s=r+t[o]+a}return s},p=[0,6,77,81,73,115,100,112,3],I=[0,4,77,81,84,84,4],v=function(e,t){this.type=e;for(var s in t)t.hasOwnProperty(s)&&(this[s]=t[s])};v.prototype.encode=function(){var e=(15&this.type)<<4,t=0,i=new Array,a=0;switch(void 0!=this.messageIdentifier&&(t+=2),this.type){case u.CONNECT:switch(this.mqttVersion){case 3:t+=p.length+3;break;case 4:t+=I.length+3}if(t+=r(this.clientId)+2,void 0!=this.willMessage){t+=r(this.willMessage.destinationName)+2;var c=this.willMessage.payloadBytes;c instanceof Uint8Array||(c=new Uint8Array(d)),t+=c.byteLength+2}void 0!=this.userName&&(t+=r(this.userName)+2),void 0!=this.password&&(t+=r(this.password)+2);break;case u.SUBSCRIBE:e|=2;for(var h=0;h<this.topics.length;h++)i[h]=r(this.topics[h]),t+=i[h]+2;t+=this.requestedQos.length;break;case u.UNSUBSCRIBE:e|=2;for(var h=0;h<this.topics.length;h++)i[h]=r(this.topics[h]),t+=i[h]+2;break;case u.PUBREL:e|=2;break;case u.PUBLISH:this.payloadMessage.duplicate&&(e|=8),e=e|=this.payloadMessage.qos<<1,this.payloadMessage.retained&&(e|=1),a=r(this.payloadMessage.destinationName),t+=a+2;var d=this.payloadMessage.payloadBytes;t+=d.byteLength,d instanceof ArrayBuffer?d=new Uint8Array(d):d instanceof Uint8Array||(d=new Uint8Array(d.buffer));break;case u.DISCONNECT:}var f=o(t),l=f.length+1,_=new ArrayBuffer(t+l),g=new Uint8Array(_);if(g[0]=e,g.set(f,1),this.type==u.PUBLISH)l=n(this.payloadMessage.destinationName,a,g,l);else if(this.type==u.CONNECT){switch(this.mqttVersion){case 3:g.set(p,l),l+=p.length;break;case 4:g.set(I,l),l+=I.length}var v=0;this.cleanSession&&(v=2),void 0!=this.willMessage&&(v|=4,v|=this.willMessage.qos<<3,this.willMessage.retained&&(v|=32)),void 0!=this.userName&&(v|=128),void 0!=this.password&&(v|=64),g[l++]=v,l=s(this.keepAliveInterval,g,l)}switch(void 0!=this.messageIdentifier&&(l=s(this.messageIdentifier,g,l)),this.type){case u.CONNECT:l=n(this.clientId,r(this.clientId),g,l),void 0!=this.willMessage&&(l=n(this.willMessage.destinationName,r(this.willMessage.destinationName),g,l),l=s(c.byteLength,g,l),g.set(c,l),l+=c.byteLength),void 0!=this.userName&&(l=n(this.userName,r(this.userName),g,l)),void 0!=this.password&&(l=n(this.password,r(this.password),g,l));break;case u.PUBLISH:g.set(d,l);break;case u.SUBSCRIBE:for(var h=0;h<this.topics.length;h++)l=n(this.topics[h],i[h],g,l),g[l++]=this.requestedQos[h];break;case u.UNSUBSCRIBE:for(var h=0;h<this.topics.length;h++)l=n(this.topics[h],i[h],g,l)}return _};var w=function(e,t,s){this._client=e,this._window=t,this._keepAliveInterval=1e3*s,this.isReset=!1;var n=new v(u.PINGREQ).encode(),i=function(e){return function(){return o.apply(e)}},o=function(){this.isReset?(this.isReset=!1,this._client._trace("Pinger.doPing","send PINGREQ"),this._client.socket.send(n),this.timeout=this._window.setTimeout(i(this),this._keepAliveInterval)):(this._client._trace("Pinger.doPing","Timed out"),this._client._disconnected(l.PING_TIMEOUT.code,g(l.PING_TIMEOUT)))};this.reset=function(){this.isReset=!0,this._window.clearTimeout(this.timeout),this._keepAliveInterval>0&&(this.timeout=setTimeout(i(this),this._keepAliveInterval))},this.cancel=function(){this._window.clearTimeout(this.timeout)}},E=function(e,t,s,n,i){this._window=t,s||(s=30);var o=function(e,t,s){return function(){return e.apply(t,s)}};this.timeout=setTimeout(o(n,e,i),1e3*s),this.cancel=function(){this._window.clearTimeout(this.timeout)}},y=function(t,s,n,i,o){if(!("WebSocket"in e&&null!==e.WebSocket))throw new Error(g(l.UNSUPPORTED,["WebSocket"]));if(!("localStorage"in e&&null!==e.localStorage))throw new Error(g(l.UNSUPPORTED,["localStorage"]));if(!("ArrayBuffer"in e&&null!==e.ArrayBuffer))throw new Error(g(l.UNSUPPORTED,["ArrayBuffer"]));this._trace("Paho.MQTT.Client",t,s,n,i,o),this.host=s,this.port=n,this.path=i,this.uri=t,this.clientId=o,this._localKey=s+":"+n+("/mqtt"!=i?":"+i:"")+":"+o+":",this._msg_queue=[],this._sentMessages={},this._receivedMessages={},this._notify_msg_sent={},this._message_identifier=1,this._sequence=0;for(var r in localStorage)0!=r.indexOf("Sent:"+this._localKey)&&0!=r.indexOf("Received:"+this._localKey)||this.restore(r)};y.prototype.host,y.prototype.port,y.prototype.path,y.prototype.uri,y.prototype.clientId,y.prototype.socket,y.prototype.connected=!1,y.prototype.maxMessageIdentifier=65536,y.prototype.connectOptions,y.prototype.hostIndex,y.prototype.onConnectionLost,y.prototype.onMessageDelivered,y.prototype.onMessageArrived,y.prototype.traceFunction,y.prototype._msg_queue=null,y.prototype._connectTimeout,y.prototype.sendPinger=null,y.prototype.receivePinger=null,y.prototype.receiveBuffer=null,y.prototype._traceBuffer=null,y.prototype._MAX_TRACE_ENTRIES=100,y.prototype.connect=function(e){var t=this._traceMask(e,"password");if(this._trace("Client.connect",t,this.socket,this.connected),this.connected)throw new Error(g(l.INVALID_STATE,["already connected"]));if(this.socket)throw new Error(g(l.INVALID_STATE,["already connected"]));this.connectOptions=e,e.uris?(this.hostIndex=0,this._doConnect(e.uris[0])):this._doConnect(this.uri)},y.prototype.subscribe=function(e,t){if(this._trace("Client.subscribe",e,t),!this.connected)throw new Error(g(l.INVALID_STATE,["not connected"]));var s=new v(u.SUBSCRIBE);s.topics=[e],void 0!=t.qos?s.requestedQos=[t.qos]:s.requestedQos=[0],t.onSuccess&&(s.onSuccess=function(e){t.onSuccess({invocationContext:t.invocationContext,grantedQos:e})}),t.onFailure&&(s.onFailure=function(e){t.onFailure({invocationContext:t.invocationContext,errorCode:e})}),t.timeout&&(s.timeOut=new E(this,window,t.timeout,t.onFailure,[{invocationContext:t.invocationContext,errorCode:l.SUBSCRIBE_TIMEOUT.code,errorMessage:g(l.SUBSCRIBE_TIMEOUT)}])),this._requires_ack(s),this._schedule_message(s)},y.prototype.unsubscribe=function(e,t){if(this._trace("Client.unsubscribe",e,t),!this.connected)throw new Error(g(l.INVALID_STATE,["not connected"]));var s=new v(u.UNSUBSCRIBE);s.topics=[e],t.onSuccess&&(s.callback=function(){t.onSuccess({invocationContext:t.invocationContext})}),t.timeout&&(s.timeOut=new E(this,window,t.timeout,t.onFailure,[{invocationContext:t.invocationContext,errorCode:l.UNSUBSCRIBE_TIMEOUT.code,errorMessage:g(l.UNSUBSCRIBE_TIMEOUT)}])),this._requires_ack(s),this._schedule_message(s)},y.prototype.send=function(e){if(this._trace("Client.send",e),!this.connected)throw new Error(g(l.INVALID_STATE,["not connected"]));wireMessage=new v(u.PUBLISH),wireMessage.payloadMessage=e,e.qos>0?this._requires_ack(wireMessage):this.onMessageDelivered&&(this._notify_msg_sent[wireMessage]=this.onMessageDelivered(wireMessage.payloadMessage)),this._schedule_message(wireMessage)},y.prototype.disconnect=function(){if(this._trace("Client.disconnect"),!this.socket)throw new Error(g(l.INVALID_STATE,["not connecting or connected"]));wireMessage=new v(u.DISCONNECT),this._notify_msg_sent[wireMessage]=f(this._disconnected,this),this._schedule_message(wireMessage)},y.prototype.getTraceLog=function(){if(null!==this._traceBuffer){this._trace("Client.getTraceLog",new Date),this._trace("Client.getTraceLog in flight messages",this._sentMessages.length);for(var e in this._sentMessages)this._trace("_sentMessages ",e,this._sentMessages[e]);for(var e in this._receivedMessages)this._trace("_receivedMessages ",e,this._receivedMessages[e]);return this._traceBuffer}},y.prototype.startTrace=function(){null===this._traceBuffer&&(this._traceBuffer=[]),this._trace("Client.startTrace",new Date,h)},y.prototype.stopTrace=function(){delete this._traceBuffer},y.prototype._doConnect=function(e){if(this.connectOptions.useSSL){var t=e.split(":");t[0]="wss",e=t.join(":")}this.connected=!1,this.connectOptions.mqttVersion<4?this.socket=new WebSocket(e,["mqttv3.1"]):this.socket=new WebSocket(e,["mqtt"]),this.socket.binaryType="arraybuffer",this.socket.onopen=f(this._on_socket_open,this),this.socket.onmessage=f(this._on_socket_message,this),this.socket.onerror=f(this._on_socket_error,this),this.socket.onclose=f(this._on_socket_close,this),this.sendPinger=new w(this,window,this.connectOptions.keepAliveInterval),this.receivePinger=new w(this,window,this.connectOptions.keepAliveInterval),this._connectTimeout=new E(this,window,this.connectOptions.timeout,this._disconnected,[l.CONNECT_TIMEOUT.code,g(l.CONNECT_TIMEOUT)])},y.prototype._schedule_message=function(e){this._msg_queue.push(e),this.connected&&this._process_queue()},y.prototype.store=function(e,t){var s={type:t.type,messageIdentifier:t.messageIdentifier,version:1};switch(t.type){case u.PUBLISH:t.pubRecReceived&&(s.pubRecReceived=!0),s.payloadMessage={};for(var n="",i=t.payloadMessage.payloadBytes,o=0;o<i.length;o++)i[o]<=15?n=n+"0"+i[o].toString(16):n+=i[o].toString(16);s.payloadMessage.payloadHex=n,s.payloadMessage.qos=t.payloadMessage.qos,s.payloadMessage.destinationName=t.payloadMessage.destinationName,t.payloadMessage.duplicate&&(s.payloadMessage.duplicate=!0),t.payloadMessage.retained&&(s.payloadMessage.retained=!0),0==e.indexOf("Sent:")&&(void 0===t.sequence&&(t.sequence=++this._sequence),s.sequence=t.sequence);break;default:throw Error(g(l.INVALID_STORED_DATA,[key,s]))}localStorage.setItem(e+this._localKey+t.messageIdentifier,JSON.stringify(s))},y.prototype.restore=function(e){var t=localStorage.getItem(e),s=JSON.parse(t),n=new v(s.type,s);switch(s.type){case u.PUBLISH:for(var i=s.payloadMessage.payloadHex,o=new ArrayBuffer(i.length/2),r=new Uint8Array(o),a=0;i.length>=2;){var c=parseInt(i.substring(0,2),16);i=i.substring(2,i.length),r[a++]=c}var h=new Paho.MQTT.Message(r);h.qos=s.payloadMessage.qos,h.destinationName=s.payloadMessage.destinationName,s.payloadMessage.duplicate&&(h.duplicate=!0),s.payloadMessage.retained&&(h.retained=!0),n.payloadMessage=h;break;default:throw Error(g(l.INVALID_STORED_DATA,[e,t]))}0==e.indexOf("Sent:"+this._localKey)?(n.payloadMessage.duplicate=!0,this._sentMessages[n.messageIdentifier]=n):0==e.indexOf("Received:"+this._localKey)&&(this._receivedMessages[n.messageIdentifier]=n)},y.prototype._process_queue=function(){for(var e=null,t=this._msg_queue.reverse();e=t.pop();)this._socket_send(e),this._notify_msg_sent[e]&&(this._notify_msg_sent[e](),delete this._notify_msg_sent[e])},y.prototype._requires_ack=function(e){var t=Object.keys(this._sentMessages).length;if(t>this.maxMessageIdentifier)throw Error("Too many messages:"+t);for(;void 0!==this._sentMessages[this._message_identifier];)this._message_identifier++;e.messageIdentifier=this._message_identifier,this._sentMessages[e.messageIdentifier]=e,e.type===u.PUBLISH&&this.store("Sent:",e),this._message_identifier===this.maxMessageIdentifier&&(this._message_identifier=1)},y.prototype._on_socket_open=function(){var e=new v(u.CONNECT,this.connectOptions);e.clientId=this.clientId,this._socket_send(e)},y.prototype._on_socket_message=function(e){this._trace("Client._on_socket_message",e.data);for(var t=this._deframeMessages(e.data),s=0;s<t.length;s+=1)this._handleMessage(t[s])},y.prototype._deframeMessages=function(e){var s=new Uint8Array(e);if(this.receiveBuffer){var n=new Uint8Array(this.receiveBuffer.length+s.length);n.set(this.receiveBuffer),n.set(s,this.receiveBuffer.length),s=n,delete this.receiveBuffer}try{for(var i=0,o=[];i<s.length;){var r=t(s,i),a=r[0];if(i=r[1],null===a)break;o.push(a)}i<s.length&&(this.receiveBuffer=s.subarray(i))}catch(c){return void this._disconnected(l.INTERNAL_ERROR.code,g(l.INTERNAL_ERROR,[c.message,c.stack.toString()]))}return o},y.prototype._handleMessage=function(e){this._trace("Client._handleMessage",e);try{switch(e.type){case u.CONNACK:if(this._connectTimeout.cancel(),this.connectOptions.cleanSession){for(var t in this._sentMessages){var s=this._sentMessages[t];localStorage.removeItem("Sent:"+this._localKey+s.messageIdentifier)}this._sentMessages={};for(var t in this._receivedMessages){var n=this._receivedMessages[t];localStorage.removeItem("Received:"+this._localKey+n.messageIdentifier)}this._receivedMessages={}}if(0!==e.returnCode){this._disconnected(l.CONNACK_RETURNCODE.code,g(l.CONNACK_RETURNCODE,[e.returnCode,_[e.returnCode]]));break}this.connected=!0,this.connectOptions.uris&&(this.hostIndex=this.connectOptions.uris.length);var i=new Array;for(var o in this._sentMessages)this._sentMessages.hasOwnProperty(o)&&i.push(this._sentMessages[o]);for(var i=i.sort(function(e,t){return e.sequence-t.sequence}),r=0,a=i.length;a>r;r++){var s=i[r];if(s.type==u.PUBLISH&&s.pubRecReceived){var c=new v(u.PUBREL,{messageIdentifier:s.messageIdentifier});this._schedule_message(c)}else this._schedule_message(s)}this.connectOptions.onSuccess&&this.connectOptions.onSuccess({invocationContext:this.connectOptions.invocationContext}),this._process_queue();break;case u.PUBLISH:this._receivePublish(e);break;case u.PUBACK:var s=this._sentMessages[e.messageIdentifier];s&&(delete this._sentMessages[e.messageIdentifier],localStorage.removeItem("Sent:"+this._localKey+e.messageIdentifier),this.onMessageDelivered&&this.onMessageDelivered(s.payloadMessage));break;case u.PUBREC:var s=this._sentMessages[e.messageIdentifier];if(s){s.pubRecReceived=!0;var c=new v(u.PUBREL,{messageIdentifier:e.messageIdentifier});this.store("Sent:",s),this._schedule_message(c)}break;case u.PUBREL:var n=this._receivedMessages[e.messageIdentifier];localStorage.removeItem("Received:"+this._localKey+e.messageIdentifier),n&&(this._receiveMessage(n),delete this._receivedMessages[e.messageIdentifier]);var h=new v(u.PUBCOMP,{messageIdentifier:e.messageIdentifier});this._schedule_message(h);break;case u.PUBCOMP:var s=this._sentMessages[e.messageIdentifier];delete this._sentMessages[e.messageIdentifier],localStorage.removeItem("Sent:"+this._localKey+e.messageIdentifier),this.onMessageDelivered&&this.onMessageDelivered(s.payloadMessage);break;case u.SUBACK:var s=this._sentMessages[e.messageIdentifier];s&&(s.timeOut&&s.timeOut.cancel(),128===e.returnCode[0]?s.onFailure&&s.onFailure(e.returnCode):s.onSuccess&&s.onSuccess(e.returnCode),delete this._sentMessages[e.messageIdentifier]);break;case u.UNSUBACK:var s=this._sentMessages[e.messageIdentifier];s&&(s.timeOut&&s.timeOut.cancel(),s.callback&&s.callback(),delete this._sentMessages[e.messageIdentifier]);break;case u.PINGRESP:this.sendPinger.reset();break;case u.DISCONNECT:this._disconnected(l.INVALID_MQTT_MESSAGE_TYPE.code,g(l.INVALID_MQTT_MESSAGE_TYPE,[e.type]));break;default:this._disconnected(l.INVALID_MQTT_MESSAGE_TYPE.code,g(l.INVALID_MQTT_MESSAGE_TYPE,[e.type]))}}catch(d){return void this._disconnected(l.INTERNAL_ERROR.code,g(l.INTERNAL_ERROR,[d.message,d.stack.toString()]))}},y.prototype._on_socket_error=function(e){this._disconnected(l.SOCKET_ERROR.code,g(l.SOCKET_ERROR,[e.data]))},y.prototype._on_socket_close=function(){this._disconnected(l.SOCKET_CLOSE.code,g(l.SOCKET_CLOSE))},y.prototype._socket_send=function(e){if(1==e.type){var t=this._traceMask(e,"password");this._trace("Client._socket_send",t)}else this._trace("Client._socket_send",e);this.socket.send(e.encode()),this.sendPinger.reset()},y.prototype._receivePublish=function(e){switch(e.payloadMessage.qos){case"undefined":case 0:this._receiveMessage(e);break;case 1:var t=new v(u.PUBACK,{messageIdentifier:e.messageIdentifier});this._schedule_message(t),this._receiveMessage(e);break;case 2:this._receivedMessages[e.messageIdentifier]=e,this.store("Received:",e);var s=new v(u.PUBREC,{messageIdentifier:e.messageIdentifier});this._schedule_message(s);break;default:throw Error("Invaild qos="+wireMmessage.payloadMessage.qos)}},y.prototype._receiveMessage=function(e){this.onMessageArrived&&this.onMessageArrived(e.payloadMessage)},y.prototype._disconnected=function(e,t){this._trace("Client._disconnected",e,t),this.sendPinger.cancel(),this.receivePinger.cancel(),this._connectTimeout&&this._connectTimeout.cancel(),this._msg_queue=[],this._notify_msg_sent={},this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,1===this.socket.readyState&&this.socket.close(),delete this.socket),this.connectOptions.uris&&this.hostIndex<this.connectOptions.uris.length-1?(this.hostIndex++,this._doConnect(this.connectOptions.uris[this.hostIndex])):(void 0===e&&(e=l.OK.code,t=g(l.OK)),this.connected?(this.connected=!1,this.onConnectionLost&&this.onConnectionLost({errorCode:e,errorMessage:t})):4===this.connectOptions.mqttVersion&&this.connectOptions.mqttVersionExplicit===!1?(this._trace("Failed to connect V4, dropping back to V3"),this.connectOptions.mqttVersion=3,this.connectOptions.uris?(this.hostIndex=0,this._doConnect(this.connectOptions.uris[0])):this._doConnect(this.uri)):this.connectOptions.onFailure&&this.connectOptions.onFailure({invocationContext:this.connectOptions.invocationContext,errorCode:e,errorMessage:t}))},y.prototype._trace=function(){if(this.traceFunction){for(var e in arguments)"undefined"!=typeof arguments[e]&&(arguments[e]=JSON.stringify(arguments[e]));var t=Array.prototype.slice.call(arguments).join("");this.traceFunction({severity:"Debug",message:t})}if(null!==this._traceBuffer)for(var e=0,s=arguments.length;s>e;e++)this._traceBuffer.length==this._MAX_TRACE_ENTRIES&&this._traceBuffer.shift(),0===e?this._traceBuffer.push(arguments[e]):"undefined"==typeof arguments[e]?this._traceBuffer.push(arguments[e]):this._traceBuffer.push(" "+JSON.stringify(arguments[e]))},y.prototype._traceMask=function(e,t){var s={};for(var n in e)e.hasOwnProperty(n)&&(n==t?s[n]="******":s[n]=e[n]);return s};var M=function(e,t,s,n){var i;if("string"!=typeof e)throw new Error(g(l.INVALID_TYPE,[typeof e,"host"]));if(2==arguments.length){n=t,i=e;var o=i.match(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?(\/.*)$/);if(!o)throw new Error(g(l.INVALID_ARGUMENT,[e,"host"]));e=o[4]||o[2],t=parseInt(o[7]),s=o[8]}else{if(3==arguments.length&&(n=s,s="/mqtt"),"number"!=typeof t||0>t)throw new Error(g(l.INVALID_TYPE,[typeof t,"port"]));if("string"!=typeof s)throw new Error(g(l.INVALID_TYPE,[typeof s,"path"]));var r=-1!=e.indexOf(":")&&"["!=e.slice(0,1)&&"]"!=e.slice(-1);i="ws://"+(r?"["+e+"]":e)+":"+t+s}for(var a=0,c=0;c<n.length;c++){var h=n.charCodeAt(c);h>=55296&&56319>=h&&c++,a++}if("string"!=typeof n||a>65535)throw new Error(g(l.INVALID_ARGUMENT,[n,"clientId"]));var u=new y(i,e,t,s,n);this._getHost=function(){return e},this._setHost=function(){throw new Error(g(l.UNSUPPORTED_OPERATION))},this._getPort=function(){return t},this._setPort=function(){throw new Error(g(l.UNSUPPORTED_OPERATION))},this._getPath=function(){return s},this._setPath=function(){throw new Error(g(l.UNSUPPORTED_OPERATION))},this._getURI=function(){return i},this._setURI=function(){throw new Error(g(l.UNSUPPORTED_OPERATION))},this._getClientId=function(){return u.clientId},this._setClientId=function(){throw new Error(g(l.UNSUPPORTED_OPERATION))},this._getOnConnectionLost=function(){return u.onConnectionLost},this._setOnConnectionLost=function(e){if("function"!=typeof e)throw new Error(g(l.INVALID_TYPE,[typeof e,"onConnectionLost"]));u.onConnectionLost=e},this._getOnMessageDelivered=function(){return u.onMessageDelivered},this._setOnMessageDelivered=function(e){if("function"!=typeof e)throw new Error(g(l.INVALID_TYPE,[typeof e,"onMessageDelivered"]));u.onMessageDelivered=e},this._getOnMessageArrived=function(){return u.onMessageArrived},this._setOnMessageArrived=function(e){if("function"!=typeof e)throw new Error(g(l.INVALID_TYPE,[typeof e,"onMessageArrived"]));u.onMessageArrived=e},this._getTrace=function(){return u.traceFunction},this._setTrace=function(e){if("function"!=typeof e)throw new Error(g(l.INVALID_TYPE,[typeof e,"onTrace"]));u.traceFunction=e},this.connect=function(e){if(e=e||{},d(e,{timeout:"number",userName:"string",password:"string",willMessage:"object",keepAliveInterval:"number",cleanSession:"boolean",useSSL:"boolean",invocationContext:"object",onSuccess:"function",onFailure:"function",hosts:"object",ports:"object",mqttVersion:"number",mqttVersionExplicit:"boolean",uris:"object"}),void 0===e.keepAliveInterval&&(e.keepAliveInterval=60),e.mqttVersion>4||e.mqttVersion<3)throw new Error(g(l.INVALID_ARGUMENT,[e.mqttVersion,"connectOptions.mqttVersion"]));if(void 0===e.mqttVersion?(e.mqttVersionExplicit=!1,e.mqttVersion=4):e.mqttVersionExplicit=!0,void 0!==e.password&&void 0===e.userName)throw new Error(g(l.INVALID_ARGUMENT,[e.password,"connectOptions.password"]));if(e.willMessage){if(!(e.willMessage instanceof m))throw new Error(g(l.INVALID_TYPE,[e.willMessage,"connectOptions.willMessage"]));if(e.willMessage.stringPayload,"undefined"==typeof e.willMessage.destinationName)throw new Error(g(l.INVALID_TYPE,[typeof e.willMessage.destinationName,"connectOptions.willMessage.destinationName"]))}if("undefined"==typeof e.cleanSession&&(e.cleanSession=!0),e.hosts){if(!(e.hosts instanceof Array))throw new Error(g(l.INVALID_ARGUMENT,[e.hosts,"connectOptions.hosts"]));if(e.hosts.length<1)throw new Error(g(l.INVALID_ARGUMENT,[e.hosts,"connectOptions.hosts"]));for(var t=!1,n=0;n<e.hosts.length;n++){if("string"!=typeof e.hosts[n])throw new Error(g(l.INVALID_TYPE,[typeof e.hosts[n],"connectOptions.hosts["+n+"]"]));if(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?(\/.*)$/.test(e.hosts[n])){if(0==n)t=!0;else if(!t)throw new Error(g(l.INVALID_ARGUMENT,[e.hosts[n],"connectOptions.hosts["+n+"]"]))}else if(t)throw new Error(g(l.INVALID_ARGUMENT,[e.hosts[n],"connectOptions.hosts["+n+"]"]))}if(t)e.uris=e.hosts;else{if(!e.ports)throw new Error(g(l.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));if(!(e.ports instanceof Array))throw new Error(g(l.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));if(e.hosts.length!=e.ports.length)throw new Error(g(l.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));e.uris=[];for(var n=0;n<e.hosts.length;n++){if("number"!=typeof e.ports[n]||e.ports[n]<0)throw new Error(g(l.INVALID_TYPE,[typeof e.ports[n],"connectOptions.ports["+n+"]"]));var o=e.hosts[n],r=e.ports[n],a=-1!=o.indexOf(":");i="ws://"+(a?"["+o+"]":o)+":"+r+s,e.uris.push(i)}}}u.connect(e)},this.subscribe=function(e,t){if("string"!=typeof e)throw new Error("Invalid argument:"+e);if(t=t||{},d(t,{qos:"number",invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"}),t.timeout&&!t.onFailure)throw new Error("subscribeOptions.timeout specified with no onFailure callback.");if("undefined"!=typeof t.qos&&0!==t.qos&&1!==t.qos&&2!==t.qos)throw new Error(g(l.INVALID_ARGUMENT,[t.qos,"subscribeOptions.qos"]));u.subscribe(e,t)},this.unsubscribe=function(e,t){if("string"!=typeof e)throw new Error("Invalid argument:"+e);if(t=t||{},d(t,{invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"}),t.timeout&&!t.onFailure)throw new Error("unsubscribeOptions.timeout specified with no onFailure callback.");u.unsubscribe(e,t)},this.send=function(e,t,s,n){var i;if(0==arguments.length)throw new Error("Invalid argument.length");if(1==arguments.length){if(!(e instanceof m)&&"string"!=typeof e)throw new Error("Invalid argument:"+typeof e);if(i=e,"undefined"==typeof i.destinationName)throw new Error(g(l.INVALID_ARGUMENT,[i.destinationName,"Message.destinationName"]));u.send(i)}else i=new m(t),i.destinationName=e,arguments.length>=3&&(i.qos=s),arguments.length>=4&&(i.retained=n),u.send(i)},this.disconnect=function(){u.disconnect()},this.getTraceLog=function(){return u.getTraceLog()},this.startTrace=function(){u.startTrace()},this.stopTrace=function(){u.stopTrace()},this.isConnected=function(){return u.connected}};M.prototype={get host(){return this._getHost()},set host(e){this._setHost(e)},get port(){return this._getPort()},set port(e){this._setPort(e)},get path(){return this._getPath()},set path(e){this._setPath(e)},get clientId(){return this._getClientId()},set clientId(e){this._setClientId(e)},get onConnectionLost(){return this._getOnConnectionLost()},set onConnectionLost(e){this._setOnConnectionLost(e)},get onMessageDelivered(){return this._getOnMessageDelivered()},set onMessageDelivered(e){this._setOnMessageDelivered(e)},get onMessageArrived(){return this._getOnMessageArrived()},set onMessageArrived(e){this._setOnMessageArrived(e)},get trace(){return this._getTrace()},set trace(e){this._setTrace(e)}};var m=function(e){var t;if(!("string"==typeof e||e instanceof ArrayBuffer||e instanceof Int8Array||e instanceof Uint8Array||e instanceof Int16Array||e instanceof Uint16Array||e instanceof Int32Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array))throw g(l.INVALID_ARGUMENT,[e,"newPayload"]);t=e,this._getPayloadString=function(){return"string"==typeof t?t:c(t,0,t.length)},this._getPayloadBytes=function(){if("string"==typeof t){var e=new ArrayBuffer(r(t)),s=new Uint8Array(e);return a(t,s,0),s}return t};var s=void 0;this._getDestinationName=function(){return s},this._setDestinationName=function(e){if("string"!=typeof e)throw new Error(g(l.INVALID_ARGUMENT,[e,"newDestinationName"]));s=e};var n=0;this._getQos=function(){return n},this._setQos=function(e){if(0!==e&&1!==e&&2!==e)throw new Error("Invalid argument:"+e);n=e};var i=!1;this._getRetained=function(){return i},this._setRetained=function(e){if("boolean"!=typeof e)throw new Error(g(l.INVALID_ARGUMENT,[e,"newRetained"]));i=e};var o=!1;this._getDuplicate=function(){return o},this._setDuplicate=function(e){o=e}};return m.prototype={get payloadString(){return this._getPayloadString()},get payloadBytes(){return this._getPayloadBytes()},get destinationName(){return this._getDestinationName()},set destinationName(e){this._setDestinationName(e)},get qos(){return this._getQos()},set qos(e){this._setQos(e)},get retained(){return this._getRetained()},set retained(e){this._setRetained(e)},get duplicate(){return this._getDuplicate()},set duplicate(e){this._setDuplicate(e)}},{Client:M,Message:m}}(window);
//# sourceMappingURL=mqttws31.min.js.map
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
export const environment = {
production: true,
url: 'http://cloud-test.witium.com/api', // 对外访问witiumCloud2网地址
};
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
url: 'http://cloud-test.witium.com/api', // 对外访问witiumCloud2地址
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
// http://ionicframework.com/docs/theming/
@import '~@ionic/angular/css/core.css';
@import '~@ionic/angular/css/normalize.css';
@import '~@ionic/angular/css/structure.css';
@import '~@ionic/angular/css/typography.css';
@import '~@ionic/angular/css/display.css';
@import '~@ionic/angular/css/padding.css';
@import '~@ionic/angular/css/float-elements.css';
@import '~@ionic/angular/css/text-alignment.css';
@import '~@ionic/angular/css/text-transformation.css';
@import '~@ionic/angular/css/flex-utils.css';
/* You can add global styles to this file, and also import other style files */
* {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
html:lang(zh) .sg-common-class, html:lang(zh) body {
font-family: "Microsoft Yahei", 微软雅黑, Arial, STXihei, "boschsans", "Helvetica Neue", Helvetica, 华文细黑, sans-serif;
}
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
.mainCon {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow-y: auto;
}
.canClick {
color: #28c9bd;
cursor: pointer;
}
.sucCir {
width: 17px;
height: 17px;
border-radius: 17px;
background-color: #2ecc71;
display: inline-block;
vertical-align: middle;
box-shadow: #ccc 0.5px 0.5px 3px;
}
.errCir {
width: 17px;
height: 17px;
border-radius: 17px;
background-color: #9ea7b4;
display: inline-block;
vertical-align: middle;
box-shadow: #ccc 0.5px 0.5px 3px;
}
.topPart {
border-bottom: 1px solid #ddd;
box-shadow: #ddd 0.1px 0.2px 3px;
margin-bottom: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Ionic App</title>
<base href="/" />
<meta name="viewport" content="viewport-fit=cover, 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/png" href="assets/icon/favicon.png" />
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
</head>
<body>
<app-root></app-root>
</body>
</html>
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
* This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
*/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
// import 'core-js/es6/parse-int';
// import 'core-js/es6/parse-float';
// import 'core-js/es6/number';
// import 'core-js/es6/math';
// import 'core-js/es6/string';
// import 'core-js/es6/date';
// import 'core-js/es6/array';
// import 'core-js/es6/regexp';
// import 'core-js/es6/map';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/set';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect';
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Ionic Variables and Theming. For more info, please see:
// http://ionicframework.com/docs/theming/
/** Ionic CSS Variables **/
:root {
/** primary **/
--ion-color-primary: #3880ff;
--ion-color-primary-rgb: 56, 128, 255;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #3171e0;
--ion-color-primary-tint: #4c8dff;
/** secondary **/
--ion-color-secondary: #0cd1e8;
--ion-color-secondary-rgb: 12, 209, 232;
--ion-color-secondary-contrast: #ffffff;
--ion-color-secondary-contrast-rgb: 255, 255, 255;
--ion-color-secondary-shade: #0bb8cc;
--ion-color-secondary-tint: #24d6ea;
/** tertiary **/
--ion-color-tertiary: #7044ff;
--ion-color-tertiary-rgb: 112, 68, 255;
--ion-color-tertiary-contrast: #ffffff;
--ion-color-tertiary-contrast-rgb: 255, 255, 255;
--ion-color-tertiary-shade: #633ce0;
--ion-color-tertiary-tint: #7e57ff;
/** success **/
--ion-color-success: #10dc60;
--ion-color-success-rgb: 16, 220, 96;
--ion-color-success-contrast: #ffffff;
--ion-color-success-contrast-rgb: 255, 255, 255;
--ion-color-success-shade: #0ec254;
--ion-color-success-tint: #28e070;
/** warning **/
--ion-color-warning: #ffce00;
--ion-color-warning-rgb: 255, 206, 0;
--ion-color-warning-contrast: #ffffff;
--ion-color-warning-contrast-rgb: 255, 255, 255;
--ion-color-warning-shade: #e0b500;
--ion-color-warning-tint: #ffd31a;
/** danger **/
--ion-color-danger: #f04141;
--ion-color-danger-rgb: 245, 61, 61;
--ion-color-danger-contrast: #ffffff;
--ion-color-danger-contrast-rgb: 255, 255, 255;
--ion-color-danger-shade: #d33939;
--ion-color-danger-tint: #f25454;
/** dark **/
--ion-color-dark: #222428;
--ion-color-dark-rgb: 34, 34, 34;
--ion-color-dark-contrast: #ffffff;
--ion-color-dark-contrast-rgb: 255, 255, 255;
--ion-color-dark-shade: #1e2023;
--ion-color-dark-tint: #383a3e;
/** medium **/
--ion-color-medium: #989aa2;
--ion-color-medium-rgb: 152, 154, 162;
--ion-color-medium-contrast: #ffffff;
--ion-color-medium-contrast-rgb: 255, 255, 255;
--ion-color-medium-shade: #86888f;
--ion-color-medium-tint: #a2a4ab;
/** light **/
--ion-color-light: #f4f5f8;
--ion-color-light-rgb: 244, 244, 244;
--ion-color-light-contrast: #000000;
--ion-color-light-contrast-rgb: 0, 0, 0;
--ion-color-light-shade: #d7d8da;
--ion-color-light-tint: #f5f6f9;
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"test.ts",
"polyfills.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}
{
"rulesDirectory": [
"codelyzer"
],
"rules": {
"arrow-return-shorthand": true,
"callable-types": true,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"deprecation": {
"severity": "warn"
},
"eofline": true,
"forin": true,
"import-blacklist": [
true,
"rxjs/Rx"
],
"import-spacing": true,
"indent": [
true,
"spaces"
],
"interface-over-type-literal": true,
"label-position": true,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-super": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-misused-new": true,
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unnecessary-initializer": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"prefer-const": true,
"quotemark": [
true,
"single"
],
"radix": true,
"semicolon": [
true,
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"unified-signatures": true,
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"no-output-on-prefix": true,
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"directive-class-suffix": true
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment