|
@@ -1,43 +1,47 @@
|
|
|
<template>
|
|
|
- <el-upload ref="uploadRef" class="hc-file-upload-box" :headers="getTokenHeader()" :data="uploadData" :disabled="uploadDisabled" multiple :limit="limit" :show-file-list="false" :http-request="uploadFileHandle"
|
|
|
- :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload" :on-progress="uploadprogress">
|
|
|
- <slot></slot>
|
|
|
+ <el-upload
|
|
|
+ ref="uploadRef" class="hc-file-upload-box" :headers="getHeader()" :data="uploadData" :disabled="uploadDisabled" multiple :limit="limit" :show-file-list="false" :http-request="uploadFileHandle"
|
|
|
+ :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload" :on-progress="uploadprogress"
|
|
|
+ >
|
|
|
+ <slot />
|
|
|
</el-upload>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import {ref,watch,onMounted} from "vue";
|
|
|
-import {getTokenHeader} from '~src/api/request/header';
|
|
|
-import {isFileSize, deepClone, getObjValue} from "js-fast-way"
|
|
|
+import { onMounted, ref, watch } from 'vue'
|
|
|
+import { getHeader } from 'hc-vue3-ui'
|
|
|
+import { deepClone, getObjValue, isFileSize } from 'js-fast-way'
|
|
|
import md5 from 'js-md5' //引入MD5加密
|
|
|
-import ossApi from "~api/oss";
|
|
|
+import ossApi from '~api/oss'
|
|
|
const props = defineProps({
|
|
|
datas: {
|
|
|
type: Object,
|
|
|
- default: () => ({})
|
|
|
+ default: () => ({}),
|
|
|
},
|
|
|
api: {
|
|
|
type: String,
|
|
|
- default: "/api/blade-resource/oss/endpoint/"
|
|
|
+ default: '/api/blade-resource/oss/endpoint/',
|
|
|
},
|
|
|
action: {
|
|
|
type: String,
|
|
|
- default: "upload-file2"
|
|
|
+ default: 'upload-file2',
|
|
|
},
|
|
|
accept: {
|
|
|
type: String,
|
|
|
- default: "image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword"
|
|
|
+ default: 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword',
|
|
|
},
|
|
|
size: {
|
|
|
type: Number,
|
|
|
- default: 60
|
|
|
+ default: 60,
|
|
|
},
|
|
|
limit: {
|
|
|
type: Number,
|
|
|
- default: 10
|
|
|
- }
|
|
|
+ default: 10,
|
|
|
+ },
|
|
|
})
|
|
|
|
|
|
+//事件
|
|
|
+const emit = defineEmits(['change', 'progress'])
|
|
|
//变量
|
|
|
const uploadRef = ref(null)
|
|
|
const uploadData = ref(props.datas)
|
|
@@ -57,20 +61,17 @@ onMounted(()=> {
|
|
|
errorFileNum.value = 0
|
|
|
})
|
|
|
|
|
|
-//事件
|
|
|
-const emit = defineEmits(['change', 'progress'])
|
|
|
-
|
|
|
//上传前
|
|
|
const beforeFileNum = ref(0)
|
|
|
const beforeUpload = async (file) => {
|
|
|
- beforeFileNum.value ++;
|
|
|
- return true;
|
|
|
+ beforeFileNum.value ++
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
//超出限制时
|
|
|
const uploadExceed = () => {
|
|
|
//window?.$message?.warning(`请上传 ${props.accept} 格式的文件,文件大小不超过${props.size}M`);
|
|
|
- window?.$message?.warning(`每次请不超过 ${props.limit} 个文件同时上传`);
|
|
|
+ window?.$message?.warning(`每次请不超过 ${props.limit} 个文件同时上传`)
|
|
|
}
|
|
|
|
|
|
//上传中
|
|
@@ -85,26 +86,26 @@ const uploadSuccess = (response, uploadFile, uploadFiles) => {
|
|
|
//console.log(response)
|
|
|
//console.log(uploadFile)
|
|
|
//console.log(uploadFiles)
|
|
|
- finishFileNum.value ++;
|
|
|
+ finishFileNum.value ++
|
|
|
if (beforeFileNum.value === finishFileNum.value) {
|
|
|
const fileList = getUploadFile(deepClone(uploadFiles))
|
|
|
uploadClearFiles()
|
|
|
- emit('change', {type: 'success', fileList})
|
|
|
+ emit('change', { type: 'success', fileList })
|
|
|
emit('progress', false)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//上传失败
|
|
|
const errorFileNum = ref(0)
|
|
|
-const uploadError = (error,uploadFile,uploadFiles) => {
|
|
|
- errorFileNum.value ++;
|
|
|
- window?.$message?.error('上传失败');
|
|
|
+const uploadError = (error, uploadFile, uploadFiles) => {
|
|
|
+ errorFileNum.value ++
|
|
|
+ window?.$message?.error('上传失败')
|
|
|
console.log(error)
|
|
|
- const num = finishFileNum.value + errorFileNum.value;
|
|
|
+ const num = finishFileNum.value + errorFileNum.value
|
|
|
if (beforeFileNum.value === num) {
|
|
|
const fileList = getUploadFile(deepClone(uploadFiles))
|
|
|
uploadClearFiles()
|
|
|
- emit('change', {type: 'error', fileList})
|
|
|
+ emit('change', { type: 'error', fileList })
|
|
|
emit('progress', false)
|
|
|
}
|
|
|
}
|
|
@@ -119,7 +120,7 @@ const uploadClearFiles = () => {
|
|
|
|
|
|
//获取文件
|
|
|
const getUploadFile = (fileList) => {
|
|
|
- let fileArr = [];
|
|
|
+ let fileArr = []
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
|
const item = getObjValue(fileList[i]?.response?.data)
|
|
|
fileArr.push(item)
|
|
@@ -147,7 +148,7 @@ const uploadFileHandle = (options) =>{
|
|
|
concurrent = 3,
|
|
|
onSuccess:success,
|
|
|
onProgress:process,
|
|
|
- onError:error
|
|
|
+ onError:error,
|
|
|
}) => {
|
|
|
// 如果文件传入为空直接 return 返回
|
|
|
if (!file || file.length < 1) {
|
|
@@ -216,7 +217,7 @@ const uploadFileHandle = (options) =>{
|
|
|
return {
|
|
|
start,
|
|
|
end,
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
}
|
|
|
}
|
|
|
/***
|
|
@@ -226,7 +227,7 @@ const uploadFileHandle = (options) =>{
|
|
|
// 针对单个文件进行chunk上传
|
|
|
for (var i = 0; i < chunkCount; i++) {
|
|
|
const {
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
} = getChunkInfo(file, i, chunkSize)
|
|
|
|
|
|
// 判断已经上传的分片中是否包含当前分片
|
|
@@ -234,7 +235,7 @@ const uploadFileHandle = (options) =>{
|
|
|
uploadChunk({
|
|
|
chunk,
|
|
|
currentChunk: i,
|
|
|
- chunkCount
|
|
|
+ chunkCount,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
@@ -250,12 +251,12 @@ const uploadFileHandle = (options) =>{
|
|
|
let inde = chunkInfo.currentChunk + 1
|
|
|
if (uploaded.indexOf(inde + '') > -1) {
|
|
|
const {
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
} = getChunkInfo(file, chunkInfo.currentChunk + 1, chunkSize)
|
|
|
uploadChunk({
|
|
|
chunk,
|
|
|
currentChunk: inde,
|
|
|
- chunkCount
|
|
|
+ chunkCount,
|
|
|
})
|
|
|
} else {
|
|
|
var index = file.name.lastIndexOf('.')
|
|
@@ -278,8 +279,8 @@ const uploadFileHandle = (options) =>{
|
|
|
let config = {
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json',
|
|
|
- 'Accept': '*/*'
|
|
|
- }
|
|
|
+ 'Accept': '*/*',
|
|
|
+ },
|
|
|
}
|
|
|
|
|
|
ossApi.uploadChunk(fetchForm, config).then(res => {
|
|
@@ -294,12 +295,12 @@ const uploadFileHandle = (options) =>{
|
|
|
process(100)
|
|
|
} else {
|
|
|
const {
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
} = getChunkInfo(file, chunkInfo.currentChunk + 1, chunkSize)
|
|
|
uploadChunk({
|
|
|
chunk,
|
|
|
currentChunk: chunkInfo.currentChunk + 1,
|
|
|
- chunkCount
|
|
|
+ chunkCount,
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -322,12 +323,12 @@ const uploadFileHandle = (options) =>{
|
|
|
**/
|
|
|
const sequentialUplode = (currentChunk) => {
|
|
|
const {
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
} = getChunkInfo(file, currentChunk, chunkSize)
|
|
|
let chunkInfo = {
|
|
|
chunk,
|
|
|
currentChunk,
|
|
|
- chunkCount
|
|
|
+ chunkCount,
|
|
|
}
|
|
|
var sd = parseInt((chunkInfo.currentChunk / chunkInfo.chunkCount) * 100)
|
|
|
process(sd)
|
|
@@ -341,8 +342,8 @@ const uploadFileHandle = (options) =>{
|
|
|
let config = {
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json',
|
|
|
- 'Accept': '*/*'
|
|
|
- }
|
|
|
+ 'Accept': '*/*',
|
|
|
+ },
|
|
|
}
|
|
|
// 执行分片上传
|
|
|
ossApi.uploadChunk(uploadData, config).then(res => {
|
|
@@ -378,12 +379,12 @@ const uploadFileHandle = (options) =>{
|
|
|
concurrentExecution(chunkList, concurrent, (curItem) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
const {
|
|
|
- chunk
|
|
|
+ chunk,
|
|
|
} = getChunkInfo(file, curItem, chunkSize)
|
|
|
let chunkInfo = {
|
|
|
chunk,
|
|
|
currentChunk: curItem,
|
|
|
- chunkCount
|
|
|
+ chunkCount,
|
|
|
}
|
|
|
var sd = parseInt((chunkInfo.currentChunk / chunkInfo.chunkCount) * 100)
|
|
|
process(sd)
|
|
@@ -396,8 +397,8 @@ const uploadFileHandle = (options) =>{
|
|
|
let config = {
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json',
|
|
|
- 'Accept': '*/*'
|
|
|
- }
|
|
|
+ 'Accept': '*/*',
|
|
|
+ },
|
|
|
}
|
|
|
ossApi.uploadChunk(uploadData, config).then(res => {
|
|
|
if (res.code == 200) {
|
|
@@ -408,7 +409,7 @@ const uploadFileHandle = (options) =>{
|
|
|
// success(res)
|
|
|
// process(100)
|
|
|
// }
|
|
|
- if(typeof res.data == 'object'){
|
|
|
+ if (typeof res.data == 'object') {
|
|
|
success(res)
|
|
|
process(100)
|
|
|
}
|
|
@@ -463,7 +464,7 @@ const uploadFileHandle = (options) =>{
|
|
|
* @params asyncHandle {Function} - 对`list`的每一个项的处理函数,参数为当前处理项,必须 return 一个Promise来确定是否继续进行迭代
|
|
|
* @return {Promise} - 返回一个 Promise 值来确认所有数据是否迭代完成
|
|
|
*/
|
|
|
-const concurrentExecution = (list, limit, asyncHandle)=>{
|
|
|
+const concurrentExecution = (list, limit, asyncHandle)=>{
|
|
|
// 递归执行
|
|
|
let recursion = (arr) => {
|
|
|
// 执行方法 arr.shift() 取出并移除第一个数据
|
|
@@ -488,7 +489,6 @@ const concurrentExecution = (list, limit, asyncHandle)=>{
|
|
|
// 所有并发异步操作都完成后,本次并发控制迭代完成
|
|
|
return Promise.all(asyncList)
|
|
|
}
|
|
|
-
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|