Browse Source

[新增]第一次提交文件

master
邵佳豪 4 years ago
commit
b67883347c
  1. 13
      .editorconfig
  2. 46
      .gitignore
  3. 15
      .vscode/launch.json
  4. 9
      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. 18466
      package-lock.json
  13. 68
      package.json
  14. 7
      proxy.config.json
  15. 27
      reset.css
  16. 5098
      src/app/_theming.scss
  17. 46
      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. 732
      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. 14
      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. 40
      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. 78
      src/app/key-unit/allaround/allaround.component.html
  41. 54
      src/app/key-unit/allaround/allaround.component.scss
  42. 25
      src/app/key-unit/allaround/allaround.component.spec.ts
  43. 78
      src/app/key-unit/allaround/allaround.component.ts
  44. 18
      src/app/key-unit/allaround/imgdetails.component.html
  45. 54
      src/app/key-unit/allaround/imgdetails.component.ts
  46. 511
      src/app/key-unit/basicinfo-look/basicinfo.component.html
  47. 264
      src/app/key-unit/basicinfo-look/basicinfo.component.scss
  48. 1974
      src/app/key-unit/basicinfo-look/basicinfo.component.ts
  49. 17
      src/app/key-unit/basicinfo-look/lookmaster.component.html
  50. 66
      src/app/key-unit/basicinfo-look/lookmaster.component.ts
  51. 25
      src/app/key-unit/basicinfo/addhouseinfo.component.html
  52. 77
      src/app/key-unit/basicinfo/addhouseinfo.component.ts
  53. 531
      src/app/key-unit/basicinfo/basicinfo.component.html
  54. 269
      src/app/key-unit/basicinfo/basicinfo.component.scss
  55. 25
      src/app/key-unit/basicinfo/basicinfo.component.spec.ts
  56. 2032
      src/app/key-unit/basicinfo/basicinfo.component.ts
  57. 26
      src/app/key-unit/basicinfo/lookmaster.component.html
  58. 66
      src/app/key-unit/basicinfo/lookmaster.component.ts
  59. 56
      src/app/key-unit/edit-plan-info/edit-plan-info.component.html
  60. 3
      src/app/key-unit/edit-plan-info/edit-plan-info.component.scss
  61. 25
      src/app/key-unit/edit-plan-info/edit-plan-info.component.spec.ts
  62. 15
      src/app/key-unit/edit-plan-info/edit-plan-info.component.ts
  63. 60
      src/app/key-unit/edit-unit-info/edit-unit-info.component.html
  64. 3
      src/app/key-unit/edit-unit-info/edit-unit-info.component.scss
  65. 25
      src/app/key-unit/edit-unit-info/edit-unit-info.component.spec.ts
  66. 23
      src/app/key-unit/edit-unit-info/edit-unit-info.component.ts
  67. 69
      src/app/key-unit/fire-fighting-device-look/addGrouping.component.ts
  68. 18
      src/app/key-unit/fire-fighting-device-look/addGrouping.html
  69. 193
      src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.html
  70. 145
      src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.scss
  71. 538
      src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.ts
  72. 9
      src/app/key-unit/fire-fighting-device-look/imagesdata.component.html
  73. 82
      src/app/key-unit/fire-fighting-device-look/imagesdata.component.ts
  74. 17
      src/app/key-unit/fire-fighting-device-look/previewImg.html
  75. 69
      src/app/key-unit/fire-fighting-device/addGrouping.component.ts
  76. 18
      src/app/key-unit/fire-fighting-device/addGrouping.html
  77. 193
      src/app/key-unit/fire-fighting-device/fire-fighting-device.component.html
  78. 145
      src/app/key-unit/fire-fighting-device/fire-fighting-device.component.scss
  79. 538
      src/app/key-unit/fire-fighting-device/fire-fighting-device.component.ts
  80. 9
      src/app/key-unit/fire-fighting-device/imagesdata.component.html
  81. 82
      src/app/key-unit/fire-fighting-device/imagesdata.component.ts
  82. 17
      src/app/key-unit/fire-fighting-device/previewImg.html
  83. 23
      src/app/key-unit/function-division-look/addPartition.html
  84. 0
      src/app/key-unit/function-division-look/addPartitionAttribute.html
  85. 106
      src/app/key-unit/function-division-look/function-division.component.html
  86. 32
      src/app/key-unit/function-division-look/function-division.component.scss
  87. 247
      src/app/key-unit/function-division-look/function-division.component.ts
  88. 23
      src/app/key-unit/function-division/addPartition.html
  89. 0
      src/app/key-unit/function-division/addPartitionAttribute.html
  90. 106
      src/app/key-unit/function-division/function-division.component.html
  91. 32
      src/app/key-unit/function-division/function-division.component.scss
  92. 25
      src/app/key-unit/function-division/function-division.component.spec.ts
  93. 293
      src/app/key-unit/function-division/function-division.component.ts
  94. 120
      src/app/key-unit/key-site-look/key-site.component.html
  95. 58
      src/app/key-unit/key-site-look/key-site.component.scss
  96. 173
      src/app/key-unit/key-site-look/key-site.component.ts
  97. 0
      src/app/key-unit/key-site-look/keyimgdetail.component.html
  98. 17
      src/app/key-unit/key-site-look/keyimgdetail.component.ts
  99. 18
      src/app/key-unit/key-site-look/keysiteimgs.component.html
  100. 55
      src/app/key-unit/key-site-look/keysiteimgs.component.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 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: 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}"
}
]
}

9
README.md

@ -0,0 +1,9 @@
pad端六熟悉记录前端项目。此项目在 Angular 框架基础上编写。
后续开发都基于此。
项目初始化: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
});
};

18466
package-lock.json generated

File diff suppressed because it is too large Load Diff

68
package.json

@ -0,0 +1,68 @@
{
"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",
"ng-zorro-antd": "^9.3.0",
"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

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

@ -0,0 +1,46 @@
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秘钥
const routes: Routes = [
{path:'',redirectTo:'login',pathMatch:'full'},
{
path:'',
component:NavigationComponent,
canActivate: [AuthGuard],//守卫验证
children:[
{path:'ui',loadChildren:() => import('./ui/ui.module').then(m => m.UiModule)},
{path:'keyUnit',loadChildren:() => import('./key-unit/key-unit.module').then(m => m.KeyUnitModule)},
{path:'planManagement',loadChildren:() => import('./plan-management/plan-management.module').then(m => m.PlanManagementModule)},
{path:'planAudit',loadChildren:() => import('./plan-audit/plan-audit.module').then(m => m.PlanAuditModule)},
{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:'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;
}
}

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

@ -0,0 +1,732 @@
import { Injectable } from '@angular/core';
import {ReplaySubject} from 'rxjs';
import { Observable } from 'rxjs';
import { GameMode } from './working-area/model/gameMode';
@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: DisposalNodeData = new DisposalNodeData();
selectPanelPointBaseData: any = {description: '', notes: '', weather: '', airTemperature: '', windDirection: '', windScale: ''}; // 当前 数据节点 所对应的 天气,详情 数据节点
// 处置 节点
/**
*
*/
gameMode: GameMode = GameMode.BasicInformation;
facilityAssetsName = new Map<string, string>([
[ '消防水池', '消防水池'],
[ '疏散楼梯', '疏散楼梯'],
[ '消防电梯', '消防电梯'],
[ '避难区域', '避难区域'],
[ '安全出口', '安全出口'],
[ '地上消火栓', '室外消火栓' ],
[ '地下消火栓', '室外消火栓' ],
[ '室内消火栓', '室内消火栓' ],
[ '供水管网', '供水管网'],
[ '湿式自动喷淋系统', '湿式自动喷淋系统'],
[ '水幕系统', '水幕系统' ],
[ '消防泵房', '消防泵房'],
[ '水泵接合器(地上)', '水泵接合器'],
[ '水泵接合器(地下)', '水泵接合器'],
[ '水泵接合器(墙壁)', '水泵接合器'],
[ '消防水泵房', '消防水泵房'],
[ '箱式消火栓', '箱式消火栓'],
[ '固定水炮', '消防水炮' ],
[ '消防水罐', '储水罐'],
[ '消防水罐2', '储水罐'],
[ '卧式水罐', '储水罐'],
[ '消防泵', '水泵' ],
[ '泡沫泵', '水泵' ],
[ '泡沫泵房', '泡沫站'],
[ '泡沫栓', '泡沫栓' ],
[ '泡沫枪', '泡沫枪'],
[ '泡沫发生器', '泡沫发生器' ],
[ '消防管网', '消防管网'],
[ 'DCS控制室', 'DCS控制室']
]);
/** * *
* @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;
}
/**
*
* @param json
*/
public deserialize<T>(json: any): T {
const obj: T = JSON.parse(
json,
(_, val) => {
if (val === null) { return null; }
if (Array.isArray(val) || typeof val !== 'object') {
return val;
}
return Object.entries(val).reduce((a, [key, val]) => {
const count = key.length;
if (count > 1) {
a[key[0].toUpperCase() + key.substring(1, count)] = val;
} else {
a[key] = val;
}
return a;
}, {});
}
);
return obj;
}
}
/**
*
*/
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: any;
/**
*
*/
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 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)
}
}

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

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { GisLabelingComponent } from './gis-labeling/gis-labeling.component';
const routes: Routes = [
{ path: '', component: GisLabelingComponent },
];
@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(['/login'])
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);
};
}

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

@ -0,0 +1,40 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
@Injectable({
providedIn: 'root'
})
export class CacheTokenService {
constructor(private http:HttpClient) { }
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",
"中队"
}

78
src/app/key-unit/allaround/allaround.component.html

@ -0,0 +1,78 @@
<div class="content">
<mat-tab-group style="height: 100%;">
<mat-tab label="单位毗邻">
<div class="allImgs">
<div class="imgBox" *ngFor="let item of AllAdjoining" >
<div class="fixedImg" *ngIf="item.imageUrls.length">
<img [src]="item.imgURL" onerror="javascript:this.src='../../../assets/images/upload.png'" (click)='imgdetails(item.imageUrls)'>
</div>
<div class="fixedImg" *ngIf="!item.imageUrls.length">
<img src="../../../assets/images/upload.png" (click)='imgdetails(item.imageUrls)'>
</div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">建筑物名称:</label>
<label style="margin-left: 25px;">{{item.name}}</label>
</div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">建筑物方向:</label>
<label style="margin-left: 25px;">
<label *ngIf="item.direction==0"></label>
<label *ngIf="item.direction==1">西</label>
<label *ngIf="item.direction==2"></label>
<label *ngIf="item.direction==3"></label>
<label *ngIf="item.direction==4">东南</label>
<label *ngIf="item.direction==5">西南</label>
<label *ngIf="item.direction==6">东北</label>
<label *ngIf="item.direction==7">西北</label>
</label>
</div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">图片数量:</label>
<label style="margin-left: 25px;" *ngIf="item.imageUrls.length">{{item.imageUrls.length}}张</label>
<label style="margin-left: 25px;" *ngIf="!item.imageUrls.length">0张</label>
</div>
</div>
<p style="width: 100%;text-align: center;margin-top: 25px;" *ngIf="!AllAdjoining.length">暂无数据,请前往平面图进行相关数据录入</p>
</div>
</mat-tab>
<mat-tab label="{{item.name}}" *ngFor="let item of AllBuilding">
<div class="allImgs">
<div class="imgBox" *ngFor="let items of item.allImgs">
<div class="fixedImg" *ngIf="items.imageUrls.length">
<img [src]="items.imgURL" onerror="javascript:this.src='../../../assets/images/upload.png'" (click)='imgdetails(items.imageUrls)'>
</div>
<div class="fixedImg" *ngIf="!items.imageUrls.length"><img src="../../../assets/images/upload.png" (click)='imgdetails(items.imageUrls)'></div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">建筑物名称:</label>
<label style="margin-left: 25px;">{{items.name}}</label>
</div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">建筑物方向:</label>
<label style="margin-left: 25px;">
<label *ngIf="items.direction==0"></label>
<label *ngIf="items.direction==1">西</label>
<label *ngIf="items.direction==2"></label>
<label *ngIf="items.direction==3"></label>
<label *ngIf="items.direction==4">东南</label>
<label *ngIf="items.direction==5">西南</label>
<label *ngIf="items.direction==6">东北</label>
<label *ngIf="items.direction==7">西北</label>
</label>
</div>
<div style="margin-top: 5px;">
<label style="margin-left: 25px;">图片数量:</label>
<label style="margin-left: 25px;" *ngIf="items.imageUrls.length">{{items.imageUrls.length}}张</label>
<label style="margin-left: 25px;" *ngIf="!items.imageUrls.length">0张</label>
</div>
</div>
<p style="width: 100%;text-align: center;margin-top: 25px;" *ngIf="!item.allImgs.length">暂无数据,请前往平面图进行相关数据录入</p>
</div>
</mat-tab>
</mat-tab-group>
</div>

54
src/app/key-unit/allaround/allaround.component.scss

@ -0,0 +1,54 @@
.content {
width: 100%;
height: 90%;
padding: 10px;
overflow-y: auto;
}
//图片外部div
.allImgs {
display: flex;
overflow-y: auto;
flex-direction: row;
flex-wrap: wrap;
.imgBox{
width: 300px;
height: 250px;
margin: 25px 35px 35px 35px;
display: inline-block;
position: relative;
.fixedImg {
width: 100%;
height: 170px;
text-align: center;
margin-bottom: 3px;
img {
width: auto;
height: auto;
max-width: 100%;
height: 100%;
cursor:pointer;}
}
}
}
//预览图片
.previewImgBox {
width: 1500px;
height: 700px;
text-align: center;
img{
width: auto;
height: auto;
max-width: 100%;
height: 100%;}
}
.previewImgBottom {
text-align: center;
height: 30px;
margin: 20px auto;
}
//预览图片旋转角度
.rotateA {transform: rotate(90deg) scale(0.75);}
.rotateB {transform: rotate(180deg)}
.rotateC {transform: rotate(270deg) scale(0.75);}

25
src/app/key-unit/allaround/allaround.component.spec.ts

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

78
src/app/key-unit/allaround/allaround.component.ts

