2025-03-26

This commit is contained in:
2025-03-26 11:00:21 +08:00
parent 927d7381b8
commit b45f4950d3
468 changed files with 54473 additions and 124 deletions

View 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>