From 77966a152aa2b3211f4892ec777f4378b982dcfc Mon Sep 17 00:00:00 2001 From: Sjh <55341701@qq.com> Date: Sun, 26 Jan 2025 17:25:14 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=E6=A8=A1=E6=8B=9F=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.component.ts | 2 +- src/app/app.module.ts | 3 + src/app/http-interceptors/base-interceptor.ts | 71 ++-- src/app/service/objectsSimple.service.ts | 114 ++++++ .../analysis-of-the-host.component.ts | 1 + .../host-config/host-config.component.html | 1 + .../host-config/host-config.component.ts | 49 ++- .../simulate-data.component.html | 82 +++++ .../simulate-data.component.scss | 16 + .../simulate-data.component.spec.ts | 25 ++ .../simulate-data/simulate-data.component.ts | 327 ++++++++++++++++++ .../system-management.module.ts | 4 + 12 files changed, 660 insertions(+), 35 deletions(-) create mode 100644 src/app/service/objectsSimple.service.ts create mode 100644 src/app/system-management/host-config/simulate-data/simulate-data.component.html create mode 100644 src/app/system-management/host-config/simulate-data/simulate-data.component.scss create mode 100644 src/app/system-management/host-config/simulate-data/simulate-data.component.spec.ts create mode 100644 src/app/system-management/host-config/simulate-data/simulate-data.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 4d5661c..8fac6c1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -13,6 +13,6 @@ export class AppComponent { //调用服务中的function刷新token this.token.startUp() } - console.log('更新日期:20241202') + console.log('更新日期:20241213') } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 459b0be..65f96d9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,6 +14,9 @@ import { TreeService } from './service/tree.service'; import { RouteReuseStrategy } from '@angular/router'; import { CustomReuseStrategy } from './CustomReuseStrategy'; import { ConfigFormDataService } from './service/configFormData.service'; +import { registerLocaleData } from '@angular/common'; +import zh from '@angular/common/locales/zh'; +registerLocaleData(zh); @NgModule({ declarations: [AppComponent], imports: [ diff --git a/src/app/http-interceptors/base-interceptor.ts b/src/app/http-interceptors/base-interceptor.ts index b41f38d..3e67cc5 100644 --- a/src/app/http-interceptors/base-interceptor.ts +++ b/src/app/http-interceptors/base-interceptor.ts @@ -1,23 +1,28 @@ import { Injectable } from '@angular/core'; import { - HttpClient, HttpInterceptor, HttpHandler, HttpRequest, - HttpErrorResponse + HttpClient, + HttpInterceptor, + HttpHandler, + HttpRequest, + HttpErrorResponse, } from '@angular/common/http'; -import { throwError } from 'rxjs' +import { throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; -import { Router } from '@angular/router' -import { CacheTokenService } from '../service/cache-token.service' +import { Router } from '@angular/router'; +import { CacheTokenService } from '../service/cache-token.service'; 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, public token: CacheTokenService, private message: NzMessageService) { } + constructor( + private router: Router, + public token: CacheTokenService, + private message: NzMessageService + ) {} intercept(req: any, next: HttpHandler) { - let params = req.params; for (const key of req.params.keys()) { if (params.get(key) === undefined || params.get(key) === null) { @@ -32,45 +37,47 @@ export class BaseInterceptor implements HttpInterceptor { }); if (!req.cancelToken) { /*获取token*/ - let token = sessionStorage.getItem('token') + let token = sessionStorage.getItem('token'); + if (req.url == '/api/Data/ViolationRecordPush') { + token = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbnhpbiIsIm5hbWUiOiLlronkv6EiLCJyb2xlIjoiUHJvZmlsZSIsIm5iZiI6MTY4NTQzNjIzNCwiZXhwIjoyMDAwNzk2MjM0LCJpc3MiOiJhbnhpbjk5LmNvbSIsImF1ZCI6IkVDTElFTlQifQ.obkc9epvwk2Xain4hqL9OrsRtBrAJ2C690CA1OJIqAo'; + } /*此处设置额外请求头,token令牌*/ - newReq.headers = - newReq.headers.set('Authorization', `Bearer ${token}`) + newReq.headers = newReq.headers.set('Authorization', `Bearer ${token}`); } // 携带请求头发送下一次请求 - return next.handle(newReq) - .pipe( - //箭头函数,注意this指向 - catchError((err) => this.handleError(err)) - ) + return next.handle(newReq).pipe( + //箭头函数,注意this指向 + catchError((err) => this.handleError(err)) + ); } - // 捕获错误 + // 捕获错误 //401 token过期 403没权限!!! 400参数错误 404未找到 614刷新令牌过期!!! private handleError(error: HttpErrorResponse) { - console.log('http错误', error) + console.log('http错误', error); // 用户认证失败返回登录页 if (error.status === 401) { - this.token.delete() - sessionStorage.clear() - localStorage.removeItem("isautologin") + this.token.delete(); + sessionStorage.clear(); + localStorage.removeItem('isautologin'); this.message.create('error', `用户认证信息过期,请重新登录!`); - this.router.navigate(['/login']) - return + this.router.navigate(['/login']); + return; } if (error.status === 403) { this.message.create('error', `对不起,您无此权限!`); - return + return; } if (error.status === 400) { this.message.create('error', error.error); - return + return; } if (error.status === 503) { - this.message.create('error', error.error.detail); - return + this.message.create('error', error.error.detail); + return; } if (error.error instanceof ErrorEvent) { // 发生客户端或网络错误。相应处理。 @@ -78,14 +85,12 @@ export class BaseInterceptor implements HttpInterceptor { } else { // 服务端返回http状态码 // 服务端返回错误信息 - console.error( - `状态码${error.status}, ` + - `错误内容:${error.error}`); - this.message.create('error', error.error); + console.error(`状态码${error.status}, ` + `错误内容:${error.error}`); + this.message.create('error', error.error); } // 返回带有面向用户的错误信息 return throwError(() => { - new Error('error') + new Error('error'); }); - }; + } } diff --git a/src/app/service/objectsSimple.service.ts b/src/app/service/objectsSimple.service.ts new file mode 100644 index 0000000..716a70d --- /dev/null +++ b/src/app/service/objectsSimple.service.ts @@ -0,0 +1,114 @@ +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根路径 + constructor(private http: HttpClient) {} + + static getBucketName() { + let bucket = '/test/'; + return bucket; + } + + //普通上传,单个文件上限5M + static baseUrl = + ObjectsSimpleService.c_apiRoot + + 'Objects' + + ObjectsSimpleService.getBucketName(); + postFile(extensionPath: string, file: File): Observable { + 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' + + ObjectsSimpleService.getBucketName(); + postFile_MultipartUpload(extensionPath: string, file: File): Promise { + // 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===共分多少段 + console.log('共分多少段' + allSlice); + 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` + + +ObjectsSimpleService.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 = + ObjectsSimpleService.c_apiRoot_Multipart + + 'CompleteMultipartUpload' + + ObjectsSimpleService.getBucketName() + + objectName; + this.http + .post(path, data, { params: paramsData }) + .subscribe((data) => { + let objData: any = new Object(); + objData.fileName = file.name; + objData.filePath = ObjectsSimpleService.baseUrl + objectName; + resolve(objData); + }); + } + } //for循环 + + //分块 处理 + }); + }); + } +} diff --git a/src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts b/src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts index ddc8e14..6531dcb 100644 --- a/src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts +++ b/src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts @@ -232,6 +232,7 @@ export class AnalysisOfTheHostComponent implements OnInit { 4: '警旗3', }; config(data: any) { + sessionStorage.setItem('hostIPAddress', data.hostIPAddress); // this.isVisible = true; this.configdata = data; console.log(this.configdata); diff --git a/src/app/system-management/host-config/host-config.component.html b/src/app/system-management/host-config/host-config.component.html index 09ac7b8..0f0e894 100644 --- a/src/app/system-management/host-config/host-config.component.html +++ b/src/app/system-management/host-config/host-config.component.html @@ -43,6 +43,7 @@ 编辑 标注 + 模拟数据 禁用 diff --git a/src/app/system-management/host-config/host-config.component.ts b/src/app/system-management/host-config/host-config.component.ts index 958bf69..667872d 100644 --- a/src/app/system-management/host-config/host-config.component.ts +++ b/src/app/system-management/host-config/host-config.component.ts @@ -40,6 +40,7 @@ interface Camera { import yaml from 'js-yaml'; import { ImageLabelAnxinComponent } from '../image-label-anxin/image-label-anxin.component'; import { AnxinConfigComponent } from './anxin-config/anxin-config.component'; +import { SimulateDataComponent } from './simulate-data/simulate-data.component'; @Component({ selector: 'app-host-config', @@ -61,13 +62,14 @@ export class HostConfigComponent implements OnInit { hostId; //主机id orId; //加油站id hostType; //黄海还是交大的盒子 - + my = false; hostData; ngOnInit(): void { this.hostId = this.route.snapshot.queryParams.hostId; this.orId = this.route.snapshot.queryParams.orId; this.hostType = this.route.snapshot.queryParams.type; + this.my = this.route.snapshot.queryParams.my; this.getCamera(); this.getHostData(); } @@ -341,6 +343,51 @@ export class HostConfigComponent implements OnInit { }); } + simulate(item) { + console.log('模拟数据', item); + const modal = this.modal.create({ + nzTitle: '模拟数据', + nzContent: SimulateDataComponent, + nzViewContainerRef: this.viewContainerRef, + nzWidth: 1800, + nzComponentParams: { + data: item, + }, + nzOnOk: async () => { + if (instance.validateForm.valid) { + await new Promise((resolve) => { + function generateRandomString(length) { + const chars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // 字符集合 + let result = ''; + for (let i = 0; i < length; i++) { + result += chars.charAt( + Math.floor(Math.random() * chars.length) + ); + } + return result; + } + const randomString = generateRandomString(16); + let body = JSON.parse(JSON.stringify(instance.validateForm.value)); + body.ExternalId = randomString; + const date = new Date(body.ViolateTime); + date.setHours(date.getHours() + 8); + body.ViolateTime = date.toISOString(); + this.http + .post(`/api/Data/ViolationRecordPush`, body) + .subscribe((data) => { + this.message.create('success', '上报成功!'); + // resolve(data); + }); + }); + } else { + this.message.create('warning', '请填写完整!'); + return false; + } + }, + }); + const instance = modal.getContentComponent(); + } connect() { // let isAllLabel = this.listOfData.find((item: any) => { // if (item.type != 1 && !item.dimensionedPoints) { diff --git a/src/app/system-management/host-config/simulate-data/simulate-data.component.html b/src/app/system-management/host-config/simulate-data/simulate-data.component.html new file mode 100644 index 0000000..9798d83 --- /dev/null +++ b/src/app/system-management/host-config/simulate-data/simulate-data.component.html @@ -0,0 +1,82 @@ +
+
+ + 主机地址 + + + + + + + + 预警事件 + + + + + + + + 预警区域 + + + + + + + + 摄像头编号 + + + + + + + + 选择日期 + + + + + + 图片地址 + + + + + + + + 视频地址 + + + + + + + + 第一步 + + + + + + + 第二步 + + + + + +
+
+ + +
+ + +
+ +
+
\ No newline at end of file diff --git a/src/app/system-management/host-config/simulate-data/simulate-data.component.scss b/src/app/system-management/host-config/simulate-data/simulate-data.component.scss new file mode 100644 index 0000000..a2ce51d --- /dev/null +++ b/src/app/system-management/host-config/simulate-data/simulate-data.component.scss @@ -0,0 +1,16 @@ +.ant-form-item { + margin-bottom: 10px; + } + .img_box { + height: auto; + display: flex; + canvas { + max-width: 1000px; + height: auto; + } + button { + margin: 0; + margin-left: 10px; + } + } + \ No newline at end of file diff --git a/src/app/system-management/host-config/simulate-data/simulate-data.component.spec.ts b/src/app/system-management/host-config/simulate-data/simulate-data.component.spec.ts new file mode 100644 index 0000000..57511bd --- /dev/null +++ b/src/app/system-management/host-config/simulate-data/simulate-data.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SimulateDataComponent } from './simulate-data.component'; + +describe('SimulateDataComponent', () => { + let component: SimulateDataComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SimulateDataComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SimulateDataComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system-management/host-config/simulate-data/simulate-data.component.ts b/src/app/system-management/host-config/simulate-data/simulate-data.component.ts new file mode 100644 index 0000000..063c491 --- /dev/null +++ b/src/app/system-management/host-config/simulate-data/simulate-data.component.ts @@ -0,0 +1,327 @@ +import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core'; +import { NzModalRef } from 'ng-zorro-antd/modal'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { HttpClient } from '@angular/common/http'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ObjectsSimpleService } from 'src/app/service/objectsSimple.service'; +import { NzMessageService } from 'ng-zorro-antd/message'; +@Component({ + selector: 'app-simulate-data', + templateUrl: './simulate-data.component.html', + styleUrls: ['./simulate-data.component.scss'], +}) +export class SimulateDataComponent implements OnInit { + @Input() data: any; + validateForm!: FormGroup; + constructor( + private fb: FormBuilder, + private http: HttpClient, + private objectsSrv: ObjectsSimpleService, + private message: NzMessageService, + private sanitizer: DomSanitizer + ) {} + + currentTime = null; + arr = ['进出口', '加油区', '卸油区', '便利店']; + ngOnInit(): void { + this.currentTime = new Date().getTime(); + + let datacopy = JSON.parse(JSON.stringify(this.data)); + let HostIPAddress = sessionStorage.getItem('hostIPAddress'); + this.validateForm = this.fb.group({ + HostIPAddress: [HostIPAddress, [Validators.required]], + EventSystemName: [null, [Validators.required]], + ViolateArea: [this.arr[datacopy.type], [Validators.required]], + CameraNo: [datacopy.name, [Validators.required]], + ViolateTime: [null, [Validators.required]], + ViolateImage: [ + `/api/Objects/test/${this.currentTime}/image.png`, + [Validators.required], + ], + violateVideo: [ + `/api/Objects/test/${this.currentTime}/video.mp4`, + [Validators.required], + ], + }); + this.getImgMarkData(); + this.updateVideo(); + } + + @ViewChild('canvas') canvasRef: ElementRef; + private ctx: CanvasRenderingContext2D; + imgUrl: string; + isDrawing = false; + startX: number; + startY: number; + endX: number; + endY: number; + img: HTMLImageElement; + + //获取 摄像头图片/标注点位 + getImgMarkData() { + const httpOptions = { + responseType: 'blob' as 'json', + params: { cameraId: this.data.id }, + }; + let date = new Date().getTime(); + this.http.get(`/api/Cameras/Images?v=${date}`, httpOptions).subscribe({ + next: (data: any) => { + setTimeout(() => { + this.initCanvas(data); + }, 0); + }, + error: (error) => { + console.error('获取图片数据失败', error); + setTimeout(() => { + this.initCanvas(null); + }, 0); + }, + }); + } + + canvasObj = null; + initCanvas(data) { + if (!data) { + // 如果没有获取到图片数据,使用本地默认图片 + this.message.warning('未获取到照片数据,使用默认图片'); + this.imgUrl = '../../../../assets/images/bgImg.png'; // 请确保这个路径下有默认图片 + } else { + this.imgUrl = window.URL.createObjectURL(data); + } + + this.img = new Image(); + this.img.src = this.imgUrl; + this.img.onerror = () => { + // 如果图片加载失败,也使用默认图片 + this.message.warning('图片加载失败,使用默认图片'); + this.img.src = '../../../../assets/images/bgImg.png'; + }; + + this.img.onload = () => { + this.canvasObj = this.canvasRef.nativeElement; + this.ctx = this.canvasObj.getContext('2d'); + + // 设置 canvas 宽度为 1000px,保持图片的宽高比 + const targetWidth = 1000; + this.canvasObj.width = targetWidth; + this.canvasObj.height = (this.img.height / this.img.width) * targetWidth; + + // 在 canvas 上绘制图片 + this.ctx.drawImage( + this.img, + 0, + 0, + this.canvasObj.width, + this.canvasObj.height + ); + }; + } + + // 开始绘制红框 + onMouseDown(event: MouseEvent): void { + this.isDrawing = true; + this.startX = event.offsetX; + this.startY = event.offsetY; + } + + // 实时绘制红框 + onMouseMove(event: MouseEvent): void { + if (!this.isDrawing) return; + + this.endX = event.offsetX; + this.endY = event.offsetY; + + const canvas = this.canvasRef.nativeElement; + this.ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除 canvas + this.ctx.drawImage(this.img, 0, 0, canvas.width, canvas.height); // 重新绘制图片 + this.ctx.strokeStyle = 'red'; + this.ctx.lineWidth = 2; + this.ctx.strokeRect( + this.startX, + this.startY, + this.endX - this.startX, + this.endY - this.startY + ); + } + + // 停止绘制红框 + onMouseUp(): void { + this.isDrawing = false; + } + + async uploadImg() { + const canvas = this.canvasRef.nativeElement; + canvas.toBlob(async (blob: Blob) => { + // 创建 File 对象,'image.png' 为文件名,'image/png' 为文件类型 + const file = new File([blob], 'image.png', { type: 'image/png' }); + console.log(file); + let url = await this.postFile(file); + console.log(url); + this.validateForm.patchValue({ + ViolateImage: url, // 替换为你想要的 ViolateImage 值 + }); + }, 'image/png'); + } + + async uploadVideo() { + // 创建 File 对象,'image.png' 为文件名,'image/png' 为文件类型 + const file = new File([this.videoBlob], 'video.mp4', { type: 'video/mp4' }); + console.log(file); + let url = await this.postFile(file); + console.log(url); + this.validateForm.patchValue({ + ViolateImage: url, // 替换为你想要的 ViolateImage 值 + }); + } + + //上传文件 + async postFile(file: File) { + return new Promise((resolve, reject) => { + this.objectsSrv + .postFile(`${this.currentTime}/`, file) + .subscribe((data) => { + let dataObj = data as any; + let filePath: string = + ObjectsSimpleService.baseUrl + dataObj.objectName; + this.message.create('success', '上传成功'); + resolve(filePath); + }); + }); + } + + getImg() { + let params = { + cameraId: this.data.id, + provider: 1, + }; + this.http + .put('/api/Cameras/Commands/CaptureImages', '', { params: params }) + .subscribe({ + next: (value: Object) => { + this.message.create( + 'success', + '发送指令: 捕获图片成功,请过一段时间手动更新底图!' + ); + }, + }); + } + + getVideo() { + let params = { + cameraId: this.data.id, + provider: 1, + }; + this.http + .put('/api/Cameras/Commands/CaptureVideos', '', { params: params }) + .subscribe({ + next: (value: Object) => { + this.message.create( + 'success', + '发送指令: 捕获视频成功,请过一段时间手动更新视频!' + ); + }, + }); + } + updateImg() { + const httpOptions = { + responseType: 'blob' as 'json', + params: { cameraId: this.data.id }, + }; + let date = new Date().getTime(); + this.http.get(`/api/Cameras/Images?v=${date}`, httpOptions).subscribe({ + next: (data: any) => { + this.replaceBackground(data); + }, + }); + } + + replaceBackground(newData: Blob) { + console.log('newData', newData); + const newImgUrl = window.URL.createObjectURL(newData); + + this.img = new Image(); + this.img.src = newImgUrl; + + this.img.onload = () => { + // 清空 canvas 内容 + this.ctx.clearRect(0, 0, this.canvasObj.width, this.canvasObj.height); + + // 更新 canvas 大小和图片宽高比 + const targetWidth = 1000; + this.canvasObj.width = targetWidth; + this.canvasObj.height = (this.img.height / this.img.width) * targetWidth; + + // 绘制新的图片 + this.ctx.drawImage( + this.img, + 0, + 0, + this.canvasObj.width, + this.canvasObj.height + ); + }; + } + + videoBlob = null; + videoUrl = null; + updateVideo() { + const httpOptions = { + responseType: 'blob' as 'json', + params: { cameraId: this.data.id }, + }; + let date = new Date().getTime(); + this.http.get(`/api/Cameras/Videos?v=${date}`, httpOptions).subscribe({ + next: (data: any) => { + console.log('视频数据', data); + this.videoBlob = data; + // 获取图片数据 (data 是 Blob 类型) + const unsafeUrl = window.URL.createObjectURL(data); + + // 使用 DomSanitizer 处理 URL + this.videoUrl = this.sanitizer.bypassSecurityTrustUrl(unsafeUrl); + }, + }); + } + eventList = [ + '油罐区入侵', + '进出口停车', + '站内吸烟', + '前庭接打电话', + '设置卸油隔离区', + '拆除卸油管', + '卸油连接静电接地', + '卸油设置消防器材', + '卸油现场清理', + '油罐车无人卸油', + '连接卸油管', + '卸油中无人监卸', + '证照年检逾期报警', + '证照年检临期提醒', + '证照年检办理提醒', + '普通证照有效期逾期报警', + '证照有效期办理提醒', + '烟雾预警', + '火灾报警', + '设备报废逾期报警', + '设备报废临期提醒', + '收银员着装', + '关键证照有效期逾期报警', + '证照有效期临期提醒', + '设备维保临期提醒', + '设备维保逾期报警', + ]; + + areaList = [ + '进出口', + '卸油区', + '加油区', + '收银区', + '发油区', + '油库区', + '监控区', + '消防通道', + '泵房区', + '油罐区', + '停车区', + ]; +} diff --git a/src/app/system-management/system-management.module.ts b/src/app/system-management/system-management.module.ts index aa890d8..b831ba0 100644 --- a/src/app/system-management/system-management.module.ts +++ b/src/app/system-management/system-management.module.ts @@ -53,6 +53,8 @@ import { DragDropModule } from '@angular/cdk/drag-drop'; import { IframeComponent } from './iframe/iframe.component'; import { WorkerTagComponent } from './analysis-of-the-host/worker-tag/worker-tag.component'; import { ChangeOrComponent } from './organization/change-or/change-or.component'; +import { SimulateDataComponent } from './host-config/simulate-data/simulate-data.component'; +import { NzDatePickerModule } from 'ng-zorro-antd/date-picker'; @NgModule({ declarations: [ OrganizationComponent, @@ -86,6 +88,7 @@ import { ChangeOrComponent } from './organization/change-or/change-or.component' IframeComponent, WorkerTagComponent, ChangeOrComponent, + SimulateDataComponent, ], imports: [ CommonModule, @@ -112,6 +115,7 @@ import { ChangeOrComponent } from './organization/change-or/change-or.component' NzPopconfirmModule, NzRadioModule, DragDropModule, + NzDatePickerModule, ], entryComponents: [ AddorComponent,