@ -0,0 +1,78 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { ImgDetails } from './imgdetails.component'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-allaround',
templateUrl: './allaround.component.html',
styleUrls: ['./allaround.component.scss']
})
export class AllaroundComponent implements OnInit {
constructor(private http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar,private route:ActivatedRoute,) { }
ngOnInit(): void {
this.getAllCompany()
this.getAllBuilding()
}
AllAdjoining:any = []; //所有单位毗邻
AllBuilding:any = []; //所有建筑 + 建筑毗邻图片
//获取所有单位毗邻图片
getAllCompany () {
let id = {companyId:this.route.snapshot.queryParams.id}
this.http.get('/api/CompanyAdjoins',{params:id}).subscribe(data=>{
this.AllAdjoining = data
this.AllAdjoining.forEach(element => {element.imgURL = element.imageUrls[0] +'?x-oss-process=image/resize,m_fill,h_170,w_299'})
})
}
//获取所有建筑
getAllBuilding () {
let id = {companyId:this.route.snapshot.queryParams.id}
this.http.get('/api/Buildings',{params:id}).subscribe((data:any)=>{
if (data.length) {
this.AllBuilding = data
this.AllBuilding.forEach(element => {
element.allImgs = []
});
this.getAllArchitecture()}
})
}
//获取所有建筑毗邻图片
getAllArchitecture () {
this.AllBuilding.forEach(element => {
let id = {buildingId:element.id}
this.http.get('/api/BuildingAdjoins',{params:id}).subscribe(data=>{
element.allImgs = data
element.allImgs.forEach(element => {element.imgURL = element.imageUrls[0] +'?x-oss-process=image/resize,m_fill,h_170,w_299'});
})
});
}
//预览图片
imgdetails(e){
if (e.length && e!=null) {
let data = e
const dialogRef = this.dialog.open(ImgDetails, {//调用open方法打开对话框并且携带参数过去
width: '1600px',
height:'900px',data});
dialogRef.afterClosed().subscribe();
} else{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
}
}

18
src/app/key-unit/allaround/imgdetails.component.html

@ -0,0 +1,18 @@
<div mat-dialog-title>图片详情</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div *ngFor="let item of allImages" class="swiper-slide previewImgBox">
<img [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270}" class="swiper-lazy"
[attr.data-src]="item">
<div class="swiper-lazy-preloader"></div>
</div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
</div>

54
src/app/key-unit/allaround/imgdetails.component.ts

@ -0,0 +1,54 @@
import { Component, OnInit, Inject, ɵConsole } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import Swiper from 'swiper';
@Component({
selector: 'imgdetails',
templateUrl: './imgdetails.component.html',
styleUrls: ['./allaround.component.scss']
})
export class ImgDetails {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<ImgDetails>,
@Inject(MAT_DIALOG_DATA) public data) { }
testSwiper: Swiper;
ngOnInit(): void {
this.allImages = []
this.data.forEach(element => {
element = `${element}?x-oss-process=image/auto-orient,1`
this.allImages.push(element)
});
}
ngAfterViewInit() {
this.testSwiper = new Swiper('.swiper-container', {
lazy: true,
direction: 'horizontal',
loop: false,
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
}
allImages:any; //展示所有的图片
rotationAngle:number=0; //旋转角度
//旋转图片
rotate () {
this.rotationAngle = this.rotationAngle+90
if (this.rotationAngle === 360) {this.rotationAngle = 0}
}
}

511
src/app/key-unit/basicinfo-look/basicinfo.component.html

@ -0,0 +1,511 @@
<div style="height: 100%;display: flex; flex-direction: column;">
<!-- header -->
<mat-accordion>
<mat-expansion-panel expanded hideToggle>
<mat-expansion-panel-header style="color: black;">
<mat-panel-title>
单位信息
<mat-icon style="position: absolute;right:30px;">keyboard_arrow_down</mat-icon>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="topbox">
<form (ngSubmit)="onSubmit(form.value,form.invalid,form)" #form="ngForm" class="example-container">
<div class="mainbox" >
<div class="mainleft">
<div class="inputbox" >
<span style="color: red;">*</span>
<span>统一社会信用代码:</span>
<mat-form-field>
<input readonly matInput id="creditcode" name="creditcode" type='text' #usci="ngModel"
required minlength="1" maxlength="18"
[(ngModel)]="unitinfo.usci"
(focus)="closeorganizationbox()"
pattern="^[0-9A-HJ-NP-RTUW-Y]{2}\d{6}[0-9A-HJ-NP-RTUW-Y]{10}$">
</mat-form-field>
<div *ngIf="usci.invalid && (usci.dirty || usci.touched)" class="alert-danger">
<div *ngIf="usci.errors.pattern" class="alert-danger">
统一社会信用代码格式不正确
</div>
</div>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>单位类型:</span>
<mat-form-field>
<mat-select disabled readonly required name="unittype" [(ngModel)]="defaultbuildingTypes">
<mat-option [value]="item.id" *ngFor="let item of allunittype">{{item.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>联系人:</span>
<mat-form-field>
<input readonly matInput id="linkman" name="linkman" type='text'
required minlength="1"
[(ngModel)]="unitinfo.contacts"
(focus)="closeorganizationbox()"
>
</mat-form-field>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>联系电话:</span>
<mat-form-field>
<input readonly matInput id="linkphone" name="linkphone" type='text' #linkphone="ngModel"
required pattern="^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[35-8]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0135-9]\d{2}|66\d{2})\d{6}$"
[(ngModel)]="unitinfo.phone"
(focus)="closeorganizationbox()"
>
</mat-form-field>
<div *ngIf="linkphone.invalid && (linkphone.dirty || linkphone.touched)" class="alert-danger">
<div *ngIf="linkphone.errors.pattern" class="alert-danger">
电话号码格式不正确
</div>
</div>
</div>
<div class="inputbox" style="width: 700px;">
<span style="color: red;">*</span>
<span>辖区中队:</span>
<mat-form-field style="width: 538px;">
<input readonly matInput id="organization" name="organization" type='text'
required minlength="1"
[(ngModel)]="selectedorganization"
readonly="value" >
</mat-form-field>
</div>
<div class="inputbox" style="width: 700px;">
<span style="color: red;">*</span>
<span>单位地址:</span>
<mat-form-field style="width: 538px;">
<input readonly matInput id="unitaddress" name="unitaddress" type='text'
required minlength="1"
[(ngModel)]="unitinfo.address"
(focus)="closeorganizationbox()">
</mat-form-field>
</div>
<div class="uploadimg" (click)="lookmaster()">
<span>单位照片:</span>
<div class="uploadingimg">
<img [src]="imgsrc" alt="" style="width: 299px; height: 170px;" >
</div>
<mat-spinner *ngIf="isspinner" diameter= 50></mat-spinner>
</div>
<!-- <div class="image">
<input id="selectedfile" type="file" name="imgFile" accept=".jpg,.png,.jpeg,.gif,.webp">
</div> -->
<!-- <div class="addbtn">
<button type="submit" color="primary" class="submit1" mat-button mat-raised-button>保存</button>
</div> -->
</div>
<!-- <div class="mainright" (click)="closeorganizationbox()"> -->
<!-- 地图预留位置 -->
<!-- </div> -->
</div>
</form>
</div>
</mat-expansion-panel>
</mat-accordion>
<!-- body -->
<div class="bottombox" style="flex: 70%;overflow-y: auto;" >
<div class="houseinfobox" style="height: 100%; overflow-y: auto;padding-bottom: 64px; box-sizing:border-box">
<!-- <button type="button" mat-icon-button class="addhouseinfo"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button> -->
<mat-tab-group style="height: 100%;;" >
<mat-tab [label]="item.username" *ngFor="let item of houses;let key = index">
<form style="height: 100%; overflow-y:auto; display: block;" (ngSubmit)="onSubmit2(form.value,item,key,form.invalid)" #form="ngForm" class="example-container">
<!-- 正常建筑 -->
<div class="highinfo" *ngIf="item.tongyong">
<div class="houseinfoinput" >
<span>建筑名称:</span>
<mat-form-field>
<input readonly matInput id="housename" name="housename" type='text'
minlength="1" [(ngModel)]="item.name"
>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div class="houseinfoinput">
<span>建筑类型:</span>
<mat-form-field>
<mat-select disabled readonly name="unittype" [(ngModel)]="item.buildtype">
<mat-option [value]="n.name" *ngFor="let n of allunittype">{{n.name}}</mat-option>
</mat-select>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div *ngFor="let item of item.buildingBasicGroups;let www = index" style="float: left;">
<h1 style="font-size: 22px;">{{item.name}}</h1>
<div class="houseinfoinput" *ngFor="let i of item.propertyInfos" style="float: left;margin-left: 250px;position: relative;">
<span>{{i.propertyName}}<span *ngIf="i.physicalUnit">({{i.physicalUnit}})</span></span>
<!-- 如果类型是文本 -->
<mat-form-field *ngIf="i.propertyType == 0">
<input readonly matInput name="{{i.propertyName}}{{www}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue">
</mat-form-field>
<!-- 如果类型是数字 -->
<mat-form-field *ngIf="i.propertyType == 2">
<input readonly matInput name="{{i.propertyName}}{{www}}" type='number'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
>
<!-- <mat-error *ngIf="isshowrule">{{rulevalue}}</mat-error> -->
</mat-form-field>
<!-- 如果类型是多行文本 -->
<textarea readonly *ngIf="i.propertyType == 1" style="width: 180px;height: 60px;" required="{{ i.required==true ? 'true' : 'false' }}" [(ngModel)]="i.propertyValue" name="{{i.propertyName}}{{key}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
<div *ngIf="i.isshowrule" style="position: absolute;
left: 205px;
top: 45px;
font-size: 11px;
color: red;">
<span>{{i.rulevalue}}</span>
</div>
</div>
</div>
<div class="CustomData" style="width: 200px;">
<!-- <mat-checkbox name="checkbuilding" [(ngModel)]="item.isCustomData" style="float: left;margin-right: 10px;"></mat-checkbox> -->
<h1 style="font-size: 22px;width: 200px;">自定义信息</h1>
</div>
<div *ngIf="item.isCustomData" style="position: relative;">
<!-- <button style="position: absolute;left: 0;" type="button" mat-icon-button class="addCustomData"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button>
<button style="position: absolute;left:60px;" type="button" mat-icon-button class="deleteCustomData"><mat-icon style="font-size: 38px;">remove_circle_outline</mat-icon></button> -->
<div class="houseinfoinput" style="float: left;margin-left: 250px;" *ngFor="let i of item.buildingCustomData.customProperties;let key = index">
<mat-form-field>
<input readonly matInput type='text' name="{{key}}1CustomData"
required
[(ngModel)]="i.name">
</mat-form-field>
<span>:</span>
<mat-form-field>
<input readonly matInput type='text' name="{{key}}2CustomData"
required
[(ngModel)]="i.value">
</mat-form-field>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
</div>
<!-- 石油化工 -->
<div class="highinfo" *ngIf="item.isshiyou;let bigkey = index">
<div class="basicinfobox">
<div class="houseinfoinput">
<span>建筑名称:</span>
<mat-form-field>
<input readonly matInput id="housename" name="housename" type='text'
required minlength="1" [(ngModel)]="item.name"
>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div class="houseinfoinput" >
<span>建筑类型:</span>
<mat-form-field>
<mat-select disabled required name="unittype" [(ngModel)]="item.buildtype">
<mat-option [value]="n.name" *ngFor="let n of allunittype">{{n.name}}</mat-option>
</mat-select>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<h1 style="font-size: 22px;">{{item.buildingBasicGroups[0].name}}</h1>
<div class="houseinfoinput" *ngFor="let i of item.buildingBasicGroups[0].propertyInfos;let smkey = index" style="float: left;margin-left: 250px;position: relative;">
<span>{{i.propertyName}} <span *ngIf="i.physicalUnit">({{i.physicalUnit}})</span></span>
<!-- 如果类型是文本 -->
<mat-form-field *ngIf="i.propertyType == 0">
<input readonly matInput name="{{i.propertyName}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue">
</mat-form-field>
<!-- 如果类型是数字 -->
<mat-form-field *ngIf="i.propertyType == 2">
<input readonly matInput name="{{i.propertyName}}" type='number'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
>
<!-- <mat-error *ngIf="isshowrule">{{rulevalue}}</mat-error> -->
</mat-form-field>
<!-- 如果类型是多行文本 -->
<textarea readonly *ngIf="i.propertyType == 1" style="width: 180px;height: 60px;" required="{{ i.required==true ? 'true' : 'false' }}" [(ngModel)]="i.propertyValue" name="{{i.propertyName}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
<div *ngIf="i.isshowrule" style=" position: absolute;
left: 205px;
top: 45px;
font-size: 11px;
color: red;">
<span>{{i.rulevalue}}</span>
</div>
</div>
</div>
<div class="deviceinfo">
<div style="width: 200px;">
<!-- <mat-checkbox name="item.buildingBasicGroups[1].name" *ngIf="item.buildingBasicGroups[1].isOptional" [(ngModel)]="item.buildingBasicGroups[1].submitted" style="float: left;margin-right: 10px;"></mat-checkbox> -->
<h1 style="font-size: 22px;width: 200px;">{{item.buildingBasicGroups[1].name}}</h1>
</div>
<table mat-table [dataSource]="devicedataSourcebox[item.buildingId]" class="mat-elevation-z8" *ngIf="item.buildingBasicGroups[1].submitted">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>
<button style="width: 24px;" type="button" mat-icon-button class="adddeviceinfo2" ><mat-icon>add_circle_outline</mat-icon></button>
<button style="width: 24px;" type="button" mat-icon-button class="removedeviceinfo" ><mat-icon>remove_circle_outline</mat-icon></button>
装置区名称<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea readonly style="width: 100px;" [(ngModel)]="element.name" name="{{key}}1" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="flow">
<th mat-header-cell *matHeaderCellDef>工艺流程<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea readonly [(ngModel)]="element.flow" name="{{key}}2" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="danger">
<th mat-header-cell *matHeaderCellDef>火灾危险性<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea readonly [(ngModel)]="element.danger" name="{{key}}3" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="payattentionto">
<th mat-header-cell *matHeaderCellDef>灭火注意事项</th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea readonly style="width: 100px;" [(ngModel)]="element.payattentionto" name="{{key}}4"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<div style="width: 200px;">
<!-- <mat-checkbox *ngIf="item.buildingBasicGroups[2].isOptional" name="item.buildingBasicGroups[2].name" [(ngModel)]="item.buildingBasicGroups[2].submitted" style="float: left;margin-right: 10px;"></mat-checkbox> -->
<h1 style="font-size: 22px;width: 200px;">储罐信息</h1>
</div>
<!-- <button *ngIf="item.buildingBasicGroups[2].submitted" type="button" mat-raised-button color="primary" style="margin-top: 30px;margin-right: 5px;">添加储罐</button>
<button *ngIf="item.buildingBasicGroups[2].submitted" type="button" mat-raised-button color="warn" style="margin-top: 30px;" matTooltip="会将此建筑处于末尾的储罐移除">移除末尾储罐</button> -->
<div *ngIf="item.buildingBasicGroups[2].submitted" style="margin-top: 30px;">
<div class="tankinfo" *ngFor="let x of item.bigfor;let www = index">
<p style="font-size: 22px; width: 200px;">{{x[0].name}}</p>
<div class="basicinfobox" >
<div class="houseinfoinput" *ngFor="let i of x[0].propertyInfos;let key = index" style="line-height: 65px;">
<span>{{i.propertyName}} {{i.physicalUnit}}:</span>
<mat-form-field *ngIf="i.propertyType == 0">
<input readonly matInput name="{{www+2}}-tanker-{{key}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
>
</mat-form-field>
<textarea readonly style="width: 180px;height: 45px;" *ngIf="i.propertyType == 1" [(ngModel)]="i.propertyValue" name="{{www+2}}-tanker-{{key}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
<p style="font-size: 22px; width: 200px;">{{x[1].name}}</p>
<div class="tankdetailinfo">
<table #table mat-table [dataSource]="x[1].propertyInfos" class="mat-elevation-z8" style="position: relative;">
<ng-container matColumnDef="tank">
<th mat-header-cell *matHeaderCellDef>
<!-- <button type="button" mat-icon-button class="adddeviceinfo" style="position: absolute;left: 0;"><mat-icon>add_circle_outline</mat-icon></button>
<button type="button" mat-icon-button class="removedeviceinfo"><mat-icon>remove_circle_outline</mat-icon></button> -->
罐区 </th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tank}}tank{{key}}" type='text'
[(ngModel)]="element.tank">
</td>
</ng-container>
<ng-container matColumnDef="tankid">
<th mat-header-cell *matHeaderCellDef>罐区编号<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tankid}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankid">
</td>
</ng-container>
<ng-container matColumnDef="tankmedium">
<th mat-header-cell *matHeaderCellDef>储存介质<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tankmedium}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankmedium">
</td>
</ng-container>
<ng-container matColumnDef="tanktype">
<th mat-header-cell *matHeaderCellDef>储罐类型<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tanktype}}tank{{key}}" type='text'
required
[(ngModel)]="element.tanktype">
</td>
</ng-container>
<ng-container matColumnDef="tankcapacity">
<th mat-header-cell *matHeaderCellDef>容量(m³)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tankcapacity}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankcapacity">
</td>
</ng-container>
<ng-container matColumnDef="tankdiameter">
<th mat-header-cell *matHeaderCellDef>直径(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tankdiameter}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankdiameter">
</td>
</ng-container>
<ng-container matColumnDef="tankheight">
<th mat-header-cell *matHeaderCellDef>高度(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tankheight}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankheight">
</td>
</ng-container>
<ng-container matColumnDef="tanktectum">
<th mat-header-cell *matHeaderCellDef>顶盖形式</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tanktectum}}tank{{key}}" type='text'
[(ngModel)]="element.tanktectum">
</td>
</ng-container>
<ng-container matColumnDef="tanktexture">
<th mat-header-cell *matHeaderCellDef>浮盘材质</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.tanktexture}}tank{{key}}" type='text'
[(ngModel)]="element.tanktexture">
</td>
</ng-container>
<ng-container matColumnDef="platetype">
<th mat-header-cell *matHeaderCellDef>浮盘类型</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.platetype}}tank{{key}}" type='text'
[(ngModel)]="element.platetype">
</td>
</ng-container>
<ng-container matColumnDef="foamgeneratorid">
<th mat-header-cell *matHeaderCellDef>泡沫产生器型号</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.foamgeneratorid}}tank{{key}}" type='text'
[(ngModel)]="element.foamgeneratorid">
</td>
</ng-container>
<ng-container matColumnDef="foamgeneratortype">
<th mat-header-cell *matHeaderCellDef>泡沫产生器形式</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.foamgeneratortype}}tank{{key}}" type='text'
[(ngModel)]="element.foamgeneratortype">
</td>
</ng-container>
<ng-container matColumnDef="isprotect">
<th mat-header-cell *matHeaderCellDef>是否设置氮封惰化保护装置</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.isprotect}}tank{{key}}" type='text'
[(ngModel)]="element.isprotect">
</td>
</ng-container>
<ng-container matColumnDef="fendinggroyneheight">
<th mat-header-cell *matHeaderCellDef>防护堤高度(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.fendinggroyneheight}}tank{{key}}" type='text'
required
[(ngModel)]="element.fendinggroyneheight">
</td>
</ng-container>
<ng-container matColumnDef="portnum">
<th mat-header-cell *matHeaderCellDef>半固定泡沫灭火接口数量</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.portnum}}tank{{key}}" type='text'
[(ngModel)]="element.portnum">
</td>
</ng-container>
<ng-container matColumnDef="else">
<th mat-header-cell *matHeaderCellDef>其它设施</th>
<td mat-cell *matCellDef="let element;let key = index">
<input readonly style="height:45px" class="tankinfo" name="{{www}}{{element.else}}tank{{key}}" type='text'
[(ngModel)]="element.else">
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns2"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns2;"></tr>
</table>
</div>
</div>
</div>
<div class="CustomData" style="width: 200px;margin-top: 60px;">
<!-- <mat-checkbox name="checkbuilding" [(ngModel)]="item.isCustomData" style="float: left;margin-right: 10px;"></mat-checkbox> -->
<h1 style="font-size: 22px;width: 200px;">自定义信息</h1>
</div>
<div *ngIf="item.isCustomData" style="position: relative;">
<button style="position: absolute;left: 0;font-size: 11px;" type="button" mat-icon-button class="addCustomData"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button>
<button style="position: absolute;left:60px;" type="button" mat-icon-button class="deleteCustomData"><mat-icon style="font-size: 38px;">remove_circle_outline</mat-icon></button>
<div class="houseinfoinput" style="float: left;margin-left: 250px;" *ngFor="let i of item.buildingCustomData.customProperties;let key = index">
<mat-form-field>
<input readonly matInput type='text' name="{{key}}1CustomData"
required
[(ngModel)]="i.name">
</mat-form-field>
<span>:</span>
<mat-form-field>
<input readonly matInput type='text' name="{{key}}2CustomData"
required
[(ngModel)]="i.value">
</mat-form-field>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
</div>
<!-- <div class="infobtnbox">
<button type="submit()" mat-button mat-raised-button color="primary" >保存</button>
<button type="button" mat-raised-button color="warn">删除</button>
</div> -->
</form>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>

264
src/app/key-unit/basicinfo-look/basicinfo.component.scss

@ -0,0 +1,264 @@
.topbox{
height: 485px;
width: 100%;
// border-bottom: 1px solid black;
.mainbox{
height: 100%;
position: relative;
.mainleft{
width:800px;
height: 100%;
// background-color: yellow;
float: left;
.inputbox{
width: 343px;
height: 58px;
margin:2px 6px;
float: left;
text-align: end;
}
.organizationbox{
width:538px;
height: 200px;
background: white;
position: absolute;
top: 164px;
left:166px;
z-index: 100;
border: 1px solid grey;
overflow: auto;
li{
list-style: none;
}
mat-tree-node{
cursor: pointer;
}
mat-tree-node:hover{
background: rgba(225, 225, 225, 0.8);
}
}
.addbtn{
width: 695px;
position: absolute;
bottom: -495px;
text-align: center;
margin-bottom:20px;
button{
margin: 0 4px;
}
}
.uploadimg{
width: 400px;
height: 200px;
float: left;
margin-top:12px;
position: relative;
margin-left: 80px;
cursor: pointer;
span{
float: left;
}
// img{
// float: left;
// }
.uploadingimg{
width: 299px;
height: 170px;
// background: url('../../../assets/images/upload2.png') no-repeat center center;
position: absolute;
top: 0px;
left: 79px;
border: 1px dashed gray;
border-radius:3px;
}
}
.image{
// position: absolute;
// top: 199px;
// left: 160px;
// width: 299px;
// height: 170px;
input{
// width: 299px;
// height: 170px;
width: 190px;
margin-top: 160px;
cursor: pointer;
}
// opacity:0;
}
}
.mainright{
float: left;
width: 600px;
height: 400px;
// position: absolute;
// right: 170px;
}
}
}
.bottombox{
// height:400px;
width: 100%;
// background-color: skyblue;
.bottomtitle{
height: 60px;
// background-color: orange;
line-height: 60px;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.houseinfobox{
// height:340px;
overflow: auto;
.addhouseinfo{
float: left;
}
.infobtnbox{
margin-left: 800px;
position: absolute;
top: 30px;
right: 75px;
button{
width: 80px;
height: 40px;
margin: 0 12px;
margin-top: 15px;
}
}
.infotitle{
font-size: 28px;
font-weight: 900;
margin-left: 180px;
}
.houseinfoinput{
width: 393px;
text-align: end;
margin-left:240px;
}
}
}
.btn{
width: 100%;
text-align: center;
button{
margin: 0 8px;
}
}
.mat-spinner{
margin-top: 58px;
margin-left: 203px;
}
.mat-table{
width: 100%;
}
table{
width: 1000px;
thead{
tr{
th{
width: 60px;
display: block;
float: left;
}
}
}
tbody{
tr{
td{
width: 60px;
display: block;
float: left;
text-align: center;
}
}
}
}
.deviceinfo{
// border-bottom: 1px solid black;;
padding-bottom: 60px;
}
.tankdetailinfo{
// border-bottom: 1px solid black;;
padding-bottom: 35px;
table{
th{
text-align: center;
}
}
}
.tankinfo{
display: block;
width: 100%;
// height: 45px;
text-align: center;
}
// .adddeviceinfo{
// // position: absolute;
// // left: 0px;
// }
.submit1{
margin-left: -66px !important;
}
textarea {
vertical-align: middle;
border-radius: 5px;
padding: 5px;
width: 600px;
height: 110px;
resize: none;
}
//预览图片旋转角度
.img1{
transform:rotate(90deg) scale(0.55);
height: 100%;
}
.img2{
transform:rotate(180deg);
// height: 100%;
}
.img3{
transform:rotate(270deg) scale(0.55);
// height: 100%;
}
.img4{
transform:rotate(90deg) scale(1.3);
// height: 100%;
}
.img5{
transform:rotate(180deg);
// height: 100%;
}
.img6{
transform:rotate(270deg) scale(1.3);
// height: 100%;
}
.imgbox{
text-align: center;
height: 750px;
img{
max-width: 1500px;
max-height: 740px;
}
}
.previewImgBottom{
text-align: center;
}
.alert-danger {
margin-top: -16px;
text-align: left;
padding-left: 77px;
font-size: 12px;
color: red;
}

1974
src/app/key-unit/basicinfo-look/basicinfo.component.ts

File diff suppressed because it is too large Load Diff

17
src/app/key-unit/basicinfo-look/lookmaster.component.html

@ -0,0 +1,17 @@
<div mat-dialog-title>单位照片</div>
<div>
<div>
<ng-container *ngIf="isshowimg; else elseTemplate">
<div class="imgbox">
<img class="imgitemdefault" [src]="ImgUrl">
</div>
</ng-container>
<ng-template #elseTemplate >
<p style="text-align: center;">暂无单位图片,请先上传</p>
</ng-template>
</div>
</div>

66
src/app/key-unit/basicinfo-look/lookmaster.component.ts

@ -0,0 +1,66 @@
import { Component, OnInit, Inject } from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {FlatTreeControl} from '@angular/cdk/tree';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'lookmaster',
templateUrl: './lookmaster.component.html',
styleUrls: ['./basicinfo.component.scss']
})
export class LookMaster2 {
// myControl = new FormControl();
//注入MatDialogRef,可以用来关闭对话框
//要访问对话框组件中的数据,必须使用MAT_DIALOG_DATA注入令牌
constructor(private http: HttpClient,public dialogRef: MatDialogRef<LookMaster2>,@Inject(MAT_DIALOG_DATA) public data) {}
allunittype:any
ImgUrl:string
rotationAngle=0
isheng:any
isshowimg:boolean
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit(): void {
if(this.data.img.indexOf('?') == -1){
this.isshowimg = false
}else{
this.isshowimg = true
var imgurl = this.data.img.split("?")
this.ImgUrl = imgurl[0]
}
}
//点击旋转按钮时
rotateA = 0
rotateB = 0
rotate(){
var w= document.getElementsByClassName("imgitemdefault")[0]['naturalWidth'];
var h = document.getElementsByClassName("imgitemdefault")[0]['naturalHeight'];
if(w > h){
this.isheng = true
}else{
this.isheng = false
}
if(this.isheng){
this.rotateA += 90
if(this.rotateA == 360){
this.rotateA = 0
}
}else{
this.rotateB += 10
if(this.rotateB == 40){
this.rotateB = 0
}
}
}
}

