Browse Source

[新增]初始化文件

master
邵佳豪 3 years ago
commit
33b66ad524
  1. 13
      .editorconfig
  2. 46
      .gitignore
  3. 15
      .vscode/launch.json
  4. 261
      README.md
  5. 169
      angular.json
  6. 12
      browserslist
  7. 7
      debug.log
  8. 32
      e2e/protractor.conf.js
  9. 23
      e2e/src/app.e2e-spec.ts
  10. 11
      e2e/src/app.po.ts
  11. 13
      e2e/tsconfig.json
  12. 32
      karma.conf.js
  13. 16304
      package-lock.json
  14. 84
      package.json
  15. 13
      proxy.config.json
  16. 23
      src/app/app-routing.module.ts
  17. 1
      src/app/app.component.html
  18. 5
      src/app/app.component.scss
  19. 29
      src/app/app.component.ts
  20. 41
      src/app/app.module.ts
  21. 35
      src/app/auth.guard.ts
  22. 103
      src/app/http-interceptors/base-interceptor.ts
  23. 9
      src/app/http-interceptors/index.ts
  24. 20
      src/app/interface.ts
  25. 27
      src/app/pages/change-password/change-password.component.html
  26. 0
      src/app/pages/change-password/change-password.component.scss
  27. 45
      src/app/pages/change-password/change-password.component.ts
  28. 252
      src/app/pages/criminal-records-admin/criminal-records-admin.component.html
  29. 612
      src/app/pages/criminal-records-admin/criminal-records-admin.component.scss
  30. 739
      src/app/pages/criminal-records-admin/criminal-records-admin.component.ts
  31. 110
      src/app/pages/home/home.component.html
  32. 235
      src/app/pages/home/home.component.scss
  33. 456
      src/app/pages/home/home.component.ts
  34. 50
      src/app/pages/login/login.component.html
  35. 93
      src/app/pages/login/login.component.scss
  36. 181
      src/app/pages/login/login.component.ts
  37. 188
      src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.html
  38. 615
      src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.scss
  39. 724
      src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.ts
  40. 231
      src/app/pages/oil-unloading-process/oil-unloading-process.component.html
  41. 246
      src/app/pages/oil-unloading-process/oil-unloading-process.component.scss
  42. 41
      src/app/pages/oil-unloading-process/oil-unloading-process.component.ts
  43. 24
      src/app/pages/pages-routing.module.ts
  44. 97
      src/app/pages/pages.module.ts
  45. 105
      src/app/pages/plan-admin/plan-admin.component.html
  46. 193
      src/app/pages/plan-admin/plan-admin.component.scss
  47. 173
      src/app/pages/plan-admin/plan-admin.component.ts
  48. 51
      src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.html
  49. 225
      src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.scss
  50. 68
      src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.ts
  51. 138
      src/app/pages/today-warning/today-warning.component.html
  52. 279
      src/app/pages/today-warning/today-warning.component.scss
  53. 259
      src/app/pages/today-warning/today-warning.component.ts
  54. 85
      src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.html
  55. 89
      src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.scss
  56. 69
      src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.ts
  57. 186
      src/app/pages/warning-statistics-list/warning-statistics-list.component.html
  58. 620
      src/app/pages/warning-statistics-list/warning-statistics-list.component.scss
  59. 739
      src/app/pages/warning-statistics-list/warning-statistics-list.component.ts
  60. 13
      src/app/pipes/boolean.pipe.ts
  61. 9
      src/app/pipes/time.pipe.ts
  62. 41
      src/app/service/cache-token.service.ts
  63. 22
      src/app/service/listRefresh.service.ts
  64. 22
      src/app/service/navChange.service.ts
  65. 139
      src/app/service/objects.service.ts
  66. 85
      src/app/service/objectsSimple.service.ts
  67. 38
      src/app/service/tree.service.ts
  68. 23
      src/app/ui/tabbar/tabbar.component.html
  69. 27
      src/app/ui/tabbar/tabbar.component.scss
  70. 86
      src/app/ui/tabbar/tabbar.component.ts
  71. 8
      src/app/ui/title/title.component.html
  72. 86
      src/app/ui/title/title.component.scss
  73. 17
      src/app/ui/title/title.component.ts
  74. 13
      src/app/ui/ui-routing.module.ts
  75. 41
      src/app/ui/ui.module.ts
  76. BIN
      src/assets/font-family/sybold.OTF
  77. BIN
      src/assets/font-family/synormal.OTF
  78. BIN
      src/assets/font-family/titlefont.TTF
  79. BIN
      src/assets/images/3d.png
  80. BIN
      src/assets/images/adsorb.png
  81. BIN
      src/assets/images/awningHide.png
  82. BIN
      src/assets/images/awningShow.png
  83. BIN
      src/assets/images/baseInfo/building.png
  84. BIN
      src/assets/images/baseInfo/date.png
  85. BIN
      src/assets/images/baseInfo/hospital.png
  86. BIN
      src/assets/images/baseInfo/phone.png
  87. BIN
      src/assets/images/baseInfo/police.png
  88. BIN
      src/assets/images/baseInfo/position.png
  89. BIN
      src/assets/images/baseInfo/road.png
  90. BIN
      src/assets/images/bgImg.png
  91. BIN
      src/assets/images/bottomArrow.png
  92. BIN
      src/assets/images/bottomArrow2.png
  93. BIN
      src/assets/images/bucket.png
  94. BIN
      src/assets/images/cameraNum.png
  95. BIN
      src/assets/images/circle.png
  96. BIN
      src/assets/images/err.png
  97. BIN
      src/assets/images/excel.png
  98. BIN
      src/assets/images/expand.png
  99. BIN
      src/assets/images/fireNum.png
  100. BIN
      src/assets/images/flow.png
  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}"
}
]
}

261
README.md

@ -0,0 +1,261 @@
# 中国石化加油站项目
## 🌼v1.1.1
### 🌻 简介
> 时间:2022、2、24 周四
> 添加阀门模块
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更]
- [🌱 新增] 新增阀门模块
- [🍀 完善]
## 🌼v1.1.0
### 🌻 简介
> 时间:2022、1、22 周六
> 优化加载
> 增加镜头限制、增加吸附功能
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更] 增加对关联复制模型的支持,可以大幅减少 bin 文件的大小,增加解析速度与渲染速度
- [🚩 重大变更] 暂时停止 1+n 的模型加载模式(indexDB 问题以在另外的地方进行解决),充分利用并发加载
- [🌱 新增] 摄像头旋转时设置限制,避免看到场景的底部
- [🌱 新增] 增加建筑吸附、对齐到场景中的功能,确定对齐规则,使用“WAI”节点作为插槽
- [🍀 完善]
## 🌼v1.0.9
### 🌻 简介
> 时间:2022、1、13 周二
> 修复 json 中存在换行符的问题 ,等 bug
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更]
- [🌱 新增] post 请求出错时,统一提示,避免保存失败但用户不知道
- [🍀 完善] 修复 json 中存在换行符的问题
- [🍀 完善] 修改预案中暂停然后从进度条跳转节点后的暂停表现
## 🌼v1.0.8
### 🌻 简介
> 时间:2022、1、11 周二
> 更新 babylonjs 从 4.2.0 更新至 4.2.1, 以解决最新版本 谷歌浏览器(97.0.4692.71)下无法正常解析 pbr shader 的问题
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更] 更新 babylonjs 从 4.2.0 更新至 4.2.1, 以解决最新版本 谷歌浏览器(97.0.4692.71)下无法正常解析 pbr shader 的问题
- [🌱 新增]
- [🍀 完善]
## 🌼v1.0.7
### 🌻 简介
> 时间:2022、1、7 周五
> 根据中化业务需求及建议,调整、优化
> 尝试修复偶发的模型加载一直等待的问题,猜测为 indexDB 问题
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更] 尝试修复偶发的模型加载一直等待的问题,猜测为 indexDB 问题,将初始化机制提前值 mainStatus 中
- [🌱 新增]
- [🍀 完善] 根据中化要求,对油罐属性栏中的油枪一行进行自动换行和自适应高度
- [🍀 完善] 自定义模型加载报错的重试机制,当无论错误码为多少,都进行重试
## 🌼v1.0.6
### 🌻 简介
> 时间:2021、12、25 周六
> 根据中化业务需求及建议,调整、优化
### 🌻 详情
> 前端部分
- [🚩 重大变更]
- [🌱 新增]
- [🍀 完善]
> 三维部分
- [🚩 重大变更] 无
- [🌱 新增] 右键取消测量点
- [🍀 完善] 新增从模型中重新获取设备、更新的功能
## 🌼v1.0.5 主要变化 babylon 完全离线方案,部署测试
### 🌻 简介
> 时间:2021、12、16 周四
> 根据中化业务需求及建议,调整、优化
### 🌻 详情
> 前端部分
- [🚩 重大变更] 抽离 excel 所需导出的内容,并单独保存至服务器,以支持后端导出功能
- [🌱 新增] 添加加油机、油罐根据名称排序的功能
- [🍀 完善] 油罐 UI 列表取消“数量”字段
- [🍀 完善] 消防设备列表中数目增加单位
- [🍀 完善] 取消消防设备外其他设备的高亮效果,只有选中时才高亮,优化显示效果
- [🍀 完善] 应急预案中,主角的 UI 用红色突出,可以设置的功能
- [🍀 完善] 完善模板的应急预案(油箱口着火)中的细节与表现
- [🍀 完善] 优化进攻路线箭头的表现,增加流动动画
> 三维部分
- [🚩 重大变更] 无
- [🌱 新增]
- [🍀 完善] 无
## 🌼v1.0.4 主要变化 babylon 完全离线方案,部署测试
### 🌻 简介
> 时间:2021、12、10 周五
> 修复 bug,babylon 离线方案(asset)测试
### 🌻 详情
> 前端部分
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 无
> 三维部分
- [🚩 重大变更] 在打包后替换 preview 地址为 asset/js/地址,使其访问服务器静态资源
- [🌱 新增] 无
- [🍀 完善] 无
## 🌼v1.0.3 主要变化 修改 bug,部署测试
### 🌻 简介
> 时间:2021、12、8 周三
> 修复 bug,三维优化
### 🌻 详情
> 前端部分
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 无
> 三维部分
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 修复分块上传路径拼接使用错误变量的问题
- [🍀 完善] 优化应急中的操作: 取消模型不可见的外框可以被选中的问题。 增加右键取消高亮的功能。 非选中状态下,不再允许拖拽。
- [🍀 完善] 尝试修复因升级 obs(解决大小写变换问题)而导致的消防车和消防员加载不出来的问题
- [🍀 完善] 延迟应急中人物任务 ui 的更新时间,尝试修复背景框自适应不正确的问题
- [🍀 完善] 限制应急处置下、上传视频的格式
## 🌼v1.0.2 主要变化 修改 bug,部署测试
### 🌻 简介
> 时间:2021、12、7 周二
> 修复 bug,三维优化
### 🌻 详情
> 前端部分
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 无
> 三维部分
- [🚩 重大变更] 找到发布后 EventManager 错乱的问题:代码混淆导致类名重复! 更改对事件分类的逻辑,暂时采用自定义名称的方式。 后期需要尝试改进。
- [🌱 新增] 无
- [🍀 完善] 修复多个单位切换时,未重新获取应急预案信息的问题
- [🍀 完善] 增加打印,排查部署与本地差异: 部署后新建单位创建应急预案不成功,本地未出现此情况
## 🌼v1.0.1 主要变化 完成功能,部署测试
### 🌻 简介
> 时间:2021、12、6 周一
> 修复 bug,三维优化
### 🌻 详情
> 前端部分
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 无
> 三维部分
- [🚩 重大变更] 尝试优化运行时缓存机制,避免多次进入同一单位反复释放、加载三维场景(只要不关闭页面或刷新页面)。
- [🌱 新增] 无
- [🍀 完善] 修复属性框上传的图片无法查看的问题
## 🌼v1.0.0 主要变化 完成功能,部署测试
### 🌻 简介
> 时间:2021、12、2 周四
> 根据功能需求和开发计划,完成已知功能,部署测试
### 🌻 详情
- [🚩 重大变更] 无
- [🌱 新增] 无
- [🍀 完善] 无

169
angular.json

@ -0,0 +1,169 @@
{
"$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",
{
"glob": "**/*",
"input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
"output": "/assets/"
},
{
"glob": "abp.signalr.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
},
{
"glob": "abp.signalr-client.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
}
],
"styles": [
"src/styles.scss",
"./node_modules/swiper/css/swiper.min.css",
"./node_modules/viewerjs/dist/viewer.css",
"src/theme.less"
],
"scripts": [
"./node_modules/swiper/js/swiper.min.js",
"node_modules/@aspnet/signalr/dist/browser/signalr.min.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/abp.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": "80mb",
"maximumError": "80mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "60kb",
"maximumError": "100kb"
}
]
}
}
},
"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",
{
"glob": "abp.signalr.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
},
{
"glob": "abp.signalr-client.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
}
],
"styles": [
"src/styles.scss"
],
"scripts": [
"node_modules/@aspnet/signalr/dist/browser/signalr.min.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/abp.js"
]
}
},
"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)

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

16304
package-lock.json generated

File diff suppressed because it is too large Load Diff

84
package.json

@ -0,0 +1,84 @@
{
"name": "anxin119",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.config.json --open --port 4000 ",
"build": "node --max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^9.0.0",
"@angular/cdk": "^9.2.4",
"@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",
"@aspnet/signalr": "^1.1.4",
"@babylonjs/core": "4.2.1",
"@babylonjs/gui": "4.2.1",
"@babylonjs/inspector": "4.2.1",
"@babylonjs/loaders": "4.2.1",
"@babylonjs/materials": "4.2.1",
"@types/cesium": "^1.59.5",
"@types/earcut": "^2.1.1",
"@types/react-dom": "^17.0.10",
"@types/swiper": "^5.2.1",
"abp-ng2-module": "^6.4.0",
"abp-web-resources": "^5.4.0",
"angular-calendar": "^0.28.2",
"babylonjs": "4.2.1",
"bson-objectid": "^1.3.1",
"cesium": "^1.64.0",
"class-transformer": "^0.4.0",
"e-ngx-cesium": "^6.3.2",
"earcut": "^2.2.3",
"echarts": "^4.9.0",
"firebase": "^7.6.2",
"grpc": "^1.24.2",
"install": "^0.13.0",
"js-base64": "^3.7.2",
"linqjs": "^1.0.2",
"moment": "^2.29.1",
"ng-zorro-antd": "^9.3.0",
"ngx-cookie-service": "^3.0.2",
"ngx-countdown": "^11.0.0",
"ngx-echarts": "^4.2.2",
"ngx-perfect-scrollbar": "^8.0.0",
"reflect-metadata": "^0.1.13",
"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"
}
}

13
proxy.config.json

@ -0,0 +1,13 @@
{
"/api": {
"target": "http://39.106.78.171:8906",
"secure": false,
"changeOrigin": true
},
"/signalr": {
"target": "http://39.106.78.171:8906",
"secure": false,
"ws": true,
"logLevel": "debug"
}
}

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

@ -0,0 +1,23 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
//路由守卫
import { AuthGuard } from './auth.guard'
import { HomeComponent } from './pages/home/home.component';
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent }, //登录页
{
path: '', component: HomeComponent, canActivate: [AuthGuard], children: [
{ path: '', loadChildren: () => import('./pages/pages.module').then(m => m.PagesModule) }
]
} //首页
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

1
src/app/app.component.html

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

5
src/app/app.component.scss

@ -0,0 +1,5 @@
.btn{
position: fixed;
left: 0;
top: 0;
}

29
src/app/app.component.ts

@ -0,0 +1,29 @@
import { Component, TemplateRef, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router, ActivatedRoute } from '@angular/router'
import { CacheTokenService } from './service/cache-token.service'//引入服务
import "reflect-metadata";
import { NzNotificationService } from 'ng-zorro-antd/notification';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
@ViewChild(TemplateRef, { static: false }) template?: TemplateRef<{}>;
constructor(private http: HttpClient, private router: Router, public token: CacheTokenService, private notificationService: NzNotificationService) { }
ngOnInit(): void {
}
ngAfterViewInit(): void {
}
}

41
src/app/app.module.ts

@ -0,0 +1,41 @@
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 { PagesModule } from './pages/pages.module';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { httpInterceptorProviders } from './http-interceptors/index'
import { CacheTokenService } from './service/cache-token.service'
import { TreeService } from './service/tree.service'
import { CountdownModule } from 'ngx-countdown'; //倒计时插件
import { NzNotificationModule } from 'ng-zorro-antd/notification';
import { NzMessageModule } from 'ng-zorro-antd/message';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatButtonModule,
MatCheckboxModule,
MatSidenavModule,
MatIconModule,
PagesModule,
FormsModule,
HttpClientModule,
CountdownModule,
NzNotificationModule,
NzMessageModule
],
providers: [httpInterceptorProviders, CacheTokenService, TreeService],
bootstrap: [AppComponent]
})
export class AppModule { }

35
src/app/auth.guard.ts

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

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

@ -0,0 +1,103 @@
import { Injectable } from '@angular/core';
import {
HttpClient, HttpInterceptor, HttpHandler, HttpRequest,
HttpErrorResponse,
HttpResponse
} from '@angular/common/http';
import { throwError } from 'rxjs'
import { catchError, tap, finalize } from 'rxjs/operators';
import { Router } from '@angular/router'
import { NzMessageService } from 'ng-zorro-antd/message';
//baseurl
// const baseurl = 'http://39.106.78.171:8008';
@Injectable()
export class BaseInterceptor implements HttpInterceptor {
constructor(private router: Router, private message: NzMessageService) { }
intercept(req, next: HttpHandler) {
let params = req.params;
for (const key of req.params.keys()) {
if (params.get(key) === undefined || params.get(key) === null) {
params = params.delete(key, undefined);
}
}
req = req.clone({ params });
// debugger
// console.log('xxxxxx',req)
let newReq = req.clone({
url: req.hadBaseurl ? `${req.url}` : `${req.url}`,
});
if (!req.cancelToken) {
/*获取token*/
let token = sessionStorage.getItem("token")
/*此处设置额外请求头,token令牌*/
if (!!token) {
newReq.headers = newReq.headers.set('Authorization', `Bearer ${token}`)
}
}
// 携带请求头发送下一次请求
return next.handle(newReq)
.pipe(
tap(event => {
if (event instanceof HttpResponse) {
// 成功
// console.log('成功', event.headers.get('x-refresh-encryptedtoken'))
if (!!event.headers.get('x-refresh-token')) {
sessionStorage.setItem('token', event.headers.get('x-refresh-token'))
sessionStorage.setItem('encryptedAccessToken', event.headers.get('x-refresh-encryptedtoken'))
}
}
}, error => {
// 失败
console.log('请求http失败', error)
this.handleError(error)
}),
finalize(() => {
// 请求完成
// console.log('complete')
})
)
}
// 捕获错误
//401 token过期 403没权限!!! 400参数错误 404未找到 614刷新令牌过期!!!
private handleError(error: HttpErrorResponse) {
// 用户认证失败返回登录页
if (error.status === 401 || error.status === 614) {
sessionStorage.clear()
// window.localStorage.clear()
localStorage.removeItem("isautologin")
this.message.create('error', `用户认证信息过期,请重新登录!`);
this.router.navigate(['/login'])
}
if (error.status === 403) {
this.message.create('error', `对不起,您无此权限!`);
}
if (error.status === 400) {
this.message.create('error', `请核对您的输入信息或格式是否正确!`);
}
if (error.status === 500) {
this.message.create('error', `状态500,服务器错误!`);
}
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);
};
}

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

20
src/app/interface.ts

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

27
src/app/pages/change-password/change-password.component.html

@ -0,0 +1,27 @@
<div class="box">
<form nz-form [formGroup]="validateForm">
<nz-form-item>
<nz-form-control nzErrorTip="">
<nz-input-group>
<input name="oldpassword" nz-input type="password" formControlName="oldpassword" placeholder="请输入原密码" autocomplete="off" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input name="newpassword" nz-input type="password" formControlName="newpassword" placeholder="请输入新密码"
autocomplete="off" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input name="affirmpassword" nz-input type="password" formControlName="affirmpassword" placeholder="确认新密码"
autocomplete="new-password" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
</form>
</div>

0
src/app/pages/change-password/change-password.component.scss

45
src/app/pages/change-password/change-password.component.ts

@ -0,0 +1,45 @@
import { Component, OnInit, Input } from '@angular/core';
import { NzModalRef } from 'ng-zorro-antd/modal';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
@Component({
selector: 'app-change-password',
templateUrl: './change-password.component.html',
styleUrls: ['./change-password.component.scss']
})
export class ChangePasswordComponent implements OnInit {
constructor(private modal: NzModalRef, private fb: FormBuilder, private http: HttpClient) { }
validateForm!: FormGroup;
ngOnInit(): void {
const { password } = MyValidators;
this.validateForm = this.fb.group({
oldpassword: [null, [Validators.required]],
newpassword: [null, [Validators.required, password]],
affirmpassword: [null, [Validators.required, password]]
});
}
}
export type MyErrorsOptions = { 'zh-cn': string; en: string } & Record<string, NzSafeAny>;
export type MyValidationErrors = Record<string, MyErrorsOptions>;
export class MyValidators extends Validators {
static password(control: AbstractControl): MyValidationErrors | null {
const value = control.value;
if (isEmptyInputValue(value)) {
return null;
}
return isPassword(value) ? null : { mobile: { 'zh-cn': `长度 12 位以上,包含①大写字母、②小写字母、③数字、④特殊字符四种中的三种组合`, en: `Password phone number is not valid` } };
}
}
function isEmptyInputValue(value: NzSafeAny): boolean {
return value == null || value.length === 0;
}
function isPassword(value: string): boolean {
return typeof value === 'string' && /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{12,99}$/.test(value);
}

252
src/app/pages/criminal-records-admin/criminal-records-admin.component.html

