194 lines
6.0 KiB
Vue
194 lines
6.0 KiB
Vue
<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>
|