Browse Source

[转盘项目]新建

master
baozw 4 years ago
commit
daf362315d
  1. 13
      .editorconfig
  2. 46
      .gitignore
  3. 15
      .vscode/launch.json
  4. 7
      README.md
  5. 143
      angular.json
  6. 12
      browserslist
  7. 32
      e2e/protractor.conf.js
  8. 23
      e2e/src/app.e2e-spec.ts
  9. 11
      e2e/src/app.po.ts
  10. 13
      e2e/tsconfig.json
  11. 32
      karma.conf.js
  12. 18426
      package-lock.json
  13. 67
      package.json
  14. 7
      proxy.config.json
  15. 27
      reset.css
  16. 5098
      src/app/_theming.scss
  17. 44
      src/app/app-routing.module.ts
  18. 1
      src/app/app.component.html
  19. 0
      src/app/app.component.scss
  20. 35
      src/app/app.component.spec.ts
  21. 37
      src/app/app.component.ts
  22. 48
      src/app/app.module.ts
  23. 31
      src/app/auth.guard.ts
  24. 744
      src/app/canvas-share-data.service.ts
  25. 3
      src/app/gis-management/gis-labeling/gis-labeling.component.html
  26. 84
      src/app/gis-management/gis-labeling/gis-labeling.component.scss
  27. 25
      src/app/gis-management/gis-labeling/gis-labeling.component.spec.ts
  28. 74
      src/app/gis-management/gis-labeling/gis-labeling.component.ts
  29. 11
      src/app/gis-management/gis-management-routing.module.ts
  30. 100
      src/app/gis-management/gis-management.module.ts
  31. 114
      src/app/home/home.component.html
  32. 1
      src/app/home/home.component.scss
  33. 25
      src/app/home/home.component.spec.ts
  34. 483
      src/app/home/home.component.ts
  35. 83
      src/app/http-interceptors/base-interceptor.ts
  36. 70
      src/app/http-interceptors/cache-token.service.ts
  37. 9
      src/app/http-interceptors/index.ts
  38. 38
      src/app/http-interceptors/tree.service.ts
  39. 51
      src/app/interface.ts
  40. 6
      src/app/m-token-k1/m-token-k1.component.html
  41. 3
      src/app/m-token-k1/m-token-k1.component.scss
  42. 25
      src/app/m-token-k1/m-token-k1.component.spec.ts
  43. 96
      src/app/m-token-k1/m-token-k1.component.ts
  44. 16
      src/app/m-token-k1/m-token-k1.service.spec.ts
  45. 67
      src/app/m-token-k1/m-token-k1.service.ts
  46. 15
      src/app/navigation/navigation.component.html
  47. 60
      src/app/navigation/navigation.component.scss
  48. 25
      src/app/navigation/navigation.component.spec.ts
  49. 44
      src/app/navigation/navigation.component.ts
  50. 114
      src/app/navigation/navigation.module.ts
  51. 50
      src/app/pages/home/home.component.html
  52. 5
      src/app/pages/home/home.component.scss
  53. 25
      src/app/pages/home/home.component.spec.ts
  54. 1131
      src/app/pages/home/home.component.ts
  55. 63
      src/app/pages/home2/home2.component.html
  56. 247
      src/app/pages/home2/home2.component.scss
  57. 25
      src/app/pages/home2/home2.component.spec.ts
  58. 348
      src/app/pages/home2/home2.component.ts
  59. 70
      src/app/pages/homedetail/homedetail.component.html
  60. 1
      src/app/pages/homedetail/homedetail.component.scss
  61. 25
      src/app/pages/homedetail/homedetail.component.spec.ts
  62. 563
      src/app/pages/homedetail/homedetail.component.ts
  63. 22
      src/app/pages/lockscreen/lockscreen.component.html
  64. 111
      src/app/pages/lockscreen/lockscreen.component.scss
  65. 25
      src/app/pages/lockscreen/lockscreen.component.spec.ts
  66. 21
      src/app/pages/lockscreen/lockscreen.component.ts
  67. 54
      src/app/pages/login/login.component.html
  68. 87
      src/app/pages/login/login.component.scss
  69. 25
      src/app/pages/login/login.component.spec.ts
  70. 58
      src/app/pages/login/login.component.ts
  71. 12
      src/app/pages/pages-routing.module.ts
  72. 1
      src/app/pages/pages.component.html
  73. 0
      src/app/pages/pages.component.scss
  74. 25
      src/app/pages/pages.component.spec.ts
  75. 15
      src/app/pages/pages.component.ts
  76. 117
      src/app/pages/pages.module.ts
  77. 280
      src/app/pages/personaldata/personaldata.component.html
  78. 110
      src/app/pages/personaldata/personaldata.component.scss
  79. 25
      src/app/pages/personaldata/personaldata.component.spec.ts
  80. 15
      src/app/pages/personaldata/personaldata.component.ts
  81. 81
      src/app/pages/register/register.component.html
  82. 88
      src/app/pages/register/register.component.scss
  83. 25
      src/app/pages/register/register.component.spec.ts
  84. 18
      src/app/pages/register/register.component.ts
  85. 43
      src/app/pipes/boolean.pipe.ts
  86. 9
      src/app/pipes/time.pipe.ts
  87. 178
      src/app/tabbar/tabbar.component.html
  88. 181
      src/app/tabbar/tabbar.component.scss
  89. 25
      src/app/tabbar/tabbar.component.spec.ts
  90. 135
      src/app/tabbar/tabbar.component.ts
  91. 18
      src/app/theme.scss
  92. 48
      src/app/ui/changepassword/changepassword.component.html
  93. 15
      src/app/ui/changepassword/changepassword.component.scss
  94. 44
      src/app/ui/changepassword/changepassword.component.ts
  95. 30
      src/app/ui/changepassword/equal-validator.directive.ts
  96. 24
      src/app/ui/collection-tools/addDisposalNode.html
  97. 38
      src/app/ui/collection-tools/addPlaneFigure.html
  98. 530
      src/app/ui/collection-tools/collection-tools.component.html
  99. 677
      src/app/ui/collection-tools/collection-tools.component.scss
  100. 25
      src/app/ui/collection-tools/collection-tools.component.spec.ts
  101. Some files were not shown because too many files have changed in this diff Show More

13
.editorconfig

@ -0,0 +1,13 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

46
.gitignore vendored

@ -0,0 +1,46 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

15
.vscode/launch.json vendored

@ -0,0 +1,15 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:4200",
"webRoot": "${workspaceFolder}"
}
]
}

7
README.md

@ -0,0 +1,7 @@
智能实战指挥平台-前端项目
---广西 演示
项目初始化:npm install
项目启动:npm start

143
angular.json

@ -0,0 +1,143 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"anxin119": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/anxin119",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss",
"./node_modules/swiper/css/swiper.min.css",
"./node_modules/viewerjs/dist/viewer.css"
],
"scripts": [
"node_modules/echarts/dist/echarts.js",
"src/assets/mTokenK1/mToken_K1.js",
"./node_modules/swiper/js/swiper.min.js",
"src/assets/echarts/echarts.common.min.js",
"src/assets/chartstheme/chongqing.js",
"src/assets/chartstheme/westeros.js",
"src/assets/chartstheme/echarts-skin.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "anxin119:build",
"proxyConfig": "proxy.config.json"
},
"configurations": {
"production": {
"browserTarget": "anxin119:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "anxin119:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "anxin119:serve"
},
"configurations": {
"production": {
"devServerTarget": "anxin119:serve:production"
}
}
}
}
}
},
"defaultProject": "anxin119",
"cli": {
"analytics": "6210f5d0-2cd7-43dc-b245-2140372d1b89"
}
}

12
browserslist

@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

32
e2e/protractor.conf.js

@ -0,0 +1,32 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
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.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

23
e2e/src/app.e2e-spec.ts

@ -0,0 +1,23 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('anxin119 app is running!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

11
e2e/src/app.po.ts

@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get(browser.baseUrl) as Promise<any>;
}
getTitleText() {
return element(by.css('app-root .content span')).getText() as Promise<string>;
}
}

13
e2e/tsconfig.json

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}

32
karma.conf.js

@ -0,0 +1,32 @@
// 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/anxin119'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

18426
package-lock.json generated

File diff suppressed because it is too large Load Diff

67
package.json

@ -0,0 +1,67 @@
{
"name": "anxin119",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.config.json --open",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^9.0.0",
"@angular/cdk": "^9.0.0",
"@angular/common": "~9.0.0",
"@angular/compiler": "~9.0.0",
"@angular/core": "~9.0.0",
"@angular/fire": "^5.3.0",
"@angular/forms": "~9.0.0",
"@angular/material": "^9.0.0",
"@angular/platform-browser": "~9.0.0",
"@angular/platform-browser-dynamic": "~9.0.0",
"@angular/router": "~9.0.0",
"@types/cesium": "^1.59.5",
"@types/swiper": "^5.3.0",
"angular-calendar": "^0.28.2",
"bson-objectid": "^1.3.1",
"cesium": "^1.64.0",
"date-fns": "^2.9.0",
"e-ngx-cesium": "^6.3.2",
"echarts": "^4.6.0",
"firebase": "^7.6.2",
"ng2-file-upload": "^1.4.0",
"ngx-countdown": "^9.0.1",
"ngx-echarts": "^4.2.2",
"ngx-perfect-scrollbar": "^8.0.0",
"pixi-filters": "^3.1.1",
"pixi.js": "^5.3.2",
"rxjs": "~6.5.4",
"swiper": "^5.3.7",
"tslib": "^1.10.0",
"viewerjs": "^1.6.2",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.900.1",
"@angular/cli": "~9.0.1",
"@angular/compiler-cli": "~9.0.0",
"@angular/language-service": "~9.0.0",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.7.5"
}
}

7
proxy.config.json

@ -0,0 +1,7 @@
{
"/api": {
"target": "http://121.37.20.190:8000",
"secure": false,
"changeOrigin": true
}
}

27
reset.css

@ -0,0 +1,27 @@
@charset "utf-8";
html,body,ul,ol,dl,li,dt,dd,p,form,input,h1,h2,h3,h4,h5,h6,section,article,aside,header,footer,nav,figure,time,mark,main,canvas{
margin:0;
padding:0;
font-size:16px;
}
b,strong,i,em,h1,h2,h3,h4,h5,h6{
font-weight:500;
font-style:normal;
}
img{
border:none;
}
a{
text-decoration: none;
color:#000;
ul,ol,li{
list-style:none;
}
.clearfn:after{
content:"";
clear:both;
display: block;
overflow:hidden;
height:0;
visibility: hidden;
}

5098
src/app/_theming.scss

File diff suppressed because it is too large Load Diff

44
src/app/app-routing.module.ts

@ -0,0 +1,44 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { NavigationComponent } from './navigation/navigation.component';
import { LockscreenComponent } from './pages/lockscreen/lockscreen.component';
import {HomeComponent} from './home/home.component'
//路由守卫
import {AuthGuard} from './auth.guard'
import {MTokenK1Component} from './m-token-k1/m-token-k1.component' //K1秘钥
import { LuckDrawComponent } from './ui/luck-draw/luck-draw.component';
const routes: Routes = [
//{path:'',redirectTo:'ui/plan',pathMatch:'full',},
/* {
path:'',
component:NavigationComponent,
// canActivate: [AuthGuard],//守卫验证
children:[
{path:'ui',loadChildren:() => import('./ui/ui.module').then(m => m.UiModule)},
// {path:'home',loadChildren:() => import('./pages/pages.module').then(m => m.PagesModule)},
// {path:'visualization',component: HomeComponent},
// {path:'gis',loadChildren:() => import('./gis-management/gis-management.module').then(m => m.GISManagementModule)}
]
}, */
{path:'',component:LuckDrawComponent},
// {path:'login',
// component:LoginComponent},
// {path:'getNoMToken',
// component:MTokenK1Component, canActivate: [AuthGuard],}, //K1秘钥验证失败是跳转页面
// {path:'lockscreen',
// component:LockscreenComponent,
// canActivate: [AuthGuard]}//守卫验证
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

1
src/app/app.component.html

@ -0,0 +1 @@
<router-outlet></router-outlet>

0
src/app/app.component.scss

35
src/app/app.component.spec.ts

@ -0,0 +1,35 @@
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'anxin119'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('anxin119');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('anxin119 app is running!');
});
});

37
src/app/app.component.ts

@ -0,0 +1,37 @@
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Data } from './interface'
import { Router,ActivatedRoute } from '@angular/router'
import {CacheTokenService} from './http-interceptors/cache-token.service'//引入服务
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private http:HttpClient,private router:Router,public token:CacheTokenService) { }
ngOnInit(): void {
var token = sessionStorage.getItem("token");
var refreshToken = sessionStorage.getItem("refreshToken");
if(token && refreshToken) {
this.http.post('/api/Account/RefreshToken', {
token: token,
refreshToken: refreshToken
}).subscribe((data: Data) => {
sessionStorage.setItem("level",data.level);
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
this.token.startUp()
})
}
}
}

48
src/app/app.module.ts

@ -0,0 +1,48 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatIconModule } from '@angular/material/icon';
import { MatSidenavModule } from '@angular/material/sidenav';
import { NavigationModule } from './navigation/navigation.module';
import { HomeComponent } from './home/home.component';
import { TabbarComponent } from './tabbar/tabbar.component';
import { PagesModule } from './pages/pages.module';
import { FormsModule } from '@angular/forms';
import { UiModule } from './ui/ui.module';
import { HttpClientModule } from '@angular/common/http';
import { httpInterceptorProviders } from './http-interceptors/index'
import {CacheTokenService} from './http-interceptors/cache-token.service'
import { TreeService } from'./http-interceptors/tree.service';
import { MTokenK1Component } from './m-token-k1/m-token-k1.component' //K1秘钥
import { CountdownModule } from 'ngx-countdown'; //倒计时插件
import { GISManagementModule } from './gis-management/gis-management.module';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
MTokenK1Component
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatButtonModule,
MatCheckboxModule,
MatSidenavModule,
NavigationModule,
MatIconModule,
PagesModule,
FormsModule,
HttpClientModule,
CountdownModule,
GISManagementModule
],
providers: [httpInterceptorProviders, CacheTokenService,TreeService],
bootstrap: [AppComponent]
})
export class AppModule { }

31
src/app/auth.guard.ts

@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {
}
// 路由守卫
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.checkLogin();
}
checkLogin(): boolean {
// 判断本地有没有token
const token = sessionStorage.getItem('token');
// 如果有token,允许访问
if (token) { return true; }
//如果没有token,跳转登录页
this.router.navigate(['/login']);
return false;
}
}

744
src/app/canvas-share-data.service.ts

