tryon 反推style
This commit is contained in:
@@ -58,7 +58,7 @@ onMounted(()=>{
|
|||||||
flowTypeList: [FlowType.H_TRYON,FlowType.H_AI],
|
flowTypeList: [FlowType.H_TRYON,FlowType.H_AI],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'recommended',
|
path: 'product',
|
||||||
imgPath: new URL('@/assets/images/nav2.png',import.meta.url).href,
|
imgPath: new URL('@/assets/images/nav2.png',import.meta.url).href,
|
||||||
flowTypeList: [FlowType.H_OUTFIT],
|
flowTypeList: [FlowType.H_OUTFIT],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, reactive, ref, toRefs } from "vue";
|
import { onMounted, onUnmounted, reactive, ref, toRefs, computed } from "vue";
|
||||||
import HeaderTitle from '@/components/HeaderTitle.vue'
|
|
||||||
import FooterNavigation from '@/components/FooterNavigation.vue'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import GenerateLoading from '@/views/asistant/components/GenerateLoading.vue'
|
import GenerateLoading from '@/views/asistant/components/GenerateLoading.vue'
|
||||||
import { useGenerateStore } from '@/stores'
|
import { useGenerateStore, useHGenerateStore } from '@/stores'
|
||||||
import { generateTryOnEffect, setTryOnEffectFavorite, cancelTryOnEffectFavorite, addTryOnEffectComment } from '@/api/workshop'
|
import { generateTryOnEffect, setTryOnEffectFavorite, cancelTryOnEffectFavorite, addTryOnEffectComment } from '@/api/workshop'
|
||||||
import { FlowType } from '@/types/enum'
|
import { FlowType, IsHistoryFlow } from '@/types/enum'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
//const props = defineProps({
|
//const props = defineProps({
|
||||||
@@ -19,8 +17,11 @@ let data = reactive({
|
|||||||
],
|
],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
})
|
})
|
||||||
|
const query = computed(() => router.currentRoute.value.query)
|
||||||
const generateStore = useGenerateStore()
|
const generateStore = useGenerateStore()
|
||||||
|
const hGenerateStore = useHGenerateStore()
|
||||||
|
|
||||||
|
const isHistoryFlow = computed(() => IsHistoryFlow(query.value.flowType))
|
||||||
|
|
||||||
const vanDialogShow = ref(false)
|
const vanDialogShow = ref(false)
|
||||||
const feedbackForm = ref({
|
const feedbackForm = ref({
|
||||||
@@ -34,11 +35,10 @@ const feedbackForm = ref({
|
|||||||
|
|
||||||
|
|
||||||
const onContinue = ()=>{
|
const onContinue = ()=>{
|
||||||
const query = router.currentRoute.value.query
|
if(!isHistoryFlow.value){
|
||||||
if(query?.flowType == FlowType.MAIN){
|
router.push({ path: 'uploadFace', query: {...query.value} })
|
||||||
router.push({ path: 'uploadFace', query: {...query} })
|
|
||||||
}else{
|
}else{
|
||||||
router.push({ path: 'creation', query: {...query} })
|
router.push({ path: 'creation', query: {...query.value} })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ const startGenerate = ()=>{
|
|||||||
let value = {
|
let value = {
|
||||||
customerId:generateStore.customerId,
|
customerId:generateStore.customerId,
|
||||||
visitRecordId:generateStore.visitRecordId,
|
visitRecordId:generateStore.visitRecordId,
|
||||||
styleId:generateStore.styleId,
|
styleId:isHistoryFlow.value ? hGenerateStore.styleId : generateStore.styleId,
|
||||||
// customerPhotoId:null,
|
// customerPhotoId:null,
|
||||||
// modelPhotoId:null,
|
// modelPhotoId:null,
|
||||||
// prompt:null,
|
// prompt:null,
|
||||||
@@ -63,7 +63,7 @@ const startGenerate = ()=>{
|
|||||||
generateStore.originalTryOn.isLike = false
|
generateStore.originalTryOn.isLike = false
|
||||||
generateStore.originalTryOn.id = res.tryOnId
|
generateStore.originalTryOn.id = res.tryOnId
|
||||||
generateStore.originalTryOn.tryOnUrl = res.tryOnUrl
|
generateStore.originalTryOn.tryOnUrl = res.tryOnUrl
|
||||||
generateStore.useStyleGenerate()//生成后需要对选择衣服页面设置不可选中样式
|
// generateStore.useStyleGenerate()//生成后需要对选择衣服页面设置不可选中样式
|
||||||
generateStore.setIsGenerate(false)
|
generateStore.setIsGenerate(false)
|
||||||
|
|
||||||
generateStore.clearCustomizeInfo()
|
generateStore.clearCustomizeInfo()
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, reactive, toRefs, computed, onActivated } from "vue";
|
import { onMounted, onUnmounted, reactive, toRefs, computed, ref } from "vue";
|
||||||
import SelectItem from "@/components/selectStyle/selectItem.vue";
|
import SelectItem from "@/components/selectStyle/selectItem.vue";
|
||||||
import HeaderTitle from '@/components/HeaderTitle.vue'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import FooterNavigation from '@/components/FooterNavigation.vue'
|
import { useGenerateStore, useUserInfoStore, useHGenerateStore } from '@/stores'
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useGenerateStore, useUserInfoStore } from '@/stores'
|
|
||||||
import { showToast } from 'vant';
|
import { showToast } from 'vant';
|
||||||
import { generateRequestOutfit, getRequestOutfit } from '@/api/workshop'
|
import { shareImageToWhatsapp } from '@/utils/tools'
|
||||||
import { FlowType } from '@/types/enum'
|
import { generateRequestOutfit, getRequestOutfit, setStyleFavorite, cancelStyleFavorite, retrieveAndRegenerate } from '@/api/workshop'
|
||||||
|
import { FlowType, IsHistoryFlow } from '@/types/enum'
|
||||||
|
import GenerateLoading from '@/views/asistant/components/GenerateLoading.vue'
|
||||||
|
import gradientButton from '@/components/gradientButton.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
//const props = defineProps({
|
//const props = defineProps({
|
||||||
//})
|
//})
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
@@ -18,125 +19,190 @@ const emit = defineEmits([
|
|||||||
])
|
])
|
||||||
const generateStore = useGenerateStore()
|
const generateStore = useGenerateStore()
|
||||||
const userInfoStore = useUserInfoStore()
|
const userInfoStore = useUserInfoStore()
|
||||||
|
const hGenerateStore = useHGenerateStore()
|
||||||
|
|
||||||
|
const query = computed(() => route.query)
|
||||||
|
const isHistoryFlow = computed(() => IsHistoryFlow(query.value.flowType))
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const loadingTitle= ref('Analyzing the Outfit...')
|
||||||
|
// const loadingTitle = computed(()=>{
|
||||||
|
// let str = ''
|
||||||
|
// if(!select.value.status)str = 'Analyzing the Outfit...'
|
||||||
|
// if(select.value.status == 'RUNNING')str = 'Generating Results...'
|
||||||
|
// if(select.value.status == 'PENDING')str = 'Almost there...'
|
||||||
|
// return str
|
||||||
|
// })
|
||||||
|
|
||||||
let data = reactive({
|
let data = reactive({
|
||||||
select:computed(()=>generateStore.style),
|
select:computed(()=>generateStore.style),
|
||||||
styleList:computed(()=>generateStore.styleList),
|
// styleList:computed(()=>generateStore.styleList),
|
||||||
})
|
})
|
||||||
|
|
||||||
let getGenerateTime = null as any
|
let getGenerateTime = null as any
|
||||||
|
|
||||||
const selectItem = (item)=>{
|
const updateStyle = ()=>{
|
||||||
if(!item.id || item.status != 'SUCCEEDED'){
|
// generateStore.updateStyle(item)
|
||||||
return
|
// data.styleList[index] = {}
|
||||||
|
requestOutfit({num:1})
|
||||||
|
}
|
||||||
|
const setLikeStyle = (likeStyle)=>{
|
||||||
|
if(!select.value.id)return
|
||||||
|
if(likeStyle){
|
||||||
|
cancelStyleFavorite(select.value.id).then(()=>{
|
||||||
|
select.value.isLike = false
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
setStyleFavorite(select.value.id).then(()=>{
|
||||||
|
select.value.isLike = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
generateStore.selectStyle(item)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateStyle = ({item,index})=>{
|
const setDownload = ()=>{
|
||||||
generateStore.updateStyle(item)
|
if(select.value.path)shareImageToWhatsapp(select.value.path)
|
||||||
data.styleList[index] = {}
|
|
||||||
requestOutfit({num:1,index})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const toProduct = ()=>{
|
const toProduct = ()=>{
|
||||||
if(!generateStore.style.id){
|
// if(generateStore.style.id){
|
||||||
showToast({ message: 'Please select a style.' });
|
// generateStore.setIsGenerate(true)
|
||||||
return
|
// }
|
||||||
}
|
if(!isHistoryFlow.value){
|
||||||
if(generateStore.style.id != generateStore.style.oldId){
|
router.push({ path: 'product', query: {...query.value} })
|
||||||
generateStore.setIsGenerate(true)
|
|
||||||
}
|
|
||||||
const query = router.currentRoute.value.query
|
|
||||||
if(query?.flowType == FlowType.MAIN){
|
|
||||||
router.push({ path: 'product', query: {...query} })
|
|
||||||
}else{
|
}else{
|
||||||
router.push({ path: 'creation', query: {...query} })
|
router.push({ path: 'creation', query: {...query.value, active: FlowType.H_OUTFIT} })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestOutfit = ({num,index})=>{
|
const requestOutfit = async ({num})=>{
|
||||||
let value = {
|
let rv = await new Promise<void>((resolve, reject) => {
|
||||||
"customerId": generateStore.customerId,
|
if(isHistoryFlow.value){
|
||||||
"checkInId": generateStore.visitRecordId,
|
retrieveAndRegenerate({tryOnEffectsId:hGenerateStore.originalTryOn.id}).then((rv:any)=>{
|
||||||
"stylist": userInfoStore.state.generateParams.stylist,
|
resolve(rv)
|
||||||
"gender": userInfoStore.state.generateParams.sex,
|
})
|
||||||
"sessionId": generateStore.sessionId,
|
}else{
|
||||||
num,
|
let value = {
|
||||||
}
|
"customerId": generateStore.customerId,
|
||||||
generateRequestOutfit(value).then((rv)=>{
|
"checkInId": generateStore.visitRecordId,
|
||||||
let rvIndex = 0
|
"stylist": userInfoStore.state.generateParams.stylist,
|
||||||
data.styleList.forEach((item,styleIndex)=>{
|
"gender": userInfoStore.state.generateParams.sex,
|
||||||
if(styleIndex < index)return
|
"sessionId": generateStore.sessionId,
|
||||||
item.taskId = rv[rvIndex]
|
num,
|
||||||
rvIndex++
|
}
|
||||||
})
|
generateRequestOutfit(value).then((rv:any)=>{
|
||||||
getRequestOutfitList(rv)
|
resolve(rv)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
isLoading.value = true
|
||||||
|
generateStore.clearStyle()
|
||||||
|
data.select.taskId = rv[0]
|
||||||
|
getRequestOutfitList(rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRequestOutfitList = (generateList)=>{
|
const getRequestOutfitList = (generateList)=>{
|
||||||
let value = {requestIDs:generateList.join(',')}
|
let value = {requestIDs:generateList.join(',')}
|
||||||
getRequestOutfit(value).then((rv:any)=>{
|
getRequestOutfit(value).then((rv:any)=>{
|
||||||
let pendingList = []
|
|
||||||
rv.forEach((item)=>{
|
rv.forEach((item)=>{
|
||||||
if(['RUNNING','PENDING'].includes(item.status))pendingList.push(item.requestId)
|
data.select.id = item.id
|
||||||
let index = data.styleList.findIndex((styleItem)=>styleItem.taskId == item.requestId)
|
data.select.path = item.path
|
||||||
if(index != -1){
|
data.select.status = item.status
|
||||||
data.styleList[index].id = item.id
|
|
||||||
data.styleList[index].path = item.path
|
|
||||||
data.styleList[index].status = item.status
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if(pendingList.length > 0){
|
if(['RUNNING','PENDING'].includes(data.select.status)){
|
||||||
getGenerateTime = setTimeout(()=>{
|
getGenerateTime = setTimeout(()=>{
|
||||||
getRequestOutfitList(pendingList)
|
getRequestOutfitList([data.select.taskId])
|
||||||
},3000)
|
},3000)
|
||||||
|
}else{
|
||||||
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(()=>{
|
onMounted(()=>{
|
||||||
// generateStore.clearProductData()
|
// generateStore.clearProductData()
|
||||||
|
|
||||||
emit('view-type', 1)
|
emit('view-type', 1)
|
||||||
// if(!data.styleList[0]?.id)getRequestOutfitList(0)
|
// if(!data.styleList[0]?.id)getRequestOutfitList(0)
|
||||||
if(getGenerateTime)clearTimeout(getGenerateTime)
|
if(getGenerateTime)clearTimeout(getGenerateTime)
|
||||||
if(!data.styleList[0]?.taskId){
|
if(data.select.status == 'SUCCEEDED'){
|
||||||
requestOutfit({num:4,index:0})
|
return
|
||||||
}else if(data.styleList.filter((item)=>item?.status != 'SUCCEEDED').length > 0){
|
}else if(!data.select?.taskId){
|
||||||
let generateList = data.styleList.map((item)=>item.taskId)
|
requestOutfit({num:1})
|
||||||
getRequestOutfitList(generateList)
|
}else if(data.select.status != 'SUCCEEDED'){
|
||||||
|
isLoading.value = true
|
||||||
|
// let generateList = [data.styleList[0].taskId]
|
||||||
|
getRequestOutfitList([data.select.taskId])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
onUnmounted(()=>{
|
onUnmounted(()=>{
|
||||||
if(getGenerateTime)clearTimeout(getGenerateTime)
|
if(getGenerateTime)clearTimeout(getGenerateTime)
|
||||||
})
|
})
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
const { styleList, select } = toRefs(data);
|
const { select } = toRefs(data);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="selectStyle">
|
<div class="selectStyle">
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
What’s your Style?
|
Outfit Result
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
Select the outfit that matches you the most.
|
Refine your Look
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectContent flex-1">
|
<div class="selectContent">
|
||||||
<SelectItem :selectList="styleList" v-model:select="select" @selectItem="selectItem" @updateStyle="updateStyle" />
|
<!-- {{ select }} -->
|
||||||
|
<div class="imgBox">
|
||||||
|
<img :src="select.path" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="btn">
|
||||||
|
<div class="like" @click.stop="setLikeStyle(select.isLike)">
|
||||||
|
<SvgIcon :name="`love_${select.isLike?1:0}`" size="35" />
|
||||||
|
</div>
|
||||||
|
<div class="down" @click.stop="setDownload()">
|
||||||
|
<SvgIcon name="download" size="35" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="btn">
|
||||||
<button class="flex flex-center" @click.stop="toProduct">Continue</button>
|
<div class="btnItem style1" @click.stop="updateStyle()">
|
||||||
|
<gradientButton>
|
||||||
|
<template #content>
|
||||||
|
<div class="text">
|
||||||
|
<span class="icon">
|
||||||
|
<SvgIcon name="reTry" size="40" />
|
||||||
|
</span>
|
||||||
|
Re-try
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</gradientButton>
|
||||||
|
</div>
|
||||||
|
<div class="btnItem style2" @click.stop="toProduct">Continue</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="footer placeholder"></div> -->
|
<!-- <div class="footer placeholder"></div> -->
|
||||||
|
<div class="loading-container" v-if="isLoading">
|
||||||
|
<GenerateLoading :title="loadingTitle"/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.header-title {
|
.header-title {
|
||||||
// --header-title-background: #f6f6f6;
|
// --header-title-background: #f6f6f6;
|
||||||
}
|
}
|
||||||
|
.loading-container{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 2;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
.selectStyle{
|
.selectStyle{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -149,12 +215,12 @@ const { styleList, select } = toRefs(data);
|
|||||||
> .text{
|
> .text{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 3rem;
|
margin-top: 8.5rem;
|
||||||
margin-bottom: 4.9rem;
|
margin-bottom: 8.5rem;
|
||||||
> .title{
|
> .title{
|
||||||
font-family: satoshiBold;
|
font-family: satoshiBold;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 9.6rem;
|
font-size: 8.6rem;
|
||||||
line-height: 124%;
|
line-height: 124%;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
@@ -162,46 +228,74 @@ const { styleList, select } = toRefs(data);
|
|||||||
font-size: 4rem;
|
font-size: 4rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 124%;
|
line-height: 124%;
|
||||||
margin-top: 1.3rem;
|
margin-top: 3.2rem;
|
||||||
color: rgba(0, 0, 0, 0.6);
|
color: rgba(0, 0, 0, 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.selectContent{
|
.selectContent{
|
||||||
padding: 0 4rem;
|
// padding: 0 4rem;
|
||||||
|
margin: 0 auto;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
width: 73.7rem;
|
||||||
|
margin-bottom: 19.4rem;
|
||||||
|
> .imgBox{
|
||||||
|
height: 73.7rem;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 4.4rem;
|
||||||
|
> img{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> .btn{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 2rem;
|
||||||
|
> div{
|
||||||
|
color: #000;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 7rem;
|
||||||
|
height: 7rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: #fff;
|
||||||
|
&:hover{
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
> .btn{
|
||||||
.footer {
|
display: flex;
|
||||||
// position: fixed;
|
gap: 6.6rem;
|
||||||
// margin-top: 4.4rem;
|
justify-content: center;
|
||||||
// padding: 4rem 4rem 0 0;
|
> div {
|
||||||
margin-top: auto;
|
border-radius: .96rem;
|
||||||
margin-bottom: 5.6rem;
|
width: 33.7rem;
|
||||||
margin-right: 4rem;
|
font-size: 4.8rem;
|
||||||
display: flex;
|
font-family: satoshiMedium;
|
||||||
align-items: center;
|
line-height: 9.2rem;
|
||||||
justify-content: flex-end;
|
display: flex;
|
||||||
// position: absolute;
|
justify-content: center;
|
||||||
// right: 4rem;
|
&.style1{
|
||||||
// bottom: 4rem;
|
--borderRadius: .96rem;
|
||||||
height: 6.7rem;
|
--borderWidth: 2px;
|
||||||
// background-color: #f6f6f6;
|
.text{
|
||||||
&.placeholder{
|
width: 100%;
|
||||||
position: relative;
|
text-align: center;
|
||||||
}
|
> .icon{
|
||||||
> button {
|
left: 4rem;
|
||||||
// margin-right: 5rem;
|
top: 50%;
|
||||||
border-radius: .7rem;
|
transform: translateY(-50%);
|
||||||
border: 3px solid #000;
|
position: absolute;
|
||||||
background-color: #000;
|
}
|
||||||
text-align: center;
|
}
|
||||||
color: #fff;
|
}
|
||||||
font-family: satoshiMedium;
|
&.style2{
|
||||||
font-size: 3.6rem;
|
color: #fff;
|
||||||
width: 24.6rem;
|
background-color: #000;
|
||||||
height: 6.7rem;
|
}
|
||||||
box-sizing: border-box;
|
}
|
||||||
line-height: 6.7rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user