1342 lines
40 KiB
Vue
1342 lines
40 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"
|
|
:class="{ active: item.id == selectImg.id }"
|
|
v-for="(item, index) in fileList"
|
|
@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 }">
|
|
<i class="fi fi-br-check"></i>
|
|
</div>
|
|
<div
|
|
@click.stop="setUploadDelete(item, index)"
|
|
v-if="source != 'design'"
|
|
>
|
|
<i class="fi fi-rr-trash icon_delete"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="upload_item item"
|
|
v-show="!isDesignPage && !(videoType === 3 && fileList.length > 0)"
|
|
>
|
|
<div class="upload_file_item">
|
|
<a-upload
|
|
key="common"
|
|
:action="getUploadUrl() + '/api/history/toProductImageElementUpload'"
|
|
list-type="picture-card"
|
|
:capture="null"
|
|
:data="{
|
|
...upload,
|
|
type: 'first'
|
|
}"
|
|
: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
|
|
class="upload_item item last_frames"
|
|
v-show="!isDesignPage && lastFrameList?.length < 1"
|
|
>
|
|
<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 == selectImg.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 }">
|
|
<i class="fi fi-br-check"></i>
|
|
</div>
|
|
<div
|
|
@click.stop="setUploadDelete(item, index)"
|
|
v-if="source != 'design'"
|
|
>
|
|
<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">{{ $t('ProductImg.Prompt') }}</div>
|
|
<promptInput :content="prompt" 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
|
|
v-show="!isVideoPlaying(item.id)"
|
|
class="play-icon"
|
|
@click.stop="handlePlayMotion(item)"
|
|
name="CPlay"
|
|
size="10"
|
|
color="#fff"
|
|
/>
|
|
<SvgIcon
|
|
v-show="isVideoPlaying(item.id)"
|
|
class="play-icon pause"
|
|
@click.stop="handlePlayMotion(item)"
|
|
name="CPause"
|
|
size="10"
|
|
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
|
|
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 v-show="isGenerate && remGenerate" class="generage_btn started_btn">
|
|
<i class="fi fi-br-loading"></i>
|
|
</div> -->
|
|
<!-- <div v-show="remGenerate" @click="setRemoveGenerate" class="generage_btn started_btn">
|
|
{{$t('Generate.Close')}}
|
|
</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" />
|
|
</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 { getFirstFrame, getFirstAndLastFrame } from './prompt'
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
generalDrag,
|
|
promptInput,
|
|
Tips
|
|
},
|
|
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: 'first' // 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
|
|
remGenerate: false,
|
|
removeGenerate: false,
|
|
generateTime: null as any,
|
|
poseList: [],
|
|
selectPose: null as any,
|
|
prompt: computed(() => {
|
|
if (videoType.value === 2) {
|
|
return getFirstFrame(t)
|
|
}
|
|
if (videoType.value === 3) {
|
|
return getFirstAndLastFrame(t)
|
|
}
|
|
})
|
|
})
|
|
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
|
|
}
|
|
|
|
// 处理首帧选择
|
|
data.fileList.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 (!data.selectImg.minioUrl) return message.info(t('ProductImg.jsContent2'))
|
|
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
|
|
// data.remGenerateTime = setTimeout(()=>{
|
|
// },10000)
|
|
|
|
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 (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.remGenerate = true
|
|
data.noLikeList.unshift({
|
|
taskId: rv.taskId,
|
|
parentId: data.selectImg.parentId
|
|
})
|
|
setGenerate(rv.taskId)
|
|
})
|
|
.catch((res: any) => {
|
|
data.isGenerate = false
|
|
clearInterval(data.remGenerateTime)
|
|
data.remGenerate = 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 || !data.remGenerate) 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)
|
|
clearInterval(data.remGenerateTime)
|
|
data.remGenerate = false
|
|
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)
|
|
clearInterval(data.remGenerateTime)
|
|
data.remGenerate = false
|
|
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)
|
|
clearInterval(data.remGenerateTime)
|
|
data.isGenerate = false
|
|
data.remGenerate = false
|
|
})
|
|
}, 10000)
|
|
}
|
|
const setRemoveGenerate = () => {
|
|
//取消操作
|
|
data.isGenerate = false
|
|
data.remGenerate = 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 (!data?.upload?.projectId && !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))
|
|
// data.fileList.forEach((listItem:any)=>{
|
|
// if(listItem.id == file.id){
|
|
// listItem.isChecked = true
|
|
// }else{
|
|
// listItem.isChecked = false
|
|
// }
|
|
// })
|
|
file.type = 'ProductElement'
|
|
// if(props.productimgMenu.value == 'Relight'){
|
|
// file.type = "ToProductImage"
|
|
// }
|
|
data.selectImg = res.data
|
|
// data.fileList.filter((v: any) => v.status === "done");
|
|
let storeData = {
|
|
str: 'add',
|
|
list: [file]
|
|
}
|
|
store.commit('setUploadElement', storeData)
|
|
} 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'
|
|
// 取消尾帧列表选中状态
|
|
;(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
|
|
let value = {
|
|
likedList: [
|
|
{
|
|
...item,
|
|
sort: rv.sort,
|
|
parentId: rv.parentId
|
|
}
|
|
],
|
|
str: 'add',
|
|
index: -1
|
|
}
|
|
store.commit('setPoseTransfer', value)
|
|
data.noLikeList.splice(index, 1)
|
|
} else {
|
|
let value = {
|
|
likedList: [
|
|
{
|
|
...item
|
|
}
|
|
],
|
|
str: 'splice',
|
|
index: index
|
|
}
|
|
data.noLikeList.push(item)
|
|
store.commit('setPoseTransfer', value)
|
|
}
|
|
})
|
|
.catch(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) => {
|
|
let value = {
|
|
id: item.id
|
|
}
|
|
Https.axiosPost(
|
|
Https.httpUrls.toProductImageElementDelete,
|
|
{},
|
|
{ params: value }
|
|
).then(rv => {
|
|
let storeData = {
|
|
str: 'delete',
|
|
index
|
|
}
|
|
store.commit('setUploadElement', storeData)
|
|
})
|
|
}
|
|
watch(
|
|
() => store.state.HomeStoreModule.uploadElement.length,
|
|
(newVal, oldVal) => {
|
|
if (props.isDesignPage) return
|
|
data.fileList = store.state.HomeStoreModule.uploadElement.filter(
|
|
item => item.frameType === 'first'
|
|
)
|
|
lastFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
|
item => item.frameType === 'last'
|
|
)
|
|
|
|
data.fileList.forEach((listItem: any) => {
|
|
if (listItem.id == data.selectImg.id) {
|
|
listItem.isChecked = true
|
|
} else {
|
|
listItem.isChecked = false
|
|
}
|
|
})
|
|
}
|
|
)
|
|
// 全局维护尾帧上传列表,保持与主上传一致
|
|
const lastFrameList = ref([])
|
|
watch(
|
|
() => store.state.HomeStoreModule.lastFrameList,
|
|
val => {
|
|
if (props.isDesignPage) return
|
|
lastFrameList.value = val
|
|
if (val.length > 0) {
|
|
val[0].isChecked = true
|
|
}
|
|
},
|
|
{ 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
|
|
data.remGenerate = true
|
|
setGenerate(taskIdList[0].taskId)
|
|
}
|
|
})
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
const videoType = ref(2)
|
|
const showMotion = computed(() => videoType.value === 1)
|
|
const options = ref([
|
|
{ vlaue: 2, label: t('poseTransfer.FirstFrame') },
|
|
{ value: 3, label: t('poseTransfer.FirstAndLastFrames') },
|
|
{ value: 1, label: t('poseTransfer.FirstFrameAndSkeleton') }
|
|
])
|
|
|
|
onBeforeUnmount(() => {
|
|
clearInterval(data.generateTime)
|
|
clearInterval(data.remGenerateTime)
|
|
data.isGenerate = false
|
|
data.remGenerate = false
|
|
})
|
|
|
|
return {
|
|
...toRefs(speed),
|
|
...toRefs(dataDom),
|
|
...toRefs(data),
|
|
lastFrameList,
|
|
openSetData,
|
|
selectImgItem,
|
|
setSize,
|
|
setItemPosition,
|
|
getgenerate,
|
|
getUploadUrl,
|
|
beforeUpload,
|
|
fileUploadChange,
|
|
fileUploadChangeLast,
|
|
setRemoveGenerate,
|
|
likeSetBtn,
|
|
noLikeSetBtn,
|
|
selectPose,
|
|
openSpeed,
|
|
setSpeed,
|
|
setUploadDelete,
|
|
locale,
|
|
videoType,
|
|
options,
|
|
showMotion,
|
|
setVideoRef,
|
|
handlePlayMotion,
|
|
isVideoPlaying,
|
|
showTips
|
|
}
|
|
},
|
|
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;
|
|
}
|
|
.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: flex-end;
|
|
justify-content: center;
|
|
.icon-list {
|
|
height: 50%;
|
|
width: calc(100% - 1.6rem);
|
|
// border-top: 1px solid #fff;
|
|
display: flex;
|
|
box-sizing: border-box;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
.play-icon {
|
|
width: initial;
|
|
height: initial;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
> .head {
|
|
color: #000;
|
|
font-weight: 600;
|
|
display: flex;
|
|
align-items: center;
|
|
column-gap: 1rem;
|
|
.tips-icon {
|
|
cursor: pointer;
|
|
display: flex;
|
|
}
|
|
> .text {
|
|
// display: inline-block;
|
|
font-size: 1.6rem;
|
|
}
|
|
}
|
|
}
|
|
.prompt-input-container {
|
|
margin-top: 4rem;
|
|
}
|
|
.title {
|
|
font-size: 1.8rem;
|
|
color: #000;
|
|
margin-bottom: 1.4rem;
|
|
}
|
|
> .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;
|
|
.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>
|