Browse Source

[完善] 上海采集平台仓库初始化

master
陈鹏飞 4 years ago
commit
cf9b0f7331
  1. 13
      .editorconfig
  2. 46
      .gitignore
  3. 15
      .vscode/launch.json
  4. 2
      README.md
  5. 140
      angular.json
  6. 12
      browserslist
  7. 7
      debug.log
  8. BIN
      doc_workingArea/beginPaint.gif
  9. 79
      doc_workingArea/readme.md
  10. BIN
      doc_workingArea/selected.gif
  11. 32
      e2e/protractor.conf.js
  12. 23
      e2e/src/app.e2e-spec.ts
  13. 11
      e2e/src/app.po.ts
  14. 13
      e2e/tsconfig.json
  15. 32
      karma.conf.js
  16. 18441
      package-lock.json
  17. 68
      package.json
  18. 7
      proxy.config.json
  19. 27
      reset.css
  20. 5098
      src/app/_theming.scss
  21. 32
      src/app/app-routing.module.ts
  22. 1
      src/app/app.component.html
  23. 0
      src/app/app.component.scss
  24. 35
      src/app/app.component.spec.ts
  25. 44
      src/app/app.component.ts
  26. 47
      src/app/app.module.ts
  27. 33
      src/app/auth.guard.ts
  28. 756
      src/app/canvas-share-data.service.ts
  29. 1
      src/app/home/home.component.html
  30. 0
      src/app/home/home.component.scss
  31. 25
      src/app/home/home.component.spec.ts
  32. 18
      src/app/home/home.component.ts
  33. 85
      src/app/http-interceptors/base-interceptor.ts
  34. 44
      src/app/http-interceptors/cache-token.service.ts
  35. 9
      src/app/http-interceptors/index.ts
  36. 38
      src/app/http-interceptors/tree.service.ts
  37. 19
      src/app/interface.ts
  38. 6
      src/app/m-token-k1/m-token-k1.component.html
  39. 3
      src/app/m-token-k1/m-token-k1.component.scss
  40. 97
      src/app/m-token-k1/m-token-k1.component.ts
  41. 62
      src/app/m-token-k1/m-token-k1.service.ts
  42. 43
      src/app/navigation/navigation.component.html
  43. 150
      src/app/navigation/navigation.component.scss
  44. 25
      src/app/navigation/navigation.component.spec.ts
  45. 31
      src/app/navigation/navigation.component.ts
  46. 114
      src/app/navigation/navigation.module.ts
  47. 28
      src/app/pages/lockscreen/lockscreen.component.html
  48. 111
      src/app/pages/lockscreen/lockscreen.component.scss
  49. 25
      src/app/pages/lockscreen/lockscreen.component.spec.ts
  50. 20
      src/app/pages/lockscreen/lockscreen.component.ts
  51. 49
      src/app/pages/login/login.component.html
  52. 89
      src/app/pages/login/login.component.scss
  53. 25
      src/app/pages/login/login.component.spec.ts
  54. 53
      src/app/pages/login/login.component.ts
  55. 17
      src/app/pages/pages-routing.module.ts
  56. 1
      src/app/pages/pages.component.html
  57. 0
      src/app/pages/pages.component.scss
  58. 25
      src/app/pages/pages.component.spec.ts
  59. 15
      src/app/pages/pages.component.ts
  60. 112
      src/app/pages/pages.module.ts
  61. 280
      src/app/pages/personaldata/personaldata.component.html
  62. 110
      src/app/pages/personaldata/personaldata.component.scss
  63. 25
      src/app/pages/personaldata/personaldata.component.spec.ts
  64. 15
      src/app/pages/personaldata/personaldata.component.ts
  65. 94
      src/app/pages/register/register.component.html
  66. 91
      src/app/pages/register/register.component.scss
  67. 25
      src/app/pages/register/register.component.spec.ts
  68. 43
      src/app/pages/register/register.component.ts
  69. 13
      src/app/pipes/boolean.pipe.ts
  70. 9
      src/app/pipes/time.pipe.ts
  71. 16
      src/app/tabbar/help-file.service.spec.ts
  72. 81
      src/app/tabbar/help-file.service.ts
  73. 74
      src/app/tabbar/tabbar.component.html
  74. 45
      src/app/tabbar/tabbar.component.scss
  75. 25
      src/app/tabbar/tabbar.component.spec.ts
  76. 132
      src/app/tabbar/tabbar.component.ts
  77. 18
      src/app/theme.scss
  78. 78
      src/app/ui/allaround/allaround.component.html
  79. 54
      src/app/ui/allaround/allaround.component.scss
  80. 25
      src/app/ui/allaround/allaround.component.spec.ts
  81. 75
      src/app/ui/allaround/allaround.component.ts
  82. 18
      src/app/ui/allaround/imgdetails.component.html
  83. 54
      src/app/ui/allaround/imgdetails.component.ts
  84. 23
      src/app/ui/authority/authority.component.html
  85. 30
      src/app/ui/authority/authority.component.scss
  86. 139
      src/app/ui/authority/authority.component.ts
  87. 36
      src/app/ui/authority/createauthority.component.html
  88. 25
      src/app/ui/basicinfo/addhouseinfo.component.html
  89. 69
      src/app/ui/basicinfo/addhouseinfo.component.ts
  90. 554
      src/app/ui/basicinfo/basicinfo.component.html
  91. 294
      src/app/ui/basicinfo/basicinfo.component.scss
  92. 25
      src/app/ui/basicinfo/basicinfo.component.spec.ts
  93. 2220
      src/app/ui/basicinfo/basicinfo.component.ts
  94. 26
      src/app/ui/basicinfo/lookmaster.component.html
  95. 66
      src/app/ui/basicinfo/lookmaster.component.ts
  96. 12
      src/app/ui/card/card.component.html
  97. 10
      src/app/ui/card/card.component.scss
  98. 25
      src/app/ui/card/card.component.spec.ts
  99. 15
      src/app/ui/card/card.component.ts
  100. 48
      src/app/ui/changepassword/changepassword.component.html
  101. Some files were not shown because too many files have changed in this diff Show More

13
.editorconfig

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

46
.gitignore vendored

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

15
.vscode/launch.json vendored

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

2
README.md

@ -0,0 +1,2 @@
# AX.Angular9DataCollection

140
angular.json

@ -0,0 +1,140 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"anxin119": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss",
"spec": false
}
},
"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",
"./node_modules/swiper/js/swiper.min.js",
"src/assets/mTokenK1/mToken_K1.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": false
}
}

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'.

7
debug.log

@ -0,0 +1,7 @@
[1214/094922.722:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1215/082617.914:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1215/093432.367:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1217/083219.853:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1217/102235.409:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1217/162245.895:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1217/165122.912:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)

BIN
doc_workingArea/beginPaint.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

79
doc_workingArea/readme.md

