import { getPolicy } from “这个接口让后端给 获取oss各种信息的”;
import { ElLoading } from “element-plus”;
function useOssUpload() {
const aliOssUpload = async (fileName, file, bucket) => {
const { data } = await getPolicy({ bucket });
// 创建 FormData 对象来构建 POST 请求的 Body
const formData = new FormData();
formData.append(‘key’, `${data.dir}${fileName}`); // 根据实际情况调整 key 的格式
formData.append(‘policy’, data.policy);
formData.append(‘OSSAccessKeyId’, data.accessid);
formData.append(‘success_action_status’, ‘200’); // 设置成功状态码
formData.append(‘signature’, data.signature);
formData.append(‘file’, file); // 实际要上传的文件
const loadingInstance = ElLoading.service({
fullscreen: true,
lock: true,
text: “正在上传中,请耐心稍等”
});
// 发起上传请求
try {
const response = await fetch(data.host, {
method: ‘POST’,
body: formData,
});
loadingInstance.close()
if (response.ok) {
const url = `${data.host}/${data.dir}${fileName}`;
console.log(‘Upload success’, url);
return url; // 返回文件的 URL
} else {
throw new Error(‘Upload failed’);
}
} catch (error) {
loadingInstance.close()
}
};
return {
aliOssUpload
};
}
export default useOssUpload;
///////////////////////////////////////////////////////////useOssUploadAll.ts///////////////////////////////////////////////////////////////////////////////
<template>
<el-upload
ref=”uploadRef”
:auto-upload=”autoUpload”
:http-request=”uploadFile”
:before-upload=”handleBeforeUpload”
:on-success=”handleSuccess”
:show-file-list=”false”
:multiple=”multiple”
>
<template #trigger>
<el-button>
<span>{{ buttonText }}</span>
</el-button>
</template>
</el-upload>
</template>
<script setup>
import { ref, defineProps } from “vue”;
import useOssUpload from “@/utils/useOssUploadAll”;
import { getUrl } from “@/api/modules/upload”; //这个接口让后端给 获取下载链接的
import CryptoJS from “crypto-js”; //在阿里云 文件名直接上传会有各种各样的问题,所以这里对文件名进行加密
import { ElMessage } from “element-plus”;
const props = defineProps({
/**
* 按钮文本
* @type {String}
* @default ‘Upload’
* @description 显示在上传按钮上的文本内容
*/
buttonText: {
type: String,
default: “Upload”
},
/**
* 是否自动上传
* @type {Boolean}
* @default true
* @description 设置为 true 时,选择文件后会自动开始上传;false 时需要手动触发上传
*/
autoUpload: {
type: Boolean,
default: true
},
/**
* 上传参数
* @type {Object}
* @description 上传时需要携带的额外参数,会通过 uploadSuccess 事件返回
*/
params: {
type: Object
},
/**
* OSS 存储桶名称
* @type {String}
* @description 指定文件上传到哪个 OSS 存储桶
*/
bucket: {
type: String
},
/**
* 是否允许多文件上传
* @type {Boolean}
* @default false
* @description 设置为 true 时允许选择多个文件进行上传
*/
multiple: {
type: Boolean,
default: false
},
/**
* 是否使用 MS 加密模式
* @type {Boolean}
* @default false
* @description 设置为 true 时,文件名会使用特定的 MS 加密方式进行加密
*/
ms: {
type: Boolean,
default: false
}
});
const uploadRef = ref();
const emit = defineEmits([“uploadSuccess”]);
const fileQueue = ref([]);
// 检查文件大小是否超过 10MB
const checkFileSize = file => {
const MAX_SIZE = 10 * 1024 * 1024; // 10MB
if (Number(file.size) > MAX_SIZE) {
ElMessage.error(“文件大小不能超过 10MB”);
return false;
}
return true;
};
// 处理 before-upload 事件
const handleBeforeUpload = file => {
if (!checkFileSize(file)) {
return false;
}
const timestamp = new Date().getTime();
const extension = file.name.split(“.”).pop().toLowerCase();
let str = file.name.substring(0, file.name.lastIndexOf(“.”));
let encrypted;
if (props.ms) {
encrypted = CryptoJS.AES.encrypt(`${timestamp}/${str}`, “secret-key”).toString();
} else {
encrypted = CryptoJS.AES.encrypt(file.name, “secret-key”).toString();
}
const encodedFileName = encrypted.replace(/\+/g, “!”).replace(/\//g, “~”).replace(/=/g, “茻”);
const encodedFile = new File([file], encodedFileName + “.” + extension, { type: file.type });
fileQueue.value.push(encodedFile);
return true;
};
// 上传文件到 OSS
const uploadFile = async ({ file }) => {
const { aliOssUpload } = useOssUpload();
const uploadResults = [];
try {
for (let fileItem of fileQueue.value) {
const url = await aliOssUpload(fileItem.name, new Blob([await fileItem.arrayBuffer()]), props.bucket);
uploadResults.push({ url, name: fileItem.name });
}
fileQueue.value = [];
return uploadResults;
} catch (error) {
return Promise.reject(error);
}
};
// 处理上传成功事件
const handleSuccess = async response => {
const processedResults = await Promise.all(
response.map(async item => {
if (props.bucket === “aaf-shenzhen-file”) {
const { data } = await getUrl({ url: item.url });
return { url: data, name: item.name };
}
return { url: item.url, name: item.name };
})
);
// 传递所有处理后的结果和原始文件信息
emit(“uploadSuccess”, {
response: processedResults,
file: response[0], // 当前上传的文件对象
files: response, // 所有已上传的文件列表
…props.params
});
};
</script>
<style scoped></style>
///////////////////////////////////////////elmBtnOssUpload.vue///////////////////////////////////////////////////////////
使用
<FileUpload
buttonText=”上传文件”
:params=”{}”
bucket=”public-aaf-shenzhen-file”
:multiple=”false”
@uploadSuccess=”handleUploadSuccess”
/>
//////////////////////////////////////////
//////////////////////////////////////////
如果要预览功能 也是让后端给接口
// 获取文件预览链接
export const getFilePreviewUrl = params => {
return http.get<Upload.ResFileUrl>(PORT1 + `/file/ossFile/getFilePreviewUrl?fileId=${params.id}`);
};
const preview=async(row)=>{
const {data}=await getFilePreviewUrl({id:row.id})
window.open(data,’_blank’)
}
作为前端只需要获取data打开就好了 本来这勾八功能就应该后端搞 如果他连接口都不出的话 建议吊一顿 再找领导吊他一顿
作为前端只需要获取data打开就好了 本来这勾八功能就应该后端搞 如果他连接口都不出的话 建议吊一顿 再找领导吊他一顿