提交 dc09e709 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 5dd79037
...@@ -9,6 +9,8 @@ interface Props { ...@@ -9,6 +9,8 @@ interface Props {
modelValue: string | { name: string; url: string }[] modelValue: string | { name: string; url: string }[]
prefix?: string prefix?: string
size?: number size?: number
beforeUpload?: (file: any) => boolean | void
onChange?: (file: any, files: any) => void
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
...@@ -50,10 +52,13 @@ const handleBeforeUpload = async (file: any) => { ...@@ -50,10 +52,13 @@ const handleBeforeUpload = async (file: any) => {
url: `${response.host}/${key}` url: `${response.host}/${key}`
} }
file.url = `${response.host}/${key}` file.url = `${response.host}/${key}`
if (props.beforeUpload) {
return props.beforeUpload(file)
}
} }
// 上传成功 // 上传成功
const handleSuccess = (response: any, file: any, files: any) => { const handleSuccess: UploadProps['onSuccess'] = (response, file: any, files: any) => {
if (!files.every((item: any) => item.status === 'success')) return if (!files.every((item: any) => item.status === 'success')) return
if (showFileList.value) { if (showFileList.value) {
emit( emit(
...@@ -79,11 +84,11 @@ const handleExceed: UploadProps['onExceed'] = () => { ...@@ -79,11 +84,11 @@ const handleExceed: UploadProps['onExceed'] = () => {
} }
// 删除 // 删除
const handleRemove: UploadProps['onRemove'] = (file, files) => { const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
if (showFileList.value) { if (showFileList.value) {
emit( emit(
'update:modelValue', 'update:modelValue',
files.map((item: any) => { uploadFiles.map((item: any) => {
return { name: item.name, url: item.url || item.raw.url } return { name: item.name, url: item.url || item.raw.url }
}) })
) )
...@@ -96,6 +101,10 @@ const handleRemove: UploadProps['onRemove'] = (file, files) => { ...@@ -96,6 +101,10 @@ const handleRemove: UploadProps['onRemove'] = (file, files) => {
const handlePreview: UploadProps['onPreview'] = uploadFile => { const handlePreview: UploadProps['onPreview'] = uploadFile => {
window.open(uploadFile.url) window.open(uploadFile.url)
} }
const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
console.log(uploadFile, uploadFiles)
}
</script> </script>
<template> <template>
...@@ -104,13 +113,13 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => { ...@@ -104,13 +113,13 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => {
:data="uploadData" :data="uploadData"
:show-file-list="showFileList" :show-file-list="showFileList"
:before-upload="handleBeforeUpload" :before-upload="handleBeforeUpload"
:on-change="handleChange"
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-remove="handleRemove" :on-remove="handleRemove"
:on-preview="handlePreview" :on-preview="handlePreview"
:on-success="handleSuccess" :on-success="handleSuccess"
:file-list="fileList" :file-list="fileList"
class="uploader" class="uploader">
>
<slot> <slot>
<template v-if="showFileList"> <template v-if="showFileList">
<template v-if="$attrs['list-type'] === 'picture-card'"> <template v-if="$attrs['list-type'] === 'picture-card'">
......
...@@ -4,7 +4,7 @@ import { ElMessage } from 'element-plus' ...@@ -4,7 +4,7 @@ import { ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import AppEditor from '@/components/base/AppEditor.vue' import AppEditor from '@/components/base/AppEditor.vue'
import { replyToPost } from '../api' import { replyToPost } from '../api'
import { isVideo } from '@/utils/index'
interface Props { interface Props {
id: string id: string
} }
...@@ -39,6 +39,24 @@ const create = () => { ...@@ -39,6 +39,24 @@ const create = () => {
emit('update:modelValue', false) emit('update:modelValue', false)
}) })
} }
const images = $computed(() => {
return form.files.filter((item: any) => !isVideo(item.url))
})
const videos = $computed(() => {
return form.files.filter((item: any) => isVideo(item.url))
})
function beforeUpload(file: any) {
if (images.length >= 10 && !isVideo(file.url)) {
ElMessage.error('最多上传10张图片')
return false
}
if (videos.length >= 1 && isVideo(file.url)) {
ElMessage.error('最多上传1个视频')
return false
}
}
</script> </script>
<template> <template>
...@@ -54,7 +72,7 @@ const create = () => { ...@@ -54,7 +72,7 @@ const create = () => {
<AppEditor v-model="form.content" :height="300" /> <AppEditor v-model="form.content" :height="300" />
</el-form-item> </el-form-item>
<el-form-item prop="files"> <el-form-item prop="files">
<AppUpload v-model="form.files"> <AppUpload v-model="form.files" accept="image/*,video/*" :beforeUpload="beforeUpload">
<el-button size="default">上传图片/视频附件</el-button> <el-button size="default">上传图片/视频附件</el-button>
<template #tip <template #tip
>支持最多上传10张图片,格式支持jpg,jpeg,png,2MB以内<br />视频最多上传1个,100Mb以内 >支持最多上传10张图片,格式支持jpg,jpeg,png,2MB以内<br />视频最多上传1个,100Mb以内
......
<script setup lang="ts"> <script setup lang="ts">
import type { File } from '../types' import type { File } from '../types'
import { VideoPlay } from '@element-plus/icons-vue' import { VideoPlay } from '@element-plus/icons-vue'
import { isVideo } from '@/utils/index'
interface Props { interface Props {
preview?: boolean preview?: boolean
data: File[] | Record<string, File[]> data: File[] | Record<string, File[]>
...@@ -22,10 +24,6 @@ const videos = $computed(() => { ...@@ -22,10 +24,6 @@ const videos = $computed(() => {
if (!Array.isArray(props.data)) return [] if (!Array.isArray(props.data)) return []
return props.data.filter(item => isVideo(item.url)) return props.data.filter(item => isVideo(item.url))
}) })
function isVideo(url: string) {
return url.includes('.mp4')
}
</script> </script>
<template> <template>
...@@ -39,10 +37,17 @@ function isVideo(url: string) { ...@@ -39,10 +37,17 @@ function isVideo(url: string) {
:preview-src-list="imageSrcList" :preview-src-list="imageSrcList"
fit="cover" /> fit="cover" />
</div> </div>
<div class="file-item" v-for="(item, index) in videos" :key="index"> <template v-if="preview">
<video :src="item.url" /> <div class="video-item" v-for="(item, index) in videos" :key="index">
<el-icon class="icon-video-play"><VideoPlay /></el-icon> <video :src="item.url" controls />
</div> </div>
</template>
<template v-else>
<div class="file-item" v-for="(item, index) in videos" :key="index">
<video :src="item.url" />
<el-icon class="icon-video-play"><VideoPlay /></el-icon>
</div>
</template>
</div> </div>
</template> </template>
...@@ -58,8 +63,8 @@ function isVideo(url: string) { ...@@ -58,8 +63,8 @@ function isVideo(url: string) {
width: 160px; width: 160px;
height: 90px; height: 90px;
video { video {
width: 160px; width: 100%;
height: 90px; height: 100%;
} }
.icon-video-play { .icon-video-play {
position: absolute; position: absolute;
...@@ -70,6 +75,14 @@ function isVideo(url: string) { ...@@ -70,6 +75,14 @@ function isVideo(url: string) {
color: #fff; color: #fff;
} }
} }
.video-item {
display: block;
width: 320px;
video {
width: 100%;
height: auto;
}
}
.file-item__count { .file-item__count {
position: absolute; position: absolute;
left: 0; left: 0;
......
...@@ -6,6 +6,7 @@ import AppEditor from '@/components/base/AppEditor.vue' ...@@ -6,6 +6,7 @@ import AppEditor from '@/components/base/AppEditor.vue'
import { createPost } from '../api' import { createPost } from '../api'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
import { useGetCourseList } from '@/composables/useGetCourseList' import { useGetCourseList } from '@/composables/useGetCourseList'
import { isVideo } from '@/utils/index'
interface Props { interface Props {
courseId?: string courseId?: string
...@@ -57,6 +58,23 @@ const create = () => { ...@@ -57,6 +58,23 @@ const create = () => {
emit('update:modelValue', false) emit('update:modelValue', false)
}) })
} }
const images = $computed(() => {
return form.files.filter((item: any) => !isVideo(item.url))
})
const videos = $computed(() => {
return form.files.filter((item: any) => isVideo(item.url))
})
function beforeUpload(file: any) {
if (images.length >= 10 && !isVideo(file.url)) {
ElMessage.error('最多上传10张图片')
return false
}
if (videos.length >= 1 && isVideo(file.url)) {
ElMessage.error('最多上传1个视频')
return false
}
}
</script> </script>
<template> <template>
...@@ -92,7 +110,7 @@ const create = () => { ...@@ -92,7 +110,7 @@ const create = () => {
<AppEditor v-model="form.content" :height="300" /> <AppEditor v-model="form.content" :height="300" />
</el-form-item> </el-form-item>
<el-form-item prop="files"> <el-form-item prop="files">
<AppUpload v-model="form.files"> <AppUpload v-model="form.files" accept="image/*,video/*" :beforeUpload="beforeUpload">
<el-button size="default">上传图片/视频附件</el-button> <el-button size="default">上传图片/视频附件</el-button>
<template #tip <template #tip
>支持最多上传10张图片,格式支持jpg,jpeg,png,2MB以内<br />视频最多上传1个,100Mb以内 >支持最多上传10张图片,格式支持jpg,jpeg,png,2MB以内<br />视频最多上传1个,100Mb以内
......
...@@ -16,3 +16,8 @@ export function formatLiveStatus(status: LiveStatusType) { ...@@ -16,3 +16,8 @@ export function formatLiveStatus(status: LiveStatusType) {
export function formatQuestionType(type: QuestionType) { export function formatQuestionType(type: QuestionType) {
return questionType[type] || type return questionType[type] || type
} }
// 是否是视频
export function isVideo(url: string) {
return url.includes('.mp4')
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论