@ -0,0 +1,79 @@
# 推荐使用Typora查看此文档
### Angular组件中引用组件
demo.component.html
```html
<app-working-area #workingArea></app-working-area>
```
demo.component.ts
```tsx
import {WorkingAreaComponent} from 'working-area/working-area.component'
export class DemoComponent implements OnInit {
@ViewChild('workingArea')
private workingArea: WorkingAreaComponent;
}
```
### 刷新背景图图片
根据共享服务中{选择楼层数据} 图片地址是否为空加载显示或隐藏
```tsx
this.workingArea.refreshBackgroundImage();
```
### 开始绘制
根据共享服务中{选择模板数据}准备绘制图形
```tsx
this.workingArea.beginPaint();
```
![](beginPaint.gif)
### 监听选中/取消选中
当图标被选中/取消选中时触发
```tsx
// 监听workingArea组件选中素材事件
this.workingArea.on("select",obj=>{
// obj为选中的绘制对象,assetData为共享数据中该对象对应数据的引用,也可以通过assetData的ID自行查找,旧数据已经可以兼容使用(在Unity版本中创建绘制对象,现在应该可以正常显示加载,传递数据),开始绘制创建数据还没有添加到共享数据中。
})
// 监听workingArea组件取消选中素材事件
this.workingArea.on("deselect ",obj=>{
// 同select
})
```
![](selected.gif)
### 刷新工作区
根据共享服务中{选择楼层数据}{建筑数据}绘制图标,同时会刷新背景图
```tsx
this.workingArea.refresh();
```
调用该函数后,如果共享数据中的{选择楼层数据}{建筑数据}Version是1.0,则数据会被修改为2.0数据,但并没有修改共享数据中isChange=true(待定)
### 设置名称显示/隐藏
```tsx
/**
* 设置名称显示
* @param value true 显示 false 隐藏
* @param mode BasicInformation = 0 基本信息 Assignment想定作业 = 1 想定作业
*/
this.workingArea.setNameVisible(true, 0);
this.workingArea.setNameVisible(false, 0);
```

BIN
doc_workingArea/selected.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

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
});
};

18441
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 --port 4000 ",
"build": "ng build --prod",
"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.2.1",
"angular-calendar": "^0.28.2",
"bson-objectid": "^1.3.1",
"cesium": "^1.64.0",
"date-fns": "^2.9.0",
"e-ngx-cesium": "^6.3.2",
"echarts": "^4.6.0",
"firebase": "^7.6.2",
"ng2-file-upload": "^1.4.0",
"ngx-cookie-service": "^3.0.2",
"ngx-countdown": "^11.0.0",
"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.6",
"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:8008",
"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

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

@ -0,0 +1,32 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { RegisterComponent } from './pages/register/register.component';
import { NavigationComponent } from './navigation/navigation.component';
//路由守卫
import {AuthGuard} from './auth.guard'
import { MTokenK1Component } from './m-token-k1/m-token-k1.component';
const routes: Routes = [
{path:'',redirectTo:'login',pathMatch:'full'},
{
path:'',
component:NavigationComponent,
canActivate: [AuthGuard],//守卫验证
children:[
{path:'datacollection',loadChildren:() => import('./ui/ui.module').then(m => m.UiModule)}
]},
{path:'login', component:LoginComponent}, //登录页
{path:'register', component:RegisterComponent,}, //注册页
];
@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!');
});
});

44
src/app/app.component.ts

@ -0,0 +1,44 @@
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'//引入服务
import { CookieService } from 'ngx-cookie-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,private cookieService: CookieService) { }
ngOnInit(): void {
var token = this.cookieService.get("token")
var refreshToken = this.cookieService.get("refreshToken");
if(token && refreshToken) {
this.http.post(
'/api/CompanyAccount/RefreshToken',
{
token: token,
refreshToken: refreshToken
}
).subscribe(
(data: Data) => {
sessionStorage.setItem("token",data.token);
this.cookieService.set("token",data.token,null,'/');
this.cookieService.set("refreshToken",data.refreshToken,null,'/');
this.token.startUp()
}
)
}
}
}

47
src/app/app.module.ts

@ -0,0 +1,47 @@
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 { CookieService } from 'ngx-cookie-service';//cookie插件
import { CountdownModule } from 'ngx-countdown'; //倒计时插件
import { MTokenK1Component } from './m-token-k1/m-token-k1.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
MTokenK1Component
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatButtonModule,
MatCheckboxModule,
MatSidenavModule,
NavigationModule,
MatIconModule,
PagesModule,
FormsModule,
HttpClientModule,
CountdownModule
],
providers: [httpInterceptorProviders, CacheTokenService,TreeService,CookieService],
bootstrap: [AppComponent]
})
export class AppModule { }

33
src/app/auth.guard.ts

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

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

@ -0,0 +1,756 @@
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 updateBuildingData() {
// 删除建筑数据中当前层数据
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
if (this.originalcompanyBuildingData.data[key].FloorId === this.selectStorey.id) {
delete this.originalcompanyBuildingData.data[key];
}
});
// 新增当前层数据到建筑数据
Object.keys(this.originaleveryStoreyData.data).forEach((key) => {
this.originalcompanyBuildingData.data[key] = this.originaleveryStoreyData.data[key];
});
}
/**
*
*/
public deleteBuildingDataByCurrentFloorData():void {
Object.keys(this.originaleveryStoreyData.data).forEach((key) => {
// 删除建筑数据
delete this.originalcompanyBuildingData.data[key];
});
}
/**
*
*/
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;
}

1
src/app/home/home.component.html

@ -0,0 +1 @@
<app-navigation></app-navigation>

0
src/app/home/home.component.scss

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();
});
});

18
src/app/home/home.component.ts

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

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

@ -0,0 +1,85 @@
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';
import { CookieService } from 'ngx-cookie-service';
//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,private cookieService: CookieService) {}
intercept(req, next: HttpHandler) {
let newReq = req.clone({
url: req.hadBaseurl ? `${req.url}` : `${req.url}`,
});
if(!req.cancelToken) {
/*获取token*/
let token = this.cookieService.get("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.cookieService.set("token",'',new Date(new Date().getTime() + 1),'/')
this.cookieService.set("refreshToken",'',new Date(new Date().getTime() + 1),'/')
this.snackBar.open('用户认证信息过期,请重新登录', '确定', {
duration: 3000
});
this.router.navigate(['/login'])
}
if (error.status === 403) {
this.snackBar.open('对不起,您无此权限!', '确定', {
duration: 3000
});
}
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);
};
}

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

