12 changed files with 660 additions and 35 deletions
@ -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<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' + |
||||||
|
ObjectsSimpleService.getBucketName(); |
||||||
|
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===共分多少段
|
||||||
|
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循环
|
||||||
|
|
||||||
|
//分块 处理
|
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,82 @@ |
|||||||
|
<div class="box"> |
||||||
|
<form nz-form [formGroup]="validateForm" [nzLayout]="'inline'"> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="HostIPAddress">主机地址</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-input-group> |
||||||
|
<input nz-input type="text" formControlName="HostIPAddress" placeholder="请输入主机地址" /> |
||||||
|
</nz-input-group> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="EventSystemName">预警事件</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-select formControlName="EventSystemName" nzPlaceHolder="请选择预警事件"> |
||||||
|
<nz-option *ngFor="let item of eventList" [nzValue]="item" [nzLabel]="item"></nz-option> |
||||||
|
</nz-select> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="ViolateArea">预警区域</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-select formControlName="ViolateArea" nzPlaceHolder="请选择预警区域"> |
||||||
|
<nz-option *ngFor="let item of areaList" [nzValue]="item" [nzLabel]="item"></nz-option> |
||||||
|
</nz-select> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="CameraNo">摄像头编号</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-input-group> |
||||||
|
<input nz-input type="text" formControlName="CameraNo" placeholder="请输入摄像头编号" /> |
||||||
|
</nz-input-group> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="ViolateTime">选择日期</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-date-picker nzShowTime formControlName="ViolateTime"></nz-date-picker> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="ViolateImage">图片地址</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-input-group> |
||||||
|
<input nz-input type="text" formControlName="ViolateImage" placeholder="请输入图片地址" /> |
||||||
|
</nz-input-group> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label nzRequired nzFor="violateVideo">视频地址</nz-form-label> |
||||||
|
<nz-form-control> |
||||||
|
<nz-input-group> |
||||||
|
<input nz-input type="text" formControlName="violateVideo" placeholder="请输入图片地址" /> |
||||||
|
</nz-input-group> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label>第一步</nz-form-label> |
||||||
|
<button nz-button (click)="getImg()">捕获图片</button> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<button nz-button (click)="getVideo()">捕获视频</button> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-label>第二步</nz-form-label> |
||||||
|
<button nz-button (click)="updateImg()">更新底图</button> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<button nz-button (click)="updateVideo()">更新视频</button> |
||||||
|
</nz-form-item> |
||||||
|
</form> |
||||||
|
<div class="img_box"> |
||||||
|
<canvas #canvas (mousedown)="onMouseDown($event)" (mousemove)="onMouseMove($event)" (mouseup)="onMouseUp()" |
||||||
|
style="border: 1px solid #ccc;"></canvas> |
||||||
|
<video style="width: 500px;height: auto;" [src]="videoUrl" controls></video> |
||||||
|
<div> |
||||||
|
<button style="margin-bottom: 10px;" nz-button nzType="primary" (click)="uploadImg()">上传预警图片</button> |
||||||
|
<button nz-button nzType="primary" (click)="uploadVideo()">上传预警视频</button> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</div> |
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -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<SimulateDataComponent>; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
await TestBed.configureTestingModule({ |
||||||
|
declarations: [ SimulateDataComponent ] |
||||||
|
}) |
||||||
|
.compileComponents(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
fixture = TestBed.createComponent(SimulateDataComponent); |
||||||
|
component = fixture.componentInstance; |
||||||
|
fixture.detectChanges(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should create', () => { |
||||||
|
expect(component).toBeTruthy(); |
||||||
|
}); |
||||||
|
}); |
@ -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<HTMLCanvasElement>; |
||||||
|
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 = [ |
||||||
|
'进出口', |
||||||
|
'卸油区', |
||||||
|
'加油区', |
||||||
|
'收银区', |
||||||
|
'发油区', |
||||||
|
'油库区', |
||||||
|
'监控区', |
||||||
|
'消防通道', |
||||||
|
'泵房区', |
||||||
|
'油罐区', |
||||||
|
'停车区', |
||||||
|
]; |
||||||
|
} |
Loading…
Reference in new issue