@ -0,0 +1,744 @@
import { Injectable } from '@angular/core';
import {ReplaySubject} from 'rxjs';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CanvasShareDataService {
constructor() { }
private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1);
GameMode: any;
isChange = false; // 数据 是否改动
selectTemplateData: any; // 选择当前 模板数据
// 总平面图/建筑 楼层
selectStorey: any = {area: '', details: ''}; // 选择当前 楼层 数据
originalcompanyBuildingData: any; // 单位/建筑 数据
originaleveryStoreyData: any; // 总平面图/楼层/区域 楼层数据
// 总平面图/建筑 楼层
// 处置 节点
allDisposalNode: any = []; // 所有 处置节点
allNodeMarkers: any; // 灾情 标签信息
selectPanelPoint: any = {disposalNodeId: ''}; // 选择当前 数据节点
selectPanelPointBaseData: any = {description: '', notes: '', weather: '', airTemperature: '', windDirection: '', windScale: ''}; // 当前 数据节点 所对应的 天气,详情 数据节点
// 处置 节点
// 预案赋能 选择 车辆
selectCar: any = {Id: '', WaterYield: '', Foam: '', PeopleNum: '', Tonnage: '', Assignment: '', LinkCar: [], WaterOccupy: []};
// 预案赋能 选择 车辆
/**
*
*/
gameMode: GameMode = GameMode.BasicInformation;
facilityAssetsName = new Map<string, string>([
[ '消防水池', '消防水池'],
[ '疏散楼梯', '疏散楼梯'],
[ '消防电梯', '消防电梯'],
[ '避难区域', '避难区域'],
[ '安全出口', '安全出口'],
[ '地上消火栓', '室外消火栓' ],
[ '地下消火栓', '室外消火栓' ],
[ '室内消火栓', '室内消火栓' ],
[ '供水管网', '供水管网'],
[ '湿式自动喷淋系统', '湿式自动喷淋系统'],
[ '水幕系统', '水幕系统' ],
[ '消防泵房', '消防泵房'],
[ '水泵接合器(地上)', '水泵接合器'],
[ '水泵接合器(地下)', '水泵接合器'],
[ '水泵接合器(墙壁)', '水泵接合器'],
[ '消防水泵房', '消防水泵房'],
[ '箱式消火栓', '箱式消火栓'],
[ '固定水炮', '消防水炮' ],
[ '消防水罐', '储水罐'],
[ '消防水罐2', '储水罐'],
[ '卧式水罐', '储水罐'],
[ '消防泵', '水泵' ],
[ '泡沫泵', '水泵' ],
[ '泡沫泵房', '泡沫站'],
[ '泡沫栓', '泡沫栓' ],
[ '泡沫枪', '泡沫枪'],
[ '泡沫发生器', '泡沫发生器' ],
[ '消防管网', '消防管网'],
[ 'DCS控制室', 'DCS控制室']
]);
public getLinkCarName(car: any): any[] {
const linkCar = [];
car.assetData.Pipelines.forEach(pipeline => {
const icon = pipeline.assetData.LinkedObjects.find(i => i !== car);
if (icon.assetData.Type === 1) {
linkCar.push(icon.assetData.Name);
}
});
return linkCar;
}
public getWaterOccupyName(car: any): any[] {
const waterOccupy = [];
car.assetData.Pipelines.forEach(pipeline => {
const icon = pipeline.assetData.LinkedObjects.find(i => i !== car);
if (icon.assetData.Type === 0) {
waterOccupy.push(icon.assetData.Name);
}
});
return waterOccupy;
}
/**
* *
* @param message
* @returns {Observavle<any>}
*/
public sendMessage(message: any) {
this._sendMessage.next(message);
}
public getMessage(): Observable <any> {
return this._sendMessage.asObservable();
}
// 处置节点 筛选出 匹配数据 匹配不到 return undefined
findDisposalNode(parentId: string= null, name: string= null) {
if (parentId && name) { // 匹配 父id, name
const returnData = this.allDisposalNode.find(item => item.parentId === parentId && item.name === name);
return returnData;
} else { // 匹配 id
const returnData = this.allDisposalNode.find(item => item.id === parentId);
return returnData;
}
}
/**
*
*/
public getCompanyAdjoinInfo(): CompanyAdjoinInfo[] {
const list: CompanyAdjoinInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (item.Name === '毗邻') {
const adjoin = new CompanyAdjoinInfo();
adjoin.AssetId = item.Id;
adjoin.Id = '';
adjoin.ImageUrls = [];
adjoin.CompanyId = sessionStorage.getItem('companyId');
item.PropertyInfos.forEach(element => {
if (element.PropertyName === '方向') {
adjoin.Direction = Number(element.PropertyValue);
} else if (element.PropertyName === '名称/编号') {
adjoin.Name = element.PropertyValue;
} else if (element.PropertyType === PropertyType.Image) {
adjoin.ImageUrls.push(element.PropertyValue);
}
});
list.push(adjoin);
}
});
return list;
}
/**
*
*/
public getBuildingAdjoinInfo(): BuildingAdjoinInfo[] {
const list: BuildingAdjoinInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (item.Name === '毗邻') {
const adjoin = new BuildingAdjoinInfo();
adjoin.AssetId = item.Id;
adjoin.Id = '';
adjoin.BuildingId = this.selectStorey.buildingId;
adjoin.ImageUrls = [];
item.PropertyInfos.forEach(element => {
if (element.PropertyName === '方向') {
adjoin.Direction = Number(element.PropertyValue);
} else if (element.PropertyName === '名称/编号') {
adjoin.Name = element.PropertyValue;
} else if (element.PropertyType === PropertyType.Image) {
adjoin.ImageUrls.push(element.PropertyValue);
}
});
list.push(adjoin);
}
});
return list;
}
/**
*
*/
public getCompanyImportantLocations(): CompanyImportantLocationInfo[] {
const list: CompanyImportantLocationInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (item.Name === '重点部位') {
const important = new CompanyImportantLocationInfo();
important.AssetId = item.Id;
important.Id = '';
important.ImageUrls = [];
important.CompanyId = sessionStorage.getItem('companyId');
item.PropertyInfos.forEach(element => {
if (element.PropertyName === '名称/编号') {
important.Name = element.PropertyValue;
} else if (element.PropertyType === PropertyType.Image) {
important.ImageUrls.push(element.PropertyValue);
} else if (element.PropertyName === '主要危险性') {
important.Hazards = element.PropertyValue;
} else if (element.PropertyName === '使用性质') {
important.Nature = element.PropertyValue;
} else if (element.PropertyName === '所在位置') {
important.Position = element.PropertyValue;
} else if (element.PropertyName === '建筑结构') {
important.Structure = element.PropertyValue;
}
});
list.push(important);
}
});
return list;
}
/**
*
*/
public getBuildingImportantLocations(): BuildingImportantLocationInfo[] {
const list: BuildingImportantLocationInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (item.Name === '重点部位') {
const important = new BuildingImportantLocationInfo();
important.AssetId = item.Id;
important.Id = '';
important.ImageUrls = [];
important.BuildingId = this.selectStorey.buildingId;
item.PropertyInfos.forEach(element => {
if (element.PropertyName === '名称/编号') {
important.Name = element.PropertyValue;
} else if (element.PropertyType === PropertyType.Image) {
important.ImageUrls.push(element.PropertyValue);
} else if (element.PropertyName === '主要危险性') {
important.Hazards = element.PropertyValue;
} else if (element.PropertyName === '使用性质') {
important.Nature = element.PropertyValue;
} else if (element.PropertyName === '所在位置') {
important.Position = element.PropertyValue;
} else if (element.PropertyName === '建筑结构') {
important.Structure = element.PropertyValue;
}
});
list.push(important);
}
});
return list;
}
/**
*
*/
public getAllCompanyFacilityAssetInfo(): CompanyFacilityAssetInfo[] {
const list: CompanyFacilityAssetInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (this.facilityAssetsName.has(item.Name)) {
const facility = new CompanyFacilityAssetInfo();
facility.CompanyId = sessionStorage.getItem('companyId');
facility.AssetId = item.Id;
facility.Id = '';
facility.Name = this.facilityAssetsName.get(item.Name);
facility.AssetName = item.Name;
facility.PropertyInfos = item.PropertyInfos;
facility.SitePlanId = item.FloorId;
list.push(facility);
}
});
return list;
}
/**
*
*/
public getAllBuildingFacilityAssetInfo(): BuildingFacilityAssetInfo[] {
const list: BuildingFacilityAssetInfo[] = [];
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
const item = this.originalcompanyBuildingData.data[key];
if (this.facilityAssetsName.has(item.Name)) {
const facility = new BuildingFacilityAssetInfo();
facility.BuildingId = this.selectStorey.buildingId;
facility.AssetId = item.Id;
facility.Id = '';
facility.Name = this.facilityAssetsName.get(item.Name);
facility.AssetName = item.Name;
facility.PropertyInfos = item.PropertyInfos;
facility.BuildingAreaId = item.FloorId;
list.push(facility);
}
});
return list;
}
}
/**
*
*/
export class CompanyAdjoinInfo {
public CompanyId: string;
public Id: string;
public Name: string;
public Direction: number;
public ImageUrls: string[] = [];
public AssetId: string;
}
/**
*
*/
export class BuildingAdjoinInfo {
public BuildingId: string;
public Id: string;
public Name: string;
public Direction: number;
public ImageUrls: string[];
public AssetId: string;
}
/**
*
*/
export class BuildingImportantLocationInfo {
public BuildingId: string;
public Id: string;
public Name: string;
public Position: string;
public Structure: string;
public Nature: string;
public Hazards: string;
public ImageUrls: string[];
public AssetId: string;
}
/**
*
*/
export class CompanyImportantLocationInfo {
public CompanyId: string;
public Id: string;
public Name: string;
public Position: string;
public Structure: string;
public Nature: string;
public Hazards: string;
public ImageUrls: string[];
public AssetId: string;
}
/**
*
*/
export class CompanyFacilityAssetInfo {
public Id: string;
public Name: string;
public AssetName: string;
public PropertyInfos: string;
public AssetId: string;
public CompanyId: string;
public SitePlanId: string;
}
/**
*
*/
export class BuildingFacilityAssetInfo {
public Id: string;
public Name: string;
public AssetName: string;
public PropertyInfos: string;
public AssetId: string;
public BuildingId: string;
public BuildingAreaId: string;
}
/**
*
*/
export class PropertyInfo {
// 标记位
public Tag: string;
// 属性书序
public Order: number;
// 是否启用
public Enabled: boolean;
// 是否可见
public Visible: boolean;
// 必填
public Required: boolean;
// 验证规则名称
public RuleName: string;
// 验证规则值
public RuleValue: string;
// 物理单位
public PhysicalUnit: string;
// 属性名称
public PropertyName: string;
// 属性类型
public PropertyType: PropertyType;
// 属性值
public PropertyValue: string;
}
/**
*
*/
export enum PropertyType {
// 单行文本。
SingleText,
// 多行文本。
MultipleText,
// 数值。
Numeric,
// 图片。
Image,
// 图片数值,专用于描述图片数量。
ImageNumeric,
// 方向
Direction,
// 布尔类型。
Boolean,
// 供给区域
SupplyArea,
// 供给类型
SupplyType
}
/**
*
*/
export class DisposalNode {
/**
*
*/
public Id: string;
/**
*
*/
public Name: string;
/**
*
*/
public Level: number;
/**
*
*/
public Order: number;
/**
*
*/
public Description: string;
/**
*
*/
public Notes: string;
/**
*
*/
public Weather: string;
/**
*
*/
public AirTemperature?: number;
/**
*
*/
public WindDirection: Direction;
/**
*
*/
public WindScale: WindScale;
/**
*
*/
public ImageNames: string[];
/**
*
*/
public ImageUrls: string[];
/**
*
*/
public ParentId: string;
/**
*
*/
public DisasterId: string;
/**
*
*/
public PlanComponentId: string;
/**
*
*/
public CompanyId: string;
/**
*
*/
public SitePlanId: string;
/**
*
*/
public BuildingId: string;
/**
*
*/
public BuildingAreaId: string;
}
/**
*
*/
export enum Direction {
/**
*
*/
East,
/**
* 西
*/
West,
/**
*
*/
South,
/**
*
*/
North,
/**
*
*/
Southeast,
/**
* 西
*/
Southwest,
/**
*
*/
Northeast,
/**
* 西
*/
Northwest
}
/**
*
*/
export enum WindScale {
WS0,
WS1,
WS2,
WS3,
WS4,
WS5,
WS6,
WS7,
WS8,
WS9,
WS10,
WS11,
WS12,
WS13,
WS14,
WS15,
WS16,
WS17,
WS18
}
/**
*
*/
export class DisposalNodeData {
/**
*
*/
public Id: string;
/**
*
*/
public Data: FloorNodeData;
/**
*
*/
public Version: string;
/**
*
*/
public DisposalNodeId: string;
/**
*
*/
public PlanComponentId: string;
}
/**
*
*/
export class FloorNodeData {
/**
*
*/
public Stock: Map<string, AssetData> = new Map<string, AssetData>();
/**
*
*/
public Increment: Map<string, AssetData> = new Map<string, AssetData>();
/**
*
*/
public DefinedIncrement: Map<string, AssetData> = new Map<string, AssetData>();
}
/**
*
*/
export class AssetData {
/// <summary>
/// 模板编号
/// </summary>
public TemplateId: string;
/// <summary>
/// 编号
/// </summary>
public Id: string;
/// <summary>
/// 名称
/// </summary>
public Name: string;
/// <summary>
/// 角度
/// </summary>
public Angle: number;
/// <summary>
/// 颜色
/// </summary>
public Color: string;
/// <summary>
/// 坐标
/// </summary>
public Point: PIXI.Point;
/// <summary>
/// 宽度
/// </summary>
public Width: number;
/// <summary>
/// 高度
/// </summary>
public Height: number;
/// <summary>
/// 是否启用
/// </summary>
public Enabled: boolean;
/// <summary>
/// 填充方式
/// </summary>
public FillMode: FillMode;
/// <summary>
/// 图片地址
/// </summary>
public ImageUrl: string;
/// <summary>
/// 是否固定大小
/// </summary>
public FixedSize: boolean;
/// <summary>
/// 点路径
/// </summary>
public MultiPoint: PIXI.Point[];
/// <summary>
/// 建筑ID
/// </summary>
public BuildingId: string;
/// <summary>
/// 单位ID
/// </summary>
public CompanyId: string;
/// <summary>
/// 楼层编号
/// </summary>
public FloorId: string;
/// <summary>
/// 楼层名称
/// </summary>
public FloorName: string;
/// <summary>
/// 消防要素编号
/// </summary>
public FireElementId: string;
/// <summary>
/// 属性列表
/// </summary>
public PropertyInfos: PropertyInfo[];
/// <summary>
/// 交互方式
/// </summary>
public InteractiveMode: InteractiveMode;
/// <summary>
/// 是否来自建筑
/// </summary>
public IsFromBuilding: boolean;
/// <summary>
/// 渲染方式。
/// </summary>
public DrawMode: ImageType;
/// <summary>
/// 9宫格边框数值。
/// </summary>
public Border: Border;
/// <summary>
/// 厚度。
/// </summary>
public Thickness: number;
/// <summary>
/// 素材类型
/// </summary>
public GameMode: GameMode;
}
/**
*
*/
export enum GameMode {
BasicInformation,
Assignment,
Demo
}
/**
*
*/
export enum FillMode {
Color,
Image
}
/**
*
*/
export enum InteractiveMode {
/**
*
*/
Single,
/**
*
*/
Multiple,
/**
*
*/
MultipleClosed
}
/**
*
*/
export enum ImageType {
Simple = 0,
Sliced = 1,
Tiled = 2,
Filled = 3
}
/**
*
*/
export class Border {
public x: number;
public y: number;
public z: number;
public w: number;
}

3
src/app/gis-management/gis-labeling/gis-labeling.component.html

@ -0,0 +1,3 @@
<div id="map" class="mapbox">
</div>

84
src/app/gis-management/gis-labeling/gis-labeling.component.scss

@ -0,0 +1,84 @@
.mapbox{
width: 100%;
height: 100%;
}
// .content-window-card {
// position: relative;
// box-shadow: none;
// bottom: 0;
// left: 0;
// width: auto;
// padding: 0;
// }
// .content-window-card p {
// height: 20px;
// }
// .custom-info {
// border: solid 1px silver;
// }
// div.info-top {
// position: relative;
// background: none repeat scroll 0 0 #F9F9F9;
// border-bottom: 1px solid #CCC;
// border-radius: 5px 5px 0 0;
// }
// div.info-top div {
// display: inline-block;
// color: #333333;
// font-size: 14px;
// font-weight: bold;
// line-height: 31px;
// padding: 0 10px;
// }
// div.info-top img {
// position: absolute;
// top: 10px;
// right: 10px;
// transition-duration: 0.25s;
// }
// div.info-top img:hover {
// box-shadow: 0px 0px 5px #000;
// }
// div.info-middle {
// font-size: 12px;
// padding: 10px 6px;
// line-height: 20px;
// }
// div.info-bottom {
// height: 0px;
// width: 100%;
// clear: both;
// text-align: center;
// }
// div.info-bottom img {
// position: relative;
// z-index: 104;
// }
// span {
// margin-left: 5px;
// font-size: 11px;
// }
// .info-middle img {
// float: left;
// margin-right: 6px;
// }

25
src/app/gis-management/gis-labeling/gis-labeling.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { GisLabelingComponent } from './gis-labeling.component';
describe('GisLabelingComponent', () => {
let component: GisLabelingComponent;
let fixture: ComponentFixture<GisLabelingComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GisLabelingComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GisLabelingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

74
src/app/gis-management/gis-labeling/gis-labeling.component.ts

@ -0,0 +1,74 @@
import { Component, OnInit ,Renderer2,ElementRef } from '@angular/core';
declare var AMap: any;
@Component({
selector: 'app-gis-labeling',
templateUrl: './gis-labeling.component.html',
styleUrls: ['./gis-labeling.component.scss']
})
export class GisLabelingComponent implements OnInit {
constructor(private elementRef: ElementRef,public renderer2: Renderer2) { }
map:any //地图
ngOnInit(): void {
setTimeout(() => {
this.map = new AMap.Map('map');
//给地图增加点击事件
this.map.on('click', (ev)=>{
// 触发事件的对象
var target = ev.target;
// 触发事件的地理坐标,AMap.LngLat 类型
var lnglat = ev.lnglat;
// 触发事件的像素坐标,AMap.Pixel 类型
var pixel = ev.pixel;
// 触发事件类型
var type = ev.type;
let marker = new AMap.Marker({
position:[lnglat.lng, lnglat.lat]//位置
})
// marker.content = '我是第' + (i + 1) + '个Marker';
marker.setMap(this.map)
AMap.event.addListener(marker, 'click', () => {
infoWindow.open(this.map, marker.getPosition());
console.log(222,marker)
setTimeout(() => {
this.renderer2.listen(this.elementRef.nativeElement.querySelector('#lnglat2container'),'click',(event)=>{
console.log(111)
})
}, 0);
});
});
var infoWindowContent =
'<div className="custom-infowindow input-card">' +
'<label style="color:grey">故宫博物院</label>' +
'<div class="input-item">' +
'<div class="input-item-prepend">' +
'<span class="input-item-text" >经纬度</span>' +
'</div>' +
'<input id="lnglat" type="text" />' +
'</div>' +
'<input id="lnglat2container" type="button" class="btn" value="获取该位置经纬度"/>' +
'</div>';
var infoWindow = new AMap.InfoWindow({
content: infoWindowContent,
offset: new AMap.Pixel(0, -45)
});
// var xxx  =  this.el.nativeElement.querySelector('#lnglat2container')
let yyy = document.getElementById('lnglat2container');
}, 0);
}
getLngLat(){
console.log(123)
}
}

11
src/app/gis-management/gis-management-routing.module.ts

@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class GisRoutingModule { }

100
src/app/gis-management/gis-management.module.ts

@ -0,0 +1,100 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GisLabelingComponent } from './gis-labeling/gis-labeling.component';
import {A11yModule} from '@angular/cdk/a11y';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {PortalModule} from '@angular/cdk/portal';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CdkStepperModule} from '@angular/cdk/stepper';
import {CdkTableModule} from '@angular/cdk/table';
import {CdkTreeModule} from '@angular/cdk/tree';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatBadgeModule} from '@angular/material/badge';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import {MatButtonModule} from '@angular/material/button';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatCardModule} from '@angular/material/card';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatChipsModule} from '@angular/material/chips';
import {MatStepperModule} from '@angular/material/stepper';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatDialogModule} from '@angular/material/dialog';
import {MatDividerModule} from '@angular/material/divider';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatMenuModule} from '@angular/material/menu';
import {MatNativeDateModule, MatRippleModule, MatOption} from '@angular/material/core';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatSliderModule} from '@angular/material/slider';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSortModule} from '@angular/material/sort';
import {MatTableModule} from '@angular/material/table';
import {MatTabsModule} from '@angular/material/tabs';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatTreeModule} from '@angular/material/tree';
import { FormsModule } from '@angular/forms';
import { GisRoutingModule } from './gis-management-routing.module';
@NgModule({
declarations: [GisLabelingComponent],
imports: [
CommonModule,
CommonModule,
GisRoutingModule,
A11yModule,
CdkStepperModule,
CdkTableModule,
CdkTreeModule,
DragDropModule,
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
PortalModule,
ScrollingModule,
FormsModule
]
})
export class GISManagementModule { }

114
src/app/home/home.component.html

@ -0,0 +1,114 @@
<div class="main" style="background-color: #000D12;">
<div class="main-top">
<!-- 左侧 -->
<div class="main-left">
<div class="panel panel04">
<div class="panel-hd">
<a href="javascript:;" class="panel-more"><svg width="18" height="12" xmlns="http://www.w3.org/2000/svg"><g fill="#93FCFF" fill-rule="evenodd" opacity=".6"><path d="M0 0h18v2H0zM0 5h18v2H0zM0 10h18v2H0z"/></g></svg></a>
</div>
<div class="panel-bd">
<div id="chartHynyxf" class="chart-item"></div>
</div>
</div>
<div class="box-wrap mt">
<div class="panel-hd">
<div class="panel-tit" style="color: white;">计划完成情况</div>
</div>
<div class="panel-bd">
<div class="progress-list">
<div class="progress-item">
<div class="progress-name">本年时间进度</div>
<div class="progress">
<div class="progress-num">47%</div>
<div class="progress-bar">
<div style="width: 47%;" class="progress-bar-inner progress-bar-gradient"></div>
</div>
</div>
</div>
<div class="progress-item">
<div class="progress-name">年计划完成率</div>
<div class="progress">
<div class="progress-num">17%</div>
<div class="progress-bar">
<div style="width: 17%;" class="progress-bar-inner progress-bar-gradient"></div>
</div>
</div>
</div>
<div class="progress-item">
<div class="progress-name">日历进度差</div>
<div class="progress">
<div class="progress-num">63%</div>
<div class="progress-bar">
<div style="width: 63%;" class="progress-bar-inner progress-bar-gradient"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 中间 -->
<div class="main-center">
<!-- 数量统计 -->
<div class="number-area">
<div class="number-box">
<div class="number-tit" style="color: white;">预案编制总量</div>
<ul class="count-number">
<li class="count-num-item" *ngFor="let item of planQuantity"><span class="num">{{item}}</span></li>
</ul>
</div>
<div class="number-item">
<div class="item-tit">采集单位总量</div>
<div class="item-txt" id="number01">{{keyUnitQuantity}}</div>
</div>
<div class="number-item">
<div class="item-tit">重点关注单位总量</div>
<div class="item-txt" id="number02">{{dataQuantity}}</div>
</div>
</div>
<!-- 图表 -->
<div class="panel panel06 mt-mlger">
<div class="panel-bd">
<div id="chartQusj" class="chart-item"></div>
</div>
</div>
</div>
<!-- 右侧 -->
<div class="main-right">
<div class="box-wrap">
<div class="panel-bd">
<div class="total-box">
<div class="total-item">
<div class="total-name">三维预案总数</div>
<div class="total-num">{{threeDimensional}}</div>
</div>
<div class="total-item">
<div class="total-name">二维预案总数</div>
<div class="total-num">{{twoDimensional}}</div>
</div>
<div class="total-item">
<div class="total-name">卡片预案总数</div>
<div class="total-num">{{cardDimensional}}</div>
</div>
<div class="total-item">
<div class="total-name">其他预案总数</div>
<div class="total-num">{{otherDimensional}}</div>
</div>
</div>
</div>
</div>
<div class="box-wrap mt">
<div class="panel-bd">
<div id="chartZdgzqy" class="chart-item"></div>
</div>
</div>
</div>
</div>
<div class="main-bottom">
<div class="panel panel05">
<div class="panel-bd">
<div id="chartDwsjcj" class="chart-item"></div>
</div>
</div>
</div>
</div>

1
src/app/home/home.component.scss

@ -0,0 +1 @@
@import "../../assets/css/newStyle.css";

25
src/app/home/home.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomeComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

483
src/app/home/home.component.ts