@ -0,0 +1,44 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { CookieService } from 'ngx-cookie-service';
@Injectable({
providedIn: 'root'
})
export class CacheTokenService {
constructor(private http:HttpClient,private cookieService: CookieService) { }
public timer;
//刷新token令牌定时器
startUp = ():void=>{
window.clearInterval(this.timer)
this.timer = window.setInterval( ()=>{
var token = this.cookieService.get("token");
var refreshToken = this.cookieService.get("refreshToken");
this.http.post('/api/CompanyAccount/RefreshToken', {
token: token,
refreshToken: refreshToken
}).subscribe( (data:any) => {
sessionStorage.setItem("token",data.token);
this.cookieService.set("token",data.token,null,'/');
this.cookieService.set("refreshToken",data.refreshToken,null,'/');
})
} ,18*60*1000)
}
//删除定时器
delete = ():void=> {
window.clearInterval(this.timer)
}
createTime = (time:string)=>{
var newtime = time.substr(0,4) + '年' + time.substr(5,2) + '月' + time.substr(8,2) + '日' + time.substr(11,8)
}
}

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;
}
}

19
src/app/interface.ts

@ -0,0 +1,19 @@
export interface Data {
token:string,
refreshToken:string,
expires: number,
realName:string
}
export interface windows {
token:string
}
export enum isno {
"是",
"否"
}
export interface House {
name:string,
type:string,
space:string
}

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

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

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

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

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

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

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

@ -0,0 +1,62 @@
import { Injectable } from '@angular/core';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { Router } from '@angular/router';
declare var mToken : any;
@Injectable({
providedIn: 'root'
})
export class MTokenK1Service {
constructor(public snackBar: MatSnackBar,private router: Router,) { }
public mTokenK1Timer; //定时器查询
K1mToken = new mToken("mTokenPlugin")
keyBase64 = '5YyX5Lqs5a6J5L+h4oCU5LqM57u06aKE5qGI57yW5Yi25bel5YW3d2Vi'; //秘钥验证base64字符
password='12345678'; //秘钥验证用户密码
public verificationURL = '/login' //验证url地址是否为验证页面
public verificationURLTwo = '/register' //验证url地址是否为验证页面
//验证秘钥定时器
startUp = ():void=>{
window.clearInterval(this.mTokenK1Timer)
this.mTokenK1Timer = window.setInterval( ()=>{
let url = this.router.url
if (url == this.verificationURL || url == this.verificationURLTwo) {
} else {
this.K1mToken.LoadLibrary()
let keyIndex = this.K1mToken.K1_mTokenFindDevice() //查找秘钥是否插入
if (keyIndex < 1) { //秘钥被拔出
this.goToEdit()
} else if (keyIndex > 0) { //秘钥存在
let keyUID = this.K1mToken.K1_mTokenGetUID(keyIndex) //读取秘钥UID
let isLogin = this.K1mToken.K1_mTokenOpen(keyUID,this.password)
if (isLogin==0) { //密码验证成功
let keyMSG = window.atob( this.K1mToken.K1_mTokenReadUserStorage(keyUID,0,56) )
if (keyMSG!=this.keyBase64) { //base64转码 验证失败
this.goToEdit() }
} else { //密码验证失败
this.goToEdit()
}
}
}
},10000)
}
//秘钥拔出,删除验证定时器,跳转页面
goToEdit () {
window.clearInterval(this.mTokenK1Timer) //删除定时器
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('密钥已被拔出,即将跳转页面','确定',config);
let that = this
window.setTimeout(()=>{
that.router.navigate(['/login'])
},5000)
}
}

43
src/app/navigation/navigation.component.html

@ -0,0 +1,43 @@
<!-- <app-tabbar></app-tabbar> -->
<mat-sidenav-container class="example-container" autosize [class.myapp-dark-theme]="darktheme">
<mat-sidenav #drawer class="example-sidenav" mode="side" opened="true" color="primary" style="overflow-x: hidden;">
<div class="biglogobox">
<img src="../../assets/images/logo2.png" alt="">
</div>
<div class="navbox">
<ul>
<!-- basicinfo -->
<li [routerLink]="['/datacollection/basicinfo']" routerLinkActive="router-link-active">基本信息</li>
<!-- plan -->
<li [routerLink]="['/datacollection/plan']" routerLinkActive="router-link-active">平面图</li>
<li [routerLink]="['/datacollection/collectionTools']" routerLinkActive="router-link-active">H5平面图</li>
<!-- allaround -->
<li [routerLink]="['/datacollection/allaround']" routerLinkActive="router-link-active">四周毗邻</li>
<!-- fire-fighting-device -->
<li [routerLink]="['/datacollection/fire-fighting-device']" routerLinkActive="router-link-active">消防设施</li>
<!-- key-site -->
<li [routerLink]="['/datacollection/key-site']" routerLinkActive="router-link-active">重点部位</li>
<!-- function-division -->
<li [routerLink]="['/datacollection/function-division']" routerLinkActive="router-link-active">功能分区</li>
<!-- realistic-picture -->
<li [routerLink]="['/datacollection/realistic-picture']" routerLinkActive="router-link-active">实景图</li>
<!-- uploading-cad -->
<li [routerLink]="['/datacollection/uploadingCAD']" routerLinkActive="router-link-active">上传CAD图</li>
</ul>
</div>
</mat-sidenav>
<button type="button" mat-button (click)="drawer.toggle()" class="shownav">
<mat-icon>menu</mat-icon>
</button>
<div class="example-sidenav-content">
<div style="height: 64px;">
<app-tabbar (toggleDarkTheme)="switchTheme($event)" (defaulttheme)="defaulttheme()" (redtheme)="redtheme()"></app-tabbar>
</div>
<div style="flex: 1; overflow: hidden;">
<router-outlet></router-outlet>
</div>
</div>
</mat-sidenav-container>

150
src/app/navigation/navigation.component.scss

@ -0,0 +1,150 @@
.example-container {
width: 100%;
height:100%;
border: 1px solid rgba(0, 0, 0, 0.5);
overflow: hidden;
}
mat-accordion{
height: 100%;
}
mat-sidenav{
box-shadow: 2px 0px 5px #888888;
color: white;
background-color: #3c4252;
width: 240px;
overflow-x: hidden;
p{
height: 48px;
cursor: pointer;
font-size: 16px;
line-height: 48px;
}
ul{
width: 100%;
li{
list-style: none;
height: 48px;
line-height: 48px;
cursor: pointer;
background: white;
padding-left: 55px;
background-color: #3c4252;
color: white;
}
.superli{
padding-left: 66px;
}
}
}
.logobox{
border-radius: 50%;
width: 64px;
height: 64px;
background:url("https://img5.tianyancha.com/logo/lll/cce72488294fb8f4bc670a5bb7f0cc4d.png@!f_200x200") no-repeat;
background-size: 100%;
margin: 0px auto;
img{
width: 100%;
height: 100%;
}
}
.shownav{
position: absolute;
top: 13px;
z-index: 200;
}
.mat-accordion .mat-expansion-panel:first-of-type {
border-top-right-radius:0px;
border-top-left-radius:0px;
}
.mat-accordion .mat-expansion-panel:last-of-type {
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
}
.mat-expansion-panel{
border-radius: 0px;
}
.mat-expansion-panel-spacing {
margin: 0px;
}
.superdiv{
padding-left: 31px;
}
mat-icon{
color: white;
}
.navbox{
position: absolute;
left: 0px;
top: 153px;
right: -18px;
bottom: 0px;
overflow-y: scroll;
}
mat-sidenav-container.myapp-dark-theme{
background-color: #fafafa;
color: black;
mat-panel-title{
color: black;
}
ul li{
background-color: white;
color: black;
}
.biglogobox{
background-color: #d50000;
}
color: black;
}
.biglogobox{
width: 250px;
background-color: #42a5f5;
padding-top: 15px;
display: block;
text-align: center;
line-height:40px;
position: relative;
color: #FFF;
font-size: 2em;
margin: 0 auto;
margin-bottom: 100px;
img{
margin-right: 11px;
}
}
mat-panel-title mat-icon{
color: #afb2bb;
font-size: 16px;
line-height: 24px;
margin-right: 6px;
}
mat-expansion-panel{
background-color: #3c4252;
mat-panel-title{
color: white;
}
}
.mat-expansion-indicator::after {
color: white;
}
.example-container .navbox .router-link-active {
background-color: rgba(225,225,225,.5);
border:0
}
.example-sidenav-content{
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}

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

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

