AI_Painting_V2.0/src/views/home/display/components/set.vue

368 lines
8.5 KiB
Vue

<template>
<div style="width: 100%;display: flex;justify-content: center;align-items: center;">
<div class="primary-box" :class="{ 'none-primary-box': props.item.status === 'none' }">
<!-- 标题 -->
<div class="title">
<div class="style">
<span class="name">{{ props.item.text }}</span>
</div>
<div v-if="props.item.parentIndex" class="style">
<span class="time">源自 {{ props.item.parentTime }}</span>
<div class="dividing-line"></div>
<span class="time">源自 {{ props.item.parentTime }}</span>
<div v-if="props.item.parentIndex" class="dividing-line"></div>
<span class="time"> 第 {{ props.item.parentIndex }} 张图片</span>
</div>
</div>
<!-- 加载中 -->
<div v-if="props.item.status === 'none'" class="box none-box">
<!-- <img :src="primaryPicture" alt="无" class="img" /> -->
</div>
<!-- 生成失败 -->
<div v-if="props.item.status === 'error'" class="box none-box">
<img :src="primaryPicture" alt="无" class="img" />
<!-- <span>生成失败</span> -->
</div>
<!-- 生成中 -->
<div v-if="props.item.status === 'generate'" class="box generate-box">
<div class="generate-content">
<!-- 欢快的加载动画 -->
<div class="loading-animation">
<div class="bounce-dot"></div>
<div class="bounce-dot"></div>
<div class="bounce-dot"></div>
</div>
<!-- 状态文本 -->
<div class="status-text">{{ generateStatusText }}</div>
</div>
</div>
<!-- 已完成 -->
<div v-if="props.item.status === 'success'" class="box success-box">
<div v-for="(file, index) in props.item.files" :key="index" class="one-box">
<img :src="file" alt="index" class="img" />
<div class="left-top">
<div class="left-top-btn" @click="downloadImage(file, 'image')"><img src="@/assets/display/download.svg" /></div>
<span class="line" />
<div class="left-top-btn" @click="addCollection(file)"><img src="@/assets/display/collection.svg" /></div>
</div>
<div class="bottom-brush">
<el-tooltip
effect="dark"
content="画笔"
placement="top"
>
<img @click.stop="AIvideo(file, index)" :src="brush" />
</el-tooltip>
</div>
</div>
</div>
<div v-if="props.item.status === 'success'" class="bottom-btn-group">
<div v-for="(item, index) in bottomBtnGroup" :key="index" class="bottom-btn" @click="item.click(file, index)">
<img :src="item.icon" />
<span>{{ item.name }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import brush from '@/assets/display/brush.svg'
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
import { downloadImage } from '@/utils/downloadImage.js'
import reEditIcon from '@/assets/display/reEdit.svg'
import againGenerateIcon from '@/assets/display/againGenerate.svg'
import deleteImageIcon from '@/assets/display/deleteImage.svg'
const props = defineProps({
item: {
type: Object,
default: () => ({})
}
})
const useDisplay = useDisplayStore()
const useParams = useParamStore()
const useUser = useUserStore()
const reEdit = (url, number) => {
console.log(number)
// const index = String(number + 1)
// useDisplay.DialogModification = true
// useDisplay.AIvideo = false
// useParams.dialogModificationImage = { title: '对话修改', url, time: props.item.time, parentIndex: index, parentTaskId: props.item.id }
}
const againGenerate = (url, number) => {
console.log(number)
// const index = String(number + 1)
// useDisplay.AIvideo = true
// useDisplay.DialogModification = false
// useParams.AIvideoImage = { title: '对话修改', url, time: props.item.time, parentIndex: index, parentTaskId: props.item.id }
}
const deleteImage = (url, number) => {
console.log(number)
// const index = String(number + 1)
// useDisplay.deleteImage = true
// useParams.deleteImage = { title: '删除图片', url, time: props.item.time, parentIndex: index, parentTaskId: props.item.id }
}
const bottomBtnGroup = [
{
name: '重新编辑',
icon: reEditIcon,
click: reEdit
},
{
name: '再次生成',
icon: againGenerateIcon,
click: againGenerate
},
{
name: '删除该批次',
icon: deleteImageIcon,
click: deleteImage
}
]
const addCollection = (url) => {
setCollectImg({ userId: useUser.userInfo.id, url, clothesId: 0 }).then((res) => {
if (res.code === '0' && res.success === true) {
// eslint-disable-next-line no-undef
ElMessage.success('添加收藏成功')
} else {
// eslint-disable-next-line no-undef
ElMessage.error(res.msg || '添加收藏失败')
}
})
}
</script>
<style lang="less" scoped>
.primary-box{
width: 100%;
max-width: 1024px;
display: flex;
flex-direction: column;
flex: 1;
gap: 20px;
padding-bottom: 20px;
}
.none-primary-box{
height: 350px;
}
.title{
height: 25px;
width: 100%;
display: flex;
align-items: center;
gap: 20px;
.style{
display: flex;
align-items: center;
gap: 10px;
}
.name{
color: #333;
font-family: "Microsoft YaHei";
font-size: 15px;
font-style: normal;
font-weight: 700;
line-height: normal;
}
.time{
color: #333;
font-family: "Microsoft YaHei";
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.dividing-line{
height: 100%;
border: 1px solid #ccc;
}
.delete-btn{
cursor: pointer;
}
.delete-btn:hover{
color: #ff4949;
}
}
.box{
height: calc(100% - 37px);
width: 100%;
}
.none-box{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.img{
width: 100%;
max-width: 300px;
}
}
// 生成中
.generate-box {
height: 300px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 20px;
.generate-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
.status-text {
font-size: 14px;
color: #333;
font-weight: 600;
font-family: "Microsoft YaHei";
}
}
}
// 欢快的弹跳动画
.loading-animation {
display: flex;
gap: 8px;
justify-content: center;
align-items: center;
.bounce-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #333;
animation: bounce 1.5s infinite ease-in-out;
&:nth-child(2) {
animation-delay: 0.2s;
background-color: #409eff;
}
&:nth-child(3) {
animation-delay: 0.4s;
background-color: #67c23a;
}
}
}
@keyframes bounce {
0%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-15px);
}
}
// 成功
.one-box{
position: relative;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
border-radius: 10px;
// height: 100%;
}
.one-box:hover{
.left-top,.bottom-brush{
display:flex
}
}
.success-box{
display: grid;
grid-template-columns: repeat(4, 1fr);
border-radius: 10px;
gap: 10px;
.img{
width: 100%;
height: auto; /* 保持宽高比 */
object-fit: contain; /* 确保图片完整显示,不被裁剪 */
border-radius: 8px; /* 可选:给图片添加圆角 */
}
}
.left-top,.bottom-brush{
display: none;
position: absolute;
z-index: 1;
cursor: pointer;
justify-content: center;
align-items: center;
}
.left-top{
padding: 4px 6px;
gap: 10px;
right: 10px;
top: 10px;
border-radius: 5px;
background: rgba(51, 51, 51, 0.80);
backdrop-filter: blur(2.5px);
.left-top-btn{
display: flex;
align-items: center;
padding: 4px;
border-radius: 4px;
}
.line{
width: 1px;
height: 12px;
background-color: #ccc;
}
}
.bottom-brush{
width: 60px;
height: 32px;
border-radius: 10px;
background: rgba(51, 51, 51, 0.80);
backdrop-filter: blur(2.5px);
bottom: 10px;
}
.left-top-btn:hover,.bottom-brush:hover {
background-color: rgb(112, 112, 112);
}
// 成功时底部按钮组
.bottom-btn-group{
display: flex;
align-items: center;
gap: 10px;
}
.bottom-btn{
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
.bottom-btn:hover{
background-color: #e4e7ed;
}
</style>