@ -0,0 +1,483 @@
import { Component, OnInit, Renderer2, ElementRef } from '@angular/core';
import { HttpClient } from '@angular/common/http'
declare var echarts: any;
declare var AMap: any;
declare var AMapUI: any;
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(private http:HttpClient, private render2: Renderer2,public element: ElementRef) { }
visualizationData:any; //统计分析数据
planQuantity:any = ['0','0']; //预案编制总量
keyUnitQuantity:any; //单位总量
dataQuantity:any; //重点关注单位预案数量
threeDimensional:any; //三维预案总量
twoDimensional:any; //三维预案总量
cardDimensional:any; //卡片预案总量
otherDimensional:any; //其他预案总量
ngOnInit() {
this.getVisualizationData()
}
ngAfterViewInit(): void {
}
//获取统计分析数据
getVisualizationData () {
this.http.get('/api/StatisticsAnalysis').subscribe((data:any)=>{
this.visualizationData = data
let numbers = (data.planStatistics.totalCount).toString();
for (var i = 0; i < numbers.length; i++) {
this.planQuantity.push(numbers[i]);
}
this.keyUnitQuantity = data.companyStatistics.totalCount
this.dataQuantity = data.planStatistics.followedCount
this.threeDimensional = data.planStatistics.planTypeStatistics.plan3DCount
this.twoDimensional = data.planStatistics.planTypeStatistics.plan2DCount
this.cardDimensional = data.planStatistics.planTypeStatistics.planCardCount
this.otherDimensional = data.planStatistics.planTypeStatistics.planOtherCount
this.unitType()
this.unitData()
this.teamData()
this.keyUnit()
})
}
//单位类型统计
unitType () {
let data = []
let color = ['#BE1B94', '#E29217', '#2AFF71', '#BE1B4D', '#D1E217', '#65F5F3','#BE1B94', '#E29217', '#2AFF71', '#BE1B4D', '#D1E217', '#65F5F3'];
//处理数据
this.visualizationData.companyStatistics.buildingTypeStatistics.buildingTypes.forEach((element,index) => {
let msg = {
name: element.buildingTypeName,
value: element.count,
itemStyle: {
color: color[index],
}
}
data.push(msg)
});
//处理数据
var chartHynyxf = echarts.init(document.getElementById('chartHynyxf'), 'skinUpp');
var categoryData = [];
for (var i = 0; i < data.length; i++) {
categoryData.push(data[i].name);
}
var option = {
// 标题
title: {
text: '采集单位类型统计',
top: 0
},
//图例
legend: {
data: ['单位类型统计'],
show: false
},
grid: {
left: 90,
top:40,
// right:8,
width: '70%' ,
height: '70%' ,
},
//提示框
tooltip: {
trigger: 'item',
},
// x轴
xAxis: {
type: 'value'
},
// y轴
yAxis: {
type: 'category',
data: categoryData,
axisLabel: { margin: 3,fontSize:11},
},
// 数据
series: [
{
name: '单位类型统计',
type: 'bar',
label: {
show: true,
position: 'right',
color:'#fff'
},
data: data,
},
],
};
chartHynyxf.setOption(option);
}
//单位数据统计
unitData () {
let data = []
let unitData = []
let planData = []
//处理数据
this.visualizationData.companyStatistics.organizationStatistics.organizations.forEach(element => {
data.push(element.organizationName)
unitData.push(element.count)
});
this.visualizationData.planStatistics.organizationStatistics.organizations.forEach(element => {
planData.push(element.count)
});
//处理数据
var chartDwsjcj = echarts.init(document.getElementById('chartDwsjcj'), 'skinUpp');
var option = {
color: ['#FB33C2', '#00CFF0', '#2C3DE0'],
// 标题
title: {
text: '单位数据采集数量与单位预案数量统计',
left: 0,
top: 0,
},
grid: {
left: 30,
right: 0,
},
//图例
legend: {
top: 0,
data: ['单位数据采集数量', '单位预案编制数量', ],
icon: 'circle',
itemGap: 20,
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
data: data,
axisLabel: {
interval: 0,
formatter:function(value){
var ret = "";//拼接加\n返回的类目项
var maxLength = 5;//每项显示文字个数
var valLength = value.length;//X轴类目项的文字个数
var rowN = Math.ceil(valLength / maxLength); //类目项需要换行的行数
if (rowN > 1) { //如果类目项的文字大于1,
for (var i = 0; i < rowN; i++) {
var temp = "";//每次截取的字符串
var start = i * maxLength;//开始截取的位置
var end = start + maxLength;//结束截取的位置
//这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
temp = value.substring(start, end) + "\n";
ret += temp;
} //凭借最终的字符串
return ret;
}else { return value; }
} //function
}
},
// y轴
yAxis: {
type: 'value',
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255,255,255,.4)'
}
},
},
// 数据
series: [
{
name: '单位数据采集数量',
type: 'bar',
data: unitData,
label: {
show: true,
position: "top",
formatter: '{c}',
color: "#fff",
},
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(254,51,194,1)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(254,51,194,.5)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
}
}, {
name: '单位预案编制数量',
type: 'bar',
data: planData,
label: {
show: true,
position: "top",
formatter: '{c}',
color: "#fff",
},
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(0,220,254,1)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(1,104,191,1)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
}
}
],
};
chartDwsjcj.setOption(option);
}
//全队数据采集和预案编制数量统计
teamData () {
let unitData = []
let planData = []
//处理数据
this.visualizationData.companyStatistics.trendStatistics.added.forEach(element => {
unitData.push(element.count)
});
this.visualizationData.planStatistics.trendStatistics.added.forEach(element => {
planData.push(element.count)
});
//处理数据
var chartQusj = echarts.init(document.getElementById('chartQusj'), 'skinUpp');
var option = {
grid: {
top: 50,
left: 30,
right: 20,
bottom: 20,
},
// 标题
title: {
text: '全队数据采集和预案编制数量统计',
top: -4,
left: 0
},
//图例
legend: {
top: 0,
data: ['单位预案编制数量', '单位数据采集数量'],
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
boundaryGap: false,
},
// y轴
yAxis: {
type: 'value',
name: '个'
},
// 数据
series: [{
name: '单位预案编制数量',
type: 'line',
data: planData,
// showSymbol: true,
// symbolSize:6,
// smooth: false,
// label: {
// show: true,
// },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(60,103,195,1)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(0,194,255,.2)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
}
},
{
name: '单位数据采集数量',
type: 'line',
data: unitData,
},
],
};
chartQusj.setOption(option);
}
//重点关注企业预案完成情况
keyUnit () {
let data = []
var realEnd = [];
var shouldEnd = [500,300,300,300,300,300,300,150];
//处理数据
this.visualizationData.planStatistics.buildingTypeStatistics.buildingTypes.forEach(element => {
data.push(element.buildingTypeName)
realEnd.push(element.count)
});
//处理数据
var chartZdgzqy = echarts.init(document.getElementById('chartZdgzqy'), 'skinUpp');
var option = {
color: ['#FB33C2', '#00CFF0', '#2C3DE0'],
// 标题
title: {
text: '重点关注企业预案完成情况',
left: 0,
top: 0,
},
grid: {
left: 30,
bottom: 45
},
//图例
legend: {
top: 0,
data: ['单位类型统计'],
icon: 'circle',
itemGap: 20,
show: false
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
axisLine: false,
data: data,
axisLabel: {
interval: 0,
formatter:function(value){
var ret = "";//拼接加\n返回的类目项
var maxLength = 3;//每项显示文字个数
var valLength = value.length;//X轴类目项的文字个数
var rowN = Math.ceil(valLength / maxLength); //类目项需要换行的行数
if (rowN > 1) { //如果类目项的文字大于1,
for (var i = 0; i < rowN; i++) {
var temp = "";//每次截取的字符串
var start = i * maxLength;//开始截取的位置
var end = start + maxLength;//结束截取的位置
//这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
temp = value.substring(start, end) + "\n";
ret += temp;
} //凭借最终的字符串
return ret;
}else { return value; }
} //function
}
},
// y轴
yAxis: [
{
type: 'value',
axisLine: false,
}, {
type: 'value',
axisLine: false,
}
],
// 数据
series: [
// {
// name: '单位类型统计',
// type: 'line',
// data: data,
// itemStyle: {
// color: '#fff'
// },
// label: {
// show: false,
// position: "top",
// formatter: '{c}',
// color: "#fff",
// },
// },
{
name: '目标完成预案数量',
type: 'bar',
barWidth: '16px',
barGap: '-100%',
itemStyle: {
color: '#025D7C'
},
label: {
show: false,
},
data: shouldEnd,
},
{
name: '完成预案数量',
type: 'bar',
barWidth: '16px',
yAxisIndex: 1,
itemStyle: {
color: '#79CBE8'
},
label: {
show: false,
position: "insideTop",
formatter: '{c}',
color: "#fff",
},
data: realEnd,
}
],
};
chartZdgzqy.setOption(option);
}
}

83
src/app/http-interceptors/base-interceptor.ts

@ -0,0 +1,83 @@
import { Injectable } from '@angular/core';
import {
HttpClient, HttpEvent, HttpInterceptor, HttpHandler, HttpRequest,
HttpErrorResponse
} from '@angular/common/http';
import { throwError } from 'rxjs'
import { catchError, retry } from 'rxjs/operators';
import { Router,ActivatedRoute } from '@angular/router'
import {CacheTokenService} from './cache-token.service'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
//baseurl
// const baseurl = 'http://39.106.78.171:8008';
@Injectable()
export class BaseInterceptor implements HttpInterceptor {
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,public snackBar: MatSnackBar) {}
intercept(req, next: HttpHandler) {
let newReq = req.clone({
url: req.hadBaseurl ? `${req.url}` : `${req.url}`,
});
if(!req.cancelToken) {
/*获取token*/
let token = sessionStorage.getItem("token") || ''
/*此处设置额外请求头,token令牌*/
newReq.headers =
newReq.headers.set('Authorization', `Bearer ${token}`)
}
// 携带请求头发送下一次请求
return next.handle(newReq)
.pipe(
//箭头函数,注意this指向
catchError((err) => this.handleError(err))
)
}
// 捕获错误
//401 token过期 403没权限!!! 400参数错误 404未找到 614刷新令牌过期!!!
private handleError(error: HttpErrorResponse) {
// 用户认证失败返回登录页
if (error.status === 401||error.status === 614) {
this.token.delete()
sessionStorage.clear()
window.localStorage.clear()
this.router.navigate(['ui/plan'])
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('用户认证信息过期,请重新登录','确定',config);
}
if (error.status === 403) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('对不起,您无此权限','确定',config);
}
if (error.status === 400) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请核对您的输入格式是否正确','确定',config);
}
if (error.error instanceof ErrorEvent) {
// 发生客户端或网络错误。相应处理。
console.error('An error occurred:', error.error.message);
} else {
// 服务端返回http状态码
// 服务端返回错误信息
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// 返回带有面向用户的错误信息
return throwError(
error.error);
};
}

70
src/app/http-interceptors/cache-token.service.ts