31
src/app/navigation/navigation.component.ts

@ -0,0 +1,31 @@
import { Component, OnInit } from '@angular/core';
import {CacheTokenService} from '../http-interceptors/cache-token.service'//引入服务
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss']
})
export class NavigationComponent implements OnInit {
constructor(public navmenus:CacheTokenService) { }
ngOnInit() {
}
ngOnDestroy(){
}
darktheme = false;
switchTheme(dark) {
this.darktheme = dark;
// alert(this.darkTheme);
}
defaulttheme(){
this.darktheme = false
}
redtheme(){
this.darktheme = true
}
}

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

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

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

@ -0,0 +1,28 @@
<div class="pages-lockscreen layout-full">
<div class="page h-100-p text-center vertical-align">
<div class="page-content auth-box vertical-align-middle">
<!-- <div class="avatar s-50 mb-20">
<img src="../../../../../assets/images/avatars/tianhun.jpg">
</div> -->
<p class="mt-0 mb-20">锁屏</p>
<div class="mt-20 mb-20" fxLayout="row" fxLayoutAlign="space-between center">
<mat-form-field color-white color="accent" appearance="outline" class="w-100-p">
<mat-label>输入密码</mat-label>
<input matInput type="password" [(ngModel)]="password">
<mat-icon matSuffix>lock</mat-icon>
</mat-form-field>
</div>
<p class="mt-0">
输入密码以进入
</p>
<button mat-button color="warn" (click)="open()">进入</button>
<!-- <p class="mt-0">
<a routerLink="/general/pages/login">输入您或登录作为一个不同的用户密码检索您的会话</a>
</p> -->
<div class="copyright">
<p>WEBSITE BY Anxin</p>
<p>© 2020. All RIGHT RESERVED.</p>
</div>
</div>
</div>
</div>

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

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

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

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

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

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

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

@ -0,0 +1,49 @@
<div class="login">
<div class="loginBox">
<div>
<div class="card">
<span class="cardheader">数据采集平台</span>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div class="input">
<label class="position"><mat-icon>account_box</mat-icon></label>
<mat-form-field>
<input matInput id="name" name="name"
required type="text"
ngModel #name="ngModel" placeholder="请输入账号">
</mat-form-field>
</div>
<div class="input">
<label class="position"><mat-icon>lock</mat-icon></label>
<mat-form-field>
<input matInput id="password" name="password" type='password'
required
ngModel #password="ngModel" placeholder="请输入密码">
</mat-form-field>
</div>
<div *ngIf="errmsg" class="alert-danger input">
{{errmsg}}
</div>
<div class="register">
<a href="javascript:void(0);" style="margin-left: 100px;" class="forget">
忘记密码?
<div class="contactUs">
<label style="font-size: 14px; text-align: center; width: 100%; display: block; color: #fff;">安信科创QQ号</label>
<img src="../../../assets/images/AnXinQQ.jpg">
</div>
</a>
<a href="javascript:void(0);" (click)='toRegister()' style="margin-left: 180px;">快速注册</a>
</div>
<button type="submit" [disabled]="!form.form.valid" class="loginbtn" mat-button>登录</button>
</form>
</div>
</div>
</div>
</div>

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

@ -0,0 +1,89 @@
.login {
width: 100%;
height: 100%;
background: url('../../../assets/images/caiji.jpg');
background-size:100% 100%;
}
.loginBox {
width: 100%;
height: 100%;
background-color: #000;
background: rgba(0,0,0,0.5);/*盒子背景透明*/
display: flex;
/*!*flex-direction: column;*!可写可不写*/
justify-content: center;
align-items: center;
}
.card {
width: 500px;
height: 355px;
border-radius: 10px;
padding-top: 25px;
background-color: hsla(0,0%,100%,.8);
text-align: center;
box-shadow:0px 0px 10px 5px #333;
}
.cardheader{
margin-bottom: 10px;
font-size: 26px;
font-weight: 500;
}
.input {
margin: 15px auto;
position: relative;
}
.mat-form-field {
width: 300px;
}
.position {
margin-top: 5px;
position: absolute;
top: 15px;
left: 75px;
}
.alert-danger {
text-align-last: left;
margin-left: 100px;
font-size: 14px;
color: red;
}
.register {
text-align: left;
a {
font-size: 14px;
color: #0066FF;
}
}
.loginbtn {
margin-top: 25px;
height: 30px;
line-height: 30px;
width: 280px;
background-color:#039be5;
border-radius: 15px;
color: #fff;
}
//二维码
.forget:hover {
.contactUs {
opacity: 1;
z-index: 1;
transition: opacity 1.5s;
}
}
.contactUs {
opacity: 0;
z-index: -999;
position: fixed;
top: 55%;
left: 28%;
width: 150px;
border-radius: 5px;;
img {
width: 150px;
height: 150px;}
}

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

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

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

@ -0,0 +1,53 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Data } from '../../interface'
import { Router,ActivatedRoute } from '@angular/router'
import {CacheTokenService} from '../../http-interceptors/cache-token.service'//引入服务
import { CookieService } from 'ngx-cookie-service';//cookie插件
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
})
export class LoginComponent implements OnInit {
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,
public snackBar: MatSnackBar,private cookieService: CookieService) { }
ngOnInit() {}
errmsg :string = ''; //错误信息
//提交登录表单
onSubmit(e){
this.http.post('/api/CompanyAccount/SignIn',{
name: e.name,
password: e.password}).subscribe(
(data: Data) =>
{
sessionStorage.setItem("token",data.token);
this.cookieService.set("token",data.token,null,'/');
this.cookieService.set("refreshToken",data.refreshToken,null,'/');
this.router.navigate(['/datacollection/basicinfo'])
//调用服务中的function刷新token
this.token.startUp()
},
(err) =>
{this.errmsg = err}
)
}
//跳转注册页面
toRegister () {
this.router.navigate(['/register'])
}
}

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

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

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

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

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

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

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

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

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

