Browse Source

[新增]模拟数据

master
邵佳豪 4 weeks ago
parent
commit
77966a152a
  1. 2
      src/app/app.component.ts
  2. 3
      src/app/app.module.ts
  3. 69
      src/app/http-interceptors/base-interceptor.ts
  4. 114
      src/app/service/objectsSimple.service.ts
  5. 1
      src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts
  6. 1
      src/app/system-management/host-config/host-config.component.html
  7. 49
      src/app/system-management/host-config/host-config.component.ts
  8. 82
      src/app/system-management/host-config/simulate-data/simulate-data.component.html
  9. 16
      src/app/system-management/host-config/simulate-data/simulate-data.component.scss
  10. 25
      src/app/system-management/host-config/simulate-data/simulate-data.component.spec.ts
  11. 327
      src/app/system-management/host-config/simulate-data/simulate-data.component.ts
  12. 4
      src/app/system-management/system-management.module.ts

2
src/app/app.component.ts

@ -13,6 +13,6 @@ export class AppComponent {
//调用服务中的function刷新token //调用服务中的function刷新token
this.token.startUp() this.token.startUp()
} }
console.log('更新日期:20241202') console.log('更新日期:20241213')
} }
} }

3
src/app/app.module.ts

@ -14,6 +14,9 @@ import { TreeService } from './service/tree.service';
import { RouteReuseStrategy } from '@angular/router'; import { RouteReuseStrategy } from '@angular/router';
import { CustomReuseStrategy } from './CustomReuseStrategy'; import { CustomReuseStrategy } from './CustomReuseStrategy';
import { ConfigFormDataService } from './service/configFormData.service'; import { ConfigFormDataService } from './service/configFormData.service';
import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';
registerLocaleData(zh);
@NgModule({ @NgModule({
declarations: [AppComponent], declarations: [AppComponent],
imports: [ imports: [

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

@ -1,23 +1,28 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
HttpClient, HttpInterceptor, HttpHandler, HttpRequest, HttpClient,
HttpErrorResponse HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
} from '@angular/common/http'; } from '@angular/common/http';
import { throwError } from 'rxjs' import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router' import { Router } from '@angular/router';
import { CacheTokenService } from '../service/cache-token.service' import { CacheTokenService } from '../service/cache-token.service';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
//baseurl //baseurl
// const baseurl = 'http://39.106.78.171:8008'; // const baseurl = 'http://39.106.78.171:8008';
@Injectable() @Injectable()
export class BaseInterceptor implements HttpInterceptor { export class BaseInterceptor implements HttpInterceptor {
constructor(
constructor(private router: Router, public token: CacheTokenService, private message: NzMessageService) { } private router: Router,
public token: CacheTokenService,
private message: NzMessageService
) {}
intercept(req: any, next: HttpHandler) { intercept(req: any, next: HttpHandler) {
let params = req.params; let params = req.params;
for (const key of req.params.keys()) { for (const key of req.params.keys()) {
if (params.get(key) === undefined || params.get(key) === null) { if (params.get(key) === undefined || params.get(key) === null) {
@ -32,45 +37,47 @@ export class BaseInterceptor implements HttpInterceptor {
}); });
if (!req.cancelToken) { if (!req.cancelToken) {
/*获取token*/ /*获取token*/
let token = sessionStorage.getItem('token') let token = sessionStorage.getItem('token');
if (req.url == '/api/Data/ViolationRecordPush') {
token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbnhpbiIsIm5hbWUiOiLlronkv6EiLCJyb2xlIjoiUHJvZmlsZSIsIm5iZiI6MTY4NTQzNjIzNCwiZXhwIjoyMDAwNzk2MjM0LCJpc3MiOiJhbnhpbjk5LmNvbSIsImF1ZCI6IkVDTElFTlQifQ.obkc9epvwk2Xain4hqL9OrsRtBrAJ2C690CA1OJIqAo';
}
/*此处设置额外请求头,token令牌*/ /*此处设置额外请求头,token令牌*/
newReq.headers = newReq.headers = newReq.headers.set('Authorization', `Bearer ${token}`);
newReq.headers.set('Authorization', `Bearer ${token}`)
} }
// 携带请求头发送下一次请求 // 携带请求头发送下一次请求
return next.handle(newReq) return next.handle(newReq).pipe(
.pipe( //箭头函数,注意this指向
//箭头函数,注意this指向 catchError((err) => this.handleError(err))
catchError((err) => this.handleError(err)) );
)
} }
// 捕获错误 // 捕获错误
//401 token过期 403没权限!!! 400参数错误 404未找到 614刷新令牌过期!!! //401 token过期 403没权限!!! 400参数错误 404未找到 614刷新令牌过期!!!
private handleError(error: HttpErrorResponse) { private handleError(error: HttpErrorResponse) {
console.log('http错误', error) console.log('http错误', error);
// 用户认证失败返回登录页 // 用户认证失败返回登录页
if (error.status === 401) { if (error.status === 401) {
this.token.delete() this.token.delete();
sessionStorage.clear() sessionStorage.clear();
localStorage.removeItem("isautologin") localStorage.removeItem('isautologin');
this.message.create('error', `用户认证信息过期,请重新登录!`); this.message.create('error', `用户认证信息过期,请重新登录!`);
this.router.navigate(['/login']) this.router.navigate(['/login']);
return return;
} }
if (error.status === 403) { if (error.status === 403) {
this.message.create('error', `对不起,您无此权限!`); this.message.create('error', `对不起,您无此权限!`);
return return;
} }
if (error.status === 400) { if (error.status === 400) {
this.message.create('error', error.error); this.message.create('error', error.error);
return return;
} }
if (error.status === 503) { if (error.status === 503) {
this.message.create('error', error.error.detail); this.message.create('error', error.error.detail);
return return;
} }
if (error.error instanceof ErrorEvent) { if (error.error instanceof ErrorEvent) {
// 发生客户端或网络错误。相应处理。 // 发生客户端或网络错误。相应处理。
@ -78,14 +85,12 @@ export class BaseInterceptor implements HttpInterceptor {
} else { } else {
// 服务端返回http状态码 // 服务端返回http状态码
// 服务端返回错误信息 // 服务端返回错误信息
console.error( console.error(`状态码${error.status}, ` + `错误内容:${error.error}`);
`状态码${error.status}, ` + this.message.create('error', error.error);
`错误内容:${error.error}`);
this.message.create('error', error.error);
} }
// 返回带有面向用户的错误信息 // 返回带有面向用户的错误信息
return throwError(() => { return throwError(() => {
new Error('error') new Error('error');
}); });
}; }
} }

114
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<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循环
//分块 处理
});
});
}
}

