feat: design跳转视频生成弹窗

This commit is contained in:
zhangyh
2025-11-18 11:31:03 +08:00
parent 026a39f1a9
commit e1e884c913
3 changed files with 499 additions and 15 deletions

View File

@@ -31,7 +31,7 @@
</div>
<div class="imgBox" v-mousewheel>
<div
class="item"
class="item first-frame"
:class="{ active: item.id == selectImg.id }"
v-for="(item, index) in showFirstFrameList"
@click="selectImgItem(item)"
@@ -52,23 +52,23 @@
v-show="item.designOutfitUrl || item.imgUrl || item.url"
class="btnBox"
>
<div :class="{ active: item.isChecked }">
<div :class="{ active: item.isChecked }" v-if="!(isDesignPage && videoType === 3)">
<i class="fi fi-br-check"></i>
</div>
<div
@click.stop="setUploadDelete(item, index)"
v-if="source != 'design'"
v-if="source != 'design' || (isDesignPage && videoType === 3)"
>
<i class="fi fi-rr-trash icon_delete"></i>
</div>
</div>
</div>
<div
class="upload_item item"
v-show="
!isDesignPage && !(videoType === 3 && showFirstFrameList.length > 0)
"
>
<div class="upload_item item first_frames" v-show="showFirstFrameUpload">
<div
class="design-mask"
v-if="isDesignPage && videoType === 3"
@click="handleClickDesignMask('first')"
/>
<div class="upload_file_item">
<a-upload
key="common"
@@ -93,9 +93,14 @@
</div>
<template v-if="videoType === 3">
<div
v-show="lastFrameList?.length < 1"
class="upload_item item last_frames"
v-show="!isDesignPage && lastFrameList?.length < 1"
>
<div
class="design-mask"
v-if="isDesignPage && videoType === 3"
@click="handleClickDesignMask('last')"
/>
<div class="upload_file_item">
<a-upload
key="lastframes"
@@ -142,12 +147,12 @@
v-show="item.designOutfitUrl || item.imgUrl || item.url"
class="btnBox"
>
<div :class="{ active: item.isChecked }">
<div :class="{ active: item.isChecked }" v-if="!(isDesignPage && videoType === 3)">
<i class="fi fi-br-check"></i>
</div>
<div
@click.stop="setUploadDelete(item, index, true)"
v-if="source != 'design'"
v-if="source != 'design' || (isDesignPage && videoType === 3)"
>
<i class="fi fi-rr-trash icon_delete"></i>
</div>
@@ -277,6 +282,13 @@
</div>
</div>
<Tips v-model:showModal="showTips" />
<Product
v-model:showModal="showProductList"
:frameList="productFrameList"
:type="productType"
:key="productType"
@confirm="handleConfirmProduct"
/>
</div>
</template>
<script lang="ts">
@@ -304,13 +316,15 @@ import showViewVideo from '@/tool/mount'
import router from '@/router'
import promptInput from './promptInput.vue'
import Tips from './Tips.vue'
import Product from './Product.vue'
import { getFirstFrame, getFirstAndLastFrame } from './prompt'
export default defineComponent({
components: {
generalDrag,
promptInput,
Tips
Tips,
Product
},
props: {
isDesignPage: {
@@ -437,6 +451,7 @@ export default defineComponent({
if (props.isDesignPage) {
//标识design页面打开的tools
data.fileList = designList
console.log('11111111111111', data.fileList)
} else {
data.currentList = store.state.UploadFilesModule.modularData.toProduct
data.currentList = data.currentList ? data.currentList : []
@@ -881,6 +896,57 @@ export default defineComponent({
document.removeEventListener('click', openSpeed)
}
const setUploadDelete = (item: any, index: any, isLastFrame: boolean = false) => {
// 在 isDesignPage 模式且 videoType === 3 时,直接从列表中删除,并将图片重新添加到产品列表中以便重新选择
if (props.isDesignPage && videoType.value === 3) {
if (isLastFrame) {
// 从 lastFrameList 中删除
const deleteIndex = lastFrameList.value.findIndex((listItem: any) => listItem.id === item.id)
if (deleteIndex >= 0) {
lastFrameList.value.splice(deleteIndex, 1)
}
// 将删除的项重新添加到 lastFrameProductList 中,以便可以重新选择
const productItem = { ...item }
// 移除 frameType 和 isChecked 属性
delete productItem.frameType
delete productItem.isChecked
// 检查是否已存在,避免重复添加
const existingIndex = lastFrameProductList.value.findIndex(
(listItem: any) => listItem.id === productItem.id
)
if (existingIndex < 0) {
lastFrameProductList.value.unshift(productItem)
}
// 清空选中状态
if (data.lastSelectImg?.id === item.id) {
data.lastSelectImg = {}
}
} else {
// 从 firstFrameList 中删除
const deleteIndex = firstFrameList.value.findIndex((listItem: any) => listItem.id === item.id)
if (deleteIndex >= 0) {
firstFrameList.value.splice(deleteIndex, 1)
}
// 将删除的项重新添加到 firstFrameProductList 中,以便可以重新选择
const productItem = { ...item }
// 移除 frameType 和 isChecked 属性
delete productItem.frameType
delete productItem.isChecked
// 检查是否已存在,避免重复添加
const existingIndex = firstFrameProductList.value.findIndex(
(listItem: any) => listItem.id === productItem.id
)
if (existingIndex < 0) {
firstFrameProductList.value.unshift(productItem)
}
// 清空选中状态
if (data.selectImg?.id === item.id) {
data.selectImg = {}
}
}
return
}
// 非 design 页面的原有逻辑
let value = {
id: item.id
}
@@ -920,9 +986,148 @@ export default defineComponent({
const firstFrameList = ref([])
const lastFrameList = ref([])
const showFirstFrameList = computed(() => {
if(props.isDesignPage) return data.fileList
if (props.isDesignPage) {
// 在 design 页面,如果 videoType === 3显示 firstFrameList否则显示 data.fileList
return videoType.value === 3 ? firstFrameList.value : data.fileList
}
return videoType.value === 3 ? firstFrameList.value : data.fileList
})
const showProductList = ref(false)
const productType = ref('first')
// 首帧和尾帧的独立数据源
const firstFrameProductList = ref([])
const lastFrameProductList = ref([])
const showFirstFrameUpload = computed(() => {
// 只读依赖
const isDesign = props.isDesignPage
const isFirstAndLast = videoType.value === 3
const hasFirstFrames = Array.isArray(showFirstFrameList.value)
? showFirstFrameList.value.length > 0
: false
if (isDesign) {
// design 页面下,仅 videoType 为 3 时可展示上传,且没有首帧时显示上传按钮
return isFirstAndLast && !hasFirstFrames
}
// 非 design 页面下也是类似逻辑
return !(isFirstAndLast && hasFirstFrames)
})
const showLastFrameUpload = computed(() => {
if (videoType.value !== 3) return false
if (props.isDesignPage && lastFrameList.length > 0) return false
return true
})
// 根据 productType 返回对应的数据源
const productFrameList = computed(() => {
if (productType.value === 'first') {
return firstFrameProductList.value.length > 0
? firstFrameProductList.value
: data.fileList
} else {
return lastFrameProductList.value.length > 0
? lastFrameProductList.value
: data.fileList
}
})
const handleClickDesignMask = (type: 'first' | 'last') => {
productType.value = type
// 初始化独立的数据源,如果为空则从 fileList 复制
if (type === 'first') {
if (firstFrameProductList.value.length === 0) {
firstFrameProductList.value = JSON.parse(JSON.stringify(data.fileList || []))
}
} else {
if (lastFrameProductList.value.length === 0) {
lastFrameProductList.value = JSON.parse(JSON.stringify(data.fileList || []))
}
}
showProductList.value = true
}
const handleConfirmProduct = ({ data: productData }) => {
if (productType.value === 'first') {
// 准备图片数据
const imageItem: any = {
...productData,
isChecked: true,
type: 'ProductElement'
}
// 设置 minioUrl
imageItem.minioUrl =
productData.miniourl || getMinioUrl(imageItem.url || imageItem.imgUrl)
// 更新首帧产品列表,移除已选择的项
const productIndex = firstFrameProductList.value.findIndex(
(item: any) => item.id === productData.id
)
if (productIndex >= 0) {
firstFrameProductList.value.splice(productIndex, 1)
}
// 首尾帧模式,添加到 firstFrameList
// 先取消其他项的选中状态
firstFrameList.value.forEach((listItem: any) => {
listItem.isChecked = false
})
// 检查是否已存在,如果存在则更新,否则添加
const existingIndex = firstFrameList.value.findIndex(
(item: any) => item.id === productData.id
)
if (existingIndex >= 0) {
Object.assign(firstFrameList.value[existingIndex], imageItem)
} else {
imageItem.frameType = 'first'
firstFrameList.value.push(imageItem)
}
// 赋值给首帧选中对象
data.selectImg = { ...imageItem }
} else if (productType.value === 'last') {
// 准备图片数据
const imageItem: any = {
...productData,
isChecked: true,
type: 'ProductElement',
frameType: 'last'
}
// 设置 minioUrl
imageItem.minioUrl =
productData.miniourl || getMinioUrl(imageItem.url || imageItem.imgUrl)
// 更新尾帧产品列表,移除已选择的项
const productIndex = lastFrameProductList.value.findIndex(
(item: any) => item.id === productData.id
)
if (productIndex >= 0) {
lastFrameProductList.value.splice(productIndex, 1)
}
// 先取消其他项的选中状态
lastFrameList.value.forEach((listItem: any) => {
listItem.isChecked = false
})
// 检查是否已存在,如果存在则更新,否则添加
const existingIndex = lastFrameList.value.findIndex(
(item: any) => item.id === productData.id
)
if (existingIndex >= 0) {
Object.assign(lastFrameList.value[existingIndex], imageItem)
} else {
lastFrameList.value.push(imageItem)
}
// 赋值给尾帧选中对象
data.lastSelectImg = { ...imageItem }
}
showProductList.value = false
}
watch(
() => store.state.HomeStoreModule.uploadElement.length,
(newVal, oldVal) => {
@@ -952,6 +1157,20 @@ export default defineComponent({
}
)
// 监听 fileList 的变化,如果独立列表为空则重新初始化
watch(
() => data.fileList,
newFileList => {
if (firstFrameProductList.value.length === 0 && newFileList?.length > 0) {
firstFrameProductList.value = JSON.parse(JSON.stringify(newFileList))
}
if (lastFrameProductList.value.length === 0 && newFileList?.length > 0) {
lastFrameProductList.value = JSON.parse(JSON.stringify(newFileList))
}
},
{ deep: true }
)
watch(
() => store.state.HomeStoreModule.lastFrameList,
val => {
@@ -1039,7 +1258,14 @@ export default defineComponent({
setVideoRef,
handlePlayMotion,
isVideoPlaying,
showTips
showTips,
showProductList,
handleClickDesignMask,
productType,
handleConfirmProduct,
productFrameList,
showFirstFrameUpload,
showLastFrameUpload
}
},
directives: {
@@ -1239,6 +1465,15 @@ export default defineComponent({
}
> .upload_item {
border: none;
position: relative;
.design-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
}
.control-container {
width: 100%;