112
src/app/pages/pages.module.ts

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

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

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

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

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

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

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

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

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

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

@ -0,0 +1,94 @@
<div class="login">
<div class="loginBox">
<div>
<div class="card">
<span class="cardheader">数据采集平台</span>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div class="input">
<label class="position"><mat-icon>group</mat-icon></label>
<mat-form-field>
<input matInput id="companyName" name="companyName"
required ngModel placeholder="请输入单位名称">
</mat-form-field>
</div>
<div class="input">
<label class="position"><mat-icon>dns</mat-icon></label>
<mat-form-field>
<input matInput id="usci" name="usci" #usci="ngModel"
pattern="^[0-9A-HJ-NP-RTUW-Y]{2}\d{6}[0-9A-HJ-NP-RTUW-Y]{10}$"
required ngModel placeholder="请输入统一社会信用代码">
</mat-form-field>
</div>
<div *ngIf="usci.invalid && (usci.dirty || usci.touched)" class="alert-danger">
<div *ngIf="usci.errors.pattern">
统一社会信用代码格式不正确
</div>
</div>
<div class="input">
<label class="position"><mat-icon>phone</mat-icon></label>
<mat-form-field>
<input matInput id="phone" name="phone" #tel="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 placeholder="请输入联系电话">
</mat-form-field>
</div>
<div *ngIf="tel.invalid && (tel.dirty || tel.touched)" class="alert-danger">
<div *ngIf="tel.errors.pattern">
电话号码格式不正确
</div>
</div>
<div class="input">
<label class="position"><mat-icon>account_box</mat-icon></label>
<mat-form-field>
<input matInput id="name" name="name" #name="ngModel" pattern="^[a-zA-Z][a-zA-Z0-9_]{4,19}$"
required ngModel placeholder="请输入账号">
</mat-form-field>
</div>
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert-danger">
<div *ngIf="name.errors.pattern">
登录账号格式为5-19位字母+数字
</div>
</div>
<div class="input">
<label class="position"><mat-icon>lock</mat-icon></label>
<mat-form-field>
<input matInput id="password" name="password" type='password' #password="ngModel"
required pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[A-Za-z0-9]{8,20}$"
ngModel placeholder="请输入密码">
</mat-form-field>
</div>
<div *ngIf="password.invalid && (password.dirty || password.touched)" class="alert-danger">
<div *ngIf="password.errors.pattern">
登录密码格式为8-20位字母+数字
</div>
</div>
<div *ngIf="errmsg" class="alert-danger">
{{errmsg}}
</div>
<div class="register">
<a href="javascript:void(0);" (click)='toLogin()'>已有账号,去登陆</a>
<a href="javascript:void(0);" style="margin-left: 135px;" class="forget">
注册失败?
<div class="contactUs">
<label style="font-size: 14px; text-align: center; width: 100%; display: block; color: #fff;">安信科创QQ号</label>
<img src="../../../assets/images/AnXinQQ.jpg">
</div>
</a>
</div>
<button type="submit" [disabled]="!form.form.valid" class="loginbtn" mat-button>注册</button>
</form>
</div>
</div>
</div>
</div>

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

@ -0,0 +1,91 @@
.login {
width: 100%;
height: 100%;
background: url('../../../assets/images/caiji.jpg');
background-size:100% 100%;
}
.loginBox {
width: 100%;
height: 100%;
background-color: #000;
background: rgba(0,0,0,0.5);/*盒子背景透明*/
display: flex;
/*!*flex-direction: column;*!可写可不写*/
justify-content: center;
align-items: center;
}
.card {
width: 500px;
border-radius: 10px;
padding-top: 25px;
background-color: hsla(0,0%,100%,.8);
text-align: center;
box-shadow:0px 0px 10px 5px #333;
}
.cardheader{
margin-bottom: 10px;
font-size: 26px;
font-weight: 500;
}
.input {
margin: 0 auto;
position: relative;
}
.mat-form-field {
width: 300px;
}
.position {
margin-top: 5px;
position: absolute;
top: 15px;
left: 75px;
}
.alert-danger {
margin-bottom: 5px;
text-align: left;
padding-left: 100px;
font-size: 12px;
color: red;
}
.register {
padding-left: 100px;
text-align: left;
a {
font-size: 14px;
color: #0066FF;
}
}
.loginbtn {
margin-top: 25px;
margin-bottom: 25px;
height: 30px;
line-height: 30px;
width: 280px;
background-color:#039be5;
border-radius: 15px;
color: #fff;
}
//二维码
.forget:hover {
.contactUs {
opacity: 1;
z-index: 1;
transition: opacity 1.5s;
}
}
.contactUs {
opacity: 0;
z-index: -999;
position: fixed;
top: 55%;
left: 64%;
width: 150px;
border-radius: 5px;;
img {
width: 150px;
height: 150px;}
}

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

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

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

@ -0,0 +1,43 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router, ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public snackBar: MatSnackBar) { }
ngOnInit() {}
errmsg:any; //错误信息
//提交注册表单
onSubmit(e){
this.http.post('/api/CompanyAccount/SignUp',{
companyName: e.companyName,
name:e.name,
password:e.password,
phone:e.phone,
usci:e.usci
}).subscribe(data=>{
this.snackBar.open('注册成功,请登录!', '确定', {
duration: 3000
});
this.router.navigate(['/login'])
},(err)=>{
this.errmsg = err
})
}
//跳转登陆页面
toLogin () {
this.router.navigate(['/login'])
}
}

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

@ -0,0 +1,13 @@
import { Pipe, PipeTransform } from '@angular/core';
import { isno } from '../interface'
@Pipe({name: 'isno'})
export class IsnoPipe implements PipeTransform {
transform(value: boolean): string {
if(value){
var x = 0
}else{
x=1
}
return isno[x]
}
}

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

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

16
src/app/tabbar/help-file.service.spec.ts

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

81
src/app/tabbar/help-file.service.ts

