301 lines
8.0 KiB
JavaScript
301 lines
8.0 KiB
JavaScript
import request from '@/utils/request';
|
||
import service from '@/utils/request';
|
||
import { upImageFileInfo } from '@/api/commit.js';
|
||
import { ElMessage } from 'element-plus';
|
||
|
||
// 上传单个文件
|
||
export async function uploadSingleFile(file, options = {}) {
|
||
try {
|
||
// 获取文件对象,确保能够正确访问文件信息
|
||
const fileObj = file.file || file;
|
||
|
||
// 创建临时文件对象用于显示
|
||
const tempFile = {
|
||
id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
||
originalName: fileObj.name,
|
||
uploading: true
|
||
};
|
||
|
||
if (options.uploadedFiles) {
|
||
options.uploadedFiles.push(tempFile);
|
||
}
|
||
|
||
const isImageFile = fileObj.type.startsWith('image/');
|
||
// 只有图片文件才压缩
|
||
let fileData = isImageFile && options.compressImage ? await options.compressImage(fileObj) : fileObj;
|
||
|
||
const data = new FormData();
|
||
data.append("file", fileData);
|
||
|
||
// 更新UI状态
|
||
if (file.status !== undefined) {
|
||
file.status = "uploading";
|
||
file.message = "上传中...";
|
||
}
|
||
|
||
const res = await upImageFileInfo(data);
|
||
|
||
// 更新文件状态
|
||
if (options.uploadedFiles) {
|
||
const fileIndex = options.uploadedFiles.findIndex(f => f.id === tempFile.id);
|
||
if (fileIndex !== -1) {
|
||
options.uploadedFiles[fileIndex] = {
|
||
id: res.id || tempFile.id,
|
||
originalName: fileObj.name,
|
||
uploading: false,
|
||
url: res.url,
|
||
fileSize: fileObj.size
|
||
};
|
||
// 更新文件ID列表
|
||
if (options.fjIds) {
|
||
options.fjIds.push(res);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新文件状态
|
||
if (file.status !== undefined) {
|
||
file.status = "done";
|
||
file.message = "上传成功";
|
||
file.id = res.id || tempFile.id;
|
||
file.url = res.url;
|
||
file.originalName = fileObj.name;
|
||
file.fileSize = fileObj.size;
|
||
}
|
||
|
||
ElMessage.success('文件上传成功');
|
||
return res;
|
||
|
||
} catch (error) {
|
||
console.error('文件上传失败:', error);
|
||
ElMessage.error('文件上传失败');
|
||
|
||
// 更新文件状态
|
||
if (file && file.status !== undefined) {
|
||
file.status = "failed";
|
||
file.message = "上传失败";
|
||
}
|
||
|
||
// 获取可能的文件名用于查找
|
||
const fileName = (file.file?.originalName || file.originalName || '');
|
||
|
||
// 移除上传失败的文件
|
||
if (options.uploadedFiles) {
|
||
const fileIndex = options.uploadedFiles.findIndex(f =>
|
||
f.originalName === fileName && f.uploading
|
||
);
|
||
if (fileIndex !== -1) {
|
||
options.uploadedFiles.splice(fileIndex, 1);
|
||
}
|
||
}
|
||
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 上传多个文件
|
||
export async function uploadMultipleFiles(files, options = {}) {
|
||
if (Array.isArray(files)) {
|
||
// 多个文件上传
|
||
const results = [];
|
||
for (const file of files) {
|
||
try {
|
||
const result = await uploadSingleFile(file, options);
|
||
results.push(result);
|
||
} catch (error) {
|
||
// 可以选择继续上传其他文件或者中断
|
||
if (!options.continueOnError) {
|
||
throw error;
|
||
}
|
||
}
|
||
}
|
||
return results;
|
||
} else {
|
||
// 单个文件上传
|
||
return [await uploadSingleFile(files, options)];
|
||
}
|
||
}
|
||
|
||
// Element Plus 的 el-upload 上传函数
|
||
// export function upImageFileInfo(data) {
|
||
// return service({
|
||
// url: '/mosty-api/mosty-base/minio/file/uploadObj',
|
||
// method: 'post',
|
||
// data
|
||
// });
|
||
// }
|
||
|
||
// 文件下载函数
|
||
export function downloadFile(fileUrl, fileName = '') {
|
||
return new Promise((resolve, reject) => {
|
||
const token = localStorage.getItem('token');
|
||
const xhr = new XMLHttpRequest();
|
||
|
||
xhr.open('GET', fileUrl, true);
|
||
xhr.setRequestHeader('Authorization', token);
|
||
xhr.responseType = 'blob';
|
||
|
||
xhr.onload = function () {
|
||
if (this.status === 200) {
|
||
const blob = this.response;
|
||
const link = document.createElement('a');
|
||
const url = window.URL.createObjectURL(blob);
|
||
|
||
link.href = url;
|
||
link.download = fileName || 'download';
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
|
||
// 清理
|
||
setTimeout(() => {
|
||
document.body.removeChild(link);
|
||
window.URL.revokeObjectURL(url);
|
||
}, 0);
|
||
|
||
resolve({ success: true });
|
||
} else {
|
||
ElMessage.error('文件下载失败');
|
||
reject(new Error('下载失败'));
|
||
}
|
||
};
|
||
|
||
xhr.onerror = function () {
|
||
ElMessage.error('网络错误,下载失败');
|
||
reject(new Error('网络错误'));
|
||
};
|
||
|
||
xhr.send();
|
||
});
|
||
}
|
||
|
||
// 删除文件前确认
|
||
export function beforeDelete(file) {
|
||
return new Promise((resolve) => {
|
||
// 创建一个简单的确认对话框
|
||
const confirmed = window.confirm(`确定要删除文件"${file.originalName || file.name}"吗?`);
|
||
resolve(confirmed);
|
||
});
|
||
}
|
||
|
||
// 删除文件
|
||
export async function deleteFile(file, options = {}) {
|
||
try {
|
||
// 显示确认对话框
|
||
const confirm = await beforeDelete(file);
|
||
|
||
if (confirm) {
|
||
const fileId = file.id;
|
||
const url = options.url || '/mosty-api/mosty-base/minio/file/delete';
|
||
const token = localStorage.getItem('token');
|
||
|
||
// 调用删除API
|
||
const res = await request({
|
||
url: url,
|
||
method: 'post',
|
||
data: { fileId },
|
||
headers: {
|
||
'Authorization': token
|
||
}
|
||
});
|
||
|
||
if (res.code === 10000 || res.status === 200) {
|
||
// 从已上传文件列表中移除
|
||
if (options.uploadedFiles) {
|
||
const fileIndex = options.uploadedFiles.findIndex(f =>
|
||
f.id === file.id || f.originalName === file.originalName
|
||
);
|
||
if (fileIndex !== -1) {
|
||
options.uploadedFiles.splice(fileIndex, 1);
|
||
}
|
||
}
|
||
|
||
// 从fileList中移除
|
||
if (options.fileList) {
|
||
const listIndex = options.fileList.findIndex(f => f.id === file.id);
|
||
if (listIndex !== -1) {
|
||
options.fileList.splice(listIndex, 1);
|
||
}
|
||
}
|
||
|
||
// 从fjIds中移除
|
||
if (options.fjIds) {
|
||
const fjIndex = options.fjIds.findIndex(f => f.id === file.id);
|
||
if (fjIndex !== -1) {
|
||
options.fjIds.splice(fjIndex, 1);
|
||
}
|
||
}
|
||
|
||
ElMessage.success('文件删除成功');
|
||
return res;
|
||
} else {
|
||
ElMessage.error('文件删除失败');
|
||
throw new Error('删除失败');
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('文件删除失败:', error);
|
||
ElMessage.error('文件删除失败');
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 格式化文件大小
|
||
export function formatFileSize(bytes) {
|
||
if (bytes === 0) return '0 Bytes';
|
||
const k = 1024;
|
||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||
}
|
||
|
||
// el-upload 组件配置生成器
|
||
export function generateUploadConfig(options = {}) {
|
||
const {
|
||
limit = 3,
|
||
accept = '',
|
||
action = '/mosty-api/mosty-base/minio/image/upload/id',
|
||
onSuccess = () => { },
|
||
onRemove = () => { },
|
||
onExceed = () => { },
|
||
beforeRemove = () => { },
|
||
beforeUpload = () => { }
|
||
} = options;
|
||
|
||
// 获取token
|
||
const getToken = () => {
|
||
return localStorage.getItem('token');
|
||
};
|
||
|
||
return {
|
||
headers: {
|
||
'Authorization': getToken()
|
||
},
|
||
action: action,
|
||
multiple: true,
|
||
limit: limit,
|
||
accept: accept,
|
||
showFileList: true,
|
||
onSuccess: (response, uploadFile, uploadFiles) => {
|
||
ElMessage.success('上传成功');
|
||
onSuccess(response, uploadFile, uploadFiles);
|
||
},
|
||
onRemove: (uploadFile, uploadFiles) => {
|
||
onRemove(uploadFile, uploadFiles);
|
||
},
|
||
onExceed: (files, uploadFiles) => {
|
||
ElMessage.warning(`最多只能上传 ${limit} 个文件`);
|
||
onExceed(files, uploadFiles);
|
||
},
|
||
beforeRemove: (uploadFile, uploadFiles) => {
|
||
const result = beforeRemove(uploadFile, uploadFiles);
|
||
if (result === undefined) {
|
||
return window.confirm(`确定移除 ${uploadFile.name}?`);
|
||
}
|
||
return result;
|
||
},
|
||
beforeUpload: (file) => {
|
||
return beforeUpload(file);
|
||
}
|
||
};
|
||
}
|