Files
aida_front/src/component/home/tools/toProduct/Prompt.vue
2025-12-10 15:53:40 +08:00

427 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- <div ref="modalContainer"></div> -->
<a-modal
class="prompt-modal generalModel"
:class="{ design: isDesignPage }"
v-model:visible="showModal"
:footer="null"
width="78%"
:maskClosable="false"
:centered="true"
:closable="false"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="handleClose()">
<svg
width="100%"
height="100%"
viewBox="0 0 46 46"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3" />
<rect
x="32.5063"
y="12"
width="3"
height="29"
rx="1.5"
transform="rotate(45 32.5063 12)"
fill="white"
/>
<rect
x="34.6274"
y="32.5059"
width="3"
height="29"
rx="1.5"
transform="rotate(135 34.6274 32.5059)"
fill="white"
/>
</svg>
</div>
</div>
<div class="title-container">
<div class="title">{{ $t('ProductImg.PromptAssit') }}</div>
<div class="sub-title">{{ $t('ProductImg.AssitSubTitle') }}</div>
</div>
<div class="example-content">
<div
class="example-wrapper"
v-for="item in Object.keys(exampleList)"
:key="item"
:class="item"
>
<div class="example-item" v-for="value in exampleList[item]" :key="value.title">
<img :src="value.src" />
<SvgIcon
v-if="value.isOriginal"
class="download-icon"
name="CDownload"
size="20"
color="#8E8E8E"
@click.stop="handleDownload(value)"
/>
</div>
</div>
</div>
<div class="prompt-list">
<div v-for="item in promptList" :key="item" class="prompt-item">
<SvgIcon
name="CCopy"
size="25"
color="#BCBCBC"
class="copy-icon"
@click.stop="handleCopy(item)"
/>
{{ item }}
</div>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { ref, useTemplateRef, onMounted, computed } from 'vue'
import { message } from 'ant-design-vue'
import originalDress from '@/assets/images/product/original_dress.png'
import generatedDress from '@/assets/images/product/geneated_dress.png'
import originalModel from '@/assets/images/product/original_model.png'
import generatedModel from '@/assets/images/product/generated_model.png'
import generatedSketch from '@/assets/images/product/generated_sketch.png'
import maleSingleGarmentSketch from '@/assets/images/product/male_single_garment_sketch.png'
import maleSingleGarmentResult from '@/assets/images/product/male_single_garment_result.png'
import maleSingleModelSketch from '@/assets/images/product/male_single_garment_model_sketch.png'
import maleSingleModelResult from '@/assets/images/product/male_single_garment_model_result.png'
import femaleChildModelResult from '@/assets/images/product/single_female_child_model_result.png'
import maleSingleChildSketch from '@/assets/images/product/single_male_child_model_sketch.png'
import maleSingleChildResult from '@/assets/images/product/single_male_child_model_result.png'
import { downloadIamge } from '@/tool/util'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
const { t, locale } = useI18n()
const store = useStore()
const props = defineProps<{
isDesignPage: boolean
}>()
const promptList = computed(() => {
const isFromDesignPage = props.source === 'design' || props.isDesignPage
const { ageGroup, httpType, sex } = store.state.Workspace.probjects
const isSingleDesign = httpType === 'SINGLE_DESIGN'
const isAdult = ageGroup === 'Adult'
const isFemale = sex === 'Female'
if (!isFromDesignPage) {
// 如果不是从design来的返回两个提示词
return [t('ProductImg.UploadWithoutModel'), t('ProductImg.UploadWithModel')]
} else {
// 如果是从design来的
if (props.isDesignPage) {
// SINGLE_DESIGN: 两个提示词
// 根据年龄和性别选择对应的提示词
let firstPrompt: string // 不带模特的提示词
let secondPrompt: string // 带模特的提示词
if (isAdult) {
// 成人
if (isFemale) {
// 成人女
firstPrompt = t('ProductImg.SingleAdultFemaleWithoutModel')
secondPrompt = t('ProductImg.SingleAdultFemaleWithModel')
} else {
// 成人男
firstPrompt = t('ProductImg.SingleAdultMaleWithoutModel')
secondPrompt = t('ProductImg.SingleAdultMaleWithModel')
}
} else {
// 儿童
if (isFemale) {
// 儿童女
firstPrompt = t('ProductImg.SingleChildFemaleWithoutModel')
secondPrompt = t('ProductImg.SingleChildFemaleWithModel')
} else {
// 儿童男
firstPrompt = t('ProductImg.SingleChildMaleWithoutModel')
secondPrompt = t('ProductImg.SingleChildMaleWithModel')
}
}
return [firstPrompt, secondPrompt]
}
}
})
const modalContainer = useTemplateRef('modalContainer')
const showModal = defineModel<boolean>('showModal', { required: true })
const garmentExample = [
{
title: 'Original Dress',
src: originalDress,
isOriginal: true
},
{
title: 'Generated Result',
src: generatedDress
}
]
const sketchExample = [
{
title: 'Origianl Sketch',
src: originalDress,
isOriginal: true
},
{
title: 'Generated Sketch',
src: generatedSketch
}
]
const modelExample = [
{
title: 'originalModel',
src: originalModel,
isOriginal: true
},
{
title: 'generatedModel',
src: generatedModel
}
]
const femaleAdultGarment = [...garmentExample]
const femaleAdultWithModel = [...sketchExample]
const maleAdultGarment = [
{
title: 'originalDress',
src: maleSingleGarmentSketch,
isOriginal: true
},
{
title: 'generated male sketch',
src: maleSingleGarmentResult
}
]
const maleAdultWithModel = [
{
title: 'original male model',
src: maleSingleModelSketch,
isOriginal: true
},
{
title: 'generated male model',
src: maleSingleModelResult
}
]
const childFemaleGarment = [...garmentExample]
const childFemaleWithModel = [
{
title: 'Origianl Sketch',
src: originalDress,
isOriginal: true
},
{
title: 'Generated female girl Sketch',
src: femaleChildModelResult
}
]
const childMaleGarment = [...maleAdultGarment]
const childMaleWithModel = [
{
title: 'original sketch',
src: maleSingleChildSketch,
isOriginal: true
},
{
title: 'generate child male model',
src: maleSingleChildResult
}
]
const exampleList = computed(() => {
let obj = {}
if (!props.isDesignPage) {
obj = {
garmentExample,
sketchExample,
modelExample
}
} else {
const { ageGroup, httpType, sex } = store.state.Workspace.probjects
// const isSingleDesign = httpType === 'SINGLE_DESIGN'
// if (!isSingleDesign) return {}
const isAdult = ageGroup === 'Adult'
const isFemale = sex === 'Female'
if (isAdult) {
if (isFemale) {
obj = {
femaleAdultGarment,
femaleAdultWithModel
}
} else {
obj = {
maleAdultGarment,
maleAdultWithModel
}
}
} else {
if (isFemale) {
obj = {
childFemaleGarment,
childFemaleWithModel
}
} else {
obj = {
childMaleGarment,
childMaleWithModel
}
}
}
}
return obj
})
const handleClose = () => {
showModal.value = false
}
const handleDownload = value => {
const { title, src } = value
downloadIamge(src, title)
}
const handleCopy = async (value: string) => {
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(value)
message.success(t('ProductImg.CopySuccess'))
} else {
// 降级方案:使用传统的 document.execCommand 方法
const textArea = document.createElement('textarea')
textArea.value = value
textArea.style.position = 'fixed'
textArea.style.left = '-999999px'
textArea.style.top = '-999999px'
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
try {
document.execCommand('copy')
message.success(t('ProductImg.CopySuccess'))
} catch (err) {
message.error(t('ProductImg.CopyFailed'))
}
document.body.removeChild(textArea)
}
} catch (err) {
message.error(t('ProductImg.CopyFailed'))
}
}
</script>
<style lang="less" scoped>
.prompt-modal {
.title-container {
.title {
font-size: 3.5rem;
color: #181818;
}
.sub-title {
font-size: 2rem;
font-weight: 400;
color: #000;
}
}
.example-content {
margin-top: 4.3rem;
padding-left: 7.4rem;
display: flex;
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
.example-wrapper {
display: flex;
gap: 0;
&.garmentExample {
margin-right: 9.6rem;
}
&.sketchExample {
margin-right: 1.6rem;
}
.example-item {
width: 20.3rem;
height: 38.4rem;
margin-left: -2px;
position: relative;
img {
width: 100%;
display: block;
}
.download-icon {
position: absolute;
top: 0.77rem;
right: 0.84rem;
cursor: pointer;
}
}
}
}
.prompt-list {
margin-top: 3.5rem;
display: flex;
column-gap: 6.3rem;
.prompt-item {
height: 12.8rem;
line-height: 2.3rem;
padding: 1.8rem 3.5rem 1.8rem 2rem;
color: #969696;
font-size: 1.9rem;
border: 1px solid #000;
border-radius: 0.8rem;
overflow-y: auto;
position: relative;
display: flex;
align-items: center;
justify-content: center;
// &:first-child{
// width: 53.6rem;
// }
.copy-icon {
position: absolute;
top: 1.1rem;
right: 1rem;
cursor: pointer;
}
}
}
&.design {
.example-content {
padding-left: 0;
justify-content: space-around;
}
.prompt-list {
justify-content: space-around;
.prompt-item {
width: 40%;
}
}
}
}
:deep(.generalModel .ant-modal-body) {
padding: 5rem 4.4rem 8rem 4.6rem;
}
.c-svg {
width: initial;
height: initial;
}
</style>