Files
aida_front/src/component/home/tools/toProduct/Prompt.vue

427 lines
10 KiB
Vue
Raw Normal View History

2025-11-11 14:20:04 +08:00
<template>
2025-11-17 16:45:40 +08:00
<!-- <div ref="modalContainer"></div> -->
2025-11-11 14:20:04 +08:00
<a-modal
class="prompt-modal generalModel"
:class="{ design: isDesignPage }"
2025-11-11 14:20:04 +08:00
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'
2025-11-11 14:20:04 +08:00
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_sketch.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'
2025-11-11 14:20:04 +08:00
import { downloadIamge } from '@/tool/util'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
2025-11-11 14:20:04 +08:00
const { t, locale } = useI18n()
const store = useStore()
2025-11-11 14:20:04 +08:00
2025-11-12 13:24:30 +08:00
const props = defineProps<{
isDesignPage: boolean
2025-11-11 14:20:04 +08:00
}>()
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 (isSingleDesign) {
// 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]
}
}
})
2025-11-11 14:20:04 +08:00
const modalContainer = useTemplateRef('modalContainer')
const showModal = defineModel<boolean>('showModal', { required: true })
const garmentExample = [
{
title: 'Original Dress',
2025-11-11 14:20:04 +08:00
src: originalDress,
isOriginal: true
},
{
title: 'Generated Result',
2025-11-11 14:20:04 +08:00
src: generatedDress
}
]
const sketchExample = [
{
title: 'Origianl Sketch',
2025-11-11 14:20:04 +08:00
src: originalDress,
isOriginal: true
},
{
title: 'Generated Sketch',
2025-11-11 14:20:04 +08:00
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
})
2025-11-11 14:20:04 +08:00
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')
2025-11-12 13:24:30 +08:00
message.success(t('ProductImg.CopySuccess'))
2025-11-11 14:20:04 +08:00
} 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;
2025-11-17 16:45:40 +08:00
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
2025-11-11 14:20:04 +08:00
.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;
}
}
}
}
2025-11-11 14:20:04 +08:00
.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;
2025-11-11 14:20:04 +08:00
// &: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%;
}
}
}
2025-11-11 14:20:04 +08:00
}
:deep(.generalModel .ant-modal-body) {
padding: 5rem 4.4rem 8rem 4.6rem;
}
.c-svg {
width: initial;
height: initial;
}
</style>