@ -0,0 +1,70 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
@Injectable({
providedIn: 'root'
})
export class CacheTokenService {
constructor(private http:HttpClient,public snackBar: MatSnackBar) { }
//登录
loginData = {name: 'superadmin', password: 'anxin119'} //登录账号信息
login () {
return new Promise ((resolve,reject)=>{
sessionStorage.setItem("buildingTypeId",'5e7c9078a3050b1a840ed4ba'); //建筑类型
sessionStorage.setItem("planId",'5f6957a29e91f4410005f5d7'); //预案ID
sessionStorage.setItem("companyId",'5f67042b9e91f4410005f55c'); //单位ID
this.http.post('/api/Account/SignIn',this.loginData).subscribe((data:any)=>{
sessionStorage.setItem("level",data.level);
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('自动登录成功','确定',config);
this.startUp()
resolve('success')
},(err) => { //捕获错误
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
})
}
//登录
public timer;
//刷新token令牌定时器
startUp = ():void=>{
window.clearInterval(this.timer) //清一遍定时器
this.timer = window.setInterval(()=>{
var token = sessionStorage.getItem("token");
var refreshToken = sessionStorage.getItem("refreshToken");
this.http.post('/api/Account/RefreshToken', {
token: token,
refreshToken: refreshToken
}).subscribe((data:any) => {
sessionStorage.setItem("level",data.level);
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
})
},18*60*1000)
}
//删除定时器
delete = ():void=> {
window.clearInterval(this.timer)
}
}

9
src/app/http-interceptors/index.ts

@ -0,0 +1,9 @@
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { BaseInterceptor } from './base-interceptor';
/** Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: BaseInterceptor, multi: true },
];

38
src/app/http-interceptors/tree.service.ts

@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';
@Injectable()
export class TreeService {
toTree(olddata){
let newdata = []
function getparentNode(parentId){
return olddata.find((item)=>{
return item.id == parentId
})
}
olddata.forEach(item => {
var parentNode = getparentNode(item.parentId);
if(parentNode){
if(!parentNode.children){
parentNode.children = []
}
if (parentNode.children.length == 0) {
item.isTop = true;
} else {
item.isTop = false;
parentNode.children[parentNode.children.length -1].isBottom = false;
}
item.isBottom = true;
parentNode.children.push(item)
}else{
if(!item.parentId){//如果parentId为null
newdata.push(item)
}
}
});
return newdata;
}
}

51
src/app/interface.ts

@ -0,0 +1,51 @@
export interface Data {
token:string,
refreshToken:string,
expires: number,
realName:string,
level:any
}
export interface windows {
token:string
}
export enum isno {
"是",
"否"
}
export enum PlanTypeEnum {
"zero",
"二维预案",
"三维预案",
"three",
"其他预案",
"five",
"six",
"seven",
"卡片预案"
}
export enum AuditStatusEnum {
"zero",
"审核中",
"审核通过",
"",
"审核退回",
"five",
"six",
"seven",
"未提交审核"
}
export enum PlanLevelEnum {
"编制级别0",
"总队",
"支队",
"编制级别3",
"大队",
"编制级别5",
"编制级别6",
"编制级别7",
"中队"
}

6
src/app/m-token-k1/m-token-k1.component.html

@ -0,0 +1,6 @@
<object id="mTokenPlugin" type="application/x-mtokenplugin" width="0" height="0">
<param value="pluginLoaded" />
</object>
<div style="text-align: center; margin-top: 10%;">
<countdown [config]="{leftTime: 5,format: '密钥验证失败,本页面将于s秒后关闭'}" (event)="handleEvent($event)"></countdown>
</div>

3
src/app/m-token-k1/m-token-k1.component.scss

@ -0,0 +1,3 @@
.count-down {
font-size: 50px;
}

25
src/app/m-token-k1/m-token-k1.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MTokenK1Component } from './m-token-k1.component';
describe('MTokenK1Component', () => {
let component: MTokenK1Component;
let fixture: ComponentFixture<MTokenK1Component>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MTokenK1Component ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MTokenK1Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

96
src/app/m-token-k1/m-token-k1.component.ts

@ -0,0 +1,96 @@
import { Component, OnInit, Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import {MTokenK1Service} from './m-token-k1.service' //引入服务
declare var mToken : any;
@Injectable({
providedIn: 'root'
})
@Component({
selector: 'app-m-token-k1',
templateUrl: './m-token-k1.component.html',
styleUrls: ['./m-token-k1.component.scss']
})
export class MTokenK1Component implements OnInit {
constructor(private router: Router,public snackBar: MatSnackBar,public mTokenK1: MTokenK1Service) { }
ngOnInit(): void {
}
// 路由守卫
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.checkKey();
}
K1mToken = new mToken("mTokenPlugin")
keyBase64 = '5YyX5Lqs5a6J5L+h4oCU5LqM57u06aKE5qGI57yW5Yi25bel5YW3d2Vi'; //秘钥验证base64字符
password='12345678'; //秘钥验证用户密码
checkKey(): boolean {
this.K1mToken.LoadLibrary()
try { //try 捕获错误
let keyIndex = this.K1mToken.K1_mTokenFindDevice() //查找秘钥是否插入
if (keyIndex > 0) { //秘钥已插入
let keyUID = this.K1mToken.K1_mTokenGetUID(keyIndex) //读取秘钥UID
let isLogin = this.K1mToken.K1_mTokenOpen(keyUID,this.password)
if (isLogin == 0 ) { //密码验证成功
let keyMSG = window.atob( this.K1mToken.K1_mTokenReadUserStorage(keyUID,0,56) )
if (keyMSG==this.keyBase64) { //base64转码 验证
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('密钥验证成功','确定',config);
this.mTokenK1.startUp() //开始定时验证秘钥是否拔出
return true
} else { //base64验证失败
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('密钥错误,不为本公司发放密钥','确定',config);
return false
}
} else { //密码验证失败
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('密钥密码错误,请使用初始密码','确定',config);
return false
}
} else { //秘钥未插入
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('密钥未插入','确定',config);
return false
}
} catch (error) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('请检查您密钥是否插入或者驱动是否已启动','确定',config);
return false
}
} //路由守卫
//倒计时插件关闭页面
handleEvent (e) {
if (e.left===0) {window.close()}
}
}

16
src/app/m-token-k1/m-token-k1.service.spec.ts

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { MTokenK1Service } from './m-token-k1.service';
describe('MTokenK1Service', () => {
let service: MTokenK1Service;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(MTokenK1Service);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

67
src/app/m-token-k1/m-token-k1.service.ts

@ -0,0 +1,67 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
declare var mToken : any;
@Injectable({
providedIn: 'root'
})
export class MTokenK1Service {
constructor(private router: Router,public snackBar: MatSnackBar,) { }
public mTokenK1Timer; //定时器查询
public verificationURL = '/keyUnit/editunitinfo' //验证url地址是否为验证页面
K1mToken = new mToken("mTokenPlugin")
keyBase64 = '5YyX5Lqs5a6J5L+h4oCU5LqM57u06aKE5qGI57yW5Yi25bel5YW3d2Vi'; //秘钥验证base64字符
password='12345678'; //秘钥验证用户密码
//验证秘钥定时器
startUp = ():void=>{
window.clearInterval(this.mTokenK1Timer)
this.mTokenK1Timer = window.setInterval( ()=>{
let url = this.router.url
if ( url.includes(this.verificationURL) ) { //当前url地址为 秘钥验证页面时
this.K1mToken.LoadLibrary()
let keyIndex = this.K1mToken.K1_mTokenFindDevice() //查找秘钥是否插入
if (keyIndex < 1) { //秘钥被拔出
this.goToEdit()
} else if (keyIndex > 0) { //秘钥存在
let keyUID = this.K1mToken.K1_mTokenGetUID(keyIndex) //读取秘钥UID
let isLogin = this.K1mToken.K1_mTokenOpen(keyUID,this.password)
if (isLogin==0) { //密码验证成功
let keyMSG = window.atob( this.K1mToken.K1_mTokenReadUserStorage(keyUID,0,56) )
if (keyMSG!=this.keyBase64) { //base64转码 验证失败
this.goToEdit() }
} else { //密码验证失败
this.goToEdit() }
}
} else { //不为当前页面时
window.clearInterval(this.mTokenK1Timer)
}
},10000)
}
isShow:boolean = false; //是否显示倒计时插件
//秘钥拔出,删除验证定时器,跳转页面
goToEdit () {
this.isShow = true
window.clearInterval(this.mTokenK1Timer) //删除定时器
window.setTimeout(()=>{
this.isShow = false
let url = this.router.url
if ( url.includes(this.verificationURL) ) { //页面还为验证页面时跳转
window.close(); }
},10000)
}
}

15
src/app/navigation/navigation.component.html

@ -0,0 +1,15 @@
<div id="content">
<header>
<div class="title">着火单位: 贵港油库</div>
<div class="router">
<div class="routerText" *ngFor="let item of routers" routerLink= {{item.url}} routerLinkActive="routerLinkActive">{{item.name}}</div>
</div>
</header>
<div class="center">
<router-outlet></router-outlet>
</div>
</div>

60
src/app/navigation/navigation.component.scss

@ -0,0 +1,60 @@
#content {
width: 100%;
height: 100%;
background: url('../../assets/images/home.png');
-moz-background-size:100% 100%;
background-size:100% 100%;
box-sizing: border-box;
padding: 10px 38px 28px;
overflow: hidden;
display: flex;
flex-direction: column;
}
//头部
header {
width: 100%;
height: 80px;
border-bottom: 1px solid #30bbec;
overflow: hidden;
.title {
width: 100%;
height: 25px;
text-align: center;
font-size: 20px;
font-weight: 550;
color: red;
}
.router{
width: 100%;
height: 55px;
}
}
//路由DIV
.routerText {
display: inline-block;
margin: 7px 15px;
width: 150px;
height: 37px;
line-height: 37px;
font-size: 20px;
text-align: center;
border-top-left-radius: 15px;
border-bottom-right-radius: 15px;
cursor:pointer;
outline: none;
border: 2px solid #fff;
color: #fff;
}
//路由选中样式
.routerLinkActive {
border: 2px solid rgb(248, 161, 62);
background-color: rgba(240,136,14,0.65);
}
//中间区域
.center {
flex: 1;
overflow: hidden;
}

25
src/app/navigation/navigation.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavigationComponent } from './navigation.component';
describe('NavigationComponent', () => {
let component: NavigationComponent;
let fixture: ComponentFixture<NavigationComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NavigationComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavigationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

44
src/app/navigation/navigation.component.ts

@ -0,0 +1,44 @@
import { Component, OnInit,Inject } from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { TreeService } from '../http-interceptors/tree.service'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import {CacheTokenService} from '../http-interceptors/cache-token.service'//引入服务
import { Router,ActivatedRoute } from '@angular/router'
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss']
})
export class NavigationComponent implements OnInit {
constructor(public navmenus:CacheTokenService,private http: HttpClient,public dialog: MatDialog,private tree:TreeService,public snackBar: MatSnackBar,
private router:Router,private route:ActivatedRoute) { }
//路由配置
routers:any = [
{name:'平面图', url: '/ui/plan'},
{name:'处置要点', url: '/ui/disposalNode'},
{name:'危化品', url: '/ui/dangerous'},
{name:'类似预案', url: '/ui/similarPlans'},
{name:'真实战例', url: '/ui/realCases'},
{name:'预案赋能', url: '/ui/planAssistance'}
]
ngOnInit () {
}
ngOnDestroy () {
}
}

114
src/app/navigation/navigation.module.ts

@ -0,0 +1,114 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NavigationComponent } from './navigation.component';
import { MatIconModule } from '@angular/material/icon';
import { MatSidenavModule } from '@angular/material/sidenav';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { TabbarComponent } from '../tabbar/tabbar.component';
import { UiModule } from '../ui/ui.module';
import {A11yModule} from '@angular/cdk/a11y';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {PortalModule} from '@angular/cdk/portal';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CdkStepperModule} from '@angular/cdk/stepper';
import {CdkTableModule} from '@angular/cdk/table';
import {CdkTreeModule} from '@angular/cdk/tree';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatBadgeModule} from '@angular/material/badge';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import {MatButtonModule} from '@angular/material/button';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatCardModule} from '@angular/material/card';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatChipsModule} from '@angular/material/chips';
import {MatStepperModule} from '@angular/material/stepper';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatDialogModule} from '@angular/material/dialog';
import {MatDividerModule} from '@angular/material/divider';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatInputModule} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatMenuModule} from '@angular/material/menu';
import {MatNativeDateModule, MatRippleModule} from '@angular/material/core';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatSliderModule} from '@angular/material/slider';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSortModule} from '@angular/material/sort';
import {MatTableModule} from '@angular/material/table';
import {MatTabsModule} from '@angular/material/tabs';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatTreeModule} from '@angular/material/tree';
@NgModule({
declarations: [
NavigationComponent,
TabbarComponent
],
imports: [
CommonModule,
MatSidenavModule,
RouterModule,
MatIconModule,
FormsModule,
UiModule,
A11yModule,
CdkStepperModule,
CdkTableModule,
CdkTreeModule,
DragDropModule,
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
PortalModule,
ScrollingModule,
],
exports: [
NavigationComponent
]
})
export class NavigationModule { }

50
src/app/pages/home/home.component.html

@ -0,0 +1,50 @@
<div class="page">
<!-- 头部 -->
<!-- <div class="header">
<h1 class="logo"><img src="images/logo.png" alt="">数字化预案编制管理平台</h1>
<div class="notice-box">
<div class="notice-icon"><svg width="18" height="16" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="a"><stop stop-color="#FEFEFE" offset="0%"/><stop stop-color="#C8CACA" offset="100%"/></linearGradient></defs><path d="M17.287 10.088h-3.472c-.394 0-.713.35-.713.784v.244c0 .433.32.784.713.784h3.472c.394 0 .713-.35.713-.784v-.244c0-.433-.319-.784-.713-.784zM9.232 3.36c-1.08.94-3.34 2.258-4.966 3.525l-.002.001c-.019.012-.038.083-.056.094-.193.119-.279.446-1.323.446H.847c-.522 0-.847.268-.847.872v5.374c0 .604.298.902.847.902h2.046c1.04.002 1.124.327 1.315.445.019.012.037.082.056.095h.002c1.575 1.268 3.85 2.689 4.966 3.59.336.272 1.454.75 1.454-.93V4.22c0-1.68-1.127-1.143-1.454-.858zm3.206 3.704c.184.356.55.446.816.2l2.854-2.634c.267-.246.333-.734.15-1.091l-.105-.202c-.184-.356-.55-.445-.816-.2l-2.854 2.634c-.267.247-.334.735-.15 1.091l.105.202zm.816 7.671c-.267-.246-.632-.156-.817.2l-.104.2c-.184.357-.117.845.15 1.092l2.853 2.633c.267.246.632.157.816-.199l.105-.201c.184-.357.117-.845-.15-1.091l-2.853-2.634z" transform="translate(0 -3)" fill="url(#a)" fill-rule="nonzero"/></svg></div>
<div class="notice-txt">
这里是公告滚动通知这里是公告滚动通知这里是公告滚动通知
</div>
</div>
</div> -->
<!-- 左侧 -->
<div class="page-side page-left">
<div class="num-item">
<div class="num-tit" style="color: white;">重点单位总量</div>
<div class="num-text"><span class="number-running" id="number01">{{keyUnitNum}}</span><span class="unit"></span></div>
</div>
<div class="num-item">
<div class="num-tit" style="color: white;">采集单位总量</div>
<div class="num-text"><span class="number-running" id="number02">{{dataNum}}</span><span class="unit"></span></div>
</div>
<div class="num-item">
<div class="num-tit" style="color: white;">预案编制单位总量</div>
<div class="num-text"><span class="number-running" id="number03">{{planNum}}</span><span class="unit"></span></div>
</div>
<div class="panel panel-lg">
<div class="panel-bd">
<div id="chartQusj" class="chart-item"></div>
</div>
</div>
</div>
<!-- 地图 -->
<div class="page-center" style="width: 48%;height: 52%;opacity: .8;">
<div class="chart-item" id="chartMap"></div>
</div>
<!-- 右侧 -->
<div class="page-side page-right">
<div id="chartYadwlx" class="chart-item"></div>
<div class="panel panel02">
<div class="panel-bd">
<div id="chartYapyph" class="chart-item"></div>
</div>
</div>
<div class="panel panel03 panel-lg">
<div class="panel-bd">
<div id="chartYalxtj" class="chart-item"></div>
</div>
</div>
</div>
</div>

5
src/app/pages/home/home.component.scss

@ -0,0 +1,5 @@
@import "../../../assets/css/style.css";
#chartMap{
border-radius: 10px;
// opacity: .6;
}

25
src/app/pages/home/home.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomeComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

1131
src/app/pages/home/home.component.ts

File diff suppressed because it is too large Load Diff

63
src/app/pages/home2/home2.component.html

@ -0,0 +1,63 @@
<div class="contentBox">
<header>
<h1>数字化预案编制和管理平台</h1>
<div class="showTime">{{time}}</div>
</header>
<section class="mainbox">
<div class="column">
<div class="panel bar">
<h2>单位类型</h2>
<div class="chart" id="unitType"></div>
<div class="panel-footer"></div>
</div>
<div class="panel line">
<h2>预案状态</h2>
<div class="chart" id="planStates"></div>
<div class="panel-footer"></div>
</div>
<div class="panel pie">
<h2>预案类型</h2>
<div class="chart" id="planType"></div>
<div class="panel-footer"></div>
</div>
</div>
<div class="column">
<div class="no">
<div class="no-hd">
<ul>
<li>123</li>
<li>456</li>
</ul>
</div>
<div class="no-bd">
<ul>
<li>预案数量</li>
<li>单位数量</li>
</ul>
</div>
</div>
<div class="map">
<div class="map1"></div>
<div class="map2"></div>
<div class="map3" id='map' style='width:98%; height:98%;'></div>
</div>
</div>
<div class="column">
<div class="panel bar">
<h2>趋势图</h2>
<div class="chart" id="trend"></div>
<div class="panel-footer"></div>
</div>
<div class="panel line">
<h2>玫瑰图</h2>
<div class="chart" id="xxx"></div>
<div class="panel-footer"></div>
</div>
<div class="panel pie">
<h2>柱状图</h2>
<div class="chart" id="yyy"></div>
<div class="panel-footer"></div>
</div>
</div>
</section>
</div>

247
src/app/pages/home2/home2.component.scss

@ -0,0 +1,247 @@
@font-face {
font-family: electronicFont;
src: url(../../../assets/font/DS-DIGIT.TTF);
}
.contentBox{
width: 100%;
height: 100%;
background: url(../../../assets/images/bg.jpg) no-repeat top center;
line-height: 1.15;
header{
position: relative;
height:8%;
min-height: 64px;
background: url(../../../assets/images/head_bg.png) no-repeat;
background-size: 100% 100%;
h1{
font-size: 28px;
color: #fff;
text-align: center;
line-height: 64px;
}
.showTime{
position: absolute;
right: 20px;
line-height: 60px;
color: rgba(255,255,255, $alpha: 0.7);
font-size: 16px;
top: 0;
}
}
.mainbox{
width: 100%;
height: 92%;
// background-color: pink;
padding: 2px 0 2px 0;
display: flex;
.column{
flex: 3;
}
.column:nth-child(2){
flex: 6;
margin: 0 8px 8px 8px;
}
.panel{
height: 29.8%;
position: relative;
// background-color: red;
border: 1px solid rgba(25,186,139,0.17);
background: url(../../../assets/images/line.png) rgba(255,255,255, $alpha: 0.03);
margin-bottom: 8px;
&::before{
position: absolute;
top: 0;
left: 0;
content: "";
width:14px;
height:14px;
border-left: 2px solid #02a6b5;
border-top: 2px solid #02a6b5;
}
&::after{
position: absolute;
top: 0;
right: 0;
content: "";
width:14px;
height:14px;
border-right: 2px solid #02a6b5;
border-top: 2px solid #02a6b5;
}
.panel-footer{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 14px;
&::before{
position: absolute;
top: 0;
left: 0;
content: "";
width:14px;
height:14px;
border-left: 2px solid #02a6b5;
border-bottom: 2px solid #02a6b5;
}
&::after{
position: absolute;
top: 0;
right: 0;
content: "";
width:14px;
height:14px;
border-right: 2px solid #02a6b5;
border-bottom: 2px solid #02a6b5;
}
}
h2{
height: 18px;
color: #fff;
line-height: 18px;
text-align: center;
font-size: 14px;
font-weight: 400;
}
.chart{
height: 91%;
// background-color: pink;
}
}
.no{
background: rgba(101,132,226,0.1);
padding: 4px 16px;
height: 10%;
min-height: 100px;
.no-hd{
position: relative;
border: 1px solid rgba(25,186,139,0.17);
&::before{
position: absolute;
top: 0;
left: 0;
content: "";
width:30px;
height:14px;
border-left: 2px solid #02a6b5;
border-top: 2px solid #02a6b5;
}
&::after{
position: absolute;
bottom: 0;
right: 0;
content: "";
width:30px;
height:14px;
border-right: 2px solid #02a6b5;
border-bottom: 2px solid #02a6b5;
}
ul{
display: flex;
li{
flex: 1;
line-height: 55px;
font-size: 48px;
color: #ffeb7b;
text-align: center;
font-family: 'electronicFont';
}
li:nth-child(1){
position: relative;
&::after{
position: absolute;
top: 25%;
height: 50%;
right: 0;
content: "";
width:1px;
background: rgba(255,255,255, $alpha: 0.2);
}
}
}
}
.no-bd{
ul{
display: flex;
padding: 4px 0;
li{
flex: 1;
text-align: center;
color: rgba(255,255,255, $alpha: 0.7);
font-size: 14px;
line-height: 30px;
}
}
}
}
.map {
position: relative;
margin-top: 12px;
height: 78%;
.map1 {
width: 480px;
height: 480px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: url(../../../assets/images/map.png);
background-size: 100% 100%;
opacity: 0.3;
}
.map2 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 600px;
height: 600px;
background: url(../../../assets/images/lbx.png);
animation: rotate1 15s linear infinite;
opacity: 0.6;
background-size: 100% 100%;
}
.map3 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
// width: 7.075rem;
// height: 7.075rem;
// background: url(../images/jt.png);
// animation: rotate2 10s linear infinite;
// opacity: 0.6;
background-size: 100% 100%;
}
// .chart {
// position: absolute;
// top: 0;
// left: 0;
// // background-color: pink;
// width: 100%;
// height: 10.125rem;
// }
@keyframes rotate1 {
0% {
transform: translate(-50%, -50%) rotate(0deg);
};
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
// @keyframes rotate2 {
// form {
// transform: translate(-50%, -50%) rotate(0deg);
// }
// to {
// transform: translate(-50%, -50%) rotate(-360deg);
// }
// }
}
}
}

25
src/app/pages/home2/home2.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Home2Component } from './home2.component';
describe('Home2Component', () => {
let component: Home2Component;
let fixture: ComponentFixture<Home2Component>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ Home2Component ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(Home2Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

348
src/app/pages/home2/home2.component.ts

@ -0,0 +1,348 @@
import { Component, OnInit ,ElementRef} from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { HighlightSpanKind } from 'typescript';
declare var echarts: any;
declare var westeros: any;
declare var AMap: any;
declare var Loca: any;
@Component({
selector: 'app-home2',
templateUrl: './home2.component.html',
styleUrls: ['./home2.component.scss']
})
export class Home2Component implements OnInit {
constructor(private http:HttpClient,public element: ElementRef) { }
unitTypeStatistics:any //单位类型统计
myUnitTypeChart:any //单位类型统计图表
unitTypeOption:any = {
title: {
// text: '单位类型统计',
// left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '占比: <br/>{b} : {c} ({d}%)'
},
legend: {
// orient: 'vertical',
// top: 'middle',
bottom: 0,
left: 'center',
data: []
},
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: [
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}; //单位类型数据
planStateStatistics //预案状态统计
myPlanStateChart:any //预案状态统计图表
planStateOption:any = {
title: {
// text: '预案编制情况统计',
// left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '占比: <br/>{b} : {c} ({d}%)'
},
legend: {
// orient: 'vertical',
// top: 'middle',
bottom: 0,
left: 'center',
data: ['审核通过','已提交','已公开']
},
series: [
{
type: 'pie',//类型为饼图
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: [
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}; //预案状态数据
planTypeStatistics //各类型预案统计
myPlanTypeChart:any //各类型预案图表
planTypeOption:any = {
title: {
// text: '各类型预案情况统计',
// left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '占比: <br/>{b} : {c} ({d}%)'
},
legend: {
// orient: 'vertical',
// top: 'middle',
bottom: 0,
left: 'center',
data: ['卡片预案','二维预案','三维预案','其他预案']
},
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: [
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}; //预案状态数据
trendStatistics //趋势统计
trendChart:any //趋势图表
trendOption:any = {
title: {
// text: '预案趋势统计'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['新增预案', '修改预案']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月','十二月']
},
yAxis: {
type: 'value'
},
series: [
{
name: '新增预案',
type: 'line',
stack: '总量',
data: []
},
{
name: '修改预案',
type: 'line',
stack: '总量',
data: []
}
]
}; //预案状态数据
xxxChart:any
xxxOption:any = {
title: {
// text: '南丁格尔玫瑰图',
// subtext: '纯属虚构',
// left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
top: 'bottom',
data: ['1', '2', '3', '4']
},
toolbox: {
show: true,
feature: {
mark: {show: true},
dataView: {show: true, readOnly: false},
magicType: {
show: true,
type: ['pie', 'funnel']
},
restore: {show: true},
saveAsImage: {show: true}
}
},
series: [
{
name: '面积模式',
type: 'pie',
radius: [30, 110],
// center: ['75%', '50%'],
roseType: 'area',
data: [
{value: 10, name: '1'},
{value: 5, name: '2'},
{value: 15, name: '3'},
{value: 25, name: '4'}
]
}
]
}
yyyChart:any
yyyOption:any = {
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '直接访问',
type: 'bar',
barWidth: '60%',
data: [10, 52, 200, 334, 390, 330, 220]
}
]
};
t:any
time:any
theme:any //主题风格
ngOnInit(): void {
// const map = new AMap.Map(this.element.nativeElement.querySelector('#map'), {
// mapStyle: 'amap://styles/1de318cbb8d12c02303a22c550b9ccc9',
// // pitch: 0,
// features: ['bg', 'road'],//地图显示要素
// zoom: 6,
// center: [116.408075, 39.950187],
// // viewMode: '3D'
// });
// const layer = new Loca.DistrictLayer({
// map: map
// });
// layer.setMap(map);
this.getTime()
setTimeout(() => {
this.myUnitTypeChart = echarts.init(this.element.nativeElement.querySelector('#unitType'),'westeros');
this.myPlanStateChart = echarts.init(this.element.nativeElement.querySelector('#planStates') ,'westeros');
this.myPlanTypeChart = echarts.init(this.element.nativeElement.querySelector('#planType'),'westeros');
this.trendChart = echarts.init(this.element.nativeElement.querySelector('#trend'),'westeros');
this.xxxChart = echarts.init(this.element.nativeElement.querySelector('#xxx'),'westeros');
this.xxxChart.setOption(this.xxxOption);
this.yyyChart = echarts.init(this.element.nativeElement.querySelector('#yyy'),'westeros');
this.yyyChart.setOption(this.yyyOption);
}, 0);
this.chartsSetOption();
}
getTime():any{
this.t = setInterval(()=>{
var dt = new Date();
var y = dt.getFullYear();
var mt = dt.getMonth() + 1;
var day = dt.getDate();
var h = dt.getHours(); //获取时
var m = dt.getMinutes(); //获取分
var s = dt.getSeconds(); //获取秒
this.time = "当前时间:" + y + "年" + mt + "月" + day + "-" + h + "时" + m + "分" + s + "秒";
}, 1000); //開始运行
}
chartsSetOption(){
this.http.get("/api/StatisticsAnalysis").subscribe((data:any)=>{
//单位类型统计
this.unitTypeStatistics = data.companyStatistics.buildingTypeStatistics.buildingTypes
this.unitTypeStatistics.forEach(item => {
item.name = item.buildingTypeName
item.value = item.count
// this.unitTypeOption.legend.data.push(item.buildingTypeName)
});
this.unitTypeOption.series[0].data = this.unitTypeStatistics
this.myUnitTypeChart.setOption(this.unitTypeOption,true);
//预案状态统计
this.planStateStatistics = data.planStatistics.planningStatistics
this.planStateOption.series[0].data.push({name:'审核通过',value:data.planStatistics.planningStatistics.approvedCount})
this.planStateOption.series[0].data.push({name:'已提交',value:data.planStatistics.planningStatistics.committedCount})
this.planStateOption.series[0].data.push({name:'已公开',value:data.planStatistics.planningStatistics.publicCount})
this.myPlanStateChart.setOption(this.planStateOption,true);
//各类型预案统计
this.planTypeStatistics = data.planStatistics.planTypeStatistics
this.planTypeOption.series[0].data.push({name:'卡片预案',value:data.planStatistics.planTypeStatistics.planCardCount})
this.planTypeOption.series[0].data.push({name:'二维预案',value:data.planStatistics.planTypeStatistics.plan2DCount})
this.planTypeOption.series[0].data.push({name:'三维预案',value:data.planStatistics.planTypeStatistics.plan3DCount})
this.planTypeOption.series[0].data.push({name:'其他预案',value:data.planStatistics.planTypeStatistics.planOtherCount})
this.myPlanTypeChart.setOption(this.planTypeOption,true);
//预案趋势图统计
this.trendStatistics = data.planStatistics.trendStatistics
// this.trendOption.series = []
this.trendStatistics.added.forEach(item=>{
this.trendOption.series[0].data.push(item.count)
})
this.trendStatistics.modified.forEach(item=>{
this.trendOption.series[1].data.push(item.count)
})
this.trendChart.setOption(this.trendOption,true);
})
}
ngOnDestroy(){
window.clearInterval(this.t) //清一遍定时器
}
}

70
src/app/pages/homedetail/homedetail.component.html

@ -0,0 +1,70 @@
<div class="page page01">
<!-- 头部 -->
<!-- <div class="header">
<h1 class="logo" text="数字化预案编制管理平台"><img src="images/logo.png" alt="">数字化预案编制管理平台</h1>
<div class="notice-box">
<div class="notice-icon"><svg width="18" height="16" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="a"><stop stop-color="#FEFEFE" offset="0%"/><stop stop-color="#C8CACA" offset="100%"/></linearGradient></defs><path d="M17.287 10.088h-3.472c-.394 0-.713.35-.713.784v.244c0 .433.32.784.713.784h3.472c.394 0 .713-.35.713-.784v-.244c0-.433-.319-.784-.713-.784zM9.232 3.36c-1.08.94-3.34 2.258-4.966 3.525l-.002.001c-.019.012-.038.083-.056.094-.193.119-.279.446-1.323.446H.847c-.522 0-.847.268-.847.872v5.374c0 .604.298.902.847.902h2.046c1.04.002 1.124.327 1.315.445.019.012.037.082.056.095h.002c1.575 1.268 3.85 2.689 4.966 3.59.336.272 1.454.75 1.454-.93V4.22c0-1.68-1.127-1.143-1.454-.858zm3.206 3.704c.184.356.55.446.816.2l2.854-2.634c.267-.246.333-.734.15-1.091l-.105-.202c-.184-.356-.55-.445-.816-.2l-2.854 2.634c-.267.247-.334.735-.15 1.091l.105.202zm.816 7.671c-.267-.246-.632-.156-.817.2l-.104.2c-.184.357-.117.845.15 1.092l2.853 2.633c.267.246.632.157.816-.199l.105-.201c.184-.357.117-.845-.15-1.091l-2.853-2.634z" transform="translate(0 -3)" fill="url(#a)" fill-rule="nonzero"/></svg></div>
<div class="notice-txt">
这里是公告滚动通知这里是公告滚动通知这里是公告滚动通知
</div>
</div>
</div> -->
<div class="page-top">
<div class="num-list">
<div class="num-item num-item-detail">
<div class="num-tit">重点单位总量</div>
<div class="num-text"><span class="number-running" id="number01">8,666</span><span class="unit"></span></div>
</div>
<div class="num-item num-item-detail">
<div class="num-tit">数据采集总量</div>
<div class="num-text"><span class="number-running" id="number02">999,999</span><span class="unit"></span></div>
</div>
<div class="num-item num-item-detail">
<div class="num-tit">预案编制总量</div>
<div class="num-text"><span class="number-running" id="number03">345,678</span><span class="unit"></span></div>
</div>
</div>
</div>
<!-- 左侧 -->
<div class="page-side page-left">
<div class="common-list">
<a href="#" class="list-item is-active">
<div class="list-tit">预案编制</div>
</a>
<a href="#" class="list-item">
<div class="list-tit">预案审核</div>
</a>
<a href="#" class="list-item">
<div class="list-tit">GIS调用</div>
</a>
</div>
<div class="panel" style="width: 755px;background-size: 100% 100%;">
<div class="panel-bd">
<div id="chartQusj" class="chart-item"></div>
</div>
</div>
</div>
<!-- 右侧 -->
<div class="page-side page-right page-right-detail">
<div id="chartYadwlx" class="chart-item" style="width: 410px;height: 270px;"></div>
<div class="panel panel02">
<div class="panel-bd">
<div id="chartYapyph" class="chart-item"></div>
</div>
</div>
<div class="panel panel03" style="width: 768px;background-size: 100% 100%;">
<div class="panel-bd">
<div id="chartYalxtj" class="chart-item"></div>
</div>
</div>
</div>
<!-- 地图 -->
<div class="page-center">
<div class="chart-item" id="chartMap" style="width: 949px;
right: 155px;
height: 400px;
bottom: 76px;
border-radius: 10px;"></div>
</div>
</div>

1
src/app/pages/homedetail/homedetail.component.scss

@ -0,0 +1 @@
@import "../../../assets/css/style.css";

25
src/app/pages/homedetail/homedetail.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomedetailComponent } from './homedetail.component';
describe('HomedetailComponent', () => {
let component: HomedetailComponent;
let fixture: ComponentFixture<HomedetailComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomedetailComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomedetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

563
src/app/pages/homedetail/homedetail.component.ts

@ -0,0 +1,563 @@
import { Component, OnInit ,ViewChild, AfterViewInit,ElementRef,Renderer2 } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router,ActivatedRoute } from '@angular/router'
declare var echarts: any;
declare var AMap: any;
declare var AMapUI: any;
@Component({
selector: 'app-homedetail',
templateUrl: './homedetail.component.html',
styleUrls: ['./homedetail.component.scss']
})
export class HomedetailComponent implements OnInit {
constructor(private http:HttpClient, private render2: Renderer2,public element: ElementRef,private router:Router,private route:ActivatedRoute) { }
//全队数据采集和预案编制数量统计
chartQusj:any
chartQusjOption:any = {
grid: {
top: 50,
left: 30,
right: 20,
bottom: 20,
},
// 标题
title: {
text: '全队数据采集和预案编制数量统计',
top: -4,
left:-2
},
//图例
legend: {
top: 0,
right:-2,
// left:3,
data: ['单位预案编制数量', '单位数据采集数量'],
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
boundaryGap: false,
},
// y轴
yAxis: {
type: 'value',
name:'个'
},
// 数据
series: [
{
name: '单位预案编制数量',
type: 'line',
data: [38, 42, 46, 40, 35, 30, 38, 38, 42, 46, 40, 35],
// showSymbol: true,
// symbolSize:6,
// smooth: false,
// label: {
// show: true,
// },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(60,103,195,1)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(0,194,255,.2)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
}
},
{
name: '单位数据采集数量',
type: 'line',
data: [28, 12, 66, 50, 25, 40, 48, 12, 66, 50, 25, 40 ],
},
],
};
//预案单位类型统计
chartYadwlx:any
data02:any = [{
value: 335,
name: '类型名称1'
},
{
value: 110,
name: '类型名称2'
},
{
value: 274,
name: '类型名称3'
},
{
value: 235,
name: '视频广告'
},
{
value: 400,
name: '类型名称4'
}
];
chartYadwlxOption:any = {
// 标题
title: {
text: '预案单位类型统计',
left: '15%',
top:0
},
//图例
legend: {
orient: 'vertical',
top: 'center',
right: '0%',
show: false,
formatter: function (name) {
var target;
for (var i = 0, l = this.data02.length; i < l; i++) {
if (this.data02[i].name == name) {
target = this.data02[i].value;
}
}
return name + ' ' + target;
}
},
//提示框
tooltip: {
trigger: 'item',
},
// 数据
series: [{
type: 'pie',
center: ['55%', '55%'],
radius: ['25%', '60%'],
roseType:true,
// labelLine: {
// show: true,
// length: 20,
// length2: 0,
// lineStyle: {
// color: '#999',
// width: 1
// }
// },
labelLine:{
lineStyle:{
color: '#93FCFF'
}
},
label: {
//formatter: '{hr|}\n{a|{b}}\n{b|{c}}万吨\n{c|{d}%}',
formatter: '{a|{b}}\n{b|{c}}{c|万吨}\n{d|{d}%}',
rich: {
// hr: {
// borderColor: '#999',
// width: '100%',
// borderWidth: 1,
// marginLeft: '-15px',
// marginRight: '-15px',
// height:0
// },
a: {
color: '#1F6F9B',
fontSize: 12,
height: 18,
borderColor: '#999',
//marginTop: '65px',
},
b: {
color: '#fff',
fontSize: 24,
height: 36,
},
c: {
color: '#fff',
fontSize: 12,
},
d: {
color: '#fff',
fontSize: 12,
height: 16,
marginLeft: '5px',
},
},
},
data: [{
value: 335,
name: '类型名称1'
},
{
value: 110,
name: '类型名称2'
},
{
value: 274,
name: '类型名称3'
},
{
value: 235,
name: '类型名称4'
}
],
}],
};
// 预案评优排行
chartYapyph:any
chartYapyphOption:any = {
// 标题
title: {
text: '预案评优排行',
left:0
},
grid: {
left: 30,
right: 0,
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
data: ['机构1', '机构2', '机构3', '机构4', '机构5', '机构6', '机构7']
},
// y轴
yAxis: {
type: 'value',
splitLine: {
show: true,
lineStyle: {
color: '#fff'
}
},
},
// 数据
series: [{
name: '预案评优',
type: 'bar',
data: [320, 302, 301, 234, 390, 330, 320],
label: {
show: false,
position: "top",
formatter: '{c}',
color: "#fff",
},
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(0,220,254,1)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba(1,104,191,1)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
}
}
],
};
//预案类型统计
chartYalxtj:any
chartYalxtjOption:any = {
color: ['#FB33C2', '#00CFF0', '#2C3DE0'],
grid: {
top: 50,
left: 30,
right: 20,
bottom: 20,
},
// 标题
title: {
text: '预案类型统计',
top: -4,
left: 0
},
//图例
legend: {
top: 0,
data: ['二维预案', '三维预案', '卡片预案'],
icon:'circle',
itemGap: 20,
},
//提示框
tooltip: {
trigger: 'axis',
},
// x轴
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
boundaryGap: false,
},
// y轴
yAxis: {
type: 'value',
},
// 数据
series: [{
name: '二维预案',
type: 'line',
symbolSize: 0,
smooth:true,
lineStyle:{
width: 4,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0,
color: 'rgba(254,51,194,0)' // 0% 处的颜色
}, {
offset: 0.5,
color: 'rgba(254,51,194,1)' // 100% 处的颜色
}, {
offset: 1,
color: 'rgba(254,51,194,0)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
data: [38, 42, 46, 40, 35, 30, 38, 42, 46, 40, 35, 30 ],
},
{
name: '三维预案',
type: 'line',
symbolSize: 0,
smooth:true,
lineStyle:{
width: 4,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0,
color: 'rgba(14,222,252,0)' // 0% 处的颜色
}, {
offset: 0.5,
color: 'rgba(0,221,255,1)' // 100% 处的颜色
}, {
offset: 1,
color: 'rgba(1,255,253,0)' // 100% 处的颜色
}],
global: false // 缺省为 false
},
},
data: [28, 72, 66, 50, 25, 40, 48, 66, 50, 25, 40, 48 ],
},
{
name: '卡片预案',
type: 'line',
symbolSize: 0,
smooth:true,
lineStyle:{
width: 4,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0,
color: 'rgba(48,63,240,0)' // 0% 处的颜色
}, {
offset: 0.5,
color: 'rgba(48,63,240,1)' // 100% 处的颜色
}, {
offset: 1,
color: 'rgba(48,63,240,0)' // 100% 处的颜色
}],
global: false // 缺省为 false
},
},
data: [28, 112, 166, 150, 125, 140, 48, 28, 112, 166, 150, 125 ],
},
],
};
//地图
chartMap:any
chartMapOption:any = {
tooltip: {
show: true,
formatter: function (params) {
return params.name + ':' + params.data['value'];
},
},
geo: [{
show: true,
map: 'chongqing',
zoom: 1,
itemStyle: {
areaColor: '#090C15',
borderColor: '#0584DD',
borderWidth: 2,
shadowColor: 'rgba(5, 132, 221, 1)',
shadowBlur: 1,
shadowOffsetX: 2,
shadowOffsetY: 10,
},
emphasis: {
label: {
color: '#fff',
},
itemStyle: {
areaColor: '#0584DD',
}
}
},
{
show: true,
map: 'chongqing',
label: {
show: true,
color: '#fff',
fontSize: 12,
},
zoom: 1,
itemStyle: {
areaColor: '#090C15',
borderColor: '#0584DD',
},
emphasis: {
label: {
color: '#fff',
},
itemStyle: {
areaColor: '#0584DD',
}
}
}
]
}
ngOnInit(): void {
setTimeout(() => {
this.chartQusj = echarts.init(this.element.nativeElement.querySelector('#chartQusj'),'skinUpp');
this.chartQusj.setOption(this.chartQusjOption);
this.chartYadwlx = echarts.init(this.element.nativeElement.querySelector('#chartYadwlx'),'skinUpp');
this.chartYadwlx.setOption(this.chartYadwlxOption);
this.chartYapyph = echarts.init(this.element.nativeElement.querySelector('#chartYapyph'),'skinUpp');
this.chartYapyph.setOption(this.chartYapyphOption);
this.chartYalxtj = echarts.init(this.element.nativeElement.querySelector('#chartYalxtj'),'skinUpp');
this.chartYalxtj.setOption(this.chartYalxtjOption);
this.chartMap = echarts.init(this.element.nativeElement.querySelector('#chartMap'));
console.log(this.chartMapOption)
this.chartMap.setOption(this.chartMapOption);
this.mapInit() //初始化地图
}, 0);
console.log(echarts)
}
mapInit () {
//创建地图
var map = new AMap.Map('chartMap', {
cursor: 'default',
zooms:[7,10],
mapStyle:"amap://styles/grey",
});
var colors = [
"#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00",
"#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707",
"#651067", "#329262", "#5574a6", "#3b3eac"
];
AMapUI.loadUI(['geo/DistrictExplorer'], (DistrictExplorer)=> {
//创建一个实例
var districtExplorer = new DistrictExplorer({
map: map,
eventSupport: true, //打开事件支持
});
var adcode = this.route.snapshot.queryParams.code;
districtExplorer.loadAreaNode(adcode, (error, areaNode)=>{
//更新地图视野
map.setBounds(areaNode.getBounds(), null, null, true);
//清除已有的绘制内容
districtExplorer.clearFeaturePolygons();
//绘制子区域
districtExplorer.renderSubFeatures(areaNode, (feature, i) => {
// console.log(123,feature,i)
var fillColor = colors[i % colors.length];
var strokeColor = colors[colors.length - 1 - i % colors.length];
return {
cursor: 'default',
bubble: true,
strokeColor: strokeColor, //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线宽
fillColor: fillColor, //填充色
fillOpacity: 0.5, //填充透明度
};
});
let fillColor2
if(this.route.snapshot.queryParams.level == 'city'){
fillColor2 = null
}else{
fillColor2 = '#329262'
}
// console.log(789,fillColor2)
//绘制父区域
districtExplorer.renderParentFeature(areaNode, {
cursor: 'default',
bubble: true,
strokeColor: 'black', //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线宽
fillColor: fillColor2, //填充色
fillOpacity: 0.5, //填充透明度
});
});
districtExplorer.on('featureClick', function(e, feature) {
var props = feature.properties;
// //如果存在子节点
// // if (props.childrenNum > 0) {
// //切换聚焦区域
// switch2AreaNode(props.adcode);
// // }
console.log(props)
});
});
}
}

22
src/app/pages/lockscreen/lockscreen.component.html

@ -0,0 +1,22 @@
<div class="pages-lockscreen layout-full">
<div class="page h-100-p text-center vertical-align">
<div class="page-content auth-box vertical-align-middle">
<p class="mt-0 mb-20">锁屏</p>
<div class="mt-20 mb-20" fxLayout="row" fxLayoutAlign="space-between center">
<mat-form-field color-white color="accent" appearance="outline" class="w-100-p">
<mat-label>输入密码</mat-label>
<input matInput type="password" [(ngModel)]="password">
<mat-icon matSuffix>lock</mat-icon>
</mat-form-field>
</div>
<p class="mt-0">
输入密码以进入
</p>
<button mat-button color="warn" (click)="open()">进入</button>
<div class="copyright">
<p>WEBSITE BY Anxin</p>
<p>© 2020. All RIGHT RESERVED.</p>
</div>
</div>
</div>
</div>

111
src/app/pages/lockscreen/lockscreen.component.scss

@ -0,0 +1,111 @@
.pages-lockscreen {
.page-content {
display: inline-block;
width: 400px;
max-width: 100%;
padding: 30px;
}
.avatar {
width: 50px;
height: 50px;
margin: 0 auto;
img {
border-radius: 50%;
}
}
}
.layout-full {
position: absolute;
z-index: 0;
width: 100%;
height: 100%;
color: #fff;
font-family: Roboto, sans-serif;
background: url('../../../assets/images/background.jpg');
&::before {
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100%;
content: "";
background-position: center top;
background-size: cover;
}
&::after {
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100%;
content: "";
background-color: rgba(33, 33, 33, .6);
}
.page {
position: relative;
height: 100%;
padding: 0;
margin: 0;
background: transparent;
}
}
.auth-box {
.copyright {
margin-top: 60px;
font-size: 12px;
font-weight: 500;
letter-spacing: 1px;
p {
margin: 0 0 14px;
}
}
.social {
mat-icon {
color: #fff;
}
}
}
.vertical-align {
&::before {
display: inline-block;
height: 100%;
vertical-align: middle;
content: "";
}
.vertical-align-middle {
display: inline-block;
vertical-align: middle;
}
}
.pages-login {
.page-content {
display: inline-block;
width: 400px;
max-width: 100%;
padding: 30px;
}
}
.page-content{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
text-align: center;
}

25
src/app/pages/lockscreen/lockscreen.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LockscreenComponent } from './lockscreen.component';
describe('LockscreenComponent', () => {
let component: LockscreenComponent;
let fixture: ComponentFixture<LockscreenComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LockscreenComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LockscreenComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

21
src/app/pages/lockscreen/lockscreen.component.ts

@ -0,0 +1,21 @@
import { Component, OnInit } from '@angular/core';
import { Router,ActivatedRoute } from '@angular/router'
import {CacheTokenService} from '../../http-interceptors/cache-token.service'//引入服务
@Component({
selector: 'app-lockscreen',
templateUrl: './lockscreen.component.html',
styleUrls: ['./lockscreen.component.scss']
})
export class LockscreenComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,private getMenus:CacheTokenService) { }
password = ''
ngOnInit() {
}
open(){
}
}

54
src/app/pages/login/login.component.html

@ -0,0 +1,54 @@
<div class="login">
<div class="intro">
<div style="display: flex; margin-top: 20%;margin-left: 10%">
<div class="logo">
<img src="../../../assets/images/filelogo.png" alt="">
</div>
<div class="text">
<span style="font-size: 36px;color: white; display: block;margin-bottom: 35px;">数字化预案编制管理平台</span>
<span style="font-size: 16px;color: white;opacity: 0.5;">
数字化预案编制管理应用平台集重点单位的数字化预案资源的管理、分析及调用为一体,可实现辖区内预案使用的高效化、集约化、统一化、标准化管理。同时,可将消防现有的三维预案、图片式预案、卡片式预案、二维预案、视频预案等接入至系统中进行更加全面、真实、直观、生动的展示各项单位预案数据,方便进行预案资源调用,更好的服务实战指挥。
</span>
</div>
</div>
</div>
<div class="card">
<div class="loginImg">
<img src="../../../assets/images/loginlogo.png">
<p class="cardheader">登录</p>
</div>
<mat-card>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-icon class="icon">account_box</mat-icon>
<mat-icon class="icon2">lock</mat-icon>
<mat-form-field>
<input matInput id="name" name="name" required
ngModel #name="ngModel" placeholder="请输入账号">
</mat-form-field>
<mat-form-field>
<input matInput id="password" name="password" type='password'
required
ngModel #password="ngModel" placeholder="请输入密码">
</mat-form-field>
<div *ngIf="errmsg" class="alert-danger">
{{errmsg}}
</div>
<mat-checkbox style="margin-top: 10px;" name="notlogin" ngModel #notlogin="ngModel">
7天免登录
<a href="javascript:void(0);" (click)='open()'>
忘记密码?
</a>
</mat-checkbox>
<button type="submit" [disabled]="!form.form.valid" class="loginbtn"mat-button>登录</button>
</form>
<div class="website"><p>北京安信科创有限公司提供技术支持和维护</p></div>
</mat-card>
</div>
</div>

87
src/app/pages/login/login.component.scss

@ -0,0 +1,87 @@
.login {
width: 100%;
height: 100%;
display: flex;
.intro {
flex: 85%;
height: 100%;
background: url('../../../assets/images/background.jpg');
background-repeat:no-repeat;
background-size:100% 100%;
-moz-background-size:100% 100%;
.text {
padding-top: 3%;
margin-left: 8%;
width: 53%;
}
}
.card{
flex: 15%;
height: 100%;
background-color: #fff;
}
}
.example-container {
display: flex;
flex-direction: column;
width: 100%;
}
.loginbtn {
margin-top: 25px;
height: 35px;
background-color:#039be5;
border-radius: 15px;
color: #fff;;
}
.website {
font-size: 14px;
text-align: center;
margin-top: 60px;
}
.alert-danger {
font-size: 14px;
color: red;
}
.cardheader{
font-size: 26px;
font-weight: 500;
margin-top: 20px;
}
.mat-card {
box-shadow: 0px 0px 0px;
margin-top: 10px;
padding-left: 20px;
}
.mat-form-field {
padding-left: 20px;;
}
.loginImg {
margin-top: 90px;
text-align: center;
}
.mat-input-element {
position: relative;
}
.mat-card .example-container .icon {
width: 24px;
color: #666;
font-size: 24px;
position: absolute;
top:36px;
left: 15px;
}
.mat-card .example-container .icon2 {
width: 24px;
color: #666;
font-size: 24px;
position: absolute;
top:100px;
left: 15px;
}
a {
font-size: 14px;
color: #0066FF;
margin-left: 250px;
}

25
src/app/pages/login/login.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

58
src/app/pages/login/login.component.ts

@ -0,0 +1,58 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Data } from '../../interface'
import { Router,ActivatedRoute } from '@angular/router'
import {CacheTokenService} from '../../http-interceptors/cache-token.service'//引入服务
import { MatSnackBar } from '@angular/material/snack-bar';
import { ConstantPositionProperty } from 'cesium';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
})
export class LoginComponent implements OnInit {
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,public snackBar: MatSnackBar) { }
ngOnInit() {
this.automaticLogin()
}
errmsg :string = ''
onSubmit(e){
}
//7天免登录自动登录
automaticLogin () {
let isNoLogin = localStorage.getItem("isnologin")
if (isNoLogin) { //7天免登录时
let token = localStorage.getItem("token");
let refreshToken = localStorage.getItem("refreshToken");
this.http.post('/api/Account/RefreshToken', {
token: token,
refreshToken: refreshToken}).subscribe((data:any)=>{
sessionStorage.setItem("level",data.level);
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
this.token.startUp()
this.snackBar.open('已自动登录', '确定', {duration: 3000});
})
} //if
}
//打开弹窗
open () {
this.snackBar.open('请联系管理员', '确定', {
duration: 3000
});
}
}

12
src/app/pages/pages-routing.module.ts

@ -0,0 +1,12 @@
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class PagesRoutingModule {}

1
src/app/pages/pages.component.html

@ -0,0 +1 @@
<p>pages works!</p>

0
src/app/pages/pages.component.scss

25
src/app/pages/pages.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesComponent } from './pages.component';
describe('PagesComponent', () => {
let component: PagesComponent;
let fixture: ComponentFixture<PagesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PagesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PagesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

15
src/app/pages/pages.component.ts

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pages',
templateUrl: './pages.component.html',
styleUrls: ['./pages.component.scss']
})
export class PagesComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

117
src/app/pages/pages.module.ts

@ -0,0 +1,117 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PagesComponent } from './pages.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { PagesRoutingModule } from './pages-routing.module'
import {A11yModule} from '@angular/cdk/a11y';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {PortalModule} from '@angular/cdk/portal';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CdkStepperModule} from '@angular/cdk/stepper';
import {CdkTableModule} from '@angular/cdk/table';
import {CdkTreeModule} from '@angular/cdk/tree';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatBadgeModule} from '@angular/material/badge';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import {MatButtonModule} from '@angular/material/button';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatCardModule, MatCardTitle} from '@angular/material/card';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatChipsModule} from '@angular/material/chips';
import {MatStepperModule} from '@angular/material/stepper';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatDialogModule} from '@angular/material/dialog';
import {MatDividerModule} from '@angular/material/divider';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatMenuModule} from '@angular/material/menu';
import {MatNativeDateModule, MatRippleModule} from '@angular/material/core';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatSliderModule} from '@angular/material/slider';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSortModule} from '@angular/material/sort';
import {MatTableModule} from '@angular/material/table';
import {MatTabsModule} from '@angular/material/tabs';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatTreeModule} from '@angular/material/tree';
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { PersonaldataComponent } from './personaldata/personaldata.component';
import { RouterModule } from '@angular/router';
import { LockscreenComponent } from './lockscreen/lockscreen.component';
import { HomeComponent } from './home/home.component';
import { Home2Component } from './home2/home2.component';
import { HomedetailComponent } from './homedetail/homedetail.component';
// import { PagesRoutingModule } from './pages-routing.module';
@NgModule({
declarations: [PagesComponent, LoginComponent, RegisterComponent, LockscreenComponent, HomeComponent, Home2Component, HomedetailComponent],
imports: [
PagesRoutingModule,
CommonModule,
A11yModule,
CdkStepperModule,
CdkTableModule,
CdkTreeModule,
DragDropModule,
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
PortalModule,
ScrollingModule,
FormsModule,
ReactiveFormsModule,
RouterModule
// PagesRoutingModule,
]
})
export class PagesModule { }

280
src/app/pages/personaldata/personaldata.component.html

@ -0,0 +1,280 @@
<div class="pages-profile">
<div fxLayout.gt-sm="row nowrap" fxLayout.lt-md="column nowrap" fxLayoutAlign.gt-sm="space-between start"
fxLayoutGap="30px" id="xxx">
<mat-card fxFlex="30" class="profile-card">
<mat-card-content>
<img mat-card-avatar src="">
<mat-card-title class="profile-user">安信科创</mat-card-title>
<mat-card-subtitle class="profile-job">嘻嘻嘻嘻</mat-card-subtitle>
<p class="profile-introduction">
不要做程序员,要做问题解决者
</p>
<div class="profile-social">
<mat-icon size="1" class="secondary-text s-24"></mat-icon>
<mat-icon size="1" class="secondary-text s-24"></mat-icon>
<mat-icon size="1" class="secondary-text s-24"></mat-icon>
<mat-icon size="1" class="secondary-text s-24"></mat-icon>
</div>
<button mat-flat-button color="accent">关注</button>
</mat-card-content>
<mat-card-actions class="profile-card-footer" fxLayout="row nowrap">
<div fxFlex="32">
<strong class="profile-stat-count">260</strong>
<span>粉丝</span>
</div>
<div fxFlex="32">
<strong class="profile-stat-count">180</strong>
<span>关注</span>
</div>
<div fxFlex="32">
<strong class="profile-stat-count">2000</strong>
<span>博客</span>
</div>
</mat-card-actions>
</mat-card>
<mat-card fxFlex="70" class="profile-board">
<mat-tab-group>
<mat-tab label="活动">
<mat-list>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
</mat-list>
<div class="pt-40 pb-40">
<button mat-flat-button class="show-more-btn">更多</button>
</div>
</mat-tab>
<mat-tab label="评论">
<mat-list>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
</div>
</mat-list-item>
</mat-list>
</mat-tab>
<mat-tab label="消息">
<mat-list>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
<img src="" alt="">
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
<mat-list-item>
<div matLine fxLayoutAlign="start center" fxLayoutGap="16px">
<img matListAvatar src="">
<div>
<div>我是假数据
<span class="secondary-text font-size-12">我是假数据</span>
</div>
<span class="secondary-text font-size-12">我是假数据</span>
</div>
</div>
<div matLine class="profile-item-content">
我是假数据
</div>
</mat-list-item>
</mat-list>
</mat-tab>
</mat-tab-group>
</mat-card>
</div>
</div>

110
src/app/pages/personaldata/personaldata.component.scss

@ -0,0 +1,110 @@
#xxx{
display: flex;
justify-content: space-around;
}
.pages-profile {
padding: 30px;
.profile-card {
padding: 9px;
text-align: center;
font-family: Roboto, sans-serif;
width: 500px;
height: 600px;
mat-card-content {
padding: 40px 15px;
margin: 0;
}
.mat-card-avatar {
width: 130px;
height: 130px;
margin-bottom: 10px;
}
.profile-user {
margin: 10px 0;
font-weight: normal;
}
.profile-job {
margin-bottom: 20px;
color: #9e9e9e;
font-weight: 500;
}
.profile-introduction {
margin: 0 0 1rem;
color: #757575;
}
.profile-social {
margin: 25px 0;
mat-icon {
margin: 0 10px;
color: rgba(66, 66, 66, .4);
}
}
mat-card-actions {
padding: 10px;
background: #f6f9fd;
}
.profile-card-footer {
display: flex;
justify-content: space-around;
.profile-stat-count {
display: block;
margin-bottom: 3px;
font-size: 20px;
font-weight: bold;
color: #616161;
+span {
color: #9e9e9e;
}
}
}
}
.profile-board {
padding: 30px;
width: 500px;
mat-list {
padding-bottom: 20px;
}
mat-list-item {
height: auto;
padding: 25px 0;
margin-left: -16px;
border-bottom: 1px solid #dfe0df;
.profile-item-content {
padding: 20px 0 0 56px;
line-height: 1.571429;
color: #757575;
white-space: normal;
display: flex;
flex-wrap: wrap;
img {
width: 100%;
max-width: 220px;
max-height: 150px;
padding: 0 20px 20px 0;
}
}
}
}
.show-more-btn {
width: 100%;
background-color: #eee;
color: #3949ab;
}
}

25
src/app/pages/personaldata/personaldata.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PersonaldataComponent } from './personaldata.component';
describe('PersonaldataComponent', () => {
let component: PersonaldataComponent;
let fixture: ComponentFixture<PersonaldataComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PersonaldataComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PersonaldataComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

15
src/app/pages/personaldata/personaldata.component.ts

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-personaldata',
templateUrl: './personaldata.component.html',
styleUrls: ['./personaldata.component.scss']
})
export class PersonaldataComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

81
src/app/pages/register/register.component.html

@ -0,0 +1,81 @@
<div class="login">
<div class="loginbox">
<div class="intro">
<p>北京安信科创有限公司</p>
<span>北京安信科创软件有限公司作为中国应急服务领跑者,于2006年进入消防救援领域,是一家专注于应急领域仿真培训演练与应急数据预判领域的软件服务供应商。安信主要利用大数据与虚拟现实技术实现对消防、公安、机场相关安防人员与企业安全监管人员的仿真培训与考核,致力于为我国应急产业的发展构建更美好的未来。目前,安信的业务遍布全国20多个省份和地区,服务全国将近四分之一以上的人口
</span>
</div>
<div class="card">
<mat-card>
<p class="cardheader">注册</p>
<p>Please register first</p>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<input matInput id="name" name="name"
required
ngModel #name="ngModel" placeholder="请输入账号">
</mat-form-field>
<!-- <div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert-danger">
<div *ngIf="name.errors.required">
账号不能为空
</div>
</div> -->
<mat-form-field>
<input matInput id="email" name="email"
required pattern="^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$"
ngModel #email="ngModel" placeholder="请输入邮箱">
</mat-form-field>
<!--
<div *ngIf="email.invalid && (email.dirty || email.touched)"
class="alert-danger">
<div *ngIf="email.errors.required">
邮箱不能为空
</div>
<div *ngIf="email.errors.pattern">
邮箱格式不正确
</div>
</div> -->
<mat-form-field>
<input matInput id="password" name="password" type='password'
required minlength="8"
ngModel #password="ngModel" placeholder="请输入密码">
</mat-form-field>
<!-- <div *ngIf="password.invalid && (password.dirty || password.touched)"
class="alert-danger">
<div *ngIf="password.errors.required">
密码不能为空
</div>
<div *ngIf="password.errors.minlength">
密码最少8位
</div>
</div> -->
<mat-checkbox style="margin-top: 25px;">请同意不扩散核武器条约条约</mat-checkbox>
<button type="submit" [disabled]="!form.form.valid" class="loginbtn"mat-button>注册</button>
</form>
<div class="applyfor">
<p>已有账号?去<a href="/login">登录</a></p>
</div>
<div class="website">
<p>WEBSITE BY AnXin</p>
<p>© 2020. All RIGHT RESERVED.</p>
</div>
</mat-card>
</div>
</div>
</div>

88
src/app/pages/register/register.component.scss

@ -0,0 +1,88 @@
.login {
width: 100%;
height: 100%;
background: url('../../../assets/images/background.jpg');
.loginbox {
width: 100%;
height: 100%;
background-color: #000;
background: rgba(0,0,0,0.5);/*盒子背景透明*/
// opacity: 0.5;
position: relative;
}
.intro {
width: 650px;
// height: 350px;
position: fixed;
top:35%;
left: 15%;
p {
font-size: 36px;
color:white;
margin-bottom: 35px;
}
span {
font-size: 16px;
color:white;
opacity: 0.5;
}
}
.card{
width: 460px;
height: 100%;
padding-left: 20px;
background-color: #fff;
position: absolute;
right: 0;
p {
width: 100%;
margin: 18px 0;
}
.cardheader{
font-size: 26px;
font-weight: 500;
}
}
}
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}
.loginbtn {
margin-top: 18px;
height: 35px;
background-color:#039be5;
border-radius: 15px;
color: #fff;;
}
.mat-card {
box-shadow: 0 0 0;
margin-top: 70px;
}
.applyfor {
font-size: 16px;
a {
color: #039be5;
}
}
.website {
font-size: 14px;
text-align: center;
margin-top: 50px;
}
.alert-danger {
font-size: 14px;
color: red;
}

