1681 lines
52 KiB
Vue
1681 lines
52 KiB
Vue
<template>
|
||
<div class="poseTransfer">
|
||
<div class="configuratioBox" :class="{ active: button.left }">
|
||
<div class="configuratio">
|
||
<div class="content">
|
||
<div class="video-type-container">
|
||
<div class="title">{{ $t('poseTransfer.VideoType') }}</div>
|
||
<a-select
|
||
class="video-type-selection"
|
||
v-model:value="videoType"
|
||
size="large"
|
||
placeholder="Please select"
|
||
>
|
||
<a-select-option
|
||
v-for="item in options"
|
||
:key="item.vlaue"
|
||
:value="item.value"
|
||
>
|
||
{{ item.label }}
|
||
</a-select-option>
|
||
</a-select>
|
||
</div>
|
||
<div class="selectImg">
|
||
<div class="head">
|
||
<div class="text">{{ $t('poseTransfer.SelectDesign') }}</div>
|
||
<i
|
||
v-show="videoType !== 2"
|
||
class="fi fi-rs-interrogation tips-icon"
|
||
@click="showTips = true"
|
||
/>
|
||
</div>
|
||
<div class="imgBox" v-mousewheel>
|
||
<div
|
||
class="item first-frame"
|
||
:class="{ active: item.id == selectImg.id }"
|
||
v-for="(item, index) in showFirstFrameList"
|
||
@click="selectImgItem(item)"
|
||
>
|
||
<div
|
||
class=""
|
||
v-if="item.status == 'uploading'"
|
||
style="display: flex; align-items: center"
|
||
>
|
||
<a-spin size="large" />
|
||
</div>
|
||
<img
|
||
v-show="item.designOutfitUrl || item.imgUrl || item.url"
|
||
:src="item.designOutfitUrl || item.imgUrl || item.url"
|
||
alt=""
|
||
/>
|
||
<div
|
||
v-show="item.designOutfitUrl || item.imgUrl || item.url"
|
||
class="btnBox"
|
||
>
|
||
<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' || (isDesignPage && videoType === 3)"
|
||
>
|
||
<i class="fi fi-rr-trash icon_delete"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<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"
|
||
:action="getUploadUrl() + '/api/history/toProductImageElementUpload'"
|
||
list-type="picture-card"
|
||
:capture="null"
|
||
:data="{
|
||
...upload
|
||
}"
|
||
:headers="{ Authorization: token }"
|
||
:before-upload="beforeUpload"
|
||
:multiple="!!upload.projectId"
|
||
accept=".jpg,.png,.jpeg,.bmp"
|
||
@change="file => fileUploadChange(file)"
|
||
>
|
||
<div class="upload_tip_block">
|
||
<i class="fi fi-br-upload"></i>
|
||
<!-- <img class="upload_img_icon" src="@/assets/images/homePage/add_file.png"> -->
|
||
</div>
|
||
</a-upload>
|
||
</div>
|
||
</div>
|
||
<template v-if="videoType === 3">
|
||
<div
|
||
v-show="lastFrameList?.length < 1"
|
||
class="upload_item item last_frames"
|
||
>
|
||
<div
|
||
class="design-mask"
|
||
v-if="isDesignPage && videoType === 3"
|
||
@click="handleClickDesignMask('last')"
|
||
/>
|
||
<div class="upload_file_item">
|
||
<a-upload
|
||
key="lastframes"
|
||
:action="
|
||
getUploadUrl() + '/api/history/toProductImageElementUpload'
|
||
"
|
||
list-type="picture-card"
|
||
:capture="null"
|
||
:data="{
|
||
...upload,
|
||
type: 'last'
|
||
}"
|
||
:headers="{ Authorization: token }"
|
||
:before-upload="beforeUpload"
|
||
accept=".jpg,.png,.jpeg,.bmp"
|
||
@change="file => fileUploadChangeLast(file)"
|
||
>
|
||
<div class="upload_tip_block">
|
||
<i class="fi fi-br-upload"></i>
|
||
<!-- <img class="upload_img_icon" src="@/assets/images/homePage/add_file.png"> -->
|
||
</div>
|
||
</a-upload>
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="item lastframe-list"
|
||
:class="{ active: item.id == lastSelectImg.id }"
|
||
v-for="(item, index) in lastFrameList"
|
||
@click="selectImgItem(item, true)"
|
||
>
|
||
<div
|
||
class=""
|
||
v-if="item.status == 'uploading'"
|
||
style="display: flex; align-items: center"
|
||
>
|
||
<a-spin size="large" />
|
||
</div>
|
||
<img
|
||
v-show="item.designOutfitUrl || item.imgUrl || item.url"
|
||
:src="item.designOutfitUrl || item.imgUrl || item.url"
|
||
alt=""
|
||
/>
|
||
<div
|
||
v-show="item.designOutfitUrl || item.imgUrl || item.url"
|
||
class="btnBox"
|
||
>
|
||
<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' || (isDesignPage && videoType === 3)"
|
||
>
|
||
<i class="fi fi-rr-trash icon_delete"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
<div class="prompt-input-container" v-show="!showMotion">
|
||
<div class="title" style="display: flex; gap: 0.5rem">
|
||
{{ $t('ProductImg.Prompt') }}
|
||
<a
|
||
:href="
|
||
locale == 'CHINESE_SIMPLIFIED'
|
||
? 'https://aida-user-manual-chinese.super.site/2b08f755cedd80a985cffdf2af80c538'
|
||
: 'https://aida-user-manual.super.site/advanced-tool/animated-product-image/to-product-video-prompt-assist '
|
||
"
|
||
target="_blank"
|
||
>
|
||
<i
|
||
class="fi fi-rs-interrogation tips-icon"
|
||
style="font-size: 1.8rem; color: #000"
|
||
/>
|
||
</a>
|
||
</div>
|
||
<!-- <div class="title">
|
||
<span>{{ $t('ProductImg.Prompt') }}</span>
|
||
<i class="fi fi-rs-interrogation tips-icon" />
|
||
</div> -->
|
||
<promptInput :content="inputPrompt" ref="promptInput" />
|
||
</div>
|
||
<div class="poses" v-show="showMotion">
|
||
<div class="head">
|
||
<div class="text">{{ $t('poseTransfer.Selectpose') }}</div>
|
||
</div>
|
||
<div class="imgBox" v-mousewheel>
|
||
<div
|
||
class="item"
|
||
v-for="item in poseList"
|
||
:key="item.id"
|
||
@click="selectPose(item)"
|
||
>
|
||
<video :ref="el => setVideoRef(item.id, el)" :src="item.video" />
|
||
<div class="btnBox">
|
||
<div :class="{ active: item.isChecked }">
|
||
<i class="fi fi-br-check"></i>
|
||
</div>
|
||
</div>
|
||
<div class="control-container">
|
||
<div class="icon-list">
|
||
<SvgIcon
|
||
class="play-icon"
|
||
@click.stop="handlePlayMotion(item)"
|
||
:name="isVideoPlaying(item.id) ? 'CPause' : 'CPlay'"
|
||
size="20"
|
||
color="#fff"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="generage_btn_box" style="margin-left: auto">
|
||
<!-- <div class="generage_btn started_btn" v-show="!isGenerate" @click="getgenerate">
|
||
{{ $t('Generate.Generate') }}
|
||
</div> -->
|
||
<div class="generage_btn started_btn" v-show="!isGenerate">
|
||
<i
|
||
class="fi fi-bs-magic-wand"
|
||
style="background-color: #000; font-size: 2.3rem; flex: 1; margin: 0"
|
||
@click="getgenerate()"
|
||
></i>
|
||
<div
|
||
v-show="showMotion"
|
||
class="icon iconfont icon-xiala"
|
||
:class="{ active: speedState }"
|
||
@click.stop="openSpeed"
|
||
></div>
|
||
<div class="content" v-show="speedState">
|
||
<div
|
||
v-for="item in speedList"
|
||
:key="item.value"
|
||
:class="{ active: item.value == speedData.value }"
|
||
@click.stop="setSpeed(item)"
|
||
:title="item.title"
|
||
>
|
||
{{ item.label }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-show="isGenerate" class="generage_btn started_btn">
|
||
<i class="fi fi-br-loading"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="likeBox">
|
||
<!-- {{ locale }}
|
||
<img src="@/assets/images/homePage/toolsGuide/productCN.png" alt="">
|
||
<img src="@/assets/images/homePage/toolsGuide/productEN.png" alt=""> -->
|
||
<div class="element">
|
||
<div class="title">
|
||
<i class="fi fi-rs-comments"></i>
|
||
<span>{{ $t('poseTransfer.LikeVideo') }}</span>
|
||
</div>
|
||
<div class="content">
|
||
<generalDrag
|
||
ref="generalDragLeft"
|
||
:list="likeList"
|
||
:isLike="true"
|
||
:isVideo="true"
|
||
@setBtn="likeSetBtn"
|
||
></generalDrag>
|
||
</div>
|
||
<!-- <div class="btnLeft" @click="setSize('left')" :class="{'active':button.left}">
|
||
<span class="icon iconfont icon-xiala"></span>
|
||
</div> -->
|
||
<div class="btnRight" @click="setSize('right')" :class="{ active: button.right }">
|
||
<span class="icon iconfont icon-xiala"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="noLikeBox" :class="{ active: button.right, designPage: isDesignPage }">
|
||
<div class="element">
|
||
<div class="title">
|
||
<i class="fi fi-rs-comments"></i>
|
||
<span>{{ $t('poseTransfer.InputVideo') }}</span>
|
||
</div>
|
||
<div class="content">
|
||
<generalDrag
|
||
ref="generalDragRight"
|
||
:list="noLikeList"
|
||
:isVideo="true"
|
||
@setBtn="noLikeSetBtn"
|
||
></generalDrag>
|
||
</div>
|
||
</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">
|
||
import {
|
||
defineComponent,
|
||
computed,
|
||
ref,
|
||
inject,
|
||
nextTick,
|
||
watch,
|
||
createVNode,
|
||
toRefs,
|
||
reactive,
|
||
onMounted
|
||
} from 'vue'
|
||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
||
import { Https } from '@/tool/https'
|
||
import { useStore } from 'vuex'
|
||
import { Upload, message, Modal } from 'ant-design-vue'
|
||
import { useI18n } from 'vue-i18n'
|
||
import generalDrag from '@/component/modules/generalDrag.vue'
|
||
import { getUploadUrl, isMoible, getMinioUrl } from '@/tool/util'
|
||
import { getCookie, setCookie } from '@/tool/cookie'
|
||
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,
|
||
Product,
|
||
},
|
||
props: {
|
||
isDesignPage: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
source: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
emit: ['unLike'],
|
||
setup(props, { emit }) {
|
||
const { t, locale } = useI18n()
|
||
const store = useStore()
|
||
const route = useRoute()
|
||
const data: any = reactive({
|
||
button: {
|
||
left: false,
|
||
right: false
|
||
},
|
||
currentList: [],
|
||
fileList: [], // 默认上传图片的fileList
|
||
lastSelectImg: {}, // 选中的尾帧
|
||
selectImg: {},
|
||
token: getCookie('token'),
|
||
upload: {
|
||
projectId: computed(() => store.state.Workspace.probjects.id),
|
||
type: null // first首帧 last尾帧
|
||
},
|
||
waitList: [],
|
||
likeList: computed(() => {
|
||
if (!route.query?.id && route.query.tools == 'poseTransfer') {
|
||
return []
|
||
} else {
|
||
return store.state.HomeStoreModule.poseTransfer.likedList
|
||
}
|
||
}),
|
||
noLikeList: computed(() => {
|
||
if (!route.query?.id && route.query.tools == 'poseTransfer') {
|
||
return []
|
||
} else {
|
||
return store.state.HomeStoreModule.poseTransfer.list
|
||
}
|
||
}),
|
||
isGenerate: false, //判断是否正在进行generate
|
||
removeGenerate: false,
|
||
generateTime: null as any,
|
||
poseList: [],
|
||
selectPose: null as any
|
||
})
|
||
let speed = reactive({
|
||
speedList: [
|
||
{
|
||
title: '',
|
||
label: t('speedList.toproductBasic'),
|
||
value: ''
|
||
},
|
||
{
|
||
title: '',
|
||
label: t('speedList.toproductFlus'),
|
||
value: 'wx'
|
||
}
|
||
],
|
||
speedState: false,
|
||
speedData: {
|
||
title: 'Generate high-quality content',
|
||
label: t('speedList.toproductBasic'),
|
||
value: ''
|
||
}
|
||
})
|
||
const showTips = ref(false)
|
||
const setIsShowMark: any = inject('setIsShowMark')
|
||
const createProbject: any = inject('createProbject', () => {})
|
||
const dataDom = reactive({
|
||
generalDragLeft: null as any,
|
||
generalDragRight: null as any,
|
||
scaleVideo: null as any,
|
||
promptInput: null as any
|
||
})
|
||
const selectImgItem = (item: any, isLastFrame = false) => {
|
||
// 如果点击已选中的项,则取消选中并清除对应选择
|
||
if (item.isChecked) {
|
||
item.isChecked = false
|
||
if (isLastFrame) {
|
||
data.lastSelectImg = {}
|
||
} else {
|
||
data.selectImg = {}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 处理尾帧选择
|
||
if (isLastFrame) {
|
||
;(lastFrameList.value || []).forEach(
|
||
(listItem: any) => (listItem.isChecked = false)
|
||
)
|
||
item.isChecked = true
|
||
data.lastSelectImg = item
|
||
if (item.url || item.imgUrl) {
|
||
data.lastSelectImg.minioUrl = getMinioUrl(item.url || item.imgUrl)
|
||
}
|
||
return
|
||
}
|
||
|
||
// 处理首帧选择
|
||
showFirstFrameList.value.forEach((listItem: any) => (listItem.isChecked = false))
|
||
data.currentList.forEach((listItem: any) => (listItem.isChecked = false))
|
||
item.isChecked = true
|
||
data.selectImg = item
|
||
if (item.url || item.imgUrl) {
|
||
data.selectImg.minioUrl = getMinioUrl(item.url || item.imgUrl)
|
||
}
|
||
}
|
||
const openSetData = (designList: any) => {
|
||
if (props.isDesignPage) {
|
||
//标识design页面打开的tools
|
||
data.fileList = designList
|
||
} else {
|
||
data.currentList = store.state.UploadFilesModule.modularData.toProduct
|
||
data.currentList = data.currentList ? data.currentList : []
|
||
setIsShowMark(false)
|
||
}
|
||
// dataDom.generalDrag.openSetData()
|
||
if (data.poseList.length == 0) {
|
||
getPoseList()
|
||
}
|
||
}
|
||
// 存储视频元素的引用
|
||
const videoRefs = ref<Record<number, HTMLVideoElement | null>>({})
|
||
// 存储视频播放状态
|
||
const videoPlayingStates = ref<Record<number, boolean>>({})
|
||
|
||
// 设置视频 ref
|
||
const setVideoRef = (id: number, el: HTMLVideoElement | null) => {
|
||
if (el) {
|
||
videoRefs.value[id] = el
|
||
// 初始化播放状态
|
||
videoPlayingStates.value[id] = !el.paused
|
||
// 监听播放事件
|
||
el.addEventListener('play', () => {
|
||
videoPlayingStates.value[id] = true
|
||
})
|
||
// 监听暂停事件
|
||
el.addEventListener('pause', () => {
|
||
videoPlayingStates.value[id] = false
|
||
})
|
||
// 监听结束事件
|
||
el.addEventListener('ended', () => {
|
||
videoPlayingStates.value[id] = false
|
||
})
|
||
}
|
||
}
|
||
|
||
// 检查视频是否正在播放
|
||
const isVideoPlaying = (id: number) => {
|
||
return videoPlayingStates.value[id] || false
|
||
}
|
||
|
||
// 播放视频
|
||
const handlePlayMotion = (item: any) => {
|
||
const video = videoRefs.value[item.id]
|
||
if (video) {
|
||
if (video.paused) {
|
||
video.play().catch(err => {
|
||
console.error('播放视频失败:', err)
|
||
})
|
||
} else {
|
||
video.pause()
|
||
}
|
||
}
|
||
}
|
||
|
||
const getPoseList = () => {
|
||
Https.axiosGet(Https.httpUrls.getAllPose).then(rv => {
|
||
rv[0].isChecked = true
|
||
data.selectPose = rv[0]?.id || 1
|
||
data.poseList = rv
|
||
})
|
||
}
|
||
const setSize = (str: any) => {
|
||
data.button[str] = !data.button[str]
|
||
setItemPosition()
|
||
}
|
||
const setItemPosition = () => {
|
||
setTimeout(() => {
|
||
dataDom.generalDragLeft.setItemPosition()
|
||
dataDom.generalDragRight.setItemPosition()
|
||
}, 200)
|
||
}
|
||
const getgenerate = async () => {
|
||
if (videoType.value === 3 && !data.lastSelectImg.minioUrl) {
|
||
message.info(t('poseTransfer.NeedLastFrame'))
|
||
return
|
||
}
|
||
if (!data.selectImg.minioUrl) return message.info(t('poseTransfer.NeedFirstFrame'))
|
||
if (data.isGenerate) return
|
||
await new Promise((res, reject) => {
|
||
Modal.confirm({
|
||
title: t('poseTransfer.jsContent1'),
|
||
icon: createVNode(ExclamationCircleOutlined),
|
||
okText: 'Yes',
|
||
cancelText: 'No',
|
||
mask: false,
|
||
centered: true,
|
||
onOk() {
|
||
res()
|
||
},
|
||
cancel() {
|
||
reject()
|
||
}
|
||
})
|
||
})
|
||
|
||
data.isGenerate = true
|
||
|
||
let value = {
|
||
poseId: data.selectPose,
|
||
projectId: store.state.Workspace.probjects.id,
|
||
productImage: data.selectImg.minioUrl,
|
||
modelName: speed.speedData.value,
|
||
isDefaultLike: false, //表示是否生成就like
|
||
parentId: data.selectImg?.parentId, //parentId 添加在指定父级里面
|
||
userLikeSortId: null, //是否进行排序
|
||
mode: videoType.value
|
||
}
|
||
if (!showMotion.value) {
|
||
value.modelName = ''
|
||
}
|
||
if (videoType.value === 2) {
|
||
const prompt = dataDom.promptInput.getFullText()
|
||
value.prompt = prompt
|
||
}
|
||
if (videoType.value === 3) {
|
||
const prompt = dataDom.promptInput.getFullText()
|
||
value.prompt = prompt
|
||
const lastFrameProductImage = data.lastSelectImg.minioUrl
|
||
value.lastFrameProductImage = lastFrameProductImage
|
||
}
|
||
Https.axiosPost(Https.httpUrls.poseTransform, value)
|
||
.then(rv => {
|
||
data.noLikeList.unshift({
|
||
taskId: rv.taskId,
|
||
parentId: data.selectImg.parentId
|
||
})
|
||
setGenerate(rv.taskId)
|
||
})
|
||
.catch((res: any) => {
|
||
data.isGenerate = false
|
||
if (res.errCode === 2) {
|
||
Modal.confirm({
|
||
title: res.errMsg,
|
||
icon: createVNode(ExclamationCircleOutlined),
|
||
okText: 'Yes',
|
||
cancelText: 'No',
|
||
mask: false,
|
||
zIndex: 99999,
|
||
centered: true,
|
||
onOk() {
|
||
store.commit('setUpgradePlan', true)
|
||
},
|
||
onCancel() {}
|
||
})
|
||
}
|
||
})
|
||
}
|
||
const setGenerate = (dataList: any) => {
|
||
let list: any = [dataList]
|
||
data.waitList = list
|
||
let state = true
|
||
data.generateTime = setInterval(() => {
|
||
if (!data.isGenerate) return
|
||
if (!state) return
|
||
state = false
|
||
Https.axiosPost(Https.httpUrls.poseTransformResult, list)
|
||
.then(rv => {
|
||
state = true
|
||
if (data.isGenerate) {
|
||
//防止取消后有正在执行的获取状态
|
||
// data.waitList = rv.filter((item:any)=>item.status != 'Success' && item.status != 'Fail' && item.status != 'Invalid')
|
||
rv.forEach((element: any) => {
|
||
if (element.status == 'Success') {
|
||
element.url = element.firstFrameUrl
|
||
let index = data.noLikeList.findIndex(
|
||
(obj: any) => obj.taskId === element.taskId
|
||
)
|
||
data.noLikeList[index] = element
|
||
list = ''
|
||
clearInterval(data.generateTime)
|
||
data.isGenerate = false
|
||
// if(list?.filter)list = list?.filter((item:any) => item !== element.taskId);
|
||
store.dispatch('getCredits')
|
||
} else if (element.status == 'Fail') {
|
||
let index = data.noLikeList.findIndex(
|
||
(obj: any) => obj.taskId === element.taskId
|
||
)
|
||
message.info(t('ProductImg.jsContent3'))
|
||
data.noLikeList.splice(index, 1)
|
||
clearInterval(data.generateTime)
|
||
data.isGenerate = false
|
||
store.dispatch('getCredits')
|
||
}
|
||
})
|
||
}
|
||
})
|
||
.catch(res => {
|
||
let index = data.noLikeList.findIndex((obj: any) => obj.taskId === list)
|
||
data.noLikeList.splice(index, 1)
|
||
clearInterval(data.generateTime)
|
||
data.isGenerate = false
|
||
})
|
||
}, 10000)
|
||
}
|
||
const setRemoveGenerate = () => {
|
||
//取消操作
|
||
data.isGenerate = false
|
||
clearInterval(data.generateTime)
|
||
if (data.waitList) {
|
||
// let str = data.waitList.map((obj:any) => obj.taskId).join(',');
|
||
let value = {
|
||
uniqueId: data.waitList[0],
|
||
userId: store.state.UserHabit.userDetail.userId,
|
||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||
type: 'PoseTransferation'
|
||
}
|
||
Https.axiosGet(Https.httpUrls.generateStopWaiting, { params: value })
|
||
.then(rv => {
|
||
data.waitList = []
|
||
const indexes = data.noLikeList
|
||
.map((item, index) => (item?.status !== 'Success' ? index : -1))
|
||
.filter(index => index !== -1)
|
||
indexes.forEach((itemIndex: number) => {
|
||
data.noLikeList.splice(itemIndex, 1)
|
||
})
|
||
})
|
||
.catch(res => {})
|
||
}
|
||
}
|
||
let isSelectObject = false
|
||
watch(
|
||
() => route?.query,
|
||
newVal => {
|
||
if (!newVal.id) {
|
||
isSelectObject = false
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
let beforeUpload = async (file: any) => {
|
||
const isJpgOrPng =
|
||
file.type === 'image/jpeg' ||
|
||
file.type === 'image/png' ||
|
||
file.type === 'image/jpg' ||
|
||
file.type === 'image/bmp'
|
||
if (!isJpgOrPng) {
|
||
message.info(useI18n().t('MoodboardUpload.jsContent3'))
|
||
}
|
||
const isLt2M = file.size / 1024 / 1024 < 5
|
||
if (!isLt2M) {
|
||
message.info(useI18n().t('MoodboardUpload.jsContent4'))
|
||
}
|
||
if (!route?.query?.id && !isSelectObject) {
|
||
isSelectObject = true
|
||
await createProbject()
|
||
}
|
||
return (isJpgOrPng && isLt2M && data.upload.projectId) || Upload.LIST_IGNORE
|
||
}
|
||
const fileUploadChange = (value: any) => {
|
||
let file = value.file
|
||
let bor = true
|
||
if (file.status === 'done') {
|
||
let res = JSON.parse(file.xhr.response)
|
||
if (res.errCode == 0) {
|
||
file.imgUrl = res.data.url
|
||
file.id = res.data.id
|
||
data.currentList.forEach((listItem: any) => (listItem.isChecked = false))
|
||
file.type = 'ProductElement'
|
||
if (videoType.value === 3) {
|
||
file.frameType = 'first'
|
||
}
|
||
let storeData = {
|
||
str: 'add',
|
||
list: [file]
|
||
}
|
||
store.commit('setUploadElement', storeData)
|
||
// 上传成功后,设置选中状态
|
||
file.isChecked = true
|
||
// 取消 showFirstFrameList 中其他项的选中状态
|
||
showFirstFrameList.value.forEach((listItem: any) => {
|
||
if (listItem.id !== file.id) {
|
||
listItem.isChecked = false
|
||
}
|
||
})
|
||
data.selectImg = res.data
|
||
if (res.data.url || res.data.imgUrl) {
|
||
data.selectImg.minioUrl = getMinioUrl(res.data.url || res.data.imgUrl)
|
||
}
|
||
} else {
|
||
bor = false
|
||
}
|
||
} else if (file.status === 'error') {
|
||
bor = false
|
||
}
|
||
}
|
||
const fileUploadChangeLast = (value: any) => {
|
||
const file = value.file
|
||
if (file.status === 'done') {
|
||
const res = JSON.parse(file.xhr.response)
|
||
if (res.errCode == 0) {
|
||
file.imgUrl = res.data.url
|
||
file.id = res.data.id
|
||
file.type = 'ProductElement'
|
||
file.frameType = 'last'
|
||
// 取消尾帧列表选中状态
|
||
;(value?.fileList || []).forEach(
|
||
(listItem: any) => (listItem.isChecked = false)
|
||
)
|
||
// 设置当前为选中并记录选择
|
||
file.isChecked = true
|
||
data.lastSelectImg = res.data
|
||
}
|
||
}
|
||
// 同步尾帧文件列表到全局 store
|
||
store.commit('setPoseTransferLastFrameList', {
|
||
str: 'set',
|
||
list: [file]
|
||
})
|
||
}
|
||
const likeSetBtn = (id: any, str: string) => {
|
||
data.likeList.forEach((item: any, index: any) => {
|
||
if (item.id == id && id) {
|
||
if (str == 'zoom') {
|
||
showViewVideo({ url: item.videoUrl })
|
||
} else if (str == 'like') {
|
||
likeFile(item, 'noLike', index)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
const noLikeSetBtn = (id: any, str: string) => {
|
||
if (str == 'delete') {
|
||
let value = {
|
||
id,
|
||
projectId: store.state.Workspace.probjects.id
|
||
}
|
||
Https.axiosGet(Https.httpUrls.generateDeleteResult, { params: value }).then(
|
||
() => {
|
||
let index = data.noLikeList.findIndex((v: any) => v.id == id)
|
||
data.noLikeList.splice(index, 1)
|
||
}
|
||
)
|
||
} else {
|
||
data.noLikeList.forEach((item: any, index: any) => {
|
||
if (item.id == id && id) {
|
||
if (str == 'zoom') {
|
||
showViewVideo({ url: item.videoUrl })
|
||
} else if (str == 'like') {
|
||
likeFile(item, 'like', index)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
let likeFile = (item: any, str: any, index: any) => {
|
||
let url
|
||
let value = {}
|
||
if (str == 'like') {
|
||
value = {
|
||
likeOrDislike: 'like',
|
||
transformedId: item.id,
|
||
projectId: store.state.Workspace.probjects.id,
|
||
collectionSortParentId: props.isDesignPage ? item.parentId : ''
|
||
}
|
||
} else {
|
||
value = {
|
||
likeOrDislike: 'dislike',
|
||
transformedId: item.id,
|
||
projectId: store.state.Workspace.probjects.id,
|
||
collectionSortParentId: props.isDesignPage ? item.parentId : ''
|
||
}
|
||
if (props.isDesignPage) {
|
||
emit('unLike', item)
|
||
}
|
||
}
|
||
Https.axiosPost(Https.httpUrls.poselikeOrDisike, {}, { params: value })
|
||
.then(rv => {
|
||
if (str == 'like') {
|
||
item.newLike = true
|
||
// 从 noLikeList 中查找索引并删除
|
||
const noLikeIndex = store.state.HomeStoreModule.poseTransfer.list.findIndex(
|
||
(v: any) => v.id === item.id
|
||
)
|
||
if (noLikeIndex !== -1) {
|
||
let deleteValue = {
|
||
list: [],
|
||
str: 'splice',
|
||
index: noLikeIndex
|
||
}
|
||
store.commit('setPoseTransfer', deleteValue)
|
||
}
|
||
// 添加到 likedList
|
||
let addValue = {
|
||
likedList: [
|
||
{
|
||
...item,
|
||
sort: rv?.sort ?? item.sort,
|
||
parentId: rv?.parentId ?? item.parentId
|
||
}
|
||
],
|
||
str: 'add',
|
||
index: -1
|
||
}
|
||
store.commit('setPoseTransfer', addValue)
|
||
} else {
|
||
item.newLike = false
|
||
// 从 likedList 中查找索引并删除
|
||
const likedIndex =
|
||
store.state.HomeStoreModule.poseTransfer.likedList.findIndex(
|
||
(v: any) => v.id === item.id
|
||
)
|
||
if (likedIndex !== -1) {
|
||
let deleteValue = {
|
||
likedList: [],
|
||
str: 'splice',
|
||
index: likedIndex
|
||
}
|
||
store.commit('setPoseTransfer', deleteValue)
|
||
}
|
||
// 添加到 noLikeList
|
||
let addValue = {
|
||
list: [
|
||
{
|
||
...item
|
||
}
|
||
],
|
||
str: 'add',
|
||
index: -1
|
||
}
|
||
store.commit('setPoseTransfer', addValue)
|
||
}
|
||
})
|
||
.catch(res => {
|
||
console.error('likeFile error:', res)
|
||
})
|
||
}
|
||
const selectPose = (item: any) => {
|
||
data.poseList.forEach((listItem: any) => (listItem.isChecked = false))
|
||
item.isChecked = true
|
||
data.selectPose = item?.id || 1
|
||
}
|
||
const openSpeed = () => {
|
||
speed.speedState = !speed.speedState
|
||
if (speed.speedState) {
|
||
document.addEventListener('click', openSpeed)
|
||
} else {
|
||
document.removeEventListener('click', openSpeed)
|
||
}
|
||
}
|
||
const setSpeed = (item: any) => {
|
||
speed.speedData = item
|
||
speed.speedState = false
|
||
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
|
||
}
|
||
Https.axiosPost(
|
||
Https.httpUrls.toProductImageElementDelete,
|
||
{},
|
||
{ params: value }
|
||
).then(rv => {
|
||
if (isLastFrame) {
|
||
// 如果删除的是当前选中的尾帧,清空选中状态
|
||
if (data.lastSelectImg?.id === item.id) {
|
||
data.lastSelectImg = {}
|
||
}
|
||
store.commit('setPoseTransferLastFrameList')
|
||
} else {
|
||
// 如果删除的是当前选中的首帧,清空选中状态
|
||
if (data.selectImg?.id === item.id) {
|
||
data.selectImg = {}
|
||
}
|
||
let storeData = {
|
||
str: 'delete',
|
||
index
|
||
}
|
||
store.commit('setUploadElement', storeData)
|
||
}
|
||
})
|
||
}
|
||
|
||
const videoType = ref(2)
|
||
const showMotion = computed(() => videoType.value === 1)
|
||
const inputPrompt = computed(() => {
|
||
if (videoType.value === 2) {
|
||
return getFirstFrame(t)
|
||
}
|
||
if (videoType.value === 3) {
|
||
return getFirstAndLastFrame(t)
|
||
}
|
||
})
|
||
const options = ref([
|
||
{ vlaue: 2, label: t('poseTransfer.FirstFrame') },
|
||
{ value: 3, label: t('poseTransfer.FirstAndLastFrames') },
|
||
{ value: 1, label: t('poseTransfer.FirstFrameAndSkeleton') }
|
||
])
|
||
|
||
const firstFrameList = ref([])
|
||
const lastFrameList = ref([])
|
||
const showFirstFrameList = computed(() => {
|
||
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) => {
|
||
if (props.isDesignPage || (!route.query?.id && !route.query?.history)) return
|
||
data.fileList = store.state.HomeStoreModule.uploadElement.filter(
|
||
item => !item.frameType
|
||
)
|
||
|
||
firstFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
||
item => item.frameType === 'first'
|
||
)
|
||
|
||
lastFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
||
item => item.frameType === 'last'
|
||
)
|
||
// 更新 showFirstFrameList 中项的选中状态
|
||
showFirstFrameList.value.forEach((listItem: any) => {
|
||
if (listItem.id == data.selectImg.id) {
|
||
listItem.isChecked = true
|
||
} else {
|
||
listItem.isChecked = false
|
||
}
|
||
})
|
||
},
|
||
{
|
||
immediate: true
|
||
}
|
||
)
|
||
|
||
// 监听 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 => {
|
||
if (props.isDesignPage) return
|
||
lastFrameList.value = val
|
||
if (val.length > 0) {
|
||
val[0].isChecked = true
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
|
||
// 首帧图片的type 切换为首尾帧时type=first,其他情况type为null
|
||
watch(
|
||
() => videoType.value,
|
||
newVal => {
|
||
if (newVal === 3) {
|
||
data.upload.type = 'first'
|
||
} else {
|
||
delete data.upload.type
|
||
}
|
||
// 当 videoType 改变时,检查 selectImg 是否在当前 showFirstFrameList 中
|
||
// 如果不在,清空选中状态或选择列表中的第一项
|
||
const currentList = showFirstFrameList.value
|
||
if (data.selectImg?.id) {
|
||
const exists = currentList.some((item: any) => item.id === data.selectImg.id)
|
||
if (!exists) {
|
||
// 如果当前选中的项不在新列表中,清空选中状态
|
||
data.selectImg = {}
|
||
// 取消所有项的选中状态
|
||
currentList.forEach((item: any) => (item.isChecked = false))
|
||
}
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
|
||
watch(
|
||
() => data.noLikeList.length,
|
||
(newVal, oldVal) => {
|
||
nextTick(() => {
|
||
let list = store.state.HomeStoreModule.poseTransfer.list
|
||
let taskIdList = list.filter((item: any) => !item.videoUrl)[0]
|
||
if (taskIdList?.length > 0) {
|
||
data.isGenerate = true
|
||
setGenerate(taskIdList[0].taskId)
|
||
}
|
||
})
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
|
||
onBeforeUnmount(() => {
|
||
clearInterval(data.generateTime)
|
||
data.isGenerate = false
|
||
})
|
||
|
||
return {
|
||
...toRefs(speed),
|
||
...toRefs(dataDom),
|
||
...toRefs(data),
|
||
lastFrameList,
|
||
firstFrameList,
|
||
showFirstFrameList,
|
||
openSetData,
|
||
selectImgItem,
|
||
setSize,
|
||
setItemPosition,
|
||
getgenerate,
|
||
getUploadUrl,
|
||
beforeUpload,
|
||
fileUploadChange,
|
||
fileUploadChangeLast,
|
||
setRemoveGenerate,
|
||
likeSetBtn,
|
||
noLikeSetBtn,
|
||
selectPose,
|
||
openSpeed,
|
||
setSpeed,
|
||
setUploadDelete,
|
||
locale,
|
||
videoType,
|
||
options,
|
||
showMotion,
|
||
setVideoRef,
|
||
handlePlayMotion,
|
||
isVideoPlaying,
|
||
showTips,
|
||
showProductList,
|
||
handleClickDesignMask,
|
||
productType,
|
||
handleConfirmProduct,
|
||
productFrameList,
|
||
showFirstFrameUpload,
|
||
showLastFrameUpload,
|
||
inputPrompt
|
||
}
|
||
},
|
||
directives: {
|
||
mousewheel: {
|
||
mounted(el) {
|
||
el.addEventListener(
|
||
'wheel',
|
||
(e: WheelEvent) => {
|
||
let num = 0
|
||
if (e.deltaY > 0) {
|
||
num = 25
|
||
} else {
|
||
num = -25
|
||
}
|
||
el.scrollBy(num, 0)
|
||
},
|
||
{ passive: true }
|
||
)
|
||
}
|
||
}
|
||
},
|
||
provide() {
|
||
return {}
|
||
}
|
||
})
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.poseTransfer {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
font-size: 2rem;
|
||
font-weight: 900;
|
||
display: flex;
|
||
> .configuratioBox {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding-right: 3.8rem;
|
||
width: 39rem;
|
||
&.active {
|
||
width: 0;
|
||
overflow: hidden;
|
||
}
|
||
> .generate {
|
||
margin-left: auto;
|
||
> .started_btn {
|
||
font-weight: 300;
|
||
}
|
||
.generage_btn {
|
||
width: 10rem;
|
||
position: relative;
|
||
}
|
||
.icon-xiala {
|
||
margin-left: 1rem;
|
||
transition: all 0.3s;
|
||
cursor: pointer;
|
||
&.active {
|
||
transform: rotate(180deg);
|
||
}
|
||
}
|
||
.content {
|
||
position: absolute;
|
||
top: 100%;
|
||
width: 100%;
|
||
left: 0rem;
|
||
text-align: center;
|
||
border-radius: calc(1rem * 1.2);
|
||
overflow: hidden;
|
||
z-index: 3;
|
||
margin-top: 0.2rem;
|
||
|
||
> div {
|
||
background: #cccccc;
|
||
line-height: 2;
|
||
font-size: 1.8rem;
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
&.active {
|
||
background-color: #616161;
|
||
}
|
||
}
|
||
> div:hover {
|
||
background: #999999;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
> .configuratioBox > .configuratio {
|
||
width: 100%;
|
||
padding-bottom: 1rem;
|
||
> .content {
|
||
> .selectImg,
|
||
> .poses {
|
||
display: flex;
|
||
flex-direction: column;
|
||
> .imgBox {
|
||
flex: 1;
|
||
max-height: 45rem;
|
||
margin-top: 2rem;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
width: 100%;
|
||
overflow: hidden;
|
||
overflow-x: auto;
|
||
column-gap: 2.4rem;
|
||
position: relative;
|
||
> .item {
|
||
width: 12.7rem;
|
||
height: 17.8rem;
|
||
cursor: pointer;
|
||
overflow: hidden;
|
||
display: flex;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
position: relative;
|
||
:deep(.ant-checkbox-wrapper) {
|
||
position: absolute;
|
||
top: 2rem;
|
||
right: 2rem;
|
||
}
|
||
> .btnBox {
|
||
position: absolute;
|
||
right: 1rem;
|
||
top: 1rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
> div {
|
||
width: 2rem;
|
||
height: 2rem;
|
||
display: flex;
|
||
border: 1px solid;
|
||
align-items: center;
|
||
border-radius: 0.5rem;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
margin-bottom: 1rem;
|
||
> i {
|
||
display: flex;
|
||
}
|
||
> .fi-br-check {
|
||
color: #fff;
|
||
display: none;
|
||
}
|
||
&.active {
|
||
background: #000;
|
||
> i {
|
||
display: flex;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
> .btnBox {
|
||
position: absolute;
|
||
right: 1rem;
|
||
top: 1rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
> div {
|
||
width: 2rem;
|
||
height: 2rem;
|
||
display: flex;
|
||
border: 1px solid;
|
||
align-items: center;
|
||
border-radius: 0.5rem;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
margin-bottom: 1rem;
|
||
> i {
|
||
display: flex;
|
||
}
|
||
> .fi-br-check {
|
||
color: #fff;
|
||
display: none;
|
||
}
|
||
&.active {
|
||
background: #000;
|
||
> i {
|
||
display: flex;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
> img {
|
||
width: 100%;
|
||
object-fit: contain;
|
||
border: 1px solid #d0d0d0;
|
||
}
|
||
}
|
||
> .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%;
|
||
height: 3.3rem;
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
background: linear-gradient(
|
||
180deg,
|
||
rgba(8, 9, 13, 0) 0%,
|
||
rgba(8, 9, 13, 0.27) 80.37%
|
||
);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
.icon-list {
|
||
// height: 50%;
|
||
// width: calc(100% - 1.6rem);
|
||
// border-top: 1px solid #fff;
|
||
padding-left: 1rem;
|
||
display: flex;
|
||
box-sizing: border-box;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
.play-icon {
|
||
width: 2rem;
|
||
height: 2rem;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
> .head {
|
||
color: #000;
|
||
font-weight: 500;
|
||
display: flex;
|
||
align-items: center;
|
||
column-gap: 1rem;
|
||
.tips-icon {
|
||
cursor: pointer;
|
||
display: flex;
|
||
}
|
||
> .text {
|
||
// display: inline-block;
|
||
font-size: 1.8rem;
|
||
}
|
||
}
|
||
}
|
||
.prompt-input-container {
|
||
margin-top: 4rem;
|
||
.title {
|
||
display: flex;
|
||
align-items: center;
|
||
column-gap: 1rem;
|
||
i {
|
||
display: flex;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
}
|
||
.title {
|
||
font-size: 1.8rem;
|
||
color: #000;
|
||
margin-bottom: 1.4rem;
|
||
font-weight: 500;
|
||
}
|
||
> .poses {
|
||
margin-top: 3rem;
|
||
}
|
||
}
|
||
}
|
||
> .likeBox,
|
||
> .noLikeBox {
|
||
flex: 1;
|
||
position: relative;
|
||
> .element {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
> .btnLeft,
|
||
> .btnRight {
|
||
position: absolute;
|
||
width: 3rem;
|
||
height: 7rem;
|
||
background: #fff;
|
||
border: 2px solid;
|
||
border-right: none;
|
||
border-radius: 2rem 0 0 2rem;
|
||
top: 50%;
|
||
transform: translate(-100%, -50%);
|
||
left: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 2;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
> span {
|
||
transition: all 0.3s;
|
||
transform: rotate(90deg);
|
||
}
|
||
|
||
&.active {
|
||
> span {
|
||
transform: rotate(270deg);
|
||
}
|
||
}
|
||
}
|
||
> .btnRight {
|
||
left: calc(100% + 3rem);
|
||
transform: translate(-100%, -50%) rotate(180deg);
|
||
&:hover {
|
||
width: 4rem;
|
||
left: calc(100% + 4rem);
|
||
}
|
||
}
|
||
> .content {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
padding: 1.7rem 2rem;
|
||
border-radius: 3rem;
|
||
background: #f7f8fa;
|
||
}
|
||
> .title {
|
||
margin-bottom: 2rem;
|
||
font-size: 1.6rem;
|
||
font-weight: 900;
|
||
> span {
|
||
margin-left: 1rem;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
> .designPage {
|
||
margin-right: 4rem;
|
||
}
|
||
> .noLikeBox {
|
||
padding-left: 2.3rem;
|
||
&.active {
|
||
flex: 0;
|
||
overflow: hidden;
|
||
}
|
||
}
|
||
|
||
.upload_file_item {
|
||
width: 100%;
|
||
height: 100%;
|
||
:deep(.ant-upload-picture-card-wrapper) {
|
||
width: 100% !important;
|
||
height: 100%;
|
||
.ant-upload-list-picture-card {
|
||
width: 100%;
|
||
height: 100%;
|
||
.ant-upload-select-picture-card {
|
||
width: 100%;
|
||
height: 100%;
|
||
border: 1px solid #000;
|
||
background: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.video-type-container {
|
||
margin-bottom: 4rem;
|
||
font-weight: 500;
|
||
.title {
|
||
font-size: 1.8rem;
|
||
color: #000;
|
||
margin-bottom: 1.4rem;
|
||
}
|
||
:deep(.ant-select) {
|
||
width: 100%;
|
||
.ant-select-selector {
|
||
border: 2px solid #d0d0d0;
|
||
border-radius: 1rem;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|