<template>
|
<div class="zt-upload">
|
<!-- 文件上传 -->
|
<el-upload
|
ref="upload"
|
class="upload-input"
|
:action="uploadAction"
|
:data="data"
|
:drag="false"
|
:limit="limit"
|
list-type="text"
|
:multiple="multiple"
|
:auto-upload="true"
|
:before-upload="handleBeforeUpload"
|
:http-request="checkedFile"
|
:before-remove="removeFile"
|
:on-exceed="handleExceed"
|
:show-file-list="false"
|
:file-list="fileList"
|
v-if="!image && !crop"
|
>
|
<!-- <el-upload-->
|
<!-- ref="upload"-->
|
<!-- class="upload-input"-->
|
<!-- :class="{hide: uploadDisabled || !isShowUpload}"-->
|
<!-- :accept="accept"-->
|
<!-- :action="uploadAction"-->
|
<!-- :before-upload="handleBeforeUpload"-->
|
<!-- :data="data"-->
|
<!-- :disabled="uploading"-->
|
<!-- :drag="false"-->
|
<!-- :limit="limit"-->
|
<!-- list-type="text"-->
|
<!-- :multiple="multiple"-->
|
<!-- :name="name"-->
|
<!-- :on-change="handleChange"-->
|
<!-- :on-error="handleUploadError"-->
|
<!-- :on-exceed="handleExceed"-->
|
<!-- :on-success="handleUploadSuccess"-->
|
<!-- :on-progress="onUploadProgress"-->
|
<!-- :show-file-list="false"-->
|
<!-- :file-list="fileList"-->
|
<!-- v-if="!image && !crop"-->
|
<!-- :auto-upload="true"-->
|
<!-- :http-request="checkedFile"-->
|
<!-- :before-remove="removeFile"-->
|
<!-- >-->
|
<div style="display:inline-block;width:600px;text-align: center" v-if="onlyUploadFile" class="el-upload__tip">
|
{{computerFileName}}
|
</div>
|
<el-button slot="trigger" v-if="onlyUploadFile" size="small" type="primary">选取文件</el-button>
|
<el-button type="primary" v-if="onlyUploadFile" size="small" style="margin-left:20px" @click="myCheckedFile">提 交
|
</el-button>
|
<el-button class="upload-btn" size="mini" type="primary" icon="el-icon-upload"
|
v-show="!uploadDisabled && isShowUpload && !onlyUploadFile">{{ buttonText }}
|
</el-button>
|
|
<div slot="tip" class="el-upload__tip" v-show="!uploadDisabled && isShowUpload && tip">{{ tip }}</div>
|
</el-upload>
|
<br/>
|
<div v-show="progressFlag">
|
<el-progress :text-inside="true" :stroke-width="30" :percentage="progressPercent" :format="format"></el-progress>
|
</div>
|
|
<ul class="el-upload-list el-upload-list--text" v-if="!image && !crop && !onlyUploadFile">
|
<li tabindex="0" class="el-upload-list__item is-success" v-for="(file, index) in uploadList" :key="file.id">
|
<a class="el-upload-list__item-name" :href="file.url" target="_blank"><i
|
class="el-icon-document"></i>{{ file.name }}</a>
|
<label class="el-upload-list__item-status-label">
|
<i class="el-icon-upload-success el-icon-circle-check"></i>
|
</label>
|
<i class="el-icon-close" @click.stop="handleRemove(index)" v-show="!uploadDisabled"></i>
|
</li>
|
</ul>
|
|
<!-- 图片列表 -->
|
<ele-gallery
|
:lazy="lazy"
|
:remove-fn="handleRemove"
|
:size="size"
|
:sliceSingle="true"
|
:source="galleryValues"
|
:thumbSuffix="thumbSuffix"
|
:title="title"
|
v-if="image && !crop"
|
>
|
<template slot="uploader">
|
<!-- 上传组件 -->
|
<el-upload
|
ref="upload"
|
:accept="accept"
|
:action="uploadAction"
|
:before-upload="handleBeforeUpload"
|
:data="data"
|
:disabled="uploading"
|
:drag="Boolean(drag)"
|
:limit="limit"
|
:list-type="drag ? 'picture' : 'picture-card'"
|
:multiple="multiple"
|
:name="name"
|
:on-change="handleChange"
|
:on-error="handleUploadError"
|
:on-exceed="handleExceed"
|
:on-success="handleUploadSuccess"
|
:show-file-list="false"
|
:file-list="fileList"
|
v-show="!uploadDisabled && isShowUpload"
|
>
|
<div v-loading="uploading">
|
<!-- drag显示 -->
|
<template v-if="drag">
|
<i class="el-icon-upload"></i>
|
<div class="el-upload__text">
|
将文件拖到此处,或
|
<em>点击上传</em>
|
</div>
|
</template>
|
|
<!-- 非drag -->
|
<template v-else>
|
<div :style="{ width: size + 'px', height: size + 'px', lineHeight: size + 'px' }">
|
<i class="el-icon-plus"></i>
|
</div>
|
</template>
|
</div>
|
|
<!-- 公共 -->
|
<div
|
class="el-upload__tip"
|
slot="tip"
|
v-if="showTip"
|
>
|
请上传
|
<b style="color: #F56C6C">{{ fileType.length ? fileType.join('/') : '图片' }}</b>
|
格式文件
|
<template v-if="fileSize">
|
,且大小不超过
|
<b style="color: #F56C6C">{{ fileSize }}MB</b>
|
</template>
|
</div>
|
</el-upload>
|
</template>
|
</ele-gallery>
|
|
<!-- 图片裁剪 -->
|
<div v-if="crop">
|
<div
|
:style="{ width: size + 'px', height: size + 'px', lineHeight: size + 'px' }"
|
@click="isShowCrop = true"
|
class="el-upload el-upload--picture-card"
|
style="margin-bottom: 20px;"
|
v-show="!uploadDisabled && isShowUpload"
|
>
|
<i class="el-icon-plus avatar-uploader-icon"></i>
|
</div>
|
|
<cropper
|
ref="cropper"
|
:field="name"
|
:width="cropWidth"
|
:height="cropHeight"
|
:noCircle="cropHeight !== cropWidth"
|
:params="data"
|
:url="uploadAction"
|
@crop-success="handleCropSuccess"
|
@crop-upload-fail="handleCropUploadError"
|
@crop-upload-success="handleCropUploadSuccess"
|
@src-file-set="handleSetFileSet"
|
class="zt-upload-image--cropper"
|
img-format="png"
|
v-if="isShowCrop"
|
v-model="isShowCrop"
|
></cropper>
|
|
<ele-gallery
|
:lazy="lazy"
|
:remove-fn="handleRemove"
|
:size="size"
|
:sliceSingle="true"
|
:source="galleryValues"
|
:thumbSuffix="thumbSuffix"
|
:title="title"
|
:disabled="uploadDisabled"
|
v-show="isShowGrllery"
|
/>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import Cookies from 'js-cookie'
|
import Cropper from 'vue-image-crop-upload'
|
import EleGallery from '../../vue-ele-gallery'
|
import SparkMD5 from "spark-md5";
|
import axios from "axios";
|
import {getUUID} from "../../../utils";
|
|
export default {
|
name: 'ZtUploader',
|
props: {
|
// 值
|
value: {
|
type: [Object, Array],
|
default() {
|
return this.multiple ? [] : null
|
}
|
},
|
dataForm: Object,
|
action: {
|
type: String,
|
default: '/sys/oss/uploadNew'
|
},
|
// 是否为图片
|
showFileList: {
|
type: Boolean,
|
default: true
|
},
|
onlyUploadFile: {
|
type: Boolean,
|
default: false
|
},
|
// 是否为图片
|
image: {
|
type: Boolean,
|
default: false
|
},
|
// 是否剪裁
|
crop: {
|
type: Boolean,
|
default: false
|
},
|
// 裁剪高度
|
cropHeight: {
|
type: Number
|
},
|
// 裁剪宽度
|
cropWidth: {
|
type: Number
|
},
|
// 是否启用拖拽上传
|
drag: {
|
type: Boolean,
|
default: false
|
},
|
// 是否支持多选文件
|
multiple: {
|
type: Boolean,
|
default: false
|
},
|
// 图片显示大小
|
size: {
|
type: Number,
|
default: 100
|
},
|
// 大小限制(MB)
|
fileSize: {
|
type: Number
|
},
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
fileType: {
|
type: Array,
|
default: () => []
|
},
|
// 缩略图后缀, 例如七牛云缩略图样式 (?imageView2/1/w/20/h/20)
|
thumbSuffix: {
|
type: String,
|
default: ''
|
},
|
// 是否显示提示
|
isShowTip: {
|
type: Boolean,
|
default: true
|
},
|
// 弹窗标题
|
title: String,
|
// 图片懒加载
|
lazy: {
|
type: Boolean,
|
default: false
|
},
|
// 文件个数显示
|
limit: {
|
type: Number,
|
default: 10
|
},
|
// 上传时附带的额外参数
|
data: Object,
|
// 上传的文件字段名
|
name: {
|
type: String,
|
default: 'file'
|
},
|
// 接受上传的文件类型(thumbnail-mode 模式下此参数无效)
|
accept: String,
|
buttonText: {
|
type: String,
|
default: '上传'
|
},
|
tip: String,
|
disabled: {
|
type: Boolean,
|
default: false
|
}
|
},
|
components: {
|
Cropper,
|
EleGallery
|
},
|
inject: {
|
elForm: {
|
default: ''
|
}
|
},
|
data() {
|
return {
|
isUpload: false,
|
maxSize: 50 * 1024 * 1024 * 1024, // 上传最大文件限制 最小单位是b
|
multiUploadSize: 10 * 1024 * 1024, // 大于这个大小的文件使用分块上传(后端可以支持断点续传) 100mb
|
eachSize: 10 * 1024 * 1024, // 每块文件大小 100mb
|
requestCancelQueue: [], // 请求方法队列(调用取消上传
|
// 每上传一块的进度
|
eachProgress: 0,
|
// 总共有多少块。断点续传使用
|
chunksKeep: 0,
|
// 切割后的文件数组
|
fileChunksKeep: [],
|
// 这个文件,断点续传
|
fileKeep: null,
|
// 断点续传,文件md5
|
fileMd5Keep: "",
|
progressPercent: 0,
|
uploadAction: `${window.SITE_CONFIG['apiURL']}/sys/oss/upload_chunk?token=${Cookies.get('token')}`,
|
uploadCheckAction: `${window.SITE_CONFIG['apiURL']}/sys/oss/upload_success?token=${Cookies.get('token')}`,
|
uploadProcessAction: `${window.SITE_CONFIG['apiURL']}${this.action}?token=${Cookies.get('token')}`,
|
cropData: {},
|
isShowCrop: false,
|
uploading: false,
|
fileList: this.getUploadList(this.value),
|
uploadList: this.getUploadList(this.value),
|
progressFlag: false
|
}
|
},
|
created() {
|
if (this.onlyUploadFile) {
|
this.fileList = [{id: '1', name: '', url: ''}]
|
} else {
|
this.fileList = []
|
}
|
},
|
computed: {
|
// 是否显示提示
|
showTip() {
|
return this.isShowTip && (this.fileType.length || this.fileSize)
|
},
|
computerFileName(computerFileName) {
|
let fileName = 'aaaa'
|
if (this.fileList.length > 0) {
|
fileName = this.fileList[0].name
|
}
|
return fileName
|
},
|
galleryValues() {
|
let urls = []
|
if (this.value) {
|
if (this.multiple) {
|
this.value.forEach(v => urls.push({
|
src: v.url,
|
title: v.name
|
}))
|
} else {
|
urls.push({
|
src: this.value.url,
|
title: this.value.name
|
})
|
}
|
}
|
return urls
|
},
|
isShowUpload() { // 是否显示上传按钮
|
if (this.multiple) {
|
return this.uploadList.length < this.limit
|
} else {
|
return this.uploadList.length === 0 || this.onlyUploadFile
|
}
|
},
|
uploadDisabled() {
|
return this.disabled || (this.elForm || {}).disabled
|
},
|
successFiles() {
|
return this.uploadList.filter((file) => file.status === 'success')
|
},
|
isShowGrllery() {
|
return this.galleryValues.length > 0
|
}
|
},
|
watch: {
|
// eslint-disable-next-line no-unused-vars
|
value(val, oldval) {
|
if (this.uploadList !== val) {
|
this.uploadList = this.getUploadList(val)
|
this.fileList = this.getUploadList(val)
|
if (this.fileList.length>0){
|
console.log(this.fileList[0].status, 'val.files[0].status23')
|
// alert('2222'+this.fileList[0].status)
|
}
|
}
|
},
|
isShowCrop(value) {
|
if (value === false) {
|
this.cropData = {}
|
}
|
}
|
},
|
methods: {
|
format(percentage) {
|
return percentage === 100 ? '后台正在处理' : percentage === 99 ? '正在进行文件校验' : `已上传${percentage}%`;
|
},
|
// 获取已上传的文件列表
|
getUploadList(val) {
|
if (val) {
|
if (val.length > 0) {
|
if (!this.multiple) { // 单选
|
console.log(val, 'getUploadList val')
|
return val
|
} else {
|
console.log([...val], 'getUploadList [...val]')
|
return [...val]
|
}
|
} else {
|
return []
|
}
|
}
|
},
|
// eslint-disable-next-line no-unused-vars
|
onUploadProgress(event, file, fileList) {
|
this.progressFlag = true
|
/*let per = Number(
|
((event.loaded / event.total) * 100).toFixed(2)
|
)
|
this.progressPercent = per > 100 ? 100 : per*/
|
},
|
handleSetFileSet(fileName, fileType, fileSize) {
|
const uid = this.cropData.uid || new Date().getTime()
|
this.cropData = {
|
name: fileName,
|
percentage: 0,
|
size: fileSize,
|
type: fileType,
|
status: 'ready',
|
uid: uid
|
}
|
},
|
handleCropSuccess(b64Data) {
|
this.cropData.url = b64Data
|
},
|
handleCropUploadError(status) {
|
this.$message.error('上传失败, 请重试')
|
this.$emit('error', status)
|
},
|
handleCropUploadSuccess(response) {
|
console.log(response, 'handleCropUploadSuccess response')
|
this.cropData.status = 'success'
|
this.cropData.percentage = 100
|
this.cropData.response = response
|
const file = Object.assign({}, this.cropData)
|
this.handleUploadSuccess(response, file)
|
},
|
// 上传前校检格式和大小
|
handleBeforeUpload(file) {
|
let isAccept = true
|
if (this.fileType.length) { // 文件类型(后缀)一致
|
let fileExtension = ''
|
if (file.name.lastIndexOf('.') > -1) {
|
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
}
|
isAccept = this.fileType.some((type) => {
|
if (file.type.indexOf(type) > -1) return true
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
return false
|
})
|
}
|
if (!isAccept) {
|
this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`)
|
return false
|
}
|
if (this.fileSize) {
|
const isLt = file.size / 1024 / 1024 < this.fileSize
|
if (!isLt) {
|
this.$message.error(`上传大小不能超过 ${this.fileSize} MB!`)
|
return false
|
}
|
}
|
if (this.dataForm) {
|
// eslint-disable-next-line vue/no-mutating-props
|
this.dataForm.hasUploadFinsh = 50
|
}
|
this.uploading = true
|
return true
|
},
|
async handleChange() {
|
this.uploading = false
|
/*const config = {
|
onUploadProgress: (progressEvent) => {
|
this.progressPercent = Number(
|
((progressEvent.loaded / progressEvent.total) * 90).toFixed(2)
|
)
|
}
|
}
|
//this.progressFlag = true;
|
let form = new FormData();
|
form.append("file", params.file);
|
this.$http.post( this.uploadAction,form,config ).then((res) => {
|
this.progressPercent = 100;
|
})*/
|
},
|
// 文件个数超出
|
handleExceed(files, fileList) {
|
if (this.onlyUploadFile) {
|
this.$set(fileList[0], 'raw', files[0])
|
this.$set(fileList[0], 'name', files[0].name)
|
/* this.$refs.upload.clearFiles()
|
this.$refs.upload.handleStart(files[0])*/
|
}
|
//this.$message.error(`最多上传${this.limit}个`)
|
},
|
// 上传失败
|
handleUploadError(err) {
|
this.uploading = false
|
this.$message.error('上传失败, 请重试')
|
this.$emit('error', err)
|
},
|
// 上传成功回调
|
// eslint-disable-next-line no-unused-vars
|
handleUploadSuccess(response, file) {
|
console.log(response, 'handleUploadSuccess response')
|
if (response.code === 0) {
|
this.progressPercent = 100
|
this.uploading = false
|
// this.$message.success('上传成功')
|
if (this.multiple) {
|
this.uploadList.push(response.data)
|
this.$emit('input', this.uploadList)
|
} else {
|
this.$emit('input', response.data)
|
}
|
this.progressFlag = false
|
this.progressPercent = 0
|
}
|
},
|
async handleRemove(index) {
|
let file = this.uploadList[index]
|
if (file.status === 1) { // 证书文件,直接从列表删除,不保存数据库
|
this.handRemoveAndSetValue(index)
|
} else {
|
if (await this.$tip.confirm(this.$t('prompt.info', {'handle': this.$t('delete')}))) {
|
let res = await this.$http.delete('/sys/oss', {'data': [file.id]})
|
if (res.success) {
|
await this.$tip.success()
|
this.handRemoveAndSetValue(index)
|
}
|
}
|
}
|
},
|
handRemoveAndSetValue(index) {
|
console.log(index, 'handRemoveAndSetValue')
|
if (this.multiple) {
|
this.uploadList.splice(index, 1)
|
this.$refs.upload.uploadFiles.splice(index, 1)
|
this.$emit('input', this.uploadList || [])
|
} else {
|
this.$emit('input', null)
|
}
|
},
|
nullFunction(param) {
|
},
|
//开始分片上传myCheckedFile
|
async myCheckedFile() {
|
if (!this.handleBeforeUpload(this.fileList[0].raw))
|
return
|
let options = {
|
file: this.fileList[0].raw,
|
onProgress: function (val) {
|
},
|
onSuccess: function (val) {
|
},
|
onError: function (val) {
|
}
|
}
|
await this.checkedFile(options)
|
},
|
async checkedFile(options) {
|
if (!this.isUpload) {
|
this.isUpload = true;
|
} else {
|
return this.$message({
|
message: `当前文件正在上传`,
|
type: "warning"
|
});
|
}
|
this.progressFlag = true
|
const {
|
maxSize,
|
multiUploadSize,
|
getSize,
|
splitUpload,
|
singleUpload
|
} = this; // 解构赋值
|
const {file, onProgress, onSuccess, onError} = options; // 解构赋值
|
|
file.uid = getUUID().toString()
|
if (file.size > maxSize) {
|
return this.$message({
|
message: `您选择的文件大于${getSize(maxSize)}`,
|
type: "error"
|
});
|
}
|
this.fileKeep = file;
|
const uploadFunc =
|
file.size > multiUploadSize ? splitUpload : singleUpload; // 选择上传方式
|
try {
|
await uploadFunc(file, onProgress);
|
onSuccess();
|
} catch (e) {
|
console.error(e);
|
this.$message({
|
message: e.message,
|
type: "error"
|
});
|
this.progressFlag = false;
|
this.progressPercent = 0;
|
onError();
|
}
|
},
|
// 格式化文件大小显示文字
|
getSize(size) {
|
return size > 1024
|
? size / 1024 > 1024
|
? size / (1024 * 1024) > 1024
|
? (size / (1024 * 1024 * 1024)).toFixed(2) + "GB"
|
: (size / (1024 * 1024)).toFixed(2) + "MB"
|
: (size / 1024).toFixed(2) + "KB"
|
: size.toFixed(2) + "B";
|
},
|
// 单文件直接上传
|
async singleUpload(file, onProgress) {
|
await this.postFile(
|
{file, uid: file.uid, fileName: file.fileName, chunk: 0},
|
onProgress
|
);
|
const reader = new FileReader();
|
|
reader.readAsArrayBuffer(file);
|
console.log(file, 'singleUpload file');
|
let hashMd5 = "";
|
console.log(hashMd5);
|
const that = this;
|
|
function getHash(cb) {
|
console.log(cb, "进入单个上传的getHash");
|
console.log("进入单个上传的getHash");
|
reader.onload = function (e) {
|
console.log("进入单个上传的getHash的函数2");
|
console.log(hashMd5);
|
console.log(this);
|
// console.log(e)
|
const hash = SparkMD5.ArrayBuffer.hash(e.target.result, false);
|
console.log(e.target.result, 'e.target.result');
|
console.log(hash, 'hash');
|
that.hashMd5 = hash;
|
console.log(that.hashMd5, 'hashMd5');
|
that.fileMd5Keep = hash;
|
cb(hash);
|
};
|
}
|
|
await getHash(function (hash) {
|
console.log(hash, 'getHash(function (hash) hash');
|
console.log(that, 'getHash(function (hash) that');
|
// 请求接口
|
that.validateFile({
|
name: file.name,
|
uid: file.uid,
|
md5: hash,
|
chunks: 1,
|
filter_type: "user_data_file"
|
});
|
});
|
},
|
|
// 大文件分块上传
|
splitUpload(file, onProgress) {
|
console.log(file, 'splitUpload(file');
|
// eslint-disable-next-line no-async-promise-executor
|
return new Promise(async (resolve, reject) => {
|
try {
|
const {eachSize} = this;
|
const chunks = Math.ceil(file.size / eachSize);
|
this.chunksKeep = chunks;
|
const fileChunks = await this.splitFile(file, eachSize, chunks);
|
this.fileChunksKeep = fileChunks;
|
//判断每上传一个文件,进度条涨多少,保留两位小数
|
this.eachProgress = 100 / chunks;
|
this.progressFlag = true;
|
let currentChunk = 0;
|
let percent = 0;
|
for (let i = 0; i < fileChunks.length; i++) {
|
// 服务端检测已经上传到第currentChunk块了,那就直接跳到第currentChunk块,实现断点续传
|
// 此时需要判断进度条
|
if (Number(currentChunk) === i) {
|
// 每块上传完后则返回需要提交的下一块的index
|
await this.postFile(
|
{
|
chunked: true,
|
chunk: i,
|
chunks,
|
eachSize,
|
fileName: file.name,
|
fullSize: file.size,
|
uid: file.uid,
|
file: fileChunks[i]
|
},
|
onProgress
|
);
|
currentChunk++;
|
|
// 上传完一块后,进度条增加
|
percent = percent + this.eachProgress;
|
// 不能超过100
|
this.progressPercent = percent > 100 ? 99 : Math.floor(percent);
|
}
|
}
|
const spark = new SparkMD5.ArrayBuffer();
|
let currentChunkMd5 = 0;
|
const that = this;
|
const reader = new FileReader();
|
reader.onload = async function (e) {
|
spark.append(e.target.result);
|
currentChunkMd5++;
|
|
if (currentChunkMd5 < chunks) {
|
await loadNext();
|
} else {
|
// console.log(spark.end());
|
const hashMd5111 = spark.end();
|
that.fileMd5Keep = hashMd5111;
|
// 在这里请求接口
|
await that.validateFile({
|
name: file.name,
|
uid: file.uid,
|
md5: hashMd5111,
|
chunks: fileChunks.length,
|
filter_type: "git_secret_file"
|
});
|
}
|
};
|
|
// eslint-disable-next-line no-inner-declarations
|
async function loadNext() {
|
const start = currentChunkMd5 * eachSize;
|
const end =
|
start + eachSize >= file.size ? file.size : start + eachSize;
|
await reader.readAsArrayBuffer(file.slice(start, end));
|
}
|
|
await loadNext();
|
resolve();
|
} catch (error) {
|
reject(error);
|
}
|
});
|
},
|
// 断点续传
|
againSplitUpload(file, array) {
|
console.log("file,array");
|
console.log(file);
|
console.log(array);
|
// eslint-disable-next-line no-async-promise-executor
|
return new Promise(async (resolve, reject) => {
|
try {
|
// eslint-disable-next-line no-unused-vars
|
const {eachSize, fileKeep} = this;
|
const chunks = this.chunksKeep;
|
const fileChunks = this.fileChunksKeep;
|
this.progressFlag = true;
|
// let currentChunk = 0;
|
for (let i = 0; i < array.length; i++) {
|
// 服务端检测已经上传到第currentChunk块了,那就直接跳到第currentChunk块,实现断点续传
|
// 此时需要判断进度条
|
// 每块上传完后则返回需要提交的下一块的index
|
await this.postFile({
|
chunked: true,
|
chunk: array[i],
|
chunks,
|
name: file.name,
|
fullSize: fileKeep.size,
|
uid: file.uid,
|
file: fileChunks[array[i]]
|
});
|
// currentChunk++
|
|
// 上传完一块后,进度条增加
|
this.progressPercent += this.eachProgress;
|
// 不能超过100
|
this.progressPercent = this.progressPercent > 100 ? 100 : this.progressPercent;
|
}
|
let fileMd5KeepTwo = this.fileMd5Keep;
|
|
const isValidate = await this.validateFile({
|
name: file.name,
|
uid: file.uid,
|
md5: fileMd5KeepTwo,
|
chunks: fileChunks.length,
|
filter_type: "git_secret_file"
|
});
|
if (!isValidate) {
|
throw new Error("文件校验异常");
|
}
|
// 关闭进度条
|
this.progressFlag = false;
|
// 重置进度条
|
this.progressPercent = 0;
|
resolve();
|
} catch (e) {
|
reject(e);
|
}
|
});
|
},
|
// 文件分块,利用Array.prototype.slice方法
|
splitFile(file, eachSize, chunks) {
|
return new Promise((resolve, reject) => {
|
try {
|
setTimeout(() => {
|
const fileChunk = [];
|
for (let chunk = 0; chunks > 0; chunks--) {
|
fileChunk.push(file.slice(chunk, chunk + eachSize));
|
chunk += eachSize;
|
}
|
resolve(fileChunk);
|
}, 0);
|
} catch (e) {
|
console.error(e);
|
reject(new Error("文件切块发生错误"));
|
}
|
});
|
},
|
removeFile(file) {
|
this.requestCancelQueue[file.uid]();
|
delete this.requestCancelQueue[file.uid];
|
return true;
|
},
|
// 提交文件方法,将参数转换为FormData, 然后通过axios发起请求
|
postFile(param, onProgress) {
|
const formData = new FormData();
|
formData.append("file", param.file); // 改了
|
formData.append("fileName", param.fileName); // 改了
|
formData.append("uid", param.uid);
|
formData.append("chunk", param.chunk);
|
formData.append("filter_type", "git_secret_file");
|
formData.append("chunks", param.chunks);
|
const {requestCancelQueue} = this;
|
const config = {
|
cancelToken: new axios.CancelToken(function executor(cancel) {
|
if (requestCancelQueue[param.uid]) {
|
requestCancelQueue[param.uid]();
|
delete requestCancelQueue[param.uid];
|
}
|
requestCancelQueue[param.uid] = cancel;
|
}),
|
onUploadProgress: e => {
|
if (param.chunked) {
|
e.percent = Number(
|
(
|
((param.chunk * (param.eachSize - 1) + e.loaded) /
|
param.fullSize) *
|
100
|
).toFixed(2)
|
);
|
} else {
|
e.percent = Number(((e.loaded / e.total) * 100).toFixed(2));
|
}
|
onProgress(e)
|
}
|
}
|
//return axios.post('sys/oss/upload_chunk/', formData, config).then(rs => rs.data)
|
return this.$http({
|
url: "/sys/oss/upload_chunk/",
|
method: "POST",
|
data: formData
|
}).then(rs => rs.data
|
);
|
},
|
// 文件校验方法
|
validateFile(file) {
|
//return axios.post('sys/oss/upload_success/', file).then(rs => rs.data)
|
return this.$http({
|
url: "/sys/oss/upload_success/",
|
method: "POST",
|
data: file
|
}).then(res => {
|
console.log(res, "validateFile res")
|
if (res && !res.data) {
|
this.againSplitUpload(file, res.data.error_file)
|
this.$message({
|
message: "有文件上传失败,正在重新上传",
|
type: "warning"
|
});
|
} else if (res && res.data) {
|
this.progressPercent = 100
|
if (!this.onlyUploadFile) {
|
this.$http({
|
url: this.action,
|
method: "POST",
|
data: file
|
}).then(res => {
|
console.log(res, '后台处理 res1')
|
let aa = res.data.status
|
console.log(aa, 'res.data.status')
|
|
if (this.multiple) {
|
this.uploadList.push(res.data)
|
this.$emit('input', this.uploadList)
|
} else {
|
this.$emit('input', res.data)
|
}
|
this.uploading = false
|
this.progressFlag = false
|
this.progressPercent = 0
|
this.isUpload = false
|
})
|
} else {
|
console.log(file.uid, 'file.uid')
|
this.$emit('recall', file.uid)
|
this.uploading = false
|
this.progressFlag = false
|
this.progressPercent = 0
|
this.isUpload = false
|
}
|
} else if (res && res.status == 40008) {
|
this.$message.error(res.message);
|
this.progressFlag = false;
|
this.progressPercent = 0;
|
}
|
})
|
}
|
},
|
mounted() {
|
// 插入到body中, 避免弹出层被遮盖
|
if (this.crop && this.$refs.cropper) {
|
document.body.appendChild(this.$refs.cropper.$el)
|
}
|
}
|
}
|
</script>
|
|
<style>
|
.zt-upload {
|
line-height: 1;
|
}
|
|
.zt .upload-input .upload-btn {
|
padding: 8px 12px;
|
}
|
|
.zt .upload-input.hide {
|
height: 0px;
|
}
|
|
.zt-upload .el-loading-spinner {
|
line-height: 1;
|
}
|
|
.zt-upload .el-icon-plus {
|
vertical-align: middle;
|
}
|
|
.zt-upload .el-upload--picture-card {
|
width: auto;
|
height: auto;
|
background: none;
|
line-height: inherit;
|
}
|
|
/* 裁剪 */
|
.vue-image-crop-upload.zt-upload-image--cropper {
|
z-index: 99;
|
}
|
|
.zt-upload-image--cropper .vicp-drop-area {
|
background-color: #fbfdff !important;
|
}
|
|
.zt-upload-image--cropper .vicp-icon1-arrow {
|
border-bottom-color: #909399 !important;
|
}
|
|
.zt-upload-image--cropper .vicp-icon1-body {
|
background-color: #909399 !important;
|
}
|
|
.zt-upload-image--cropper .vicp-icon1-bottom {
|
border-color: #909399 !important;
|
}
|
</style>
|