邵佳豪
2 years ago
5 changed files with 672 additions and 19 deletions
@ -0,0 +1,42 @@
|
||||
<div class="box" cdkDrag> |
||||
<div class="titlebox"> |
||||
<div class="title" cdkDragHandle> |
||||
<div class="selected"> |
||||
图片查看 |
||||
<div class="border"></div> |
||||
</div> |
||||
</div> |
||||
<div class="close" (click)="closeModel()"> |
||||
<i nz-icon nzType="close" nzTheme="outline"></i> |
||||
</div> |
||||
</div> |
||||
<!-- <div class="details"> |
||||
预警详情:{{details}} |
||||
</div> --> |
||||
<div class="typecheckbox"> |
||||
<ng-container> |
||||
<label *ngFor="let item of this.legendList" nz-checkbox [(ngModel)]="item.checked" |
||||
(ngModelChange)="typeChange(item)"> |
||||
<div style="width: 10px;height: 10px;display: inline-block;" |
||||
[ngStyle]="{'background': typeArr[item.id].color}"> |
||||
</div> |
||||
{{typeArr[item.id].name}} |
||||
</label> |
||||
</ng-container> |
||||
|
||||
|
||||
<button nz-button nzType="primary" (click)="downImg()">导出图片</button> |
||||
</div> |
||||
<div class="content"> |
||||
<div class="imgbox imgboxAX"> |
||||
<ng-container *ngIf="imgUrl; else elseTemplate"> |
||||
<img id="img" [src]="imgUrl" alt=""> |
||||
<canvas [width]="canvasWidth" [height]="canvasHeight" |
||||
[ngStyle]="{'width': canvasWidth + 'px','height': canvasHeight + 'px'}" id="canvas"></canvas> |
||||
</ng-container> |
||||
<ng-template #elseTemplate> |
||||
暂无图片 |
||||
</ng-template> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,189 @@
|
||||
.box { |
||||
width: 100%; |
||||
color: #fff; |
||||
display: flex; |
||||
flex-direction: column; |
||||
background-image: linear-gradient(#003B6E, #000D21); |
||||
position: relative; |
||||
border: 1px solid #6d9cc7; |
||||
box-shadow: 0 0 8px 0 #fff |
||||
} |
||||
|
||||
.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; |
||||
position: relative; |
||||
|
||||
.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%); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
.close { |
||||
position: absolute; |
||||
right: 18px; |
||||
top: 18px; |
||||
cursor: pointer; |
||||
|
||||
i { |
||||
font-size: 18px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.details { |
||||
width: 100%; |
||||
height: 45px; |
||||
line-height: 45px; |
||||
box-sizing: border-box; |
||||
padding: 0 12px; |
||||
} |
||||
|
||||
.typecheckbox { |
||||
box-sizing: border-box; |
||||
padding: 0 12px; |
||||
margin-top: 12px; |
||||
|
||||
label { |
||||
color: #fff; |
||||
} |
||||
|
||||
} |
||||
|
||||
.content { |
||||
flex: 1; |
||||
overflow: hidden; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
flex-direction: column; |
||||
|
||||
.imgbox { |
||||
flex: 1; |
||||
box-sizing: border-box; |
||||
padding:12px; |
||||
width: 100%; |
||||
height: 100%; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
position: relative; |
||||
// margin-bottom: 12px; |
||||
flex-direction: column; |
||||
|
||||
iframe { |
||||
flex: 1; |
||||
} |
||||
|
||||
#canvas { |
||||
position: absolute; |
||||
left: 50%; |
||||
top: 50%; |
||||
transform: translate(-50%, -50%); |
||||
} |
||||
|
||||
img { |
||||
max-width: 100%; |
||||
max-height: 100%; |
||||
} |
||||
} |
||||
|
||||
.imgboxAX { |
||||
img { |
||||
width: 100%; |
||||
height: auto; |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
.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; |
||||
} |
||||
|
||||
} |
||||
|
||||
// 适配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; |
||||
} |
||||
|
||||
} |
||||
|
||||
::-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; |
||||
} |
@ -0,0 +1,385 @@
|
||||
import { HttpClient } from "@angular/common/http"; |
||||
import { Component, OnInit, Input } from "@angular/core"; |
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms"; |
||||
import { DomSanitizer } from "@angular/platform-browser"; |
||||
import { NzMessageService } from "ng-zorro-antd/message"; |
||||
import { NzModalRef, NzModalService } from "ng-zorro-antd/modal"; |
||||
import { NzTreeModule } from "ng-zorro-antd/tree"; |
||||
import { ObjectsSimpleService } from "src/app/service/objectsSimple.service"; |
||||
import { PublicMethodsService } from "src/app/service/publicMethods.service"; |
||||
import Viewer from "viewerjs"; |
||||
@Component({ |
||||
selector: "app-anxin-img-look", |
||||
templateUrl: "./anxin-img-look.component.html", |
||||
styleUrls: ["./anxin-img-look.component.scss"], |
||||
}) |
||||
export class AnxinImgLookComponent implements OnInit { |
||||
@Input() data: any; |
||||
|
||||
constructor( |
||||
private objectsSrv: ObjectsSimpleService, |
||||
private fb: FormBuilder, |
||||
private http: HttpClient, |
||||
private message: NzMessageService, |
||||
private modal: NzModalService, |
||||
private initialModal: NzModalRef, |
||||
private sanitizer: DomSanitizer, |
||||
private openmodal: NzModalRef, |
||||
private pubilcMethods: PublicMethodsService |
||||
) {} |
||||
|
||||
imgUrl: string; |
||||
vedioUrl: string; |
||||
content; |
||||
details; |
||||
|
||||
// 标注安信框选区
|
||||
isAnxin = false; |
||||
coordinate = []; //完整坐标点信息
|
||||
currentCoordinate = []; //当前需要标绘坐标点信息
|
||||
legendList: any = []; |
||||
typeArr = [ |
||||
{ id: 0, name: "工装", color: "#91CCFF" }, |
||||
{ id: 2, name: "便装", color: "#46DFFF" }, |
||||
{ id: 2, name: "抽烟", color: "#36A2FF" }, |
||||
{ id: 3, name: "打电话", color: "#FF6181" }, |
||||
{ id: 4, name: "隔离锥", color: "#000000" }, |
||||
{ id: 5, name: "手持灭火器", color: "#ffffff" }, |
||||
{ id: 6, name: "推车灭火器", color: "#B4C3FF" }, |
||||
{ id: 7, name: "静电接地", color: "#FF9963" }, |
||||
{ id: 8, name: "输油管(连接)", color: "#5A9CFF" }, |
||||
{ id: 9, name: "输油管连接车", color: "#4BFFD4" }, |
||||
{ id: 10, name: "输油管连接卸油口", color: "red" }, |
||||
{ id: 11, name: "卸油口盖子", color: "green" }, |
||||
{ id: 12, name: "卸油车", color: "yellow" }, |
||||
{ id: 13, name: "私家车", color: "black" }, |
||||
{ id: 14, name: "断开的卸油管", color: "blue" }, |
||||
]; |
||||
userName; //登录账号的用户名
|
||||
|
||||
ngOnInit(): void { |
||||
// console.log(this.data);
|
||||
|
||||
// // 安信框选
|
||||
// console.log("预警信息", this.data);
|
||||
// this.details = this.data.content1;
|
||||
// this.vedioUrl = this.data.violateVideo;
|
||||
// this.content = this.data.handleRecord;
|
||||
this.imgUrl = this.data.violateImage; |
||||
let dataArr = []; |
||||
for (const key in JSON.parse(this.data.desc)) { |
||||
const element = JSON.parse(this.data.desc)[key]; |
||||
dataArr.push(element); |
||||
} |
||||
this.coordinate = dataArr; |
||||
this.currentCoordinate = JSON.parse(JSON.stringify(this.coordinate)); |
||||
console.log("坐标信息", this.coordinate); |
||||
let checkboxArr = []; |
||||
this.coordinate.forEach((element) => { |
||||
checkboxArr.push({ id: element.id, checked: true }); |
||||
}); |
||||
for (let i = 0; i < checkboxArr.length; i++) { |
||||
if (!this.legendList.some((e) => e.id == checkboxArr[i].id)) |
||||
this.legendList.push(checkboxArr[i]); |
||||
} |
||||
setTimeout(() => { |
||||
this.canvasLabel(); |
||||
}, 0); |
||||
} |
||||
|
||||
canvasWidth = 0; |
||||
canvasHeight = 0; |
||||
ctx; |
||||
canvasLabel() { |
||||
let imgBg: any = document.getElementById("img"); |
||||
imgBg.onload = () => { |
||||
this.canvasWidth = imgBg.offsetWidth; |
||||
this.canvasHeight = imgBg.offsetHeight; |
||||
const img = new Image(); |
||||
img.src = imgBg.src; |
||||
img.onload = () => { |
||||
console.log(1,this.canvasWidth) |
||||
console.log(2,this.canvasHeight) |
||||
const canvas: any = document.querySelector("#canvas"); |
||||
this.ctx = canvas.getContext("2d"); |
||||
const cWidth = canvas.width, |
||||
cHeight = canvas.height; |
||||
// 以图画底
|
||||
this.ctx.drawImage(img, 0, 0, cWidth, cHeight); |
||||
this.strokeRect(this.currentCoordinate); |
||||
}; |
||||
}; |
||||
} |
||||
|
||||
strokeRect(data) { |
||||
data.forEach((item) => { |
||||
let startPoint = [ |
||||
Math.round(this.canvasWidth * item.box[0]), |
||||
Math.round(this.canvasHeight * item.box[1]), |
||||
]; |
||||
let endPoint = [ |
||||
Math.round(this.canvasWidth * item.box[2]), |
||||
Math.round(this.canvasHeight * item.box[3]), |
||||
]; |
||||
|
||||
this.ctx.strokeStyle = this.typeArr[item.id].color; |
||||
this.ctx.lineWidth = 3; |
||||
this.ctx.strokeRect( |
||||
startPoint[0], |
||||
startPoint[1], |
||||
endPoint[0] - startPoint[0], |
||||
endPoint[1] - startPoint[1] |
||||
); |
||||
//如果当前矩形区域为错误区域,则左上角增加色块
|
||||
if (item.error) { |
||||
this.ctx.fillStyle = this.typeArr[item.id].color; |
||||
this.ctx.fillRect(startPoint[0], startPoint[1], 10, 10); |
||||
} |
||||
this.ctx.fillStyle = this.typeArr[item.id].color; |
||||
this.ctx.font = "16px Verdana"; |
||||
let name = this.typeArr[item.id].name + item.scores; |
||||
|
||||
this.ctx.fillText( |
||||
name, |
||||
startPoint[0], |
||||
startPoint[1] < 20 || item.id === 2 || item.id === 3 |
||||
? endPoint[1] + 18 |
||||
: startPoint[1] - 5 |
||||
); |
||||
}); |
||||
} |
||||
|
||||
typeChange(item) { |
||||
if (item.checked) { |
||||
this.coordinate.forEach((element) => { |
||||
if (element.id === item.id) { |
||||
this.currentCoordinate.push(element); |
||||
} |
||||
}); |
||||
} else { |
||||
this.currentCoordinate = this.currentCoordinate.filter( |
||||
(v) => v.id !== item.id |
||||
); |
||||
} |
||||
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); |
||||
this.strokeRect(this.currentCoordinate); |
||||
} |
||||
|
||||
downImg() { |
||||
const canvasDom: any = document.querySelector("#canvas"); |
||||
const imageData = canvasDom.toDataURL("image/png"); //返回base64的URL
|
||||
const elink = document.createElement("a"); |
||||
elink.download = "图片"; |
||||
elink.style.display = "none"; |
||||
elink.href = imageData; |
||||
document.body.appendChild(elink); |
||||
elink.click(); |
||||
URL.revokeObjectURL(elink.href); //释放URL对象
|
||||
document.body.removeChild(elink); |
||||
} |
||||
fileList = []; |
||||
|
||||
isLoadingSave: boolean = false; |
||||
uploadIndex: string; |
||||
filechange(e) { |
||||
this.isLoadingSave = true; |
||||
let file = e.target.files[0] || null; //获取上传的文件
|
||||
this.openFileSelect( |
||||
file, |
||||
`stationPhotos/${this.data.gasStation.id}/appealFile/${this.data.id}` |
||||
); |
||||
} |
||||
//设置文件路径并上传
|
||||
postFilePath; |
||||
async openFileSelect(file: File, extensionPath: string) { |
||||
this.postFilePath = extensionPath; |
||||
let fileSize = file.size || null; //上传文件的总大小
|
||||
let shardSize = 5 * 1024 * 1024; //5MB 超过5MB要分块上传
|
||||
if (fileSize >= shardSize) { |
||||
// 超过5MB要分块上传
|
||||
await this.postFileByMul(file); |
||||
} //普通上传
|
||||
else { |
||||
await this.postFile(file); |
||||
} |
||||
} |
||||
//上传文件
|
||||
async postFile(file: File) { |
||||
await new Promise((resolve, reject) => { |
||||
this.objectsSrv.postFile(this.postFilePath, file).subscribe((data) => { |
||||
let dataObj = data as any; |
||||
let filePath: string = |
||||
ObjectsSimpleService.baseUrl + dataObj.objectName; |
||||
this.fileList.push(filePath); |
||||
this.isLoadingSave = false; |
||||
resolve("success"); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 分块上传 |
||||
* @param file |
||||
*/ |
||||
postFileByMul(file: File) { |
||||
this.objectsSrv |
||||
.postFile_MultipartUpload(this.postFilePath, file) |
||||
.then((value) => { |
||||
let dataObj = value as any; |
||||
let filePath = dataObj.filePath; |
||||
this.fileList.push(filePath); |
||||
this.isLoadingSave = false; |
||||
}); |
||||
} |
||||
|
||||
lookfile(item) { |
||||
if (!item) { |
||||
return; |
||||
} |
||||
if (this.pubilcMethods.getFileType(item) == "word") { |
||||
let arr = item.split("."); |
||||
arr[arr.length - 1] = "pdf"; |
||||
window.open(arr.join(".")); |
||||
} else if (this.pubilcMethods.getFileType(item) == "pdf") { |
||||
window.open(item); |
||||
} else { |
||||
this.viewImg(item); |
||||
} |
||||
} |
||||
|
||||
delete(fileList, key) { |
||||
this.modal.confirm({ |
||||
nzTitle: `确定要删除这个文件吗?`, |
||||
nzOkText: "确定", |
||||
nzOkType: "primary", |
||||
nzOnOk: () => { |
||||
fileList.splice(key, 1); |
||||
}, |
||||
nzCancelText: "取消", |
||||
}); |
||||
} |
||||
|
||||
//查看图片
|
||||
viewImg(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); |
||||
} |
||||
|
||||
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.handleStateStr = "已处置"; |
||||
this.data.handleRecord = this.content; |
||||
}); |
||||
} |
||||
|
||||
//误报
|
||||
misinformation() { |
||||
this.modal.confirm({ |
||||
nzTitle: "判定该预警为误报吗?", |
||||
nzOkText: "确定", |
||||
nzOkType: "primary", |
||||
nzOnOk: () => { |
||||
let body = { |
||||
id: this.data.id, |
||||
positive: false, |
||||
}; |
||||
this.http |
||||
.post("/api/services/app/ViolateRecord/CensorViolateRecord", body) |
||||
.subscribe( |
||||
(data) => { |
||||
this.message.create("success", "处置成功!"); |
||||
// this.data.handleTime = new Date()
|
||||
this.initialModal.triggerOk(); |
||||
}, |
||||
(err) => { |
||||
this.message.create("warning", "处置失败,请联系管理员!"); |
||||
} |
||||
); |
||||
}, |
||||
nzCancelText: "取消", |
||||
nzOnCancel: () => console.log("Cancel"), |
||||
}); |
||||
} |
||||
|
||||
// 申诉
|
||||
isAppeal; |
||||
appealValue; |
||||
appeal() { |
||||
this.isAppeal = true; |
||||
} |
||||
handleOk() { |
||||
let body = { |
||||
appealReason: this.appealValue, |
||||
appealAttachments: this.fileList, |
||||
}; |
||||
this.http |
||||
.post("/api/services/app/ViolateRecord/Appeal", body, { |
||||
params: { |
||||
id: this.data.id, |
||||
}, |
||||
}) |
||||
.subscribe( |
||||
(data: any) => { |
||||
this.message.create("success", "申诉提交成功"); |
||||
this.isAppeal = false; |
||||
this.data.appealStatus = 1; |
||||
this.data.appealLog = data.result.appealLog; |
||||
}, |
||||
(err) => { |
||||
this.message.create("warning", "申诉提交失败,请联系管理员!"); |
||||
} |
||||
); |
||||
} |
||||
|
||||
handleCancel(): void { |
||||
this.isAppeal = false; |
||||
} |
||||
|
||||
Unappeal() { |
||||
this.http |
||||
.post("/api/services/app/ViolateRecord/Unappeal", null, { |
||||
params: { |
||||
id: this.data.id, |
||||
}, |
||||
}) |
||||
.subscribe( |
||||
(data) => { |
||||
this.message.create("success", "申诉撤销成功"); |
||||
this.data.appealStatus = 4; |
||||
}, |
||||
(err) => { |
||||
this.message.create("warning", "申诉撤销失败,请联系管理员!"); |
||||
} |
||||
); |
||||
} |
||||
|
||||
closeModel() { |
||||
this.openmodal.close(); |
||||
} |
||||
} |
Loading…
Reference in new issue