@ -0,0 +1,252 @@
<div class="recordsboxadmin" id="recordsboxadmin">
<div class="content">
<div class="title">
<div class="titlebox">
<img src="../../../assets/images/logosm.png" alt="">
<div class="content">
<div class="contentitem">
<span>预警类型统计</span>
<span class="grey" (click)="goOilList()">卸油统计</span>
<span class="grey" (click)="goWarningList()">证照预警统计</span>
</div>
</div>
</div>
<img (click)="isEchartsShow()" class="packup" src="../../../assets/images/packup.png" alt="">
</div>
<div class="search" [hidden]="!isEcharts">
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear id="level" formControlName="level" nzPlaceHolder="请选择预警级别">
<nz-option nzValue="1" nzLabel="一级"></nz-option>
<nz-option nzValue="2" nzLabel="二级"></nz-option>
<nz-option nzValue="3" nzLabel="三级"></nz-option>
<nz-option nzValue="4" nzLabel="四级"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParamsLong">
<nz-form-control>
<nz-tree-select [nzAllowClear]="false" [nzDropdownClassName]="'maxHeightTreeSelect'" nzShowSearch
[(ngModel)]="defaultOrId" formControlName="organization" [nzNodes]="nodes" nzPlaceHolder="请选择所属机构"
[nzExpandedIcon]="multiExpandedIconTpl">
</nz-tree-select>
<ng-template #multiExpandedIconTpl let-node let-origin="origin">
<ng-container *ngIf="node.children.length == 0; else elseTemplate">
</ng-container>
<ng-template #elseTemplate>
<i nz-icon [nzType]="node.isExpanded ? 'caret-down' : 'caret-right'"
class="ant-tree-switcher-line-icon"></i>
</ng-template>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear id="type" (ngModelChange)="typeChange($event)" formControlName="type"
nzPlaceHolder="请选择预警类型">
<nz-option *ngFor="let item of warningTypes" [nzValue]="item.key" [nzLabel]="item.key"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear formControlName="event" nzPlaceHolder="请选择预警事件">
<nz-option *ngFor="let item of warningTypesDetails" [nzValue]="item.id" [nzLabel]="item.eventSystemName">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear id="site" formControlName="site" nzPlaceHolder="请选择区域">
<nz-option nzValue="出入口" nzLabel="出入口"></nz-option>
<nz-option nzValue="加油区" nzLabel="加油区"></nz-option>
<nz-option nzValue="油罐区" nzLabel="油罐区"></nz-option>
<nz-option nzValue="便利店" nzLabel="便利店"></nz-option>
<nz-option nzValue="办公区" nzLabel="办公区"></nz-option>
<nz-option nzValue="其他区域" nzLabel="其他区域"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear formControlName="disposalState" nzPlaceHolder="请选择处置状态">
<nz-option nzValue="0" nzLabel="已处置"></nz-option>
<nz-option nzValue="1" nzLabel="未处置"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParams2">
<nz-form-control>
<nz-range-picker [nzAllowClear]="false" formControlName="datePicker"></nz-range-picker>
<br />
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="submit" class="submit"><i nz-icon [nzType]="'search'"></i>查询</button>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="button" class="reset" (click)="resetForm($event)"><i nz-icon
[nzType]="'sync'"></i>重置</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div class="chartsbox" [hidden]="!isEcharts">
<div class="chart">
<div class="leftbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
预警类别统计
</span>
<div class="centerContent">
<div class="numname">预警事件总数</div>
<div class="num">{{num}}</div>
</div>
<div class="piechart" id="piechart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
<div class="rightbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
近一个月预警统计
</span>
<div class="btnbox">
<div class="btn" (click)="echartClick('分布')" [ngClass]="{'selectedbtn': selectedType == '分布'}">统计</div>
<div class="rankingBtnbox" (mouseenter)="mouseEnter()" (mouseleave)="mouseleave()">
<div class="btn"
[ngClass]="{'selectedbtn': (selectedRankingType == '站点排名' || selectedRankingType == '事件排名')}">排名</div>
<div class="btn rankingBtn" *ngIf="isMouseEnter" (click)="echartClick2('站点排名')"
[ngClass]="{'selectedbtn': selectedRankingType == '站点排名'}">油站</div>
<div class="btn rankingBtn" *ngIf="isMouseEnter" (click)="echartClick2('事件排名')"
[ngClass]="{'selectedbtn': selectedRankingType == '事件排名'}">事件</div>
</div>
</div>
<div class="barchart" id="barchart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
</div>
</div>
<div class="title">
<app-title [name]="'预警类型统计'"></app-title>
</div>
<div class="tablebox">
<div class="table">
<div nz-row class="th">
<div nz-col nzSpan="1" style="text-align: center;">
<span>序号</span>
</div>
<div nz-col nzSpan="2" style="text-align: center;">
<span style="margin-right:46px;">
预警级别
</span>
</div>
<div nz-col nzSpan="2">
预警类型
</div>
<div nz-col nzSpan="2">
预警事件
</div>
<div nz-col nzSpan="2">
所属公司
</div>
<div nz-col nzSpan="3">
管理区域
</div>
<div nz-col nzSpan="2">
加油站
</div>
<div nz-col nzSpan="2">
预警区域
</div>
<div nz-col nzSpan="2">
摄像头名称
</div>
<div nz-col nzSpan="3">
预警时间
</div>
<div nz-col nzSpan="2">
状态
</div>
<div nz-col nzSpan="1">
操作
</div>
</div>
<div class="tbody" id="tbody">
<div nz-row class="tr" *ngFor="let item of list;let key = index">
<div nz-col nzSpan="1" style="text-align: center;">
<span>{{key + 1}}</span>
</div>
<div nz-col nzSpan="2">
<img style="margin-left: 18px;" *ngIf="item.violation.level == 1" src="../../../assets/images/level1.png" alt="">
<img style="margin-left: 18px;" *ngIf="item.violation.level == 2" src="../../../assets/images/level2.png" alt="">
<img style="margin-left: 18px;" *ngIf="item.violation.level == 3" src="../../../assets/images/level3.png" alt="">
<img style="margin-left: 18px;" *ngIf="item.violation.level == 4" src="../../../assets/images/level4.png" alt="">
<span *ngIf="item.violation.level == 1">Ⅰ级</span>
<span *ngIf="item.violation.level == 2">Ⅱ级</span>
<span *ngIf="item.violation.level == 3">Ⅲ级</span>
<span *ngIf="item.violation.level == 4">Ⅳ级</span>
</div>
<div nz-col nzSpan="2" [title]="item.violation.violationType">
{{item.violation.violationType}}
</div>
<div nz-col nzSpan="2" [title]="item.violation.eventSystemName">
{{item.violation.eventSystemName}}
</div>
<div nz-col nzSpan="2" [title]="item.gasStation.companyName">
{{item.gasStation.companyName}}
</div>
<div nz-col nzSpan="3" [title]="item.gasStation.locationName">
{{item.gasStation.locationName}}
</div>
<div nz-col nzSpan="2" [title]="item.gasStation.stationName">
{{item.gasStation.stationName}}
</div>
<div nz-col nzSpan="2" [title]="item.violateArea">
{{item.violateArea}}
</div>
<div nz-col nzSpan="2" [title]="item.cameraNo">
{{item.cameraNo}}
</div>
<div nz-col nzSpan="3">
{{item.violateTime | date:"yyyy-MM-dd HH:mm:ss"}}
</div>
<div nz-col nzSpan="2">
<span *ngIf="item.handleTime">已处置</span>
<span *ngIf="!item.handleTime" style="color: #FF4B65;">未处置</span>
</div>
<div nz-col nzSpan="1">
<span class="look" (click)="look(item)" style="margin-right: 12px;">查看</span>
<!-- <span *ngIf="!item.handleTime" style="color: #36A2FF;cursor: pointer;" (click)="dispose(item)">处置</span>
<span *ngIf="item.handleTime" style="color: rgba(145, 204, 255, 0.24);;">处置</span> -->
</div>
</div>
<div nz-row class="tr" *ngIf="tableSpin">
<div nz-col nzSpan="24" style="text-align: center;">
<nz-spin nzSimple></nz-spin>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

612
src/app/pages/criminal-records-admin/criminal-records-admin.component.scss