25
src/app/key-unit/basicinfo/addhouseinfo.component.html

@ -0,0 +1,25 @@
<div mat-dialog-title>新增建筑</div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field hintLabel="名字不多于20个字">
<input matInput id="name" name="name"
required
maxlength="20"
ngModel #name="ngModel" placeholder="建筑名称"
#input
>
<mat-hint align="end">{{input.value?.length || 0}}/20</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-select required name="unittype" ngModel #unittype="ngModel" placeholder="建筑类型">
<mat-option [value]="item.id" *ngFor="let item of allunittype" >{{item.name}}</mat-option>
</mat-select>
</mat-form-field>
<div class="btn">
<button type="submit" class="savebtn" mat-raised-button color="primary" [disabled]='form.invalid'>确定</button>
<button type="button" mat-button (click)="onNoClick()" mat-raised-button>取消</button>
</div>
</form>

77
src/app/key-unit/basicinfo/addhouseinfo.component.ts

@ -0,0 +1,77 @@
import { Component, OnInit, Inject } from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {FlatTreeControl} from '@angular/cdk/tree';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'addhouseinfo',
templateUrl: './addhouseinfo.component.html',
styleUrls: ['./basicinfo.component.scss']
})
export class AddHouseInfo {
myControl = new FormControl();
//注入MatDialogRef,可以用来关闭对话框
//要访问对话框组件中的数据,必须使用MAT_DIALOG_DATA注入令牌
constructor(private http: HttpClient,public dialogRef: MatDialogRef<AddHouseInfo>,@Inject(MAT_DIALOG_DATA) public data) {}
allunittype:any
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit(): void {
// console.log(this.data)
this.getallunittype()
}
getallunittype(){
this.http.get("/api/BuildingTypes/Simple").subscribe(data=>{
this.allunittype = data
})
}
onSubmit(value){
this.http.get("/api/Buildings",{
params:{
companyId:this.data.unitId
}
}).subscribe((data:any)=>{
this.data.allBuildings = data
let order
if(data.length == 0){
order = 0
}else{
order = data[data.length - 1].order + 1
}
let buildingTypename = ""
this.allunittype.forEach(item => {
if(item.id == value.unittype){
buildingTypename = item.name
}
});
this.http.post("/api/Buildings",{
id: "",
name: value.name,
order: order,
enabled: true,
companyId: this.data.unitinfo.id,
buildingTypes: [
{
id: value.unittype,
name: buildingTypename
}
]
},{params:{
companyId : this.data.unitId
}}).subscribe(data=>{
this.dialogRef.close(data);
})
})
}
}

531
src/app/key-unit/basicinfo/basicinfo.component.html

@ -0,0 +1,531 @@
<div style="height: 100%;display: flex; flex-direction: column;">
<!-- header -->
<mat-accordion>
<mat-expansion-panel expanded hideToggle >
<mat-expansion-panel-header style="color: black;">
<mat-panel-title>
单位信息
<mat-icon style="position: absolute;right:30px;">keyboard_arrow_down</mat-icon>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="topbox">
<form (ngSubmit)="onSubmit(form.value,form.invalid,form)" #form="ngForm" class="example-container">
<div class="mainbox" >
<div class="mainleft">
<div class="inputbox" >
<span style="color: red;">*</span>
<span>统一社会信用代码:</span>
<mat-form-field>
<input matInput id="creditcode" name="creditcode" type='text' #usci="ngModel"
required minlength="1" maxlength="18"
[(ngModel)]="unitinfo.usci"
(focus)="closeorganizationbox()"
pattern="^[0-9A-HJ-NP-RTUW-Y]{2}\d{6}[0-9A-HJ-NP-RTUW-Y]{10}$">
</mat-form-field>
<div *ngIf="usci.invalid && (usci.dirty || usci.touched)" class="alert-danger">
<div *ngIf="usci.errors.pattern" class="alert-danger">
统一社会信用代码格式不正确
</div>
</div>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>单位类型:</span>
<mat-form-field (click)="closeorganizationbox()">
<mat-select required name="unittype" [(ngModel)]="defaultbuildingTypes">
<mat-option [value]="item.id" *ngFor="let item of allunittype">{{item.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>联系人:</span>
<mat-form-field>
<input matInput id="linkman" name="linkman" type='text'
required minlength="1"
[(ngModel)]="unitinfo.contacts"
(focus)="closeorganizationbox()"
>
</mat-form-field>
</div>
<div class="inputbox">
<span style="color: red;">*</span>
<span>联系电话:</span>
<mat-form-field>
<input matInput id="linkphone" name="linkphone" type='text' #linkphone="ngModel"
required pattern="^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[35-8]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0135-9]\d{2}|66\d{2})\d{6}$"
[(ngModel)]="unitinfo.phone"
(focus)="closeorganizationbox()"
>
</mat-form-field>
<div *ngIf="linkphone.invalid && (linkphone.dirty || linkphone.touched)" class="alert-danger">
<div *ngIf="linkphone.errors.pattern" class="alert-danger">
电话号码格式不正确
</div>
</div>
</div>
<div class="inputbox" style="width: 700px;">
<span style="color: red;">*</span>
<span>辖区中队:</span>
<mat-form-field style="width: 538px;">
<input matInput id="organization" name="organization" type='text'
required minlength="1"
[(ngModel)]="selectedorganization"
(focus)="openorganizationbox()"
readonly="value" >
</mat-form-field>
</div>
<div id="organizationbox" class="organizationbox" *ngIf="isorganizationbox">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='add(node)' class="organizationlist">
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='add(node)' class="organizationlist">
<button
type="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>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
<div class="inputbox" style="width: 700px;">
<span style="color: red;">*</span>
<span>单位地址:</span>
<mat-form-field style="width: 538px;">
<input matInput id="unitaddress" name="unitaddress" type='text'
required minlength="1"
[(ngModel)]="unitinfo.address"
(focus)="closeorganizationbox()">
</mat-form-field>
</div>
<div class="uploadimg" (click)="lookmaster()">
<span>单位照片:</span>
<div class="uploadingimg">
<img [src]="imgsrc" alt="" style="width: 299px; height: 170px;" >
</div>
<mat-spinner *ngIf="isspinner" diameter= 50></mat-spinner>
</div>
<div class="image" (click)="closeorganizationbox()">
<input id="selectedfile" type="file" (change)="filechange($event)" name="imgFile" accept=".jpg,.png,.jpeg,.gif,.webp">
</div>
<div class="addbtn">
<button type="submit" color="primary" class="submit1" mat-button mat-raised-button>保存</button>
</div>
</div>
<!-- <div class="mainright" (click)="closeorganizationbox()"> -->
<!-- 地图预留位置 -->
<!-- </div> -->
</div>
</form>
</div>
</mat-expansion-panel>
</mat-accordion>
<!-- body -->
<div class="bottombox" style="flex: 70%;overflow-y: auto;" >
<div class="houseinfobox" style="height: 100%; overflow-y: auto;padding-bottom: 64px; box-sizing:border-box">
<button type="button" mat-icon-button (click)="addhouseinfo()" class="addhouseinfo"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button>
<mat-tab-group style="height: 100%;;" (focusChange)="selecttab($event)" >
<mat-tab [label]="item.username" *ngFor="let item of houses;let key = index">
<form style="height: 100%; overflow-y:auto; display: block;" (ngSubmit)="onSubmit2(form.value,item,key,form.invalid)" #form="ngForm" class="example-container">
<!-- 正常建筑 -->
<div class="highinfo" *ngIf="item.tongyong">
<div class="houseinfoinput" >
<span>建筑名称:</span>
<mat-form-field>
<input matInput id="housename" name="housename" type='text'
minlength="1" [(ngModel)]="item.name"
>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div class="houseinfoinput">
<span>建筑类型:</span>
<mat-form-field>
<mat-select name="unittype" [(ngModel)]="item.buildtype">
<mat-option [value]="n.name" *ngFor="let n of allunittype" (click)="templatebuildtype(n,item,key)">{{n.name}}</mat-option>
</mat-select>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div *ngFor="let item of item.buildingBasicGroups;let www = index" style="float: left;">
<h1 style="font-size: 22px;">{{item.name}}</h1>
<div class="houseinfoinput" *ngFor="let i of item.propertyInfos" style="float: left;margin-left: 250px;position: relative;">
<span>{{i.propertyName}}<span *ngIf="i.physicalUnit">({{i.physicalUnit}})</span></span>
<!-- 如果类型是文本 -->
<mat-form-field *ngIf="i.propertyType == 0">
<input matInput name="{{i.propertyName}}{{www}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue">
</mat-form-field>
<!-- 如果类型是数字 -->
<mat-form-field *ngIf="i.propertyType == 2">
<input matInput name="{{i.propertyName}}{{www}}" type='number'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
(change)="inputchange($event,i.ruleName,i.ruleValue,i)"
>
<!-- <mat-error *ngIf="isshowrule">{{rulevalue}}</mat-error> -->
</mat-form-field>
<!-- 如果类型是多行文本 -->
<textarea *ngIf="i.propertyType == 1" style="width: 180px;height: 60px;" required="{{ i.required==true ? 'true' : 'false' }}" [(ngModel)]="i.propertyValue" name="{{i.propertyName}}{{key}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
<div *ngIf="i.isshowrule" style="position: absolute;
left: 205px;
top: 45px;
font-size: 11px;
color: red;">
<span>{{i.rulevalue}}</span>
</div>
</div>
</div>
<div class="CustomData" style="width: 200px;">
<mat-checkbox (change)="checkCustomData($event)" name="checkbuilding" [(ngModel)]="item.isCustomData" style="float: left;margin-right: 10px;"></mat-checkbox>
<h1 style="font-size: 22px;width: 200px;">自定义信息</h1>
</div>
<div *ngIf="item.isCustomData" style="position: relative;">
<button style="position: absolute;left: 0;" type="button" mat-icon-button (click)="addCustomData(item)" class="addCustomData"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button>
<button style="position: absolute;left:60px;" type="button" mat-icon-button (click)="deleteCustomData(item)" class="deleteCustomData"><mat-icon style="font-size: 38px;">remove_circle_outline</mat-icon></button>
<div class="houseinfoinput" style="float: left;margin-left: 250px;" *ngFor="let i of item.buildingCustomData.customProperties;let key = index">
<mat-form-field>
<input matInput type='text' name="{{key}}1CustomData"
required
[(ngModel)]="i.name">
</mat-form-field>
<span>:</span>
<mat-form-field>
<input matInput type='text' name="{{key}}2CustomData"
required
[(ngModel)]="i.value">
</mat-form-field>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
</div>
<!-- 石油化工 -->
<div class="highinfo" *ngIf="item.isshiyou;let bigkey = index">
<div class="basicinfobox">
<div class="houseinfoinput">
<span>建筑名称:</span>
<mat-form-field>
<input matInput id="housename" name="housename" type='text'
required minlength="1" [(ngModel)]="item.name"
>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<div class="houseinfoinput" >
<span>建筑类型:</span>
<mat-form-field>
<mat-select required name="unittype" [(ngModel)]="item.buildtype">
<mat-option [value]="n.name" *ngFor="let n of allunittype" (click)="templatebuildtype(n,item,key)">{{n.name}}</mat-option>
</mat-select>
</mat-form-field>
<span style="color: red;">*</span>
</div>
<h1 style="font-size: 22px;">{{item.buildingBasicGroups[0].name}}</h1>
<div class="houseinfoinput" *ngFor="let i of item.buildingBasicGroups[0].propertyInfos;let smkey = index" style="float: left;margin-left: 250px;position: relative;">
<span>{{i.propertyName}} <span *ngIf="i.physicalUnit">({{i.physicalUnit}})</span></span>
<!-- 如果类型是文本 -->
<mat-form-field *ngIf="i.propertyType == 0">
<input matInput name="{{i.propertyName}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue">
</mat-form-field>
<!-- 如果类型是数字 -->
<mat-form-field *ngIf="i.propertyType == 2">
<input matInput name="{{i.propertyName}}" type='number'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
(change)="inputchange($event,i.ruleName,i.ruleValue,i)"
>
<!-- <mat-error *ngIf="isshowrule">{{rulevalue}}</mat-error> -->
</mat-form-field>
<!-- 如果类型是多行文本 -->
<textarea *ngIf="i.propertyType == 1" style="width: 180px;height: 60px;" required="{{ i.required==true ? 'true' : 'false' }}" [(ngModel)]="i.propertyValue" name="{{i.propertyName}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
<div *ngIf="i.isshowrule" style=" position: absolute;
left: 205px;
top: 45px;
font-size: 11px;
color: red;">
<span>{{i.rulevalue}}</span>
</div>
</div>
</div>
<div class="deviceinfo">
<div style="width: 200px;">
<mat-checkbox (change)="checkboxchange(item.buildingBasicGroups[1].submitted,$event)" name="item.buildingBasicGroups[1].name" *ngIf="item.buildingBasicGroups[1].isOptional" [(ngModel)]="item.buildingBasicGroups[1].submitted" style="float: left;margin-right: 10px;"></mat-checkbox>
<h1 style="font-size: 22px;width: 200px;">{{item.buildingBasicGroups[1].name}}</h1>
</div>
<table mat-table [dataSource]="devicedataSourcebox[item.buildingId]" class="mat-elevation-z8" *ngIf="item.buildingBasicGroups[1].submitted">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>
<button style="width: 24px;" type="button" mat-icon-button class="adddeviceinfo2" (click)="adddeviceinfo(item)"><mat-icon>add_circle_outline</mat-icon></button>
<button style="width: 24px;" type="button" mat-icon-button class="removedeviceinfo" (click)="removedeviceinfo(item)"><mat-icon>remove_circle_outline</mat-icon></button>
装置区名称<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea style="width: 100px;" [(ngModel)]="element.name" name="{{key}}1" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="flow">
<th mat-header-cell *matHeaderCellDef>工艺流程<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea [(ngModel)]="element.flow" name="{{key}}2" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="danger">
<th mat-header-cell *matHeaderCellDef>火灾危险性<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea [(ngModel)]="element.danger" name="{{key}}3" required></textarea>
</td>
</ng-container>
<ng-container matColumnDef="payattentionto">
<th mat-header-cell *matHeaderCellDef>灭火注意事项</th>
<td mat-cell *matCellDef="let element;let key = index">
<textarea style="width: 100px;" [(ngModel)]="element.payattentionto" name="{{key}}4"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<div style="width: 200px;">
<mat-checkbox (change)="checkboxchange(item,$event)" *ngIf="item.buildingBasicGroups[2].isOptional" name="item.buildingBasicGroups[2].name" [(ngModel)]="item.buildingBasicGroups[2].submitted" style="float: left;margin-right: 10px;"></mat-checkbox>
<h1 style="font-size: 22px;width: 200px;">储罐信息</h1>
</div>
<button *ngIf="item.buildingBasicGroups[2].submitted" type="button" mat-raised-button color="primary" (click)="addtankbox(item,bigkey)" style="margin-top: 30px;margin-right: 5px;">添加储罐</button>
<button *ngIf="item.buildingBasicGroups[2].submitted" type="button" mat-raised-button color="warn" (click)="removetankbox(item,bigkey)" style="margin-top: 30px;" matTooltip="会将此建筑处于末尾的储罐移除">移除末尾储罐</button>
<div *ngIf="item.buildingBasicGroups[2].submitted" style="margin-top: 30px;">
<div class="tankinfo" *ngFor="let x of item.bigfor;let www = index">
<p style="font-size: 22px; width: 200px;">{{x[0].name}}</p>
<div class="basicinfobox" >
<div class="houseinfoinput" *ngFor="let i of x[0].propertyInfos;let key = index" style="line-height: 65px;">
<span>{{i.propertyName}} {{i.physicalUnit}}:</span>
<mat-form-field *ngIf="i.propertyType == 0">
<input matInput name="{{www+2}}-tanker-{{key}}" type='text'
required="{{ i.required==true ? 'true' : 'false' }}"
[(ngModel)]="i.propertyValue"
>
</mat-form-field>
<textarea style="width: 180px;height: 45px;" *ngIf="i.propertyType == 1" [(ngModel)]="i.propertyValue" name="{{www+2}}-tanker-{{key}}"></textarea>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
<p style="font-size: 22px; width: 200px;">{{x[1].name}}</p>
<div class="tankdetailinfo">
<table #table mat-table [dataSource]="x[1].propertyInfos" class="mat-elevation-z8" style="position: relative;">
<ng-container matColumnDef="tank">
<th mat-header-cell *matHeaderCellDef>
<button type="button" mat-icon-button class="adddeviceinfo" (click)="adddeviceinfo2(www,item)" style="position: absolute;left: 0;"><mat-icon>add_circle_outline</mat-icon></button>
<button type="button" mat-icon-button class="removedeviceinfo" (click)="removedeviceinfo3(www,item)"><mat-icon>remove_circle_outline</mat-icon></button>
罐区 </th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tank}}tank{{key}}" type='text'
[(ngModel)]="element.tank">
</td>
</ng-container>
<ng-container matColumnDef="tankid">
<th mat-header-cell *matHeaderCellDef>罐区编号<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tankid}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankid">
</td>
</ng-container>
<ng-container matColumnDef="tankmedium">
<th mat-header-cell *matHeaderCellDef>储存介质<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tankmedium}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankmedium">
</td>
</ng-container>
<ng-container matColumnDef="tanktype">
<th mat-header-cell *matHeaderCellDef>储罐类型<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tanktype}}tank{{key}}" type='text'
required
[(ngModel)]="element.tanktype">
</td>
</ng-container>
<ng-container matColumnDef="tankcapacity">
<th mat-header-cell *matHeaderCellDef>容量(m³)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tankcapacity}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankcapacity">
</td>
</ng-container>
<ng-container matColumnDef="tankdiameter">
<th mat-header-cell *matHeaderCellDef>直径(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tankdiameter}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankdiameter">
</td>
</ng-container>
<ng-container matColumnDef="tankheight">
<th mat-header-cell *matHeaderCellDef>高度(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tankheight}}tank{{key}}" type='text'
required
[(ngModel)]="element.tankheight">
</td>
</ng-container>
<ng-container matColumnDef="tanktectum">
<th mat-header-cell *matHeaderCellDef>顶盖形式</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tanktectum}}tank{{key}}" type='text'
[(ngModel)]="element.tanktectum">
</td>
</ng-container>
<ng-container matColumnDef="tanktexture">
<th mat-header-cell *matHeaderCellDef>浮盘材质</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.tanktexture}}tank{{key}}" type='text'
[(ngModel)]="element.tanktexture">
</td>
</ng-container>
<ng-container matColumnDef="platetype">
<th mat-header-cell *matHeaderCellDef>浮盘类型</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.platetype}}tank{{key}}" type='text'
[(ngModel)]="element.platetype">
</td>
</ng-container>
<ng-container matColumnDef="foamgeneratorid">
<th mat-header-cell *matHeaderCellDef>泡沫产生器型号</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.foamgeneratorid}}tank{{key}}" type='text'
[(ngModel)]="element.foamgeneratorid">
</td>
</ng-container>
<ng-container matColumnDef="foamgeneratortype">
<th mat-header-cell *matHeaderCellDef>泡沫产生器形式</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.foamgeneratortype}}tank{{key}}" type='text'
[(ngModel)]="element.foamgeneratortype">
</td>
</ng-container>
<ng-container matColumnDef="isprotect">
<th mat-header-cell *matHeaderCellDef>是否设置氮封惰化保护装置</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.isprotect}}tank{{key}}" type='text'
[(ngModel)]="element.isprotect">
</td>
</ng-container>
<ng-container matColumnDef="fendinggroyneheight">
<th mat-header-cell *matHeaderCellDef>防护堤高度(m)<span style="color: red;">*</span></th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.fendinggroyneheight}}tank{{key}}" type='text'
required
[(ngModel)]="element.fendinggroyneheight">
</td>
</ng-container>
<ng-container matColumnDef="portnum">
<th mat-header-cell *matHeaderCellDef>半固定泡沫灭火接口数量</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.portnum}}tank{{key}}" type='text'
[(ngModel)]="element.portnum">
</td>
</ng-container>
<ng-container matColumnDef="else">
<th mat-header-cell *matHeaderCellDef>其它设施</th>
<td mat-cell *matCellDef="let element;let key = index">
<input style="height:45px" class="tankinfo" name="{{www}}{{element.else}}tank{{key}}" type='text'
[(ngModel)]="element.else">
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns2"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns2;"></tr>
</table>
</div>
</div>
</div>
<div class="CustomData" style="width: 200px;margin-top: 60px;">
<mat-checkbox (change)="checkCustomData($event)" name="checkbuilding" [(ngModel)]="item.isCustomData" style="float: left;margin-right: 10px;"></mat-checkbox>
<h1 style="font-size: 22px;width: 200px;">自定义信息</h1>
</div>
<div *ngIf="item.isCustomData" style="position: relative;">
<button style="position: absolute;left: 0;font-size: 11px;" type="button" mat-icon-button (click)="addCustomData(item)" class="addCustomData"><mat-icon style="font-size: 38px;">add_circle_outline</mat-icon></button>
<button style="position: absolute;left:60px;" type="button" mat-icon-button (click)="deleteCustomData(item)" class="deleteCustomData"><mat-icon style="font-size: 38px;">remove_circle_outline</mat-icon></button>
<div class="houseinfoinput" style="float: left;margin-left: 250px;" *ngFor="let i of item.buildingCustomData.customProperties;let key = index">
<mat-form-field>
<input matInput type='text' name="{{key}}1CustomData"
required
[(ngModel)]="i.name">
</mat-form-field>
<span>:</span>
<mat-form-field>
<input matInput type='text' name="{{key}}2CustomData"
required
[(ngModel)]="i.value">
</mat-form-field>
<span style="color: red;" *ngIf="i.required">*</span>
</div>
</div>
</div>
<div class="infobtnbox">
<button type="submit()" mat-button mat-raised-button color="primary" >保存</button>
<button type="button" mat-raised-button (click)="deletedbuilding(item)" color="warn">删除</button>
</div>
</form>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>