@ -0,0 +1,81 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class HelpFileService {
constructor(private http:HttpClient,) { }
helpFile:any = 'api/ObjectMetadata/help/cjhelp.pdf'; //下载文件的url地址
download:any; //下载的文件
//获取下载文件信息
getFileMSG () {
this.http.get(`${this.helpFile}`).subscribe(data=>{
this.download = data
this.downloadFile()
})
}
//初始化下载
downloadFile () {
let file = this.download
let fileSize = file.fileLength//下载文件的总大小
let shardSize = 10 * 1024 * 1024 //文件大小是否大于10MB
if (file && fileSize<=shardSize) { //<=10MB时直接下载
this.http.get(`/api/Objects/help/${file.objectName}`,{responseType: 'blob'},).subscribe(data=>{
let url = window.URL.createObjectURL(new Blob([data])); //createObjectURL创建一个下载Blob的url地址
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", '数据采集平台使用说明.pdf');
document.body.appendChild(link);
link.click();
})
} else if (file && fileSize>shardSize) { //>10MB时分块下载
this.blockingDownload() //分段下载
}
}
//分段下载并合并
async blockingDownload () {
let file = this.download
let fileSize = file.fileLength //下载文件的总大小
let shardSize = 3 * 1024 * 1024 //3MB一个分片
let allSlice = Math.ceil(fileSize / shardSize) //总文件/3MB===共分多少段
let allFile:any = [] //所有的file分段
for (let i=0;i<allSlice;i++) {
let start = i * shardSize //每次下载文件开始位置
let end = Math.min(fileSize, start + shardSize-1); //每次下载文件结束为止
let result = await new Promise ((result,reject)=>{
this.http.get(`/api/Objects/help/${file.objectName}`,{headers:{'range':`bytes= ${start}-${end}`},responseType:'blob'}).subscribe(data=>{
result(data) })
})
allFile.push(result)
if (allFile.length === allSlice) { //合并文件输出给浏览器
let url = window.URL.createObjectURL(new Blob(allFile)); //createObjectURL创建一个下载Blob的url地址
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", '数据采集平台使用说明.pdf');
document.body.appendChild(link);
link.click();
}
} //for循环
}
}

74
src/app/tabbar/tabbar.component.html

@ -0,0 +1,74 @@
<mat-toolbar [color]="theme?'primary':'accent'">
<!-- <mat-toolbar> -->
<h1 *ngIf="companyName">{{companyName}}</h1>
<!-- 全屏 -->
<!-- <button mat-button (click)="!isfullscreen?fullscreenToggle():closefullscreen()" class="fullscreen">
<ng-container *ngIf="!isfullscreen; else elseTemplate">
<mat-icon *ngIf="!isfullscreen">fullscreen</mat-icon>
</ng-container>
<ng-template #elseTemplate>
<mat-icon else>fullscreen_exit</mat-icon>
</ng-template>
</button> -->
<!-- 黑夜模式开关 -->
<!-- <mat-slide-toggle (change)='onChange($event.checked)' class="darktheme"></mat-slide-toggle> -->
<!-- 锁屏按钮 -->
<!-- <button mat-button class="lockscreen" [routerLink]="['/lockscreen']" routerLinkActive="router-link-active" >
<mat-icon>screen_lock_landscape</mat-icon>
</button> -->
<!-- 帮助文档按钮 -->
<button mat-icon-button [matMenuTriggerFor]="appSet" class="help" title="帮助">
<mat-icon>help</mat-icon>
</button>
<mat-menu #appSet="matMenu" yPosition="below" xPosition="after">
<button mat-menu-item (click)='downloadHelpFile()'>
<mat-icon>save_alt</mat-icon>
<span>下载帮助文档</span>
</button>
</mat-menu>
<!-- 登录信息按钮 -->
<button mat-icon-button [matMenuTriggerFor]="appMenu" class="login">
<mat-icon>account_circle</mat-icon>
</button>
<mat-menu #appMenu="matMenu">
<button mat-menu-item [routerLink]="['/datacollection/userdata']" >
<mat-icon>perm_identity</mat-icon>
<span>个人资料</span>
</button>
<button mat-menu-item (click)='changpsw()'>
<mat-icon>verified_user</mat-icon>
<span>修改密码</span>
</button>
<button mat-menu-item (click)='signOut()'>
<mat-icon>power_settings_new</mat-icon>
<span>退出系统</span>
</button>
</mat-menu>
<!-- 设置按钮 -->
<!-- <button mat-icon-button [matMenuTriggerFor]="appSet" class="setting">
<mat-icon>settings</mat-icon>
</button>
<mat-menu #appSet="matMenu" yPosition="below" xPosition="after">
<button mat-menu-item (click)="defaulttheme.next()">
<mat-icon>palette</mat-icon>
<span>默认主题</span>
</button>
<button mat-menu-item (click)="redtheme.next()">
<mat-icon>whatshot</mat-icon>
<span>亮色主题</span>
</button>
<button mat-menu-item (click)="standard()">
<mat-icon>settings_overscan</mat-icon>
<span>标准模式</span>
</button>
<button mat-menu-item (click)="boxed('boxed')">
<mat-icon>laptop</mat-icon>
<span>盒子模式</span>
</button>
</mat-menu> -->
</mat-toolbar>

45
src/app/tabbar/tabbar.component.scss

@ -0,0 +1,45 @@
mat-toolbar{
position: relative;
padding-left: 65px;
}
.logo{
height: 64px;
widows: 64px;
}
h1{
line-height: 64px;
color: white;
}
mat-icon{
color: white;
}
.login{
position: absolute;
right:30px;
}
.fullscreen{
position: absolute;
right:60px;
}
.help {
position: absolute;
right:90px;
}
.setting{
position: absolute;
right:120px;
}
.lockscreen{
position: absolute;
right:160px;
}
.darktheme{
position: absolute;
right:140px;
display: none;
}
.boxed{
width: 1200px;
}

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

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

132
src/app/tabbar/tabbar.component.ts

