import { Component, OnInit, Inject, ViewChild } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { FileUploader } from 'ng2-file-upload'; import { MatPaginator } from '@angular/material/paginator'; import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar'; import Swiper from 'swiper'; import { Router, ActivatedRoute } from '@angular/router' import { TabbarAndScoreService } from 'src/app/http-interceptors/tabbar-and-score.service'; @Component({ selector: 'app-realistic-picture', templateUrl: './realistic-picture.component.html', styleUrls: ['./realistic-picture.component.scss'] }) export class RealisticPictureComponent implements OnInit { uploader: FileUploader = new FileUploader({ //初始化上传文件 url: `/api/Objects/PlanPlatform/${this.route.snapshot.queryParams.id}/RealImgs`, method: "POST", itemAlias: "uploadedfile", autoUpload: false, removeAfterUpload: true, }); constructor(private tabbarService: TabbarAndScoreService, private router: Router, private route: ActivatedRoute, private http: HttpClient, public dialog: MatDialog, public snackBar: MatSnackBar) { } ngOnInit(): void { let companyId = this.route.snapshot.queryParams.id this.http.get('/api/RealityImageGroups', { params: { companyId: companyId } }).subscribe((data: any) => { this.allRealPicture = data this.allRealPicture.unshift({ companyId: sessionStorage.getItem('companyId'), id: '重点部位', name: "重点部位", realityImages: null }, { companyId: sessionStorage.getItem('companyId'), id: '安全出口', name: "安全出口", realityImages: null }) this.selectReal = data[0] this.getAllRealPicture() }) } companyId: any; //单位编号 allRealPicture: any = []; //所有实景图文件 selectReal: any; //选中的实景图文件 selectRealIndex: number = 0; //选中的实景图文件下标 allImages: any = []; //实景图文件对应所有的实景图 isDownload: boolean = false; //是否批量下载 downloadList: any = []; //选中需要下载的图片 //分页 @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; length: any; //共多少条数据 pageSize: any = '12'; //每页条数 pageSizeOptions: number[] = [12] //设置每页条数 PageNumber: any; //第几页 //分页切换 chagePage(e) { this.PageNumber = e.pageIndex + 1 this.getAllRealPicture() } //获取所有实景图分组 getAllGrouping() { let companyId = this.route.snapshot.queryParams.id this.http.get('/api/RealityImageGroups', { params: { companyId: companyId } }).subscribe((data: any) => { this.allRealPicture = data this.selectReal = data[this.selectRealIndex] }) } //获取实景图分组对应实景图 getAllRealPicture() { if (this.selectReal) { if (this.selectReal.id == '安全出口') { let params = { companyId: this.selectReal.companyId, PageNumber: this.PageNumber || 1, pageSize: this.pageSize, } this.http.get('/api/CompanySafetyExits/GetCompanySafetyExitImages', { params: params }).subscribe((data: any) => { console.log('当前单位安全出口', data) this.allImages = data.items this.length = data.totalCount this.pageSize = this.pageSize this.downloadList = [] this.allImages.forEach(element => { //每张图片设置选中状态为false element.newImageUrl = `${element.imageUrl}?x-oss-process=image/resize,m_fill,h_170,w_299` //处理图片URL地址 element.nameStart = element.name element.checked = false //图片是否选中布尔值 }); }) } else { let data if (this.selectReal.id == '重点部位') { data = { groupId: this.selectReal.id, companyId: this.selectReal.companyId, PageNumber: this.PageNumber || 1, pageSize: this.pageSize, } } else { data = { groupId: this.selectReal.id, PageNumber: this.PageNumber || 1, pageSize: this.pageSize, } } this.http.get('/api/RealityImages', { params: data }).subscribe((data: any) => { this.allImages = data.items this.length = data.totalCount this.pageSize = data.pageSize this.downloadList = [] this.allImages.forEach(element => { //每张图片设置选中状态为false if (this.selectReal.id == '重点部位') { element.newImageUrl = `${element.imageUrl}?x-oss-process=image/resize,m_fill,h_170,w_299` element.nameStart = element.name } else { element.newImageUrl = `/api/Objects/PlanPlatform/${element.imageUrl}?x-oss-process=image/resize,m_fill,h_170,w_299` //处理图片URL地址 element.nameStart = element.name.substring(0, element.name.lastIndexOf(".")); //图片名称前缀 } element.checked = false //图片是否选中布尔值 element.nameEnd = element.name.substring(element.name.lastIndexOf("."), element.name.length); //图片名称后缀 }); }) } } } //切换左侧实景图文件 changeReal(e, index) { if (this.selectRealIndex != index) { this.selectReal = e this.selectRealIndex = index this.isDownload = false this.downloadList = [] this.getAllRealPicture() } } //选择批量下载 download() { this.isDownload = !this.isDownload if (!this.isDownload) { //取消批量下载时数组清空 this.allImages.forEach(element => { element.checked = false }); this.downloadList = [] } } // 预览图片---批量选择图片 operation(e, index) { if (this.isDownload) { //批量选择图片 e.checked = !e.checked if (e.checked == true) { this.downloadList.push(e) } else { this.downloadList.splice(this.downloadList.findIndex(item => item.id === e.id), 1) } } else { //预览图片 let data = { selectReal: this.selectReal, allImages: this.allImages, imgIndex: index } let dialogRef = this.dialog.open(previewImg, { data }); dialogRef.afterClosed().subscribe(); } } //新建实景图文件 addReal() { let dialogRef = this.dialog.open(addRealPicture); dialogRef.afterClosed().subscribe(data => { if (data) { this.tabbarService.sendMessage('changeScore');//通知服务改变分数 this.getAllGrouping() } }); } //编辑实景图文件 editReal() { let data = this.selectReal if (this.selectReal) { let dialogRef = this.dialog.open(editRealPicture, { data }); dialogRef.afterClosed().subscribe(data => { if (data) { this.tabbarService.sendMessage('changeScore');//通知服务改变分数 this.getAllGrouping() } }); } } //删除实景图文件 delete() { let companyId = this.route.snapshot.queryParams.id if (this.selectReal) { let isDelete = confirm('您确定要删除吗') if (isDelete) { this.http.delete(`/api/RealityImageGroups/${this.selectReal.id}`).subscribe(data => { this.http.get('/api/RealityImageGroups', { params: { companyId: companyId } }).subscribe((data: any) => { this.allRealPicture = data this.selectReal = data[this.selectRealIndex] this.allImages = [] this.getAllRealPicture() this.tabbarService.sendMessage('changeScore');//通知服务改变分数 }) }) } } } //实景图修改 preservationImg(e) { let companyId = this.route.snapshot.queryParams.id let data = { id: e.id, name: e.nameStart + e.nameEnd, imageUrl: e.imageUrl, realityImageGroupId: e.realityImageGroupId } this.http.put(`/api/RealityImages/${e.id}`, data, { params: { companyId: companyId } }).subscribe(data => { this.getAllRealPicture() const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('图片修改成功', '确定', config); this.tabbarService.sendMessage('changeScore');//通知服务改变分数 }) } //实景图删除 deleteImg(e) { let isDelete = confirm('您确定要删除吗') if (isDelete) { this.http.delete(`/api/RealityImages/${e.id}`).subscribe(data => { this.getAllRealPicture() const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('图片删除成功', '确定', config); this.tabbarService.sendMessage('changeScore');//通知服务改变分数 }) this.http.delete(`/api/Objects/PlanPlatform/${e.imageUrl}`).subscribe(data => { }) } } isLoading: boolean = false; //loading加载 //上传文件↓ file: any; //上传的文件 objectName: any; //上传对象名 uploadId: any; //上传分块上传事件编号 //change选择文件 uploadFile(e) { if (this.selectReal) { this.file = e.target.files[0] || null //上传的文件 let URL = window.URL.createObjectURL(this.file) var img = new Image() img.src = URL let that = this img.onload = function () { if (img.width >= 4096 || img.height >= 5000) { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 that.snackBar.open('请选择分辨率小于4096*5000的图片', '确定', config); that.uploader.clearQueue(); //清空input控件文件 (document.getElementById('uploadFile')).value = null //清空input框缓存 } else { that.startUploading() } } //onload } else { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择或创建实景图文件夹', '确定', config); this.uploader.clearQueue(); //清空input控件文件 (document.getElementById('uploadFile')).value = null //清空input框缓存 } } //上传文件 startUploading() { let file = this.file || null //获取上传的文件 let fileSize = file.size || null //上传文件的总大小 let shardSize = 5 * 1024 * 1024 //5MB一个分片 let maxdSize = 20 * 1024 * 1024 //限制20MB if (file && fileSize <= shardSize) { //上传文件<=5MB时 this.uploader.queue[0].upload();//开始上传 this.uploader.queue[0].onSuccess = (response, status, headers) => { if (status == 201) { // 上传文件成功,上传文件后获取服务器返回的数据 let tempRes = JSON.parse(response); this.objectName = tempRes.objectName this.addRealImg() } else { // 上传文件后获取服务器返回的数据错误 let tempRes = JSON.parse(response); } }; } else if (file && fileSize > shardSize && fileSize < maxdSize) { //上传文件>5MB时,分块上传 let data = { filename: file.name } this.isLoading = true this.http.post(`/api/NewMultipartUpload/PlanPlatform/${this.companyId}/RealImgs`, {}, { params: data }).subscribe((data: any) => { //初始化分段上传 this.objectName = data.objectName this.uploadId = data.uploadId this.subsectionUploading() }) } } PartNumberETag: any = []; //每次返回需要保存的信息 //开始分段上传 async subsectionUploading() { let file = this.file || null //获取上传的文件 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(`/api/MultipartUpload/PlanPlatform/${this.objectName}?uploadId=${this.uploadId}&partNumber=${i + 1}`, formData).subscribe((data: any) => { let msg = { "partNumber": data.partNumber || null, "eTag": data.eTag || null } resolve(msg) // 调用 promise 内置方法处理成功 }) }); this.PartNumberETag.push(result) if (this.PartNumberETag.length === allSlice) { this.endUploading() } }//for循环 } //完成分块上传 endUploading() { let data = this.PartNumberETag let paramsData = { uploadId: this.uploadId } this.http.post(`/api/CompleteMultipartUpload/PlanPlatform/${this.objectName}`, data, { params: paramsData }).subscribe(data => { this.addRealImg() //上传完成后,发送请求创建实景图 this.isLoading = false this.uploader.clearQueue(); //清空input控件文件 this.PartNumberETag = [] //清空保存返回的信息 }) } //上传图片成功后获取url地址发送请求创建实景图 addRealImg() { let companyId = this.route.snapshot.queryParams.id let data = { name: this.file.name, imageUrl: this.objectName, realityImageGroupId: this.selectReal.id, } this.http.post('/api/RealityImages', data, { params: { companyId: companyId } }).subscribe(data => { (document.getElementById('uploadFile')).value = null //清空input框缓存 this.getAllRealPicture() const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('图片上传成功', '确定', config); this.tabbarService.sendMessage('changeScore');//通知服务改变分数 }) } //批量下载↓ //开始下载 async batchDownload() { if (this.downloadList.length) { //开始批量循环下载 this.isLoading = true for (let i = 0; i < this.downloadList.length; i++) { let result = await new Promise((result, reject) => { let url if (this.selectReal.id == '重点部位' || this.selectReal.id == '安全出口') { url = this.downloadList[i].imageUrl } else { url = `/api/Objects/PlanPlatform/${this.downloadList[i].imageUrl}` } this.http.get(url, { responseType: 'blob' },).subscribe((data: any) => { let url = window.URL.createObjectURL(new Blob([data])); //createObjectURL创建一个下载Blob的url地址 let link = document.createElement("a"); link.style.display = "none"; link.href = url; let imgName if (this.selectReal.id == '重点部位') { imgName = this.downloadList[i].name + '.' + data.type.split('/')[data.type.split('/').length - 1] } else if (this.selectReal.id == '安全出口') { imgName = '安全出口' + this.downloadList[i].name } else { imgName = this.downloadList[i].name } link.setAttribute("download", imgName); document.body.appendChild(link); link.click(); result('success') }) }) if (i == this.downloadList.length - 1) { //判断是否下载完毕 this.isLoading = false this.isDownload = false this.allImages.forEach(element => { element.checked = false }); this.downloadList = [] } } //for循环 } else { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择图片', '确定', config); } } } //预览图片组件 @Component({ selector: 'app-previewImg', templateUrl: './previewImg.html', styleUrls: ['./realistic-picture.component.scss'] }) export class previewImg { constructor(private http: HttpClient, public dialog: MatDialog, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data) { } testSwiper: Swiper; ngOnInit(): void { this.allImages = this.data.allImages this.allImages.forEach(element => { if (this.data.selectReal.id == '重点部位' || this.data.selectReal.id == '安全出口') { element.previewImageUrl = `${element.imageUrl}` //处理图片URL地址 } else { element.previewImageUrl = `/api/Objects/PlanPlatform/${element.imageUrl}?x-oss-process=image/auto-orient,1` //处理图片URL地址 } }); } ngAfterViewInit() { this.testSwiper = new Swiper('.swiper-container', { lazy: true, initialSlide: this.data.imgIndex, direction: 'horizontal', loop: false, // 如果需要前进后退按钮 navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', } }); } allImages: any; //展示所有的图片 rotationAngle: number = 0; //旋转角度 //旋转图片 rotate() { this.rotationAngle = this.rotationAngle + 90 if (this.rotationAngle === 360) { this.rotationAngle = 0 } } } //新建实景图文件组件 @Component({ selector: 'app-addRealPicture', templateUrl: './addRealPicture.html', styleUrls: ['./realistic-picture.component.scss'] }) export class addRealPicture { constructor(private router: Router, private route: ActivatedRoute, private http: HttpClient, public dialog: MatDialog, public dialogRef: MatDialogRef) { } ngOnInit(): void { this.companyId = sessionStorage.getItem('companyId') } companyId: any; //单位编号 //提交表单 onSubmit(e) { let companyId = this.route.snapshot.queryParams.id let data = { name: e.name, companyId: companyId } this.http.post('/api/RealityImageGroups', data).subscribe(data => { this.dialogRef.close(data); }) } } //编辑实景图文件组件 @Component({ selector: 'app-editRealPicture', templateUrl: './editRealPicture.html', styleUrls: ['./realistic-picture.component.scss'] }) export class editRealPicture { constructor(private router: Router, private route: ActivatedRoute, private http: HttpClient, public dialog: MatDialog, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data) { } ngOnInit(): void { this.name = this.data.name } name: any //实景图分组名称 //提交表单 onSubmit(e) { let companyId = this.route.snapshot.queryParams.id let data = { id: this.data.id, name: e.name, companyId: companyId } this.http.put(`/api/RealityImageGroups/${this.data.id}`, data).subscribe(data => { this.dialogRef.close('success'); }) } }