25
src/app/pages/register/register.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegisterComponent } from './register.component';
describe('RegisterComponent', () => {
let component: RegisterComponent;
let fixture: ComponentFixture<RegisterComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RegisterComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RegisterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

18
src/app/pages/register/register.component.ts

@ -0,0 +1,18 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {
constructor() { }
ngOnInit() {
}
onSubmit(e){
}
}

43
src/app/pipes/boolean.pipe.ts

@ -0,0 +1,43 @@
import { Pipe, PipeTransform } from '@angular/core';
import { isno , PlanTypeEnum , AuditStatusEnum , PlanLevelEnum} from '../interface'
import {DomSanitizer} from '@angular/platform-browser'
@Pipe({name: 'isno'})
export class IsnoPipe implements PipeTransform {
transform(value: boolean): string {
if(value){
var x = 0
}else{
x=1
}
return isno[x]
}
}
@Pipe({name: 'plantype'})
export class PlanType implements PipeTransform {
transform(value: number): string {
return PlanTypeEnum[value]
}
}
@Pipe({name: 'auditsatus'})
export class AuditSatus implements PipeTransform {
transform(value: number): string {
return AuditStatusEnum[value]
}
}
@Pipe({name: 'planlevel'})
export class PlanLevel implements PipeTransform {
transform(value: number): string {
return PlanLevelEnum[value]
}
}
@Pipe({name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
}
transform(html) {
return this.sanitizer.bypassSecurityTrustHtml(html)
}
}

9
src/app/pipes/time.pipe.ts

@ -0,0 +1,9 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'time'})
export class TimePipe implements PipeTransform {
transform(value: string): string {
var newtime = value.substr(0,4) + '-' + value.substr(5,2) + '-' + value.substr(8,2)
return newtime
}
}