269
src/app/key-unit/basicinfo/basicinfo.component.scss

@ -0,0 +1,269 @@
.topbox{
height: 485px;
width: 100%;
// border-bottom: 1px solid black;
.mainbox{
height: 100%;
position: relative;
.mainleft{
width:800px;
height: 100%;
// background-color: yellow;
float: left;
.inputbox{
width: 343px;
height: 58px;
margin:2px 6px;
float: left;
text-align: end;
}
.organizationbox{
width:538px;
height: 200px;
background: white;
position: absolute;
top: 164px;
left:166px;
z-index: 100;
border: 1px solid grey;
overflow: auto;
li{
list-style: none;
}
mat-tree-node{
cursor: pointer;
}
mat-tree-node:hover{
background: rgba(225, 225, 225, 0.8);
}
}
.addbtn{
width: 695px;
position: absolute;
bottom: -495px;
text-align: center;
margin-bottom:20px;
button{
margin: 0 4px;
}
}
.uploadimg{
width: 400px;
height: 200px;
float: left;
margin-top:12px;
position: relative;
margin-left: 80px;
cursor: pointer;
span{
float: left;
}
// img{
// float: left;
// }
.uploadingimg{
width: 299px;
height: 170px;
// background: url('../../../assets/images/upload2.png') no-repeat center center;
position: absolute;
top: 0px;
left: 79px;
border: 1px dashed gray;
border-radius:3px;
}
}
.image{
// position: absolute;
// top: 199px;
// left: 160px;
// width: 299px;
// height: 170px;
input{
// width: 299px;
// height: 170px;
width: 190px;
margin-top: 160px;
cursor: pointer;
}
// opacity:0;
}
}
.mainright{
float: left;
width: 600px;
height: 400px;
// position: absolute;
// right: 170px;
}
}
}
.bottombox{
// height:400px;
width: 100%;
// background-color: skyblue;
.bottomtitle{
height: 60px;
// background-color: orange;
line-height: 60px;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.houseinfobox{
// height:340px;
overflow: auto;
.addhouseinfo{
float: left;
}
.infobtnbox{
margin-left: 800px;
position: absolute;
top: 30px;
right: 75px;
button{
width: 80px;
height: 40px;
margin: 0 12px;
margin-top: 15px;
}
}
.infotitle{
font-size: 28px;
font-weight: 900;
margin-left: 180px;
}
.houseinfoinput{
width: 393px;
text-align: end;
margin-left:240px;
}
}
}
.btn{
width: 100%;
text-align: center;
button{
margin: 0 8px;
}
}
.mat-spinner{
margin-top: 58px;
margin-left: 203px;
}
.mat-table{
width: 100%;
}
table{
width: 1000px;
thead{
tr{
th{
width: 60px;
display: block;
float: left;
}
}
}
tbody{
tr{
td{
width: 60px;
display: block;
float: left;
text-align: center;
}
}
}
}
.deviceinfo{
// border-bottom: 1px solid black;;
padding-bottom: 60px;
}
.tankdetailinfo{
// border-bottom: 1px solid black;;
padding-bottom: 35px;
table{
th{
text-align: center;
}
}
}
.tankinfo{
display: block;
width: 100%;
// height: 45px;
text-align: center;
}
// .adddeviceinfo{
// // position: absolute;
// // left: 0px;
// }
.submit1{
margin-left: -66px !important;
}
textarea {
vertical-align: middle;
border-radius: 5px;
padding: 5px;
width: 600px;
height: 110px;
resize: none;
}
//预览图片旋转角度
.img1{
transform:rotate(90deg) scale(0.55);
height: 100%;
}
.img2{
transform:rotate(180deg);
// height: 100%;
}
.img3{
transform:rotate(270deg) scale(0.55);
// height: 100%;
}
.img4{
transform:rotate(90deg) scale(1.3);
// height: 100%;
}
.img5{
transform:rotate(180deg);
// height: 100%;
}
.img6{
transform:rotate(270deg) scale(1.3);
// height: 100%;
}
.imgbox{
text-align: center;
height: 750px;
img{
max-width: 1500px;
max-height: 740px;
}
}
.previewImgBottom{
text-align: center;
}
.alert-danger {
margin-top: -16px;
text-align: left;
padding-left: 77px;
font-size: 12px;
color: red;
}
.mat-expansion-panel{
span{
color: black;
}
}

25
src/app/key-unit/basicinfo/basicinfo.component.spec.ts

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

2032
src/app/key-unit/basicinfo/basicinfo.component.ts

File diff suppressed because it is too large Load Diff

26
src/app/key-unit/basicinfo/lookmaster.component.html

@ -0,0 +1,26 @@
<div mat-dialog-title>单位照片</div>
<div>
<div>
<ng-container *ngIf="isshowimg; else elseTemplate">
<div class="imgbox">
<img class="imgitemdefault" [src]="ImgUrl">
<!-- <img class="imgitemdefault" [src]="ImgUrl" [ngClass]="{'img1': rotateA==90,'img2': rotateA==180,'img3': rotateA==270,'img4': rotateB==10,'img5': rotateB==20,'img6': rotateB==30}" > -->
</div>
</ng-container>
<ng-template #elseTemplate >
<p style="text-align: center;">暂无单位图片,请先上传</p>
</ng-template>
</div>
</div>
<!--
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div> -->
<!-- <div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
</div> -->

66
src/app/key-unit/basicinfo/lookmaster.component.ts

@ -0,0 +1,66 @@
import { Component, OnInit, Inject } from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {FlatTreeControl} from '@angular/cdk/tree';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'lookmaster',
templateUrl: './lookmaster.component.html',
styleUrls: ['./basicinfo.component.scss']
})
export class LookMaster {
// myControl = new FormControl();
//注入MatDialogRef,可以用来关闭对话框
//要访问对话框组件中的数据,必须使用MAT_DIALOG_DATA注入令牌
constructor(private http: HttpClient,public dialogRef: MatDialogRef<LookMaster>,@Inject(MAT_DIALOG_DATA) public data) {}
allunittype:any
ImgUrl:string
rotationAngle=0
isheng:any
isshowimg:boolean
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit(): void {
if(this.data.img.indexOf('?') == -1){
this.isshowimg = false
}else{
this.isshowimg = true
var imgurl = this.data.img.split("?")
this.ImgUrl = imgurl[0]
}
}
//点击旋转按钮时
rotateA = 0
rotateB = 0
rotate(){
var w= document.getElementsByClassName("imgitemdefault")[0]['naturalWidth'];
var h = document.getElementsByClassName("imgitemdefault")[0]['naturalHeight'];
if(w > h){
this.isheng = true
}else{
this.isheng = false
}
if(this.isheng){
this.rotateA += 90
if(this.rotateA == 360){
this.rotateA = 0
}
}else{
this.rotateB += 10
if(this.rotateB == 40){
this.rotateB = 0
}
}
}
}

56
src/app/key-unit/edit-plan-info/edit-plan-info.component.html

@ -0,0 +1,56 @@
<mat-tab-group selectedIndex="0" style="height: 94%;" >
<mat-tab label="1.基本信息">
<ng-template matTabContent>
<app-basicinfo></app-basicinfo>
</ng-template>
</mat-tab>
<mat-tab label="2.平面图">
<ng-template matTabContent>
<iframe id="main" src="/unityApp2Basic/index.html" name="unityApp" frameborder="0" width="96%" height="100%" style="margin-left: 2%;"></iframe>
</ng-template>
</mat-tab>
<mat-tab label="3.四周毗邻">
<ng-template matTabContent>
<app-allaround></app-allaround>
</ng-template>
</mat-tab>
<mat-tab label="4.消防设施">
<ng-template matTabContent>
<app-fire-fighting-device></app-fire-fighting-device>
</ng-template>
</mat-tab>
<mat-tab label="5.重点部位">
<ng-template matTabContent>
<app-key-site></app-key-site>
</ng-template>
</mat-tab>
<mat-tab label="6.功能分区">
<ng-template matTabContent>
<app-function-division></app-function-division>
</ng-template>
</mat-tab>
<mat-tab label="7.实景图">
<ng-template matTabContent>
<app-realistic-picture></app-realistic-picture>
</ng-template>
</mat-tab>
<mat-tab label="8.上传CAD">
<ng-template matTabContent>
<app-uploading-cad></app-uploading-cad>
</ng-template>
</mat-tab>
<mat-tab label="9.六熟悉记录">
<ng-template matTabContent>
功能开发中~~
</ng-template>
</mat-tab>
<mat-tab label="10.实战演练记录">
<ng-template matTabContent>
功能开发中~~
</ng-template>
</mat-tab>
</mat-tab-group>

3
src/app/key-unit/edit-plan-info/edit-plan-info.component.scss

@ -0,0 +1,3 @@
.mat-tab-body-wrapper{
height: 100%!important;
}

25
src/app/key-unit/edit-plan-info/edit-plan-info.component.spec.ts

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

15
src/app/key-unit/edit-plan-info/edit-plan-info.component.ts

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

60
src/app/key-unit/edit-unit-info/edit-unit-info.component.html

@ -0,0 +1,60 @@
<!-- K1密钥拔出时倒计时显示 -->
<div style="width: 100%;height: 0;position: relative; z-index: 999;" *ngIf="mToken.isShow">
<div style="position: absolute;color: red;width: 100%;text-align: center;margin-top: 5%;font-size: 18px;">
<countdown [config]="{leftTime: 10,format: '密钥已拔出,本页面将于s秒后关闭,请及时保存'}"></countdown>
</div>
</div>
<mat-tab-group selectedIndex="9" style="height: 100%;">
<mat-tab label="1.基本信息">
<ng-template matTabContent>
<app-basicinfo></app-basicinfo>
</ng-template>
</mat-tab>
<mat-tab label="2.四周毗邻">
<ng-template matTabContent>
<app-allaround></app-allaround>
</ng-template>
</mat-tab>
<mat-tab label="3.消防设施">
<ng-template matTabContent>
<app-fire-fighting-device></app-fire-fighting-device>
</ng-template>
</mat-tab>
<mat-tab label="4.重点部位">
<ng-template matTabContent>
<app-key-site></app-key-site>
</ng-template>
</mat-tab>
<mat-tab label="5.功能分区">
<ng-template matTabContent>
<app-function-division></app-function-division>
</ng-template>
</mat-tab>
<mat-tab label="6.实景图">
<ng-template matTabContent>
<app-realistic-picture></app-realistic-picture>
</ng-template>
</mat-tab>
<mat-tab label="7.上传CAD">
<ng-template matTabContent>
<app-uploading-cad></app-uploading-cad>
</ng-template>
</mat-tab>
<mat-tab label="8.六熟悉记录">
<ng-template matTabContent>
功能开发中~~
</ng-template>
</mat-tab>
<mat-tab label="9.实战演练记录">
<ng-template matTabContent>
功能开发中~~
</ng-template>
</mat-tab>
<mat-tab label="10.作战部署">
<ng-template matTabContent>
<!-- <iframe id="main" src="/unityApp2/index.html" name="unityApp" frameborder="0" width="100%" height="98%"></iframe> -->
<app-collection-tools></app-collection-tools>
</ng-template>
</mat-tab>
</mat-tab-group>

3
src/app/key-unit/edit-unit-info/edit-unit-info.component.scss

@ -0,0 +1,3 @@
.mat-tab-body-wrapper{
height: 100%!important;
}

25
src/app/key-unit/edit-unit-info/edit-unit-info.component.spec.ts

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

23
src/app/key-unit/edit-unit-info/edit-unit-info.component.ts

@ -0,0 +1,23 @@
import { Component, OnInit } from '@angular/core';
// import { BasicinfoComponent } from '../basicinfo/basicinfo.component'
import { Router,ActivatedRoute } from '@angular/router'
import {MTokenK1Service} from '../../m-token-k1/m-token-k1.service' //引入服务
import { CollectionToolsComponent } from '../../../app/ui/collection-tools/collection-tools.component'
@Component({
selector: 'app-edit-unit-info',
templateUrl: './edit-unit-info.component.html',
styleUrls: ['./edit-unit-info.component.scss']
})
export class EditUnitInfoComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,public mToken: MTokenK1Service) { }
ngOnInit(): void {
}
}

69
src/app/key-unit/fire-fighting-device-look/addGrouping.component.ts

