Files
orico-officialWebsite-ts-admin/src/components/Upload/UploadVideo.vue

194 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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-error="uploadError"
:on-exceed="handleExceed"
:limit="1"
:accept="fileType.join(',')"
ref="upload"
>
<!-- :on-success="uploadSuccess" -->
<!-- disabled -->
<el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput">
<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 { genFileId } from "element-plus";
import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
import type { UploadProps, UploadRawFile, UploadInstance } from "element-plus";
//UploadRequestOptions
interface UploadFileProps {
videoUrl: any; // 图片地址 ==> 必传
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<any>(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",
bannerListIndex: "banner",
downloadListIndex: "download",
videoListIndex: "video",
QAListIndex: "QA"
};
const routerName = ref(routerObj[routerValueName]);
// 生成组件唯一id
const uuid = ref("id-" + generateUUID());
const upload = ref<UploadInstance>();
// 获取 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: any) => {
let formData = new FormData();
formData.append("video", options.file);
try {
const api = props.api ?? uploadVideo;
const { data } = await api(formData, routerName.value);
if (data.path) {
ElNotification({
title: "温馨提示",
message: "视频上传成功!",
type: "success"
});
emit("update:videoUrl", data.path);
// 调用 el-form 内部的校验方法(可自动校验)
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
} else {
videoShowUrl.value = "";
emit("update:videoUrl", "");
}
} catch (error) {
videoShowUrl.value = "";
emit("update:videoUrl", "");
if (!error) {
return;
}
options.onError(error as any);
}
};
const handleExceed: UploadProps["onExceed"] = files => {
upload.value!.clearFiles();
const file = files[0] as UploadRawFile;
file.uid = genFileId();
let options: any = {
file
};
handleHttpUpload(options);
};
const handleInput = () => {
emit("update:videoUrl", videoShowUrl.value);
};
/**
* @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) => {
if (newVal) {
videoShowUrl.value = newVal;
}
}
);
</script>
<style scoped lang="scss">
.el-upload__tip {
line-height: 18px;
text-align: center;
}
</style>