1
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', 4: '警旗3',
}; };
config(data: any) { config(data: any) {
sessionStorage.setItem('hostIPAddress', data.hostIPAddress);
// this.isVisible = true; // this.isVisible = true;
this.configdata = data; this.configdata = data;
console.log(this.configdata); console.log(this.configdata);

1
src/app/system-management/host-config/host-config.component.html

@ -43,6 +43,7 @@
<td> <td>
<span class="blue" style="margin-right: 12px;" (click)="editCamera(item)">编辑</span> <span class="blue" style="margin-right: 12px;" (click)="editCamera(item)">编辑</span>
<span class="blue" style="margin-right: 12px;" (click)="label(item)">标注</span> <span class="blue" style="margin-right: 12px;" (click)="label(item)">标注</span>
<span class="blue" *ngIf="my" style="margin-right: 12px;" (click)="simulate(item)">模拟数据</span>
<ng-container *ngIf="item.isEnabled; else elseTemplate2"> <ng-container *ngIf="item.isEnabled; else elseTemplate2">
<span class="red" style="margin-right: 12px;" (click)="forbidden(item)">禁用</span> <span class="red" style="margin-right: 12px;" (click)="forbidden(item)">禁用</span>
</ng-container> </ng-container>

49
src/app/system-management/host-config/host-config.component.ts

@ -40,6 +40,7 @@ interface Camera {
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import { ImageLabelAnxinComponent } from '../image-label-anxin/image-label-anxin.component'; import { ImageLabelAnxinComponent } from '../image-label-anxin/image-label-anxin.component';
import { AnxinConfigComponent } from './anxin-config/anxin-config.component'; import { AnxinConfigComponent } from './anxin-config/anxin-config.component';
import { SimulateDataComponent } from './simulate-data/simulate-data.component';
@Component({ @Component({
selector: 'app-host-config', selector: 'app-host-config',
@ -61,13 +62,14 @@ export class HostConfigComponent implements OnInit {
hostId; //主机id hostId; //主机id
orId; //加油站id orId; //加油站id
hostType; //黄海还是交大的盒子 hostType; //黄海还是交大的盒子
my = false;
hostData; hostData;
ngOnInit(): void { ngOnInit(): void {
this.hostId = this.route.snapshot.queryParams.hostId; this.hostId = this.route.snapshot.queryParams.hostId;
this.orId = this.route.snapshot.queryParams.orId; this.orId = this.route.snapshot.queryParams.orId;
this.hostType = this.route.snapshot.queryParams.type; this.hostType = this.route.snapshot.queryParams.type;
this.my = this.route.snapshot.queryParams.my;
this.getCamera(); this.getCamera();
this.getHostData(); 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() { connect() {
// let isAllLabel = this.listOfData.find((item: any) => { // let isAllLabel = this.listOfData.find((item: any) => {
// if (item.type != 1 && !item.dimensionedPoints) { // if (item.type != 1 && !item.dimensionedPoints) {

82
src/app/system-management/host-config/simulate-data/simulate-data.component.html

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

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

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

327
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<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 = [
'进出口',
'卸油区',
'加油区',
'收银区',
'发油区',
'油库区',
'监控区',
'消防通道',
'泵房区',
'油罐区',
'停车区',
];
}

4
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 { IframeComponent } from './iframe/iframe.component';
import { WorkerTagComponent } from './analysis-of-the-host/worker-tag/worker-tag.component'; import { WorkerTagComponent } from './analysis-of-the-host/worker-tag/worker-tag.component';
import { ChangeOrComponent } from './organization/change-or/change-or.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({ @NgModule({
declarations: [ declarations: [
OrganizationComponent, OrganizationComponent,
@ -86,6 +88,7 @@ import { ChangeOrComponent } from './organization/change-or/change-or.component'
IframeComponent, IframeComponent,
WorkerTagComponent, WorkerTagComponent,
ChangeOrComponent, ChangeOrComponent,
SimulateDataComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -112,6 +115,7 @@ import { ChangeOrComponent } from './organization/change-or/change-or.component'
NzPopconfirmModule, NzPopconfirmModule,
NzRadioModule, NzRadioModule,
DragDropModule, DragDropModule,
NzDatePickerModule,
], ],
entryComponents: [ entryComponents: [
AddorComponent, AddorComponent,

Loading…
Cancel
Save