fix
This commit is contained in:
@@ -60,8 +60,12 @@
|
||||
)
|
||||
const onAdd = () => {
|
||||
const tier_ = tier.value + 1
|
||||
// 从data中获取originalImage
|
||||
let nodeData = props.node?.data?.data.imageProcessTasks.filter((v) => v.taskId === props.node?.data?.data.selectTaskId)
|
||||
const originalImage = nodeData[0]?.url
|
||||
if(!originalImage)console.log('originalImage 找不到原始图片')
|
||||
props.stateManager.nodeManager.createCardsSelect({
|
||||
data: { tier: tier_, superiorID: props.node.id }
|
||||
data: { tier: tier_, superiorID: props.node.id, originalImage }
|
||||
})
|
||||
}
|
||||
const posCenter = computed(() => {
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
data: {
|
||||
tier: v.tier,
|
||||
type: v.type,
|
||||
superiorID
|
||||
superiorID,
|
||||
originalImage: props.node.data?.originalImage,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
import To3View from './to-3view.vue'
|
||||
import To3DModel from './to-3d-model.vue'
|
||||
|
||||
import { toRealStyleApi } from '@/api/flow-canvas'
|
||||
|
||||
// import ToVideo from './to-video.vue'
|
||||
// import AddPrint from './add-print.vue'
|
||||
// import ToCAD from './to-cad.vue'
|
||||
@@ -46,19 +48,20 @@
|
||||
title: 'Advanced Tools',
|
||||
component: CardsSelect,
|
||||
hideFooter: true,
|
||||
hideIcon: true
|
||||
hideIcon: true,
|
||||
},
|
||||
{
|
||||
tier: NODE_DATATIER.TO_REAL_STYLE,
|
||||
type: NODE_DATATYPE.TO_REAL_STYLE,
|
||||
title: 'To Real Style',
|
||||
component: ToRealStyle
|
||||
component: ToRealStyle,
|
||||
api: toRealStyleApi
|
||||
},
|
||||
{
|
||||
tier: NODE_DATATIER.SURFACE_EDIT,
|
||||
type: NODE_DATATYPE.SURFACE_EDIT,
|
||||
title: 'Surface Edit',
|
||||
component: SurfaceEdit
|
||||
component: SurfaceEdit,
|
||||
},
|
||||
{
|
||||
tier: NODE_DATATIER.SCENE_COMPOSITION,
|
||||
@@ -100,6 +103,10 @@
|
||||
| 'to-3view',
|
||||
default: 'to-real-style'
|
||||
},
|
||||
sketchId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
@@ -110,17 +117,32 @@
|
||||
return components.find((item) => item.type === props.type)
|
||||
})
|
||||
const componentRef = ref(null)
|
||||
const onGenerateClick = () => {
|
||||
|
||||
const onGenerateClick = async () => {
|
||||
const data = componentRef.value.data
|
||||
const subordNode = stateManager.getSubordNodeByID(attrs.node.id)
|
||||
emit('update-data', data)
|
||||
console.log(attrs.node,data)
|
||||
if(!attrs.node?.data?.originalImage)console.log('originalImage 找不到原始图片')
|
||||
|
||||
const apiData = {
|
||||
sketchId: props.sketchId,
|
||||
mode: data.mode,
|
||||
size: data.pixelRatio,
|
||||
imageUrl: attrs.node?.data?.originalImage,
|
||||
userPrompt: data.prompt,
|
||||
}
|
||||
const taskList = await currentComponent.value.api(apiData).then((rv)=>{
|
||||
return rv
|
||||
}) || []
|
||||
if (!subordNode) {
|
||||
nodeManager.createResultNode({
|
||||
data: {
|
||||
superiorID: attrs.node.id,
|
||||
tier: currentComponent.value.tier,
|
||||
data: {
|
||||
url: 'https://s3-alpha-sig.figma.com/img/ea2f/590e/9638f62a2fc91e31f33db0022db1642c?Expires=1773014400&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=M0B8oJJOk~dGG0aZAqOIocAp7T0LFdJ9FYmCrEZVTCRzYxM6SJRNtYMTX-rTO3Z~s14QINh~o-S41XiZnBv-0zcKjuWot~VVaNHfd0~1LesfNe2KwvCinT~72btFut1pheLnKE-wWCX5ewtonxU77bnw386YPMTqv7DBZzksf2udsJA7NmOYD6~TUG3Q2dWSt~zPH~lkaidscPqpCnCbqzljCEi4RiHY4U3A45l5XypcX2umqn1UaYUFCTqV9471J4qdB6Dg2pcKocdp-7-3s1De6Q~2SmBOrSgDQ~KEADCB2lhKfhxgWmy0lwMvhTd4l90ygVZDWZRABgjHNrGUvg__'
|
||||
imageProcessTasks:taskList,
|
||||
selectTaskId:taskList[0].taskId,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,49 +1,56 @@
|
||||
<template>
|
||||
<!-- 结果图片 -->
|
||||
<div class="result-image">
|
||||
<div class="header" v-show="showHeader" @mousedown.stop>
|
||||
<span class="icon">
|
||||
<svg-icon name="chat-compose" size="20" size-unit="px" />
|
||||
</span>
|
||||
<span class="icon" @click="onPreview">
|
||||
<svg-icon name="expand-lg" size="20" size-unit="px" />
|
||||
</span>
|
||||
<span class="icon" @click="onDownload">
|
||||
<svg-icon name="download" size="20" size-unit="px" />
|
||||
</span>
|
||||
<button class="edit" @click="onEdit">
|
||||
<span class="icon"><svg-icon name="edit" size="13" /></span>
|
||||
<span class="text">Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
<img
|
||||
class="image"
|
||||
:src="data.url"
|
||||
:style="{ transform: `scale(${data?.scale?.x || 1}, ${data?.scale?.y || 1})` }"
|
||||
/>
|
||||
<div class="more" @click="showMenu = !showMenu" @mousedown.stop>
|
||||
<svg-icon name="more" size="24" size-unit="px" color="#C9C9C9" />
|
||||
</div>
|
||||
<div class="menu" v-show="showMenu" @mousedown.stop>
|
||||
<div
|
||||
v-for="(v, i) in menus"
|
||||
:key="i"
|
||||
:class="[v.isDivide ? 'divide' : 'item', { disabled: v.disabled }]"
|
||||
@click="onMenuItem(v)"
|
||||
>
|
||||
<template v-if="!v.isDivide">
|
||||
<span class="label">{{ v.label }}</span>
|
||||
<span class="tip">{{ v.tip }}</span>
|
||||
</template>
|
||||
<div class="result-image-container" :class="{'show-border': data.imageProcessTasks.length > 1}">
|
||||
<div class="result-image"
|
||||
v-for="(item, i) in data.imageProcessTasks"
|
||||
:key="item.taskId"
|
||||
:class="{'active': item.taskId === data.selectTaskId}"
|
||||
@click="setSelectTaskId(item.taskId)"
|
||||
>
|
||||
<div class="header" v-show="showHeader && item.taskId === data.selectTaskId" @mousedown.stop>
|
||||
<span class="icon">
|
||||
<svg-icon name="chat-compose" size="20" size-unit="px" />
|
||||
</span>
|
||||
<span class="icon" @click="onPreview(item?.url)">
|
||||
<svg-icon name="expand-lg" size="20" size-unit="px" />
|
||||
</span>
|
||||
<span class="icon" @click="onDownload(item?.url)">
|
||||
<svg-icon name="download" size="20" size-unit="px" />
|
||||
</span>
|
||||
<button class="edit" @click="onEdit(item?.url)">
|
||||
<span class="icon"><svg-icon name="edit" size="13" /></span>
|
||||
<span class="text">Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
<img
|
||||
class="image"
|
||||
:src="item?.url"
|
||||
:style="{ transform: `scale(${item?.scale?.x || 1}, ${item?.scale?.y || 1})` }"
|
||||
/>
|
||||
<div class="more" @click="clickimageProcessTaskItem(item.taskId)" @mousedown.stop>
|
||||
<svg-icon name="more" size="24" size-unit="px" color="#C9C9C9" />
|
||||
</div>
|
||||
<div class="menu" v-show="showMenu && item.taskId === clickTaskId" @mousedown.stop>
|
||||
<div
|
||||
v-for="(v, i) in menus"
|
||||
:key="i"
|
||||
:class="[v.isDivide ? 'divide' : 'item', { disabled: v.disabled }]"
|
||||
@click="onMenuItem(v)"
|
||||
>
|
||||
<template v-if="!v.isDivide">
|
||||
<span class="label">{{ v.label }}</span>
|
||||
<span class="tip">{{ v.tip }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import myEvent from '@/utils/myEvent'
|
||||
import { downloadImage } from '../../../tools/tools'
|
||||
import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch } from 'vue'
|
||||
import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch, } from 'vue'
|
||||
const openImagePreview = inject('openImagePreview') as (url: string) => void
|
||||
const props = defineProps({
|
||||
config: {
|
||||
@@ -65,10 +72,21 @@
|
||||
const attrs = useAttrs()
|
||||
const showHeader = ref(!!attrs.node?.data?.isHeader)
|
||||
const showMenu = ref(false)
|
||||
const clickTaskId = ref('')
|
||||
const clickimageProcessTaskItem = (taskId: string) => {
|
||||
if(clickTaskId.value == taskId){
|
||||
showMenu.value = !showMenu.value
|
||||
}
|
||||
clickTaskId.value = taskId
|
||||
}
|
||||
const data = reactive({
|
||||
url: props.data?.url || '',
|
||||
scale: props.data?.scale || { x: 1, y: 1 }
|
||||
selectTaskId: props.data?.selectTaskId || '',
|
||||
imageProcessTasks: props.data?.imageProcessTasks || [],
|
||||
})
|
||||
const setSelectTaskId = (taskId: string) => {
|
||||
data.selectTaskId = taskId
|
||||
emit('update-data', data)
|
||||
}
|
||||
watch(
|
||||
() => props.data.url,
|
||||
(newVal) => {
|
||||
@@ -76,34 +94,49 @@
|
||||
}
|
||||
)
|
||||
const menus = ref([
|
||||
{ label: 'Copy', tip: 'Ctrl+C', on: () => emit('copy-node') },
|
||||
{ label: 'Copy', tip: 'Ctrl+C', on: () => emit('copy-node', clickTaskId.value) },
|
||||
{
|
||||
label: 'Delete',
|
||||
tip: 'Del',
|
||||
on: () => emit('delete-node'),
|
||||
on: () => {
|
||||
if(data.imageProcessTasks.length > 1){
|
||||
if(clickTaskId.value){
|
||||
data.imageProcessTasks = data.imageProcessTasks.filter((item) => item.taskId !== clickTaskId.value)
|
||||
clickTaskId.value = ''
|
||||
emit('update-data', data)
|
||||
}
|
||||
}else{
|
||||
emit('delete-node')
|
||||
}
|
||||
},
|
||||
disabled: !!props.config?.disableDelete
|
||||
},
|
||||
{ isDivide: true },
|
||||
{
|
||||
label: 'Bring to font',
|
||||
tip: '',
|
||||
on: () => {
|
||||
emit('bring-to-font')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Send to back',
|
||||
tip: '',
|
||||
on: () => {
|
||||
emit('send-to-back')
|
||||
}
|
||||
},
|
||||
{ isDivide: true },
|
||||
// {
|
||||
// label: 'Bring to font',
|
||||
// tip: '',
|
||||
// on: () => {
|
||||
// emit('bring-to-font')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: 'Send to back',
|
||||
// tip: '',
|
||||
// on: () => {
|
||||
// emit('send-to-back')
|
||||
// }
|
||||
// },
|
||||
// { isDivide: true },
|
||||
{
|
||||
label: 'Flip horizontal',
|
||||
tip: '',
|
||||
on: () => {
|
||||
data.scale.x = -data.scale.x
|
||||
data.imageProcessTasks.forEach((item) => {
|
||||
if(!item.scale){
|
||||
item.scale = { x: 1, y: 1 }
|
||||
}
|
||||
item.scale.x = -item.scale.x
|
||||
})
|
||||
emit('update-data', data)
|
||||
}
|
||||
},
|
||||
@@ -111,16 +144,21 @@
|
||||
label: 'Flip vertical',
|
||||
tip: '',
|
||||
on: () => {
|
||||
data.scale.y = -data.scale.y
|
||||
data.imageProcessTasks.forEach((item) => {
|
||||
if(!item.scale){
|
||||
item.scale = { x: 1, y: 1 }
|
||||
}
|
||||
item.scale.y = -item.scale.y
|
||||
})
|
||||
emit('update-data', data)
|
||||
}
|
||||
}
|
||||
])
|
||||
const onPreview = () => {
|
||||
openImagePreview(data.url)
|
||||
const onPreview = (url: string) => {
|
||||
openImagePreview(url)
|
||||
}
|
||||
const onDownload = () => {
|
||||
downloadImage(data.url, 'image.png')
|
||||
const onDownload = (url: string) => {
|
||||
downloadImage(url, 'image.png')
|
||||
}
|
||||
const onMenuItem = (v) => {
|
||||
if (v.disabled) return
|
||||
@@ -129,9 +167,10 @@
|
||||
}
|
||||
const hideMenu = () => {
|
||||
showMenu.value = false
|
||||
clickTaskId.value = ''
|
||||
}
|
||||
const onEdit = () => {
|
||||
myEvent.emit('openDepthCanvas', { url: data.url })
|
||||
const onEdit = (url: string) => {
|
||||
myEvent.emit('openDepthCanvas', { url })
|
||||
}
|
||||
document.addEventListener('mousedown', hideMenu)
|
||||
onBeforeUnmount(() => {
|
||||
@@ -141,6 +180,16 @@
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.result-image-container{
|
||||
&.show-border{
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 9.4px;
|
||||
padding: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr); /* 一行3列 */
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
.result-image {
|
||||
width: 244px;
|
||||
border-radius: 16px;
|
||||
|
||||
@@ -31,10 +31,11 @@
|
||||
:active="stateManager.activeNodeID.value === node.id"
|
||||
:node="node"
|
||||
:config="node.data"
|
||||
:sketchId="config.imgId"
|
||||
:data="node.data.data"
|
||||
v-bind="node.data"
|
||||
@delete-node="deleteNode(node.id)"
|
||||
@copy-node="copyNode(node.id)"
|
||||
@copy-node="copyNode($event,node.id)"
|
||||
@update-data="(v) => (node.data.data = v)"
|
||||
@bring-to-font="bringToFont(node.id)"
|
||||
@send-to-back="sendToBack(node.id)"
|
||||
@@ -157,8 +158,8 @@
|
||||
nodeManager.deleteNode(id)
|
||||
}
|
||||
/** 复制节点 */
|
||||
const copyNode = (id) => {
|
||||
nodeManager.copyNodeById(id)
|
||||
const copyNode = (clickTaskId,id) => {
|
||||
nodeManager.copyNodeById(clickTaskId,id)
|
||||
}
|
||||
/** 节点zIndex设置最大 */
|
||||
const bringToFont = (id) => {
|
||||
@@ -171,11 +172,11 @@
|
||||
// 导出流程
|
||||
const exportFlow = () => {
|
||||
// flowManager.exportFlow()
|
||||
|
||||
|
||||
const str = JSON.stringify(stateManager.nodes.value)
|
||||
const json = JSON.parse(str)
|
||||
putSketchFlowCanvas({
|
||||
id: props.config.id || '==========',
|
||||
id: props.config.imgId,
|
||||
canvasData: str
|
||||
}).then((res) => {
|
||||
if (res) {
|
||||
@@ -214,10 +215,9 @@
|
||||
// window['nodes'] = nodes
|
||||
let json = []
|
||||
await new Promise((resolve) => {
|
||||
getSketchFlowCanvas({ id: props.config.id || '==========' }).then((res) => {
|
||||
getSketchFlowCanvas({ id: props.config.imgId }).then((res:any) => {
|
||||
if (res) {
|
||||
console.log(res)
|
||||
json = res.data
|
||||
json = JSON.parse(res)
|
||||
}
|
||||
resolve(true)
|
||||
}).catch(() => {
|
||||
@@ -227,12 +227,21 @@
|
||||
if(json.length > 0){
|
||||
importFlow(json)
|
||||
}else{
|
||||
const timestamp = Date.now()
|
||||
nodeManager.createResultNode({
|
||||
data: {
|
||||
disableDelete: true,
|
||||
isHeader: false,
|
||||
data: {
|
||||
url: props.config.url
|
||||
imageProcessTasks:[
|
||||
{
|
||||
id: props.config.imgId,
|
||||
url: props.config.url,
|
||||
state:'success',
|
||||
taskId: timestamp + '',
|
||||
},
|
||||
],
|
||||
selectTaskId: timestamp + '',
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
33
src/components/Canvas/FlowCanvas/manager/GenerateManager.ts
Normal file
33
src/components/Canvas/FlowCanvas/manager/GenerateManager.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { getTaskidResult } from '@/api/flow-canvas'
|
||||
interface NodeOptions {
|
||||
id?: string
|
||||
position?: { x: number, y: number }
|
||||
positionX?: number
|
||||
positionY?: number
|
||||
component?: any
|
||||
}
|
||||
|
||||
export class GenerateManager {
|
||||
stateManager: any
|
||||
taskIds: string[] = []
|
||||
constructor(options) {
|
||||
this.stateManager = options.stateManager;
|
||||
}
|
||||
|
||||
/** 删除taskId */
|
||||
deleteTaskId(taskId: string) {
|
||||
|
||||
}
|
||||
/** 添加taskId */
|
||||
addTaskId(TaskId: any) {
|
||||
this.stateManager.addTaskId(TaskId)
|
||||
}
|
||||
/** 添加taskId */
|
||||
async getTasksIdImg(list) {
|
||||
let taskIds = list.map((item)=>item.taskId)
|
||||
getTaskidResult({taskIds}).then((rv)=>{
|
||||
console.log(rv)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ interface NodeData {
|
||||
superiorID?: string// 上级节点ID
|
||||
disableDelete?: boolean// 是否禁用删除
|
||||
disableCopy?: boolean// 是否禁用复制
|
||||
originalImage?: string// 要进行生成的图片
|
||||
}
|
||||
interface NodeOptions {
|
||||
id?: string
|
||||
@@ -113,13 +114,15 @@ export class NodeManager {
|
||||
return this.createNode(options_)
|
||||
}
|
||||
|
||||
copyNodeById(id: string) {
|
||||
copyNodeById(clickTaskId:string, id: string) {
|
||||
const node = this.stateManager.getNodeById(id)
|
||||
let copyNode = JSON.parse(JSON.stringify(node))
|
||||
copyNode.data.data.imageProcessTasks = copyNode.data.data.imageProcessTasks.filter((item:any)=>item.taskId == clickTaskId)
|
||||
const flowNode = this.stateManager.flowManager.getNodeById(id)
|
||||
if (!node) return console.warn(`${id}找不到对应节点`)
|
||||
if (node.data?.disableCopy) return console.warn(`${id}节点已禁用复制`)
|
||||
const node_ = {
|
||||
...JSON.parse(JSON.stringify(node)),
|
||||
...copyNode,
|
||||
id: createId(),
|
||||
position: {
|
||||
x: node.position.x,
|
||||
|
||||
Reference in New Issue
Block a user