@ -0,0 +1,69 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
@Component({
selector: 'imgsdatadetail',
templateUrl: './addGrouping.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class ImgsDataDetail2 {
constructor(private http: HttpClient,public dialogRef: MatDialogRef<ImgsDataDetail2>,@Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar) {}
ngOnInit(): void {
}
ngAfterViewInit(): void{
}
//提交表单
onSubmit (e) {
if (this.data.buildingId) { //建筑新建内置项
let repeat = this.data.item.facilityItems.find(items=>items.name==e.name)
if (repeat==undefined) {
let header = {buildingId:this.data.buildingId, groupId:this.data.item.id}
let msg = {
isBuiltin: false,
details: '',
name: e.name,
isEachFloor: false,
order: this.data.item.facilityItems.length? this.data.item.facilityItems[this.data.item.facilityItems.length-1].order+1 : 0}
this.http.post('/api/CompanyAccount/BuildingFacilityItems',msg,{params:header}).subscribe(data=>{
this.dialogRef.close(data); })
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('当前分组下禁止创建名称相同内置项','确定',config);
}
} else { //单位新建内置项
let repeat = this.data.facilityItems.find(item=>item.name==e.name)
if (repeat==undefined) {
let header = {groupId:this.data.id}
let msg = {
isBuiltin: false,
details: '',
name: e.name,
isEachFloor: false,
order: this.data.facilityItems.length? this.data.facilityItems[this.data.facilityItems.length-1].order+1 : 0}
this.http.post('/api/CompanyAccount/CompanyFacilityItems',msg,{params:header}).subscribe(data=>{
this.dialogRef.close(data); })
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('当前分组下禁止创建名称相同内置项','确定',config);
}
} //else
}
}

18
src/app/key-unit/fire-fighting-device-look/addGrouping.html

@ -0,0 +1,18 @@
<div mat-dialog-title>创建消防设施内置项</div>
<div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<input matInput placeholder="请输入消防设施内置项名称" required ngModel name="name" maxlength="30">
</mat-form-field>
<p style="font-size: 14px; color: red; margin-bottom: 15px;">*注: 该名称不允许与当前分组内置项重名</p>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit"
[disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

193
src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.html

@ -0,0 +1,193 @@
<div class="content">
<mat-tab-group>
<mat-tab label="单位消防设施">
<div class="contentBox">
<p style="width: 100%; margin: 30px auto; text-align: center;" *ngIf="!companyBuiltInGrouping.length">暂无数据,请完善单位基本信息</p>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of companyBuiltInGrouping;let key = index">
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<div style="margin-bottom: 10px;">
<!-- <mat-icon title="创建" (click)='addCompanyGrouping(item)'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editCompanyGrouping(item)'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='deleteCompanyGrouping(item)'>delete</mat-icon> -->
</div>
<div>
<mat-accordion multi>
<mat-expansion-panel disabled>
<mat-expansion-panel-header>
<label class="firstContent"></label>
<label class="textContent">项目</label>
<label class="textContent">照片</label>
<label class="totalContent">总数</label>
<label class="lastTextContent">主要情况</label>
</mat-expansion-panel-header>
</mat-expansion-panel>
<mat-expansion-panel *ngFor="let items of item.facilityItems" disabled [expanded]=items.expanded>
<mat-expansion-panel-header>
<label class="firstContent">
<mat-checkbox (change)='checkedCompany($event,item,items)' [disabled]='items.isBuiltin'></mat-checkbox>
</label>
<label class="textContent">{{items.name}}</label>
<label class="textContent"><a href="javascript:void(0)" (click)='previewImg(items)'>查看图片</a></label>
<label class="totalContent">{{items.total ? items.total : '总数: 0'}}</label>
<label class="lastTextContent">
<textarea readonly maxlength="250" [(ngModel)]="items.details" style="width: 80%;"></textarea>
</label>
<label><mat-icon (click)='SwitchBoard(items)' *ngIf="items.isBuiltin">keyboard_arrow_down</mat-icon></label>
</mat-expansion-panel-header>
<div class="overflowTable">
<div class="detailsTable">
<table>
<tr>
<th *ngFor="let header of items.header">{{header}}</th>
</tr>
<tr *ngFor="let body of items.body">
<td *ngFor="let header of items.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
<div *ngFor="let tableMsg of items.loopTable" class="detailsTable">
<p style="text-align: center; font-size: 16px; margin: 5px 0;">楼层/区域名称: {{tableMsg.name? tableMsg.name: '暂无名称'}}</p>
<table>
<tr>
<th *ngFor="let header of tableMsg.header">{{header}}</th>
</tr>
<tr *ngFor="let body of tableMsg.body">
<td *ngFor="let header of tableMsg.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of companyOptionalGrouping;let key = index">
<mat-accordion multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<!-- <mat-icon title="保存" style="margin-left: 25px;" (click)='editCompanyOptional($event,item)'>description</mat-icon> -->
</mat-expansion-panel-header>
<div *ngFor="let items of item.propertyInfos" class="InputField">
<label>{{items.propertyName}}:</label>
<input readonly type="text" *ngIf="items.propertyType!=1&&items.propertyType!=2&&items.propertyType!=4&&items.propertyType!=6"
[(ngModel)]="items.propertyValue" name="propertyValue">
<textarea readonly maxlength="250" *ngIf="items.propertyType==1" [(ngModel)]="items.propertyValue" name="propertyValue"></textarea>
<input readonly type="number" *ngIf="items.propertyType==2 ||items.propertyType==4" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-group *ngIf="items.propertyType==6" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-button style="margin-left: 5px;" [value]='radio.value' *ngFor="let radio of singleElection">{{radio.name}}</mat-radio-button>
</mat-radio-group>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
</mat-tab>
<mat-tab label="{{newItem.name}}" *ngFor="let newItem of allBuildingGrouping">
<div class="contentBox">
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of newItem.buildingFacilityGroups">
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<div style="margin-bottom: 10px;">
<!-- <mat-icon title="创建" (click)='addBuildingGrouping(newItem,item)'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editBuildingGrouping(newItem,item)'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='deleteBuildingGrouping(newItem,item)'>delete</mat-icon> -->
</div>
<div>
<mat-accordion multi>
<mat-expansion-panel disabled>
<mat-expansion-panel-header>
<label class="firstContent"></label>
<label class="textContent">项目</label>
<label class="textContent">照片</label>
<label class="totalContent">总数</label>
<label class="lastTextContent">主要情况</label>
</mat-expansion-panel-header>
</mat-expansion-panel>
<mat-expansion-panel *ngFor="let items of item.facilityItems" disabled [expanded]=items.expanded>
<mat-expansion-panel-header>
<label class="firstContent">
<mat-checkbox (change)='checkedCompany($event,item,items)' [disabled]='items.isBuiltin'></mat-checkbox>
</label>
<label class="textContent">{{items.name}}</label>
<label class="textContent"><a href="javascript:void(0)" (click)='previewBuildingImg(newItem,items)'>查看图片</a></label>
<label class="totalContent">{{items.total ? items.total : '总数: 0'}}</label>
<label class="lastTextContent">
<textarea readonly maxlength="250" [(ngModel)]="items.details" style="width: 80%;"></textarea>
</label>
<label><mat-icon (click)='SwitchBuildingBoard(newItem,items)' *ngIf="items.isBuiltin">keyboard_arrow_down</mat-icon></label>
</mat-expansion-panel-header>
<div class="overflowTable">
<div class="detailsTable">
<table>
<tr>
<th *ngFor="let header of items.header">{{header}}</th>
</tr>
<tr *ngFor="let body of items.body">
<td *ngFor="let header of items.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
<div *ngFor="let tableMsg of items.loopTable" class="detailsTable">
<p style="text-align: center; font-size: 16px; margin: 5px 0;">楼层/区域名称: {{tableMsg.name? tableMsg.name : '暂无名称'}}</p>
<table>
<tr>
<th *ngFor="let header of tableMsg.header">{{header}}</th>
</tr>
<tr *ngFor="let body of tableMsg.body">
<td *ngFor="let header of tableMsg.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of newItem.buildingOptionalGroups">
<mat-accordion multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<!-- <mat-icon title="保存" style="margin-left: 25px;" (click)='editBuildingOptional($event,item)'>description</mat-icon> -->
</mat-expansion-panel-header>
<div *ngFor="let items of item.propertyInfos" class="InputField">
<label>{{items.propertyName}}:</label>
<input readonly type="text" *ngIf="items.propertyType!=1&&items.propertyType!=2&&items.propertyType!=4&&items.propertyType!=6"
[(ngModel)]="items.propertyValue" name="propertyValue">
<textarea readonly maxlength="250" *ngIf="items.propertyType==1" [(ngModel)]="items.propertyValue" name="propertyValue"></textarea>
<input readonly type="number" *ngIf="items.propertyType==2 ||items.propertyType==4" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-group *ngIf="items.propertyType==6" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-button style="margin-left: 5px;" [value]='radio.value' *ngFor="let radio of singleElection">{{radio.name}}</mat-radio-button>
</mat-radio-group>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>

145
src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.scss

@ -0,0 +1,145 @@
.content {
width: 100%;
height: 90%;
padding: 10px;
overflow-y: auto;
.contentBox {
width: 90%;
height: 100%;
margin: 0 auto;
overflow-y: auto;
}
}
.mat-icon {
color: black;
cursor:pointer;
}
//可展开面板每一行css
.mat-expansion-panel-header {
padding: 3px 24px;
}
.firstContent {
width: 3%;
}
.textContent {
width: 12%;
color: black;
text-align: center;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.totalContent {
width: 25%;
color: black;
text-align: center;
white-space: pre-line;
max-height: 48px;
overflow-y: auto;
}
.lastTextContent { //textarea多行文本
width: 45%;
color: black;
text-align: center;
}
input {
height: 22px;
line-height: 22px;
padding-left: 5px;
border-radius: 3px;
}
a {
color: #0000ff;
}
//bottom用户输入框
.InputField {
display: inline-block;
width: 40%;
text-align: right;
margin: 10px 25px;
input {width: 60%;}
label {margin-right: 10px;}
}
textarea {
vertical-align: middle;
border-radius: 5px;
padding: 5px;
width: 60%;
height: 36px;
resize: none;
}
//表格样式
.overflowTable {
width: 95%;
margin: 0 auto;
max-height: 300px;
overflow-y: auto;
}
.detailsTable {
margin: 10px 0;
table {
width: 100%;
text-align: center;
border-collapse:collapse;
word-break:break-all;
word-wrap:break-all;
table-layout:fixed;
th {
height: 35px;
border: 1px solid #999;}
td {
height: 35px;
border: 1px solid #999;}
}
}
//滚动条样式
::-webkit-scrollbar{
width: 5px;
background-color: white;
}
::-webkit-scrollbar-thumb{
background-color: #999;
}
//img图片列表页面
.imageList {
width: 100%;
height: 100%;
overflow-y: auto;
.imageListBox {
width: 100%;
height: 90%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.imagesBox {
width: 300px;
height: 200px;
margin: 0 11px 0 11px;
display: inline-block;
img {
border: 1px solid #999;
width: auto;
height: auto;
max-width: 100%;
height: 170px;
cursor:pointer;
}
}
}
}

538
src/app/key-unit/fire-fighting-device-look/fire-fighting-device.component.ts

@ -0,0 +1,538 @@
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http'
import { MatDialogRef, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ImgsDataDetail2 } from './addGrouping.component'
import { MatSnackBarConfig, MatSnackBar } from '@angular/material/snack-bar';
import { ImagesData2 } from './imagesdata.component'
import { Router,ActivatedRoute } from '@angular/router'
export interface Food {
value: string;
name: string;
}
@Component({
selector: 'app-fire-fighting-device-look',
templateUrl: './fire-fighting-device.component.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class FireFightingDeviceLookComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,public http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit(): void {
this.getCompanyInformation()
this.getAllBuilding()
}
//定义属性数据
singleElection:Food[]=[
{value:'true', name: '有'},
{value:'false', name: '无'}]
companyBuiltInGrouping:any = []; //单位消防设施内置分组
companyDetails:any = []; //单位详情
companyEachDetails:any = [] //单位每层详情
companyOptionalGrouping:any = []; //单位消防设施可选分组
//获得单位基本信息
getCompanyInformation () {
let companyId = this.route.snapshot.queryParams.id
this.http.get(`/api/Companies/${companyId}`).subscribe((data:any)=>{
if (data.buildingTypes.length) {
let newData = {buildingType: data.buildingTypes[0].id,companyId : companyId}
this.http.get('/api/CompanyFacilities',{params:newData}).subscribe((data:any)=>{ //获得单位的消防设施
this.companyBuiltInGrouping = data[0].summary.companyFacilityGroups
this.companyOptionalGrouping = data[0].summary.companyOptionalGroups
this.companyDetails = data[0].details
this.companyEachDetails = data[0].eachDetails
this.companyBuiltInGrouping.forEach(element => { //循环单位内置分组项
element.selectBuiltInGrouping = []
element.facilityItems.forEach((elements,index) => {
elements.total = element.facilityCount[index]
elements.expanded = false});
});
}) //http
} //if
})
}
//创建单位消防设施内置分组项
addCompanyGrouping (e) {
let data = e
let dialogRef = this.dialog.open(ImagesData2,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) { e.facilityItems.push(data) } });
}
//保存单位消防设施内置分组项
editCompanyGrouping(e) {
let header = {groupId:e.id}
let data = []
e.facilityItems.forEach((element,index) => {
let msg = {
isBuiltin: element.isBuiltin,
details: element.details,
name: element.name,
isEachFloor: element.isEachFloor,
order: element.order}
data.push(msg)
if (index==e.facilityItems.length-1) {
this.http.post('/api/CompanyFacilityItems/Batch',data,{params:header}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
}) }
}); //forEach
}
//checked单位消防设施内置分组项时
checkedCompany (e,item,items) {
if (e.checked) {
item.selectBuiltInGrouping.push(items)
} else {
item.selectBuiltInGrouping.splice(item.selectBuiltInGrouping.findIndex(oldItem => oldItem == items), 1)
}
}
//删除消防设施内置分组项
deleteCompanyGrouping (e) {
if (e.selectBuiltInGrouping.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let msg:any = `?groupId=${e.id}`
e.selectBuiltInGrouping.forEach((element,index) => {
let data = `&name=${element.name}`
msg = msg + data
if (index === e.selectBuiltInGrouping.length-1) {
this.http.delete('/api/CompanyFacilityItems/Batch' + msg).subscribe(data=>{
let deleteMsg = e.selectBuiltInGrouping
deleteMsg.forEach(deleteElement => {
e.facilityItems.splice(e.facilityItems.findIndex(item=>item.name==deleteElement.name),1)
});
e.selectBuiltInGrouping = []
}) //http
} //if
}); //forEach
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择内置分组项','确定',config);
}
}
//保存单位消防设施可选分组
editCompanyOptional (e,item) {
e.stopPropagation() //阻止冒泡
item.propertyInfos.forEach((element,index) => {
element.propertyValue = String(element.propertyValue)
if (index == item.propertyInfos.length-1 ) {
this.http.post('/api/CompanyOptionalGroups',item).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
} //if
});
}
//单位消防设施切换展开面板
SwitchBoard (e) {
e.expanded = !e.expanded
if (e.expanded) { //展开面板展开时
if (e.isEachFloor) { //逐层统计时
let data = this.companyEachDetails[e.name]
if (data) {
e.loopTable = []
data.forEach(item => {
let tableMsg = {name:item.name, header:[], body:[]}
item.assets[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
tableMsg.header.push(element.propertyName+unit)}
});
item.assets.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
}); //propertyInfos
tableMsg.body.push(everyBody)
}); //assets
e.loopTable.push(tableMsg)
});
} //data有数据时
} else { //非逐层统计时
let data = this.companyDetails[e.name]
if (data) {
e.header = []
e.body = []
data[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
e.header.push(element.propertyName+unit)}
});
data.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
});
e.body.push(everyBody)
});
}
} //非逐层统计时
}
}
allBuildingGrouping:any; //所有建筑的消防设施 内置分组+可选分组
//获取所有建筑
getAllBuilding () {
let companyId = this.route.snapshot.queryParams.id
this.http.get('/api/Buildings',{params:{
companyId:companyId
}}).subscribe((data:any)=>{
this.allBuildingGrouping = data
if (this.allBuildingGrouping.length) { this.getAllBuildingFacilities() }
})
}
//获取所有建筑的消防设施
getAllBuildingFacilities () {
let companyId = this.route.snapshot.queryParams.id
this.allBuildingGrouping.forEach(element => {
let header = {buildingId: element.id, buildingType: element.buildingTypes[0].id,companyId:companyId}
this.http.get('/api/BuildingFacilities',{params:header}).subscribe(data=>{
element.buildingFacilityGroups = data[0].summary.buildingFacilityGroups
element.buildingOptionalGroups = data[0].summary.buildingOptionalGroups
element.buildingDetails = data[0].details
element.buildingEachDetails = data[0].eachDetails
element.buildingFacilityGroups.forEach((elements) => { //循环每个建筑内置分组项
elements.selectBuiltInGrouping = []
elements.facilityItems.forEach((newElement,index) => {
newElement.total = elements.facilityCount[index]
newElement.expanded = false });
});
})
});
}
//创建建筑消防设施内置分组项
addBuildingGrouping (e,item) {
let data = {buildingId: e.id, item}
let dialogRef = this.dialog.open(ImgsDataDetail2,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) { item.facilityItems.push(data) }
});
}
//保存建筑消防设施内置分组项
editBuildingGrouping (e,item) {
let companyId = this.route.snapshot.queryParams.id
let header = {companyId:companyId,buildingId:e.id, groupId:item.id}
let data = []
item.facilityItems.forEach((element,index) => {
let msg = {
isBuiltin: element.isBuiltin,
details: element.details,
name: element.name,
isEachFloor: element.isEachFloor,
order: element.order}
data.push(msg)
if (index==item.facilityItems.length-1) {
this.http.post('/api/BuildingFacilityItems/Batch',data,{params:header}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
}) }
}); //forEach
}
//删除建筑消防设施内置分组项
deleteBuildingGrouping (e,item) {
if (item.selectBuiltInGrouping.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let msg:any = `?buildingId=${e.id}&groupId=${item.id}`
item.selectBuiltInGrouping.forEach((element,index) => {
let data = `&name=${element.name}`
msg = msg + data
if (index === item.selectBuiltInGrouping.length-1) {
this.http.delete('/api/BuildingFacilityItems/Batch'+msg).subscribe(data=>{
let deleteMsg = item.selectBuiltInGrouping
deleteMsg.forEach(deleteElement => {
item.facilityItems.splice(item.facilityItems.findIndex(items=>items.name==deleteElement.name),1)
});
item.selectBuiltInGrouping = []
}) //http
} //if
}) //forEach
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择内置分组项','确定',config);
}
}
//保存建筑消防设施可选分组
editBuildingOptional (e,item) {
let companyId = this.route.snapshot.queryParams.id
e.stopPropagation() //阻止冒泡
item.propertyInfos.forEach((element,index) => {
element.propertyValue = String(element.propertyValue)
if (index == item.propertyInfos.length-1 ) {
this.http.post('/api/BuildingOptionalGroups',item,{params:{
companyId :companyId
}}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
} //if
});
}
//建筑消防设施切换展开面板
SwitchBuildingBoard (item,e) {
e.expanded = !e.expanded
if (e.expanded) { //展开面板展开时
if (e.isEachFloor) { //逐层统计时
let data = item.buildingEachDetails[e.name]
if (data) {
e.loopTable = []
data.forEach(item => {
let tableMsg = {name:item.name, header:[], body:[]}
item.assets[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
tableMsg.header.push(element.propertyName+unit)}
});
item.assets.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
}); //propertyInfos
tableMsg.body.push(everyBody)
}); //assets
e.loopTable.push(tableMsg)
});
} //data有数据时
} else { //非逐层统计时
let data = item.buildingDetails[e.name]
if (data) {
e.header = []
e.body = []
data[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
e.header.push(element.propertyName+unit)}
});
data.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
});
e.body.push(everyBody)
});
}
} //非逐层统计时
}
}
//单位消防设施预览图片
previewImg (e) {
if (e.isEachFloor) { //逐层统计时
let newData = this.companyEachDetails[e.name]
if (newData) {
let data = {name:e.name, images:[]}
let imgName
newData.forEach(item => {
item.assets.forEach(element => {
element.propertyInfos.forEach( elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
}); //newDate
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData2,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
} else { //非逐层统计时
let newData = this.companyDetails[e.name]
let imgName
if (newData) {
let data = {name:e.name, images:[]}
newData.forEach(element => {
element.propertyInfos.forEach(elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData2,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
}
}
//建筑消防设施预览图片
previewBuildingImg (item,e) {
if (e.isEachFloor) { //逐层统计时
let newData = item.buildingEachDetails[e.name]
if (newData) {
let data = {name:e.name, images:[]}
let imgName
newData.forEach(item => {
item.assets.forEach(element => {
element.propertyInfos.forEach( elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
}); //newDate
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData2,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
} else { //非逐层统计时
let newData = item.buildingDetails[e.name]
let imgName
if (newData) {
let data = {name:e.name, images:[]}
newData.forEach(element => {
element.propertyInfos.forEach(elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)}
});
});
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData2,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
}
}
}

9
src/app/key-unit/fire-fighting-device-look/imagesdata.component.html

@ -0,0 +1,9 @@
<div class="imageList">
<div mat-dialog-title *ngIf="data">{{data.name}}</div>
<div class="imageListBox">
<div class="imagesBox" *ngFor="let item of data.images;let key = index">
<img [src]='item.newImageUrl' (click)='seeImage(key)'>
<label style="display: inline-block;width: 100%;text-align: center;">{{item.propertyName}}</label>
</div>
</div>
</div>

82
src/app/key-unit/fire-fighting-device-look/imagesdata.component.ts

@ -0,0 +1,82 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import Swiper from 'swiper';
@Component({
selector: 'imagesdata',
templateUrl: './imagesdata.component.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class ImagesData2 {
constructor(private http: HttpClient,public dialogRef: MatDialogRef<ImagesData2>,@Inject(MAT_DIALOG_DATA) public data,public dialog: MatDialog) {}
ngOnInit(): void {
this.data.images.forEach(element => {
element.newImageUrl = `${element.propertyValue}?x-oss-process=image/resize,m_fill,h_170,w_299`
});
}
//查看大图
seeImage (index) {
let data = {
allImages:this.data.images,
imgIndex: index}
let dialogRef = this.dialog.open(previewBigImg2,
{width: '1600px',
height:'900px',data});
}
}
@Component({
selector: 'previewBigImg',
templateUrl: './previewImg.html',
styleUrls: ['../realistic-picture/realistic-picture.component.scss']
})
export class previewBigImg2 {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<previewBigImg2>,
@Inject(MAT_DIALOG_DATA) public data) { }
testSwiper: Swiper;
ngOnInit(): void {
this.allImages = this.data.allImages
this.allImages.forEach(element => {
element.previewImageUrl = `${element.propertyValue}?x-oss-process=image/auto-orient,1` //处理图片URL地址
});
}
ngAfterViewInit() {
this.testSwiper = new Swiper('.swiper-container', {
lazy: true,
initialSlide: this.data.imgIndex,
direction: 'horizontal',
loop: false,
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
}
allImages:any; //展示所有的图片
rotationAngle:number=0; //旋转角度
//旋转图片
rotate () {
this.rotationAngle = this.rotationAngle+90
if (this.rotationAngle === 360) {this.rotationAngle = 0}
}
}

17
src/app/key-unit/fire-fighting-device-look/previewImg.html

@ -0,0 +1,17 @@
<div mat-dialog-title>图片详情</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide previewImgBox" *ngFor="let item of allImages">
<img [attr.data-src]="item.previewImageUrl" class="swiper-lazy" [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270}">
<div class="swiper-lazy-preloader"></div>
</div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
</div>

69
src/app/key-unit/fire-fighting-device/addGrouping.component.ts

@ -0,0 +1,69 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
@Component({
selector: 'imgsdatadetail',
templateUrl: './addGrouping.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class ImgsDataDetail {
constructor(private http: HttpClient,public dialogRef: MatDialogRef<ImgsDataDetail>,@Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar) {}
ngOnInit(): void {
}
ngAfterViewInit(): void{
}
//提交表单
onSubmit (e) {
if (this.data.buildingId) { //建筑新建内置项
let repeat = this.data.item.facilityItems.find(items=>items.name==e.name)
if (repeat==undefined) {
let header = {buildingId:this.data.buildingId, groupId:this.data.item.id}
let msg = {
isBuiltin: false,
details: '',
name: e.name,
isEachFloor: false,
order: this.data.item.facilityItems.length? this.data.item.facilityItems[this.data.item.facilityItems.length-1].order+1 : 0}
this.http.post('/api/CompanyAccount/BuildingFacilityItems',msg,{params:header}).subscribe(data=>{
this.dialogRef.close(data); })
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('当前分组下禁止创建名称相同内置项','确定',config);
}
} else { //单位新建内置项
let repeat = this.data.facilityItems.find(item=>item.name==e.name)
if (repeat==undefined) {
let header = {groupId:this.data.id}
let msg = {
isBuiltin: false,
details: '',
name: e.name,
isEachFloor: false,
order: this.data.facilityItems.length? this.data.facilityItems[this.data.facilityItems.length-1].order+1 : 0}
this.http.post('/api/CompanyAccount/CompanyFacilityItems',msg,{params:header}).subscribe(data=>{
this.dialogRef.close(data); })
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('当前分组下禁止创建名称相同内置项','确定',config);
}
} //else
}
}

18
src/app/key-unit/fire-fighting-device/addGrouping.html

@ -0,0 +1,18 @@
<div mat-dialog-title>创建消防设施内置项</div>
<div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<input matInput placeholder="请输入消防设施内置项名称" required ngModel name="name" maxlength="30">
</mat-form-field>
<p style="font-size: 14px; color: red; margin-bottom: 15px;">*注: 该名称不允许与当前分组内置项重名</p>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit"
[disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

193
src/app/key-unit/fire-fighting-device/fire-fighting-device.component.html

@ -0,0 +1,193 @@
<div class="content">
<mat-tab-group>
<mat-tab label="单位消防设施">
<div class="contentBox">
<p style="width: 100%; margin: 30px auto; text-align: center;" *ngIf="!companyBuiltInGrouping.length">暂无数据,请完善单位基本信息</p>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of companyBuiltInGrouping;let key = index">
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<div style="margin-bottom: 10px;">
<mat-icon title="创建" (click)='addCompanyGrouping(item)'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editCompanyGrouping(item)'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='deleteCompanyGrouping(item)'>delete</mat-icon>
</div>
<div>
<mat-accordion multi>
<mat-expansion-panel disabled>
<mat-expansion-panel-header>
<label class="firstContent"></label>
<label class="textContent">项目</label>
<label class="textContent">照片</label>
<label class="totalContent">总数</label>
<label class="lastTextContent">主要情况</label>
</mat-expansion-panel-header>
</mat-expansion-panel>
<mat-expansion-panel *ngFor="let items of item.facilityItems" disabled [expanded]=items.expanded>
<mat-expansion-panel-header>
<label class="firstContent">
<mat-checkbox (change)='checkedCompany($event,item,items)' [disabled]='items.isBuiltin'></mat-checkbox>
</label>
<label class="textContent">{{items.name}}</label>
<label class="textContent"><a href="javascript:void(0)" (click)='previewImg(items)'>查看图片</a></label>
<label class="totalContent">{{items.total ? items.total : '总数: 0'}}</label>
<label class="lastTextContent">
<textarea maxlength="250" [(ngModel)]="items.details" style="width: 80%;"></textarea>
</label>
<label><mat-icon (click)='SwitchBoard(items)' *ngIf="items.isBuiltin">keyboard_arrow_down</mat-icon></label>
</mat-expansion-panel-header>
<div class="overflowTable">
<div class="detailsTable">
<table>
<tr>
<th *ngFor="let header of items.header">{{header}}</th>
</tr>
<tr *ngFor="let body of items.body">
<td *ngFor="let header of items.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
<div *ngFor="let tableMsg of items.loopTable" class="detailsTable">
<p style="text-align: center; font-size: 16px; margin: 5px 0;">楼层/区域名称: {{tableMsg.name? tableMsg.name: '暂无名称'}}</p>
<table>
<tr>
<th *ngFor="let header of tableMsg.header">{{header}}</th>
</tr>
<tr *ngFor="let body of tableMsg.body">
<td *ngFor="let header of tableMsg.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of companyOptionalGrouping;let key = index">
<mat-accordion multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editCompanyOptional($event,item)'>description</mat-icon>
</mat-expansion-panel-header>
<div *ngFor="let items of item.propertyInfos" class="InputField">
<label>{{items.propertyName}}:</label>
<input type="text" *ngIf="items.propertyType!=1&&items.propertyType!=2&&items.propertyType!=4&&items.propertyType!=6"
[(ngModel)]="items.propertyValue" name="propertyValue">
<textarea maxlength="250" *ngIf="items.propertyType==1" [(ngModel)]="items.propertyValue" name="propertyValue"></textarea>
<input type="number" *ngIf="items.propertyType==2 ||items.propertyType==4" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-group *ngIf="items.propertyType==6" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-button style="margin-left: 5px;" [value]='radio.value' *ngFor="let radio of singleElection">{{radio.name}}</mat-radio-button>
</mat-radio-group>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
</mat-tab>
<mat-tab label="{{newItem.name}}" *ngFor="let newItem of allBuildingGrouping">
<div class="contentBox">
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of newItem.buildingFacilityGroups">
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<div style="margin-bottom: 10px;">
<mat-icon title="创建" (click)='addBuildingGrouping(newItem,item)'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editBuildingGrouping(newItem,item)'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='deleteBuildingGrouping(newItem,item)'>delete</mat-icon>
</div>
<div>
<mat-accordion multi>
<mat-expansion-panel disabled>
<mat-expansion-panel-header>
<label class="firstContent"></label>
<label class="textContent">项目</label>
<label class="textContent">照片</label>
<label class="totalContent">总数</label>
<label class="lastTextContent">主要情况</label>
</mat-expansion-panel-header>
</mat-expansion-panel>
<mat-expansion-panel *ngFor="let items of item.facilityItems" disabled [expanded]=items.expanded>
<mat-expansion-panel-header>
<label class="firstContent">
<mat-checkbox (change)='checkedCompany($event,item,items)' [disabled]='items.isBuiltin'></mat-checkbox>
</label>
<label class="textContent">{{items.name}}</label>
<label class="textContent"><a href="javascript:void(0)" (click)='previewBuildingImg(newItem,items)'>查看图片</a></label>
<label class="totalContent">{{items.total ? items.total : '总数: 0'}}</label>
<label class="lastTextContent">
<textarea maxlength="250" [(ngModel)]="items.details" style="width: 80%;"></textarea>
</label>
<label><mat-icon (click)='SwitchBuildingBoard(newItem,items)' *ngIf="items.isBuiltin">keyboard_arrow_down</mat-icon></label>
</mat-expansion-panel-header>
<div class="overflowTable">
<div class="detailsTable">
<table>
<tr>
<th *ngFor="let header of items.header">{{header}}</th>
</tr>
<tr *ngFor="let body of items.body">
<td *ngFor="let header of items.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
<div *ngFor="let tableMsg of items.loopTable" class="detailsTable">
<p style="text-align: center; font-size: 16px; margin: 5px 0;">楼层/区域名称: {{tableMsg.name? tableMsg.name : '暂无名称'}}</p>
<table>
<tr>
<th *ngFor="let header of tableMsg.header">{{header}}</th>
</tr>
<tr *ngFor="let body of tableMsg.body">
<td *ngFor="let header of tableMsg.header">{{body[header]? body[header] : '暂无数据'}}</td>
</tr>
</table>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div style="width: 100%;margin-top: 25px;" *ngFor="let item of newItem.buildingOptionalGroups">
<mat-accordion multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<h3 style="text-align: center;font-weight: 550;">{{item.name}}</h3>
<mat-icon title="保存" style="margin-left: 25px;" (click)='editBuildingOptional($event,item)'>description</mat-icon>
</mat-expansion-panel-header>
<div *ngFor="let items of item.propertyInfos" class="InputField">
<label>{{items.propertyName}}:</label>
<input type="text" *ngIf="items.propertyType!=1&&items.propertyType!=2&&items.propertyType!=4&&items.propertyType!=6"
[(ngModel)]="items.propertyValue" name="propertyValue">
<textarea maxlength="250" *ngIf="items.propertyType==1" [(ngModel)]="items.propertyValue" name="propertyValue"></textarea>
<input type="number" *ngIf="items.propertyType==2 ||items.propertyType==4" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-group *ngIf="items.propertyType==6" [(ngModel)]="items.propertyValue" name="propertyValue">
<mat-radio-button style="margin-left: 5px;" [value]='radio.value' *ngFor="let radio of singleElection">{{radio.name}}</mat-radio-button>
</mat-radio-group>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>

145
src/app/key-unit/fire-fighting-device/fire-fighting-device.component.scss

@ -0,0 +1,145 @@
.content {
width: 100%;
height: 90%;
padding: 10px;
overflow-y: auto;
.contentBox {
width: 90%;
height: 100%;
margin: 0 auto;
overflow-y: auto;
}
}
.mat-icon {
color: black;
cursor:pointer;
}
//可展开面板每一行css
.mat-expansion-panel-header {
padding: 3px 24px;
}
.firstContent {
width: 3%;
}
.textContent {
width: 12%;
color: black;
text-align: center;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.totalContent {
width: 25%;
color: black;
text-align: center;
white-space: pre-line;
max-height: 48px;
overflow-y: auto;
}
.lastTextContent { //textarea多行文本
width: 45%;
color: black;
text-align: center;
}
input {
height: 22px;
line-height: 22px;
padding-left: 5px;
border-radius: 3px;
}
a {
color: #0000ff;
}
//bottom用户输入框
.InputField {
display: inline-block;
width: 40%;
text-align: right;
margin: 10px 25px;
input {width: 60%;}
label {margin-right: 10px;}
}
textarea {
vertical-align: middle;
border-radius: 5px;
padding: 5px;
width: 60%;
height: 36px;
resize: none;
}
//表格样式
.overflowTable {
width: 95%;
margin: 0 auto;
max-height: 300px;
overflow-y: auto;
}
.detailsTable {
margin: 10px 0;
table {
width: 100%;
text-align: center;
border-collapse:collapse;
word-break:break-all;
word-wrap:break-all;
table-layout:fixed;
th {
height: 35px;
border: 1px solid #999;}
td {
height: 35px;
border: 1px solid #999;}
}
}
//滚动条样式
::-webkit-scrollbar{
width: 5px;
background-color: white;
}
::-webkit-scrollbar-thumb{
background-color: #999;
}
//img图片列表页面
.imageList {
width: 100%;
height: 100%;
overflow-y: auto;
.imageListBox {
width: 100%;
height: 90%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.imagesBox {
width: 300px;
height: 200px;
margin: 0 11px 0 11px;
display: inline-block;
img {
border: 1px solid #999;
width: auto;
height: auto;
max-width: 100%;
height: 170px;
cursor:pointer;
}
}
}
}

538
src/app/key-unit/fire-fighting-device/fire-fighting-device.component.ts

@ -0,0 +1,538 @@
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http'
import { MatDialogRef, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ImgsDataDetail } from './addGrouping.component'
import { MatSnackBarConfig, MatSnackBar } from '@angular/material/snack-bar';
import { ImagesData } from './imagesdata.component'
import { Router,ActivatedRoute } from '@angular/router'
export interface Food {
value: string;
name: string;
}
@Component({
selector: 'app-fire-fighting-device',
templateUrl: './fire-fighting-device.component.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class FireFightingDeviceComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,public http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit(): void {
this.getCompanyInformation()
this.getAllBuilding()
}
//定义属性数据
singleElection:Food[]=[
{value:'true', name: '有'},
{value:'false', name: '无'}]
companyBuiltInGrouping:any = []; //单位消防设施内置分组
companyDetails:any = []; //单位详情
companyEachDetails:any = [] //单位每层详情
companyOptionalGrouping:any = []; //单位消防设施可选分组
//获得单位基本信息
getCompanyInformation () {
let companyId = this.route.snapshot.queryParams.id
this.http.get(`/api/Companies/${companyId}`).subscribe((data:any)=>{
if (data.buildingTypes.length) {
let newData = {buildingType: data.buildingTypes[0].id,companyId : companyId}
this.http.get('/api/CompanyFacilities',{params:newData}).subscribe((data:any)=>{ //获得单位的消防设施
this.companyBuiltInGrouping = data[0].summary.companyFacilityGroups
this.companyOptionalGrouping = data[0].summary.companyOptionalGroups
this.companyDetails = data[0].details
this.companyEachDetails = data[0].eachDetails
this.companyBuiltInGrouping.forEach(element => { //循环单位内置分组项
element.selectBuiltInGrouping = []
element.facilityItems.forEach((elements,index) => {
elements.total = element.facilityCount[index]
elements.expanded = false});
});
}) //http
} //if
})
}
//创建单位消防设施内置分组项
addCompanyGrouping (e) {
let data = e
let dialogRef = this.dialog.open(ImgsDataDetail,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) { e.facilityItems.push(data) } });
}
//保存单位消防设施内置分组项
editCompanyGrouping(e) {
let header = {groupId:e.id}
let data = []
e.facilityItems.forEach((element,index) => {
let msg = {
isBuiltin: element.isBuiltin,
details: element.details,
name: element.name,
isEachFloor: element.isEachFloor,
order: element.order}
data.push(msg)
if (index==e.facilityItems.length-1) {
this.http.post('/api/CompanyFacilityItems/Batch',data,{params:header}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
}) }
}); //forEach
}
//checked单位消防设施内置分组项时
checkedCompany (e,item,items) {
if (e.checked) {
item.selectBuiltInGrouping.push(items)
} else {
item.selectBuiltInGrouping.splice(item.selectBuiltInGrouping.findIndex(oldItem => oldItem == items), 1)
}
}
//删除消防设施内置分组项
deleteCompanyGrouping (e) {
if (e.selectBuiltInGrouping.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let msg:any = `?groupId=${e.id}`
e.selectBuiltInGrouping.forEach((element,index) => {
let data = `&name=${element.name}`
msg = msg + data
if (index === e.selectBuiltInGrouping.length-1) {
this.http.delete('/api/CompanyFacilityItems/Batch' + msg).subscribe(data=>{
let deleteMsg = e.selectBuiltInGrouping
deleteMsg.forEach(deleteElement => {
e.facilityItems.splice(e.facilityItems.findIndex(item=>item.name==deleteElement.name),1)
});
e.selectBuiltInGrouping = []
}) //http
} //if
}); //forEach
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择内置分组项','确定',config);
}
}
//保存单位消防设施可选分组
editCompanyOptional (e,item) {
e.stopPropagation() //阻止冒泡
item.propertyInfos.forEach((element,index) => {
element.propertyValue = String(element.propertyValue)
if (index == item.propertyInfos.length-1 ) {
this.http.post('/api/CompanyOptionalGroups',item).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
} //if
});
}
//单位消防设施切换展开面板
SwitchBoard (e) {
e.expanded = !e.expanded
if (e.expanded) { //展开面板展开时
if (e.isEachFloor) { //逐层统计时
let data = this.companyEachDetails[e.name]
if (data) {
e.loopTable = []
data.forEach(item => {
let tableMsg = {name:item.name, header:[], body:[]}
item.assets[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
tableMsg.header.push(element.propertyName+unit)}
});
item.assets.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
}); //propertyInfos
tableMsg.body.push(everyBody)
}); //assets
e.loopTable.push(tableMsg)
});
} //data有数据时
} else { //非逐层统计时
let data = this.companyDetails[e.name]
if (data) {
e.header = []
e.body = []
data[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
e.header.push(element.propertyName+unit)}
});
data.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
});
e.body.push(everyBody)
});
}
} //非逐层统计时
}
}
allBuildingGrouping:any; //所有建筑的消防设施 内置分组+可选分组
//获取所有建筑
getAllBuilding () {
let companyId = this.route.snapshot.queryParams.id
this.http.get('/api/Buildings',{params:{
companyId:companyId
}}).subscribe((data:any)=>{
this.allBuildingGrouping = data
if (this.allBuildingGrouping.length) { this.getAllBuildingFacilities() }
})
}
//获取所有建筑的消防设施
getAllBuildingFacilities () {
let companyId = this.route.snapshot.queryParams.id
this.allBuildingGrouping.forEach(element => {
let header = {buildingId: element.id, buildingType: element.buildingTypes[0].id,companyId:companyId}
this.http.get('/api/BuildingFacilities',{params:header}).subscribe(data=>{
element.buildingFacilityGroups = data[0].summary.buildingFacilityGroups
element.buildingOptionalGroups = data[0].summary.buildingOptionalGroups
element.buildingDetails = data[0].details
element.buildingEachDetails = data[0].eachDetails
element.buildingFacilityGroups.forEach((elements) => { //循环每个建筑内置分组项
elements.selectBuiltInGrouping = []
elements.facilityItems.forEach((newElement,index) => {
newElement.total = elements.facilityCount[index]
newElement.expanded = false });
});
})
});
}
//创建建筑消防设施内置分组项
addBuildingGrouping (e,item) {
let data = {buildingId: e.id, item}
let dialogRef = this.dialog.open(ImgsDataDetail,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) { item.facilityItems.push(data) }
});
}
//保存建筑消防设施内置分组项
editBuildingGrouping (e,item) {
let companyId = this.route.snapshot.queryParams.id
let header = {companyId:companyId,buildingId:e.id, groupId:item.id}
let data = []
item.facilityItems.forEach((element,index) => {
let msg = {
isBuiltin: element.isBuiltin,
details: element.details,
name: element.name,
isEachFloor: element.isEachFloor,
order: element.order}
data.push(msg)
if (index==item.facilityItems.length-1) {
this.http.post('/api/BuildingFacilityItems/Batch',data,{params:header}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
}) }
}); //forEach
}
//删除建筑消防设施内置分组项
deleteBuildingGrouping (e,item) {
if (item.selectBuiltInGrouping.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let msg:any = `?buildingId=${e.id}&groupId=${item.id}`
item.selectBuiltInGrouping.forEach((element,index) => {
let data = `&name=${element.name}`
msg = msg + data
if (index === item.selectBuiltInGrouping.length-1) {
this.http.delete('/api/BuildingFacilityItems/Batch'+msg).subscribe(data=>{
let deleteMsg = item.selectBuiltInGrouping
deleteMsg.forEach(deleteElement => {
item.facilityItems.splice(item.facilityItems.findIndex(items=>items.name==deleteElement.name),1)
});
item.selectBuiltInGrouping = []
}) //http
} //if
}) //forEach
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择内置分组项','确定',config);
}
}
//保存建筑消防设施可选分组
editBuildingOptional (e,item) {
let companyId = this.route.snapshot.queryParams.id
e.stopPropagation() //阻止冒泡
item.propertyInfos.forEach((element,index) => {
element.propertyValue = String(element.propertyValue)
if (index == item.propertyInfos.length-1 ) {
this.http.post('/api/BuildingOptionalGroups',item,{params:{
companyId :companyId
}}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
} //if
});
}
//建筑消防设施切换展开面板
SwitchBuildingBoard (item,e) {
e.expanded = !e.expanded
if (e.expanded) { //展开面板展开时
if (e.isEachFloor) { //逐层统计时
let data = item.buildingEachDetails[e.name]
if (data) {
e.loopTable = []
data.forEach(item => {
let tableMsg = {name:item.name, header:[], body:[]}
item.assets[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
tableMsg.header.push(element.propertyName+unit)}
});
item.assets.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
}); //propertyInfos
tableMsg.body.push(everyBody)
}); //assets
e.loopTable.push(tableMsg)
});
} //data有数据时
} else { //非逐层统计时
let data = item.buildingDetails[e.name]
if (data) {
e.header = []
e.body = []
data[0].propertyInfos.forEach(element => { //表头
if (element.propertyType!=3) {
let unit = element.physicalUnit? '('+ element.physicalUnit +')' : '' //单位
e.header.push(element.propertyName+unit)}
});
data.forEach(element => { //表格内容
let everyBody = {}
element.propertyInfos.forEach((elements,index) => {
if (elements.propertyType!=3 && elements.propertyName!='图片' && elements.propertyType!=6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue }
if (elements.propertyType==6) {
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = elements.propertyValue=='1'?'是':'否' }
if (elements.propertyType!=3 && elements.propertyName=='图片') {
let imgLength = []
element.propertyInfos.find(item=>{ if(item.propertyType==3){imgLength.push(item)} })
let unit = elements.physicalUnit? '('+ elements.physicalUnit +')' : '' //单位
everyBody[elements.propertyName+unit] = String(imgLength.length) }
});
e.body.push(everyBody)
});
}
} //非逐层统计时
}
}
//单位消防设施预览图片
previewImg (e) {
if (e.isEachFloor) { //逐层统计时
let newData = this.companyEachDetails[e.name]
if (newData) {
let data = {name:e.name, images:[]}
let imgName
newData.forEach(item => {
item.assets.forEach(element => {
element.propertyInfos.forEach( elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
}); //newDate
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
} else { //非逐层统计时
let newData = this.companyDetails[e.name]
let imgName
if (newData) {
let data = {name:e.name, images:[]}
newData.forEach(element => {
element.propertyInfos.forEach(elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
}
}
//建筑消防设施预览图片
previewBuildingImg (item,e) {
if (e.isEachFloor) { //逐层统计时
let newData = item.buildingEachDetails[e.name]
if (newData) {
let data = {name:e.name, images:[]}
let imgName
newData.forEach(item => {
item.assets.forEach(element => {
element.propertyInfos.forEach( elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)} });
});
}); //newDate
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
} else { //非逐层统计时
let newData = item.buildingDetails[e.name]
let imgName
if (newData) {
let data = {name:e.name, images:[]}
newData.forEach(element => {
element.propertyInfos.forEach(elements => {
if (elements.propertyName.includes('名称')) {imgName = elements.propertyValue}
if (elements.propertyType===3) {
elements.propertyName = imgName
data.images.push(elements)}
});
});
if (data.images.length) {
let dialogRef = this.dialog.open(ImagesData,{width:'1350px',height:'700px',data}); //打开图片弹窗
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config); }
}
}
}

9
src/app/key-unit/fire-fighting-device/imagesdata.component.html

@ -0,0 +1,9 @@
<div class="imageList">
<div mat-dialog-title *ngIf="data">{{data.name}}</div>
<div class="imageListBox">
<div class="imagesBox" *ngFor="let item of data.images;let key = index">
<img [src]='item.newImageUrl' (click)='seeImage(key)'>
<label style="display: inline-block;width: 100%;text-align: center;">{{item.propertyName}}</label>
</div>
</div>
</div>

82
src/app/key-unit/fire-fighting-device/imagesdata.component.ts

@ -0,0 +1,82 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import Swiper from 'swiper';
@Component({
selector: 'imagesdata',
templateUrl: './imagesdata.component.html',
styleUrls: ['./fire-fighting-device.component.scss']
})
export class ImagesData {
constructor(private http: HttpClient,public dialogRef: MatDialogRef<ImagesData>,@Inject(MAT_DIALOG_DATA) public data,public dialog: MatDialog) {}
ngOnInit(): void {
this.data.images.forEach(element => {
element.newImageUrl = `${element.propertyValue}?x-oss-process=image/resize,m_fill,h_170,w_299`
});
}
//查看大图
seeImage (index) {
let data = {
allImages:this.data.images,
imgIndex: index}
let dialogRef = this.dialog.open(previewBigImg,
{width: '1600px',
height:'900px',data});
}
}
@Component({
selector: 'previewBigImg',
templateUrl: './previewImg.html',
styleUrls: ['../realistic-picture/realistic-picture.component.scss']
})
export class previewBigImg {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<previewBigImg>,
@Inject(MAT_DIALOG_DATA) public data) { }
testSwiper: Swiper;
ngOnInit(): void {
this.allImages = this.data.allImages
this.allImages.forEach(element => {
element.previewImageUrl = `${element.propertyValue}?x-oss-process=image/auto-orient,1` //处理图片URL地址
});
}
ngAfterViewInit() {
this.testSwiper = new Swiper('.swiper-container', {
lazy: true,
initialSlide: this.data.imgIndex,
direction: 'horizontal',
loop: false,
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
}
allImages:any; //展示所有的图片
rotationAngle:number=0; //旋转角度
//旋转图片
rotate () {
this.rotationAngle = this.rotationAngle+90
if (this.rotationAngle === 360) {this.rotationAngle = 0}
}
}

17
src/app/key-unit/fire-fighting-device/previewImg.html

@ -0,0 +1,17 @@
<div mat-dialog-title>图片详情</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide previewImgBox" *ngFor="let item of allImages">
<img [attr.data-src]="item.previewImageUrl" class="swiper-lazy" [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270}">
<div class="swiper-lazy-preloader"></div>
</div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
</div>

23
src/app/key-unit/function-division-look/addPartition.html

@ -0,0 +1,23 @@
<div mat-dialog-title>创建建筑功能分区</div>
<div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<mat-select [(value)]="selected" required ngModel name="buildingId" placeholder="建筑名称:">
<mat-option *ngFor="let item of data" [value]="item.id">
{{item.name}}
</mat-option>
</mat-select>
</mat-form-field>
<p style="font-size: 14px;" *ngIf="!data.length">暂无数据,请您创建基本信息建筑模块</p>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit"
[disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

0
src/app/key-unit/function-division-look/addPartitionAttribute.html

106
src/app/key-unit/function-division-look/function-division.component.html

@ -0,0 +1,106 @@
<div class="content">
<div style="margin-top:16px">
<!-- <mat-icon title="创建" (click)='addPartition()'>add_circle_outline</mat-icon> -->
</div>
<mat-tab-group class="tableContent">
<mat-tab label="单位功能分区">
<div style="overflow: auto; height: 100%;">
<div style="margin: 30px 0 25px 5%;">
<!-- <mat-icon title="创建" (click)='addCompany()'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='preservation()'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='delete()'>delete</mat-icon> -->
</div>
<table mat-table [dataSource]="companyFunctionalZoning">
<ng-container matColumnDef="checked">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<mat-checkbox disabled (change)='changeCompany(element,$event)'></mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="region">
<th mat-header-cell *matHeaderCellDef>区域</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input readonly matInput [(ngModel)]="element.region" type="text" maxlength="20">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="measure">
<th mat-header-cell *matHeaderCellDef>面积</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input readonly matInput type="number" [(ngModel)]="element.area" onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" placeholder="请输入数字">
</mat-form-field>
<label style="margin-left: 5px;"></label>
</td>
</ng-container>
<ng-container matColumnDef="situation">
<th mat-header-cell *matHeaderCellDef>基本情况</th>
<td mat-cell *matCellDef="let element">
<textarea readonly [(ngModel)]="element.details" maxlength="250"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<p style="width: 100%; margin-top: 30px; text-align: center;" *ngIf="!companyFunctionalZoning.length">暂无数据</p>
</div>
</mat-tab>
<mat-tab label="{{item.name}}" *ngFor="let item of allBuildingFunctionalZoning;let key = index">
<div style="overflow: auto; height: 100%;">
<div style="margin: 30px 0 25px 5%;">
<!-- <mat-icon title="创建" (click)='addBuilding(item,key)'>add_circle_outline</mat-icon>
<mat-icon title="保存" (click)='preservationBuilding(item,key)' style="margin-left: 25px;">description</mat-icon>
<mat-icon title="删除" (click)='deleteBuilding(item,key)' style="margin-left: 25px;">delete</mat-icon> -->
</div>
<table mat-table [dataSource]="item.functionalZoning">
<ng-container matColumnDef="checked">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<mat-checkbox disabled (change)='changeBuilding(element,$event,key)'></mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="region">
<th mat-header-cell *matHeaderCellDef>区域</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input readonly matInput [(ngModel)]="element.region" type="text" maxlength="20">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="measure">
<th mat-header-cell *matHeaderCellDef>面积</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input readonly matInput type="number" [(ngModel)]="element.area" onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" placeholder="请输入数字">
</mat-form-field>
<label style="margin-left: 5px;"></label>
</td>
</ng-container>
<ng-container matColumnDef="situation">
<th mat-header-cell *matHeaderCellDef>基本情况</th>
<td mat-cell *matCellDef="let element">
<textarea readonly [(ngModel)]="element.details" maxlength="250"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</mat-tab>
</mat-tab-group>
</div>

32
src/app/key-unit/function-division-look/function-division.component.scss

@ -0,0 +1,32 @@
.content {
width: 100%;
height: 90%;
overflow-y: auto;
padding: 10px 0 0 10px;
display: flex;
}
.tableContent {
margin-left: 10px;
width: 100%;
height: 100%;
table {
width: 90%;
text-align: center;
margin: 0 auto;
.cdk-header-cell {
text-align: center;
}
textarea {
border-radius: 5px;
padding: 5px;
width: 80%;
height: 36px;
resize: none;
}
}
}
//icon统一样式
.mat-icon {
cursor:pointer;
}

247
src/app/key-unit/function-division-look/function-division.component.ts

@ -0,0 +1,247 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { Router,ActivatedRoute } from '@angular/router'
@Component({
selector: 'app-function-division-look',
templateUrl: './function-division.component.html',
styleUrls: ['./function-division.component.scss']
})
export class FunctionDivisionLookComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,private http:HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit(): void {
this.companyId = this.route.snapshot.queryParams.id
this.getAllCompany()
this.getAllBuilding()
}
displayedColumns: string[] = ['checked', 'region', 'measure', 'situation'];
companyId:any; //单位编号
companyFunctionalZoning:any=[]; //所有单位功能分区属性
selectFunctionalZoning:any=[]; //选中的单位功能分区属性
//获得所有单位功能分区属性
getAllCompany () {
let companyId = this.route.snapshot.queryParams.id
this.http.get('/api/CompanyFunctionalDivisions',{params:{
companyId:companyId
}}).subscribe((data:any)=>{
this.companyFunctionalZoning = data
this.selectFunctionalZoning = []
})
}
//新建单位功能分区属性
addCompany () {
let companyId = this.route.snapshot.queryParams.id
let data = {companyId:companyId, region:'', area:0, details:''}
this.companyFunctionalZoning.push(data)
this.preservation()
}
//保存单位功能分区属性
preservation () {
let companyId = this.route.snapshot.queryParams.id
// console.log(123,companyId)
if (this.companyFunctionalZoning.length) {
this.http.post('/api/CompanyFunctionalDivisions/Batch',this.companyFunctionalZoning,{params:{
companyId:companyId
}}).subscribe(data=>{
this.getAllCompany()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
}
}
//单位功能分区checked选择
changeCompany (ele,e) {
if (e.checked) {
this.selectFunctionalZoning.push(ele.id)
} else {
this.selectFunctionalZoning.splice(this.selectFunctionalZoning.findIndex(item => item === ele.id), 1)
}
}
//删除单位功能分区属性
delete () {
let companyId = this.route.snapshot.queryParams.id
if (this.selectFunctionalZoning.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
this.http.post('/api/CompanyFunctionalDivisions/Batch',this.companyFunctionalZoning,{params:{
companyId:companyId
}}).subscribe(data=>{
const options = {
headers: new HttpHeaders({'Content-Type': 'application/json',}),
body:this.selectFunctionalZoning}
this.http.delete(`/api/CompanyFunctionalDivisions/Batch`,options).subscribe(data=>{
this.getAllCompany()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
})
}
} else if (!this.selectFunctionalZoning.length) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择单位功能分区','确定',config);
}
}
//建筑功能分区↓
allBuilding:any = []; //所有建筑
allBuildingFunctionalZoning:any = []; //所有建筑的功能分区
selectBuildingFunctionalZoning:any = []; //选中的建筑的功能分区
//获得所有建筑
getAllBuilding () {
let companyId = this.route.snapshot.queryParams.id
this.http.get(`/api/Buildings`,{params:{
companyId:companyId
}}).subscribe((data:any)=>{
if (data.length) {
this.allBuilding = data
this.allBuilding.forEach(element => { //为每个建筑添加一个 功能分区对象
element.functionalZoning = null
});
this.getAllBuildingFunctionalZoning()
}
})
}
//获得所有建筑的功能分区
getAllBuildingFunctionalZoning () {
this.selectBuildingFunctionalZoning = []
this.allBuildingFunctionalZoning = []
this.allBuilding.forEach(element => {
let data={buildingId: element.id}
this.http.get(`/api/BuildingFunctionalDivisions`,{params:data}).subscribe((data:any)=>{
if (data.length) {
element.functionalZoning = data
this.selectBuildingFunctionalZoning.push([]) //拥有建筑功能分区的提前push空数组
this.allBuildingFunctionalZoning.push(element) }
})
});
}
//封装函数刷新当前建筑功能分区
updateCurrent (e,index) {
let data= {buildingId: e.id}
this.http.get(`/api/BuildingFunctionalDivisions`,{params:data}).subscribe((data:any)=>{
this.selectBuildingFunctionalZoning[index] = []
this.allBuildingFunctionalZoning[index].functionalZoning = data
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
}
//创建建筑功能分区
addPartition () {
}
//创建建筑功能分区属性
addBuilding (e,index) {
let data = {buildingId:e.id, region:'', area:0, details:''}
this.http.post('/api/BuildingFunctionalDivisions',data).subscribe(data=>{
this.preservationBuilding(e,index)
})
}
//保存建筑功能分区属性
preservationBuilding (e,index) {
let data ={buildingId:e.id}
this.http.post(`/api/BuildingFunctionalDivisions/Batch`,this.allBuildingFunctionalZoning[index].functionalZoning,{params:data}).subscribe(data=>{
this.updateCurrent(e,index)
})
}
//建筑功能分区checked选择
changeBuilding (ele,e,index) {
if (e.checked) {
this.selectBuildingFunctionalZoning[index].push(ele.id)
} else {
this.selectBuildingFunctionalZoning[index].splice(this.selectBuildingFunctionalZoning[index].findIndex(item => item === ele.id), 1)
}
}
//删除建筑功能分区
deleteBuilding (e,index) {
if (this.selectBuildingFunctionalZoning[index].length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let data ={buildingId:e.id}
this.http.post(`/api/BuildingFunctionalDivisions/Batch`,this.allBuildingFunctionalZoning[index].functionalZoning,{params:data}).subscribe(data=>{
const options = {
headers: new HttpHeaders({'Content-Type': 'application/json',}),
body:this.selectBuildingFunctionalZoning[index],
params:{buildingId:e.id}}
this.http.delete(`/api/BuildingFunctionalDivisions/Batch`,options).subscribe(data=>{
this.selectBuildingFunctionalZoning[index].forEach((element,newIndex) => {
this.allBuildingFunctionalZoning[index].functionalZoning.splice(this.allBuildingFunctionalZoning[index].functionalZoning.findIndex(item=>item.id==element),1)
if (newIndex==this.selectBuildingFunctionalZoning[index].length-1) {
if (this.allBuildingFunctionalZoning[index].functionalZoning.length) {
this.updateCurrent(e,index)
} else {
this.selectBuildingFunctionalZoning.splice(index,1)
this.allBuildingFunctionalZoning.splice(index,1)}
}
});
})
})
}
} else if (!this.selectBuildingFunctionalZoning[index].length) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择建筑功能分区','确定',config);
}
}
}
//暂时无用
@Component({
selector: 'app-addPartitionAttribute',
templateUrl: './addPartitionAttribute.html',
styleUrls: ['./function-division.component.scss']
})
export class addPartitionAttribute2 {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<addPartitionAttribute2>,
@Inject(MAT_DIALOG_DATA) public data) { }
ngOnInit(): void {
}
}

23
src/app/key-unit/function-division/addPartition.html

@ -0,0 +1,23 @@
<div mat-dialog-title>创建建筑功能分区</div>
<div>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<mat-select [(value)]="selected" required ngModel name="buildingId" placeholder="建筑名称:">
<mat-option *ngFor="let item of buildings" [value]="item.id">
{{item.name}}
</mat-option>
</mat-select>
</mat-form-field>
<p style="font-size: 14px;" *ngIf="!buildings.length">暂无数据,请您创建基本信息建筑模块</p>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit"
[disabled]="!form.form.valid">
确定
</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>
</form>
</div>

0
src/app/key-unit/function-division/addPartitionAttribute.html

106
src/app/key-unit/function-division/function-division.component.html

@ -0,0 +1,106 @@
<div class="content">
<div style="margin-top:16px">
<mat-icon title="创建" (click)='addPartition()'>add_circle_outline</mat-icon>
</div>
<mat-tab-group class="tableContent">
<mat-tab label="单位功能分区">
<div style="overflow: auto; height: 100%;">
<div style="margin: 30px 0 25px 5%;">
<mat-icon title="创建" (click)='addCompany()'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;" (click)='preservation()'>description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;" (click)='delete()'>delete</mat-icon>
</div>
<table mat-table [dataSource]="companyFunctionalZoning">
<ng-container matColumnDef="checked">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<mat-checkbox (change)='changeCompany(element,$event)'></mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="region">
<th mat-header-cell *matHeaderCellDef>区域</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input matInput [(ngModel)]="element.region" type="text" maxlength="20">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="measure">
<th mat-header-cell *matHeaderCellDef>面积</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input matInput type="number" [(ngModel)]="element.area" onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" placeholder="请输入数字">
</mat-form-field>
<label style="margin-left: 5px;"></label>
</td>
</ng-container>
<ng-container matColumnDef="situation">
<th mat-header-cell *matHeaderCellDef>基本情况</th>
<td mat-cell *matCellDef="let element">
<textarea [(ngModel)]="element.details" maxlength="250"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<p style="width: 100%; margin-top: 30px; text-align: center;" *ngIf="!companyFunctionalZoning.length">暂无数据</p>
</div>
</mat-tab>
<mat-tab label="{{item.name}}" *ngFor="let item of allBuildingFunctionalZoning;let key = index">
<div style="overflow: auto; height: 100%;">
<div style="margin: 30px 0 25px 5%;">
<mat-icon title="创建" (click)='addBuilding(item,key)'>add_circle_outline</mat-icon>
<mat-icon title="保存" (click)='preservationBuilding(item,key)' style="margin-left: 25px;">description</mat-icon>
<mat-icon title="删除" (click)='deleteBuilding(item,key)' style="margin-left: 25px;">delete</mat-icon>
</div>
<table mat-table [dataSource]="item.functionalZoning">
<ng-container matColumnDef="checked">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<mat-checkbox (change)='changeBuilding(element,$event,key)'></mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="region">
<th mat-header-cell *matHeaderCellDef>区域</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input matInput [(ngModel)]="element.region" type="text" maxlength="20">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="measure">
<th mat-header-cell *matHeaderCellDef>面积</th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="example-full-width">
<input matInput type="number" [(ngModel)]="element.area" onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" placeholder="请输入数字">
</mat-form-field>
<label style="margin-left: 5px;"></label>
</td>
</ng-container>
<ng-container matColumnDef="situation">
<th mat-header-cell *matHeaderCellDef>基本情况</th>
<td mat-cell *matCellDef="let element">
<textarea [(ngModel)]="element.details" maxlength="250"></textarea>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</mat-tab>
</mat-tab-group>
</div>

32
src/app/key-unit/function-division/function-division.component.scss

@ -0,0 +1,32 @@
.content {
width: 100%;
height: 90%;
overflow-y: auto;
padding: 10px 0 0 10px;
display: flex;
}
.tableContent {
margin-left: 10px;
width: 100%;
height: 100%;
table {
width: 90%;
text-align: center;
margin: 0 auto;
.cdk-header-cell {
text-align: center;
}
textarea {
border-radius: 5px;
padding: 5px;
width: 80%;
height: 36px;
resize: none;
}
}
}
//icon统一样式
.mat-icon {
cursor:pointer;
}

25
src/app/key-unit/function-division/function-division.component.spec.ts

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

293
src/app/key-unit/function-division/function-division.component.ts

@ -0,0 +1,293 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { Router,ActivatedRoute } from '@angular/router'
@Component({
selector: 'app-function-division',
templateUrl: './function-division.component.html',
styleUrls: ['./function-division.component.scss']
})
export class FunctionDivisionComponent implements OnInit {
constructor(private router:Router,private route:ActivatedRoute,private http:HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit(): void {
this.companyId = this.route.snapshot.queryParams.id
this.getAllCompany()
this.getAllBuilding()
}
displayedColumns: string[] = ['checked', 'region', 'measure', 'situation'];
companyId:any; //单位编号
companyFunctionalZoning:any=[]; //所有单位功能分区属性
selectFunctionalZoning:any=[]; //选中的单位功能分区属性
//获得所有单位功能分区属性
getAllCompany () {
let companyId = this.route.snapshot.queryParams.id
this.http.get('/api/CompanyFunctionalDivisions',{params:{
companyId:companyId
}}).subscribe((data:any)=>{
this.companyFunctionalZoning = data
this.selectFunctionalZoning = []
})
}
//新建单位功能分区属性
addCompany () {
let companyId = this.route.snapshot.queryParams.id
let data = {companyId:companyId, region:'', area:0, details:''}
this.companyFunctionalZoning.push(data)
this.preservation()
}
//保存单位功能分区属性
preservation () {
let companyId = this.route.snapshot.queryParams.id
// console.log(123,companyId)
if (this.companyFunctionalZoning.length) {
this.http.post('/api/CompanyFunctionalDivisions/Batch',this.companyFunctionalZoning,{params:{
companyId:companyId
}}).subscribe(data=>{
this.getAllCompany()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
}
}
//单位功能分区checked选择
changeCompany (ele,e) {
if (e.checked) {
this.selectFunctionalZoning.push(ele.id)
} else {
this.selectFunctionalZoning.splice(this.selectFunctionalZoning.findIndex(item => item === ele.id), 1)
}
}
//删除单位功能分区属性
delete () {
let companyId = this.route.snapshot.queryParams.id
if (this.selectFunctionalZoning.length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
this.http.post('/api/CompanyFunctionalDivisions/Batch',this.companyFunctionalZoning,{params:{
companyId:companyId
}}).subscribe(data=>{
const options = {
headers: new HttpHeaders({'Content-Type': 'application/json',}),
body:this.selectFunctionalZoning}
this.http.delete(`/api/CompanyFunctionalDivisions/Batch`,options).subscribe(data=>{
this.getAllCompany()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
})
}
} else if (!this.selectFunctionalZoning.length) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择单位功能分区','确定',config);
}
}
//建筑功能分区↓
allBuilding:any = []; //所有建筑
allBuildingFunctionalZoning:any = []; //所有建筑的功能分区
selectBuildingFunctionalZoning:any = []; //选中的建筑的功能分区
//获得所有建筑
getAllBuilding () {
let companyId = this.route.snapshot.queryParams.id
this.http.get(`/api/Buildings`,{params:{
companyId:companyId
}}).subscribe((data:any)=>{
if (data.length) {
this.allBuilding = data
this.allBuilding.forEach(element => { //为每个建筑添加一个 功能分区对象
element.functionalZoning = null
});
this.getAllBuildingFunctionalZoning()
}
})
}
//获得所有建筑的功能分区
getAllBuildingFunctionalZoning () {
this.selectBuildingFunctionalZoning = []
this.allBuildingFunctionalZoning = []
this.allBuilding.forEach(element => {
let data={buildingId: element.id}
this.http.get(`/api/BuildingFunctionalDivisions`,{params:data}).subscribe((data:any)=>{
if (data.length) {
element.functionalZoning = data
this.selectBuildingFunctionalZoning.push([]) //拥有建筑功能分区的提前push空数组
this.allBuildingFunctionalZoning.push(element) }
})
});
}
//封装函数刷新当前建筑功能分区
updateCurrent (e,index) {
let data= {buildingId: e.id}
this.http.get(`/api/BuildingFunctionalDivisions`,{params:data}).subscribe((data:any)=>{
this.selectBuildingFunctionalZoning[index] = []
this.allBuildingFunctionalZoning[index].functionalZoning = data
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据更新成功','确定',config);
})
}
//创建建筑功能分区
addPartition () {
let data = this.allBuilding
let dialogRef = this.dialog.open(addPartition,{data:{
allBuilding:this.allBuilding,
companyId:this.companyId
}});
dialogRef.afterClosed().subscribe(data=>{
if (data) {this.getAllBuilding()}
});
}
//创建建筑功能分区属性
addBuilding (e,index) {
let data = {buildingId:e.id, region:'', area:0, details:''}
this.http.post('/api/BuildingFunctionalDivisions',data,{params:{
companyId : this.companyId
}}).subscribe(data=>{
this.preservationBuilding(e,index)
})
}
//保存建筑功能分区属性
preservationBuilding (e,index) {
let data ={buildingId:e.id,companyId : this.companyId}
this.http.post(`/api/BuildingFunctionalDivisions/Batch`,this.allBuildingFunctionalZoning[index].functionalZoning,{params:data}).subscribe(data=>{
this.updateCurrent(e,index)
})
}
//建筑功能分区checked选择
changeBuilding (ele,e,index) {
if (e.checked) {
this.selectBuildingFunctionalZoning[index].push(ele.id)
} else {
this.selectBuildingFunctionalZoning[index].splice(this.selectBuildingFunctionalZoning[index].findIndex(item => item === ele.id), 1)
}
}
//删除建筑功能分区
deleteBuilding (e,index) {
if (this.selectBuildingFunctionalZoning[index].length) {
let isDelete = confirm('您确定要删除吗')
if (isDelete) {
let data ={buildingId:e.id,companyId : this.companyId}
this.http.post(`/api/BuildingFunctionalDivisions/Batch`,this.allBuildingFunctionalZoning[index].functionalZoning,{params:data}).subscribe(data=>{
const options = {
headers: new HttpHeaders({'Content-Type': 'application/json',}),
body:this.selectBuildingFunctionalZoning[index],
params:{buildingId:e.id}}
this.http.delete(`/api/BuildingFunctionalDivisions/Batch`,options).subscribe(data=>{
this.selectBuildingFunctionalZoning[index].forEach((element,newIndex) => {
this.allBuildingFunctionalZoning[index].functionalZoning.splice(this.allBuildingFunctionalZoning[index].functionalZoning.findIndex(item=>item.id==element),1)
if (newIndex==this.selectBuildingFunctionalZoning[index].length-1) {
if (this.allBuildingFunctionalZoning[index].functionalZoning.length) {
this.updateCurrent(e,index)
} else {
this.selectBuildingFunctionalZoning.splice(index,1)
this.allBuildingFunctionalZoning.splice(index,1)}
}
});
})
})
}
} else if (!this.selectBuildingFunctionalZoning[index].length) {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择建筑功能分区','确定',config);
}
}
}
//创建建筑功能分区组件
@Component({
selector: 'app-addPartition',
templateUrl: './addPartition.html',
styleUrls: ['./function-division.component.scss']
})
export class addPartition {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<addPartition>,
@Inject(MAT_DIALOG_DATA) public data) { }
buildings:any
ngOnInit(): void {
this.buildings = this.data.allBuilding
}
selected:any; //选中的建筑
//创建建筑功能分区
onSubmit (e) {
let data = {
buildingId:e.buildingId,
region: "",
area: 0,
details: ""
}
this.http.post('/api/BuildingFunctionalDivisions',data,{params:{
companyId : this.data.companyId
}}).subscribe(data=>{
this.dialogRef.close(data);
})
}
}
//暂时无用
@Component({
selector: 'app-addPartitionAttribute',
templateUrl: './addPartitionAttribute.html',
styleUrls: ['./function-division.component.scss']
})
export class addPartitionAttribute {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<addPartitionAttribute>,
@Inject(MAT_DIALOG_DATA) public data) { }
ngOnInit(): void {
}
}

120
src/app/key-unit/key-site-look/key-site.component.html

@ -0,0 +1,120 @@
<div class="content">
<mat-tab-group style="height: 100%;">
<mat-tab label="单位重点部位">
<div class="contentBox">
<div style="margin-top: 25px;">
<h3 style="text-align: center;font-weight: 550;">重点部位情况</h3>
<table mat-table [dataSource]="allCompanyPosition">
<ng-container matColumnDef="mainname">
<th mat-header-cell *matHeaderCellDef>重点部位名称</th>
<td mat-cell *matCellDef="let element">
{{element.name}}
</td>
</ng-container>
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>重点部位所在位置</th>
<td mat-cell *matCellDef="let element">
{{element.position}}
</td>
</ng-container>
<ng-container matColumnDef="construction">
<th mat-header-cell *matHeaderCellDef>建筑结构</th>
<td mat-cell *matCellDef="let element">
{{element.structure}}
</td>
</ng-container>
<ng-container matColumnDef="nature">
<th mat-header-cell *matHeaderCellDef>使用性质</th>
<td mat-cell *matCellDef="let element">
{{element.nature}}
</td>
</ng-container>
<ng-container matColumnDef="danger">
<th mat-header-cell *matHeaderCellDef>主要危险性</th>
<td mat-cell *matCellDef="let element">
{{element.hazards}}
</td>
</ng-container>
<ng-container matColumnDef="img">
<th mat-header-cell *matHeaderCellDef>图片</th>
<td mat-cell *matCellDef="let element">
<a href="javascript:void(0);" (click)='seeImg(element.imageUrls)' style="color: blue;">查看图片</a>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<p style="text-align: center;" *ngIf="!allCompanyPosition.length">暂无数据,请前往平面图进行相关数据录入</p>
</div>
<div style="margin-top: 25px; text-align: left;">
<h3 style="text-align: center;font-weight: 550;">重点提示</h3>
<!-- <mat-icon title="保存" style="margin-left: 11%; cursor: pointer;" (click)='Preservation()'>description</mat-icon> -->
<p class="tips">
<textarea readonly [(ngModel)]="companyInput" maxlength="500"></textarea>
</p>
</div>
</div>
</mat-tab>
<mat-tab label="{{item.name}}" *ngFor="let item of allBuilding">
<div class="contentBox">
<div style="margin-top: 25px;">
<h3 style="text-align: center;font-weight: 550;">重点部位情况</h3>
<table mat-table [dataSource]="item.position">
<ng-container matColumnDef="mainname">
<th mat-header-cell *matHeaderCellDef>重点部位名称</th>
<td mat-cell *matCellDef="let element">
{{element.name}}
</td>
</ng-container>
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>重点部位所在位置</th>
<td mat-cell *matCellDef="let element">
{{element.position}}
</td>
</ng-container>
<ng-container matColumnDef="construction">
<th mat-header-cell *matHeaderCellDef>建筑结构</th>
<td mat-cell *matCellDef="let element">
{{element.structure}}
</td>
</ng-container>
<ng-container matColumnDef="nature">
<th mat-header-cell *matHeaderCellDef>使用性质</th>
<td mat-cell *matCellDef="let element">
{{element.nature}}
</td>
</ng-container>
<ng-container matColumnDef="danger">
<th mat-header-cell *matHeaderCellDef>主要危险性</th>
<td mat-cell *matCellDef="let element">
{{element.hazards}}
</td>
</ng-container>
<ng-container matColumnDef="img">
<th mat-header-cell *matHeaderCellDef>图片</th>
<td mat-cell *matCellDef="let element">
<a href="javascript:void(0);" (click)='seeImg(element.imageUrls)' style="color: blue;">查看图片</a>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<p style="text-align: center;" *ngIf="!item.position.length">暂无数据,请前往平面图进行相关数据录入</p>
</div>
<div style="margin-top: 25px; text-align: left;">
<h3 style="text-align: center;font-weight: 550;">重点提示</h3>
<!-- <mat-icon title="保存" style="margin-left: 11%;cursor: pointer;" (click)='PreservationBuilding(item)'>description</mat-icon> -->
<p class="tips">
<textarea readonly [(ngModel)]="item.companyInput" maxlength="500"></textarea>
</p>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>

58
src/app/key-unit/key-site-look/key-site.component.scss

@ -0,0 +1,58 @@
.content {
width: 100%;
height: 90%;
padding: 10px;
overflow-y: auto;
.contentBox{
width: 100%;
height: 100%;
overflow-y: auto;
text-align: center;
margin: 0 auto;
}
}
table {
width: 90%;
margin: 15px auto;
text-align: center;
.cdk-header-cell {
text-align: center;
}
}
//重点提示
.tips{
width: 75%;
height: 150px;
border: 1px solid black;
border-radius: 5px;
margin: 15px auto;
text-align: center;
padding: 25px;
textarea {
resize: none;
width: 100%;
height: 100%;
}
}
//预览图片旋转角度
.rotateA {transform: rotate(90deg) scale(0.75);}
.rotateB {transform: rotate(180deg)}
.rotateC {transform: rotate(270deg) scale(0.75);}
//预览图片
.previewImgBox {
width: 1500px;
height: 700px;
text-align: center;
img{
width: auto;
height: auto;
max-width: 100%;
height: 100%;}
}
.previewImgBottom {
text-align: center;
height: 30px;
margin: 20px auto;
}

173
src/app/key-unit/key-site-look/key-site.component.ts

@ -0,0 +1,173 @@
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import { MatDialogRef, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { KeySiteImgs2 } from './keysiteimgs.component'
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-key-site-look',
templateUrl: './key-site.component.html',
styleUrls: ['./key-site.component.scss']
})
export class KeySiteLookComponent implements OnInit {
constructor(public http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar,private route:ActivatedRoute,) { }
displayedColumns: string[] = ['mainname', 'position', 'construction', 'nature', 'danger', 'img'];
ngOnInit(): void {
this.getCompanyPostion()
this.getCompanyTips()
this.getAllBuilding()
}
allCompanyPosition:any = []; //所有单位重点部位
companyTips:any; //所有单位重点提示
companyInput:any; //单位重点提示数据
allBuilding:any = []; //所有建筑 + 建筑重点部位 + 建筑重点提示
//获取单位重点部位
getCompanyPostion () {
let id = {companyId:this.route.snapshot.queryParams.id}
this.http.get('/api/CompanyImportantLocations',{params:id}).subscribe(data=>{
this.allCompanyPosition = data
})
}
//获取单位重点提示
getCompanyTips () {
let id = {companyId:this.route.snapshot.queryParams.id}
this.http.get('/api/CompanyImportantTips',{params:id}).subscribe((data:any)=>{
if (data) {
this.companyTips = data
this.companyInput = data.details}
})
}
//获取所有建筑
getAllBuilding () {
let id = {companyId:this.route.snapshot.queryParams.id}
this.http.get('/api/Buildings',{params:id}).subscribe((data:any)=>{
if (data.length) {
this.allBuilding = data
this.allBuilding.forEach(element => {
element.position = [] //建筑重点部位
element.tips = null //建筑重点提示
element.companyInput = null }) //建筑重点提示数据
this.getAllBuildingPositon()
this.getAllBuildingTips()
}
})
}
//获取所有建筑重点部位
getAllBuildingPositon () {
this.allBuilding.forEach(element => {
let id = {buildingId:element.id}
this.http.get('/api/BuildingImportantLocations',{params:id}).subscribe(data=>{
element.position = data
})
});
}
//获取所有建筑重点提示
getAllBuildingTips () {
this.allBuilding.forEach(element => {
let id = {buildingId:element.id}
this.http.get('/api/BuildingImportantTips',{params:id}).subscribe((data:any)=>{
if (data) {
element.tips = data
element.companyInput = data.details}
})
});
}
//保存单位重点提示
Preservation () {
if (this.companyTips) { //编辑单位重点提示
let data = {
companyId: this.companyTips.companyId,
id: this.companyTips.id,
details: this.companyInput}
this.http.put(`/api/CompanyImportantTips/${this.companyTips.id}`,data).subscribe(data=>{
this.getCompanyTips()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据修改成功','确定',config);
})
} else { //新增单位重点提示
let data = {
companyId: this.route.snapshot.queryParams.id,
id : "",
details: this.companyInput || ""}
this.http.post('/api/CompanyImportantTips',data).subscribe(data=>{
this.getCompanyTips()
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据修改成功','确定',config);
})
}
}
//保存建筑重点提示
PreservationBuilding (e) {
if (e.tips) { //编辑建筑重点提示
let data = {
buildingId: e.id,
id: e.tips.id,
details: e.companyInput}
this.http.put(`/api/BuildingImportantTips/${e.tips.id}`,data).subscribe(data=>{
this.toUpdate(e)
})
} else { //新增重点单位提示
let data = {
buildingId: e.id,
details: e.companyInput || ""}
this.http.post('/api/BuildingImportantTips',data).subscribe(data=>{
this.toUpdate(e)
})
}
}
//查看图片
seeImg (e) {
if (e.length) {
let data = e
const dialogRef = this.dialog.open(KeySiteImgs2, {//调用open方法打开对话框并且携带参数过去
width: '1600px',
height:'900px',data});
dialogRef.afterClosed().subscribe();
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('暂无图片数据','确定',config);
}
}
//封装方法获取更新当前tab页重点提示
toUpdate (e) {
let id = {buildingId:e.id}
this.http.get('/api/BuildingImportantTips',{params:id}).subscribe((data:any)=>{
if (data) {
this.allBuilding.forEach(element => {
if (element.id === e.id) {
element.tips = data
element.companyInput = data.details}
});
} // if
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('数据修改成功','确定',config);
})
}
}

0
src/app/key-unit/key-site-look/keyimgdetail.component.html

17
src/app/key-unit/key-site-look/keyimgdetail.component.ts

@ -0,0 +1,17 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import Swiper from 'swiper';
@Component({
selector: 'keyimgdetail',
templateUrl: './keyimgdetail.component.html',
styleUrls: ['./key-site.component.scss']
})
export class KeyImgDetail {
}

18
src/app/key-unit/key-site-look/keysiteimgs.component.html

@ -0,0 +1,18 @@
<div mat-dialog-title>图片详情</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div *ngFor="let item of allImages" class="swiper-slide previewImgBox">
<img [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270} " class="swiper-lazy"
[attr.data-src]="item">
<div class="swiper-lazy-preloader"></div>
</div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
</div>

55
src/app/key-unit/key-site-look/keysiteimgs.component.ts

@ -0,0 +1,55 @@
import { Component, OnInit, Inject ,ViewChild} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import Swiper from 'swiper';
@Component({
selector: 'keysiteimgs',
templateUrl: './keysiteimgs.component.html',
styleUrls: ['./key-site.component.scss']
})
export class KeySiteImgs2 {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<KeySiteImgs2>,
@Inject(MAT_DIALOG_DATA) public data) { }
testSwiper: Swiper;
ngOnInit(): void {
this.allImages = []
this.data.forEach(element => {
element = `${element}?x-oss-process=image/auto-orient,1`
this.allImages.push(element)
});
}
ngAfterViewInit() {
this.testSwiper = new Swiper('.swiper-container', {
direction: 'horizontal',
loop: false,
lazy: true,
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
}
allImages:any; //展示所有的图片
rotationAngle:number=0; //旋转角度
//旋转图片
rotate () {
this.rotationAngle = this.rotationAngle+90
if (this.rotationAngle === 360) {this.rotationAngle = 0}
}
}

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

Loading…
Cancel
Save