@ -0,0 +1,612 @@
.recordsboxadmin {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.search {
box-sizing: border-box;
padding: 0 36px;
width: 100%;
height: 32px;
margin-bottom: 16px;
form {
width: 100%;
height: 32px;
display: flex;
justify-content: flex-start;
.searchParams,
.btn {
margin: 0 3px;
}
.searchParams {
// flex: 5;
width: 150px;
}
.searchParamsLong {
width: 250px;
}
.searchParams2 {
width: 220px;
}
.btn {
// flex: 1;
}
nz-select {
color: rgba(145, 204, 255, 0.95);
}
nz-tree-select {
color: rgba(145, 204, 255, 0.95);
}
nz-range-picker {
background-color: rgba(0, 0, 0, 0);
width: 100%;
}
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
width: 100%;
height: 64px;
box-sizing: border-box;
padding: 0 28px;
margin: 13px 0;
position: relative;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 65px;
height: 65px;
}
.content {
flex: 1;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
// background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%);
.contentitem {
width: 100%;
height: 32px;
display: flex;
align-items: center;
// background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%);
span {
margin-left: 10px;
color: #bce0ff;
font-size: 20px;
font-family: titlefont;
cursor: pointer;
}
span:nth-child(1) {
margin-left: 12px;
}
.grey {
color: #68829F;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 16px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
display: flex;
justify-content: center;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 98%;
height: 350px;
box-sizing: border-box;
padding: 0 10px;
display: flex;
div {
display: flex;
flex-direction: column;
span {
font-family: titlefont;
display: flex;
align-items: center;
height: 28px;
color: #bee1ff;
font-size: 16px;
}
div {
flex: 1;
}
}
.leftbox {
width: 360px;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
margin-right: 16px;
.centerContent {
position: absolute;
top: 42%;
left: 50%;
transform: translateX(-50%);
width: 170px;
div {
text-align: center;
}
.numname {
font-family: titlefont;
color: #bee1ff;
}
.num {
color: #FFFFFF;
font-size: 42px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 49px;
line-height: 50px;
}
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.btn {
width: 64px;
height: 30px;
text-align: center;
line-height: 30px;
// border: 1px solid #91CCFF;
color: #91CCFF;
border-radius: 0px;
box-shadow: 0 0 5px 1px #2399FF inset;
background: none;
cursor: pointer;
}
.rankingBtnbox {
display: flex;
flex-direction: column;
}
.selectedbtn {
background: linear-gradient(180deg, #000D21 0%, #001331 27%, #2399FF 100%);
color: white;
}
}
}
}
}
.tablebox {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
.table {
color: white;
flex: 1;
width: 96%;
display: flex;
flex-direction: column;
overflow: hidden;
.th {
height: 38px;
line-height: 38px;
background: rgba(35, 153, 255, 0.2);
border: 1px solid rgba(35, 217, 255, 0.4);
box-shadow: 0 0 3px 0 rgba(35, 217, 255, 0.4) inset;
color: #23D9FF;
}
.tbody {
flex: 1;
overflow-y: auto;
.tr {
height: 38px;
line-height: 38px;
border-bottom: 1px solid #0d3761;
div {
color: #91CCFF;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.look {
color: #36A2FF;
cursor: pointer;
}
}
img {
width: 36px;
}
}
}
}
.pagination {
margin: 15px 0;
display: flex;
align-items: center;
justify-content: center;
}
::-webkit-scrollbar {
width: 0px;
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.search {
box-sizing: border-box;
padding: 0 30px;
height: 32px;
margin-bottom: 12px;
form {
width: 100%;
height: 32px;
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
height: 42px;
padding: 0 20px;
margin: 8px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 46px;
height: 46px;
}
.content {
height: 36px;
.contentitem {
width: 100%;
height: 25px;
span {
margin-left: 6px;
font-size: 16px;
}
span:nth-child(1) {
margin-left: 8px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 4px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 43%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 300px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 12px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 42px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 49px;
line-height: 50px;
}
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 12px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 32px;
line-height: 32px;
font-size: 12px !important;
}
.tbody {
.tr {
height: 32px;
line-height: 32px;
div {
font-size: 12px !important;
}
img {
width: 32px;
}
}
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.search {
box-sizing: border-box;
padding: 0 22px;
height: 32px;
margin-bottom: 6px;
form {
width: 100%;
height: 32px;
}
}
.content {
.title {
height: 36px;
padding: 0 20px;
margin: 3px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 36px;
height: 36px;
}
.content {
height: 30px;
.contentitem {
width: 100%;
height: 22px;
span {
margin-left: 6px;
font-size: 13px;
}
span:nth-child(1) {
margin-left: 12px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 2px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 40%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 260px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 8px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 32px;
text-shadow: 0px 0px 12px #3A9AFF;
font-weight: bold;
height: 42px;
line-height: 42px;
}
}
}
.rightbox {
box-shadow: 0 0 22px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 8px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 28px;
line-height: 28px;
font-size: 10px !important;
}
.tbody {
.tr {
height: 28px;
line-height: 28px;
div {
font-size: 10px !important;
}
img {
width: 30px;
}
}
}
}
}
}
}

739
src/app/pages/criminal-records-admin/criminal-records-admin.component.ts

@ -0,0 +1,739 @@
import { HttpClient } from '@angular/common/http';
import { Component, ElementRef, OnInit, ViewContainerRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router'
import * as echarts from 'echarts';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import * as moment from 'moment';
import { NzModalService } from 'ng-zorro-antd/modal';
import { GetOutOfLineDetailsComponent } from '../today-warning/get-out-of-line-details/get-out-of-line-details.component';
import { NzMessageService } from 'ng-zorro-antd/message';
import { TreeService } from 'src/app/service/tree.service';
import { DisposeequipmentComponent } from '../warning-statistics-list/disposeequipment/disposeequipment.component';
@Component({
selector: 'app-criminal-records-admin',
templateUrl: './criminal-records-admin.component.html',
styleUrls: ['./criminal-records-admin.component.scss']
})
export class CriminalRecordsAdminComponent implements OnInit {
validateForm!: FormGroup;
constructor(private element: ElementRef, private toTree: TreeService, private http: HttpClient, private fb: FormBuilder, private router: Router, private modal: NzModalService, private viewContainerRef: ViewContainerRef, private message: NzMessageService) { }
//饼图
myChart
option = {
color: ['#FF4B65', '#23D9FF', '#608AFF', '#B2FF6D', '#FFFF99', '#C4E2FC', '#FF7F00', '#0090FF', '#FFD634', '#105597', '#FF4B65', '#23D9FF', '#71FFF5', '#B2FF6D'],
tooltip: {
trigger: 'item'//触发类型
},
series: [
{
// name: 'Access From',
type: 'pie',
radius: ['58%', '75%'],//内半径外,外半径
left: '0',
top: '9%',
avoidLabelOverlap: false,//防止标签重叠策略
label: {//每一个标签外网延伸的引导说明
show: false,
position: 'outside'
},
labelLine: {//引导线
show: true,
showAbove: true
},
emphasis: {//中间高亮区域
label: {
show: false,
fontSize: '40',
fontWeight: 'bold'
}
},
data: [
],
tooltip: {//鼠标移入提示
position: 'right',
padding: [14, 19],
backgroundColor: 'rgba(28, 129, 218, 0.4)',
textStyle: {
color: '#fff',
fontSize: 12
},
formatter: "{b} : {c} ({d}%)"
}
}
]
};
//柱状图
mybarChart: any
baroption = {
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF'
}
},
axisTick: {//刻度线
show: false
},
inverse: true
},
yAxis: {
type: 'value',
nameTextStyle: {
color: '#C4E2FC'
},
splitLine: {//分割线
lineStyle: {
color: ['#0f4374'],
width: 2
}
},
axisTick: {//刻度线
show: false
},
axisLine: {//轴线
show: false,
lineStyle: {
color: '#C4E2FC'
}
}
},
tooltip: {
// trigger: 'axis'
},
series: [
{
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#23F0FF' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(35, 153, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
data: [],
type: 'line',
symbol: 'circle',
symbolSize: 8,
label: {
show: true
},
itemStyle: {
color: '#fff',
shadowColor: '#fff',
shadowBlur: 10
},
lineStyle: {
color: '#FFCC8A',
width: 1
}
}
],
grid: {
left: '42px',
right: '30px',
bottom: '38px',
top: '80px'
}
};
baroption2 = {
xAxis: {
type: 'value',
show: false
},
tooltip: {
// trigger: 'axis'
},
yAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF',
}
},
axisTick: {//刻度线
show: false
},
axisLabel: {
formatter: function (value, index) {
let newParamsName = '';
const paramsNameNumber = value.length;
const provideNumber = 10;
const rowNumber = Math.ceil(paramsNameNumber / provideNumber);
if (paramsNameNumber > provideNumber) {
for (let p = 0; p < rowNumber; p++) {
let tempStr = '';
const start = p * provideNumber;
const end = start + provideNumber;
if (p == rowNumber - 1) {
tempStr = value.substring(start, paramsNameNumber);
} else {
tempStr = value.substring(start, end) + '\n';
}
newParamsName += tempStr;
}
} else {
newParamsName = value;
}
// 格式化成月/日,只在第一个刻度显示年份
return '{s|·}' + `{a|${newParamsName}}`;
},
rich: {
a: {
color: '#C4E2FC',
padding: [0, 0, 0, 8],
},
s: {
color: '#fff',
borderWidth: 1,
borderColor: '#23D9FF',
backgroundColor: '#fff',
width: 4,
height: 4,
shadowBlur: 3,
shadowColor: "#fff"
}
}
},
inverse: true
},
series:
{
label: {
// 柱图头部显示值
show: true,
position: "right",
color: "#fff",
fontSize: 12,
formatter: '{c}',
offset: [6, 0]
},
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#063d72' // 0% 处的颜色
}, {
offset: 1, color: '#FF9963' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '36%',
}
,
grid: {
left: '150px',
right: '80px',
bottom: '3px',
top: '36px'
},
// dataZoom: [ //Y轴滑动条
// {
// type: 'slider', //滑动条
// show: true, //开启
// yAxisIndex: 0,//表示控制第几个y轴
// left: '97%', //滑动条位置
// start: 1, //初始化时,滑动条宽度开始标度
// end: 100, //初始化时,滑动条宽度结束标度<br>
// maxValueSpan: 10,//显示数据的条数(默认显示10个)
// showDataShadow: false,//是否显示数据阴影 默认auto
// showDetail: false,//即拖拽时候是否显示详细数值信息 默认true
// realtime: true, //是否实时更新
// filterMode: 'filter',
// backgroundColor: '#001735',
// width: '18'
// },
// {
// type: 'inside',
// yAxisIndex: 0,
// zoomOnMouseWheel: false, //滚轮是否触发缩放
// moveOnMouseMove: true, //鼠标滚轮触发滚动
// moveOnMouseWheel: true
// }
// ]
}
isEcharts: boolean = true
isEchartsShow() {
this.isEcharts = !this.isEcharts
}
startdate
enddate
ngOnInit(): void {
//当前日期
let myDate: any = new Date();
let nowY = myDate.getFullYear();
let nowM = myDate.getMonth() + 1;
let nowD = myDate.getDate();
this.enddate = nowY + "-" + (nowM < 10 ? "0" + nowM : nowM) + "-" + (nowD < 10 ? "0" + nowD : nowD);//当前日期
//获取三十天前日期
let lw = new Date(myDate - 1000 * 60 * 60 * 24 * 30);//最后一个数字30可改,30天的意思
let lastY = lw.getFullYear();
let lastM = lw.getMonth() + 1;
let lastD = lw.getDate();
this.startdate = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD);//三十天之前日期
this.validateForm = this.fb.group({
level: [null],
organization: [null],
type: [null],
event: [null],
site: [null],
disposalState: [null],
datePicker: [[this.startdate, this.enddate]]
});
//饼图
this.myChart = echarts.init(document.getElementById('piechart'));
this.myChart.setOption(this.option);
//柱状折线图
this.mybarChart = echarts.init(document.getElementById('barchart'));
this.mybarChart.setOption(this.baroption);
this.warningType()
this.tableSpin = true
this.getAllOrganization()
this.getAggregations()
}
defaultOrId: string
//获取所有组织机构
nodes: any = []
getAllOrganization() {
let OrganizationUnitId = sessionStorage.getItem('isGasStation') == 'true' ? JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id : JSON.parse(sessionStorage.getItem('userdata')).organization.id
let params = {
OrganizationUnitId: OrganizationUnitId,
IsContainsChildren: "true"
}
this.http.get('/api/services/app/Organization/GetAll', {
params: params
}).subscribe((data: any) => {
data.result.items.forEach(element => {
if (element.id == OrganizationUnitId) {
element.parentId = null
}
element.key = element.id
element.title = element.displayName
});
this.nodes = [...this.toTree.toTree(data.result.items)]
this.defaultOrId = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.value.organization = this.defaultOrId
this.getViolateRecordList()
})
}
//刷新饼图图表数据
num
echartsData: any
refreshPieData(data) {
//饼图
let option = this.myChart.getOption();
var num = 0
data.pieTop.forEach(element => {
num += element.count
element.name = element.key
element.value = element.count
});
this.num = num
option.series[0].data = data.pieTop;
this.myChart.setOption(option);
}
//刷新柱状折线图表数据
refreshBarLineData(data, type) {
console.log('统计图表数据', data)
//柱状图
let option = this.mybarChart.getOption();
console.log('柱图option', option)
if (type == 'month') {//近一个月柱状折线图
option = this.baroption
let monthArr = []
let valuedata = []
data.timeTop.forEach(element => {
monthArr.push(moment(element.key).format('MM.DD'))
valuedata.push(element.count)
});
option.xAxis.data = monthArr
option.series[0].data = valuedata
option.series[1].data = valuedata
} else if (type == 'eventTop') {
option = this.baroption2
let ydata = []
let valuedata = []
data.eventTop.forEach(element => {
ydata.push(element.key)
valuedata.push(element.count)
});
option.yAxis.data = ydata
option.series.data = valuedata
} else if (type == 'siteTop') {
option = this.baroption2
let ydata = []
let valuedata = []
data.siteTop.forEach(element => {
ydata.push(element.key)
valuedata.push(element.count)
});
option.yAxis.data = ydata
option.series.data = valuedata
}
this.mybarChart.setOption(option);
}
//获取统计信息
chartsSpin: boolean = false
getAggregations() {
this.chartsSpin = true
let ViolationIds = []
if (this.validateForm.value.type) {
this.warningTypesDetails.forEach(item => {
item.id ? ViolationIds.push(item.id) : null
});
}
let body: any = {
organizationUnitId: JSON.parse(sessionStorage.getItem('userdata')).organization.id,
isContainsChildren: true,
ViolateTime: this.validateForm.value.datePicker ? [moment(this.validateForm.value.datePicker[0]).format('yyyy-MM-DD'), moment(this.validateForm.value.datePicker[1]).format('yyyy-MM-DD')] : null
}
this.validateForm.value.level ? body.level = this.validateForm.value.level : null
this.validateForm.value.site ? body.violateArea = this.validateForm.value.site : null
ViolationIds.length != 0 ? body.violationType = ViolationIds : null
this.http.post('/api/services/app/ViolateRecord/Aggregations', body).subscribe((data: any) => {
this.echartsData = data.result
this.chartsSpin = false
this.refreshPieData(data.result)
this.refreshBarLineData(this.echartsData, 'month')
})
}
//获得违规记录列表
SkipCount: string = '0'
MaxResultCount: string = '50'
list: any = []
totalCount: string
tableSpin: boolean = false
getViolateRecordList() {
let ViolationIds = []
if (this.validateForm.value.event) {
ViolationIds.push(this.validateForm.value.event)
}
if (this.validateForm.value.type && !this.validateForm.value.event) {
this.warningTypesDetails.forEach(item => {
item.id ? ViolationIds.push(item.id) : null
});
}
let disposalState
if (this.validateForm.value.disposalState == '0') {
disposalState = true
} else if (this.validateForm.value.disposalState == '1') {
disposalState = false
} else {
disposalState = null
}
let params = {
Level: this.validateForm.value.level,
ViolationIds: ViolationIds,
ViolateArea: this.validateForm.value.site,
OrganizationUnitId: JSON.parse(sessionStorage.getItem('userdata')).organization.id,
IsContainsChildren: 'true',
IsHandled: disposalState,
ViolateTime: this.validateForm.value.datePicker ? [moment(this.validateForm.value.datePicker[0]).format('yyyy-MM-DD'), moment(this.validateForm.value.datePicker[1]).format('yyyy-MM-DD')] : null,
SkipCount: this.SkipCount,
MaxResultCount: this.MaxResultCount
}
this.tableSpin = true
this.http.get('/api/services/app/ViolateRecord/GetAll', {
params: params
}).subscribe((data: any) => {
this.list = this.list.concat(data.result.items);
this.list = [...this.list]
// this.list = data.result.items
this.totalCount = data.result.totalCount
console.log('违规记录列表', data)
this.tableSpin = false
console.log(this.list.length)
})
}
isMouseEnter = false
mouseEnter() {
this.isMouseEnter = true
}
mouseleave() {
this.isMouseEnter = false
}
ngAfterViewInit(): void {
fromEvent(this.element.nativeElement.querySelector(`#tbody`) as HTMLCanvasElement, 'scroll').pipe(debounceTime(100)).subscribe((event: any) => { //监听 DOM 滚动事件
if (event.target.scrollHeight - (event.target.scrollTop + event.target.clientHeight) <= 10) {
if (this.totalCount > this.list.length) {
console.log('需要加载数据了', event)
this.SkipCount = String(Number(this.SkipCount) + 50)
this.getViolateRecordList()
}
}
});
}
getThirtyDays() {
//获取当前日期
let myDate = new Date();
var nowY = myDate.getFullYear();
var nowM = myDate.getMonth() + 1;
var nowD = myDate.getDate();
var enddateStr = nowY + "-" + (nowM < 10 ? "0" + nowM : nowM) + "-" + (nowD < 10 ? "0" + nowD : nowD);//当前日期
var enddate = new Date(enddateStr);
//获取三十天前日期
var lw = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 30);//最后一个数字30可改,30天的意思
var lastY = lw.getFullYear();
var lastM = lw.getMonth() + 1;
var lastD = lw.getDate();
var startdateStr = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD);//三十天之前日期
var startDate = new Date(startdateStr);
const dateList = []
while (true) {
startDate.setDate(startDate.getDate() + 1)
if (startDate.getTime() <= enddate.getTime()) {
if (startDate.getDate() < 10) {
// startDate.getFullYear() 获取年,此处没加上年份
dateList.push((startDate.getMonth() + 1) + '.0' + startDate.getDate())
} else {
dateList.push((startDate.getMonth() + 1) + '.' + startDate.getDate())
}
} else {
break
}
}
return dateList;
}
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
// this.getAggregations()
}
resetForm(e: MouseEvent): void {
e.preventDefault();
this.validateForm.reset();
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
this.validateForm.patchValue({
organization: JSON.parse(sessionStorage.getItem('userdata')).organization.id,
datePicker: [this.startdate, this.enddate]
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
//预警类型接口
warningTypes: any //预警接口数据
warningTypesDetails: any
warningType() {
this.http.get('/api/services/app/Violation/GetAllList').subscribe((data: any) => {
this.warningTypesDetails = data.result
this.warningTypes = (data.result as any).groupBy((t) => { return t.violationType });
})
}
typeChange(e) {
this.warningTypes.forEach(element => {
if (element.key == e) {
this.warningTypesDetails = element
}
});
this.validateForm.patchValue({
event: null,
});
}
look(item) {
console.log('点击item', item)
if (item.violation.eventSystemName == '灭火器维护') {
item.violatedItemSnapshotObj = JSON.parse(item.violatedItemSnapshot)
const modal = this.modal.create({
nzContent: DisposeequipmentComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 380,
nzBodyStyle: {
'border': '1px solid #91CCFF',
'border-radius': '0px',
'padding': '7px',
'box-shadow': '0 0 8px 0 #fff',
'background-image': 'linear-gradient(#003665, #000f25)'
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzClosable: false,
nzOnOk: async () => {
if (instance.isScrap) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.copydata2.violatedItemSnapshotObj.name,
storageLocation: instance.copydata2.violatedItemSnapshotObj.storageLocation,
productionDate: moment(instance.copydata2.violatedItemSnapshotObj.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.copydata2.violatedItemSnapshotObj.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.copydata2.violatedItemSnapshotObj.validityEndTime).format('yyyy-MM-DD'),
isScrapped: true,
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: item.id,
handleRecord: '报废成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '报废成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
if (instance.validateForm.valid) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.validateForm.value.name,
storageLocation: instance.validateForm.value.storageLocation,
productionDate: moment(instance.validateForm.value.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.validateForm.value.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.validateForm.value.validityEndTime).format('yyyy-MM-DD'),
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
// item.violatedItemSnapshotObj = data.result
let body = {
id: item.id,
handleRecord: '维保成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '维保成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
}
});
const instance = modal.getContentComponent();
} else {
const modal = this.modal.create({
nzContent: GetOutOfLineDetailsComponent,
nzWrapClassName: "vertical-center-modal",
nzViewContainerRef: this.viewContainerRef,
nzWidth: (document.documentElement.clientHeight < 650 || document.documentElement.clientWidth < 1400) ? 1000 : 1200,
nzBodyStyle: {
'border': '1px solid #6d9cc7',
'border-radius': '0px',
'padding': '0px',
'box-shadow': '0 0 8px 0 #fff',
'background': '#000D21',
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzOnOk: async () => {
}
});
const instance = modal.getContentComponent();
}
}
selectedType = '分布'
selectedRankingType = null
echartClick(type) {
this.selectedType = type
this.mybarChart.dispose()
this.mybarChart = echarts.init(document.getElementById('barchart'));
// if (type == '排名') {
// console.log(this.selectedRankingType)
// if (this.selectedRankingType == '站点排名') {
// this.refreshBarLineData(this.echartsData, 'siteTop')
// }
// if (this.selectedRankingType == '事件排名') {
// this.refreshBarLineData(this.echartsData, 'eventTop')
// }
// } else {
// }
this.selectedRankingType = null
this.refreshBarLineData(this.echartsData, 'month')
}
echartClick2(type) {
this.mybarChart.dispose()
this.mybarChart = echarts.init(document.getElementById('barchart'));
this.selectedType = null
this.selectedRankingType = type
if (this.selectedRankingType == '站点排名') {
this.refreshBarLineData(this.echartsData, 'siteTop')
}
if (this.selectedRankingType == '事件排名') {
this.refreshBarLineData(this.echartsData, 'eventTop')
}
}
//跳转卸油统计页面
goOilList() {
this.router.navigate(['/records/oliunloadinglist'])
}
goWarningList() {
this.router.navigate(['/records/warningstatisticslist'])
}
}

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

@ -0,0 +1,110 @@
<div class="box">
<!-- <div>
<app-tabbar></app-tabbar>
</div> -->
<div class="menu">
<div class="boxleft">
<img src="../../../assets/images/logo2.png" alt="">
</div>
<div class="libox">
<li [routerLink]="['/records']" routerLinkActive="router-link-active">
预警误报审核
</li>
</div>
<!-- 登录信息按钮 -->
<div class="boxright">
<img *ngIf="!isfullscreen" (click)="fullscreenToggle()" style="margin-right: 8px;cursor: pointer;"
src="../../../assets/images/fullscreen.png" alt="" title="全屏">
<img *ngIf="isfullscreen" (click)="closefullscreen()" style="margin-right: 8px;cursor: pointer;"
src="../../../assets/images/fullscreen.png" alt="" title="全屏">
<span class="time">
{{time}}
</span>
<span style="margin: 0 12px;">|</span>
<span style="margin-right: 8px;"> {{surname}} </span>
<a nz-dropdown [nzDropdownMenu]="menu" [nzTrigger]="'click'" [nzBackdrop]='false'>
<img src="../../../assets/images/head.png" alt="">
</a>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu nzSelectable>
<li nz-menu-item (click)="changePassword()">修改密码</li>
<li nz-menu-item (click)="signOut()">退出系统</li>
</ul>
</nz-dropdown-menu>
<span style="margin: 0 12px;" *ngIf="isGasStationBack">|</span>
<img style="cursor: pointer;" *ngIf="isGasStationBack" src="../../../assets/images/goback.png" alt=""
(click)="goback()">
</div>
</div>
<div class="content">
<router-outlet></router-outlet>
</div>
</div>
<ng-template #warning let-item="data">
<div class="topbox">
<div>
<img src="../assets/images/warning.png" alt="">
</div>
<div class="text">
<span class="name">您有一条新的预警提醒!</span>
<span class="details">{{item.notification.data.properties.ViolationName}}</span>
</div>
</div>
<div class="btnbox">
<div class="look" (click)="look(item)">
查看
</div>
<div class="lose" (click)="close(item)">
忽略
</div>
</div>
</ng-template>
<!-- 修改密码 -->
<nz-modal [(nzVisible)]="isVisible" [nzTitle]="modalTitle" [nzContent]="modalContent" [nzFooter]="modalFooter"
[nzWidth]="350">
<ng-template #modalTitle>
修改初始密码
</ng-template>
<ng-template #modalContent>
<form nz-form [formGroup]="passwordValidateForm">
<nz-form-item>
<nz-form-control nzErrorTip="">
<nz-input-group>
<input name="oldpassword" type="password" nz-input formControlName="oldpassword" placeholder="请输入原密码"
autocomplete="off" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input name="newpassword" nz-input type="password" formControlName="newpassword" placeholder="请输入新密码"
autocomplete="off" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input name="affirmpassword" nz-input type="password" formControlName="affirmpassword" placeholder="确认新密码"
autocomplete="new-password" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #modalFooter>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">确定</button>
</ng-template>
</nz-modal>

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

@ -0,0 +1,235 @@
.box {
width: 100%;
height: 100%;
overflow: hidden;
// background-image: radial-gradient(closest-side at 50% 55%,#03447c, #02325c, #002046);
background: radial-gradient(closest-side at 50% 55%, #004988 0%, #00122D 100%);
display: flex;
flex-direction: column;
}
.menu {
height: 56px;
width: 100%;
display: flex;
justify-content: center;
font-size: 17px;
background: url('../../../assets/images/navbg.png') no-repeat;
background-size: 100% 115%;
position: relative;
.libox {
width: 33%;
display: flex;
li {
flex: 1;
height: 52px;
line-height: 52px;
text-align: center;
cursor: pointer;
font-family: sybold;
color: #EBFAFF;
}
}
}
.boxleft {
position: absolute;
left: 24px;
top: 16px;
img {
width: 154px;
}
}
.boxright {
position: absolute;
right: 24px;
top: 12px;
display: flex;
align-items: center;
span {
font-size: 16px;
color: #FFFFFF;
opacity: 0.6;
}
img {
width: 36px;
height: 36px;
}
}
.backbtn {
position: absolute;
left: 205px;
bottom: 6px;
button {
width: 64px;
height: 32px;
background: rgba(0, 129, 255, 0.3);
border: 1px solid #36A2FF;
border-radius: 0px;
color: #91CCFF;
}
}
.warningnumber {
position: absolute;
left: 20px;
top: 0;
display: flex;
align-items: flex-start;
img {
margin-bottom: 30px;
}
.num {
font-size: 50px;
text-shadow: 0px 0px 6px #8df;
color: white;
font-weight: 600;
margin-top: -5px;
}
.today {
font-size: 19px;
font-family: titlefont;
color: #D0EAFF;
margin-top: 11px;
margin-left: 10px;
}
}
.content {
flex: 1;
overflow: hidden;
}
.router-link-active {
// background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, #1c8199 50%, rgba(35, 153, 255, 0) 100%);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, #36A2FF 50%, rgba(35, 153, 255, 0) 100%);
}
// 适配125%
@media screen and (max-height: 750px) {
.menu {
height: 42px;
font-size: 14px;
.libox {
width: 33%;
li {
height: 42px;
line-height: 42px;
}
}
}
.boxleft {
left:30px;
top: 12px;
img {
width: 125px;
}
}
.boxright {
right: 24px;
top: 13px;
span {
font-size: 13px;
opacity: 0.6;
}
img {
width: 26px;
height: 26px;
}
}
.backbtn {
left: 176px;
bottom: 3px;
button {
width: 46px;
height: 25px;
line-height: 25px;
font-size: 10px;
text-align: center;
padding: 0;
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.menu {
height: 32px;
font-size: 8px;
.libox {
width: 33%;
li {
height: 32px;
line-height: 32px;
}
}
}
.boxleft {
left: 24px;
top: 8px;
img {
width: 105px;
}
}
.boxright {
right: 24px;
top: 10px;
span {
font-size: 8px;
opacity: 0.6;
}
img {
width: 20px;
height: 20px;
}
}
.backbtn {
left: 156px;
bottom: 0px;
button {
width: 46px;
height: 25px;
line-height: 25px;
font-size: 8px;
text-align: center;
padding: 0;
}
}
}

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

@ -0,0 +1,456 @@
import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
import { NavChangeService } from '../../service/navChange.service';
import { CacheTokenService } from '../../service/cache-token.service' //引入服务
import { NzMessageService } from 'ng-zorro-antd/message';
import { SignalRAspNetCoreHelper } from '../../../shared/helpers/SignalRAspNetCoreHelper';
import { NzNotificationService } from 'ng-zorro-antd/notification';
import { GetOutOfLineDetailsComponent } from '../today-warning/get-out-of-line-details/get-out-of-line-details.component';
import { NzModalService } from 'ng-zorro-antd/modal';
import { HttpClient } from '@angular/common/http';
import { ChangePasswordComponent, MyValidators } from '../change-password/change-password.component';
import { listRefreshService } from '../../service/listRefresh.service';
import { DisposeequipmentComponent } from '../warning-statistics-list/disposeequipment/disposeequipment.component';
declare var abp: any
import * as moment from 'moment';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
@ViewChild('warning', { static: false }) template?: TemplateRef<{}>;
passwordValidateForm!: FormGroup;
constructor(private listRefreshService: listRefreshService, private http: HttpClient, private router: Router, private navChangeService: NavChangeService, public token: CacheTokenService,
private message: NzMessageService, private notificationService: NzNotificationService, private modal: NzModalService, private viewContainerRef: ViewContainerRef, private fb: FormBuilder) {
const { password } = MyValidators;
this.passwordValidateForm = this.fb.group({
oldpassword: [null, [Validators.required]],
newpassword: [null, [Validators.required, password]],
affirmpassword: [null, [Validators.required, password]]
});
}
isGasStationNav: boolean
isGasStation: boolean
isGasStationBack: boolean
num
surname: string
userName: string
ngOnInit(): void {
this.navChangeService.getMessage().subscribe((message: any) => {
console.log(message);//send a message
if (message.name == 'oilstation') {
this.isGasStationNav = true
}
});
if (this.router.url.indexOf('petrolStation') != -1 && sessionStorage.getItem('isGasStation') == 'false') {//控制返回按钮显示
this.isGasStationBack = true
} else {
this.isGasStationBack = false
}
// if (this.router.url.indexOf('petrolStation') != -1 && sessionStorage.getItem('isGasStation') == 'true') {
// this.isGasStation = true
// } else {
// this.isGasStation = false
// }
if (sessionStorage.getItem('isGasStation') == 'true') {
this.isGasStation = true
this.isGasStationNav = true
} else {
this.isGasStation = false
this.isGasStationNav = false
}
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: any) => {
if (event.url.indexOf('petrolStation') != -1 && sessionStorage.getItem('isGasStation') == 'false') {//控制返回按钮显示
this.isGasStationBack = true
} else {
this.isGasStationBack = false
}
});
setInterval(() => {
this.getTime()
}, 1000);
this.isGasStation = JSON.parse(sessionStorage.getItem('isGasStation'))
if (this.isGasStation) {
this.surname = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).name
this.userName = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).userName
} else {
this.surname = JSON.parse(sessionStorage.getItem('userdata')).name
this.userName = JSON.parse(sessionStorage.getItem('userdata')).userName
}
if ((sessionStorage.getItem('isDefaultPassword') == 'true' || sessionStorage.getItem('isPasswordExpired') == 'true') && JSON.parse(sessionStorage.getItem('userdata')).userName != 'admin') {
this.changePasswordPopup()
}
}
//初次登陆修改密码弹窗
isVisible = false
isConfirmLoading = false
changePasswordPopup() {
this.isVisible = true
}
handleOk(): void {
console.log(this.passwordValidateForm)
if (this.passwordValidateForm.invalid) {
this.message.create('warning', `输入格式不正确`);
} else {
if (this.passwordValidateForm.value.newpassword != this.passwordValidateForm.value.affirmpassword) {
this.message.create('warning', '两次密码输入不一致!');
} else if (this.passwordValidateForm.value.newpassword == this.passwordValidateForm.value.oldpassword) {
this.message.create('warning', '旧密码和新密码不能相同!');
} else {
this.isConfirmLoading = true;
let body = {
currentPassword: this.passwordValidateForm.value.oldpassword,
newPassword: this.passwordValidateForm.value.newpassword
}
this.http.post('/api/services/app/User/ChangePassword', body).subscribe(data => {
this.message.create('success', '修改成功!');
this.isConfirmLoading = false;
this.isVisible = false;
//清除sessionStorage
sessionStorage.removeItem('isDefaultPassword')
}, err => {
this.message.create('warning', err.error.error.message);
this.isConfirmLoading = false;
})
}
}
}
reloadPage = (userNotification) => {
console.log('abp.notifications.received收到通知', userNotification);
if (this.router.url.indexOf('todaywarning') != -1) {
let obj = {
type: 'add',
data: userNotification
}
this.listRefreshService.sendMessage(obj);//发布一条消息
}
this.receiptOfNotification(userNotification)
};
ngAfterViewInit() {
SignalRAspNetCoreHelper.initSignalR();
abp.event.on('abp.notifications.received', this.reloadPage);
}
messageId = []
receiptOfNotification(userNotification) {
let obj = {
id: userNotification.notification.entityId,
messageId: this.notificationService.template(this.template!, { nzPlacement: 'bottomRight', nzClass: 'receiptOfNotification', nzDuration: 0, nzData: userNotification }).messageId
}
this.messageId.push(obj)
}
modalData
look(item) {
console.log('推送信息', item)
let params = {
id: item.notification.entityId
}
this.http.get('/api/services/app/ViolateRecord/Get', {
params: params
}).subscribe((data: any) => {
console.log('推送信息后获取信息', data)
setTimeout(() => {
let copydata = data.result
if (item.notification.data.properties.EventSystemName == '灭火器维护') {
copydata.violatedItemSnapshotObj = JSON.parse(copydata.violatedItemSnapshot)
const modal = this.modal.create({
nzContent: DisposeequipmentComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 380,
nzBodyStyle: {
'border': '1px solid #91CCFF',
'border-radius': '0px',
'padding': '7px',
'box-shadow': '0 0 8px 0 #fff',
'background-image': 'linear-gradient(#003665, #000f25)'
},
nzComponentParams: {
data: copydata
},
nzFooter: null,
nzClosable: false,
nzOnOk: async () => {
if (instance.isScrap) {
await new Promise(resolve => {
let body = {
id: copydata.violatedItemSnapshotObj.id,
isScrapped: true,
organizationUnitId: copydata.violatedItemSnapshotObj.organizationUnitId,
name: instance.copydata2.violatedItemSnapshotObj.name,
storageLocation: instance.copydata2.violatedItemSnapshotObj.storageLocation,
productionDate: moment(instance.copydata2.violatedItemSnapshotObj.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.copydata2.violatedItemSnapshotObj.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.copydata2.violatedItemSnapshotObj.validityEndTime).format('yyyy-MM-DD')
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: copydata.id,
handleRecord: '报废成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '报废成功!');
copydata.handleTime = new Date()
if (this.router.url.indexOf('todaywarning') != -1) {
let obj = {
type: 'updatehandleTime',
data: copydata.id
}
this.listRefreshService.sendMessage(obj);//发布一条消息
}
return true
})
})
})
} else {
if (instance.validateForm.valid) {
await new Promise(resolve => {
let body = {
id: copydata.violatedItemSnapshotObj.id,
name: instance.validateForm.value.name,
storageLocation: instance.validateForm.value.storageLocation,
productionDate: moment(instance.validateForm.value.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.validateForm.value.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.validateForm.value.validityEndTime).format('yyyy-MM-DD'),
organizationUnitId: copydata.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: copydata.id,
handleRecord: '维保成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '维保成功!');
copydata.handleTime = new Date()
if (this.router.url.indexOf('todaywarning') != -1) {
let obj = {
type: 'updatehandleTime',
data: copydata.id
}
this.listRefreshService.sendMessage(obj);//发布一条消息
}
return true
})
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
}
});
const instance = modal.getContentComponent();
} else {
const modal = this.modal.create({
nzContent: GetOutOfLineDetailsComponent,
nzWrapClassName: "vertical-center-modal",
nzViewContainerRef: this.viewContainerRef,
nzWidth: (document.documentElement.clientHeight < 650 || document.documentElement.clientWidth < 1400) ? 1000 : 1200,
nzBodyStyle: {
'border': '1px solid #6d9cc7',
'border-radius': '0px',
'padding': '0px',
'box-shadow': '0 0 8px 0 #fff',
'background': '#000D21',
},
nzComponentParams: {
data: copydata
},
nzFooter: null,
});
const instance = modal.getContentComponent();
}
}, 0);
this.messageId.forEach((element) => {
if (element.id == item.notification.entityId) {
this.notificationService.remove(element.messageId)
}
})
this.readMess(item.notification.id)
})
}
//标记为已读
readMess(id) {
let body = {
id: id
}
this.http.post('/api/services/app/Notification/Read', body).subscribe((data: any) => {
console.log('标记已读成功')
})
}
close(item) {
// console.log(item)
this.messageId.forEach((element) => {
if (element.id == item.notification.entityId) {
this.notificationService.remove(element.messageId)
}
})
}
ngOnDestroy() {
console.log('退出')
abp.event.off('abp.notifications.received', this.reloadPage);
abp.signalr.disconnect()
}
//获得时间
time: string
getTime() {
let myDate = new Date();
let y = myDate.getFullYear();
let M = myDate.getMonth() + 1; //获取当前月份(0-11,0代表1月)
let d = myDate.getDate(); //获取当前日(1-31)
let h = myDate.getHours(); //获取当前小时数(0-23)
let m = myDate.getMinutes(); //获取当前分钟数(0-59)
let s = myDate.getSeconds(); //获取当前秒数(0-59)
//检查是否小于10
M = check(M);
d = check(d);
h = check(h);
m = check(m);
s = check(s);
let timestr = y + "-" + M + "-" + d + " " + h + ":" + m + ":" + s;
this.time = timestr;
//时间数字小于10,则在之前加个“0”补位。
function check(i) {
let num = (i < 10) ? ("0" + i) : i;
return num;
}
}
//退出系统
signOut() {
this.message.create('success', `退出成功`);
this.token.delete()
sessionStorage.clear()
localStorage.removeItem("isautologin")
this.router.navigate(['/login'])
}
navChange(router) {
this.router.navigate([router])
}
goback() {
this.router.navigate(['/plan'])
this.isGasStationNav = false
}
//全屏
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;
}
//修改密码
changePassword() {
const modal: any = this.modal.create({
nzTitle: '修改密码',
nzContent: ChangePasswordComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 288,
nzComponentParams: {},
nzOnOk: async () => {
if (instance.validateForm.valid) {
if (instance.validateForm.value.newpassword != instance.validateForm.value.affirmpassword) {
this.message.create('warning', '两次密码输入不一致!');
return false
} else {
await new Promise((resolve, reject) => {
let body = {
currentPassword: instance.validateForm.value.oldpassword,
newPassword: instance.validateForm.value.newpassword
}
this.http.post('/api/services/app/User/ChangePassword', body).subscribe(data => {
resolve(data)
this.message.create('success', '修改成功!');
return true
}, err => {
this.message.create('warning', err.error.error.message);
modal.config.nzOkLoading = false
return false
})
})
}
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
});
const instance = modal.getContentComponent();
modal.afterOpen.subscribe(() => console.log('[afterOpen] emitted!'));
// Return a result when closed
modal.afterClose.subscribe(result => console.log('[afterClose] The result is:', result));
}
}

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

@ -0,0 +1,50 @@
<div class="login" id="login">
<div class="card">
<h1 class="cardheader">欢迎登录</h1>
<h1 class="cardheader">加油站智能安全管理系统</h1>
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item>
<nz-form-control nzErrorTip="请输入账号!">
<nz-input-group nzPrefixIcon="user">
<input required nz-input type="text" formControlName="userName" placeholder="请输入账号" nzSize="large" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control nzErrorTip="请输入密码!">
<nz-input-group nzPrefixIcon="lock">
<input required nz-input type="password" formControlName="password" placeholder="请输入密码"
[nzSize]="'small'" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<div class="hint">
<nz-form-item style="margin-bottom: 0;">
<nz-form-control>
<label nz-checkbox formControlName="remember" [(ngModel)]="remember">记住密码</label>
</nz-form-control>
</nz-form-item>
<span class="forget" (click)="forget()">忘记密码?</span>
</div>
<nz-form-item style="margin-bottom: 0;">
<nz-form-control>
<label class="autologin" formControlName="autologin" nz-checkbox [(ngModel)]="autologin">自动登录</label>
</nz-form-control>
</nz-form-item>
<button [nzLoading]="isLoading" nz-button class="login-form-button login-form-margin"
[nzType]="'primary'">登录</button>
</form>
<p class="company">中化石油销售有限公司 北京安信科创软件有限公司 版权所有</p>
</div>
<div class="name">
<img src="../../../assets/images/logo2.png" alt="">
<!-- <h1>中化石油</h1>
<h1>智能安全管理系统</h1> -->
</div>
</div>

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

@ -0,0 +1,93 @@
.login {
width: 100%;
height: 100%;
background: url('../../../assets/images/bgImg.png');
background-size: 100% 100%;
position: relative;
}
.card {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background-color: rgba(0, 13, 33, 0.24);
border-radius: 16px;
width: 468px;
height: 548px;
box-sizing: border-box;
padding: 79px 45px 42px 45px;
color: rgba(255, 255, 255, 1);
}
.cardheader {
font-size: 22px;
color: rgba(255, 255, 255, 1);
}
.cardheader:nth-child(2) {
margin-bottom: 40px;
}
label {
color: #fff;
}
.hint {
display: flex;
justify-content: space-between;
margin-bottom: 6px;
align-items: center;
.forget {
cursor: pointer;
color: #2399FF;
}
}
.autologin {
margin-bottom: 40px;
}
button {
width: 100%;
height: 42px;
font-size: 16px;
border-radius: 4px;
}
p {
text-align: center;
}
.role {
color: #2399FF;
margin-top: 38px;
font-size: 15px;
}
.company {
color: #666262;
margin-top: 25px;
font-size: 14px;
}
.name {
position: absolute;
left:40px;
top:40px;
img {
// margin-bottom: 32px;
width: 254px;
height: 56px;
}
h1 {
font-size: 63px;
color: #feffff;
font-weight: 600;
text-shadow: 0px 2px 8px #2399FF;
letter-spacing: 5px;
margin-bottom: 0px;
}
}

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

@ -0,0 +1,181 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router, ActivatedRoute } from '@angular/router'
import { CacheTokenService } from '../../service/cache-token.service'//引入服务
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { Base64 } from 'js-base64';
import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
declare var abp: any
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
})
export class LoginComponent implements OnInit {
validateForm!: FormGroup;
passwordValidateForm!: FormGroup;
constructor(private http: HttpClient, private router: Router, private route: ActivatedRoute, public token: CacheTokenService, private fb: FormBuilder, private message: NzMessageService, private notificationService: NzNotificationService) {
const { password } = MyValidators;
this.validateForm = this.fb.group({
userName: [null, [Validators.required]],
password: [null, [Validators.required, password]],
remember: [null],
autologin: [null],
});
this.passwordValidateForm = this.fb.group({
oldpassword: [null, [Validators.required]],
newpassword: [null, [Validators.required, password]],
affirmpassword: [null, [Validators.required, password]]
});
}
ngOnInit() {
//如果本地储存了账号密码信息,那就回显在输入框
let account = localStorage.getItem('account')
let password = localStorage.getItem('password')
if (account && password) {
this.validateForm.patchValue({
userName: Base64.decode(localStorage.getItem('account')),
password: Base64.decode(localStorage.getItem('password'))
});
this.remember = true //这一步是回显后让勾选框为选中状态
}
//自动登录
if (localStorage.getItem('isautologin') == 'true') {
this.submitForm()
this.autologin = true //这一步是回显后让勾选框为选中状态
}
}
errmsg: string = ''; //错误信息
//跳转注册页面
toRegister() {
this.router.navigate(['/register'])
}
//记住密码
rememberInfo() {
// 判断用户是否勾选记住密码,如果勾选,在本地储存中储存登录信息
if (this.remember) {
localStorage.setItem("account", Base64.encode(this.validateForm.value.userName))
localStorage.setItem("password", Base64.encode(this.validateForm.value.password))
}
}
//自动登录
autoLogin() {
if (this.autologin) {
localStorage.setItem("isautologin", 'true')
}
}
remember: any//记住密码
autologin: any//自动登录
isLoading = false;
messages
encryptedAccessToken
submitForm(): void {
if (!this.remember) {
localStorage.removeItem("account")
localStorage.removeItem("password")
}
if (!this.autologin) {
localStorage.removeItem("isautologin")
}
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
if (!this.validateForm.valid) {
this.message.create('error', `请输入账号密码`);
return
}
this.isLoading = true;
this.http.post('/api/TokenAuth/Authenticate', {
userNameOrEmailAddress: this.validateForm.value.userName,
password: this.validateForm.value.password
}).subscribe(
(data: any) => {
sessionStorage.setItem("token", data.result.accessToken);
sessionStorage.setItem("encryptedAccessToken", data.result.encryptedAccessToken);
console.log('token', data.result)
this.http.get('/api/services/app/Session/GetCurrentLoginInformations').subscribe((data: any) => {
console.log('GetCurrentLoginInformations', data.result)
sessionStorage.setItem('userdata', JSON.stringify(data.result.user))
sessionStorage.setItem('userdataOfgasstation', JSON.stringify(data.result.user))
sessionStorage.setItem('isDefaultPassword', JSON.stringify(data.result.user.isDefaultPassword))
sessionStorage.setItem('isPasswordExpired', JSON.stringify(data.result.user.isPasswordExpired))
this.isLoading = false;
//记住密码
this.rememberInfo()
//自动登录
this.autoLogin()
if (data.result.user.userName == 'admin') {
sessionStorage.setItem("isGasStation", 'false');
this.router.navigate(['/system/organization'])
this.message.create('success', `登录成功`);
} else {
if (data.result.user.organization.isGasStation) {
sessionStorage.setItem("isGasStation", 'true');
this.router.navigate(['/todaywarning/petrolStation'])
this.message.create('success', `登录成功`);
} else {
sessionStorage.setItem("isGasStation", 'false');
this.router.navigate(['/homepage'])
this.message.create('success', `登录成功`);
}
}
}, err => {
this.isLoading = false;
})
//调用服务中的function刷新token
// this.token.startUp()
},
(err) => {
this.isLoading = false;
this.message.create('error', err.error.error.details);
}
)
}
forget() {
this.message.create('warning', `请联系管理员`);
}
}
export type MyErrorsOptions = { 'zh-cn': string; en: string } & Record<string, NzSafeAny>;
export type MyValidationErrors = Record<string, MyErrorsOptions>;
export class MyValidators extends Validators {
static password(control: AbstractControl): MyValidationErrors | null {
const value = control.value;
if (isEmptyInputValue(value)) {
return null;
}
return isPassword(value) ? null : { mobile: { 'zh-cn': `长度 12 位以上,包含①大写字母、②小写字母、③数字、④特殊字符四种中的三种组合`, en: `Password phone number is not valid` } };
}
}
function isEmptyInputValue(value: NzSafeAny): boolean {
return value == null || value.length === 0;
}
function isPassword(value: string): boolean {
return typeof value === 'string' && /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{12,99}$/.test(value);
}

188
src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.html

@ -0,0 +1,188 @@
<div class="recordsbox" id="recordsbox">
<div class="content">
<div class="title">
<div class="titlebox">
<img src="../../../assets/images/logosm.png" alt="">
<div class="content">
<div class="contentitem">
<span class="grey" (click)="gorecordList()">预警类型统计</span>
<span>卸油统计</span>
<span class="grey" (click)="goWarningList()">证照预警统计</span>
</div>
</div>
</div>
<img (click)="isEchartsShow()" class="packup" src="../../../assets/images/packup.png" alt="">
</div>
<div class="chartsbox" [hidden]="!isEcharts">
<div class="chart">
<div class="leftbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
卸油预警统计
</span>
<div class="centerContent">
<div class="num">{{num}}</div>
<div class="numname">总数</div>
</div>
<span *ngIf="isgoback" class="goback" (click)="goback()">返回</span>
<div class="piechart" id="piechart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
<div class="rightbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
近30天卸油作业总数走势
</span>
<div class="barchart" id="barchart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
</div>
</div>
<div class="title">
<app-title [name]="'卸油作业留证列表'"></app-title>
</div>
<div class="search" [hidden]="!isEcharts">
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear formControlName="state" nzPlaceHolder="请选择状态">
<nz-option nzValue="0" nzLabel="预警"></nz-option>
<nz-option nzValue="1" nzLabel="合规"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParamsLong" *ngIf="isOrShow">
<nz-form-control>
<nz-tree-select [nzAllowClear]="false" [nzDropdownClassName]="'maxHeightTreeSelect'"
nzShowSearch [(ngModel)]="defaultOrId" formControlName="organization" [nzNodes]="nodes"
nzPlaceHolder="请选择所属机构" [nzExpandedIcon]="multiExpandedIconTpl">
</nz-tree-select>
<ng-template #multiExpandedIconTpl let-node let-origin="origin">
<ng-container *ngIf="node.children.length == 0; else elseTemplate">
</ng-container>
<ng-template #elseTemplate>
<i nz-icon [nzType]="node.isExpanded ? 'caret-down' : 'caret-right'"
class="ant-tree-switcher-line-icon"></i>
</ng-template>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParams2">
<nz-form-control>
<nz-range-picker [nzAllowClear]="false" formControlName="datePicker"></nz-range-picker>
<br />
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="submit" class="submit"><i nz-icon [nzType]="'search'"></i>查询</button>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="button" class="reset" (click)="resetForm($event)"><i nz-icon
[nzType]="'sync'"></i>重置</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div class="tablebox">
<div class="table">
<div nz-row class="th">
<div nz-col nzSpan="1">
<span style="margin-left: 15px;">序号</span>
</div>
<div nz-col nzSpan="3">
<span>油站名称</span>
</div>
<div nz-col nzSpan="2">
公司名称
</div>
<div nz-col nzSpan="4">
区域
</div>
<div nz-col nzSpan="3">
卸油开始时间
</div>
<div nz-col nzSpan="3">
卸油结束时间
</div>
<div nz-col nzSpan="3" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
操作前准备预警节点数量
</div>
<div nz-col nzSpan="3" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
操作中准备预警节点数量
</div>
<!-- <div nz-col nzSpan="3" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
全流程准备预警节点数量
</div> -->
<div nz-col nzSpan="1">
状态
</div>
<div nz-col nzSpan="1">
操作
</div>
</div>
<div class="tbody" id="tbody">
<div nz-row class="tr" *ngFor="let item of list;let key = index">
<div nz-col nzSpan="1">
<span style="margin-left: 15px;">{{key + 1}}</span>
</div>
<div nz-col nzSpan="3" [title]="item.gasStation.stationName">
<span>{{item.gasStation.stationName}}</span>
</div>
<div nz-col nzSpan="2" [title]="item.gasStation.companyName">
{{item.gasStation.companyName}}
</div>
<div nz-col nzSpan="4" [title]="item.gasStation.locationName">
{{item.gasStation.locationName}}
</div>
<div nz-col nzSpan="3">
{{item.startTime ? (item.startTime | date:"yyyy-MM-dd HH:mm:ss") : '/'}}
</div>
<div nz-col nzSpan="3">
{{item.endTime ? (item.endTime | date:"yyyy-MM-dd HH:mm:ss") : '/'}}
</div>
<div nz-col nzSpan="3">
{{item.proccessBeforeCount}}
</div>
<div nz-col nzSpan="3">
{{item.proccessingCount}}
</div>
<!-- <div nz-col nzSpan="3">
{{item.allProccessCount}}
</div> -->
<div nz-col nzSpan="1">
<ng-container
*ngIf="item.proccessBeforeCount == 0 && item.proccessingCount == 0 && item.allProccessCount == 0; else elseTemplate">
<span style="color: #4BFFD4;">合规</span>
</ng-container>
<ng-template #elseTemplate>
<span style="color: #FF4B65;">预警</span>
</ng-template>
</div>
<div nz-col nzSpan="1">
<span style="color: #36A2FF;cursor: pointer;" (click)="look(item)">查看</span>
</div>
</div>
<div nz-row class="tr" *ngIf="tableSpin">
<div nz-col nzSpan="24" style="text-align: center;">
<nz-spin nzSimple></nz-spin>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

615
src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.scss

@ -0,0 +1,615 @@
.recordsbox {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.search {
box-sizing: border-box;
padding: 0 36px;
width: 100%;
height: 32px;
margin-bottom: 16px;
form {
width: 100%;
height: 32px;
display: flex;
justify-content: flex-start;
.searchParams,
.btn {
margin: 0 3px;
}
.searchParams {
// flex: 10;
width: 150px;
}
.searchParamsLong {
width: 250px;
}
.searchParams2 {
width: 220px;
}
.btn {
// flex: 1;
}
nz-select {
color: rgba(145, 204, 255, 0.95);
}
nz-tree-select {
color: rgba(145, 204, 255, 0.95);
}
nz-range-picker {
background-color: rgba(0, 0, 0, 0);
width: 100%;
}
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
margin: 13px 0;
width: 100%;
height: 64px;
box-sizing: border-box;
padding: 0 28px;
position: relative;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 65px;
height: 65px;
}
.content {
flex: 1;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
// background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%);
.contentitem {
width: 100%;
height: 32px;
display: flex;
align-items: center;
// background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%);
span {
margin-left: 10px;
color: #bce0ff;
font-size: 20px;
font-family: titlefont;
cursor: pointer;
}
span:nth-child(1) {
margin-left: 12px;
}
.grey {
color: #68829F;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 16px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
display: flex;
justify-content: center;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 350px;
box-sizing: border-box;
padding: 0 10px;
display: flex;
div {
display: flex;
flex-direction: column;
span {
font-family: titlefont;
display: flex;
align-items: center;
height: 28px;
color: #bee1ff;
font-size: 16px;
}
div {
flex: 1;
}
}
.leftbox {
width: 360px;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
margin-right: 16px;
.centerContent {
position: absolute;
top: 34%;
left: 50%;
transform: translateX(-50%);
width: 170px;
div {
text-align: center;
}
.numname {
// font-family: titlefont;
color: #bee1ff;
}
.num {
color: #FFFFFF;
font-size: 38px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 46px;
line-height: 46px;
}
}
.goback {
position: absolute;
right: 20px;
top: 14px;
color: #C4E2FC;
font-family: synormal;
font-size: 14px;
z-index: 999;
cursor: pointer;
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
button {
border: 1px solid #91CCFF;
color: #91CCFF;
border-radius: 0px;
box-shadow: 0 0 5px 0 #2399FF inset;
background: none;
}
.rankingBtn {
margin-right: 16px;
}
.selectedbtn {
background: linear-gradient(180deg, #000D21 0%, #001331 27%, #2399FF 100%);
color: white;
}
}
}
}
}
.tablebox {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
.table {
color: white;
flex: 1;
width: 96%;
display: flex;
flex-direction: column;
overflow: hidden;
.th {
height: 38px;
line-height: 38px;
background: rgba(35, 153, 255, 0.2);
border: 1px solid rgba(35, 217, 255, 0.4);
box-shadow: 0 0 3px 0 rgba(35, 217, 255, 0.4) inset;
color: #23D9FF;
}
.tbody {
flex: 1;
overflow-y: auto;
.tr {
height: 38px;
line-height: 38px;
border-bottom: 1px solid #0d3761;
div {
color: #91CCFF;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.look {
color: #36A2FF;
cursor: pointer;
}
}
}
}
}
.pagination {
margin: 15px 0;
display: flex;
align-items: center;
justify-content: center;
}
::-webkit-scrollbar {
width: 0px;
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.search {
box-sizing: border-box;
padding: 0 30px;
height: 32px;
margin-bottom: 12px;
form {
width: 100%;
height: 32px;
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
height: 42px;
padding: 0 20px;
margin: 8px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 46px;
height: 46px;
}
.content {
height: 36px;
.contentitem {
width: 100%;
height: 25px;
span {
margin-left: 6px;
font-size: 16px;
}
span:nth-child(1) {
margin-left: 8px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 4px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 43%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 300px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 12px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 42px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 49px;
line-height: 50px;
}
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 12px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 32px;
line-height: 32px;
font-size: 12px !important;
}
.tbody {
.tr {
height: 32px;
line-height: 32px;
div {
font-size: 12px !important;
}
img {
width: 32px;
}
}
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.search {
box-sizing: border-box;
padding: 0 22px;
height: 32px;
margin-bottom: 6px;
form {
width: 100%;
height: 32px;
}
}
.content {
.title {
height: 36px;
padding: 0 20px;
margin: 3px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 36px;
height: 36px;
}
.content {
height: 30px;
.contentitem {
width: 100%;
height: 22px;
span {
margin-left: 6px;
font-size: 13px;
}
span:nth-child(1) {
margin-left: 12px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 2px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 40%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 260px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 8px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 32px;
text-shadow: 0px 0px 12px #3A9AFF;
font-weight: bold;
height: 42px;
line-height: 42px;
}
}
}
.rightbox {
box-shadow: 0 0 22px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 8px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 28px;
line-height: 28px;
font-size: 10px !important;
}
.tbody {
.tr {
height: 28px;
line-height: 28px;
div {
font-size: 10px !important;
}
img {
width: 30px;
}
}
}
}
}
}
}

724
src/app/pages/oil-unloading-process-list/oil-unloading-process-list.component.ts

@ -0,0 +1,724 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewContainerRef, ElementRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import * as echarts from 'echarts';
import { NzModalService } from 'ng-zorro-antd/modal';
import { GetOutOfLineDetailsComponent } from '../today-warning/get-out-of-line-details/get-out-of-line-details.component';
import * as moment from 'moment';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { Router } from '@angular/router';
import { OilUnloadingProcessComponent } from '../oil-unloading-process/oil-unloading-process.component';
import { TreeService } from 'src/app/service/tree.service';
@Component({
selector: 'app-oil-unloading-process-list',
templateUrl: './oil-unloading-process-list.component.html',
styleUrls: ['./oil-unloading-process-list.component.scss']
})
export class OilUnloadingProcessListComponent implements OnInit {
validateForm!: FormGroup;
constructor(private toTree: TreeService, private http: HttpClient, private fb: FormBuilder, private router: Router, private modal: NzModalService, private viewContainerRef: ViewContainerRef, private element: ElementRef) { }
myChart: any //左侧饼图
mybarChart: any //柱状图
getThirtyDays() {
//获取当前日期
let myDate = new Date();
var nowY = myDate.getFullYear();
var nowM = myDate.getMonth() + 1;
var nowD = myDate.getDate();
var enddateStr = nowY + "-" + (nowM < 10 ? "0" + nowM : nowM) + "-" + (nowD < 10 ? "0" + nowD : nowD);//当前日期
var enddate = new Date(enddateStr);
//获取三十天前日期
var lw = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 30);//最后一个数字30可改,30天的意思
var lastY = lw.getFullYear();
var lastM = lw.getMonth() + 1;
var lastD = lw.getDate();
var startdateStr = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD);//三十天之前日期
var startDate = new Date(startdateStr);
const dateList = []
while (true) {
startDate.setDate(startDate.getDate() + 1)
if (startDate.getTime() <= enddate.getTime()) {
if (startDate.getDate() < 10) {
// startDate.getFullYear() 获取年,此处没加上年份
dateList.push((startDate.getMonth() + 1) + '.0' + startDate.getDate())
} else {
dateList.push((startDate.getMonth() + 1) + '.' + startDate.getDate())
}
} else {
break
}
}
return dateList;
}
isEcharts: boolean = true
isEchartsShow() {
this.isEcharts = !this.isEcharts
}
startdate
enddate
isOrShow: boolean
ngOnInit(): void {
//当前日期
let myDate: any = new Date();
let nowY = myDate.getFullYear();
let nowM = myDate.getMonth() + 1;
let nowD = myDate.getDate();
this.enddate = nowY + "-" + (nowM < 10 ? "0" + nowM : nowM) + "-" + (nowD < 10 ? "0" + nowD : nowD);//当前日期
//获取三十天前日期
let lw = new Date(myDate - 1000 * 60 * 60 * 24 * 30);//最后一个数字30可改,30天的意思
let lastY = lw.getFullYear();
let lastM = lw.getMonth() + 1;
let lastD = lw.getDate();
this.startdate = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD);//三十天之前日期
this.validateForm = this.fb.group({
state: [null],
organization: [null],
datePicker: [[this.startdate, this.enddate]]
});
// 饼图
this.myChart = echarts.init(document.getElementById('piechart'));
//柱状折线图
this.mybarChart = echarts.init(document.getElementById('barchart'));
this.tableSpin = true
this.getAllOrganization()
this.getAggregations()
if (this.router.url.indexOf('petrolStation') != -1) {
this.isOrShow = false
} else {
this.isOrShow = true
}
}
//刷新饼图图表数据
num
echartsData: any
//一级饼图
oilchartpieOption = {
color: ['#FF4B65', '#36A2FF'],
tooltip: {
trigger: 'item'//触发类型
},
legend: {
bottom: '12%',
left: 'center',
itemGap: 40,
itemWidth: 8,
itemHeight: 8,
formatter: (name) => {
let data = this.oilchartpieOptionPieData1
let value
for (var i = 0, l = data.length; i < l; i++) {
if (data[i].name == name) {
value = data[i].value;
}
}
return '{a|' + name + '}' + '{b|' + value + '}';
},
textStyle: {
color: '#fff',
rich: {
a: {
width: 80
}
}
}
},
series: [
{
type: 'pie',
radius: ['50%', '60%'],
bottom: '10%',
avoidLabelOverlap: false,//防止标签重叠策略
label: {//每一个标签外网延伸的引导说明
show: false,
position: 'outside'
},
data: [],
tooltip: {//鼠标移入提示
position: 'right',
padding: [14, 19],
backgroundColor: 'rgba(28, 129, 218, 0.4)',
textStyle: {
color: '#fff',
fontSize: 12
}
}
}
]
};
oilchartpieOptionPieData1: any
//一级柱状图
oilchartbarOption = {
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF'
}
},
axisTick: {//刻度线
show: false
},
inverse: true
},
yAxis: {
type: 'value',
nameTextStyle: {
color: '#C4E2FC'
},
splitLine: {//分割线
lineStyle: {
color: ['#0f4374'],
width: 2
}
},
axisTick: {//刻度线
show: false
},
axisLine: {//轴线
show: false,
lineStyle: {
color: '#C4E2FC'
}
}
},
tooltip: {
// trigger: 'axis'
},
series: [
{
name: '卸油事件',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#23F0FF' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(35, 153, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '卸油事件',
data: [],
type: 'line',
symbol: 'circle',
symbolSize: 8,
label: {
show: true
},
itemStyle: {
color: '#fff',
shadowColor: '#fff',
shadowBlur: 10
},
lineStyle: {
color: '#FFCC8A',
width: 1
}
}
],
legend: {
data: ['卸油事件'],
textStyle: {
color: '#fff'
},
right: 28,
top: 18,
itemWidth: 8,
itemHeight: 8,
},
grid: {
left: '42px',
right: '30px',
bottom: '38px',
top: '80px'
}
};
//二级饼图
oilchartpieOption2 = {
color: ['#36A2FF', '#FFBD4B', '#46DFFF'],
tooltip: {
trigger: 'item'//触发类型
},
legend: {
bottom: '8%',
left: 'center',
itemGap: 10,
itemWidth: 8,
itemHeight: 8,
formatter: (name) => {
let data = this.oilchartpieOptionPieData2
let value
for (var i = 0, l = data.length; i < l; i++) {
if (data[i].name == name) {
value = data[i].value;
}
}
return '{a|' + name + '}' + '{b|' + value + '}';
},
textStyle: {
color: '#fff',
rich: {
a: {
width: 60
}
}
}
},
series: [
{
type: 'pie',
radius: ['50%', '60%'],
bottom: '10%',
avoidLabelOverlap: false,//防止标签重叠策略
label: {//每二个标签外网延伸的引导说明
show: false,
position: 'outside'
},
data: [],
tooltip: {//鼠标移入提示
position: 'right',
padding: [14, 19],
backgroundColor: 'rgba(28, 129, 218, 0.4)',
textStyle: {
color: '#fff',
fontSize: 12
}
}
}
]
};
oilchartpieOptionPieData2: any
//二级柱状图
oilchartbarOption2 = {
tooltip: {
// trigger: 'axis'
},
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF'
}
},
axisTick: {//刻度线
show: false
},
inverse: true
},
yAxis: {
type: 'value',
nameTextStyle: {
color: '#C4E2FC'
},
splitLine: {//分割线
lineStyle: {
color: ['#0f4374'],
width: 2
}
},
axisTick: {//刻度线
show: false
},
axisLine: {//轴线
show: false,
lineStyle: {
color: '#C4E2FC'
}
}
},
legend: {
data: ['事前准备', '事中操作', '全程监测'],
textStyle: {
color: '#fff'
},
right: 18,
top: 18,
itemWidth: 8,
itemHeight: 8,
},
series: [
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(54, 162, 255, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(54, 162, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(255, 189, 75, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(255, 189, 75, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(70, 223, 255, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(70, 223, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
}
],
grid: {
left: '42px',
right: '30px',
bottom: '38px',
top: '80px'
}
};
isgoback: boolean = false
refreshEchartsData1(data) {
this.num = data.totalCount
//饼图
this.oilchartpieOptionPieData1 = [
{ name: '预警事件', value: data.notCorrectCount },
{ name: '正常操作', value: data.correctCount },
]
this.oilchartpieOption.series[0].data = this.oilchartpieOptionPieData1
this.myChart.setOption(this.oilchartpieOption);
this.myChart.off('legendselectchanged')
this.myChart.off('click')
this.myChart.on('legendselectchanged', (params) => {
this.myChart.setOption({
legend: { selected: { [params.name]: true } }
})
if (params.name == '预警事件') {
this.isgoback = true
this.refreshEchartsData2(this.echartsData)
this.validateForm.patchValue({
state: '0'
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
});
this.myChart.on('click', (params) => {
if (params.name == '预警事件') {
this.isgoback = true
this.refreshEchartsData2(this.echartsData)
this.validateForm.patchValue({
state: '0'
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
});
//柱状图
let monthArr = []
let valuedata = []
data.list.forEach(element => {
monthArr.push(moment(element.key).format('MM.DD'))
valuedata.push(element.totalCount)
});
this.oilchartbarOption.xAxis.data = monthArr
this.oilchartbarOption.series[0].data = valuedata
this.oilchartbarOption.series[1].data = valuedata
this.mybarChart.setOption(this.oilchartbarOption);
}
refreshEchartsData2(data) {
this.num = Number(data.proccessBeforeCount + data.proccessingCount + data.allProccessCount)
//饼图
this.oilchartpieOptionPieData2 = [
{ name: '事前准备', value: data.proccessBeforeCount },
{ name: '事中操作', value: data.proccessingCount },
{ name: '全程检测', value: data.allProccessCount }
]
this.oilchartpieOption2.series[0].data = this.oilchartpieOptionPieData2
this.myChart.setOption(this.oilchartpieOption2);
//柱状图
let monthArr = []
let valuedataBefore = []
let valuedataIng = []
let valuedataAll = []
data.list.forEach(element => {
monthArr.push(moment(element.key).format('MM.DD'))
valuedataBefore.push(element.proccessBeforeCount)
valuedataIng.push(element.proccessingCount)
valuedataAll.push(element.allProccessCount)
});
this.oilchartbarOption2.xAxis.data = monthArr
this.oilchartbarOption2.series[0].name = '事前准备'
this.oilchartbarOption2.series[0].data = valuedataBefore
this.oilchartbarOption2.series[1].name = '事中操作'
this.oilchartbarOption2.series[1].data = valuedataIng
this.oilchartbarOption2.series[2].name = '全程监测'
this.oilchartbarOption2.series[2].data = valuedataAll
this.mybarChart.setOption(this.oilchartbarOption2);
}
goback() {
this.isgoback = false
this.myChart.clear();
this.mybarChart.clear();
this.refreshEchartsData1(this.echartsData)
this.validateForm.patchValue({
state: null
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
defaultOrId: string
//获取所有组织机构
nodes: any = []
getAllOrganization() {
let OrganizationUnitId = sessionStorage.getItem('isGasStation') == 'true' ? JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id : JSON.parse(sessionStorage.getItem('userdata')).organization.id
let params = {
OrganizationUnitId: OrganizationUnitId,
IsContainsChildren: "true"
}
this.http.get('/api/services/app/Organization/GetAll', {
params: params
}).subscribe((data: any) => {
data.result.items.forEach(element => {
if (element.id == OrganizationUnitId) {
element.parentId = null
}
element.key = element.id
element.title = element.displayName
});
this.nodes = [...this.toTree.toTree(data.result.items)]
this.defaultOrId = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.value.organization = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.patchValue({
datePicker: [this.startdate, this.enddate]
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
})
}
//获取统计信息
chartsSpin: boolean = false
getAggregations() {
this.chartsSpin = true
let organizationUnitId
if (this.router.url.indexOf('petrolStation') != -1) {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id
} else {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdata')).organization.id
}
let params: any = {
OrganizationUnitId: organizationUnitId,
IsContainsChildren: 'true'
}
this.http.get('/api/services/app/OilUnloadingProcess/GetAllCountByDays', { params: params }).subscribe((data: any) => {
console.log('统计信息', data)
this.chartsSpin = false
this.echartsData = data.result
this.refreshEchartsData1(this.echartsData)
// this.refreshBarLineData(this.echartsData)
})
}
//获得卸油记录列表
SkipCount: string = '0'
MaxResultCount: string = '50'
list: any = []
totalCount: string
tableSpin: boolean = false
getViolateRecordList() {
this.tableSpin = true
let organizationUnitId
if (this.router.url.indexOf('petrolStation') != -1) {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id
} else {
organizationUnitId = this.validateForm.value.organization
}
let IsCorrect = null
if (this.validateForm.value.state) {
this.validateForm.value.state == '0' ? IsCorrect = 'false' : IsCorrect = 'true'
}
let params = {
IsCorrect: IsCorrect,
StartTime: moment(this.validateForm.value.datePicker[0]).format('yyyy-MM-DD'),
EndTime: moment(this.validateForm.value.datePicker[1]).format('yyyy-MM-DD'),
IsContainsChildren: 'true',
OrganizationUnitId: organizationUnitId,
SkipCount: this.SkipCount,
MaxResultCount: this.MaxResultCount
}
this.http.get('/api/services/app/OilUnloadingProcess/GetAll', {
params: params
}).subscribe((data: any) => {
this.tableSpin = false
this.list = this.list.concat(data.result.items);
this.list = [...this.list]
this.totalCount = data.result.totalCount
console.log('获取卸油流程列表', data.result.items)
})
}
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
resetForm(e: MouseEvent): void {
e.preventDefault();
this.validateForm.reset();
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
console.log(JSON.parse(sessionStorage.getItem('userdata')).organization.id)
// this.validateForm.value.organization = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.patchValue({
organization: JSON.parse(sessionStorage.getItem('userdata')).organization.id,
datePicker: [this.startdate, this.enddate]
});
this.list = []
this.SkipCount = '0'
this.getViolateRecordList()
}
ngAfterViewInit(): void {
fromEvent(this.element.nativeElement.querySelector(`#tbody`) as HTMLCanvasElement, 'scroll').pipe(debounceTime(100)).subscribe((event: any) => { //监听 DOM 滚动事件
if (event.target.scrollHeight - (event.target.scrollTop + event.target.clientHeight) <= 10) {
if (this.totalCount > this.list.length) {
console.log('需要加载数据了', event)
this.SkipCount = String(Number(this.SkipCount) + 50)
this.getViolateRecordList()
}
}
});
}
look(item) {
// console.log(item)
let arr = []
let arr1 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '车辆进场' });
let arr2 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '设置卸油隔离区' });
let arr3 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '卸油连接静电接地' });
let arr4 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '卸油设置消防器材' });
let arr5 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '连接卸油管' });
let arr6 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '卸油中无人监卸' });
let arr7 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '拆除卸油管' });
let arr8 = item.oilUnloadingNodes.find((item) => { return item.nodeName == '车辆离场' || item.nodeName == '车辆离厂' || item.nodeName == '车辆出厂' });
// console.log(1, arr1)
// console.log(2, arr2)
// console.log(3, arr3)
// console.log(4, arr4)
// console.log(5, arr5)
// console.log(6, arr6)
// console.log(7, arr7)
// console.log(8, arr8)
arr = [arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8]
console.log('卸油流程', arr)
const modal = this.modal.create({
nzContent: OilUnloadingProcessComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 1000,
nzBodyStyle: {
'border': '1px solid #6d9cc7',
'border-radius': '0px',
'padding': '0px',
'box-shadow': '0 0 8px 0 #fff',
'background': '#000D21',
},
nzComponentParams: {
data: arr
},
nzFooter: null,
nzOnOk: async () => {
}
});
const instance = modal.getContentComponent();
}
gorecordList() {
if (this.router.url.indexOf('petrolStation') != -1) {
this.router.navigate(['/records/petrolStation'])
} else {
this.router.navigate(['/records'])
}
}
goWarningList() {
if (this.router.url.indexOf('petrolStation') != -1) {
this.router.navigate(['/records/petrolStation/warningstatisticslist'])
} else {
this.router.navigate(['/records/warningstatisticslist'])
}
}
}

