Commit dd652a61 by lijiabin

【需求 20331】 feat: 支持编辑视频时回显视频相关信息

parent 5ce1af42
...@@ -44,8 +44,9 @@ ...@@ -44,8 +44,9 @@
<div class="video-details-text"> <div class="video-details-text">
<p class="video-name">{{ videoInfo.name }}</p> <p class="video-name">{{ videoInfo.name }}</p>
<p class="video-meta"> <p class="video-meta">
{{ formatFileSize(videoInfo.size) }} · {{ videoInfo.duration }} · <span v-if="videoInfo.size"> {{ formatFileSize(videoInfo.size) }} </span> ·
{{ videoInfo.resolution }} <span v-if="videoInfo.duration"> {{ videoInfo.duration }} </span> ·
<span v-if="videoInfo.resolution"> {{ videoInfo.resolution }} </span>
</p> </p>
</div> </div>
</div> </div>
...@@ -92,7 +93,6 @@ const { ...@@ -92,7 +93,6 @@ const {
acceptFormats = ['mp4', 'avi', 'mov', 'wmv', 'flv'], acceptFormats = ['mp4', 'avi', 'mov', 'wmv', 'flv'],
btnClass = '', btnClass = '',
} = defineProps<UploadVideoProps>() } = defineProps<UploadVideoProps>()
console.log(btnClass, 'btnClass')
const modelValue = defineModel<string>('modelValue', { required: true }) const modelValue = defineModel<string>('modelValue', { required: true })
const videoInfo = defineModel<VideoInfo | null>('videoInfo', { required: false, default: null }) const videoInfo = defineModel<VideoInfo | null>('videoInfo', { required: false, default: null })
...@@ -211,9 +211,38 @@ const cancelUpload = () => { ...@@ -211,9 +211,38 @@ const cancelUpload = () => {
push.info('已取消上传') push.info('已取消上传')
} }
// 编辑回显:当 modelValue 有值(父组件赋值)时,通过 getVideoMetadata 拉取元信息并展示
async function syncVideoInfoFromModel() {
const url = modelValue.value
if (!url || uploading.value) return
// 下面这种直接限制 新增视频 或者 编辑视频的二次上传
if (videoInfo.value?.url === url) return
let duration = '--'
let resolution = '--'
try {
const metadata = await getVideoMetadata(url)
duration = metadata.duration
resolution = metadata.resolution
} catch {
// 跨域或加载失败时使用占位
}
if (modelValue.value !== url) return
// 手动回显视频信息
videoInfo.value = {
url,
name: '已上传视频',
size: 0,
duration,
resolution,
}
}
watch(() => modelValue.value, syncVideoInfoFromModel, { immediate: true })
// 重新选择视频 // 重新选择视频
const replaceVideo = () => { const replaceVideo = () => {
videoInfo.value = null videoInfo.value = null
modelValue.value = ''
uploadError.value = '' uploadError.value = ''
uploadProgress.value = 0 uploadProgress.value = 0
currentFile.value = null currentFile.value = null
......
...@@ -99,3 +99,10 @@ export function formatSeconds(seconds: string | number) { ...@@ -99,3 +99,10 @@ export function formatSeconds(seconds: string | number) {
const res = dayjs.unix(Number(seconds)).endOf('day').unix() const res = dayjs.unix(Number(seconds)).endOf('day').unix()
return typeof seconds === 'number' ? res : res.toString() return typeof seconds === 'number' ? res : res.toString()
} }
// fetch远程oss链接转为 本地的blob链接
export function fetchOssBlob(url: string): Promise<string> {
return fetch(url)
.then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
}
...@@ -472,7 +472,7 @@ onActivated(async () => { ...@@ -472,7 +472,7 @@ onActivated(async () => {
console.log(route.query.id, '编辑 或者 草稿箱') console.log(route.query.id, '编辑 或者 草稿箱')
// 要编辑回显 // 要编辑回显
const { data } = await getArticleDetail(route.query.id as string) const { data } = await getArticleDetail(route.query.id as string)
// 首先回显基础的信息 // 1首先回显基础的信息
// 标题 内容 主标签 副标签 所属栏目 是否推荐 是否同步同事吧 发布时间 发布状态 // 标题 内容 主标签 副标签 所属栏目 是否推荐 是否同步同事吧 发布时间 发布状态
const { const {
id, id,
...@@ -500,34 +500,40 @@ onActivated(async () => { ...@@ -500,34 +500,40 @@ onActivated(async () => {
id, id,
} }
// 回显主副标签 // 2回显主副标签
form.value.mainTagId = tagIdList[0] ? String(tagIdList[0]) : '' form.value.mainTagId = tagIdList[0] ? String(tagIdList[0]) : ''
form.value.tagList = tagIdList.slice(1) || [] form.value.tagList = tagIdList.slice(1) || []
const { imgUrl, faceUrl } = data // 3回显封面图内容图片 以及顶部 底部 视频等
const { imgUrl, faceUrl, articleVideoUrl } = data
if (type === ArticleTypeEnum.QUESTION || type === ArticleTypeEnum.PRACTICE) { if (type === ArticleTypeEnum.QUESTION || type === ArticleTypeEnum.PRACTICE) {
form.value.imgUrl = imgUrl form.value.imgUrl = imgUrl
} else { } else {
form.value.faceUrl = faceUrl form.value.faceUrl = faceUrl
} }
// 回显推送人员设置 if (articleVideoUrl) {
form.value.articleVideoUrl = articleVideoUrl
}
// 4回显推送人员设置
if ( if (
(type === ArticleTypeEnum.COLUMN || type === ArticleTypeEnum.INTERVIEW) && (type === ArticleTypeEnum.COLUMN || type === ArticleTypeEnum.INTERVIEW) &&
userInfo.value.isOfficialAccount userInfo.value.isOfficialAccount
) { ) {
selectedDepts.value = data.pushList selectedDepts.value =
.filter((item) => item.valueType === 1) data.pushList
.map((item) => ({ ?.filter((item) => item.valueType === 1)
id: item.valueId, .map((item) => ({
name: item.valueName, id: item.valueId,
})) name: item.valueName,
selectedUsers.value = data.pushList })) || []
.filter((item) => item.valueType === 2) selectedUsers.value =
.map((item) => ({ data.pushList
id: item.valueId, ?.filter((item) => item.valueType === 2)
name: item.valueName, .map((item) => ({
})) id: item.valueId,
name: item.valueName,
})) || []
} }
} }
}) })
......
...@@ -273,6 +273,7 @@ ...@@ -273,6 +273,7 @@
width="800px" width="800px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 这个用blob是因为 转为canvas 防止跨域污染 -->
<div v-if="locationVideoBlolUrl" class="space-y-6"> <div v-if="locationVideoBlolUrl" class="space-y-6">
<!-- 视频预览 --> <!-- 视频预览 -->
<div class="relative"> <div class="relative">
...@@ -347,14 +348,16 @@ ...@@ -347,14 +348,16 @@
import UploadVideo from '@/components/common/UploadVideo/index.vue' import UploadVideo from '@/components/common/UploadVideo/index.vue'
import { useResetData } from '@/hooks' import { useResetData } from '@/hooks'
import { ArticleTypeEnum, ReleaseStatusTypeEnum, SendTypeEnum } from '@/constants' import { ArticleTypeEnum, ReleaseStatusTypeEnum, SendTypeEnum } from '@/constants'
import { addOrUpdateArticle, uploadFile } from '@/api' import { addOrUpdateArticle, uploadFile, getArticleDetail } from '@/api'
import SelectTags from '@/components/common/SelectTags/index.vue' import SelectTags from '@/components/common/SelectTags/index.vue'
import type { TagItemDto, AddOrUpdateVideoDto } from '@/api' import type { TagItemDto, AddOrUpdateVideoDto } from '@/api'
import { useVideoStore, useUserStore } from '@/stores' import { useVideoStore, useUserStore } from '@/stores'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { selectDepOrUser } from '@/utils' import { selectDepOrUser, fetchOssBlob } from '@/utils'
import BackButton from '@/components/common/BackButton/index.vue' import BackButton from '@/components/common/BackButton/index.vue'
import { push } from 'notivue' import { push } from 'notivue'
const route = useRoute()
const videoStore = useVideoStore() const videoStore = useVideoStore()
const { videoList } = storeToRefs(videoStore) const { videoList } = storeToRefs(videoStore)
...@@ -600,21 +603,36 @@ onDeactivated(() => { ...@@ -600,21 +603,36 @@ onDeactivated(() => {
uploadVideoRef.value?.reset() uploadVideoRef.value?.reset()
}) })
// const isEdit = computed(() => { // 处理编辑回显
// return !!route.query.id onActivated(async () => {
// }) if (route.query.id) {
// onActivated(async () => { const { data } = await getArticleDetail(route.query.id as string)
// resetPageData() const blobUrl = await fetchOssBlob(data.videoUrl)
// if (isEdit.value) { locationVideoBlolUrl.value = blobUrl
// const { data } = await getArticleDetail(route.query.id as string) form.value = {
// form.value = { ...form.value,
// ...form.value, ...data,
// ...data, mainTagId: String(data.tagIdList?.[0]),
// mainTagId:String( data.tagIdList?.[0]) || '', tagList: data.tagIdList?.slice(1),
// tagList: data.tagIdList?.slice(1) || [], }
// } // 回显推送的部门 这个后端没有返回相关数据 需要返回
// } console.log(data.pushList, 'data.pushList')
// }) selectedDepts.value =
data.pushList
?.filter((item) => item.valueType === 1)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
selectedUsers.value =
data.pushList
?.filter((item) => item.valueType === 2)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
}
})
</script> </script>
<style scoped> <style scoped>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment