Browse Source

[新增]实景图分段上传功能逻辑实现

develop
陈鹏飞 5 years ago
parent
commit
49bfda86eb
  1. 1
      src/app/app.component.ts
  2. 1
      src/app/http-interceptors/cache-token.service.ts
  3. 1
      src/app/pages/login/login.component.ts
  4. 2
      src/app/tabbar/tabbar.component.html
  5. 8
      src/app/tabbar/tabbar.component.ts
  6. 1
      src/app/ui/function-division/function-division.component.html
  7. 1
      src/app/ui/plan/plan.component.html
  8. 18
      src/app/ui/realistic-picture/previewImg.html
  9. 9
      src/app/ui/realistic-picture/realistic-picture.component.html
  10. 72
      src/app/ui/realistic-picture/realistic-picture.component.scss
  11. 121
      src/app/ui/realistic-picture/realistic-picture.component.ts

1
src/app/app.component.ts

@ -28,6 +28,7 @@ export class AppComponent {
}
).subscribe(
(data: Data) => {
sessionStorage.setItem("realName",data.realName)
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
this.token.startUp()

1
src/app/http-interceptors/cache-token.service.ts

@ -28,6 +28,7 @@ export class CacheTokenService {
).subscribe(
(data:any) => {
console.log(data)
sessionStorage.setItem("realName",data.realName)
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
}

1
src/app/pages/login/login.component.ts

@ -29,6 +29,7 @@ export class LoginComponent implements OnInit {
password: e.password}).subscribe(
(data: Data) =>
{
sessionStorage.setItem("realName",data.realName)
sessionStorage.setItem("token",data.token);
sessionStorage.setItem("refreshToken",data.refreshToken);
this.router.navigate(['/datacollection/basicinfo'])

2
src/app/tabbar/tabbar.component.html

@ -1,6 +1,6 @@
<mat-toolbar [color]="theme?'primary':'accent'">
<!-- <mat-toolbar> -->
<h1>{{companyName}}</h1>
<h1 *ngIf="companyName">{{companyName}}</h1>
<!-- 全屏 -->
<!-- <button mat-button (click)="!isfullscreen?fullscreenToggle():closefullscreen()" class="fullscreen">

8
src/app/tabbar/tabbar.component.ts

@ -32,7 +32,7 @@ export class TabbarComponent implements OnInit {
constructor(private http:HttpClient,private router:Router,private route:ActivatedRoute,public token:CacheTokenService,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit() {
this.getCompany()
this.companyName = sessionStorage.getItem("realName");
}
boxed(css){
@ -84,12 +84,6 @@ export class TabbarComponent implements OnInit {
}
companyName:any; //企业name
//获取当前登录企业信息
getCompany () {
this.http.get('/api/CompanyAccount/Profiles').subscribe((data:any)=>{
this.companyName = data.companyName
})
}
//退出系统
signOut = () => {

1
src/app/ui/function-division/function-division.component.html

@ -8,6 +8,7 @@
<mat-tab label="单位功能分区">
<div style="margin: 30px 0 25px 50px;">
<mat-icon title="创建" (click)='addPartitionAttribute()'>add_circle_outline</mat-icon>
<mat-icon title="保存" style="margin-left: 25px;">description</mat-icon>
<mat-icon title="删除" style="margin-left: 25px;">delete</mat-icon>
</div>
<table mat-table [dataSource]="dataSource" style="margin-left: 50px;">

1
src/app/ui/plan/plan.component.html

@ -1 +0,0 @@
<p>plan works!</p>

18
src/app/ui/realistic-picture/previewImg.html

@ -0,0 +1,18 @@
<div mat-dialog-title>图片详情</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide previewImgBox"><img [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270}"
src="../../../assets/images/bg_login.jpg"></div>
<div class="swiper-slide previewImgBox"><img [ngClass]="{'rotateA':rotationAngle==90,'rotateB':rotationAngle==180,'rotateC':rotationAngle==270}"
src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1583660754310&di=782b4fc4e7186c8db2fa6dfe5e0760f4&imgtype=0&src=http%3A%2F%2Ffile06.16sucai.com%2F2016%2F0704%2F04e855314b2e0b342a949fd9f8698e97.jpg"></div>
</div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="previewImgBottom">
<button type="button" mat-icon-button (click)='rotate()'><mat-icon>refresh</mat-icon></button>
<button type="button" mat-icon-button><mat-icon>vertical_align_bottom</mat-icon></button>
</div>

9
src/app/ui/realistic-picture/realistic-picture.component.html

@ -21,9 +21,13 @@
<div class="topBox">
<div>
<span class="title" *ngIf="selectReal">{{selectReal.name}}</span>
<button mat-raised-button color="primary">上传图片</button>
<button mat-raised-button color="primary" class="uploadFileFixed">
上传图片
<input type="file" class="uploadFile" (change)='uploadFile($event)' ng2FileSelect [uploader]="uploader">
</button>
<button mat-raised-button color="primary" style="margin-left: 15px;" (click)='download()'>批量下载</button>
<button mat-raised-button color="primary" style="margin-left: 15px;" *ngIf="isDownload">下载</button>
<span style="margin-left: 15px;color: red;font-size: 12px;" *ngIf="isDownload">*现为批量下载状态,如需预览图片,请关闭批量下载</span>
</div>
<div>
<span>已用/容量:</span>
@ -33,7 +37,8 @@
<div class="bottomBox">
<div class="imgBox">
<img src="../../../assets/images/upload.png" (click)='operation()'>
<mat-icon class="checkedImg">check_circle</mat-icon>
<div class="fixedImg"><img src="../../../assets/images/upload.png" (click)='operation()'></div>
<label style="margin-left: 5px;">图片名称:</label>
<input type="text" style="margin-left: 10px;">
<a href="javascript:" style="margin-left: 5px;">保存</a>

72
src/app/ui/realistic-picture/realistic-picture.component.scss

@ -57,7 +57,25 @@
height: 200px;
margin: 0 25px 25px 0;
display: inline-block;
img {width: 100%;cursor:pointer;}
position: relative;
.fixedImg {
width: 100%;
height: 170px;
text-align: center;
margin-bottom: 3px;
img {
width: 100px;
height: 100px;
cursor:pointer;
}
}
.checkedImg {
position: absolute;
top: 1px;
right: 1px;
color:#00FF00;
font-size: 30px;
}
input{
font-size:12px;
width: 100px;
@ -83,14 +101,50 @@
font-size: 14px;
color: #fff;}
}
.uploadFileFixed {
position: relative;
.uploadFile {
opacity:0;
display: inline-block;
width: 86px;
height: 34px;
position: absolute;
top: 0px;
left: 0px;
}
}
//左侧实景图文件样式
.leftFile {
background-color: rgba(225,225,225,0.8);
}
.leftFile {
background-color: rgba(225,225,225,0.8);
}
//选中图片样式
.selectImg {
-webkit-filter: drop-shadow(0px 0px 5px #000);
filter: drop-shadow(0px 0px 5px #000);
border: 2px solid #00FF00;
}
.selectImg {
-webkit-filter: drop-shadow(0px 0px 5px #000);
filter: drop-shadow(0px 0px 5px #000);
border: 3px dotted red;
}
//旋转角度
.rotateA {transform: rotate(90deg) scale(0.75);}
.rotateB {transform: rotate(180deg)}
.rotateC {transform: rotate(270deg) scale(0.75);}
//预览图片
.previewImgBox {
width: 1500px;
height: 700px;
text-align: center;
img{
width: auto;
height: auto;
max-width: 100%;
height: 100%;}
}
.previewImgBottom {
text-align: center;
height: 30px;
margin: 20px auto;
:first-child {margin-right: 20px;}
}

121
src/app/ui/realistic-picture/realistic-picture.component.ts

@ -1,6 +1,8 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FileUploader, FileItem } from 'ng2-file-upload';
import Swiper from 'swiper';
@ -11,15 +13,24 @@ import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dial
})
export class RealisticPictureComponent implements OnInit {
uploader:FileUploader = new FileUploader({ //初始化上传文件
url: "/api/Objects/PlanPlatform",
method: "POST",
itemAlias: "uploadedfile",
autoUpload: false,
removeAfterUpload:true,
});
constructor(private http:HttpClient,public dialog: MatDialog) { }
ngOnInit(): void {
console.log(sessionStorage.getItem('realName'))
}
allRealPicture:any=[{name:'单位实景图'},{name:'高科技创业园'}]; //所有实景图文件
selectReal:any; //选中的实景图文件
selectRealIndex:any=0; //选中的实景图文件下标
miniImg:'?x-oss-process=image/resize,m_fill,h_100,w_100'; //缩略图片格式
isDownload:boolean = false; //是否批量下载
downloadList:any = []; //选中需要下载的图片
@ -40,8 +51,8 @@ export class RealisticPictureComponent implements OnInit {
} else { //预览图片
let dialogRef = this.dialog.open(previewImg,
{height: '400px',
width:'600px',
{width: '1600px',
height:'900px',
data: {}});
dialogRef.afterClosed().subscribe();
}
@ -66,6 +77,87 @@ export class RealisticPictureComponent implements OnInit {
//上传文件↓
file:any; //上传的文件
objectName:any; //上传对象名
uploadId:any; //上传分块上传事件编号
//change选择文件
uploadFile (e) {
this.file = e.target.files[0] || null //上传的文件
this.startUploading()
}
//上传文件
startUploading () {
let file = this.file || null //获取上传的文件
let fileSize = file.size || null //上传文件的总大小
let shardSize = 5 * 1024 * 1024 //5MB一个分片
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);
console.log(tempRes)
}else { // 上传文件后获取服务器返回的数据错误
let tempRes = JSON.parse(response);
console.log(tempRes)
}};
} else if (file && fileSize>shardSize) { //上传文件>5MB时,分块上传
let data = {filename: file.name}
this.http.post(`/api/NewMultipartUpload/PlanPlatform/YYY`,{},{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=>{
alert('图片上传成功!')
this.file = null //清空文件
this.PartNumberETag =[] //清空保存返回的信息
})
}
}
@ -82,13 +174,36 @@ export class previewImg {
constructor(private http:HttpClient,public dialog: MatDialog,public dialogRef: MatDialogRef<previewImg>,
@Inject(MAT_DIALOG_DATA) public data) { }
testSwiper: Swiper;
ngOnInit(): void {
}
ngAfterViewInit() {
this.testSwiper = new Swiper('.swiper-container', {
direction: 'horizontal',
loop: false,
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
}
rotationAngle:number=0; //旋转角度
//旋转图片
rotate () {
this.rotationAngle = this.rotationAngle+90
if (this.rotationAngle === 360) {this.rotationAngle = 0}
}
}

Loading…
Cancel
Save