231
src/app/pages/oil-unloading-process/oil-unloading-process.component.html

@ -0,0 +1,231 @@
<div class="box">
<div class="titlebox">
<div class="title">
<div>
卸油全流程
<div class="border"></div>
</div>
</div>
</div>
<div class="contentbox">
<div class="topbox">
<div class="title">
卸油前准备
</div>
<div class="content content1">
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[0].isCorrect}"><i nz-icon
nzType="clock-circle" nzTheme="outline"></i>{{data[0].violateTime
? (data[0].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[0].violateImage)"
[ngClass]="{'selectedimg': !data[0].violateImage}">
<img [src]="data[0].violateImage ? data[0].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[0].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">油罐车进场</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[1].isCorrect}"><i nz-icon
nzType="clock-circle" nzTheme="outline"></i>{{data[1].violateTime
? (data[1].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[1].violateImage)"
[ngClass]="{'selectedimg': !data[1].violateImage}">
<img [src]="data[1].violateImage ? data[1].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[1].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">设置隔离区域</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<!-- <div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data.oilUnloadingNodes[4].isCorrect || !data.oilUnloadingNodes[4].violateImage}"><i
nz-icon nzType="clock-circle" nzTheme="outline"></i>{{data.oilUnloadingNodes[4].violateTime ? (data.oilUnloadingNodes[4].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data.oilUnloadingNodes[4].violateImage)" [ngClass]="{'selectedimg': !data.oilUnloadingNodes[4].violateImage}">
<img [src]="data.oilUnloadingNodes[4].violateImage ? data.oilUnloadingNodes[4].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data.oilUnloadingNodes[4].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">固定罐车轮胎</span>
</div>
<img src="../../../assets/images/rightArrow.png" alt=""> -->
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[2].isCorrect}"><i nz-icon
nzType="clock-circle" nzTheme="outline"></i>{{data[2].violateTime
? (data[2].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[2].violateImage)"
[ngClass]="{'selectedimg': !data[2].violateImage}">
<img [src]="data[2].violateImage ? data[2].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[2].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">连接静电接地</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[3].isCorrect}"><i nz-icon
nzType="clock-circle" nzTheme="outline"></i>{{data[3].violateTime
? (data[3].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[3].violateImage)"
[ngClass]="{'selectedimg': !data[3].violateImage}">
<img [src]="data[3].violateImage ? data[3].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[3].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">放置消防器材</span>
</div>
</div>
</div>
<img class="bottomArrow" src="../../../assets/images/bottomArrow.png" alt="">
<div class="bottombox">
<div class="title">
卸油操作
</div>
<div class="content content2">
<!-- <div class="colimglist">
<div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data.oilUnloadingNodes[7].isCorrect || !data.oilUnloadingNodes[7].violateImage}"><i
nz-icon nzType="clock-circle" nzTheme="outline"></i>{{data.oilUnloadingNodes[7].violateTime ? (data.oilUnloadingNodes[7].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data.oilUnloadingNodes[7].violateImage)" [ngClass]="{'selectedimg': !data.oilUnloadingNodes[7].violateImage}">
<img [src]="data.oilUnloadingNodes[7].violateImage ? data.oilUnloadingNodes[7].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data.oilUnloadingNodes[7].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">取样检查</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data.oilUnloadingNodes[8].isCorrect || !data.oilUnloadingNodes[8].violateImage}"><i
nz-icon nzType="clock-circle" nzTheme="outline"></i>{{data.oilUnloadingNodes[8].violateTime ? (data.oilUnloadingNodes[8].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data.oilUnloadingNodes[8].violateImage)" [ngClass]="{'selectedimg': !data.oilUnloadingNodes[8].violateImage}">
<img [src]="data.oilUnloadingNodes[8].violateImage ? data.oilUnloadingNodes[8].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data.oilUnloadingNodes[8].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">连接卸油管</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data.oilUnloadingNodes[9].isCorrect || !data.oilUnloadingNodes[9].violateImage}"><i
nz-icon nzType="clock-circle" nzTheme="outline"></i>{{data.oilUnloadingNodes[9].violateTime ? (data.oilUnloadingNodes[9].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data.oilUnloadingNodes[9].violateImage)" [ngClass]="{'selectedimg': !data.oilUnloadingNodes[9].violateImage}">
<img [src]="data.oilUnloadingNodes[9].violateImage ? data.oilUnloadingNodes[9].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data.oilUnloadingNodes[9].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">第三方确认</span>
</div>
</div> -->
<div class="colimglist">
<!-- <div class="imgbox">
<span class="name">开始卸油</span>
</div> -->
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[4].isCorrect}"><i
nz-icon nzType="clock-circle"
nzTheme="outline"></i>{{data[4].violateTime ?
(data[4].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[4].violateImage)"
[ngClass]="{'selectedimg': !data[4].violateImage}">
<img [src]="data[4].violateImage ? data[4].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[4].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">连接卸油管</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[5].isCorrect}"><i
nz-icon nzType="clock-circle"
nzTheme="outline"></i>{{data[5].violateTime ?
(data[5].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[5].violateImage)"
[ngClass]="{'selectedimg': !data[5].violateImage}">
<img [src]="data[5].violateImage ? data[5].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[5].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">全程监卸</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan" [ngClass]="{'timespanerr': !data[6].isCorrect}"><i
nz-icon nzType="clock-circle"
nzTheme="outline"></i>{{data[6].violateTime ?
(data[6].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[6].violateImage)"
[ngClass]="{'selectedimg': !data[6].violateImage}">
<img [src]="data[6].violateImage ? data[6].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[6].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">拆除卸油管</span>
</div>
<img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data[7].isCorrect}"><i
nz-icon nzType="clock-circle"
nzTheme="outline"></i>{{data[7].violateTime ?
(data[7].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data[7].violateImage)"
[ngClass]="{'selectedimg': !data[7].violateImage}">
<img [src]="data[7].violateImage ? data[7].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data[7].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">油罐车离场</span>
</div>
<!-- <img class="rightArrow" src="../../../assets/images/rightArrow.png" alt="">
<div class="imgbox">
<span class="timespan"
[ngClass]="{'timespanerr': !data.oilUnloadingNodes[12].isCorrect || !data.oilUnloadingNodes[12].violateImage}"><i
nz-icon nzType="clock-circle"
nzTheme="outline"></i>{{data.oilUnloadingNodes[12].violateTime ?
(data.oilUnloadingNodes[12].violateTime | date:"MM-dd HH:mm:ss") : '/'}}</span>
<div class="img" (click)="lookImg(data.oilUnloadingNodes[12].violateImage)"
[ngClass]="{'selectedimg': !data.oilUnloadingNodes[12].violateImage}">
<img [src]="data.oilUnloadingNodes[12].violateImage ? data.oilUnloadingNodes[12].violateImage : '../../../../assets/images/nopng.png'"
alt="">
<img *ngIf="!data.oilUnloadingNodes[12].isCorrect" class="err"
src="../../../../assets/images/err.png" alt="">
</div>
<span class="name">清理现场</span>
</div> -->
</div>
<!--
<div class="line"></div>
<div class="line2"></div>
<img class="bottomArrow2" src="../../../assets/images/bottomArrow2.png" alt=""> -->
</div>
</div>
</div>
</div>
<div id="viewerjs" style="display:none">
</div>

246
src/app/pages/oil-unloading-process/oil-unloading-process.component.scss

@ -0,0 +1,246 @@
.box {
width: 100%;
color: #fff;
display: flex;
flex-direction: column;
background-image: linear-gradient(#003B6E, #000D21);
position: relative;
::-webkit-scrollbar {
display: none;
/* Chrome Safari */
}
scrollbar-width: none;
/* firefox */
-ms-overflow-style: none;
/* IE 10+ */
}
.titlebox {
width: 100%;
height: 48px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
display: flex;
align-items: center;
.title {
width: 100%;
height: 32px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
display: flex;
justify-content: center;
div {
width: 120px;
height: 32px;
text-align: center;
line-height: 32px;
font-family: sybold;
font-size: 16px;
position: relative;
cursor: pointer;
margin: 0 18px;
.border {
position: absolute;
bottom: -7px;
left: -18px;
width: 120px;
height: 4px;
}
}
.selected {
background: linear-gradient(90deg, rgba(35, 153, 255, 0.57) 0%, #25b7d4 50%, rgba(35, 153, 255, 0.57) 100%);
.border {
background: linear-gradient(90deg, rgba(35, 217, 255, 0) 0%, #25b7d4 50%, rgba(35, 217, 255, 0) 100%);
}
}
}
}
.ant-modal-close {
color: #fff;
}
.contentbox {
flex: 1;
width: 100%;
box-sizing: border-box;
padding: 18px;
max-height: 700px;
overflow-y: auto;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
.topbox,
.bottombox {
display: flex;
border: 1px solid rgba(54, 162, 255, 0.4);
.title {
width: 28px;
height: 100%;
border-right: 1px solid rgba(54, 162, 255, 0.4);
background: #052c53;
line-height: 20px;
font-size: 14px;
color: #36A2FF;
text-align: center;
box-sizing: border-box;
padding-top: 20px;
}
.content {
flex: 1;
background: #001631;
}
.content1 {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0 30px;
.rightArrow {
width: 40px;
height: 38px;
margin: 0 12px;
}
}
.content2 {
display: flex;
flex-direction: column;
justify-content: space-around;
align-content: center;
position: relative;
.colimglist {
display: flex;
justify-content: center;
align-items: center;
}
.rightArrow {
width: 40px;
height: 38px;
margin: 0 12px;
}
.line {
position: absolute;
width: 465px;
height: 10px;
border-bottom: 1px solid #91CCFF;
border-right: 1px solid #91CCFF;
left: 190px;
top: 180px;
}
.line2 {
position: absolute;
width: 1px;
height: 6px;
border-right: 1px solid #91CCFF;
left: 190px;
top: 190px;
}
.bottomArrow2 {
position: absolute;
left: 172px;
top: 187px;
}
}
}
.topbox {
width: 100%;
height: 200px;
}
.bottombox {
width: 100%;
// height: 384px;
height: 200px;
}
.bottomArrow {
margin: 13px 0;
}
.imgbox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.timespan {
i {
margin-right: 6px;
}
color: #36A2FF;
}
.timespanerr{
color: #FF4B65;
}
.img {
width: 120px;
height: 80px;
box-shadow: 0px 0px 6px #36A2FF;
border: 1px solid #C4E2FC;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
margin: 8px 0;
img {
width: 100%;
height: 100%;
cursor: pointer;
}
.err {
width: 24px;
height: 24px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.selectedimg {
// box-shadow: 0px 0px 8px #FF4B65;
// border: 1px solid #FF4B65;
// background: #3f213b;
img {
width: 24px;
height: 24px;
}
}
.errimg {
box-shadow: 0px 0px 8px #FF4B65;
border: 1px solid #FF4B65;
}
.name {
margin-top: 3px;
color: #FFFFFF;
font-size: 14px;
}
}
}

41
src/app/pages/oil-unloading-process/oil-unloading-process.component.ts

@ -0,0 +1,41 @@
import { Component, OnInit, Input } from '@angular/core';
import Viewer from 'viewerjs'
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-oil-unloading-process',
templateUrl: './oil-unloading-process.component.html',
styleUrls: ['./oil-unloading-process.component.scss']
})
export class OilUnloadingProcessComponent implements OnInit {
@Input() data: any
constructor(private message: NzMessageService) { }
ngOnInit(): void {
// console.log(this.data)
}
lookImg(url) {
if (url) {
console.log(url)
let dom = document.getElementById(`viewerjs`)
let pObjs = dom.childNodes;
let node = document.createElement("img")
node.style.display = "none";
node.src = url;
node.id = 'img'
dom.appendChild(node)
setTimeout(() => {
let viewer = new Viewer(document.getElementById(`viewerjs`), {
hidden: () => {
dom.removeChild(pObjs[0]);
viewer.destroy();
}
});
node.click();
}, 0);
} else {
this.message.create('warning', `该节点没有图片`);
}
}
}

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

@ -0,0 +1,24 @@
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { TodayWarningComponent } from './today-warning/today-warning.component';
import { AuthGuard } from '../auth.guard'
import { CriminalRecordsAdminComponent } from './criminal-records-admin/criminal-records-admin.component';
import { PlanAdminComponent } from './plan-admin/plan-admin.component';
import { OilUnloadingProcessListComponent } from './oil-unloading-process-list/oil-unloading-process-list.component';
import { WarningStatisticsListComponent } from './warning-statistics-list/warning-statistics-list.component';
const routes: Routes = [
{ path: 'plan', component: PlanAdminComponent },
{ path: 'todaywarning/petrolStation', component: TodayWarningComponent },
{ path: 'records', component: CriminalRecordsAdminComponent },
{ path: 'records/oliunloadinglist', component: OilUnloadingProcessListComponent },
{ path: 'records/petrolStation/oliunloadinglist', component: OilUnloadingProcessListComponent },
{ path: 'records/warningstatisticslist', component: WarningStatisticsListComponent },
{ path: 'records/petrolStation/warningstatisticslist', component: WarningStatisticsListComponent },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class PagesRoutingModule { }

97
src/app/pages/pages.module.ts

@ -0,0 +1,97 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
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 { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
import { NzFormModule } from 'ng-zorro-antd/form';
import { NzInputModule } from 'ng-zorro-antd/input';
import { UiModule } from '../ui/ui.module';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { PagesRoutingModule } from './pages-routing.module';
import { TodayWarningComponent } from './today-warning/today-warning.component';
import { NzSelectModule } from 'ng-zorro-antd/select';
import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzModalModule } from 'ng-zorro-antd/modal';
import { NzPaginationModule } from 'ng-zorro-antd/pagination';
import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
import { NzMessageModule } from 'ng-zorro-antd/message';
import { NzSpinModule } from 'ng-zorro-antd/spin';
import { NzTreeModule } from 'ng-zorro-antd/tree';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
import { NzStepsModule } from 'ng-zorro-antd/steps';
import { NzTableModule } from 'ng-zorro-antd/table';
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
import { NzProgressModule } from 'ng-zorro-antd/progress';
import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm';
import { NzBadgeModule } from 'ng-zorro-antd/badge';
import { NzRadioModule } from 'ng-zorro-antd/radio';
import { CriminalRecordsAdminComponent } from './criminal-records-admin/criminal-records-admin.component';
import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select';
import { PlanAdminComponent } from './plan-admin/plan-admin.component';
import { GetOutOfLineDetailsComponent } from './today-warning/get-out-of-line-details/get-out-of-line-details.component';
import { NzNotificationModule } from 'ng-zorro-antd/notification';
import { OilUnloadingProcessComponent } from './oil-unloading-process/oil-unloading-process.component';
import { OilUnloadingProcessListComponent } from './oil-unloading-process-list/oil-unloading-process-list.component';
import { ChangePasswordComponent } from './change-password/change-password.component';
import { WarningStatisticsListComponent } from './warning-statistics-list/warning-statistics-list.component';
import { DisposeequipmentComponent } from './warning-statistics-list/disposeequipment/disposeequipment.component';
@NgModule({
declarations: [LoginComponent, HomeComponent, TodayWarningComponent, CriminalRecordsAdminComponent, PlanAdminComponent, GetOutOfLineDetailsComponent, OilUnloadingProcessComponent, OilUnloadingProcessListComponent, ChangePasswordComponent, WarningStatisticsListComponent, DisposeequipmentComponent],
imports: [
PagesRoutingModule,
CommonModule,
A11yModule,
PortalModule,
ScrollingModule,
CdkStepperModule,
CdkTableModule,
CdkTreeModule,
DragDropModule,
FormsModule,
ReactiveFormsModule,
RouterModule,
NzFormModule,
NzInputModule,
UiModule,
NzButtonModule,
NzSelectModule,
NzDatePickerModule,
NzIconModule,
NzGridModule,
NzModalModule,
NzPaginationModule,
NzDropDownModule,
NzMessageModule,
NzSpinModule,
NzTreeModule,
NzTreeSelectModule,
NzCollapseModule,
NzStepsModule,
NzTableModule,
NzCheckboxModule,
NzTimePickerModule,
NzProgressModule,
NzNotificationModule,
NzPopconfirmModule,
NzBadgeModule,
NzRadioModule
],
entryComponents: [GetOutOfLineDetailsComponent, OilUnloadingProcessComponent, ChangePasswordComponent, DisposeequipmentComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class PagesModule { }

105
src/app/pages/plan-admin/plan-admin.component.html

@ -0,0 +1,105 @@
<!-- <p>站点预案!</p> -->
<div class="stationPlanBox" id="stationPlanBox">
<div class="orbox" style="position: relative;">
<div class="title">
<app-title [name]="'组织机构'"></app-title>
</div>
<div class="or">
<nz-tree [nzExpandedKeys]="nzExpandedKeys" [nzSelectedKeys]="nzSelectedKeys" [nzShowExpand]="false"
#nzTreeComponent [nzExpandAll]="nzExpandAll" nzBlockNode [nzData]="nodes" (nzClick)="activeNode($event)"
[nzTreeTemplate]="nzTreeTemplate" [nzMultiple]="false"></nz-tree>
<ng-template #nzTreeTemplate let-node let-origin="origin">
<ng-container *ngIf="node.origin.parentId == null; else elseTemplate">
<img style="vertical-align: bottom;" src="../../../assets/images/flower.png" alt="">
</ng-container>
<ng-template #elseTemplate>
<img src="../../../assets/images/point.png" alt="">
</ng-template>
<span>{{ node.title }}</span>
<img (click)="expand($event,node)" *ngIf="node.isExpanded && node.children.length != 0 "
src="../../../assets/images/expand.png" alt="">
<img (click)="expand($event,node)" *ngIf="!node.isExpanded && node.children.length != 0"
src="../../../assets/images/unexpand.png" alt="">
</ng-template>
</div>
<nz-spin *ngIf="orSpin" nzSimple class="nzspin"></nz-spin>
</div>
<div class="stationList">
<div class="title">
<app-title [name]="'站点管理'"></app-title>
</div>
<div class="search">
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item class="searchParams">
<nz-form-control>
<nz-input-group>
<input required nz-input type="text" formControlName="name" placeholder="请输入名称" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="submit" class="submit"><i nz-icon [nzType]="'search'"></i>查询</button>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="button" class="reset" (click)="resetForm($event)"><i nz-icon
[nzType]="'sync'"></i>重置</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div class="tablebox" id="tablebox">
<nz-table [nzLoading]="tableSpin" [nzPageSize]='999' #headerTable [nzData]="list" [nzShowPagination]="false"
[nzScroll]="{ y:tableheight() }" [nzNoResult]='null' nzTableLayout="fixed">
<thead>
<tr>
<th [nzWidth]="'20%'">
<div style="width: 20px;height: 20px;display: inline-block;margin-left: 20px;margin-right: 6px;">
</div>加油站名称
</th>
<th>区域</th>
<th>所属公司</th>
<th>联系人</th>
<th>联系电话</th>
<th>油站等级</th>
<th>经营品类</th>
<th [nzWidth]="'6%'">油机数量</th>
<th [nzWidth]="'6%'">车道数量</th>
<th [nzWidth]="'8%'">油罐容积</th>
<th [nzWidth]="'5%'">操作</th>
</tr>
</thead>
<tbody id="table">
<tr *ngFor="let item of headerTable.data;let key = index">
<th nzEllipsis [title]="item.stationName">
<div style="width: 20px;height: 20px;display: inline-block;margin-left: 20px;margin-right: 6px;">
<img src="../../../assets/images/3d.png" alt="" *ngIf="item.hasBuildingInfo">
</div>
{{item.stationName}}
</th>
<th nzEllipsis [title]="item.locationName">{{item.locationName}}</th>
<th nzEllipsis [title]="item.companyName">{{item.companyName}}</th>
<th nzEllipsis [title]="item.leaderName">{{item.leaderName}}</th>
<th nzEllipsis [title]="item.leaderContact">{{item.leaderContact}}</th>
<th nzEllipsis [title]="item.stationLevel">{{item.stationLevel}}</th>
<th nzEllipsis [title]="item.sellVariety">{{item.sellVariety}}</th>
<th>{{item.gasStationCount}}</th>
<th>{{item.laneCount}}</th>
<th style="display: flex;justify-content: space-between;">
<span>{{item.tankVolume}}</span>
<span style="margin-right:55%;">{{item.tankVolume ? 'm³' : null}}</span>
</th>
<th>
<span class="look" (click)="look(item)" style="cursor:pointer;color: #36A2FF">查看</span>
</th>
</tr>
</tbody>
</nz-table>
</div>
</div>
</div>

193
src/app/pages/plan-admin/plan-admin.component.scss

@ -0,0 +1,193 @@
.stationPlanBox {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 20px 24px;
display: flex;
}
.title {
width: 100%;
height: 48px;
}
.orbox {
height: 100%;
width: 360px;
margin-right: 40px;
display: flex;
flex-direction: column;
.or {
flex: 1;
overflow-y: auto;
border: 1px solid rgba(54, 162, 255, 0.3);
background: linear-gradient(180deg, rgba(3, 0, 0, 0) 0%, rgba(0, 46, 91, 0.68) 100%);
margin-top: 12px;
box-sizing: border-box;
padding: 18px 12px;
nz-tree {
background: none;
color: #c4e2fc;
}
}
}
.stationList {
flex: 1;
display: flex;
flex-direction: column;
.search {
box-sizing: border-box;
padding-left: 22px;
padding-right: 33px;
width: 100%;
height: 32px;
margin-top: 14px;
margin-bottom: 22px;
form {
width: 100%;
height: 32px;
display: flex;
justify-content: flex-end;
input {
background: none;
border: 1px solid #91ccff;
color: #fff;
}
.searchParams {
width: 22%;
}
.btn {
width: 5%;
margin-left: 16px;
}
}
}
.tablebox {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
.pagination {
margin-top: 26px;
display: flex;
align-items: center;
justify-content: center;
}
::-webkit-scrollbar {
width: 0px;
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.stationPlanBox {
padding: 16px 20px;
}
.title {
width: 100%;
height: 42px;
}
.orbox {
width: 290px;
margin-right: 32px;
.or {
margin-top: 8px;
padding: 15px 10px;
}
}
.stationList {
.search {
box-sizing: border-box;
padding-left: 22px;
padding-right: 30px;
width: 100%;
height: 32px;
margin-top: 8px;
margin-bottom: 15px;
form {
height: 32px;
.searchParams {
flex: 12;
}
.btn {
flex: 1;
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.stationPlanBox {
padding: 12px 15px;
}
.title {
width: 100%;
height: 33px;
}
.orbox {
width: 250px;
margin-right:23px;
.or {
margin-top: 5px;
padding: 10px 6px;
}
}
.stationList {
.search {
box-sizing: border-box;
padding-left: 18px;
padding-right: 22px;
width: 100%;
height: 32px;
margin-top: 8px;
margin-bottom: 15px;
form {
height: 32px;
.searchParams {
flex: 10;
}
.btn {
flex: 1;
}
}
}
.tablebox{
nz-table{
th{
font-size: 10px!important;
}
}
}
}
}

173
src/app/pages/plan-admin/plan-admin.component.ts

@ -0,0 +1,173 @@
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TreeService } from 'src/app/service/tree.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown';
import { NzFormatEmitEvent, NzTreeComponent, NzTreeNode } from 'ng-zorro-antd/tree';
import { Router } from '@angular/router';
import { NavChangeService } from 'src/app/service/navChange.service';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Component({
selector: 'app-plan-admin',
templateUrl: './plan-admin.component.html',
styleUrls: ['./plan-admin.component.scss']
})
export class PlanAdminComponent implements OnInit {
validateForm!: FormGroup;
@ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;
constructor(private element: ElementRef, private navChangeService: NavChangeService, private http: HttpClient, private toTree: TreeService, private fb: FormBuilder, private nzContextMenuService: NzContextMenuService, private router: Router) { }
list: any = []
ngOnInit(): void {
this.validateForm = this.fb.group({
name: [null]
});
this.tableSpin = true
this.getAllOrganization()
}
ngAfterViewInit(): void {
fromEvent(this.element.nativeElement.querySelector(`.ant-table-body`) as HTMLCanvasElement, 'scroll').pipe(debounceTime(100)).subscribe(async (event: any) => { //监听 DOM 滚动事件
if (event.target.scrollHeight - (event.target.scrollTop + event.target.clientHeight) <= 10) {
if (this.totalCount > this.list.length) {
console.log('需要加载数据了', event)
this.SkipCount = String(Number(this.SkipCount) + 50)
await this.getGasStation()
}
}
});
}
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
this.list = []
this.SkipCount = '0'
this.getGasStation()
}
resetForm(e: MouseEvent): void {
e.preventDefault();
this.validateForm.reset();
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
this.list = []
this.SkipCount = '0'
this.getGasStation()
}
//获取所有组织机构
nodes: any = []
nzExpandAll = false
nzSelectedKeys: any = []
orSpin: boolean = false
getAllOrganization() {
this.orSpin = true
let OrganizationUnitId = sessionStorage.getItem('isGasStation') == 'true' ? JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id : JSON.parse(sessionStorage.getItem('userdata')).organization.id
let params = {
OrganizationUnitId: OrganizationUnitId,
IsContainsChildren: "true"
}
this.http.get('/api/services/app/Organization/GetAll', {
params: params
}).subscribe((data: any) => {
data.result.items.forEach(element => {
if (element.id == OrganizationUnitId) {
element.parentId = null
}
});
data.result.items = data.result.items.filter((item, i) => {
return !item.isGasStation
})
for (let index = 0; index < data.result.items.length; index++) {
const element = data.result.items[index];
element.key = element.id
element.title = element.displayName
}
// console.log('组织机构', data.result.items)
this.orSpin = false
this.nodes = [...this.toTree.toTree(data.result.items)]
this.nzExpandedKeys = [OrganizationUnitId]
this.nzSelectedKeys = [OrganizationUnitId]
this.OrganizationUnitId = OrganizationUnitId
this.getGasStation()
})
}
tableheight() {
return (document.getElementById('tablebox').clientHeight - 42) + 'px'
}
look(item) {
let gastionobj = {
organization: {
displayName: item.stationName,
isGasStation: true,
id: item.organizationUnitId
}
}
sessionStorage.setItem('userdataOfgasstation', JSON.stringify(gastionobj))
this.router.navigate(['/todaywarning/petrolStation'])
let obj = {
name: 'oilstation'
}
this.navChangeService.sendMessage(obj);//发布一条消息
}
nzExpandedKeys: any = []
activatedNode?: NzTreeNode;
//点击tree节点
activeNode(data: NzFormatEmitEvent): void {
this.activatedNode = data.node!;
// console.log(data)
this.OrganizationUnitId = data.node.origin.id
this.list = []
this.SkipCount = '0'
this.getGasStation()
}
//获取点击组织机构的所有加油站
SkipCount: string = '0'
MaxResultCount: string = '100'
OrganizationUnitId: any
tableSpin: boolean = false
totalCount: any //总数
async getGasStation() {
let params = {
StationName: this.validateForm.value.name,
OrganizationUnitId: String(this.OrganizationUnitId),
IsContainsChildren: 'true',
SkipCount: this.SkipCount,
MaxResultCount: this.MaxResultCount,
Sorting: ' BuildingBasicInfo.Id asc'
}
this.tableSpin = true
await new Promise((resolve, reject) => {
this.http.get('/api/services/app/GasStation/GetAll', {
params: params
}).subscribe((data: any) => {
this.totalCount = data.result.totalCount
this.list = this.list.concat(data.result.items);
this.list = [...this.list]
this.tableSpin = false
resolve(data)
})
})
}
expand(e, node) {
e.stopPropagation()
node.isExpanded = !node.isExpanded
}
}

51
src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.html

@ -0,0 +1,51 @@
<div class="box">
<div class="titlebox">
<div class="title">
<div (click)="contentType('img')" [ngClass]="{'selected': selectedType == 'img'}">
预警截图
<div class="border"></div>
</div>
<div
*ngIf="data.violation && data.violation.eventSystemName != '灭火器维护' && data.violation.eventSystemName != '证照预警'"
(click)="contentType('video')" [ngClass]="{'selected': selectedType == 'video'}">
预警视频
<div class="border"></div>
</div>
</div>
</div>
<div class="details">
预警详情:{{details}}
</div>
<div class="content">
<div *ngIf="selectedType == 'img'" class="imgbox">
<img [src]="imgUrl" alt="">
</div>
<div *ngIf="selectedType == 'video'" class="vediobox">
<video controls style="width: 100%;height: 100%;" [src]="vedioUrl"></video>
</div>
</div>
<div class="disposebox">
<div class="title">
<span>处置内容</span>
<div class="disposeboxbtn">
<span *ngIf="!data.handleTime" style="color: #c73939;cursor: pointer;margin-right: 6px;" (click)="misinformation()">误报</span>
<span *ngIf="!data.handleTime" style="color: #36A2FF;cursor: pointer;" (click)="submit()">提交</span>
<span *ngIf="data.handleTime" style="color: #4BFFD4;cursor: default;">已处置<span *ngIf="data.isFalsePositive">(误报)</span></span>
</div>
</div>
<div class="disposeContent">
<textarea *ngIf="!data.handleTime" [(ngModel)]="content"></textarea>
<span *ngIf="data.handleTime">{{content}}</span>
</div>
<div class="disposeTime" *ngIf="data.handleTime">
<span style="margin-right: 12px;">
处置人:{{data.handleUsername}}
</span>
<span>
处置时间:{{data.handleTime|date:"yyyy-MM-dd HH:mm:ss"}}
</span>
</div>
</div>
</div>

225
src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.scss

@ -0,0 +1,225 @@
.box {
width: 100%;
height: 715px;
// overflow-y: auto;
color: #fff;
display: flex;
flex-direction: column;
background-image: linear-gradient(#003B6E, #000D21);
position: relative;
}
.titlebox {
width: 100%;
height: 48px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
display: flex;
align-items: center;
.title {
width: 100%;
height: 32px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
display: flex;
justify-content: center;
div {
width: 120px;
height: 32px;
text-align: center;
line-height: 32px;
font-family: sybold;
font-size: 16px;
position: relative;
cursor: pointer;
margin: 0 18px;
.border {
position: absolute;
bottom: -7px;
left: -18px;
width: 120px;
height: 4px;
}
}
.selected {
background: linear-gradient(90deg, rgba(35, 153, 255, 0.57) 0%, #25b7d4 50%, rgba(35, 153, 255, 0.57) 100%);
.border {
background: linear-gradient(90deg, rgba(35, 217, 255, 0) 0%, #25b7d4 50%, rgba(35, 217, 255, 0) 100%);
}
}
}
}
.details {
width: 100%;
height: 45px;
line-height: 45px;
box-sizing: border-box;
padding: 0 12px;
}
.content {
flex: 1;
overflow: hidden;
.imgbox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img {
max-width: 100%;
max-height: 100%;
}
}
.vediobox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
video {
max-width: 100%;
max-height: 100%;
}
}
}
.disposebox {
width: 100%;
height: 95px;
box-sizing: border-box;
padding: 5px 12px;
display: flex;
flex-direction: column;
.title {
display: flex;
justify-content: space-between;
}
.disposeboxbtn {
display: flex;
align-items: center;
}
.disposeContent {
display: flex;
align-items: center;
textarea {
width: 100%;
height: 40px;
color: #C4E2FC;
border: 1px solid #91CCFF;
background-color: #172c45;
}
span {
display: inline-block;
width: 100%;
height: 40px;
line-height: 40px;
}
}
.disposeTime {}
}
.ant-modal-close {
color: #fff;
}
// 适配125%
@media screen and (max-height: 750px) {
.box {
width: 100%;
height: 650px;
color: #fff;
display: flex;
flex-direction: column;
background-image: linear-gradient(#003B6E, #000D21);
position: relative;
}
.content {
.imgbox {
.bigimg {
// min-width: 1149px;
flex: 1;
box-sizing: border-box;
padding-left: 13px;
display: flex;
justify-content: center;
img {
max-width: 100%;
max-height: 100%;
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.box {
width: 100%;
height: 480px;
color: #fff;
display: flex;
flex-direction: column;
background-image: linear-gradient(#003B6E, #000D21);
position: relative;
}
.content {
.imgbox {
.bigimg {
// min-width: 1149px;
flex: 1;
box-sizing: border-box;
padding-left: 13px;
display: flex;
justify-content: center;
img {
max-width: 100%;
max-height: 100%;
}
}
}
}
}
::-webkit-input-placeholder {
/* WebKit browsers */
color: #345d85;
}
//滚动条样式
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-thumb {
background-image: linear-gradient(#2495f8, #1c73c2, #0a3d6a, #061d3c);
}
::-webkit-scrollbar-track {
background-color: #061d3c;
}

68
src/app/pages/today-warning/get-out-of-line-details/get-out-of-line-details.component.ts

@ -0,0 +1,68 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, Input } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
@Component({
selector: 'app-get-out-of-line-details',
templateUrl: './get-out-of-line-details.component.html',
styleUrls: ['./get-out-of-line-details.component.scss']
})
export class GetOutOfLineDetailsComponent implements OnInit {
@Input() data: any
constructor(private fb: FormBuilder, private http: HttpClient, private message: NzMessageService, private modal: NzModalService) { }
imgUrl: string
vedioUrl: string
content
details
ngOnInit(): void {
console.log(this.data)
this.details = this.data.content1
this.imgUrl = this.data.violateImage
this.vedioUrl = this.data.violateVideo
this.content = this.data.handleRecord
}
selectedType: string = 'img'
contentType(type) {
this.selectedType = type
}
submit() {
let body = {
id: this.data.id,
handleRecord: this.content
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
this.message.create('success', '处置成功!');
this.data.handleTime = new Date()
this.data.handleRecord = this.content
})
}
//误报
misinformation() {
this.modal.confirm({
nzTitle: '确定判定该预警为误报吗?',
// nzContent: '<b style="color: red;">Some descriptions</b>',
nzOkText: '确定',
nzOkType: 'danger',
nzOnOk: () => {
let body = {
id: this.data.id,
handleRecord: this.content ? this.content : '此条预警为误报',
isFalsePositive: true
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
this.message.create('success', '处置成功!');
this.data.handleTime = new Date()
this.content ? this.data.handleRecord = this.content : this.data.handleRecord = '此条预警为误报'
})
},
nzCancelText: '取消',
nzOnCancel: () => console.log('Cancel')
});
}
}

138
src/app/pages/today-warning/today-warning.component.html

@ -0,0 +1,138 @@
<div class="warningbox" id="warningbox">
<div class="title">
<app-title [name]="'当日预警事件列表'"></app-title>
<div class="warningnumber">
<img src="../../../assets/images/warningnum.png" alt="">
<span class="today">今日预警</span>
<span class="num">{{totalCount}}</span>
</div>
</div>
<div class="search">
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear id="level" formControlName="level" nzPlaceHolder="请选择预警级别">
<nz-option nzValue="1" nzLabel="一级"></nz-option>
<nz-option nzValue="2" nzLabel="二级"></nz-option>
<nz-option nzValue="3" nzLabel="三级"></nz-option>
<nz-option nzValue="4" nzLabel="四级"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear id="type" (ngModelChange)="typeChange($event)" formControlName="type" nzPlaceHolder="请选择预警类型">
<nz-option *ngFor="let item of warningTypes" [nzValue]="item.key" [nzLabel]="item.key"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear formControlName="area" nzPlaceHolder="请选择区域">
<nz-option nzValue="出入口" nzLabel="出入口"></nz-option>
<nz-option nzValue="加油区" nzLabel="加油区"></nz-option>
<nz-option nzValue="油罐区" nzLabel="油罐区"></nz-option>
<nz-option nzValue="便利店" nzLabel="便利店"></nz-option>
<nz-option nzValue="办公区" nzLabel="办公区"></nz-option>
<nz-option nzValue="其他区域" nzLabel="其他区域"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-select nzAllowClear formControlName="disposalState" nzPlaceHolder="请选择处置状态">
<nz-option nzValue="0" nzLabel="已处置"></nz-option>
<nz-option nzValue="1" nzLabel="未处置"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-time-picker [nzAllowEmpty]="false" nzPlaceHolder="请选择开始时间" formControlName="datePickerStart" nzFormat="HH:mm"></nz-time-picker>
</nz-form-control>
</nz-form-item>
<i style="display: flex;align-items: center;color: #fff;" nz-icon nzType="swap-right" nzTheme="outline"></i>
<nz-form-item class="searchParams">
<nz-form-control>
<nz-time-picker [nzAllowEmpty]="false" nzPlaceHolder="请选择结束时间" formControlName="datePickerEnd" nzFormat="HH:mm"></nz-time-picker>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="submit" class="submit"><i nz-icon [nzType]="'search'"></i>查询</button>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="button" class="reset" (click)="resetForm($event)"><i nz-icon
[nzType]="'sync'"></i>重置</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div class="listbox" style="text-align: center;">
<div nz-row class="listitem" *ngFor="let item of list">
<div nz-col nzSpan="3" class="imgbox">
<span *ngIf="item.violation.violationType == '卸油作业检查'">
<img src="../../../assets/images/warning2.png">
</span>
<span
*ngIf="item.violation.violationType != '卸油作业检查' && item.violation.violationType != '证件临期' && item.violation.violationType != '器材临期' ">
<img src=" ../../../assets/images/warning1.png">
</span>
<span *ngIf="item.violation.violationType === '证件临期'">
<img src="../../../assets/images/warning3.png">
</span>
<span *ngIf="item.violation.violationType === '器材临期'">
<img src="../../../assets/images/warning3.png">
</span>
<span *ngIf="item.violation.level == 1">
Ⅰ级
</span>
<span *ngIf="item.violation.level == 2">
Ⅱ级
</span>
<span *ngIf="item.violation.level == 3">
Ⅲ级
</span>
<span *ngIf="item.violation.level == 4">
Ⅳ级
</span>
</div>
<div nz-col nzSpan="3">
预警类型: {{item.violation.violationType}}
</div>
<div nz-col nzSpan="4">
预警信息: {{item.violation.eventSystemName}}
</div>
<div nz-col nzSpan="4">
区域: {{item.violateArea}}
</div>
<div nz-col nzSpan="3">
摄像头: {{item.cameraNo}}
</div>
<div nz-col nzSpan="3">
{{item.violateTime | date:"yyyy-MM-dd HH:mm:ss"}}
</div>
<div nz-col nzSpan="2">
<ng-container *ngIf="!item.handleTime; else elseTemplate">
未处置
</ng-container>
<ng-template #elseTemplate>
<span style="color: #23D9FF;">已处置</span>
</ng-template>
</div>
<div nz-col nzSpan="2">
<button nz-button (click)="look(item)" style="margin-right: 16px;">查看</button>
<!-- <button *ngIf="!item.handleTime" nz-button (click)="dispose(item)">处置</button>
<span *ngIf="item.handleTime" style="color: #23D9FF;margin-left: 10px;">已处置</span> -->
</div>
</div>
<nz-spin nzSimple *ngIf="isSpin"></nz-spin>
</div>
</div>

279
src/app/pages/today-warning/today-warning.component.scss

@ -0,0 +1,279 @@
.warningbox {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
.title {
box-sizing: border-box;
padding: 0 20PX;
width: 100%;
height: 48px;
margin: 16px 0;
position: relative;
}
.warningnumber {
position: absolute;
right: 80px;
top: 9px;
display: flex;
align-items: center;
img {
width: 32px;
}
.today {
font-size: 18px;
font-family: titlefont;
color: #D0EAFF;
margin-left: 8px;
margin-right: 16px;
}
.num {
font-size: 20px;
text-shadow: 0px 0px 6px #8df;
color: white;
font-weight: 600;
}
}
.search {
box-sizing: border-box;
padding: 0 36px;
width: 100%;
height: 32px;
// margin-bottom: 18px;
form {
width: 100%;
height: 32px;
display: flex;
justify-content: flex-start;
.searchParams,
.btn {
margin: 0 3px;
}
.searchParams {
// flex: 2.9;
width: 150px;
}
.searchParamsLong{
width: 250px;
}
.btn {
// flex: 1;
}
nz-select {
color: rgba(145, 204, 255, 0.95);
}
nz-time-picker {
background-color: rgba(0, 0, 0, 0);
width: 100%;
}
}
}
.listbox {
flex: 1;
overflow-y: auto;
box-sizing: border-box;
padding: 20px 47px 20px 39px;
.listitem {
width: 100%;
height: 78px;
line-height: 78px;
border: 1px solid rgba(54, 162, 255, 0.478);
color: #91CCFF;
margin-bottom: 12px;
background: linear-gradient(180deg, rgba(3, 0, 0, 0) 0%, rgba(0, 46, 91, 0.68) 100%);
box-sizing: border-box;
padding-right: 60px;
div {
font-size: 15px;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
button {
font-size: 15px;
background-color: #013064;
border: 1px solid #4c8ac8;
color: #91CCFF;
}
}
.imgbox{
span{
img{
width: 30%;
height: 80%;
}
}
}
}
.dispositioned {
color: #23D9FF;
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.warningbox {
.title {
box-sizing: border-box;
padding: 0 16PX;
height: 42px;
margin: 12px 0;
position: relative;
}
.warningnumber {
right: 70px;
top: 9px;
img {
width: 32px;
}
.today {
font-size: 16px;
margin-left: 5px;
margin-right: 13px;
}
.num {
font-size: 18px;
}
}
.search {
padding: 0 32px;
height: 32px;
form {
height: 32px;
.searchParams,
.btn {
margin: 0 3px;
}
}
}
.listbox {
flex: 1;
overflow-y: auto;
box-sizing: border-box;
padding: 16px 35px 16px 36px;
.listitem {
height: 40px;
line-height: 40px;
margin-bottom: 8px;
padding-right: 36px;
div {
font-size: 12px;
button {
font-size: 12px;
}
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.warningbox {
.title {
box-sizing: border-box;
padding: 0 12PX;
height: 38px;
margin: 6px 0;
position: relative;
}
.warningnumber {
right: 70px;
top: 6px;
img {
width: 32px;
}
.today {
font-size: 15px;
margin-left: 5px;
margin-right: 13px;
}
.num {
font-size: 16px;
}
}
.search {
padding: 0 32px;
height: 32px;
form {
height: 32px;
.searchParams,
.btn {
margin: 0 3px;
}
}
}
.listbox {
flex: 1;
overflow-y: auto;
box-sizing: border-box;
padding: 16px 35px 16px 36px;
.listitem {
height: 36px;
line-height: 36px;
margin-bottom: 5px;
padding-right: 22px;
div {
font-size: 10px;
button {
font-size: 10px;
}
}
}
}
}
}

259
src/app/pages/today-warning/today-warning.component.ts

@ -0,0 +1,259 @@
import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { NzModalService } from 'ng-zorro-antd/modal';
import { GetOutOfLineDetailsComponent } from './get-out-of-line-details/get-out-of-line-details.component';
// import { TreeService } from 'src/app/service/tree.service';
// import { NavChangeService } from 'src/app/service/navChange.service';
import { TreeService } from '../../service/tree.service';
import { NavChangeService } from '../../service/navChange.service';
import * as moment from 'moment';
import { NzMessageService } from 'ng-zorro-antd/message';
import { listRefreshService } from '../../service/listRefresh.service';
import { DisposeequipmentComponent } from '../warning-statistics-list/disposeequipment/disposeequipment.component';
@Component({
selector: 'app-today-warning',
templateUrl: './today-warning.component.html',
styleUrls: ['./today-warning.component.scss']
})
export class TodayWarningComponent implements OnInit {
validateForm!: FormGroup;
constructor(private listRefreshService: listRefreshService, private http: HttpClient, private fb: FormBuilder, private toTree: TreeService, private modal: NzModalService, private viewContainerRef: ViewContainerRef, private navChangeService: NavChangeService, private message: NzMessageService) { }
ngOnInit(): void {
this.validateForm = this.fb.group({
level: [null],
type: [null],
area: [null],
disposalState: [null],
datePickerStart: [new Date(`${moment(new Date()).format('YYYY-MM-DD')} 00:00`)],
datePickerEnd: [new Date(`${moment(new Date()).format('YYYY-MM-DD')} 23:59`)]
});
this.warningType()
this.getEarlyWarningList()
this.listRefreshService.getMessage().subscribe((message: any) => {
//列表刷新
if (message.type == 'add') {
this.getEarlyWarningList()
}
//更新处置状态
if (message.type == 'updatehandleTime') {
// console.log('更新处置状态', message)
// console.log(this.list)
this.list.forEach(element => {
if (element.id == message.data) {
element.handleTime = new Date()
}
});
}
// let params = {
// id: message.notification.entityId
// }
// this.http.get('/api/services/app/ViolateRecord/Get', {
// params: params
// }).subscribe((data: any) => {
// this.list.unshift(data.result)
// console.log('新获取一条', data.result)
// })
});
}
//预警类型接口
warningTypes: any //预警接口数据
warningTypesDetails: any
warningType() {
this.http.get('/api/services/app/Violation/GetAllList').subscribe((data: any) => {
this.warningTypesDetails = data.result
this.warningTypes = (data.result as any).groupBy((t) => { return t.violationType });
})
}
typeChange(e) {
this.warningTypes.forEach(element => {
if (element.key == e) {
this.warningTypesDetails = element
}
});
}
//获得预警列表
list: any = [
]
totalCount: string //预警总数
isSpin: boolean = false
getEarlyWarningList() {
let ViolationIds = []
if (this.validateForm.value.type) {
this.warningTypesDetails.forEach(item => {
item.id ? ViolationIds.push(item.id) : null
});
}
let disposalState
if (this.validateForm.value.disposalState == '0') {
disposalState = true
} else if (this.validateForm.value.disposalState == '1') {
disposalState = false
} else {
disposalState = null
}
let params = {
Level: this.validateForm.value.level,
ViolationIds: ViolationIds,
ViolateArea: this.validateForm.value.area,
organizationUnitId: JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id,
ViolateTime: (this.validateForm.value.datePickerEnd && this.validateForm.value.datePickerStart) ? [moment(this.validateForm.value.datePickerStart).format('yyyy-MM-DD HH:mm:ss'), moment(this.validateForm.value.datePickerEnd).format('yyyy-MM-DD HH:mm:ss')] : null,
IsHandled: disposalState,
// ViolateTime: ['2021-10-27', '2021-11-26'],
IsContainsChildren: 'true',
SkipCount: '0',
MaxResultCount: '9999'
}
this.isSpin = true
this.http.get('/api/services/app/ViolateRecord/GetAll', {
params: params
}).subscribe((data: any) => {
this.list = data.result.items
this.totalCount = data.result.totalCount
console.log('预警列表', this.list)
this.isSpin = false
let obj = {
name: '改变数量',
num: this.totalCount
}
setTimeout(() => {
this.navChangeService.sendMessage(obj);//发布一条消息
}, 0);
})
}
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
this.getEarlyWarningList()
}
resetForm(e: MouseEvent): void {
e.preventDefault();
this.validateForm.reset();
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
this.validateForm.patchValue({
datePickerStart: new Date(`${moment(new Date()).format('YYYY-MM-DD')} 00:00`),
datePickerEnd: new Date(`${moment(new Date()).format('YYYY-MM-DD')} 23:59`)
});
this.getEarlyWarningList()
}
look(item) {
if (item.violation.eventSystemName == '灭火器维护') {
item.violatedItemSnapshotObj = JSON.parse(item.violatedItemSnapshot)
const modal = this.modal.create({
nzContent: DisposeequipmentComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 380,
nzBodyStyle: {
'border': '1px solid #91CCFF',
'border-radius': '0px',
'padding': '7px',
'box-shadow': '0 0 8px 0 #fff',
'background-image': 'linear-gradient(#003665, #000f25)'
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzClosable: false,
nzOnOk: async () => {
if (instance.isScrap) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.copydata2.violatedItemSnapshotObj.name,
storageLocation: instance.copydata2.violatedItemSnapshotObj.storageLocation,
productionDate: moment(instance.copydata2.violatedItemSnapshotObj.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.copydata2.violatedItemSnapshotObj.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.copydata2.violatedItemSnapshotObj.validityEndTime).format('yyyy-MM-DD'),
isScrapped: true,
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: item.id,
handleRecord: '报废成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '报废成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
if (instance.validateForm.valid) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.validateForm.value.name,
storageLocation: instance.validateForm.value.storageLocation,
productionDate: moment(instance.validateForm.value.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.validateForm.value.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.validateForm.value.validityEndTime).format('yyyy-MM-DD'),
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
// item.violatedItemSnapshotObj = data.result
let body = {
id: item.id,
handleRecord: '维保成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '维保成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
}
});
const instance = modal.getContentComponent();
} else {
const modal = this.modal.create({
nzContent: GetOutOfLineDetailsComponent,
nzWrapClassName: "vertical-center-modal",
nzViewContainerRef: this.viewContainerRef,
nzWidth: (document.documentElement.clientHeight < 650 || document.documentElement.clientWidth < 1400) ? 1000 : 1200,
nzBodyStyle: {
'border': '1px solid #6d9cc7',
'border-radius': '0px',
'padding': '0px',
'box-shadow': '0 0 8px 0 #fff',
'background': '#000D21',
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzOnOk: async () => {
}
});
const instance = modal.getContentComponent();
}
}
}

85
src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.html

@ -0,0 +1,85 @@
<div class="box" id="disposeequipment">
<div class="title">
<div class="titlecontent">
处置消防器材
</div>
<i nz-icon nzType="close" nzTheme="outline" (click)="destroyModal()"></i>
</div>
<p *ngIf="!data2.handleTime && !isScrap" style="color: green;text-align: center;margin-top: 12px;">维保<span
*ngIf="data2.numberOfTimes == 2">临期预警</span><span *ngIf="data2.numberOfTimes == 3">逾期预警</span>
</p>
<p *ngIf="!data2.handleTime && isScrap" style="color: red;text-align: center;margin-top: 12px;">报废<span
*ngIf="data2.numberOfTimes == 2">临期预警</span><span *ngIf="data2.numberOfTimes == 3">逾期预警</span>
</p>
<p *ngIf="data2.handleTime && (isScraped == '维保' || isScraped == '报废')" style="text-align: center;color: #91CCFF;">
<br>
<span *ngIf="isScraped == '维保'" style="color: green;">已处置<br></span>
<span *ngIf="isScraped == '报废'" style="color: red;">已处置<br></span>
<span>器材名称:{{newdata.name}}</span><br>
<span *ngIf="isScraped == '维保'" style="color: green;">处置方式:维保<br></span>
<span *ngIf="isScraped == '报废'" style="color: red;">处置方式:报废<br></span>
<span>处置时间:{{data2.handleTime | date:"yyyy-MM-dd HH:mm:ss"}}<br></span>
<span>存放地点:{{newdata.storageLocation}}<br></span>
<span>生产日期:{{newdata.productionDate | date:"yyyy-MM-dd"}}<br></span>
<span>下次维保日期:{{newdata.maintenanceDate | date:"yyyy-MM-dd"}}<br></span>
<span>有效期至:{{newdata.validityEndTime | date:"yyyy-MM-dd"}}</span>
</p>
<p *ngIf=" !data2.handleTime && isScrap" style="text-align: center;color: #91CCFF;">
<span>器材名称:{{data2.violatedItemSnapshotObj.name}}</span><br>
<span>存放地点:{{data2.violatedItemSnapshotObj.storageLocation}}<br></span>
<span>有效期至:{{data2.violatedItemSnapshotObj.validityEndTime | date:"yyyy-MM-dd"}}</span>
</p>
<form nz-form [formGroup]="validateForm" class="form">
<div *ngIf=" !data2.handleTime && !isScrap">
<p>消防器材名称</p>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input [(ngModel)]="data2.violatedItemSnapshotObj.name" nz-input type="text"
formControlName="name" placeholder="请输入名称" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<p>存放地点</p>
<nz-form-item>
<nz-form-control>
<nz-input-group>
<input [(ngModel)]="data2.violatedItemSnapshotObj.storageLocation" nz-input type="text"
formControlName="storageLocation" placeholder="请输入存放地点" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<p>生产日期</p>
<nz-form-item>
<nz-form-control>
<nz-date-picker [nzAllowClear]="false" [(ngModel)]="data2.violatedItemSnapshotObj.productionDate"
formControlName="productionDate" nzPlaceHolder="请输入生产日期">
</nz-date-picker>
</nz-form-control>
</nz-form-item>
<p>下次维保日期</p>
<nz-form-item>
<nz-form-control>
<nz-date-picker [nzAllowClear]="false" [(ngModel)]="data2.violatedItemSnapshotObj.maintenanceDate"
formControlName="maintenanceDate" nzPlaceHolder="请输入下次维保日期">
</nz-date-picker>
</nz-form-control>
</nz-form-item>
<p>有效期至</p>
<nz-form-item>
<nz-form-control>
<nz-date-picker [nzAllowClear]="false" [(ngModel)]="data2.violatedItemSnapshotObj.validityEndTime"
formControlName="validityEndTime" nzPlaceHolder="有效期至">
</nz-date-picker>
</nz-form-control>
</nz-form-item>
</div>
<div class="btnbox" *ngIf="!data2.handleTime">
<button nz-button type="submit" class="ok" (click)="ok()">确定</button>
<button nz-button type="button" class="cancel" (click)="destroyModal()">取消</button>
</div>
</form>
</div>

89
src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.scss

@ -0,0 +1,89 @@
#disposeequipment {
.title {
font-family: sybold;
width: 100%;
height: 48px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
display: flex;
align-items: center;
position: relative;
.titlecontent {
width: 100%;
height: 32px;
line-height: 32px;
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.57) 50%, rgba(35, 153, 255, 0) 100%);
text-align: center;
color: #91CCFF;
font-size: 16px;
}
i {
position: absolute;
right: 12px;
color: #fff;
font-size: 18px;
cursor: pointer;
}
}
.radiobox{
label{
color: white;
}
display: flex;
justify-content: center;
margin-top: 12px;
}
.form {
box-sizing: border-box;
padding: 0 17px;
p {
margin-bottom: 0;
color: #C4E2FC;
margin: 16px 0;
}
nz-form-item {
margin-bottom: 0;
input {
color: rgba(145, 204, 255, 0.95) !important;
}
}
nz-date-picker {
background-color: #143c61;
width: 100%;
}
.btnbox {
width: 100%;
margin-top: 24px;
margin-bottom: 17px;
display: flex;
justify-content: flex-end;
button {
border-radius: 0px;
color: #91CCFF;
}
button:nth-child(2) {
margin-left: 16px;
}
.ok {
background: rgba(0, 129, 255, 0.4);
}
.cancel {
border: 1px solid #C4E2FC;
background: #0c1e38;
color: rgba(99, 102, 105, 0.6);
box-shadow: 0 0 3px 0 #fff inset;
}
}
}
}

69
src/app/pages/warning-statistics-list/disposeequipment/disposeequipment.component.ts

@ -0,0 +1,69 @@
import { Component, OnInit, Input } from '@angular/core';
import { NzModalRef } from 'ng-zorro-antd/modal';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-disposeequipment',
templateUrl: './disposeequipment.component.html',
styleUrls: ['./disposeequipment.component.scss']
})
export class DisposeequipmentComponent implements OnInit {
@Input() data?: any;
validateForm!: FormGroup;
constructor(private modal: NzModalRef, private fb: FormBuilder, private http: HttpClient) { }
radioValue = "A"
data2
copydata2
isScrap
isScraped
newdata
ngOnInit(): void {
this.data2 = JSON.parse(JSON.stringify(this.data))
this.copydata2 = JSON.parse(JSON.stringify(this.data))
// console.log('快照预警数据', this.data2)
if (this.data2.handleTime) {
let params = {
Id: this.data2.violatedItemSnapshotObj.id
}
this.http.get('/api/services/app/FireEquipment/Get', { params: params }).subscribe((data: any) => {
console.log('处置后的设备信息', data)
this.newdata = data.result
if (data.result.isScrapped) {
this.isScraped = '报废'
} else {
this.isScraped = '维保'
}
})
}else{
if(this.data2.desc == '维保'){
this.isScrap = false
}else{
this.isScrap = true
}
}
this.validateForm = this.fb.group({
name: [null, [Validators.required]],
storageLocation: [null, [Validators.required]],
productionDate: [null, [Validators.required]],
maintenanceDate: [null, [Validators.required]],
validityEndTime: [null, [Validators.required]]
});
}
destroyModal() {
this.modal.destroy({ data: 'this the result data' });
}
ok() {
this.modal.triggerOk()
}
}

186
src/app/pages/warning-statistics-list/warning-statistics-list.component.html

@ -0,0 +1,186 @@
<div class="recordsbox" id="recordsbox">
<div class="content">
<div class="title">
<div class="titlebox">
<img src="../../../assets/images/logosm.png" alt="">
<div class="content">
<div class="contentitem">
<span class="grey" (click)="gorecordList()">预警类型统计</span>
<span class="grey" (click)="goOilList()">卸油统计</span>
<span>证照预警统计</span>
</div>
</div>
</div>
<img (click)="isEchartsShow()" class="packup" src="../../../assets/images/packup.png" alt="">
</div>
<div class="chartsbox" [hidden]="!isEcharts">
<div class="chart">
<div class="leftbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
预警统计
</span>
<div class="centerContent">
<div class="num">{{num}}</div>
<div class="numname">总数</div>
</div>
<div class="piechart" id="piechart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
<div class="rightbox" style="position: relative;">
<span class="chartname">
<img src="../../../assets/images/flower.png" alt="">
近30天预警走势
</span>
<div class="barchart" id="barchart">
</div>
<nz-spin *ngIf="chartsSpin" nzSimple class="nzspin"></nz-spin>
</div>
</div>
</div>
<div class="title">
<app-title [name]="'预警列表'"></app-title>
</div>
<div class="search">
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
<nz-form-item class="searchParams searchParamsLong">
<nz-form-control>
<nz-select [nzAllowClear]="false" nzAllowClear formControlName="eventSystemName"
nzPlaceHolder="请选择状态">
<nz-option *ngFor="let item of eventSystemNameOption" [nzValue]="item.id"
[nzLabel]="item.name"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParamsLong" *ngIf="isOrShow">
<nz-form-control>
<nz-tree-select [nzAllowClear]="false" [nzDropdownClassName]="'maxHeightTreeSelect'"
nzShowSearch [(ngModel)]="defaultOrId" formControlName="organization" [nzNodes]="nodes"
nzPlaceHolder="请选择所属机构" [nzExpandedIcon]="multiExpandedIconTpl">
</nz-tree-select>
<ng-template #multiExpandedIconTpl let-node let-origin="origin">
<ng-container *ngIf="node.children.length == 0; else elseTemplate">
</ng-container>
<ng-template #elseTemplate>
<i nz-icon [nzType]="node.isExpanded ? 'caret-down' : 'caret-right'"
class="ant-tree-switcher-line-icon"></i>
</ng-template>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item class="searchParams searchParams2">
<nz-form-control>
<nz-range-picker [nzAllowClear]="false" formControlName="datePicker"></nz-range-picker>
<br />
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="submit" class="submit"><i nz-icon [nzType]="'search'"></i>查询</button>
</nz-form-control>
</nz-form-item>
<nz-form-item class="btn">
<nz-form-control>
<button nz-button type="button" class="reset" (click)="resetForm($event)"><i nz-icon
[nzType]="'sync'"></i>重置</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div class="tablebox">
<div class="table">
<div nz-row class="th">
<div nz-col nzSpan="1">
<span style="margin-left: 20px;white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;">序号</span>
</div>
<div nz-col nzSpan="2">
预警类别
</div>
<div nz-col nzSpan="3">
预警内容
</div>
<div nz-col nzSpan="3">
公司名称
</div>
<div nz-col nzSpan="5">
区域名称
</div>
<div nz-col nzSpan="3">
所属油站
</div>
<div nz-col nzSpan="3">
证照/消防设施名称
</div>
<div nz-col nzSpan="3">
有效期限
</div>
<div nz-col nzSpan="1">
操作
</div>
</div>
<div class="tbody" id="tbody">
<div nz-row class="tr" *ngFor="let item of list;let key = index">
<div nz-col nzSpan="1">
<span style="margin-left: 20px;">{{key+1}}</span>
</div>
<div nz-col nzSpan="2">
<ng-container *ngIf="item.numberOfTimes; else elseTemplate">
<span *ngIf="item.numberOfTimes == 1">办理提醒</span>
<span *ngIf="item.numberOfTimes == 2">临期提醒</span>
<span *ngIf="item.numberOfTimes == 3">逾期报警</span>
</ng-container>
<ng-template #elseTemplate>
逾期报警
</ng-template>
</div>
<div nz-col nzSpan="3">
<ng-container *ngIf="item.numberOfTimes; else elseTemplate2">
<span *ngIf="item.numberOfTimes == 1">{{item.desc}}办理提醒</span>
<span *ngIf="item.numberOfTimes == 2">{{item.desc}}临期提醒</span>
<span *ngIf="item.numberOfTimes == 3">{{item.desc}}逾期报警</span>
</ng-container>
<ng-template #elseTemplate2>
消防设备逾期报警
</ng-template>
</div>
<div nz-col nzSpan="3" [title]="item.gasStation.companyName">
{{item.gasStation.companyName ? item.gasStation.companyName : '/'}}
</div>
<div nz-col nzSpan="5" [title]="item.gasStation.locationName">
{{item.gasStation.locationName ? item.gasStation.locationName : '/'}}
</div>
<div nz-col nzSpan="3" [title]="item.gasStation.stationName">
{{item.gasStation.stationName ? item.gasStation.stationName : '/'}}
</div>
<div nz-col nzSpan="3">
{{item.violatedItemSnapshotObj.name ? item.violatedItemSnapshotObj.name : '/'}}
</div>
<div nz-col nzSpan="3">
{{item.violatedItemSnapshotObj.validityEndTime ?
(item.violatedItemSnapshotObj.validityEndTime | date:"yyyy-MM-dd") : '/'}}
</div>
<div nz-col nzSpan="1">
<span style="cursor: pointer;color: #36A2FF;" (click)="look(item)">查看</span>
</div>
</div>
<div nz-row class="tr" *ngIf="tableSpin">
<div nz-col nzSpan="24" style="text-align: center;">
<nz-spin nzSimple></nz-spin>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

620
src/app/pages/warning-statistics-list/warning-statistics-list.component.scss

@ -0,0 +1,620 @@
.recordsbox {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.search {
box-sizing: border-box;
padding: 0 36px;
width: 100%;
height: 32px;
margin-bottom: 16px;
form {
width: 100%;
height: 32px;
display: flex;
justify-content: flex-start;
.searchParams,
.btn {
margin: 0 3px;
}
.searchParams {
// flex: 10;
width: 150px;
}
.searchParamsLong {
width: 250px;
}
.searchParams2 {
width: 220px;
}
.btn {
// flex: 1;
}
nz-select {
color: rgba(145, 204, 255, 0.95);
}
nz-tree-select {
color: rgba(145, 204, 255, 0.95);
}
nz-range-picker {
background-color: rgba(0, 0, 0, 0);
width: 100%;
}
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
margin: 13px 0;
width: 100%;
height: 64px;
box-sizing: border-box;
padding: 0 28px;
position: relative;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 65px;
height: 65px;
}
.content {
flex: 1;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
// background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%);
.contentitem {
width: 100%;
height: 32px;
display: flex;
align-items: center;
// background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%);
span {
margin-left: 10px;
color: #bce0ff;
font-size: 20px;
font-family: titlefont;
cursor: pointer;
}
span:nth-child(1) {
margin-left: 12px;
}
.grey {
color: #68829F;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 16px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
display: flex;
justify-content: center;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 350px;
box-sizing: border-box;
padding: 0 10px;
display: flex;
div {
display: flex;
flex-direction: column;
span {
font-family: titlefont;
display: flex;
align-items: center;
height: 28px;
color: #bee1ff;
font-size: 16px;
}
div {
flex: 1;
}
}
.leftbox {
width: 360px;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
margin-right: 16px;
.centerContent {
position: absolute;
top: 34%;
left: 50%;
transform: translateX(-50%);
width: 170px;
div {
text-align: center;
}
.numname {
// font-family: titlefont;
color: #bee1ff;
}
.num {
color: #FFFFFF;
font-size: 38px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 46px;
line-height: 46px;
}
}
.goback {
position: absolute;
right: 20px;
top: 14px;
color: #C4E2FC;
font-family: synormal;
font-size: 14px;
z-index: 999;
cursor: pointer;
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
button {
border: 1px solid #91CCFF;
color: #91CCFF;
border-radius: 0px;
box-shadow: 0 0 5px 0 #2399FF inset;
background: none;
}
.rankingBtn {
margin-right: 16px;
}
.selectedbtn {
background: linear-gradient(180deg, #000D21 0%, #001331 27%, #2399FF 100%);
color: white;
}
}
}
}
}
.tablebox {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
.table {
color: white;
flex: 1;
width: 96%;
display: flex;
flex-direction: column;
overflow: hidden;
.th {
height: 38px;
line-height: 38px;
background: rgba(35, 153, 255, 0.2);
border: 1px solid rgba(35, 217, 255, 0.4);
box-shadow: 0 0 3px 0 rgba(35, 217, 255, 0.4) inset;
color: #23D9FF;
}
.tbody {
flex: 1;
overflow-y: auto;
.tr {
height: 38px;
line-height: 38px;
border-bottom: 1px solid #0d3761;
div {
color: #91CCFF;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.look {
color: #36A2FF;
cursor: pointer;
}
.grey{
color: grey!important;
}
}
}
}
}
.pagination {
margin: 15px 0;
display: flex;
align-items: center;
justify-content: center;
}
::-webkit-scrollbar {
width: 0px;
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.search {
box-sizing: border-box;
padding: 0 30px;
height: 32px;
margin-bottom: 12px;
form {
width: 100%;
height: 32px;
}
}
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
height: 42px;
padding: 0 20px;
margin: 8px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 46px;
height: 46px;
}
.content {
height: 36px;
.contentitem {
width: 100%;
height: 25px;
span {
margin-left: 6px;
font-size: 16px;
}
span:nth-child(1) {
margin-left: 8px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 4px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 43%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 300px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 12px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 42px;
text-shadow: 0px 0px 16px #3A9AFF;
font-weight: bold;
height: 49px;
line-height: 50px;
}
}
}
.rightbox {
flex: 1;
position: relative;
border: 0px;
box-shadow: 0 0 26px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 12px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 32px;
line-height: 32px;
font-size: 12px !important;
}
.tbody {
.tr {
height: 32px;
line-height: 32px;
div {
font-size: 12px !important;
}
img {
width: 32px;
}
}
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.search {
box-sizing: border-box;
padding: 0 22px;
height: 32px;
margin-bottom: 6px;
form {
width: 100%;
height: 32px;
}
}
.content {
.title {
height: 36px;
padding: 0 20px;
margin: 3px 0;
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 36px;
height: 36px;
}
.content {
height: 30px;
.contentitem {
width: 100%;
height: 22px;
span {
margin-left: 6px;
font-size: 13px;
}
span:nth-child(1) {
margin-left: 12px;
}
}
}
}
.packup {
position: absolute;
right: 33px;
top: 2px;
cursor: pointer;
}
}
.chartsbox {
width: 100%;
height: 40%;
.chartname {
position: absolute;
left: 20px;
top: 12px;
}
.chart {
width: 97%;
height: 100%;
div {
span {
font-size: 14px;
}
div {
flex: 1;
}
}
.leftbox {
width: 260px;
box-shadow: 0 0 20px 0px #1a7fd7 inset;
margin-right: 8px;
.centerContent {
.num {
color: #FFFFFF;
font-size: 32px;
text-shadow: 0px 0px 12px #3A9AFF;
font-weight: bold;
height: 42px;
line-height: 42px;
}
}
}
.rightbox {
box-shadow: 0 0 22px 0px #1a7fd7 inset;
.btnbox {
position: absolute;
right: 28px;
top: 12px;
display: flex;
flex-direction: row;
z-index: 999;
.rankingBtn {
margin-right: 8px;
}
}
}
}
}
.tablebox {
.table {
.th {
height: 28px;
line-height: 28px;
font-size: 10px !important;
}
.tbody {
.tr {
height: 28px;
line-height: 28px;
div {
font-size: 10px !important;
}
img {
width: 30px;
}
}
}
}
}
}
}

739
src/app/pages/warning-statistics-list/warning-statistics-list.component.ts

@ -0,0 +1,739 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewContainerRef, ElementRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import * as echarts from 'echarts';
import { NzModalService } from 'ng-zorro-antd/modal';
import { GetOutOfLineDetailsComponent } from '../today-warning/get-out-of-line-details/get-out-of-line-details.component';
import * as moment from 'moment';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { Router } from '@angular/router';
import { OilUnloadingProcessComponent } from '../oil-unloading-process/oil-unloading-process.component';
import { TreeService } from 'src/app/service/tree.service';
import { DisposeequipmentComponent } from './disposeequipment/disposeequipment.component';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-warning-statistics-list',
templateUrl: './warning-statistics-list.component.html',
styleUrls: ['./warning-statistics-list.component.scss']
})
export class WarningStatisticsListComponent implements OnInit {
validateForm!: FormGroup;
constructor(private toTree: TreeService, private message: NzMessageService, private http: HttpClient, private fb: FormBuilder, private router: Router, private modal: NzModalService, private viewContainerRef: ViewContainerRef, private element: ElementRef) { }
myChart: any //左侧饼图
mybarChart: any //柱状图
isEcharts: boolean = true
isEchartsShow() {
this.isEcharts = !this.isEcharts
}
startdate
enddate
isOrShow: boolean
ngOnInit(): void {
//当前日期
let myDate: any = new Date();
let nowY = myDate.getFullYear();
let nowM = myDate.getMonth() + 1;
let nowD = myDate.getDate();
this.enddate = JSON.parse(JSON.stringify(nowY + "-" + (nowM < 10 ? "0" + nowM : nowM) + "-" + (nowD < 10 ? "0" + nowD : nowD)));//当前日期
//获取三十天前日期
let lw = new Date(myDate - 1000 * 60 * 60 * 24 * 30);//最后一个数字30可改,30天的意思
let lastY = lw.getFullYear();
let lastM = lw.getMonth() + 1;
let lastD = lw.getDate();
this.startdate = JSON.parse(JSON.stringify(lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD)));//三十天之前日期
this.validateForm = this.fb.group({
eventSystemName: null,
organization: [null],
datePicker: [[this.startdate, this.enddate]]
});
// 饼图
this.myChart = echarts.init(document.getElementById('piechart'));
//柱状折线图
this.mybarChart = echarts.init(document.getElementById('barchart'));
this.tableSpin = true
this.getAllOrganization()
this.getAggregations()
if (this.router.url.indexOf('petrolStation') != -1) {
this.isOrShow = false
} else {
this.isOrShow = true
}
}
//刷新饼图图表数据
num
echartsData: any
//一级饼图
oilchartpieOption = {
color: ['#FF4B65', '#36A2FF'],
tooltip: {
trigger: 'item'//触发类型
},
legend: {
bottom: '12%',
left: 'center',
itemGap: 40,
itemWidth: 8,
itemHeight: 8,
formatter: (name) => {
let data = this.oilchartpieOptionPieData1
let value
for (var i = 0, l = data.length; i < l; i++) {
if (data[i].name == name) {
value = data[i].value;
}
}
return '{a|' + name + '}' + '{b|' + value + '}';
},
textStyle: {
color: '#fff',
rich: {
a: {
width: 80
}
}
}
},
series: [
{
type: 'pie',
radius: ['50%', '60%'],
bottom: '10%',
avoidLabelOverlap: false,//防止标签重叠策略
label: {//每一个标签外网延伸的引导说明
show: false,
position: 'outside'
},
data: [],
tooltip: {//鼠标移入提示
position: 'right',
padding: [14, 19],
backgroundColor: 'rgba(28, 129, 218, 0.4)',
textStyle: {
color: '#fff',
fontSize: 12
}
}
}
]
};
oilchartpieOptionPieData1: any
//一级柱状图
oilchartbarOption = {
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF'
}
},
axisTick: {//刻度线
show: false
},
inverse: true
},
yAxis: {
type: 'value',
nameTextStyle: {
color: '#C4E2FC'
},
splitLine: {//分割线
lineStyle: {
color: ['#0f4374'],
width: 2
}
},
axisTick: {//刻度线
show: false
},
axisLine: {//轴线
show: false,
lineStyle: {
color: '#C4E2FC'
}
}
},
tooltip: {
// trigger: 'axis'
},
series: [
{
name: '预警事件',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#23F0FF' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(35, 153, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '预警事件',
data: [],
type: 'line',
symbol: 'circle',
symbolSize: 8,
label: {
show: true
},
itemStyle: {
color: '#fff',
shadowColor: '#fff',
shadowBlur: 10
},
lineStyle: {
color: '#FFCC8A',
width: 1
}
}
],
legend: {
data: ['预警事件'],
textStyle: {
color: '#fff'
},
right: 28,
top: 18,
itemWidth: 8,
itemHeight: 8,
},
grid: {
left: '42px',
right: '30px',
bottom: '38px',
top: '80px'
}
};
//二级饼图
oilchartpieOption2 = {
color: ['#36A2FF', '#FFBD4B', '#46DFFF'],
tooltip: {
trigger: 'item'//触发类型
},
legend: {
bottom: '8%',
left: 'center',
itemGap: 10,
itemWidth: 8,
itemHeight: 8,
formatter: (name) => {
let data = this.oilchartpieOptionPieData2
let value
for (var i = 0, l = data.length; i < l; i++) {
if (data[i].name == name) {
value = data[i].value;
}
}
return '{a|' + name + '}' + '{b|' + value + '}';
},
textStyle: {
color: '#fff',
rich: {
a: {
width: 60
}
}
}
},
series: [
{
type: 'pie',
radius: ['50%', '60%'],
bottom: '10%',
avoidLabelOverlap: false,//防止标签重叠策略
label: {//每二个标签外网延伸的引导说明
show: false,
position: 'outside'
},
data: [],
tooltip: {//鼠标移入提示
position: 'right',
padding: [14, 19],
backgroundColor: 'rgba(28, 129, 218, 0.4)',
textStyle: {
color: '#fff',
fontSize: 12
}
}
}
]
};
oilchartpieOptionPieData2: any
//二级柱状图
oilchartbarOption2 = {
tooltip: {
// trigger: 'axis'
},
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false,
lineStyle: {
color: '#91CCFF'
}
},
axisTick: {//刻度线
show: false
},
inverse: true
},
yAxis: {
type: 'value',
nameTextStyle: {
color: '#C4E2FC'
},
splitLine: {//分割线
lineStyle: {
color: ['#0f4374'],
width: 2
}
},
axisTick: {//刻度线
show: false
},
axisLine: {//轴线
show: false,
lineStyle: {
color: '#C4E2FC'
}
}
},
legend: {
data: ['事前准备', '事中操作', '全程监测'],
textStyle: {
color: '#fff'
},
right: 18,
top: 18,
itemWidth: 8,
itemHeight: 8,
},
series: [
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(54, 162, 255, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(54, 162, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(255, 189, 75, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(255, 189, 75, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
},
{
name: '',
data: [],
type: 'bar',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(70, 223, 255, 1)' // 0% 处的颜色
}, {
offset: 1, color: 'rgba(70, 223, 255, 0.1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
barWidth: '25%'
}
],
grid: {
left: '42px',
right: '30px',
bottom: '38px',
top: '80px'
}
};
isgoback: boolean = false
//获取统计信息
chartsSpin: boolean = false
getAggregations() {
this.chartsSpin = true
let organizationUnitId
if (this.router.url.indexOf('petrolStation') != -1) {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id
} else {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdata')).organization.id
}
let params: any = {
OrganizationUnitId: organizationUnitId,
IsContainsChildren: 'true'
}
this.http.get('/api/services/app/ViolateRecord/LicenseSummary', { params: params }).subscribe((data: any) => {
this.chartsSpin = false
this.echartsData = data.result
this.refreshEchartsData1(this.echartsData)
})
}
refreshEchartsData1(data) {
// console.log('echarts信息', data)
//饼图
let totalCount = 0
data.violationList.forEach(element => {
element.name = element.eventSystemName
element.value = element.count
totalCount += element.count
});
this.num = totalCount
this.oilchartpieOptionPieData1 = data.violationList
this.oilchartpieOption.series[0].data = this.oilchartpieOptionPieData1
this.myChart.setOption(this.oilchartpieOption);
this.myChart.off('legendselectchanged')
this.myChart.off('click')
this.myChart.on('click', (params) => {
if (params.name == '证照预警') {
console.log('点击myChart')
// this.validateForm.patchValue({
// state: '0'
// });
// this.list = []
// this.SkipCount = '0'
// this.getViolateRecordList()
}
});
//柱状图
let monthArr = []
let valuedata = []
data.timeList.forEach(element => {
monthArr.push(moment(element.key).format('MM.DD'))
valuedata.push(element.count)
});
this.oilchartbarOption.xAxis.data = monthArr
this.oilchartbarOption.series[0].data = valuedata
this.oilchartbarOption.series[1].data = valuedata
this.mybarChart.setOption(this.oilchartbarOption);
}
//预警类型接口
licenseId
equipmentId
defaultOrId: string
//获取所有组织机构
nodes: any = []
eventSystemNameOption = []
getAllOrganization() {
let OrganizationUnitId = sessionStorage.getItem('isGasStation') == 'true' ? JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id : JSON.parse(sessionStorage.getItem('userdata')).organization.id
let params = {
OrganizationUnitId: OrganizationUnitId,
IsContainsChildren: "true"
}
this.http.get('/api/services/app/Organization/GetAll', {
params: params
}).subscribe((data: any) => {
data.result.items.forEach(element => {
if (element.id == OrganizationUnitId) {
element.parentId = null
}
element.key = element.id
element.title = element.displayName
});
this.nodes = [...this.toTree.toTree(data.result.items)]
this.defaultOrId = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.value.organization = JSON.parse(sessionStorage.getItem('userdata')).organization.id
this.validateForm.patchValue({
datePicker: [this.startdate, this.enddate]
});
this.http.get('/api/services/app/Violation/GetAllList').subscribe((data: any) => {
console.log('预警事件', data.result)
let option1
let option2
data.result.forEach(element => {
if (element.eventSystemName == '证照预警') {
option1 = element.id
}
if (element.eventSystemName == '灭火器维护') {
option2 = element.id
}
});
this.eventSystemNameOption = [
{ id: option1, name: '证照预警' },
{ id: option2, name: '消防设施预警' },
]
this.list = []
this.SkipCount = '0'
this.getLicenseList()
})
})
}
//获得卸油记录列表
SkipCount: string = '0'
MaxResultCount: string = '50'
list: any = []
totalCount: string
tableSpin: boolean = false
//获得证照预警
getLicenseList() {
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
this.tableSpin = true
let organizationUnitId
if (this.router.url.indexOf('petrolStation') != -1) {
organizationUnitId = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).organization.id
} else {
organizationUnitId = this.validateForm.value.organization
}
let ViolationIds = []
// console.log(456, this.validateForm.value)
if (this.validateForm.value.eventSystemName) {
ViolationIds.push(this.validateForm.value.eventSystemName)
} else {
this.eventSystemNameOption.forEach(element => {
ViolationIds.push(element.id)
});
}
let params = {
ViolationIds: ViolationIds,
organizationUnitId: organizationUnitId,
ViolateTime: (this.validateForm.value.datePicker[0] && this.validateForm.value.datePicker[1]) ? [moment(this.validateForm.value.datePicker[0]).format('yyyy-MM-DD HH:mm:ss'), moment(this.validateForm.value.datePicker[1]).format('yyyy-MM-DD HH:mm:ss')] : null,
IsContainsChildren: 'true',
SkipCount: this.SkipCount,
MaxResultCount: '50'
}
this.http.get('/api/services/app/ViolateRecord/GetAll', {
params: params
}).subscribe((data: any) => {
this.tableSpin = false
data.result.items.forEach(element => {
element.violatedItemSnapshotObj = JSON.parse(element.violatedItemSnapshot)
});
this.list = this.list.concat(data.result.items);
this.list = [...this.list]
this.totalCount = data.result.totalCount
console.log('证照预警列表', data.result.items)
})
}
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
this.list = []
this.SkipCount = '0'
this.getLicenseList()
}
resetForm(e: MouseEvent): void {
e.preventDefault();
for (const key in this.validateForm.controls) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
// console.log('赋值日期', [this.startdate, this.enddate])
this.validateForm.patchValue({
datePicker: [this.startdate, this.enddate],
eventSystemName: null,
organization: JSON.parse(sessionStorage.getItem('userdata')).organization.id
});
this.list = []
this.SkipCount = '0'
this.getLicenseList()
}
ngAfterViewInit(): void {
fromEvent(this.element.nativeElement.querySelector(`#tbody`) as HTMLCanvasElement, 'scroll').pipe(debounceTime(100)).subscribe((event: any) => { //监听 DOM 滚动事件
if (event.target.scrollHeight - (event.target.scrollTop + event.target.clientHeight) <= 10) {
if (this.totalCount > this.list.length) {
console.log('需要加载数据了', event)
this.SkipCount = String(Number(this.SkipCount) + 50)
this.getLicenseList()
}
}
});
}
look(item) {
console.log(item)
if (item.violation.eventSystemName == '证照预警') {
const modal = this.modal.create({
nzContent: GetOutOfLineDetailsComponent,
nzWrapClassName: "vertical-center-modal",
nzViewContainerRef: this.viewContainerRef,
nzWidth: (document.documentElement.clientHeight < 650 || document.documentElement.clientWidth < 1400) ? 1000 : 1200,
nzBodyStyle: {
'border': '1px solid #6d9cc7',
'border-radius': '0px',
'padding': '0px',
'box-shadow': '0 0 8px 0 #fff',
'background': '#000D21',
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzOnOk: async () => {
// console.log(99999, instance.content)
}
});
const instance = modal.getContentComponent();
} else {
this.dispose(item)
}
}
//处置消防设施
dispose(item) {
const modal = this.modal.create({
nzContent: DisposeequipmentComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 380,
nzBodyStyle: {
'border': '1px solid #91CCFF',
'border-radius': '0px',
'padding': '7px',
'box-shadow': '0 0 8px 0 #fff',
'background-image': 'linear-gradient(#003665, #000f25)'
},
nzComponentParams: {
data: item
},
nzFooter: null,
nzClosable: false,
nzOnOk: async () => {
if (instance.isScrap) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.copydata2.violatedItemSnapshotObj.name,
storageLocation: instance.copydata2.violatedItemSnapshotObj.storageLocation,
productionDate: moment(instance.copydata2.violatedItemSnapshotObj.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.copydata2.violatedItemSnapshotObj.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.copydata2.violatedItemSnapshotObj.validityEndTime).format('yyyy-MM-DD'),
isScrapped: true,
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: item.id,
handleRecord: '报废成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '报废成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
if (instance.validateForm.valid) {
await new Promise(resolve => {
let body = {
id: item.violatedItemSnapshotObj.id,
name: instance.validateForm.value.name,
storageLocation: instance.validateForm.value.storageLocation,
productionDate: moment(instance.validateForm.value.productionDate).format('yyyy-MM-DD'),
maintenanceDate: moment(instance.validateForm.value.maintenanceDate).format('yyyy-MM-DD'),
validityEndTime: moment(instance.validateForm.value.validityEndTime).format('yyyy-MM-DD'),
organizationUnitId: item.violatedItemSnapshotObj.organizationUnitId
}
this.http.put('/api/services/app/FireEquipment/Update', body).subscribe((data: any) => {
let body = {
id: item.id,
handleRecord: '维保成功!'
}
this.http.post('/api/services/app/ViolateRecord/HandleViolateRecord', body).subscribe(data => {
resolve(data)
this.message.create('success', '维保成功!');
item.handleTime = new Date()
return true
})
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
}
});
const instance = modal.getContentComponent();
}
goOilList() {
if (this.router.url.indexOf('petrolStation') != -1) {
this.router.navigate(['/records/petrolStation/oliunloadinglist'])
} else {
this.router.navigate(['/records/oliunloadinglist'])
}
}
gorecordList() {
if (this.router.url.indexOf('petrolStation') != -1) {
this.router.navigate(['/records/petrolStation'])
} else {
this.router.navigate(['/records'])
}
}
}

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

41
src/app/service/cache-token.service.ts

@ -0,0 +1,41 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
@Injectable({
providedIn: 'root'
})
export class CacheTokenService {
constructor(private http: HttpClient) { }
public timer;
//刷新token令牌定时器
startUp = (): void => {
window.clearInterval(this.timer)
this.timer = window.setInterval(() => {
var token = sessionStorage.getItem("token");
var refreshToken = sessionStorage.getItem("refreshToken");
this.http.post('/api/CompanyAccount/RefreshToken', {
token: token,
refreshToken: refreshToken
}).subscribe((data: any) => {
sessionStorage.setItem("token", data.token);
})
}, 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)
}
}

22
src/app/service/listRefresh.service.ts

@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class listRefreshService {
constructor() { }
private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1);
/** * **
* @param message *
* @returns {Observavle<any>} */
public sendMessage(message: any) {
this._sendMessage.next(message);
}
public getMessage(): Observable<any> {
return this._sendMessage.asObservable();
}
}

22
src/app/service/navChange.service.ts

@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class NavChangeService {
constructor() { }
private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1);
/** * **
* @param message *
* @returns {Observavle<any>} */
public sendMessage(message: any) {
this._sendMessage.next(message);
}
public getMessage(): Observable <any> {
return this._sendMessage.asObservable();
}
}

139
src/app/service/objects.service.ts

@ -0,0 +1,139 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
/**
*
*/
enum EnvironmentType {
/**
*
*/
DevelopEditor,
/**
*
*/
Test,
/**
*
*/
Production,
}
@Injectable({
providedIn: 'root'
})
export class ObjectsService {
static readonly c_apiRoot = "/api/Objects/";//普通上传的API根路径
static readonly c_apiRoot_Multipart = "/api/";//分块上传的API根路径
/**
*
*/
static currentEnvironmentType: EnvironmentType = EnvironmentType.DevelopEditor;
/**
* +
*/
static baseUrl;
/**
*
* @param extensionPath ,
* 1 extensionPath = ceshi/assets//outDoor/a.gltf /api/Objects/{}/ceshi/assets//outDoor/a.gltf
* 2extensionPath = ceshi/web/a.rgb /api/Objects/{}/ceshi/web/a.rgb
*/
static getFullPath(extensionPath: string) {
return ObjectsService.baseUrl + extensionPath;
}
/**
*
*/
obsRootByEnv = new Map<EnvironmentType, string>([
[EnvironmentType.DevelopEditor, "sinochemweb/"], //开发与编辑
[EnvironmentType.Test, "sinochemweb/"],//测试
[EnvironmentType.Production, "sinochemweb/"],//生产环境(根据需要设置)最好是与测试环境的桶名相同
]);
constructor(private http: HttpClient) {
let bucketName = this.getBucketName();
ObjectsService.baseUrl = ObjectsService.c_apiRoot + bucketName;
}
/**
*
*/
getBucketName() {
return this.obsRootByEnv.get(ObjectsService.currentEnvironmentType);
}
/**
* 5M
*/
postFile(extensionPath: string, file: File): Observable<Object> {
let formData = new FormData()
formData.append("file", file, file.name)
let data = { keepOriginalName: 'true' }
return this.http.post(ObjectsService.getFullPath(extensionPath), formData, { params: data });
}
//分块上传
postFile_MultipartUpload(extensionPath: string, file: File): Promise<Object> {
// let formData = new FormData()
// formData.append("file", file, file.name)
// return this.http.post(ObjectsService.baseUrl + extensionPath, formData);
let data = { keepOriginalName: 'true', filename: file.name }
return new Promise((resolve, reject) => {
this.http.post(ObjectsService.c_apiRoot_Multipart + "NewMultipartUpload/" + this.getBucketName() + extensionPath, {}, { params: data }).subscribe(async (data: any) => { //初始化分段上传
let instance = this;
let objectName = data.objectName
let uploadId = data.uploadId
let PartNumberETag = []; //每次返回需要保存的信息
//分块 处理
let fileSize = file.size || null //上传文件的总大小
let shardSize = 5 * 1024 * 1024 //5MB一个分片
let allSlice = Math.ceil(fileSize / shardSize) //总文件/5MB===共分多少段
for (let i = 0; i < allSlice; i++) { //循环分段上传
let start = i * shardSize //切割文件开始位置
let end = Math.min(fileSize, start + shardSize); //切割文件结束位置
let formData = new FormData()
formData.append("file", file.slice(start, end))
//同步写法实现异步调用
let result = await new Promise((resolve, reject) => {
// await 需要后面返回一个 promise 对象
this.http.post(ObjectsService.c_apiRoot_Multipart + `MultipartUpload/${instance.getBucketName()}${objectName}?uploadId=${uploadId}&partNumber=${i + 1}`, formData).subscribe((data: any) => {
let msg = { "partNumber": data.partNumber || null, "eTag": data.eTag || null }
resolve(msg) // 调用 promise 内置方法处理成功
})
});
PartNumberETag.push(result)
if (PartNumberETag.length === allSlice) { //分块上传完成
let data = PartNumberETag
let paramsData = { uploadId: uploadId };
let path = ObjectsService.c_apiRoot_Multipart + `CompleteMultipartUpload/${instance.getBucketName()}` + objectName;
this.http.post(path, data, { params: paramsData }).subscribe(data => {
let objData: any = new Object();
objData.fileName = file.name;
// objData.filePath = (ObjectsService.baseUrl + objectName).replace(file.name, "");//桶名要根据当前环境动态组装
objData.filePath = objectName;//此路径不全,前面缺少ObjectsService.baseUrl,这部分不可序列化,要在运行时拼接
resolve(objData)
})
}
}//for循环
//分块 处理
})
})
}
}

85
src/app/service/objectsSimple.service.ts

@ -0,0 +1,85 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ObjectsSimpleService {
static readonly c_apiRoot = "/api/";//普通上传的API根路径
static readonly c_apiRoot_Multipart = "/api/";//分块上传的API根路径
// static testPath = "f1/f2";//测试路径
constructor(private http: HttpClient) { }
//普通上传,单个文件上限5M
static baseUrl = ObjectsSimpleService.c_apiRoot + 'Objects/sinochemweb/';
postFile(extensionPath: string, file: File): Observable<Object> {
let formData = new FormData()
formData.append("file", file, file.name)
let data = { keepOriginalName: 'true' }
return this.http.post(ObjectsSimpleService.baseUrl + extensionPath, formData, { params: data });
}
//分块上传
static baseUrl_MultipartUpload = ObjectsSimpleService.c_apiRoot_Multipart + 'NewMultipartUpload/sinochemweb/';
// {
// "objectName": "string",
// "uploadId": "string"
// }
postFile_MultipartUpload(extensionPath: string, file: File): Promise<Object> {
// let formData = new FormData()
// formData.append("file", file, file.name)
// return this.http.post(ObjectsSimpleService.baseUrl + extensionPath, formData);
let data = { keepOriginalName: 'true', filename: file.name }
return new Promise((resolve, reject) => {
this.http.post(ObjectsSimpleService.baseUrl_MultipartUpload + extensionPath, {}, { params: data }).subscribe(async (data: any) => { //初始化分段上传
let objectName = data.objectName
let uploadId = data.uploadId
let PartNumberETag = []; //每次返回需要保存的信息
//分块 处理
let fileSize = file.size || null //上传文件的总大小
let shardSize = 5 * 1024 * 1024 //5MB一个分片
let allSlice = Math.ceil(fileSize / shardSize) //总文件/5MB===共分多少段
for (let i = 0; i < allSlice; i++) { //循环分段上传
let start = i * shardSize //切割文件开始位置
let end = Math.min(fileSize, start + shardSize); //切割文件结束位置
let formData = new FormData()
formData.append("file", file.slice(start, end))
//同步写法实现异步调用
let result = await new Promise((resolve, reject) => {
// await 需要后面返回一个 promise 对象
this.http.post(ObjectsSimpleService.c_apiRoot_Multipart + `MultipartUpload/sinochemweb/${objectName}?uploadId=${uploadId}&partNumber=${i + 1}`, formData).subscribe((data: any) => {
let msg = { "partNumber": data.partNumber || null, "eTag": data.eTag || null }
resolve(msg) // 调用 promise 内置方法处理成功
})
});
PartNumberETag.push(result)
if (PartNumberETag.length === allSlice) { //分块上传完成
let data = PartNumberETag
let paramsData = { uploadId: uploadId };
let path = ObjectsSimpleService.c_apiRoot_Multipart + 'CompleteMultipartUpload/sinochemweb/' + objectName;
this.http.post(path, data, { params: paramsData }).subscribe(data => {
let objData: any = new Object();
objData.fileName = file.name;
objData.filePath = (ObjectsSimpleService.baseUrl + objectName).replace(file.name, "");
resolve(objData)
})
}
}//for循环
//分块 处理
})
})
}
}

38
src/app/service/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;
}
}

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

@ -0,0 +1,23 @@
<div class="box">
<div class="boxleft">
<img style="width: 200px;" src="../../../assets/images/logo2.png" alt="">
</div>
<!-- 登录信息按钮 -->
<div class="boxright">
<span class="time">
{{time}}
</span>
<span style="margin: 0 18px;">|</span>
<span style="margin-right: 8px;"> {{surname}} </span>
<a nz-dropdown [nzDropdownMenu]="menu" [nzTrigger]="'click'" [nzBackdrop]='false'>
<img src="../../../assets/images/head.png" alt="">
</a>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu nzSelectable>
<li nz-menu-item (click)="signOut()">退出系统</li>
</ul>
</nz-dropdown-menu>
</div>
</div>

27
src/app/ui/tabbar/tabbar.component.scss

@ -0,0 +1,27 @@
.box {
width: 100%;
height: 56px;
background: linear-gradient(#01142f, #0d2b4f);
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
box-sizing: border-box;
padding: 0 20px;
color: #8aacce;
}
.boxright {
display: flex;
align-items: center;
span {
font-size: 16px;
color: #FFFFFF;
opacity: 0.6;
}
img {
width: 36px;
height: 36px;
}
}

86
src/app/ui/tabbar/tabbar.component.ts

@ -0,0 +1,86 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router, ActivatedRoute } from '@angular/router'
import { CacheTokenService } from '../../service/cache-token.service' //引入服务
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-tabbar',
templateUrl: './tabbar.component.html',
styleUrls: ['./tabbar.component.scss']
})
export class TabbarComponent implements OnInit {
constructor(private http: HttpClient, private router: Router, private route: ActivatedRoute, public token: CacheTokenService,
private message: NzMessageService) { }
surname: string
userName: string
isGasStation: string
ngOnInit() {
setInterval(() => {
this.getTime()
}, 1000);
this.isGasStation = JSON.parse(sessionStorage.getItem('isGasStation'))
if (this.isGasStation == 'true') {
this.surname = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).name
this.userName = JSON.parse(sessionStorage.getItem('userdataOfgasstation')).userName
} else {
this.surname = JSON.parse(sessionStorage.getItem('userdata')).name
this.userName = JSON.parse(sessionStorage.getItem('userdata')).userName
}
}
//获得时间
time: string
getTime() {
let myDate = new Date();
let y = myDate.getFullYear();
let M = myDate.getMonth() + 1; //获取当前月份(0-11,0代表1月)
let d = myDate.getDate(); //获取当前日(1-31)
let h = myDate.getHours(); //获取当前小时数(0-23)
let m = myDate.getMinutes(); //获取当前分钟数(0-59)
let s = myDate.getSeconds(); //获取当前秒数(0-59)
//检查是否小于10
M = check(M);
d = check(d);
h = check(h);
m = check(m);
s = check(s);
let timestr = y + "-" + M + "-" + d + " " + h + ":" + m + ":" + s;
this.time = timestr;
//时间数字小于10,则在之前加个“0”补位。
function check(i) {
let num = (i < 10) ? ("0" + i) : i;
return num;
}
}
//退出系统
signOut() {
this.message.create('success', `退出成功`);
this.token.delete()
sessionStorage.clear()
// window.localStorage.clear()
localStorage.removeItem("isautologin")
this.router.navigate(['/login'])
}
navChange(router) {
this.router.navigate([router])
}
//修改密码
changpsw() {
// let dialogRef = this.dialog.open(ChangepasswordComponent, { width: '348.000051px' });
// dialogRef.afterClosed().subscribe();
}
}

8
src/app/ui/title/title.component.html

@ -0,0 +1,8 @@
<div class="titlebox">
<img src="../../../assets/images/logosm.png" alt="">
<div class="content">
<div class="contentitem">
<span>{{name}}</span>
</div>
</div>
</div>

86
src/app/ui/title/title.component.scss

@ -0,0 +1,86 @@
.titlebox {
width: 100%;
height: 100%;
display: flex;
align-items: center;
img {
width: 65px;
height: 65px;
}
.content {
flex: 1;
height: 48px;
display: flex;
align-items: center;
// background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%);
.contentitem {
width: 100%;
height: 32px;
display: flex;
align-items: center;
// background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147);
background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%);
span {
margin-left: 10px;
color: #bce0ff;
font-size: 20px;
font-family: titlefont;
}
}
}
}
// 适配125%
@media screen and (max-height: 750px) {
.titlebox {
img {
width: 46px;
height: 46px;
}
.content {
height: 36px;
.contentitem {
height: 25px;
span {
margin-left: 6px;
font-size: 16px;
}
}
}
}
}
// 适配150%
@media screen and (max-height: 600px) {
.titlebox {
img {
width: 36px;
height: 36px;
}
.content {
height: 28px;
.contentitem {
height: 20px;
span {
margin-left: 6px;
font-size: 13px;
}
}
}
}
}

17
src/app/ui/title/title.component.ts

@ -0,0 +1,17 @@
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-title',
templateUrl: './title.component.html',
styleUrls: ['./title.component.scss']
})
export class TitleComponent implements OnInit {
@Input() name: string
constructor() { }
ngOnInit(): void {
}
}

13
src/app/ui/ui-routing.module.ts

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

41
src/app/ui/ui.module.ts

@ -0,0 +1,41 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UiRoutingModule } from './ui-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 { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { IsnoPipe } from '../pipes/boolean.pipe';
import { TimePipe } from '../pipes/time.pipe';
import { TabbarComponent } from './tabbar/tabbar.component';
import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
import { TitleComponent } from './title/title.component';
import { NzMessageModule } from 'ng-zorro-antd/message';
@NgModule({
declarations: [TabbarComponent, IsnoPipe, TimePipe, TitleComponent],
imports: [
CommonModule,
UiRoutingModule,
A11yModule,
CdkStepperModule,
CdkTableModule,
CdkTreeModule,
DragDropModule,
PortalModule,
ScrollingModule,
ReactiveFormsModule,
FormsModule,
NzDropDownModule,
NzMessageModule
],
exports: [TabbarComponent, TitleComponent]
})
export class UiModule { }

BIN
src/assets/font-family/sybold.OTF

Binary file not shown.

BIN
src/assets/font-family/synormal.OTF

Binary file not shown.

BIN
src/assets/font-family/titlefont.TTF

Binary file not shown.

BIN
src/assets/images/3d.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

BIN
src/assets/images/adsorb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/images/awningHide.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/assets/images/awningShow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/assets/images/baseInfo/building.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
src/assets/images/baseInfo/date.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

BIN
src/assets/images/baseInfo/hospital.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

BIN
src/assets/images/baseInfo/phone.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

BIN
src/assets/images/baseInfo/police.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

BIN
src/assets/images/baseInfo/position.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

BIN
src/assets/images/baseInfo/road.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

BIN
src/assets/images/bgImg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 KiB

BIN
src/assets/images/bottomArrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/assets/images/bottomArrow2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/images/bucket.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
src/assets/images/cameraNum.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/images/circle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
src/assets/images/err.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

BIN
src/assets/images/excel.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

BIN
src/assets/images/expand.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 B

BIN
src/assets/images/fireNum.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/images/flow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

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

Loading…
Cancel
Save