upload.js
3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common';
import BMF from 'browser-md5-file';
// import { v4 as uuidv4 } from 'uuid';
// 获取文件后缀
const getFileSuffix = (fileName) => {
return /.[^.]+$/.exec(fileName) || '';
};
// 获取文件MD5
const getFileMD5 = (file) => {
return new Promise((resolve, reject) => {
const bmf = new BMF();
bmf.md5(file, (err, md5) => {
if (err) {
reject(err);
return;
}
resolve(md5);
});
});
};
// 上传文件到七牛云
const uploadToQiniu = async (file, token, fileName, onProgress) => {
const formData = new FormData();
formData.append('file', file);
formData.append('token', token);
formData.append('key', fileName);
const config = {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: (progressEvent) => {
if (progressEvent.total > 0) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
// 使用requestAnimationFrame确保进度更新的平滑性
requestAnimationFrame(() => {
onProgress?.(percent);
});
}
}
};
// 根据协议选择上传地址
const qiniuUploadUrl = window.location.protocol === 'https:'
? 'https://up.qbox.me'
: 'http://upload.qiniu.com';
return await qiniuUploadAPI(qiniuUploadUrl, formData, config);
};
// 校验文件
export const validateFile = (file, options = {}) => {
const {
maxSize = 100, // 默认100MB
allowedTypes = ['video/mp4', 'video/quicktime'],
} = options;
if (!allowedTypes.includes(file.type)) {
return {
valid: false,
message: '请上传正确格式的视频文件'
};
}
const fileSize = (file.size / 1024 / 1024).toFixed(2);
if (fileSize > maxSize) {
return {
valid: false,
message: `文件大小不能超过${maxSize}MB`
};
}
return { valid: true };
};
// 上传文件
export const uploadFile = async (file, fileCode, onProgress) => {
try {
// 获取文件MD5
const md5 = await getFileMD5(file);
// 获取七牛token
const tokenResult = await qiniuTokenAPI({
name: file.name,
hash: md5
});
// 如果文件已存在,直接返回
if (tokenResult.data) {
onProgress?.(100);
return tokenResult.data;
}
// 新文件上传
if (tokenResult.token) {
const suffix = getFileSuffix(file.name);
const fileName = `uploadForm/${fileCode}/${md5}${suffix}`;
// TODO: image_info 为七牛返回的图片信息,现在是上传视频看后期适配
const { filekey, image_info } = await uploadToQiniu(
file,
tokenResult.token,
fileName,
onProgress
);
if (filekey) {
// 保存文件信息
const { data } = await saveFileAPI({
name: file.name,
filekey,
hash: md5,
height: image_info?.height,
width: image_info?.width,
});
return data;
}
}
throw new Error('上传失败');
} catch (error) {
console.error('Upload error:', error);
throw error;
}
};