先贴代码
<template>
<el-row>
<el-col :span="24" p-t-20px>
<el-upload
action
ref="uploadBtn0"
multiple
:limit="3"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:file-list="FileList"
:on-change="handleChange"
:on-remove="handleRemove"
:auto-upload="false"
>
<el-button size="small" type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">只能上传 jpg/png 文件,且不超过 500kb</div>
</template>
</el-upload>
</el-col>
<el-col :span="0" p-t-20px>
<el-button
v-show="true"
style="margin-left: 10px"
size="small"
type="success"
@click="multipartUpload"
ref="uploadBtn"
>上传到服务器</el-button>
<el-button
style="margin-left: 10px"
size="small"
type="success"
@click="resumeUpload"
>继续</el-button>
<el-button
style="margin-left: 10px"
size="small"
type="success"
@click="stopUplosd"
>暂停</el-button>
</el-col>
</el-row>
<el-progress :percentage="percentage" :status="uploadStatus"></el-progress>
</template>
<script setup lang="ts">
import { ref, reactive, inject, onMounted, computed, watch } from 'vue'
import OSS from "ali-oss";
import { post } from "@/js/ajaxFn"
import { ElMessage } from 'element-plus'
const FileList = ref([])
let file = null
const tempCheckpoint = ref(null)
const uploadId = ref('')
const uploadStatus = ref(null)
const percentage = ref(0)
const uploadName = ref('')
const props = defineProps([
"handleExceed",
"handleUploadSuccess",
"fileList",
"prePath",
"fileTypeList",
"fileSize",
])
const uploadBtn0 = ref(null)
const uploadBtn = ref(null)
async function limitFileType(file:any) {
const { fileTypeList } = props
let type = file.name.substring(file.name.lastIndexOf('.') + 1)
if(!fileTypeList) return true
if(fileTypeList.includes(type)) return true
await ElMessage.error(`${type}类型文件禁止上传`)
return false
}
async function limitFileSize(file:any) {
const { fileSize } = props
let size = Number(file.size)
if(!fileSize) return true
if(fileSize > size) return true
let info = fileSize >= 1024 ? `${Number((fileSize / 1024).toFixed())}M` : `${fileSize}KB`
await ElMessage.error(`文件超过了${info}`)
return false
}
async function resumeUpload() {
window.removeEventListener("online", resumeUpload);
if (!tempCheckpoint.value) {
ElMessage.error("请先上传");
return;
}
uploadStatus.value = null;
try {
let result = await client.multipartUpload(file.name, file, {
progress: (p, checkpoint) => {
percentage.value = p * 100;
console.log(
p,
checkpoint,
"checkpoint----恢复上传的切片信息-------"
);
tempCheckpoint.value = checkpoint;
},
checkpoint: tempCheckpoint,
meta: { year: 2022, people: "test" },
});
console.log(result, "result-=-=-恢复上传完毕");
} catch (e) {
console.log(e, "e-=-=-");
}
}
async function abortMultipartUpload() {
window.removeEventListener("online", resumeUpload);
const name = uploadName;
const result = await client.abortMultipartUpload(name, uploadId.value);
console.log(result, "=======清除切片====");
}
function stopUplosd() {
window.removeEventListener("online", resumeUpload);
let result = client.cancel();
console.log(result, "---------暂停上传-----------");
}
async function multipartUpload() {
if (!props.prePath) {
ElMessage.error("请选择作品要求");
return;
}
if (!file) {
ElMessage.error("请选择文件");
return;
}
if(!(await limitFileType(file))) return
if(!(await limitFileSize(file))) return
uploadStatus.value = null;
percentage.value = 0;
try {
const fullPath = props.prePath + file.name
let result = await client
.multipartUpload(fullPath, file, {
headers: {
"Content-Disposition": "inline",
},
progress: (p, checkpoint) => {
tempCheckpoint.value = checkpoint;
uploadId.value = checkpoint && checkpoint.uploadId;
uploadName.value = checkpoint && checkpoint.name;
percentage.value = (p * 100).toFixed(2);
console.log(
p,
checkpoint,
percentage,
"---------uploadId-----------"
);
},
})
.then((res:any) => {
props.handleUploadSuccess(res)
console.log(res, "完成了");
},
(err:any) => {
console.log(err, '错误原因');
}
);
console.log(result, percentage, "result= 切片上传完毕=");
} catch (e) {
console.log(e, '这里是发生了错误');
window.addEventListener("online", resumeUpload);
if (e.code === "ConnectionTimeoutError") {
uploadStatus.value = "exception";
console.log("TimeoutError");
}
}
}
function handleChange(theFile, FileList) {
FileList = FileList.filter((row) => row.uid == theFile.uid);
file = theFile.raw;
console.log(file, FileList);
uploadBtn.value.$el.click();
}
function handleRemove(file, FileList) {
percentage.value = 0;
FileList = [];
}
let client;
function initOss() {
let params = {};
let token = localStorage.getItem("mytoken");
post("/ajax/public/oss/get_sts_token", params, (res) => {
const { AccessKeyId, AccessKeySecret, Expiration, SecurityToken } = res;
client = new OSS({
region: "oss-cn-shanghai",
accessKeyId: AccessKeyId,
accessKeySecret: AccessKeySecret,
stsToken: SecurityToken,
bucket: "pro-dsbactc-prod-10001-oss",
Expiration: Expiration,
secure: true,
});
});
}
initOss();
</script>
<script lang="ts">
export default {
data() {
return {
};
},
methods: {
},
};
</script>
第一步是初始化oss
- 这里采用的是SDK的方式,
npm i ali-oss, 然后去初始化
function initOss() {
let params = {};
let token = localStorage.getItem("mytoken");
post("/ajax/public/oss/get_sts_token", params, (res) => {
const { AccessKeyId, AccessKeySecret, Expiration, SecurityToken } = res;
client = new OSS({
region: "oss-cn-shanghai",
accessKeyId: AccessKeyId,
accessKeySecret: AccessKeySecret,
stsToken: SecurityToken,
bucket: "pro-dsbactc-prod-10001-oss",
Expiration: Expiration,
secure: true,
});
});
}
第二步是去调用上传的方法
- 上传分成两种方式,一种是简单上传,这种的话,就不能够去查看上传进度
- 第二种的话是切片上传,这种的话,就可以拿到当前的上传进度,来用进度条了
try {
const fullPath = props.prePath + file.name
let result = await client
.multipartUpload(fullPath, file, {
headers: {
"Content-Disposition": "inline",
},
progress: (p, checkpoint) => {
tempCheckpoint.value = checkpoint;
uploadId.value = checkpoint && checkpoint.uploadId;
uploadName.value = checkpoint && checkpoint.name;
percentage.value = (p * 100).toFixed(2);
console.log(
p,
checkpoint,
percentage,
"---------uploadId-----------"
);
},
})
.then((res:any) => {
props.handleUploadSuccess(res)
console.log(res, "完成了");
},
(err:any) => {
console.log(err, '错误原因');
}
);
console.log(result, percentage, "result= 切片上传完毕=");
} catch (e) {
console.log(e, '这里是发生了错误');
window.addEventListener("online", resumeUpload);
if (e.code === "ConnectionTimeoutError") {
uploadStatus.value = "exception";
console.log("TimeoutError");
}
}