|
|
@@ -14,7 +14,7 @@
|
|
|
<el-upload
|
|
|
v-model:file-list="fileList"
|
|
|
list-type="picture-card"
|
|
|
- :limit="20"
|
|
|
+ :limit="hasVideoInList() ? 1 : 20"
|
|
|
:on-preview="handlePicturePreview"
|
|
|
:on-remove="handleRemoveImage"
|
|
|
:on-change="handleFileChange"
|
|
|
@@ -45,7 +45,7 @@
|
|
|
<el-icon :size="32" color="#999">
|
|
|
<Plus />
|
|
|
</el-icon>
|
|
|
- <div class="upload-count">({{ fileList.length }}/20)</div>
|
|
|
+ <div class="upload-count">({{ fileList.length }}/{{ hasVideoInList() ? 1 : 20 }})</div>
|
|
|
</div>
|
|
|
</el-upload>
|
|
|
</div>
|
|
|
@@ -278,6 +278,23 @@ const handleFileChange = (uploadFile: UploadFile, uploadFiles: UploadFile[]) =>
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 权限:已上传视频则不能再传;已上传图片则只能继续传图片(检查时排除当前文件,用已存在的列表)
|
|
|
+ const otherFiles = fileList.value.filter(f => f.uid !== uploadFile.uid);
|
|
|
+ const alreadyHasVideo = otherFiles.some(f => isVideoFile(f));
|
|
|
+ const alreadyHasImage = otherFiles.some(f => !isVideoFile(f));
|
|
|
+ if (alreadyHasVideo) {
|
|
|
+ const index = uploadFiles.findIndex(f => f.uid === uploadFile.uid);
|
|
|
+ if (index > -1) uploadFiles.splice(index, 1);
|
|
|
+ ElMessage.warning("已上传视频,只能上传一个视频,不可再上传");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (alreadyHasImage && isVideo) {
|
|
|
+ const index = uploadFiles.findIndex(f => f.uid === uploadFile.uid);
|
|
|
+ if (index > -1) uploadFiles.splice(index, 1);
|
|
|
+ // ElMessage.warning("已上传图片,后续只能上传图片,不能上传视频");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 根据文件类型设置不同的大小限制
|
|
|
const maxSize = isVideo ? 100 : 20;
|
|
|
const isLtMaxSize = uploadFile.raw.size / 1024 / 1024 < maxSize;
|
|
|
@@ -402,14 +419,22 @@ const beforeImageUpload = (file: File) => {
|
|
|
const isVideo = file.type.startsWith("video/");
|
|
|
const isValidType = isImage || isVideo;
|
|
|
|
|
|
- // 图片和视频使用不同的大小限制
|
|
|
- const maxSize = isVideo ? 100 : 20; // 视频100MB,图片20MB
|
|
|
- const isLtMaxSize = file.size / 1024 / 1024 < maxSize;
|
|
|
-
|
|
|
if (!isValidType) {
|
|
|
ElMessage.error("只能上传图片或视频文件!");
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ // 权限:已上传视频则不能再传;已上传图片则只能继续传图片(排除当前文件,避免清除图片后选视频被误判)
|
|
|
+ const permission = checkUploadPermission(file, file);
|
|
|
+ if (!permission.allowed) {
|
|
|
+ ElMessage.warning(permission.message);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图片和视频使用不同的大小限制
|
|
|
+ const maxSize = isVideo ? 100 : 20; // 视频100MB,图片20MB
|
|
|
+ const isLtMaxSize = file.size / 1024 / 1024 < maxSize;
|
|
|
+
|
|
|
if (!isLtMaxSize) {
|
|
|
ElMessage.error(`${isVideo ? "视频" : "图片"}大小不能超过 ${maxSize}MB!`);
|
|
|
return false;
|
|
|
@@ -429,6 +454,26 @@ const isVideoFile = (file: any) => {
|
|
|
return fileName.toLowerCase().endsWith(".mp4") || file.raw?.type?.startsWith("video/") || false;
|
|
|
};
|
|
|
|
|
|
+// 上传类型权限:第一个是图片则只能继续传图片;第一个是视频则只能传一个视频
|
|
|
+const hasVideoInList = () => fileList.value.some(f => isVideoFile(f));
|
|
|
+const hasImageInList = () => fileList.value.some(f => !isVideoFile(f));
|
|
|
+
|
|
|
+/** 校验上传权限,excludeRawFile 为当前正在校验的文件,校验时排除它(避免刚选中的文件已被加入列表导致误判) */
|
|
|
+const checkUploadPermission = (file: File, excludeRawFile?: File): { allowed: boolean; message?: string } => {
|
|
|
+ const isVideo = file.type.startsWith("video/");
|
|
|
+ const existingFiles = excludeRawFile ? fileList.value.filter(f => f.raw !== excludeRawFile) : fileList.value;
|
|
|
+ const existingHasVideo = existingFiles.some(f => isVideoFile(f));
|
|
|
+ const existingHasImage = existingFiles.some(f => !isVideoFile(f));
|
|
|
+
|
|
|
+ if (existingHasVideo) {
|
|
|
+ return { allowed: false, message: "已上传视频,只能上传一个视频,不可再上传" };
|
|
|
+ }
|
|
|
+ if (existingHasImage && isVideo) {
|
|
|
+ return { allowed: false, message: "已上传图片,后续只能上传图片,不能上传视频" };
|
|
|
+ }
|
|
|
+ return { allowed: true };
|
|
|
+};
|
|
|
+
|
|
|
// 图片/视频预览
|
|
|
const handlePicturePreview = (uploadFile: UploadUserFile) => {
|
|
|
previewImageUrl.value = uploadFile.url!;
|