2025-03-26
This commit is contained in:
162
src/components/Upload/UploadVideo.vue
Normal file
162
src/components/Upload/UploadVideo.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
:id="uuid"
|
||||
action="#"
|
||||
:multiple="false"
|
||||
:disabled="self_disabled"
|
||||
:show-file-list="false"
|
||||
:http-request="handleHttpUpload"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="uploadSuccess"
|
||||
:on-error="uploadError"
|
||||
:limit="1"
|
||||
:accept="fileType.join(',')"
|
||||
>
|
||||
<!-- disabled -->
|
||||
<el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput" disabled>
|
||||
<template #prepend
|
||||
><el-icon :size="20" style="cursor: pointer"><FolderAdd /></el-icon
|
||||
></template>
|
||||
</el-input>
|
||||
</el-upload>
|
||||
<div class="el-upload__tip">
|
||||
<slot name="tip"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="UploadVideo">
|
||||
// Edit, ZoomIn, Delete,Plus
|
||||
import { FolderAdd } from "@element-plus/icons-vue";
|
||||
import { ref, computed, inject } from "vue";
|
||||
import { generateUUID } from "@/utils";
|
||||
import { uploadVideo } from "@/api/modules/upload";
|
||||
import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
|
||||
import type { UploadProps, UploadRequestOptions } from "element-plus";
|
||||
|
||||
interface UploadFileProps {
|
||||
videoUrl: string; // 图片地址 ==> 必传
|
||||
api?: (params: any) => Promise<any>; // 上传图片的 api 方法,一般项目上传都是同一个 api 方法,在组件里直接引入即可 ==> 非必传
|
||||
width?: string;
|
||||
disabled?: boolean; // 是否禁用上传组件 ==> 非必传(默认为 false)
|
||||
fileSize?: number; //视频大小限制 ==> 非必传(默认为 5M)
|
||||
fileType?: any[]; //视频类型限制 ==> 非必传(默认为[".mp4", ".avi", ".mov"])
|
||||
borderRadius?: string; // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
}
|
||||
const videoShowUrl = ref(null);
|
||||
// 接受父组件参数
|
||||
const props = withDefaults(defineProps<UploadFileProps>(), {
|
||||
videoUrl: "",
|
||||
disabled: false,
|
||||
fileSize: 200,
|
||||
width: "400px",
|
||||
fileType: () => [".mp4", ".avi", ".mov", "video/mp4", "video/mov", "video/avi"],
|
||||
borderRadius: "8px"
|
||||
});
|
||||
const $router = useRouter();
|
||||
const routerValueName: string = $router.currentRoute.value.name as string;
|
||||
const routerObj: any = {
|
||||
articleEditIndex: "article",
|
||||
productEditIndex: "product",
|
||||
videoListIndex: "video"
|
||||
};
|
||||
const routerName = ref(routerObj[routerValueName]);
|
||||
|
||||
// 生成组件唯一id
|
||||
const uuid = ref("id-" + generateUUID());
|
||||
|
||||
// 获取 el-form 组件上下文
|
||||
const formContext = inject(formContextKey, void 0);
|
||||
// 获取 el-form-item 组件上下文
|
||||
const formItemContext = inject(formItemContextKey, void 0);
|
||||
// 判断是否禁用上传和删除
|
||||
const self_disabled = computed(() => {
|
||||
return props.disabled || formContext?.disabled;
|
||||
});
|
||||
/**
|
||||
* @description 视频上传
|
||||
* @param options upload 所有配置项
|
||||
* */
|
||||
interface UploadEmits {
|
||||
(e: "update:videoUrl", value: string): void;
|
||||
}
|
||||
const emit = defineEmits<UploadEmits>();
|
||||
const handleHttpUpload = async (options: UploadRequestOptions) => {
|
||||
let formData = new FormData();
|
||||
formData.append("video", options.file);
|
||||
try {
|
||||
const api = props.api ?? uploadVideo;
|
||||
const { data } = await api(formData, routerName.value);
|
||||
emit("update:videoUrl", data.path);
|
||||
// 调用 el-form 内部的校验方法(可自动校验)
|
||||
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
|
||||
} catch (error) {
|
||||
options.onError(error as any);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
console.log("会触发吗");
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 文件上传之前判断
|
||||
* @param rawFile 选择的文件
|
||||
* */
|
||||
const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
||||
const videoSize = rawFile.size / 1024 / 1024 < props.fileSize;
|
||||
const videoType = props.fileType.includes(rawFile.type as any);
|
||||
if (!videoType)
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "上传视频不符合所需的格式!",
|
||||
type: "warning"
|
||||
});
|
||||
if (!videoSize)
|
||||
setTimeout(() => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `上传视频大小不能超过 ${props.fileSize}M!`,
|
||||
type: "warning"
|
||||
});
|
||||
}, 0);
|
||||
return videoType && videoSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 视频上传成功
|
||||
* */
|
||||
const uploadSuccess = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "视频上传成功!",
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 视频上传错误
|
||||
* */
|
||||
const uploadError = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "视频上传失败,请您重新上传!",
|
||||
type: "error"
|
||||
});
|
||||
};
|
||||
watch(
|
||||
() => props.videoUrl,
|
||||
(newVal: any) => {
|
||||
videoShowUrl.value = newVal;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.el-upload__tip {
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user