178
src/app/tabbar/tabbar.component.html

@ -0,0 +1,178 @@
<mat-toolbar [color]="theme?'primary':'accent'">
<!-- <mat-toolbar> -->
<h1>{{title}} <span *ngIf="planName != null">: {{planName}}</span> </h1>
<!--分数框-->
<!-- <div class="grade" *ngIf="grade" onmouseover="xiangqing.style.display='block';" onmouseout="xiangqing.style.display='none';">
<a class="active"><span ><a></a>{{grade}} 分</span></a>
</div> -->
<div class="uploadFile">
<a href="http://139.9.106.124:8088/ExaminationLauncher.zip"><span>获取中高级指挥长考评系统(仅供练习使用)</span></a>
</div>
<!--详情框 -->
<div class="integrityDetails" id="xiangqing">
<div class="integrityDetailsTop">
<span class="span1">分类名称</span>
<span class="span2">已得分</span>
<span class="span3">总分</span>
</div>
<div class="integrityDetailsBody">
<ul>
<li>
<div class="name">单位信息</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">建筑信息</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">平面图</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">四周毗邻</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">消防设施</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">重点部位</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">功能分区</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">实景图</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
<li>
<div class="name">CAD上传</div>
<div class="colorDiv">
<div class="colorDivBac">
<div class="colorDivCon" [style]="integrityDetails(8,10)"></div>
</div>
<span>8分</span>
</div>
<div class="number">10分</div>
</li>
</ul>
</div>
<div style="width: 100%;text-align: center;font-size: 13px;">
仅供参考
</div>
</div>
<p style="font-size: 16px;position: absolute; right: 170px;">欢迎您, {{realName}}</p>
<!-- 全屏 -->
<button mat-button (click)="!isfullscreen?fullscreenToggle():closefullscreen()" class="fullscreen">
<ng-container *ngIf="!isfullscreen; else elseTemplate">
<mat-icon *ngIf="!isfullscreen">fullscreen</mat-icon>
</ng-container>
<ng-template #elseTemplate>
<mat-icon else>fullscreen_exit</mat-icon>
</ng-template>
</button>
<!-- 黑夜模式开关 -->
<mat-slide-toggle (change)='onChange($event.checked)' class="darktheme"></mat-slide-toggle>
<!-- 锁屏按钮 -->
<!-- <button mat-button class="lockscreen" [routerLink]="['/lockscreen']" routerLinkActive="router-link-active" >
<mat-icon>screen_lock_landscape</mat-icon>
</button> -->
<!-- 登录信息按钮 -->
<button mat-icon-button [matMenuTriggerFor]="appMenu" class="login">
<mat-icon>account_circle</mat-icon>
</button>
<mat-menu #appMenu="matMenu">
<button mat-menu-item [routerLink]="['/ui/userdata']" >
<mat-icon>perm_identity</mat-icon>
<span>个人资料</span>
</button>
<button mat-menu-item (click)='changpsw()'>
<mat-icon>verified_user</mat-icon>
<span>修改密码</span>
</button>
<button mat-menu-item (click)='signOut()'>
<mat-icon>power_settings_new</mat-icon>
<span>退出系统</span>
</button>
</mat-menu>
<!-- 设置按钮 -->
<button mat-icon-button [matMenuTriggerFor]="appSet" class="setting">
<mat-icon>settings</mat-icon>
</button>
<mat-menu #appSet="matMenu" yPosition="below" xPosition="after">
<button mat-menu-item (click)="defaulttheme.next()">
<mat-icon>palette</mat-icon>
<span>默认主题</span>
</button>
<button mat-menu-item (click)="redtheme.next()">
<mat-icon>whatshot</mat-icon>
<span>亮色主题</span>
</button>
<button mat-menu-item (click)="standard()">
<mat-icon>settings_overscan</mat-icon>
<span>标准模式</span>
</button>
<button mat-menu-item (click)="boxed('boxed')">
<mat-icon>laptop</mat-icon>
<span>盒子模式</span>
</button>
</mat-menu>
</mat-toolbar>

181
src/app/tabbar/tabbar.component.scss

@ -0,0 +1,181 @@
//@import "/src/app/style.css";
mat-toolbar{
position: relative;
padding-left: 65px;
.grade{
width: 120px;
height: 45px;
//border:1px solid #F00;
position: absolute;
text-align: center;
margin-left: 250px;
margin-top: 0px;
-webkit-transform: rotate(-10deg);
-moz-transform: rotate(-10deg);
transform:text;
a{
box-sizing: border-box;
display: inline-block;
color: #fff;
//padding: 12px 5px;
text-decoration: none;
cursor: pointer;
}
span{
text-align: center;
font-size: 36px;
line-height: 45px;
font-family: "STXinwei";
color:#FFA500;
cursor: default;
text-decoration:underline;
padding-bottom:5px;
}
a.active>span ,a:hover>span {
//padding-bottom: 8px;
border-bottom: 3px solid #FFA500;
}
}
}
.logo{
height: 64px;
widows: 64px;
}
h1{
line-height: 64px;
color: white;
}
mat-icon{
color: white;
}
.login{
position: absolute;
right:30px;
}
.fullscreen{
position: absolute;
right:60px;
}
.setting{
position: absolute;
right:120px;
}
.lockscreen{
position: absolute;
right:160px;
}
.darktheme{
position: absolute;
right:140px;
display: none;
}
.boxed{
width: 1200px;
}
//鼠标移入详情页面显示
.integrityDetails{
position: absolute;
z-index: 999;
color: black;
display: none;
width: 350px;
height:290px;
left: 440px;
top: 30px;
border: 1px solid rgba(0, 0, 0, 0.22);
background-color: white;
.integrityDetailsTop{
width: 100%;
height: 23px;
line-height:23px;
border-bottom: 1px solid rgba(0, 0, 0, 0.22);
margin-bottom: 1px;
font-size: 14px;
span{
display: inline-block;
text-align: center;
font-weight: 800;
}
.span1{
width: 25%;
}
.span2{
width: 60%;
}
.span3{
width: 15%;
}
}
.integrityDetailsBody{
ul{
li{
width: 100%;
height: 23px;
line-height: 23px;
margin: 3px 15px;
div{
float: left;
font-size: 13px;
}
.name{
width: 25%;
height: 100%;
}
.colorDiv{
width: 60%;
height: 100%;
position: relative;
.colorDivBac{
width: 90%;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
background-color: #dfe5ec;
border-radius: 5px;
.colorDivCon{
border-radius: 5px;
height: 100%;
background-color: #2398f1;
}
}
span{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
// color: white;
font-weight: 600;
}
}
.number{
width: 15%;
height: 100%;
}
}
}
}
}
.uploadFile{
height: 64px;
line-height: 64px;
a{
color: rgb(26, 15, 179);
font-size: 22px;
position: absolute;
right: 370px;
}
a:hover{
text-decoration: underline;
color: red;
}
}

25
src/app/tabbar/tabbar.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TabbarComponent } from './tabbar.component';
describe('TabbarComponent', () => {
let component: TabbarComponent;
let fixture: ComponentFixture<TabbarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TabbarComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TabbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

135
src/app/tabbar/tabbar.component.ts

@ -0,0 +1,135 @@
import { Component, OnInit,Output,EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router,ActivatedRoute,NavigationEnd } from '@angular/router'
import {CacheTokenService} from '../http-interceptors/cache-token.service'//引入服务
import { MatDialog } from '@angular/material/dialog';
import {ChangepasswordComponent} from '../ui/changepassword/changepassword.component'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-tabbar',
templateUrl: './tabbar.component.html',
styleUrls: ['./tabbar.component.scss']
})
export class TabbarComponent implements OnInit {
theme: boolean = true;
@Output()
toggle = new EventEmitter<void>();
@Output()
toggleDarkTheme = new EventEmitter<boolean>();
@Output()
defaulttheme = new EventEmitter<boolean>();
@Output()
redtheme = new EventEmitter<boolean>();
onChange(eventValue: boolean){
this.toggleDarkTheme.emit(eventValue);
}
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,public dialog: MatDialog,
public snackBar: MatSnackBar) { }
grade = null //单位完整度得分
title:any = "数字化预案编制管理平台"
planName:any = null
routerEventsListener //监测路由变化
ngOnInit() {
}
ngOnDestroy(){
}
integrityDetails(width,zong){
let style:any = {}
style.width = (width/zong)*100 +'%';
return style
}
boxed(css){
const Element = document.body;
Element.style.width = '1200px'
}
standard(){
const Element = document.body;
Element.style.width = '100%'
}
isfullscreen:boolean = false;
fullscreenToggle(){
const docElmWithBrowsersFullScreenFunctions = document.documentElement as HTMLElement & {
mozRequestFullScreen(): Promise<void>;
webkitRequestFullscreen(): Promise<void>;
msRequestFullscreen(): Promise<void>;
};
if (docElmWithBrowsersFullScreenFunctions.requestFullscreen) {
docElmWithBrowsersFullScreenFunctions.requestFullscreen();
} else if (docElmWithBrowsersFullScreenFunctions.mozRequestFullScreen) { /* Firefox */
docElmWithBrowsersFullScreenFunctions.mozRequestFullScreen();
} else if (docElmWithBrowsersFullScreenFunctions.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
docElmWithBrowsersFullScreenFunctions.webkitRequestFullscreen();
} else if (docElmWithBrowsersFullScreenFunctions.msRequestFullscreen) { /* IE/Edge */
docElmWithBrowsersFullScreenFunctions.msRequestFullscreen();
}
this.isfullscreen = true;
}
closefullscreen(){
const docWithBrowsersExitFunctions = document as Document & {
mozCancelFullScreen(): Promise<void>;
webkitExitFullscreen(): Promise<void>;
msExitFullscreen(): Promise<void>;
};
if (docWithBrowsersExitFunctions.exitFullscreen) {
docWithBrowsersExitFunctions.exitFullscreen();
} else if (docWithBrowsersExitFunctions.mozCancelFullScreen) { /* Firefox */
docWithBrowsersExitFunctions.mozCancelFullScreen();
} else if (docWithBrowsersExitFunctions.webkitExitFullscreen) { /* Chrome, Safari and Opera */
docWithBrowsersExitFunctions.webkitExitFullscreen();
} else if (docWithBrowsersExitFunctions.msExitFullscreen) { /* IE/Edge */
docWithBrowsersExitFunctions.msExitFullscreen();
}
this.isfullscreen = false;
}
realName:any; //登录用户信息
//获取用户信息
getUserInfo () {
this.http.get("/api/Account/Profiles").subscribe((data:any)=>{
this.realName = data.realName
})
}
//退出系统
signOut = () => {
let out = confirm("您确定要退出吗")
if(out) {
this.http.post('/api/Account/SignOut',{}).subscribe(
data=> {
this.token.delete()
sessionStorage.clear()
window.localStorage.clear()
const config = new MatSnackBarConfig();
config.verticalPosition = 'bottom';
config.duration = 3000
this.snackBar.open('成功退出','确定',config);
}
)
}
}
//修改密码
changpsw() {
let dialogRef = this.dialog.open(ChangepasswordComponent,
{width:'348px'});
dialogRef.afterClosed().subscribe();
}
}

18
src/app/theme.scss

@ -0,0 +1,18 @@
@import "./theming";
@include mat-core();
$my-app-primary:mat-palette($mat-blue,500);
$my-app-accent :mat-palette($mat-pink,A200,A100,A400);
$my-app-warn :mat-palette($mat-red);
$my-app-theme :mat-light-theme($my-app-primary,$my-app-accent,$my-app-warn);
@include angular-material-theme($my-app-theme);
$my-dark-primary:mat-palette($mat-red,A700);
$my-dark-accent :mat-palette($mat-amber,A200,A100,A400);
$my-dark-warn :mat-palette($mat-deep-orange);
$my-dark-theme :mat-dark-theme($my-dark-primary,$my-dark-accent,$my-dark-warn);
.myapp-dark-theme{
@include angular-material-theme($my-dark-theme);
}

48
src/app/ui/changepassword/changepassword.component.html

