Files
aida_front/src/component/home/design/tools.vue
X1627315083 0efb7ec6da fix
2025-10-13 17:32:24 +08:00

544 lines
16 KiB
Vue

<template>
<div class="designToolsModel" ref="designToolsModel" v-show="designTools"></div>
<a-modal
class="collection generalModel fullScreen"
v-model:visible="designTools"
:footer="null"
width="100%"
height="100%"
:get-container="() => $refs.designToolsModel"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="false"
:keyboard="false"
:destroyOnClose="true"
:zIndex="1000"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cleardata()">
<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="designOpenrtion_content">
<!-- <div class="modal_title_text">
<div>Setting</div>
</div> -->
<div class="collectionBox">
<toProductRelight ref="toProduct"
:productimgMenu="{value:'ToProductImage',label:$t('ProductImg.ProductImage')}"
:isDesignPage="true"
@setLike="designLike"
class="toProduct"
:source="source"
@unLike="unLike"
:isState="openType =='toProduct'"
v-if="openType == 'toProduct'"
></toProductRelight>
<toProductRelight ref="relight"
:productimgMenu="{value:'Relight',label:$t('ProductImg.Relight')}"
:isDesignPage="true"
@setLike="designLike"
class="relight"
:source="source"
@unLike="unLike"
:isState="openType =='relight'"
v-if="openType == 'relight'"
></toProductRelight>
<poseTransfer v-if="openType == 'poseTransfer'" @unLike="unLike" :source="source" :isDesignPage="true" @setLike="designLike" ref="poseTransfer"></poseTransfer>
<div v-if="openType == 'editCanvas'" class="canvasBox" :class="{editCanvas:openType == 'editCanvas'}">
<div class="canvas" ref="canvasBox">
<editCanvas
@changeCanvas="changeCanvas"
@trigger-library="triggerLibrary"
:canvasJSON="canvasJSON"
ref="editCanvas">
<template #existsImageList>
<ExistsImageList :list="canvasSelectList" @select="handleImageSelect" />
</template>
</editCanvas>
<!-- <canvasAA ></canvasAA> -->
</div>
<div class="btn">
<div class="gallery_btn" @click="saveCanvas">{{ $t('exportModel.Save') }}</div>
<div class="gallery_btn" @click="share">{{ $t('exportModel.Share') }}</div>
<div class="gallery_btn" @click="exportElement">{{ $t('exportModel.Export') }}</div>
</div>
</div>
</div>
</div>
<publish ref="publish" @setPublish="setPublish"></publish>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
</a-modal>
<SelectImages
ref="selectImages"
@select="handleImageSelect"
:api="Https.httpUrls.queryLibraryPage"
isLibrary
/>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,inject,toRefs, reactive, onBeforeMount} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal,message } from 'ant-design-vue';
import { downloadIamge,getMinioUrl } from "@/tool/util";
import { useI18n } from 'vue-i18n'
import toProductRelight from '../tools/toProduct/index.vue'
import poseTransfer from '../tools/poseTransfer/index.vue'
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
import ExistsImageList from "@/component/Canvas/ExistsImageList/index.vue";
import JSZip, { forEach } from "jszip";
import publish from "@/component/WorksPage/publish.vue";
import canvasAA from '@/component/Canvas/canvasExample.vue'
import SelectImages from '@/component/common/SelectImages.vue'
export default defineComponent({
components:{
toProductRelight,poseTransfer,editCanvas,ExistsImageList,publish,canvasAA,SelectImages
},
props:{
source:{
type:String,
default:'',
},
},
emits:['editToolsSuccess'],
setup(props,{emit}) {
const store = useStore();
let locale = null as any;
let t = null as any;
const data = reactive({
designTools:false,
isShowMark:false,
openType:'',
selectObject:computed(()=>store.state.Workspace.probjects),//选择的项目
canvasJSON:computed(()=>store.state.HomeStoreModule.canvasData.canvas),
createProbject:inject('createProbject',()=>{}) as any,
likeDesignList:[],
canvasSelectList:[] as any,
videoList:[] as any,
canvasDetailData:null as any,
unLikeList:[],
locale:null as any,
t:null as any,
})
const dataDom = reactive({
toProduct:null as any,
relight:null as any,
poseTransfer:null as any,
editCanvas:null as any,
publish:null as any,
}) as any
const init = async (value:any,list:any,t:any,locale:any)=>{
data.t = t
data.locale = locale.value
data.designTools = true
if(value == 'editCanvas')await getCanvasData('canvas')
data.openType = value
if(value == 'editCanvas'){
nextTick(()=>{
getSelectCanvasImg()
return
})
}
data.likeDesignList = list
nextTick(()=>{
let fileList = [] as any
let likeList = [] as any
if(value == 'toProduct'){
list.forEach((item:any) => {
item.type = 'DesignOutfit'
fileList.push(item)
item.childList.forEach((child:any) => {
if(child.resultType == 'ToProductImage'){
likeList.push(child)
}
});
});
}else if(value == 'relight' || value == 'poseTransfer'){
list.forEach((item:any) => {
if(item.childList){
item.childList.forEach((child:any) => {
if(child.resultType == 'ToProductImage' || child.resultType == 'Relight'){
fileList.push(child)
}
if(child.resultType == 'Relight' && value == 'relight'){
likeList.push(child)
}else if(child.resultType == 'PoseTransfer' && value == 'poseTransfer'){
likeList.push(child)
}
});
}
});
}
let likeData = {
likedList: likeList,
str:'add',
index:-1,
}
store.commit('toolsClear')
if(data.openType == 'toProduct'){
store.commit("setToProductImage", likeData);
}else if(data.openType == 'relight'){
store.commit("setRelightList", likeData);
}else if(data.openType == 'poseTransfer'){
store.commit("setPoseTransfer", likeData);
}
if(dataDom[value]?.openSetData)dataDom[value]?.openSetData(fileList)
})
}
const unLike = (item)=>{
data.unLikeList.push(item)
}
let cleardata = async ()=>{
let list = []
if(data.openType == 'toProduct'){
list = store.state.HomeStoreModule.toProductImageList.likedList
}else if(data.openType == 'relight'){
list = store.state.HomeStoreModule.relightList.likedList
}else if(data.openType == 'poseTransfer'){
list = store.state.HomeStoreModule.poseTransfer.likedList
}
let generateCourse = list.filter((item) => item.newLike)
.map(item => {
// 删除 newLike 字段
const { newLike, ...rest } = item; // 解构赋值移除 newLike
return item.oldSort ? { ...rest, sort: item.oldSort } : rest;
});
let emitData = {
status:'add',
addList:generateCourse,
deleteList:data.unLikeList,
}
emit('editToolsSuccess',emitData)
data.openType = ''
data.designTools = false
data.unLikeList = []
store.commit('toolsClear')
}
const designLike = ()=>{
}
//画布相关
const getCanvasData = (str:any)=>{
return new Promise((resolve, reject) => {
let value = {
module:str,
projectId:data.selectObject.id,
}
Https.axiosPost(Https.httpUrls.exportSearch, value)
.then((rv) => {
store.commit("setCanvasData", {type:str,file:rv});
resolve('')
})
.catch((rv) => {
resolve(null)
});
})
}
const getSelectCanvasImg = ()=>{
data.canvasSelectList = []
let allCollection = store.state.UploadFilesModule.allBoardData
let allCollectionStr = [
{value:'disposeMoodboard',name:'Entirety Moodboard',nameCn:'整体情绪版'},
{value:'moodboardFiles',name:'Moodboard',nameCn:'情绪版'},
{value:'printboardFiles',name:'Printboard',nameCn:'印花板'},
{value:'sketchboardFiles',name:'Sketchboard',nameCn:'整体情绪版'},
]
allCollectionStr.forEach((itemStr:any)=>{
let list = [] as any
allCollection[itemStr.value].forEach((imgItem)=>{
list.push({url:imgItem.url || imgItem.imgUrl})
})
let obj = {
value:itemStr.value,
type:data.locale == "ENGLISH"?itemStr.name:itemStr.nameCn,
imgList:list,
}
if(list.length > 0){
data.canvasSelectList.push(obj)
}
})
let designData = store.state.HomeStoreModule.likeDesignCollectionList
if(designData.length > 0){
let list = [] as any
designData.forEach((item:any)=>{
list.push({url:item.designOutfitUrl || item.url})
if(item.childList.length > 0){
item.childList.forEach((childItem)=>{
if(childItem.relationType == "PoseTransfer"){
data.videoList.push({url:childItem.videoUrl})
}else{
list.push({url:(childItem?.designOutfitUrl || childItem?.url)})
}
})
}
})
let obj = {
value:'design',
type:data.locale == "ENGLISH"?'Design':'设计',
imgList:list
}
if(list.length > 0){
data.canvasSelectList.push(obj)
}
}
let mannquinList = data.selectObject.model
let list = [] as any
mannquinList.forEach((item:any)=>{
list.push({url:item.url})
})
let obj = {
value:'mannquin',
// type:'Mannquin',
type:data.locale == "ENGLISH"?'Mannquin':'模特',
imgList:list
}
if(list.length > 0){
data.canvasSelectList.push(obj)
}
}
const selectImages = ref(null)
const triggerLibrary = ()=>{
selectImages.value.init()
}
const handleImageSelect = (list:any)=>{
list.forEach(item => {
dataDom.editCanvas.addImageToLayer(item)
});
}
const saveCanvas = ()=>{
let canvasJSON = dataDom.editCanvas.getJSON()
let canvasData = JSON.parse(canvasJSON)
if(!canvasData)return
canvasData.canvas.objects.forEach((objectsItem:any) => {
if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src)
});
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData();
formData.append("file", blob, "data.json");
formData.append("module", "canvas");
formData.append("projectId", store.state.Workspace.probjects.id)
let config = {
headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
};
Https.axiosPost(Https.httpUrls.exportSave, formData, config).then(
(rv) => {
message.success(data.t('exportModel.jsContent7'))
}
);
}
const exportElement = async ()=>{
//设置导出
let img = [] as any;
if(data.canvasDetailData?.commandManager?.undoStack?.length > 0){
await dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:false}).then((rv:any)=>{
var imageDataURL = rv
img.push({
imgUrl: imageDataURL,
name: "collection.png",
});
})
}
for(let i = 0; i < data.canvasSelectList.length;i++){
let item = data.canvasSelectList[i]
item.imgList.forEach((imgItem:any,index:any)=>{
let nameTail = imgItem.url?.split(".").pop().split("?").shift();
img.push({
imgUrl:imgItem.url,
name:`${item.type}${index}.${nameTail?nameTail:'png'}`
})
})
}
data.videoList.forEach((imgItem:any,index:any)=>{
let nameTail = imgItem.url?.split(".").pop().split("?").shift();
img.push({
imgUrl:imgItem.url,
name:`video${index}.${nameTail?nameTail:'mp4'}`
})
})
if(img.length>0)downImg(img);
}
let getImgArrayBuffer = (url) => {
return new Promise((resolve, reject) => {
//通过请求获取文件blob格式
let xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.responseType = "blob";
xmlhttp.withCredentials = false;
xmlhttp.onload = function () {
if (this.status == 200) {
resolve(this.response);
} else {
reject(this.status);
}
};
xmlhttp.send();
});
};
let downImg = (imagesParams:any) => {
let zip = new JSZip();
let cache = {};
let promises = [];
for (let item of imagesParams) {
const promise = getImgArrayBuffer(item.imgUrl).then((value) => {
// 下载文件, 并存成ArrayBuffer对象(blob)
zip.file(item.name, value, { binary: true }); // 逐个添加文件
cache[item.title] = value;
})
promises.push(promise);
}
Promise.all(promises)
.then(() => {
function downloadBlob(blob, filename) {
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
document.body.removeChild(link);
}
zip.generateAsync({ type: "blob" }).then((content) => {
// 生成二进制流
downloadBlob(content,'DesignFiles')
// FileSaver.saveAs(content, "DesignFiles"); // 利用file-saver保存文件 自定义文件名
data.isShowMark = false;
});
})
.catch((res) => {
// message.warning(t('HomeView.jsContent3'));
data.isShowMark = false;
});
};
const changeCanvas = (value:any)=>{
data.canvasDetailData = value
}
const share = async ()=>{
var imageDataURL = '';
imageDataURL = await dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:false})
let value = {
imgUrl:imageDataURL,
userlikeGroupId:'',
}
dataDom.publish.init(value)
}
const setPublish = ()=>{
saveCanvas()
}
return{
...toRefs(dataDom),
...toRefs(data),
cleardata,
init,
designLike,
handleImageSelect,
saveCanvas,
exportElement,
changeCanvas,
share,
setPublish,
unLike,
triggerLibrary,
Https,
selectImages
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.designToolsModel{
position: relative;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
z-index: 1000;
:deep(>div){
// position: absolute;
// .ant-modal-mask{
// position: absolute;
// }
.ant-modal-wrap,.ant-modal-mask{
}
> .ant-modal-root{
> .ant-modal-centered{
> .fullScreen{
> .ant-modal-content{
box-shadow: none;
> .ant-modal-body{
padding: 0;
}
}
}
}
}
}
.designOpenrtion_content{
height: 100%;
> .collectionBox{
height: 100%;
display: flex;
> .canvasBox{
height: 100%;
width: 100%;
// flex:1;
// width: 99rem;
// height: 80rem;
display: flex;
overflow: hidden;
position: relative;
&.editCanvas{
padding-top: 5rem;
display: flex;
}
> .canvas{
position: relative;
flex: 1;
}
> .btn{
display: flex;
flex-direction: column;
justify-content: flex-end;
> div{
margin: 1rem;
}
}
}
}
}
.fullScreen{
.generalModel_btn {
.generalModel_closeIcon{
transform: translate(-100%, 50%);
}
}
}
}
</style>