@ -0,0 +1,132 @@
import { Component, OnInit,Output,EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router,ActivatedRoute } from '@angular/router'
import {HelpFileService} from './help-file.service' //引入服务
import {CacheTokenService} from '../http-interceptors/cache-token.service' //引入服务
import { MatDialog } from '@angular/material/dialog';
import {ChangepasswordComponent} from '../ui/changepassword/changepassword.component'
import { MatSnackBar } from '@angular/material/snack-bar';
import { CookieService } from 'ngx-cookie-service';
@Component({
selector: 'app-tabbar',
templateUrl: './tabbar.component.html',
styleUrls: ['./tabbar.component.scss']
})
export class TabbarComponent implements OnInit {
theme: boolean = true;
@Output()
toggle = new EventEmitter<void>();
@Output()
toggleDarkTheme = new EventEmitter<boolean>();
@Output()
defaulttheme = new EventEmitter<boolean>();
@Output()
redtheme = new EventEmitter<boolean>();
// @Output()
// boxed = new EventEmitter<boolean>();
onChange(eventValue: boolean){
this.toggleDarkTheme.emit(eventValue);
}
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,public dialog: MatDialog,public snackBar: MatSnackBar,
private cookieService: CookieService,private help: HelpFileService) { }
ngOnInit() {
this.getUserInfo()
}
boxed(css){
const Element = document.body;
Element.style.width = '1200px'
}
standard(){
const Element = document.body;
Element.style.width = '100%'
}
isfullscreen:boolean = false;
fullscreenToggle(){
const docElmWithBrowsersFullScreenFunctions = document.documentElement as HTMLElement & {
mozRequestFullScreen(): Promise<void>;
webkitRequestFullscreen(): Promise<void>;
msRequestFullscreen(): Promise<void>;
};
if (docElmWithBrowsersFullScreenFunctions.requestFullscreen) {
docElmWithBrowsersFullScreenFunctions.requestFullscreen();
} else if (docElmWithBrowsersFullScreenFunctions.mozRequestFullScreen) { /* Firefox */
docElmWithBrowsersFullScreenFunctions.mozRequestFullScreen();
} else if (docElmWithBrowsersFullScreenFunctions.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
docElmWithBrowsersFullScreenFunctions.webkitRequestFullscreen();
} else if (docElmWithBrowsersFullScreenFunctions.msRequestFullscreen) { /* IE/Edge */
docElmWithBrowsersFullScreenFunctions.msRequestFullscreen();
}
this.isfullscreen = true;
}
closefullscreen(){
const docWithBrowsersExitFunctions = document as Document & {
mozCancelFullScreen(): Promise<void>;
webkitExitFullscreen(): Promise<void>;
msExitFullscreen(): Promise<void>;
};
if (docWithBrowsersExitFunctions.exitFullscreen) {
docWithBrowsersExitFunctions.exitFullscreen();
} else if (docWithBrowsersExitFunctions.mozCancelFullScreen) { /* Firefox */
docWithBrowsersExitFunctions.mozCancelFullScreen();
} else if (docWithBrowsersExitFunctions.webkitExitFullscreen) { /* Chrome, Safari and Opera */
docWithBrowsersExitFunctions.webkitExitFullscreen();
} else if (docWithBrowsersExitFunctions.msExitFullscreen) { /* IE/Edge */
docWithBrowsersExitFunctions.msExitFullscreen();
}
this.isfullscreen = false;
}
companyName:any; //企业name
//获取用户信息
getUserInfo () {
this.http.get('/api/CompanyAccount/Profiles').subscribe((data:any)=>{
sessionStorage.setItem('companyId',data.companyId)
this.companyName = data.companyName
})
}
//退出系统
signOut = () => {
let out = confirm("您确定要退出吗")
if(out) {
this.http.post('/api/CompanyAccount/SignOut',{}).subscribe(
data=> {
this.token.delete()
sessionStorage.clear()
window.localStorage.clear()
this.cookieService.set("token",'',new Date(new Date().getTime() + 1),'/');
this.cookieService.set("refreshToken",'',new Date(new Date().getTime() + 1),'/');
this.snackBar.open('成功退出', '确定', {
duration: 3000
});
this.router.navigate(['/login'])
}
)
}
}
//修改密码
changpsw() {
let dialogRef = this.dialog.open(ChangepasswordComponent,
{width:'348px'});
dialogRef.afterClosed().subscribe();
}
//下载帮助文档
downloadHelpFile () {
this.help.getFileMSG()
}
}

18
src/app/theme.scss

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

78
src/app/ui/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/ui/allaround/allaround.component.scss

@ -0,0 +1,54 @@
.content {
width: 100%;
height: 100%;
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/ui/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();
});
});

75
src/app/ui/allaround/allaround.component.ts

@ -0,0 +1,75 @@
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';
@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) { }
ngOnInit(): void {
this.getAllCompany()
this.getAllBuilding()
}
AllAdjoining:any = []; //所有单位毗邻
AllBuilding:any = []; //所有建筑 + 建筑毗邻图片
//获取所有单位毗邻图片
getAllCompany () {
this.http.get('/api/CompanyAccount/CompanyAdjoins').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 () {
this.http.get('/api/CompanyAccount/Buildings').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/CompanyAccount/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/ui/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/ui/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}
}
}

23
src/app/ui/authority/authority.component.html

@ -0,0 +1,23 @@
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" >
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<button mat-icon-button disabled ></button>
{{node.name}}
<button mat-icon-button class="create" (click)="createauthority(node)"><mat-icon>add_circle_outline</mat-icon></button>
<button mat-icon-button class="deleted" (click)="deleted(node)"><mat-icon>delete</mat-icon></button>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<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>
{{node.name}}
<button mat-icon-button class="create" (click)="createauthority(node)"><mat-icon>add_circle_outline</mat-icon></button>
<button mat-icon-button class="deleted" (click)="deleted(node)"><mat-icon>delete</mat-icon></button>
</mat-tree-node>
</mat-tree>

30
src/app/ui/authority/authority.component.scss

@ -0,0 +1,30 @@
table {
width: 100%;
th,td{
text-align: center;
}
}
form{
text-align: center;
button{
margin: 0 12px;
}
}
mat-tree{
width: 500px;
button{
display: block;
float: right;
}
mat-tree-node{
position: relative;
.deleted{
position: absolute;
right: 0;
}
.create{
position: absolute;
right: 40px;
}
}
}

139
src/app/ui/authority/authority.component.ts