@ -0,0 +1,48 @@
<div mat-dialog-title>
修改密码
</div>
<div class="passwordCard" mat-dialog-content>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<span class="cardLeft">原密码</span>
<mat-form-field>
<input matInput id="password" name="password"
required type="password"
ngModel #password="ngModel" placeholder="请输入原密码">
</mat-form-field>
<span class="cardLeft">新密码</span>
<mat-form-field>
<input matInput id="newPassword" name="newPassword" type="password"
required pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[A-Za-z0-9]{8,20}$"
ngModel #newPassword="ngModel" placeholder="请输入新密码">
</mat-form-field>
<div *ngIf="newPassword.invalid && (newPassword.dirty || newPassword.touched)">
<div class="group-error-content">密码格式8-20位,字母+数字</div>
</div>
<span class="cardLeft">确认新密码</span>
<mat-form-field>
<input matInput id="newsPassword" name="newsPassword" type="password"
required
ngModel #newsPassword="ngModel" placeholder="请确认新密码"
[appConfirmpsw] = "newPassword.value">
</mat-form-field>
<div *ngIf="newsPassword.touched&&newsPassword.invalid">
<div class="group-error-content">密码输入不一致!</div>
</div>
<div *ngIf="errmsg" class="group-error-content">
{{errmsg}}
</div>
<div mat-dialog-actions class="btnbox">
<button mat-raised-button color="primary" type="submit"
[disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button color="primary" mat-dialog-close>取消</button>
</div>
</form>
</div>

15
src/app/ui/changepassword/changepassword.component.scss

@ -0,0 +1,15 @@
.passwordCard {
width: 300px;
height: 100%;
}
.mat-form-field {
display: block;
width: 300px;
}
.group-error-content {
font-size: 12px;
color: red;
}
.mat-dialog-content {
overflow: visible
}

44
src/app/ui/changepassword/changepassword.component.ts

@ -0,0 +1,44 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { MatDialogRef } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
@Component({
selector: 'app-changepassword',
templateUrl: './changepassword.component.html',
styleUrls: ['./changepassword.component.scss']
})
export class ChangepasswordComponent implements OnInit {
constructor(private http:HttpClient,public snackBar: MatSnackBar,
public dialogRef: MatDialogRef<ChangepasswordComponent>) { }
ngOnInit() {
}
errmsg :string = ''
onSubmit(e){
this.http.put(
'/api/Account/Password',
{
newPassword: e.newPassword,
password: e.password
}
).subscribe(data=> {
this.dialogRef.close(data);
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('密码修改成功','确定',config);
},(err) =>
{this.errmsg = err}
)
}
}

30
src/app/ui/changepassword/equal-validator.directive.ts

@ -0,0 +1,30 @@
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl, ValidatorFn} from '@angular/forms';
@Directive({
selector: '[appConfirmpsw]',
providers: [{
provide : NG_VALIDATORS,
useExisting : ConfirmpswDirective,
multi: true
}]
})
export class ConfirmpswDirective implements Validator {
@Input('appConfirmpsw') confirmpsw: string;
constructor() {
}
validate(control: AbstractControl): {[key: string]: any} {
return this.confirmpsw ? comfirmPswValidator(this.confirmpsw)(control) : null;
}
}
export function comfirmPswValidator(_confirmpsw: string): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
if ( !control.value ) {
return { 'required' : true };
}
return control.value !== _confirmpsw ? {'confirmpsw' : {value: true}} : null;
};
}

24
src/app/ui/collection-tools/addDisposalNode.html

@ -0,0 +1,24 @@
<div class="functionalDomainContent">
<div mat-dialog-title>
<label *ngIf="!data.parentId">新建处置节点</label>
<label *ngIf="data.parentId">新建节点</label>
</div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div class="keyMargin">
<mat-form-field>
<input matInput name="name" required ngModel placeholder="名称">
</mat-form-field>
</div>
<div class="submitBottom">
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

38
src/app/ui/collection-tools/addPlaneFigure.html

@ -0,0 +1,38 @@
<div class="functionalDomainContent">
<div mat-dialog-title>
<label *ngIf="!data.isBuilding">新建平面图</label>
<label *ngIf="data.isBuilding">新建楼层/区域</label>
</div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div class="keyMargin">
<mat-form-field>
<input matInput name="name" required ngModel placeholder="名称">
</mat-form-field>
</div>
<div class="keyMargin" *ngIf="data.isBuilding">
<mat-checkbox name="isRefugeStorey" [(ngModel)]="checked">是否为避难层</mat-checkbox>
</div>
<div class="keyMargin">
<mat-form-field>
<input matInput name="area" type="number" required ngModel placeholder="面积 (平方米)">
</mat-form-field>
</div>
<div class="keyMargin">
<textarea name="details" ngModel placeholder="详情"></textarea>
</div>
<div class="submitBottom">
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

530
src/app/ui/collection-tools/collection-tools.component.html

@ -0,0 +1,530 @@
<div class="content">
<!-- header头部 -->
<div class="header" style="display: none;">
<button mat-button (click)="toggle()">
<mat-icon style="vertical-align: middle;">toc</mat-icon>
</button>
<button mat-button (click)="toggle2()">
<mat-icon style="vertical-align: middle;">list</mat-icon>
</button>
<span style="color: gray;margin-right: 10px;margin-left: 10px;">图标大小</span>
<mat-form-field style="margin-top: 3px;">
<mat-select (selectionChange)='iconScale()' [(ngModel)]="selected">
<mat-option value="1">正常</mat-option>
<mat-option value="2">放大2倍</mat-option>
<mat-option value="4">放大4倍</mat-option>
</mat-select>
</mat-form-field>
<button (click)="copyAsset()" class="copytobutn" mat-button title="复制" style="margin:0 5px;" *ngIf="isEditPattern">
<mat-icon style="padding-bottom: 7px;">library_books</mat-icon>
</button>
<button (click)="pasteAsset()" class="copytobutn" mat-button title="粘贴" *ngIf="isEditPattern">
<mat-icon style="padding-bottom: 7px;">screen_share</mat-icon>
</button>
<span title="基本信息名称显示/隐藏" style="margin-right:20px;user-select: none;margin-left: 12px;" class="nameShow" (click)="basicInfoClick()">
基本信息名称
<mat-icon [ngClass]="{'icongray': !basicInfo}">visibility</mat-icon>
</span>
<span title="想定作业名称显示/隐藏" style="user-select: none;" class="nameShow" (click)="wantToWorkClick()">
想定作业名称
<mat-icon [ngClass]="{'icongray': !wantToWork}">visibility</mat-icon>
</span>
<div class="patternSwitch">
<span (click)="baseInfo()" [ngClass]="{'selectedPattern': pattern}">
基本信息编辑
</span>
<span (click)="wantWork()" [ngClass]="{'selectedPattern': !pattern}">
想定作业编辑
</span>
</div>
<span style="position: absolute;right: 60px;cursor: pointer;">
<mat-icon title="查看/编辑模式" (click)="lookpat()" *ngIf="isEditPattern">tv</mat-icon>
<mat-icon title="查看/编辑模式" (click)="editpat()" *ngIf="!isEditPattern">create</mat-icon>
<mat-icon *ngIf="isEditPattern " style="margin-left: 12px;" title="保存" (click)="saveSite()">description</mat-icon>
</span>
</div>
<!-- 头部操作栏 -->
<div class="headerOperate" style="display: none;">
<button mat-button (click)="checkedBuilding({name:'总平面图'},-1)"
[ngClass]="{'buildingbtnchecked': checkedBuildingIndex==-1}">
<span>总平面图</span>
<span *ngIf="isEditPattern && !pattern">
<img src="../../../assets/images/noFire.png" *ngIf="sitePlanIcon.fire==1 && sitePlanBuildingID!=params.companyId">
<img src="../../../assets/images/noForce.png" *ngIf="sitePlanIcon.force==1 && sitePlanBuildingID!=params.companyId">
<img src="../../../assets/images/fire.png" *ngIf="sitePlanIcon.fire==1 && sitePlanBuildingID==params.companyId">
<img src="../../../assets/images/force.png" *ngIf="sitePlanIcon.force==1 && sitePlanBuildingID==params.companyId">
</span>
</button>
<button mat-button *ngFor="let item of allBuildings;let key = index" (click)="checkedBuilding(item,key)" class="bigeditdeletebtn"
[ngClass]="{'buildingbtnchecked': checkedBuildingIndex==key}">
<span>{{item.name}}</span>
<span *ngIf="isEditPattern && !pattern">
<img src="../../../assets/images/noFire.png" *ngIf="item.fire && item.fire==1 && sitePlanBuildingID!=item.id">
<img src="../../../assets/images/noForce.png" *ngIf="item.force && item.force==1 && sitePlanBuildingID!=item.id">
<img src="../../../assets/images/fire.png" *ngIf="item.fire && item.fire==1 && sitePlanBuildingID==item.id">
<img src="../../../assets/images/force.png" *ngIf="item.force && item.force==1 && sitePlanBuildingID==item.id">
</span>
<span class="editdeletebtn" *ngIf="isEditPattern && pattern">
<mat-icon (click)="editBuilding($event,item)"
style="font-size: 23px;vertical-align:sub;margin-left: 6px;color: rgb(26, 194, 26);">create</mat-icon>
<mat-icon (click)="deleteBuilding($event,item)"
style="font-size: 23px;vertical-align:sub;color: rgb(224, 51, 51);">delete</mat-icon>
</span>
</button>
<button mat-button (click)="createBuilding()" *ngIf="isEditPattern && pattern">
<span style="font-size: 24px;">+</span>
</button>
<div class="bigBox" *ngIf="!pattern">
<div class="weatherBox" [ngClass]="{'opened': weatherBtn,'close': !weatherBtn}">
<mat-icon class="openbtn" *ngIf="weatherBtn" (click)="weatherBtnHidden()">keyboard_arrow_right</mat-icon>
<mat-icon class="openbtn" *ngIf="!weatherBtn" (click)="weatherBtnShow()">keyboard_arrow_left</mat-icon>
<span class="name">天气</span>
<input [(ngModel)]="canvasData.selectPanelPointBaseData.weather" type="text" placeholder="最多输入10字节" maxlength="10">
<span class="name">气温</span>
<div style="display: inline-block;position: relative;">
<input [(ngModel)]="canvasData.selectPanelPointBaseData.airTemperature" style="width: 120px;" type="number" value="0" oninput="if(value.length>2)value=value.slice(0,2)">
<span style="position: absolute;right:17px;color: #9c9fa5;"></span>
</div>
<span class="name">风力</span>
<select [(ngModel)]="canvasData.selectPanelPointBaseData.windScale">
<option value ="0">0(无风)</option>
<option value ="1">1(软风)</option>
<option value ="2">2(轻风)</option>
<option value ="3">3(微风)</option>
<option value ="4">4(和风)</option>
<option value ="5">5(清风)</option>
<option value ="6">6(强风)</option>
</select>
<span class="name">风向</span>
<select [(ngModel)]="canvasData.selectPanelPointBaseData.windDirection">
<option value ="0"></option>
<option value ="1">西</option>
<option value ="2"></option>
<option value ="3"></option>
<option value ="4">东南</option>
<option value ="5">西南</option>
<option value ="6">东北</option>
<option value ="7">西北</option>
</select>
</div>
</div>
</div>
<!-- 头部操作栏 -->
<div class="headerOperate">
<div class="bigeditdeletebtn" (click)="checkedBuilding({name:'总平面图'},-1)" [ngClass]="{'buildingbtnchecked': checkedBuildingIndex==-1}">
<span>总平面图</span>
</div>
<div class="bigeditdeletebtn" *ngFor="let item of allBuildings;let key = index" (click)="checkedBuilding(item,key)" [ngClass]="{'buildingbtnchecked': checkedBuildingIndex==key}">
<span>{{item.name}}</span>
</div>
<!-- <div class="bigTalkBox" style="position: absolute;right: 26px;">
<mat-icon class="titleIcon" (click)="openTalkDiv()">volume_up</mat-icon>
<div class="talkBox" *ngIf="isOpenTalk">
<div class="btndiv">
<div>泵房</div>
<div>控制室</div>
</div>
<div class="bottomDiv">
<div>
<mat-icon>settings_voice</mat-icon>
</div>
<div>
按住说话
</div>
<div>
<mat-icon>search</mat-icon>
</div>
</div>
</div>
</div> -->
</div>
<!--功能区 -->
<div class="functionalDomain">
<div class='functionalDomainContent' id="functionalDomainContent">
<!-- H5Canvas -->
<div id="leftDiv" class='functionalDomainLeft publicCss' [ngClass]="{'togglePanel': toggleExpandPanel==true,'scenarioAssignment': !pattern}" style="user-select: none;">
<!-- 平面图 -->
<div class="planarGraph" style="display: none;">
<div class="planarGraphHeader" (click)='togglePlanarGraph()'>
<mat-icon *ngIf="togglePlane">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!togglePlane">keyboard_arrow_down</mat-icon>
<label class="overflowText" style="font-weight: 550;">平面图</label>
<label class="hover" *ngIf="isEditPattern && pattern">
<mat-icon (click)='foundPanel($event)'>add</mat-icon>
</label>
</div>
<div [hidden]="!togglePlane" >
<div class="sitePlanContent" *ngFor="let item of sitePlanData;let key = index" [ngClass]="{'isRefugeStorey':item.isRefugeStorey==true,'selectSitePlan': selectSitePlanIndex==key}" (click)='selectSitePlan(item,key)'>
<mat-icon *ngIf="!item.imageUrl" class="matIcons">broken_image</mat-icon>
<label class="overflowText">{{item.name}}</label>
<a href="javascript:;" class="fireForce" *ngIf="isEditPattern && !pattern">
<img src="../../../assets/images/noFire.png" *ngIf="item.fire && item.fire==1 && storeyID!=item.id">
<img src="../../../assets/images/noForce.png" *ngIf="item.force && item.force==1 && storeyID!=item.id">
<img src="../../../assets/images/fire.png" *ngIf="item.fire && item.fire==1 && storeyID==item.id">
<img src="../../../assets/images/force.png" *ngIf="item.force && item.force==1 && storeyID==item.id">
</a>
<a href="javascript:;" class="a-upload" *ngIf="selectSitePlanIndex==key && isEditPattern && pattern" title="替换底图" >
<input type="file" (change)='replaceBaseMap($event,item)' accept="image/*">
<mat-icon class="matIcons">photo_size_select_actual</mat-icon>
</a>
<a href="javascript:;" id="a-uploadImg" *ngIf="selectSitePlanIndex==key && !item.imageUrl && isEditPattern" title="上传底图" >
<input type="file" (change)='replaceBaseMap($event,item)' accept="image/*">
<img src="../../../assets/images/upload.jpg">
</a>
<!-- 右边定位操作栏 -->
<div id="rightOperate" *ngIf="selectSitePlanIndex==key && item.imageUrl && isEditPattern" (click)="$event.stopPropagation();">
<p class="functionButton">
<mat-icon class="functionIcon bigFunctionIcon" title="上移" (click)='moveUp(item,key)'>keyboard_arrow_up</mat-icon>
</p>
<p class="functionButton">
<mat-icon class="functionIcon" title="编辑属性" (click)='editPlaneData(item)'>edit</mat-icon>
<mat-icon class="functionIcon" title="删除" (click)="deletePlaneData(item)">delete</mat-icon>
</p>
<p class="functionButton">
<mat-icon class="functionIcon" title="旋转底图" (click)='revolveImg(item)'>cached</mat-icon>
<mat-icon class="functionIcon" title="复制" (click)="duplicateLayer(item)">library_books</mat-icon>
</p>
<p class="functionButton">
<mat-icon class="functionIcon bigFunctionIcon" title="下移" (click)='moveDown(item,key)'>keyboard_arrow_down</mat-icon>
</p>
</div>
<!-- 右边定位操作栏 -->
</div>
</div>
</div>
<!-- 平面图 -->
<!-- 素材库 -->
<div id="materialBank" *ngIf="isEditPattern" [ngClass]="{'selectEditMode': pattern}" style="display: none;">
<!-- <div class="planarGraphHeader" (click)='toggleMaterial()'>
<mat-icon *ngIf="toggleMaterialBank">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!toggleMaterialBank">keyboard_arrow_down</mat-icon>
<label class="overflowText" style="font-weight: 550;">素材库</label>
</div> -->
<div class="planarGraphHeader">
<label class="overflowText">素材库</label>
</div>
<div [hidden]="!toggleMaterialBank" [ngClass]="{'materialBankDIV': pattern}">
<mat-accordion *ngFor="let item of allLibrary" id="panelLibrary">
<mat-expansion-panel (opened)='opened(item)'>
<mat-expansion-panel-header>
<label class="text">{{item.name}}</label>
</mat-expansion-panel-header>
<div class="panelLibraryFlex">
<div class="imgBox" *ngFor="let items of item.images;let key = index" [title]="items.name"
(click)='selectImg(item,items,key)'
[ngClass]="{'selectImg': selectLibrary==item.name && selectImageIndex==key}">
<img [src]="items.imageUrl" onerror="javascript:this.src='../../../assets/images/noImg.png'">
<p class="overflowText">{{items.name}}</p>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<!-- 素材库 -->
<!-- 处置预案 -->
<div class="handlePlan">
<!-- <div class="planarGraphHeader" (click)='toggleHandlePlan()'>
<mat-icon *ngIf="toggleHandlePlans">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!toggleHandlePlans">keyboard_arrow_down</mat- icon>
<label class="overflowText" style="font-weight: 550;">处置预案</label>
<label style="margin-left: 45px;">
<mat-icon style="color: #c2a40ce8;" title="计算差异" (click)='countValue($event)'>flash_on</mat-icon>
<mat-icon style="margin-left: 3px;" title="新建空节点" (click)='addPanelPoint($event,null,fireTreeData)'>add</mat-icon>
</label>
</div> -->
<div class="planarGraphHeader">
<label class="overflowText">处置预案</label>
</div>
<div [hidden]="!toggleHandlePlans">
<mat-tree [dataSource]="fireTreeData" [treeControl]="fireTreeControl" >
<mat-tree-node *matTreeNodeDef="let node;" matTreeNodePadding cdkTreeNodePaddingIndent='5' id="terrNodePublic" (click)='selectanelPoint(node)' [ngClass]="{'selectanelPoint': selectDisposalNode==node.id}">
<button mat-icon-button disabled><mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId">arrow_drop_up</mat-icon></button>
<label title="{{node.name}}" class="textNode overflowText">
{{node.name}}
</label>
<!-- <div class="planIconDiv">
<mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId" (click)='editPanelPoint($event,node)'>edit</mat-icon>
<mat-icon *ngIf="node.level<1" (click)='addPanelPoint($event,node,null)'>add</mat-icon>
<mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId" (click)='copyPanelPoint($event,node,fireTreeData)'>library_books</mat-icon>
<mat-icon (click)='deletePanelPoint($event,node)'>delete_forever</mat-icon>
</div> -->
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding cdkTreeNodePaddingIndent='5' id="terrNodePublic" (click)='selectanelPoint(node)' [ngClass]="{'selectanelPoint': selectDisposalNode==node.id}">
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId">{{fireTreeControl.isExpanded(node) ? 'arrow_drop_down' : 'arrow_drop_up'}}</mat-icon>
</button>
<label title="{{node.name}}" class="textNode overflowText">
{{node.name}}
</label>
<!-- <div class="planIconDiv">
<mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId" (click)='editPanelPoint($event,node)'>edit</mat-icon>
<mat-icon *ngIf="node.level<1" (click)='addPanelPoint($event,node,null)'>add</mat-icon>
<mat-icon *ngIf="!node.sitePlanId && !node.buildingAreaId" (click)='copyPanelPoint($event,node,fireTreeData)'>library_books</mat-icon>
<mat-icon (click)='deletePanelPoint($event,node)'>delete_forever</mat-icon>
</div> -->
</mat-tree-node>
</mat-tree>
</div>
</div>
<!-- 处置预案 -->
</div>
<!-- H5Canvas -->
<div class="canvas" style="position: relative;" >
<!-- 右侧楼层区域 -->
<!-- <div class="showRightStorey" *ngIf="!rightIsShow" title="打开楼层/区域"><mat-icon (click)='openRight()'>keyboard_arrow_left</mat-icon></div> -->
<div class="rightStorey" [ngClass]="{closeRight: !rightIsShow,openRight: rightIsShow}" cdkDragBoundary=".canvas" cdkDrag >
<div style="flex: 10%;" cdkDragHandle>
<!-- <label><mat-icon (click)='closeRight()' title="关闭楼层/区域">keyboard_arrow_right</mat-icon> 楼层/区域</label> -->
<label>楼层/区域</label>
</div>
<div style="flex: 90%;border-top: 1px solid #30bbec;padding: 1px 0;">
<div *ngFor="let item of sitePlanData;let key = index" style="font-size: 14px;width: 100%;height: 35px;line-height: 35px;background-color: rgba(7,89,155,0.7);"><label>{{item.name}}</label></div>
</div>
</div>
<!-- 右侧楼层区域 -->
<app-working-area #canvas [init]='this'></app-working-area>
<!-- 下方 -->
<div class="openbottombtn" *ngIf="!bottomIsShow" (click)="openedbottom()"><mat-icon> keyboard_arrow_up </mat-icon></div>
<div class="canvasbottomCss" [ngClass]="{'closeBottom': !bottomIsShow,'openBottom': bottomIsShow}">
<div class="title">
<div (click)="details()" [ngClass]="{'detailsAndattentBtn': detailsAndattentBtn}">
节点详情
</div>
<div (click)="attent()" [ngClass]="{'detailsAndattentBtn': !detailsAndattentBtn}">
注意事项
</div>
<div class="closebottombtn" (click)="closedbottom()"><mat-icon> expand_more </mat-icon></div>
</div>
<div class="body">
<div *ngIf="detailsAndattentBtn">{{canvasData.selectPanelPointBaseData.description}}</div>
<div *ngIf="!detailsAndattentBtn">{{canvasData.selectPanelPointBaseData.notes}}</div>
</div>
</div>
</div>
<div id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<div class="title">
<span (click)="rightSwitch(1)" [ngClass]="{selectedTitle: isProperty}">
属性
</span>
<span (click)="rightSwitch(2)" [ngClass]="{selectedTitle: !isProperty}">
消防要素
</span>
</div>
<div style="width: 100%;height: 100%;">
<!-- 属性 -->
<div *ngIf="isProperty" id="property" class="property" style="height: 94%;">
<!-- 平面图属性 -->
<div class="siteproperty" style="user-select: none" *ngIf="isShowProperty && isShowAttribute">
<p>面积(平方米)</p>
<div class="siteproperty_size">{{canvasData.selectStorey.area}}</div>
<p>详情</p>
<div class="siteproperty_size">
{{canvasData.selectStorey.details}}
</div>
</div>
<!-- 素材属性 -->
<div class="assetsproperty" style="user-select: none" *ngIf="isShowProperty && !isShowAttribute">
<h3 style="text-align: center;font-weight: 900;">{{assetName}}</h3>
<div *ngIf="canvasAssetObj.InteractiveMode == 0">
<p>宽度(像素)</p>
<div class="siteproperty_size">{{assetWidth}}</div>
<p>高度(像素)</p>
<div class="siteproperty_size">{{assetHeight}}</div>
<p>角度</p>
<div style="width: 100%;display: flex;vertical-align: top;height: 22px;">
<!-- <input type="number" class="smallinput" [(ngModel)]="sliderValue"
oninput="if(value>360)value=360;if(value<0)value=0;" (input)="assetAngleIunput()">
<mat-slider color="primary" min="0" max="360" step="1" style="bottom: 12px;left: 2px;width: 70%;"
[(ngModel)]="sliderValue" (change)="assetAngleIunput()"></mat-slider> -->
<div class="siteproperty_size">{{sliderValue}}</div>
</div>
</div>
<!-- 如果是多点连线 -->
<div *ngIf="canvasAssetObj.InteractiveMode == 1">
<p>厚度</p>
<div style="width: 100%;display: flex;vertical-align: top;height: 22px;">
<!-- <input type="number" class="smallinput" [(ngModel)]="sliderValueThickness"
oninput="if(value>999)value=999;if(value<0)value=0;" (input)="assetThicknessIunput()">
<mat-slider color="primary" min="0" max="999" step="1" style="bottom: 12px;left: 2px;width: 70%;"
[(ngModel)]="sliderValueThickness" (change)="assetThicknessIunput()"></mat-slider> -->
<div class="siteproperty_size">{{sliderValueThickness}}</div>
</div>
</div>
<!-- <p style="margin-top: 4px;margin-bottom: 0px;">是否高亮</p>
<div>
<input class="input" [(ngModel)]="isHighLight" type="checkbox">
<span style="font-size: 14px;">选中高亮</span>
</div> -->
<div *ngIf="canvasAssetObj.FillMode == 0" style="margin-top: 6px;">
<div class="colorBigTemplateDiv">
<span style="
font-size: 16px;
color: #d0e0f4;
padding-left: 7px;
letter-spacing:3px;
margin: 5px 0;">颜色</span>
<div class="colorTemplateDiv" [style]="{'background-color':selectedcolor}">
</div>
</div>
<!-- <div class="colorDiv">
<ul>
<li class="colorLi" *ngFor="let item of colors,let key=index" [style]="{'background-color':item}"></li>
</ul>
</div> -->
<p>透明度</p>
<!-- <span style="color: #9c9fa5;font-size: 14px;">透明度</span> -->
<!-- <mat-slider color="primary" min="0" max="100%" step="1" style="left: 1px; width: 55%;min-width: 90px;"
[(ngModel)]="colorDivSliderValue" (change)="colorDivSliderChange()"></mat-slider>
<span style="color: #9c9fa5;font-size: 12px;">{{colorDivSliderValue}}%</span> -->
<div class="siteproperty_size">{{colorDivSliderValue}}%</div>
</div>
<div *ngFor="let item of PropertyInfos;index as key ">
<!-- 单行文本 -->
<div *ngIf="item.PropertyType == 0">
<p>{{item.PropertyName}}<span style="font-size: 14px;" *ngIf="item.PhysicalUnit">({{item.PhysicalUnit}})</span></p>
<!-- <input type="text" class="biginput" [value]="item.PropertyValue" (input)="assetInputChange(item,$event)"> -->
<div class="siteproperty_size">{{item.PropertyValue}}</div>
</div>
<!-- 多行文本 -->
<div *ngIf="item.PropertyType == 1">
<p>{{item.PropertyName}}<span style="font-size: 14px;" *ngIf="item.PhysicalUnit">({{item.PhysicalUnit}})</span></p>
<!-- <textarea class="textarea" name="" id="" [value]="item.PropertyValue" (input)="assetInputChange(item,$event)"></textarea> -->
<div class="siteproperty_size">{{item.PropertyValue}}</div>
</div>
<!-- 数值 -->
<div *ngIf="item.PropertyType == 2">
<p>{{item.PropertyName}}<span style="font-size: 14px;" *ngIf="item.PhysicalUnit">({{item.PhysicalUnit}})</span></p>
<div class="siteproperty_size">{{item.PropertyValue}}</div>
</div>
<!-- 图片数量 -->
<div *ngIf="item.PropertyType == 4" style="height: 140px;">
<div style="position: relative;width: 100%;height: 21px;margin: 1px 0;">
<p style="width: 40%;display: inline-block;">{{item.PropertyName}}</p>
<span style="width: 26%;text-align:right;font-size: 13px;">{{imagesArr.length ? imagesArr.length : 0}} / {{item.PropertyValue}}</span>
<div style="position: relative;;width: 89%;border:1px solid rgb(208, 211, 214);height: 140px;margin: 6px auto;" class="swiper-container">
<div id="viewerjs" class="swiper-wrapper" [ngClass]="{'noImgCss': imagesArr.length == 0}">
<div class="swiper-slide" style="text-align: center;" *ngFor="let img of imagesArr"><img [src]="img.PropertyValue + '?x-oss-process=image/resize,m_fixed,h_140,w_140'" alt="" [attr.data-original]="img.PropertyValue"></div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
</div>
</div>
<!-- 方向 -->
<div *ngIf="item.PropertyType == 5">
<p>{{item.PropertyName}}</p>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==0"></div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==1">西</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==2"></div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==3"></div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==4">东南</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==5">西南</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==6">东北</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==7">西北</div>
</div>
<!-- 布尔值 是1或否0 -->
<div *ngIf="item.PropertyType == 6">
<p>{{item.PropertyName}}</p>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==1"></div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==0"></div>
<!-- <input [checked]="item.PropertyValue == 1" class="input" type="radio" name="radio" (click)="assetRadioChange(item,'1')"><span>是</span>
<input [checked]="item.PropertyValue == 0" class="input" type="radio" name="radio" (click)="assetRadioChange(item,'0')"><span></span> -->
</div>
<!-- 供给区域 -->
<div *ngIf="item.PropertyType == 7">
<p style="display: inline-block;">{{item.PropertyName}}</p>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==0">全部</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==1">高区</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==2">中区</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==3">低区</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==4">高中区</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==5">高低区</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==6">中底区</div>
</div>
<!-- 供给类型 -->
<div *ngIf="item.PropertyType == 8">
<p style="display: inline-block;">{{item.PropertyName}}</p>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==0">消火栓</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==1">喷淋</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==2">水幕</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==3">泡沫</div>
<div class="siteproperty_size" *ngIf="item.PropertyValue ==4">消防</div>
</div>
</div>
</div>
</div>
<!-- 消防要素 -->
<div *ngIf="!isProperty" id="firecategories" class="firecategories" style="height:94%;">
<div class="firecategoriesTree">
<!-- 消防列表树写在这里 -->
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node cdkDrag cdkDragDisabled="false" [ngClass]="{'isLookPattern': !node.isLookPattern}" *matTreeNodeDef="let node;" matTreeNodePadding cdkTreeNodePaddingIndent='26' (click)="clickTreeNode(node)" class="treeNode">
<button mat-icon-button disabled></button>
<span title="{{node.name}}" [ngClass]="{'treeText': !node.isTemplate}">
{{node.name}}
</span>
<span *ngIf="node.isTemplate">({{node.children.length}})</span>
<span class="isLookCss" (click)="clickLookItem(node)"><mat-icon [ngClass]="{'icongray': node.isLook == false}">visibility</mat-icon></span>
</mat-tree-node>
<mat-tree-node cdkDrag cdkDragDisabled="false" [ngClass]="{'isLookPattern': !node.isLookPattern}" *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)="clickTreeNode(node)"class="treeNode" >
<button mat-icon-button
matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
<span title="{{node.name}}" [ngClass]="{'treeText': !node.isTemplate}">
{{node.name}}
</span>
<span *ngIf="node.isTemplate && node.isNewElement">({{node.children.length}})</span>
<span class="isLookCss" (click)="clickLookItem(node)"><mat-icon [ngClass]="{'icongray': node.isLook == false}">visibility</mat-icon></span>
</mat-tree-node>
</mat-tree>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

