Files
aida_front/src/component/HomePage/scaleImage.vue
2025-01-07 17:15:28 +08:00

666 lines
19 KiB
Vue

<template>
<div ref="scaleImageModal">
<a-modal
class="scaleImage_modal generalModel"
v-model:visible="scaleImage"
:footer="null"
:get-container="() => $refs.scaleImageModal"
width="78%"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="scaleImageMask"
:keyboard="false"
:destroyOnClose="true"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" 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 class="generalModel_closeIcon download" @click.stop="download()">
<i class="fi fi-rr-down-to-line"></i>
</div>
</div>
<div class="scaleImage_content">
<div v-if="isProductimg" class="productImg_modal">
<div class="productImg_left">
<div class="productImg_content_item_title productImg_content_item_title_menu">
<span>{{$t('ProductImg.MagicTools')}}</span>
</div>
<div class="input_border productImg_content_item_generate">
<div class="input_box">
<div class="input_box_btnBox">
<input
class="search_input"
:placeholder="$t('Generate.inputContent1')"
v-model="productimgSearchName"
@keydown.enter="getPrductimg()"
/>
<i v-show="!productimgIsTextarea" class="fi fi-br-expand" @click.stop="()=>productimgIsTextarea = !productimgIsTextarea"></i>
<i v-show="productimgIsTextarea" class="fi fi-bs-compress" @click.stop="()=>productimgIsTextarea = !productimgIsTextarea"></i>
</div>
<textarea
v-show="productimgIsTextarea"
class="search_textarea "
@keydown.enter="getPrductimg()"
v-model="productimgSearchName"
></textarea>
</div>
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'ToProductImage'" class="productImg_content_item_title productImg_content_item_title_similarity">
<span>{{$t('ProductImg.Similarity')}}</span>
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'ToProductImage'" class="productImg_content_item_similarity ">
<a-slider class="system_silder"
v-model:value="productimgSimilarity"
:tooltipVisible="false"
:step="5"
@afterChange="()=>{}"
>
</a-slider>
<input type="number" readonly v-model="productimgSimilarity">
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'Relight'" class="productImg_content_item_title productImg_content_item_title_similarity">
<span>{{$t('ProductImg.RelightDirection')}}</span>
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'Relight'" class="productImg_content_item_Direction">
<!-- <a-slider class="system_silder"
v-model:value="similarity"
@afterChange="setSimilarity"
:tooltipVisible="false"
:step="5"
>
</a-slider> -->
<a-select style="width: 100%;" v-model:value="productimgRelightDirection" :options="productimgRelightDirectionList"></a-select>
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'Relight'" class="productImg_content_item_title productImg_content_item_title_similarity">
<span>{{$t('ProductImg.Highlight')}}</span>
</div>
<div v-show="scaleImageList[scaleImageIndex]?.resultType == 'Relight'" class="productImg_content_item_similarity">
<a-slider class="system_silder"
v-model:value="productimgBrightenValue"
:tooltipVisible="false"
:max="3"
:min="1"
:step="0.1"
>
</a-slider>
<input type="number" readonly v-model="productimgBrightenValue">
</div>
<div class="productImg_content_item_generate_btn input_border">
<div class="input_box">
<div v-show="!productimgIsProductimg" class="generage_btn started_btn" @click.stop="getPrductimg">
{{ $t('Generate.Generate') }}
</div>
<div v-show="productimgIsProductimg && !productimgRemProductimg" class="generage_btn started_btn" @click="getPrductimg">
<i class="fi fi-br-loading"></i>
</div>
<div v-show="productimgRemProductimg" @click="removeProductimg" class="generage_btn started_btn">
{{$t('Generate.Close')}}
</div>
</div>
</div>
</div>
</div>
<div class="scaleImage_content_imgBox" :class="{active:isComparison}">
<img v-if="isComparison" :src="scaleImageList[scaleImageIndex]?.sourceUrl">
<generalMiniCanvas v-if="isCanvas" :imgUrl="scaleImageList[scaleImageIndex]?.imgUrl" @submitBase64Data="submitBase64Data"></generalMiniCanvas>
<img v-else :src="scaleImageList[scaleImageIndex]?.imgUrl || scaleImageList[scaleImageIndex]?.url">
<div class="img_operate_block" v-if="isLike">
<i v-if="!scaleImageList[scaleImageIndex]?.like" class="fi fi-rr-heart operate_icon" @click.stop="LikeFile(scaleImageList[scaleImageIndex],'like')"></i>
<i v-else class="fi fi-sr-heart operate_icon" :adminLike="!!scaleImageList[scaleImageIndex]?.like" @click.stop="LikeFile(scaleImageList[scaleImageIndex],'noLike')"></i>
</div>
</div>
</div>
<div class="scaleImage_nav">
<div class="nav_left">
<i class="fi fi-rr-arrow-small-left" @click="lastStep()"></i>
</div>
<div class="nav_list" v-mousewheel>
<div class="nav_centent">
<img v-for="item,index in scaleImageList" @click="setScaleImageIndex(index)" :class="{active:index == scaleImageIndex}" :src="item?.imgUrl || item?.url" :key="item.id">
</div>
</div>
<div class="nav_right">
<i class="fi fi-rr-arrow-small-right" @click.stop="nextStep()"></i>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</a-modal>
</div>
</template>
<script lang="ts">
import { defineComponent, h, ref ,toRefs,createVNode,reactive, computed} from "vue";
import { Https } from "@/tool/https";
import { Modal } from "ant-design-vue";
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { downloadIamge } from "@/tool/util";
import { useI18n } from "vue-i18n";
import { useStore } from "vuex";
import generalMiniCanvas from "@/component/modules/generalMiniCanvas.vue";
export default defineComponent({
components:{generalMiniCanvas},
props:{
productData:{
type:Object,
default:{
similarity:30,
brightenValue:1,
upload:'',
},
},
isCanvas:{
type:Boolean,
default:false,
},
workspace:{
type:Object,
default:{
}
},
},
setup(props:any,{emit}) {
const store = useStore();
let userDetail:any= computed(()=>{
return store.state.UserHabit.userDetail
})
let {t} = useI18n()
let productimg = reactive({
isProductimg:false,
productimgSearchName:'',
productimgIsTextarea:false,
productimgRemProductimg:false,
productimgIsProductimg:false,
productimgSimilarity:props.productData.similarity,
productimgBrightenValue:props.productData.brightenValue,
productimgUpload:props.productData.upload,
productimgRelightDirection:props.productData.RelightDirection,
productimgRelightDirectionList:props.productData.RelightDirectionList,
})
let scaleImage: any = ref(false);
let isShowMark = ref(false)
let loadingShow = ref(false)
let isComparison = ref(false)
const visible = ref<boolean>(false);
const setVisible = (value:any): void => {
visible.value = value;
};
let scaleImageList:any = ref([
])
let scaleImageMask:any = ref(false)
let scaleImageIndex:any = ref(0)
let isLike:any = ref(true)
let robotAssits:any = ref(0)
//procuctimg
let remPrductimgTime:any = null
let prductimgTime:any = null
let getPrductimg = ()=>{
let obj = {
elementId:scaleImageList.value[scaleImageIndex.value].elementId,
elementType:scaleImageList.value[scaleImageIndex.value].elementType,
}
let imageStrength = productimg.productimgSimilarity == 100? 95 :productimg.productimgSimilarity
let data:any ={
direction:productimg.productimgRelightDirection,
prompt:productimg.productimgSearchName,
toProductImageVOList:[obj],
brightenValue:productimg.productimgBrightenValue,
userLikeGroupId:productimg.productimgUpload.userlikeGroupId,
imageStrength:(100 - imageStrength)/100,
}
productimg.productimgIsProductimg = true
remPrductimgTime = setTimeout(()=>{
productimg.productimgRemProductimg = true
},10000)
let url = Https.httpUrls.relight
if(scaleImageList.value[scaleImageIndex.value]?.resultType == 'ToProductImage'){
url = Https.httpUrls.toProduct
}
isShowMark.value = true
Https.axiosPost(url, data).then(
(rv) => {
isShowMark.value = false
scaleImageList.value[scaleImageIndex.value].imgUrl = '/image/loading.gif'
let arr:any = []
rv.forEach((item:any)=>{
arr.push(item.taskId)
})
// productimg.generateList.unshift(...rv)
setPrductimg(arr)
}
).catch(res=>{
isShowMark.value = false
productimg.productimgIsProductimg = false
clearInterval(remPrductimgTime)
productimg.productimgRemProductimg = false
});
}
let generateProceedList:any = []
let setPrductimg = (dataList:any)=>{
let data = dataList
let dataNum = dataList.length
let state = true
let url = Https.httpUrls.relightResult
if(scaleImageList.value[scaleImageIndex.value]?.resultType == 'ToProductImage'){
url = Https.httpUrls.toProductImageResult
}
prductimgTime = setInterval(()=>{
if(!state)return
state = false
Https.axiosPost(url, data).then(
(rv) => {
state = true
if(productimg.productimgIsProductimg){//防止取消后有正在执行的获取状态
// generateProceedList = rv.filter((item:any)=>item.status != 'Success' && item.status != 'Fail' && item.status != 'Invalid')
let isEnd = false
if(rv[0].status == 'Success'){
rv[0].imgUrl = rv[0].url
scaleImageList.value[scaleImageIndex.value] = rv[0]
isEnd = true
}else if(rv[0].status == 'Fail'){
isEnd = true
}
generateProceedList = data
if(isEnd){
store.state.store.dispatch('getCredits')
clearInterval(prductimgTime)
clearInterval(remPrductimgTime)
productimg.productimgRemProductimg = false
productimg.productimgIsProductimg = false
}
}
}
).catch(res=>{
clearInterval(prductimgTime)
clearInterval(remPrductimgTime)
productimg.productimgIsProductimg = false
productimg.productimgRemProductimg= false
});
},1000)
}
let removeProductimg = ()=>{
productimg.productimgIsProductimg = false
productimg.productimgRemProductimg= false
clearInterval(prductimgTime)
if(generateProceedList){
// let str = generateProceedList.map((obj:any) => obj.taskId).join(',');
let str = generateProceedList.join(',')
let data = {
uniqueId:str,
userId:userDetail.value.userId,
type:scaleImageList.value[scaleImageIndex.value]?.resultType
}
Https.axiosGet(Https.httpUrls.generateStopWaiting, {params:data}).then(
(rv) => {
generateProceedList = []
}
).catch(res=>{
});
}
}
let submitBase64Data = async (rv:any)=>{
loadingShow.value = true
let isOverlay = false
await new Promise<void>((resolve, reject) => {
Modal.confirm({
title: t('scaleImage.overlayOrNot'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
resolve()
isOverlay = true
},
onCancel(){
isOverlay = false
resolve()
}
});
})
let data = {
"base64": rv,
"category": scaleImageList.value[scaleImageIndex.value]?.categoryValue,
"gender": props.workspace.sexEnum.value,
"originalId":scaleImageList.value[scaleImageIndex.value]?.id,
"isOverride":isOverlay,
}
Https.axiosPost(Https.httpUrls.modifySketch, data).then(
(rv) => {
rv.imgUrl = rv.url
rv.status = 'Success'
rv.category = scaleImageList.value[scaleImageIndex.value]?.category
rv.categoryValue = scaleImageList.value[scaleImageIndex.value]?.categoryValue
isOverlay?(scaleImageList.value[scaleImageIndex.value] = rv):(scaleImageList.value.unshift(rv))
loadingShow.value = false
scaleImage.value = false
}
).catch(res=>{
loadingShow.value = false
});
}
return {
t,
...toRefs(productimg),
scaleImage,
isShowMark,
loadingShow,
isComparison,
visible,
setVisible,
scaleImageList,
scaleImageMask,
scaleImageIndex,
isLike,
robotAssits,
getPrductimg,
removeProductimg,
submitBase64Data,
};
},
data() {
return {
// moodTemplateId: "", //模板id
isNext:false
};
},
directives:{
mousewheel:{
mounted (el) {
el.addEventListener('wheel',(e:WheelEvent)=>{
let num = 0
if(e.deltaY > 0){
num = 25
}else{
num = -25
}
el.scrollBy(num, 0);
})
}
},
},
mounted() {
},
methods: {
init(list:any,index:any,dialogueIndex:any){
this.scaleImage = true
this.scaleImageList = list
this.scaleImageIndex = index
if(dialogueIndex)this.robotAssits = dialogueIndex
// let scaleImageList = this.store.state.UploadFilesModule.moodboard
document.addEventListener('keydown',this.setKeydown)
},
cancelDsign(){
this.scaleImage = false
this.scaleImageList = []
this.scaleImageIndex = 0
this.isNext = false
document.removeEventListener('keydown',this.setKeydown)
},
lastStep(){
if(this.productimgIsProductimg) return
if(this.isNext)return
let num = this.scaleImageIndex
if(this.scaleImageIndex <= 0){
}else{
num -=1
this.setImageIndex(num)
}
},
nextStep(){
if(this.productimgIsProductimg) return
if(this.isNext)return
let num = this.scaleImageIndex
if(this.scaleImageIndex >= this.scaleImageList.length-1){
}else{
num += 1
this.setImageIndex(num)
}
},
download(){
downloadIamge(this.scaleImageList[this.scaleImageIndex].imgUrl)
},
setScaleImageIndex(index:any){
// this.scaleImageIndex = index
this.setImageIndex(index)
},
setImageIndex(index:any){
if(this.isNext)return
let this_ = this
if(this.isCanvas){
this.isNext = true
new Promise((resolve,reject)=>{
Modal.confirm({
title: this.t('scaleImage.submitCanvas'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
this_.scaleImageIndex = index
this_.isNext = false
resolve('')
},
onCancel(){
this_.isNext = false
resolve('')
}
});
})
}else{
this.scaleImageIndex = index
}
},
LikeFile(item:any,str:string){
let parent:any = this.$parent
if(this.robotAssits){
parent.likeFile(item,this.scaleImageIndex,this.robotAssits)
}else{
parent.likeFile(item,str)
}
},
setKeydown(event:any){
if(event.keyCode == 37){
this.lastStep()
}else if(event.keyCode == 39){
this.nextStep()
}
},
},
});
</script>
<style scoped>
.scaleImage_modal{
overflow: visible !important;
}
</style>
<style lang="less" scoped>
.scaleImage_modal {
.ant-modal-body {
display: flex;
flex-direction: column;
}
.productImg_content_item_title{
font-weight: 600;
font-size: 1.6rem;
}
.scaleImage_content{
display: flex;
justify-content: center;
// margin-top: calc(5rem*1.2);
// height: 75%;
height: 100%;
position: relative;
.productImg_modal{
position: relative;
left: 0;
z-index: 9;
.productImg_left{
width: 100%;
.input_box_btnBox{
width: 100%;
}
.input_box{
justify-content: flex-end;
}
.productImg_content_item_generate_btn{
transform: translateY(100%);
position: absolute;
bottom: 0;
top: auto;
width: 100%;
justify-content: space-around;
}
.productImg_content_item_similarity{
padding-bottom: 2.4rem;
display: flex;
input{
width: 5rem;
height: 5rem;
text-align: center;
font-size: 1.8rem;
}
}
}
}
.scaleImage_content_imgBox{
position: relative;
// max-width: 70rem;
width: 100%;
text-align: center;
justify-content: center;
img{
width: auto;
height: 100%;
max-width: 40rem;
object-fit: contain;
}
&.active{
display: flex;
img{
// width: 50%;
height: 100%;
object-fit: cover;
}
}
.img_operate_block{
width: 3.6rem;
height: 3.6rem;
background: rgba(0,0,0,0.6);
border-radius: 50%;
text-align: center;
line-height: 3.6rem;
cursor: pointer;
margin-bottom: 0.4rem;
position: absolute;
right: 2rem;
top: 2rem;
opacity: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
.operate_icon{
font-size: 1.8rem;
color: #fff;
&.fi-sr-heart{
color: red;
}
}
i{
display: flex;
font-size: 1.8rem;
color: #fff;
}
}
}
}
.scaleImage_content_imgBox:hover{
.img_operate_block{
opacity: 1;
}
}
.scaleImage_nav{
flex: 1;
margin: calc(2.5rem*1.2) calc(0rem*1.2);
display: flex;
justify-content: center;
align-items: center;
width: 100%;
top: 100%;
left: 0;
position: absolute;
.nav_left,.nav_right{
cursor: pointer;
top: 50%;
i{
display: flex;
font-size: 4rem;
transition: .3s all;
color: rgba(0, 0, 0, .5);
}
}
// .nav_left{
// left: 0;
// transform: translate(-200%,-50%);
// }
// .nav_right{
// right: 0;
// transform: translate(200%,-50%);
// }
.nav_left:hover,.nav_right:hover{
i{
color: rgba(0, 0, 0, 1);
}
}
.nav_list{
margin: 0 calc(2rem*1.2);
max-width: calc(60rem*1.2);
overflow-y: hidden;
&.nav_list::-webkit-scrollbar {
display: none;
}
.nav_centent{
width: auto;
display: flex;
}
img{
max-width: calc(5rem*1.2);
max-height: calc(5rem*1.2);
object-fit: cover;
object-position: 50%,50%;
margin-left: calc(1rem*1.2);
border-radius: calc(1rem*1.2);
overflow: hidden;
cursor: pointer;
padding: calc(.1rem*1.2);
flex-shrink: 0;
&.active{
border: 2px solid #aaaaaa;
}
}
img:nth-child(1){
margin-left: calc(0rem*1.2);
}
}
}
}
</style>