import { Component, OnInit, Inject } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar'; @Component({ selector: 'app-uploading-cad', templateUrl: './uploading-cad.component.html', styleUrls: ['./uploading-cad.component.scss'] }) export class UploadingCADComponent implements OnInit { constructor(private http:HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { } ngOnInit(): void { this.companyId = sessionStorage.getItem('companyId') this.getAllCAD() } displayedColumns: string[] = ['checked', 'name', 'time', 'state','size']; companyId:any; //单位编号 CADList:any=[]; //所有CAD图 selectCAD:any = []; //选中的CAD图 //获取所有CAD图 getAllCAD () { this.http.get('/api/CompanyAccount/CadData').subscribe(data=>{ this.CADList = data this.selectCAD = [] this.CADList.forEach(element => { element.loading = false element.suffix = element.cadUrl.substring(element.cadUrl.lastIndexOf("."),element.cadUrl.length); //图名后缀 element.fileLength = (element.fileLength/1024/1024).toFixed(2)}); }) } //change CAD图checked checkedCAD (e,element) { if (e.checked) { this.selectCAD.push(element) } else { this.selectCAD.splice(this.selectCAD.findIndex(item => item.id === element.id), 1)} } //打开上传文件窗口 openReadFile() { let dialogRef = this.dialog.open(readFile); dialogRef.afterClosed().subscribe(data=>{ if (data) { this.file = data.file this.fileName = data.name this.startUploading()} //开始上传 }); } //打开编辑文件窗口 editFile () { if (this.selectCAD.length===1) { let data = this.selectCAD[0] let dialogRef = this.dialog.open(editFile,{data}); dialogRef.afterClosed().subscribe(data=>{ if (data) {this.getAllCAD()} }); } else if (this.selectCAD.length>1) { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('不支持批量编辑','确定',config); }else if (!this.selectCAD.length) { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择CAD图纸','确定',config); } } //删除CAD图 deleteCAD () { if (this.selectCAD.length) { let isDelete = confirm('您确定要删除吗') let arr = [] if (isDelete) { this.selectCAD.forEach( async (element,index) => { let result = await new Promise((result,reject)=>{ this.http.delete(`/api/CompanyAccount/CadData/${element.id}`).subscribe(data=>{result(index)}) this.http.delete(`/api/Objects/PlanPlatform/${element.cadUrl}`).subscribe(data=>{}) }) arr.push(result) if (arr.length == this.selectCAD.length) { this.getAllCAD() const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('删除CAD图纸成功','确定',config);} }); } } else { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择CAD图纸','确定',config); } } //上传文件↓ file:any; //上传的文件 fileName:any; //上传文件name uploadisLoading:boolean = false; //进度条loading加载 uploadProgress:number=0; //进度条进度 objectName:any; //上传对象名 uploadId:any; //上传分块上传事件编号 //上传文件 startUploading () { let file = this.file || null //获取上传的文件 let fileSize = file.size || null //上传文件的总大小 let shardSize = 5 * 1024 * 1024 //5MB一个分片 if (file && fileSize<=shardSize) { //上传文件<=5MB时 let formData = new FormData() formData.append("file",file) this.http.post(`/api/Objects/PlanPlatform/${this.companyId}/CAD`,formData).subscribe((data:any)=>{ this.objectName = data.objectName this.addCADData() }) } else if (file && fileSize>shardSize) { //上传文件>5MB时,分块上传 let data = {filename: file.name} this.uploadisLoading = true this.http.post(`/api/NewMultipartUpload/PlanPlatform/${this.companyId}/CAD`,{},{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) this.uploadProgress = Number((i/allSlice).toFixed(2))*100 if (this.PartNumberETag.length === allSlice) { this.uploadProgress = 100 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.addCADData() this.uploadProgress = 0; this.uploadisLoading = false this.PartNumberETag =[] //清空保存返回的信息 }) } //取消分块上传 cancel () { this.http.delete(`/api/MultipartUpload/PlanPlatform/${this.objectName}?uploadId=${this.uploadId}`).subscribe(data=>{ this.uploadProgress = 0; this.uploadisLoading= false this.PartNumberETag =[] //清空保存返回的信息 const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('取消上传成功!','确定',config); }) } //上传成功创建CAD addCADData () { let data = { name: this.fileName, cadUrl: this.objectName, fileLength: this.file.size, creationTime: new Date(), companyId: this.companyId } this.http.post('/api/CompanyAccount/CadData',data).subscribe(data=>{ this.getAllCAD() }) } //下载↓ selectDownloadFile:any; //选择下载的文件 download:any; //下载文件元数据 downloadisLoading:boolean = false; //进度条loading加载 downloadProgress:number=0; //进度条进度 //读取下载文件信息 readFile () { if (this.selectCAD.length===1) { this.selectDownloadFile = this.selectCAD[0] this.http.get('/api/ObjectMetadata/PlanPlatform/'+this.selectDownloadFile.cadUrl).subscribe(data=>{ this.download = data this.downloadFile() }) } else if (this.selectCAD.length>1) { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('暂时不支持批量下载','确定',config) } else if (!this.selectCAD.length) { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择CAD图纸','确定',config); } } //初始化下载 downloadFile () { let file = this.download let fileSize = file.fileLength//下载文件的总大小 let shardSize = 10 * 1024 * 1024 //文件大小是否大于10MB if (file && fileSize<=shardSize) { //<=10MB时直接下载 this.downloadisLoading = true this.setFileLoading() this.http.get(`/api/Objects/PlanPlatform/${file.objectName}`,{responseType: 'blob'},).subscribe(data=>{ let url = window.URL.createObjectURL(new Blob([data])); //createObjectURL创建一个下载Blob的url地址 let link = document.createElement("a"); link.style.display = "none"; link.href = url; link.setAttribute("download", this.selectDownloadFile.name+this.selectDownloadFile.suffix); document.body.appendChild(link); link.click(); this.downloadisLoading = false this.setFileLoading() }) } else if (file && fileSize>shardSize) { //>10MB时分块下载 this.blockingDownload() //分段下载 this.downloadisLoading = true this.setFileLoading() } } //分段下载并合并 async blockingDownload () { let file = this.download let fileSize = file.fileLength //下载文件的总大小 let shardSize = 3 * 1024 * 1024 //3MB一个分片 let allSlice = Math.ceil(fileSize / shardSize) //总文件/3MB===共分多少段 let allFile:any = [] //所有的file分段 for (let i=0;i{ this.http.get(`/api/Objects/PlanPlatform/${file.objectName}`,{headers:{'range':`bytes= ${start}-${end}`},responseType:'blob'}).subscribe(data=>{ result(data) }) }) allFile.push(result) this.downloadProgress = Number((i/allSlice).toFixed(2))*100 if (allFile.length === allSlice) { //合并文件输出给浏览器 let url = window.URL.createObjectURL(new Blob(allFile)); //createObjectURL创建一个下载Blob的url地址 let link = document.createElement("a"); link.style.display = "none"; link.href = url; link.setAttribute("download", this.selectDownloadFile.name+this.selectDownloadFile.suffix); document.body.appendChild(link); link.click(); this.downloadProgress = 0 this.downloadisLoading = false this.setFileLoading() } } //for循环 } //取消分块下载 cancelDowload () { } //封装函数设置当前文件loading状态 setFileLoading () { let id = this.selectDownloadFile.id this.CADList.forEach(element => { if (element.id === id) { element.loading = !element.loading } }); } } //创建文件弹窗组件 @Component({ selector: 'app-readFile', templateUrl: './readFile.html', styleUrls: ['./uploading-cad.component.scss'] }) export class readFile { constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar) { } ngOnInit(): void { } file:any; //上传的文件 //input file 选择文件 selectFile (e) { this.file = e.target.files[0] || null //上传的文件 } //提交表单上传 onSubmit (e) { if (this.file) { let data = { name:e.name, file: this.file} this.dialogRef.close(data); } else { const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请选择CAD图纸','确定',config); } } } //编辑文件弹窗组件 @Component({ selector: 'app-editFile', templateUrl: './editFile.html', styleUrls: ['./uploading-cad.component.scss'] }) export class editFile { constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data) { } ngOnInit(): void { this.CADname = this.data.name } CADname:any; //name //提交表单保存 onSubmit (e) { let headers = new HttpHeaders({'Content-Type': 'text/json'}); let options = {headers}; this.http.put(`/api/CompanyAccount/CadData/${this.data.id}`,JSON.stringify(e.name),options).subscribe(data=>{ this.dialogRef.close('success'); }) } }