@ -0,0 +1,139 @@
import { Component, OnInit, Inject } from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { TreeService } from '../../http-interceptors/tree.service'
export interface authority {
id: string,
name: string,
value: string,
order: number,
parentId: string
}
@Component({
selector: 'app-authority',
templateUrl: './authority.component.html',
styleUrls: ['./authority.component.scss']
})
export class AuthorityComponent implements OnInit {
data:any =[]
newdata = [];
private _transformer = (node, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
constructor(private http: HttpClient,public dialog: MatDialog,private tree:TreeService) { }
//重新拉去列表函数
getlist = ():void=>{
this.http.get('/api/Permissions').subscribe((data: any[])=>{
this.newdata = this.tree.toTree(data)
const nodes = this.treeControl.dataNodes;
const expandNodes = [];
nodes.forEach((item) => {
if(item.expandable && this.treeControl.isExpanded(item)){
expandNodes.push(item.id);
}
});
this.dataSource.data = this.newdata;
let newNodes = this.treeControl.dataNodes;
newNodes = newNodes.filter(n => {
return expandNodes.indexOf(n.id) >= 0;
});
newNodes.forEach(item => {
this.treeControl.expand(item);
});
})
}
//初始化视图
ngOnInit() {
this.http.get('/api/Permissions').subscribe((data: any[])=>{
this.dataSource.data = this.tree.toTree(data)
})
}
hasChild = (_: number, node: any) => node.expandable;
//创建按钮
createauthority(value){
const dialogRef = this.dialog.open(CreateAuthority, {//调用open方法打开对话框并且携带参数过去
width: '260px',
data: {id:value.id}
});
dialogRef.afterClosed().subscribe(
data=>{
if(data){
this.newdata = []
this.getlist()
}
}
);
}
//删除按钮
deleted(authority){
var isdeleted = confirm("确定要删除此用户吗?")
if(isdeleted){
//请求删除接口
this.newdata = []
this.http.delete(`/api/Permissions/${authority.id}`).subscribe( data=>{
this.getlist()
})
}
}
}
//创建组件
@Component({
selector: 'createauthority',
templateUrl: './createauthority.component.html',
styleUrls: ['./authority.component.scss']
})
export class CreateAuthority {
myControl = new FormControl();
options: string[] = ['0', '1','2', '3','4', '5','6', '7','8'];
//注入MatDialogRef,可以用来关闭对话框
//要访问对话框组件中的数据,必须使用MAT_DIALOG_DATA注入令牌
constructor(private http: HttpClient,public dialogRef: MatDialogRef<CreateAuthority>,@Inject(MAT_DIALOG_DATA) public data) {}
onNoClick(): void {
this.dialogRef.close();
}
onSubmit(value){
if(value.parentId == "null"){
value.parentId = null
}
//编写请求创建用户接口(value是参数)//并且刷新一下
this.http.post(
'/api/Permissions',
{
id: '',
name: value.name,
value: value.value,
order: Number(value.order),
parentId: this.data.id
}
).subscribe(
data=>{
this.dialogRef.close(data);
},
err=>{
alert("请填写正确格式")
}
)
}
}

36
src/app/ui/authority/createauthority.component.html

@ -0,0 +1,36 @@
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<mat-form-field>
<input matInput id="name" name="name"
required
ngModel #name="ngModel" placeholder="权限名称">
</mat-form-field>
<mat-form-field>
<input matInput id="value" name="value"
required
ngModel #name="ngModel" placeholder="权限值">
</mat-form-field>
<mat-form-field class="example-full-width">
<input type="text" placeholder="权限顺序" aria-label="Number" matInput [matAutocomplete]="auto1" name="order" ngModel #order="ngModel">
<mat-autocomplete #auto1="matAutocomplete">
<mat-option *ngFor="let option of options" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<!-- <mat-form-field>
<input matInput id="parentId" name="parentId" type='text'
required minlength="3"
ngModel #organizationId="ngModel" placeholder="父级编号">
</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>

25
src/app/ui/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>

69
src/app/ui/basicinfo/addhouseinfo.component.ts

@ -0,0 +1,69 @@
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 {
this.getallunittype()
}
getallunittype(){
this.http.get("/api/BuildingTypes/Simple").subscribe(data=>{
this.allunittype = data
})
}
onSubmit(value){
this.http.get("/api/CompanyAccount/Buildings").subscribe((data:any)=>{
let allBuildings = data
let order
if(allBuildings.length == 0){
order = 0
}else{
order = allBuildings[allBuildings.length-1].order + 1
}
let buildingTypename = ""
this.allunittype.forEach(item => {
if(item.id == value.unittype){
buildingTypename = item.name
}
});
this.http.post("/api/CompanyAccount/Buildings",{
id: "",
name: value.name,
order: order,
enabled: true,
companyId: this.data.unitinfo.id,
buildingTypes: [
{
id: value.unittype,
name: buildingTypename
}
]
}).subscribe(data=>{
this.dialogRef.close(data);
})
})
}
}

554
src/app/ui/basicinfo/basicinfo.component.html

@ -0,0 +1,554 @@
<div style="height: 100%;display: flex; flex-direction: column;overflow: hidden;">
<!-- header -->
<mat-accordion>
<mat-expansion-panel expanded>
<mat-expansion-panel-header style="color: black;">
<mat-panel-title>
单位信息
</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">
<span>单位照片:</span>
<div class="uploadingimg" (click)="lookmaster()">
<img [src]="imgsrc ? imgsrc : noImg" 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" ng2FileSelect [uploader]="uploader" (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" id="setPosition">
<div style="width: 100%;height: 100%;" id="container">
</div>
<div class="gistopbox" *ngIf="isGisTopBox">
<div class="positionItem">
<span>
经度 :
</span>
<div class="itemNum">
{{markerPosition.x || '暂未标注'}}
</div>
</div>
<div class="positionItem">
<span>
纬度 :
</span>
<div class="itemNum">
{{markerPosition.y || '暂未标注'}}
</div>
</div>
<div class="setPosition" (click)="setPosition()">
<mat-icon style="width: 22px;height: 22px;font-size: 22px;">place</mat-icon> 位置
</div>
</div>
</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 id="floorspace" 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 id="floorspace" 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 id="floorspace" 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 id="floorspace" 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 id="floorspace" 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>

294
src/app/ui/basicinfo/basicinfo.component.scss

@ -0,0 +1,294 @@
.topbox{
height: 485px;
width: 100%;
padding-bottom: 20px;
.mainbox{
height: 100%;
position: relative;
display: flex;
.mainleft{
width:800px;
height: 100%;
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;
margin:20px 0;
padding-bottom: 20px;
}
.uploadimg{
width: 400px;
height: 200px;
float: left;
margin-top:12px;
position: relative;
margin-left: 80px;
span{
float: left;
}
.uploadingimg{
width: 299px;
height: 170px;
cursor: pointer;
position: absolute;
top: 0px;
left: 79px;
border: 1px dashed gray;
border-radius:3px;
}
}
.image{
input{
width: 190px;
margin-top: 160px;
cursor: pointer;
}
}
}
.mainright{
float: left;
flex: 1;
height: 430px;
margin-right: 100px;
position: relative;
.searchinput{
display: flex;
position: absolute;
left: 0;
top: 0;
}
.gistopbox{
position: absolute;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
border-radius: 4px;
left: 5%;
top: 10px;
width: 90%;
height:46px;
background: #FFFFFF;
display: flex;
justify-content: space-around;
align-items: center;
cursor: default;;
.positionItem{
width: 30%;
height: 35px;
display: flex;
align-items: center;
.itemNum{
background: #F2F2F2;
box-sizing: border-box;
padding-left: 10px;
width: 80%;
height: 32px;
line-height: 32px;
margin-left: 5px;
border-radius: 4px;
}
}
.setPosition{
cursor: pointer;
width: 15%;
height: 32px;
background: #2196F3;
color: #fff;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.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;
}

25
src/app/ui/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();
});
});

2220
src/app/ui/basicinfo/basicinfo.component.ts

File diff suppressed because it is too large Load Diff

26
src/app/ui/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/ui/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
}
}
}
}

12
src/app/ui/card/card.component.html

@ -0,0 +1,12 @@
<mat-card>
<mat-card-title>简单的卡片</mat-card-title>
<mat-card-subtitle>卡片的字幕</mat-card-subtitle>
<mat-card-content>原来爱情的世界很大,大得可以装下一百种委屈;原来爱情的世界很小,小得三个人就会窒息。</mat-card-content>
<img mat-card-image src="https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1579480490&di=f80c114e78ea7a439c19cc7f1622227f&src=http://pic1.win4000.com/wallpaper/2017-11-17/5a0e94afc140c.jpg">
<mat-card-actions>
<button mat-raised-button color="primary">我是按钮</button>
</mat-card-actions>
<mat-card-footer>
我要被固定在卡片底部
</mat-card-footer>
</mat-card>

10
src/app/ui/card/card.component.scss

@ -0,0 +1,10 @@
mat-card{
width: 300px;
height: 600px;
img{
width: 300px;
height: 300px;
padding: 16px;
}
}

25
src/app/ui/card/card.component.spec.ts

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

15
src/app/ui/card/card.component.ts

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

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

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

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

Loading…
Cancel
Save