Files
lanecarford_front/src/views/Workshop/selectStyle.vue
2025-12-23 14:00:30 +08:00

301 lines
7.2 KiB
Vue

<script setup lang="ts">
import { onMounted, onUnmounted, reactive, toRefs, computed, ref } from "vue";
import SelectItem from "@/components/selectStyle/selectItem.vue";
import { useRouter, useRoute } from 'vue-router'
import { useGenerateStore, useUserInfoStore, useHGenerateStore } from '@/stores'
import { showToast } from 'vant';
import { shareImageToWhatsapp } from '@/utils/tools'
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 route = useRoute()
//const props = defineProps({
//})
const emit = defineEmits([
'view-type'
])
const generateStore = useGenerateStore()
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({
select:computed(()=>generateStore.style),
// styleList:computed(()=>generateStore.styleList),
})
let getGenerateTime = null as any
const updateStyle = ()=>{
// generateStore.updateStyle(item)
// 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
})
}
}
const setDownload = ()=>{
if(select.value.path)shareImageToWhatsapp(select.value.path)
}
const toProduct = ()=>{
// if(generateStore.style.id){
// generateStore.setIsGenerate(true)
// }
if(!isHistoryFlow.value){
router.push({ path: 'product', query: {...query.value} })
}else{
router.push({ path: 'creation', query: {...query.value, active: FlowType.H_OUTFIT} })
}
}
const requestOutfit = async ({num})=>{
let rv = await new Promise<void>((resolve, reject) => {
if(isHistoryFlow.value){
retrieveAndRegenerate({tryOnEffectsId:hGenerateStore.originalTryOn.id}).then((rv:any)=>{
resolve(rv)
})
}else{
let value = {
"customerId": generateStore.customerId,
"checkInId": generateStore.visitRecordId,
"stylist": userInfoStore.state.generateParams.stylist,
"gender": userInfoStore.state.generateParams.sex,
"sessionId": generateStore.sessionId,
num,
}
generateRequestOutfit(value).then((rv:any)=>{
resolve(rv)
})
}
})
isLoading.value = true
generateStore.clearStyle()
data.select.taskId = rv[0]
getRequestOutfitList(rv)
}
const getRequestOutfitList = (generateList)=>{
let value = {requestIDs:generateList.join(',')}
getRequestOutfit(value).then((rv:any)=>{
rv.forEach((item)=>{
data.select.id = item.id
data.select.path = item.path
data.select.status = item.status
})
if(['RUNNING','PENDING'].includes(data.select.status)){
getGenerateTime = setTimeout(()=>{
getRequestOutfitList([data.select.taskId])
},3000)
}else{
isLoading.value = false
}
})
}
onMounted(()=>{
// generateStore.clearProductData()
emit('view-type', 1)
// if(!data.styleList[0]?.id)getRequestOutfitList(0)
if(getGenerateTime)clearTimeout(getGenerateTime)
if(data.select.status == 'SUCCEEDED'){
return
}else if(!data.select?.taskId){
requestOutfit({num:1})
}else if(data.select.status != 'SUCCEEDED'){
isLoading.value = true
// let generateList = [data.styleList[0].taskId]
getRequestOutfitList([data.select.taskId])
}
})
onUnmounted(()=>{
if(getGenerateTime)clearTimeout(getGenerateTime)
})
defineExpose({})
const { select } = toRefs(data);
</script>
<template>
<div class="selectStyle">
<div class="text">
<div class="title">
Outfit Result
</div>
<div class="info">
Refine your Look
</div>
</div>
<div class="selectContent">
<!-- {{ 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 class="btn">
<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 class="footer placeholder"></div> -->
<div class="loading-container" v-if="isLoading">
<GenerateLoading :title="loadingTitle"/>
</div>
</template>
<style lang="less" scoped>
.header-title {
// --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{
width: 100%;
flex: 1;
// height: 100%;
position: relative;
display: flex;
flex-direction: column;
background-color: #f6f6f6;
overflow: hidden;
> .text{
text-align: center;
width: 100%;
margin-top: 8.5rem;
margin-bottom: 8.5rem;
> .title{
font-family: satoshiBold;
font-weight: 700;
font-size: 8.6rem;
line-height: 124%;
color: #000;
}
> .info{
font-size: 4rem;
font-weight: 400;
line-height: 124%;
margin-top: 3.2rem;
color: rgba(0, 0, 0, 0.6);
}
}
.selectContent{
// padding: 0 4rem;
margin: 0 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{
display: flex;
gap: 6.6rem;
justify-content: center;
> div {
border-radius: .96rem;
width: 33.7rem;
font-size: 4.8rem;
font-family: satoshiMedium;
line-height: 9.2rem;
display: flex;
justify-content: center;
&.style1{
--borderRadius: .96rem;
--borderWidth: 2px;
.text{
width: 100%;
text-align: center;
> .icon{
left: 4rem;
top: 50%;
transform: translateY(-50%);
position: absolute;
}
}
}
&.style2{
color: #fff;
background-color: #000;
}
}
}
}
</style>