677
src/app/ui/collection-tools/collection-tools.component.scss

@ -0,0 +1,677 @@
@import './panel.scss';
.icongray{
color: #D9D0DC;
}
.content {
width: 100%;
height: 100%;
overflow: hidden;
box-sizing: border-box;
padding: 1px;
display: flex;
flex-direction: column;
.buildingbtnchecked{
color: white;
background-image: url("../../../assets/images/标签选中.png")!important;
}
}
//header头部
.header {
position: relative;
flex: 5%;
display: flex;
align-items:center;
min-height: 40px;
background-color: #fff;
.nameShow{
cursor: pointer;
user-select: none;
}
.copytobutn{
width: 33px;
min-width: 33px;
display: flex;
justify-content: center;
}
font-size: 18px;
mat-icon{
font-size: 26px;
vertical-align: text-top;
}
span{
height: 24px;
line-height: 24px;
}
.patternSwitch{
position: absolute;
right: 140px;
span{
font-size: 18px;
cursor: pointer;
margin: 0 3px;
display: inline-block;
border: 1px solid gray;
border-radius: 3px;
padding: 0 5px;
}
.selectedPattern{
background-color: #2196f3;
color: white;
}
}
}
// //头部操作栏
// .headerOperate {
// img {
// width: 24px;
// height: 24px;
// vertical-align: middle;
// margin-left: 1px;
// }
// span{
// font-size: 18px;
// }
// flex: 5%;
// display: flex;
// align-items:center;
// min-height: 40px;
// box-sizing: border-box;
// margin: 3px 0;
// background-color: white;
// button{
// border: 0.5px solid rgb(208, 211, 214);
// margin: 0 2px;
// }
// .editdeletebtn{
// display: none;
// }
// .bigeditdeletebtn:hover{
// .editdeletebtn{
// display: inline-block;
// }
// }
// }
.headerOperate {
position: relative;
span{
font-size: 18px;
}
flex: 2%;
display: flex;
align-items:center;
min-height: 40px;
box-sizing: border-box;
margin: 3px 0;
.bigeditdeletebtn{
margin-right: 12px;
height: 80%;
display: flex;
flex-direction: column;
// align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
justify-content: center;
user-select: none;
background-image: url("../../../assets/images/标签正常.png") ;
background-size:100% 100%;
color: white;
span{
padding: 0 13px;
padding-right: 18px;
}
}
.bigeditdeletebtn:hover{
cursor: pointer;
background-image: url("../../../assets/images/标签经过.png") ;
}
.bigTalkBox{
user-select: none;
.titleIcon{
font-size: 33px;
vertical-align: sub;
color: white;
}
.talkBox{
width: 309px;
height: 326px;
border: 1px solid #30bbec;
background-color: #013a64;
opacity: .9 ;
position: absolute;
top: 32px;
right:4px;
z-index: 2000;
.btndiv{
div{
border-radius: 18px;
width: 70px;
height: 30px;
text-align: center;
line-height: 30px;
display: inline-block;
font-size: 13px;
color: white;
cursor: pointer;
}
div:nth-child(1){
background-color: #fe9400;
margin: 10px;
}
div:nth-child(2){
background-color: #f95e5a;
}
}
.bottomDiv{
position: absolute;
bottom:6px;
width: 100%;
height: 32px;
line-height: 32px;
display: flex;
color: white;
text-align: center;
div:nth-child(1){
flex: 1;
}
div:nth-child(2){
flex: 6;
color: #409eff;
background: url('../../../assets/images/输入框.png');
background-size: 100% 100%;
}
div:nth-child(3){
flex: 1;
}
}
}
}
}
//功能区
// icon统一样式
.mat-icon {
cursor:pointer;
vertical-align: middle;
}
//左右两侧功能栏 统一样式
.publicCss {
overflow: hidden;
border-radius: 5px;
top: 0;
}
.functionalDomain {
flex: 98%;
overflow: hidden;
.functionalDomainContent {
display: flex;
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.functionalDomainLeft {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 0px;
transition: margin-left 0.5s;
border: 1px solid #30bbec;
left: 0;
z-index: 111;
.leftDragDiv{
position: absolute;
right: 0;
height: 100%;
width: 3px;
z-index: 1000;
cursor: e-resize;
}
}
.canvas{
flex: 5;
.closebottombtn{
width: 30px;
vertical-align: sub;
}
.openbottombtn{
width: 30px;
color: white;
text-align: center;
height: 30px;
line-height: 30px;
vertical-align: sub;
position: absolute;
left: 5px;
bottom: 5px;
background-color:rgba(2, 44, 73, 0.9);
}
//打开时
.openBottom{
margin-bottom: 0;
transition: margin-bottom 1s;
}
//关闭
.closeBottom{
margin-bottom: -300px!important;
transition: margin-bottom 1s;
}
//右侧 楼层UI
.rightStorey {
width: 100px;
height: 250px;
position: absolute;
left: 0;
top: 50%;
margin-top: -200px;
z-index: 9999;
display: flex;
flex-direction: column;
background-color:rgba(2, 44, 73, 0.9);
color: #fff;
font-weight: 300;
>div {text-align: center; line-height: 25px;}
}
.showRightStorey {
position: absolute;
right: 0;
top: 50%;
margin-top: -13px;
z-index: 9999;
width: 26px;
height: 26px;
line-height: 26px;
text-align: center;
background-color:rgba(2, 44, 73, 0.9);
color: #fff;
}
//打开关闭右侧 楼层
.openRight {
margin-right: 0px;
transition: margin-right 0.5s;
}
.closeRight {
margin-right: -300px;
transition: margin-right 0.5s;
}
.canvasbottomCss{
margin-bottom: 0;
transition: margin-bottom 0.5s;
position: absolute;
bottom: 0;
width: 100%;
height: 200px;
display: flex;
flex-direction: column;
.title{
border-bottom: 1px solid #30bbec;
flex: 1;
div{
cursor: pointer;
background-color: rgba(2, 44, 73, 0.9);
width: 120px;
height: 30px;
line-height: 35px;
text-align: center;
margin-right: 10px;
color: white;
font-style: italic;
font-size:18px;
}
.closebottombtn{
width: 30px;
vertical-align: sub;
}
.detailsAndattentBtn{
background-color: #ed863b;
}
}
.body{
flex: 10;
background-color:rgba(2, 44, 73, 0.9);
div{
color: #d0e0f4;
font-size: 16px;
letter-spacing:5px;
margin: 5px 0 0 8px;
}
}
}
}
.functionalDomainRight {
color: white;
// background-color: #113e5e;
z-index: 1001;
margin-right: 0px;
transition: margin-right 0.5s;
border: 1px solid #30bbec;
width: 235px;
right: 0;
flex: 1;
}
//右边导航栏显示隐藏
.togglePanel2 {
margin-right: -2000px;
transition: margin-right 1s;
}
//左侧导航栏显示隐藏
.togglePanel {
margin-left: -2000px;
transition: margin-left 1s;
}
}
//右边操作栏
.title{
width: 100%;
height: 40px;
line-height: 40px;
border-bottom:2px solid #accbf2;
display: flex;
align-content: center;
span{
display: inline-block;
flex: 1;
text-align: center;
}
span:hover{
cursor: pointer;
}
}
.selectedTitle{
background: #0c2d44;
}
//右侧属性
.property{
display: flex;
flex-flow: column;
.siteproperty{
height: 100%;
overflow-y: auto;
p{
color: #d0e0f4;
padding-left: 7px;
letter-spacing:3px;
margin: 5px 0;
}
.siteproperty_size{
border-bottom:1px solid #d0e0f4;
width: 93%;
margin: 0 auto;
min-height: 21px;
color: #2399f1;
padding-bottom: 5px;
font-size: 16px;
letter-spacing:2px;
}
.rightAttribute{
width: 12%;
height: 99.5%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
border: 2px solid #464646;
}
}
.assetsproperty{
overflow-y: auto;
height: 100%;
p{
color: #d0e0f4;
padding-left: 7px;
letter-spacing:3px;
margin: 5px 0;
}
.siteproperty_size{
border-bottom:1px solid #d0e0f4;
width: 93%;
margin: 0 auto;
min-height: 21px;
color: #2399f1;
padding-bottom: 5px;
font-size: 16px;
letter-spacing:2px;
}
span{
font-size: 15px;
}
input{
height: 18px;
}
.biginput{
display: block;
width: 88%;
margin: 0 auto;
}
.smallinput{
display: block;
width: 19%;
margin-left: 8px;
}
.textarea{
display: block;
width: 88%;
height: 50px;
margin: 0 auto;
}
.swiper-button-next{
right: 6px;
}
.swiper-button-prev{
left: 6px;
}
.swiper-container{
// --swiper-theme-color: #ff6600;/* 设置Swiper风格 */
// --swiper-navigation-color: #00ff33;/* 单独设置按钮颜色 */
--swiper-navigation-size:20px;/* 设置按钮大小 */
}
.hoverred:hover{
color: rgb(187, 28, 28);
}
.selectDiv{
height: 21px;
position: relative;
margin-bottom: 5px;
select{
width: 98px;
height: 22px;
vertical-align: middle;
position: absolute;
right: 10px;
top: 1px;
border: 1px solid rgb(208, 211, 214);
border-radius: 2px;
}
}
.colorBigDiv{
width: 88%;
margin-left: 8px;
.colorDiv{
.colorLi{
width: 24px;
height: 24px;
list-style: none;
float: left;
border: 2px solid white;
}
.coloractive{
border: 2px solid black;
}
}
}
.colorBigTemplateDiv{
span{
color: #9c9fa5;
font-size: 14px;
height: 26px;
line-height: 26px;
}
.colorTemplateDiv{
width: 65%;
height: 22px;
display: inline-block;
vertical-align: middle;
margin-left: 26px;
}
}
}
}
//右侧消防要素
.firecategories{
position: relative;
// display: flex;
// flex-flow: column;
.firecategoriesTree{
overflow-y: auto;
height: 100%;
mat-tree-node{
position: relative;
}
.isLookCss{
position: absolute;
right: 6px;
z-index: 1000;
}
}
.mat-tree{
background-color:transparent;
.mat-tree-node{
color: white!important;
}
}
}
// 解决轮播图蓝框问题
div:focus {
outline: none;
}
//没有图片时显示无图片背景图
.noImgCss{
background: url(../../../assets/images/noImg.png) ;
background-size: 100% 100%;/*按比例缩放*/
}
.input{
width: 18px;
height: 18px;
vertical-align: middle;
margin-left: 9px;
margin-right: 3px;
}
// tree
.mat-tree-node{
min-height: 0;
height: 32px;
line-height: 32px;
font-size: 13px;
cursor: pointer;
}
.treeNode:hover{
background-color: #ccebf8;
}
.isLookPattern{
display: none;
}
.treeText{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
width: 65px;
}
.bigBox{
width: 700px;
height: 40px;
position: absolute;
overflow: hidden;
right: 0;
}
.weatherBox{
height: 40px;
width: 700px;
line-height: 40px;
position: absolute;
right: 0;
transition: right linear .5s;
.openbtn{
font-size: 45px;
height: 45px;
width: 40px;
}
.name{
font-size: 16px;
vertical-align: middle;
margin-left: 3px;
}
input{
width: 140px;
height: 22px;
margin-left: 3px;
}
select{
width: 96px;
height: 25px;
margin-left: 3px;
vertical-align: middle;
}
}
.open{
right: 0px;
}
.close{
right:-622px;
}
.bottomCss{
position: absolute;
left: 232px;
right: 0px;
bottom: 0;
height: 158px;
width: auto;
z-index: 100;
background-color: white;
border: 1px solid #464646;
.dragDiv{
width: 100%;
height: 3px;
position: absolute;
top: 0;
z-index: 1000;
cursor: n-resize;
}
.title{
height: 35px;
background-color: #464646;
div{
background-color: #464646;
float: left;
width: 80px;
color: white;
font-size: 13px;
padding-left: 5px;
cursor: pointer;
}
.detailsAndattentBtn{
background-color: #595959;
}
}
.body{
textarea{
width: 100%;
border-radius: 0px;
}
}
}

25
src/app/ui/collection-tools/collection-tools.component.spec.ts

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CollectionToolsComponent } from './collection-tools.component';
describe('CollectionToolsComponent', () => {
let component: CollectionToolsComponent;
let fixture: ComponentFixture<CollectionToolsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CollectionToolsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CollectionToolsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save