删除卡片会删除卡片链路所有生成节点,版本树新增点击遮罩关闭版本树

This commit is contained in:
X1627315083@163.com
2026-03-24 13:58:36 +08:00
parent f8f760119c
commit d8d9f09bf4
12 changed files with 85 additions and 55 deletions

View File

@@ -70,13 +70,13 @@
const id = props.node.id const id = props.node.id
if (!id) return if (!id) return
const superiorID = props.node.data.superiorID const superiorID = props.node.data.superiorID
stateManager.deleteNode(id)
if(v.secondaryMenu){ if(v.secondaryMenu){
nodeManager.createCardsSelect({ nodeManager.createCardsSelect({
data: { data: {
tier: props.node.data?.tier, tier: props.node.data?.tier,
superiorID, superiorID,
isActive: props.node.data?.isActive, isActive: props.node.data?.isActive,
originalImage: props.node.data?.originalImage,
secondaryMenu: v.secondaryMenu, secondaryMenu: v.secondaryMenu,
createIndexPosition: props.node.data.createIndexPosition, createIndexPosition: props.node.data.createIndexPosition,
} }
@@ -89,11 +89,9 @@
superiorID, superiorID,
isActive: props.node.data?.isActive, isActive: props.node.data?.isActive,
createIndexPosition: props.node.data.createIndexPosition, createIndexPosition: props.node.data.createIndexPosition,
originalImage: props.node.data?.originalImage,
} }
}) })
} }
stateManager.deleteNode(id)
} }
defineExpose({}) defineExpose({})

View File

@@ -9,24 +9,26 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, inject, useAttrs } from 'vue' import { reactive, inject, useAttrs, computed } from 'vue'
import myEvent from '@/utils/myEvent' import myEvent from '@/utils/myEvent'
import { getCurrentTime } from '../../../../tools/tools.ts' import { getCurrentTime } from '../../../../tools/tools.ts'
import { NODE_DATATIER } from '../../../tools/index.d' import { NODE_DATATIER } from '../../../tools/index.d'
const attrs = useAttrs() const attrs = useAttrs()
const data = reactive({
url: attrs.node?.data?.originalImage,
})
const stateManager = inject('stateManager') as any const stateManager = inject('stateManager') as any
const nodeManager = inject('nodeManager') as any const nodeManager = inject('nodeManager') as any
const eventManager = inject('eventManager') as any const eventManager = inject('eventManager') as any
const data = reactive({
url: computed(()=>stateManager.getSuperiorNodeImage(attrs.node?.data?.superiorID)),
})
const getApiData = ()=>{ const getApiData = ()=>{
return { return {
} }
} }
const opCanvas = ()=>{ const opCanvas = ()=>{
const superiorNodeUrl = stateManager.getSuperiorNodeImage(attrs?.node?.data?.superiorID || null)
if (!superiorNodeUrl) console.log('superiorNodeUrl 找不到原始图片')
const data = { const data = {
url:attrs?.node?.data?.originalImage, url:superiorNodeUrl,
canvasId: attrs?.node?.data?.canvasId || null, canvasId: attrs?.node?.data?.canvasId || null,
sketchId: stateManager.sketchId.value, sketchId: stateManager.sketchId.value,
onWorkbench:(options)=>{ onWorkbench:(options)=>{

View File

@@ -42,12 +42,15 @@
import ColorPalette from './color-palette.vue' import ColorPalette from './color-palette.vue'
import To3View from './to-3view.vue' import To3View from './to-3view.vue'
import To3DModel from './to-3d-model.vue' import To3DModel from './to-3d-model.vue'
import { useI18n } from 'vue-i18n'
import { ElMessageBox } from 'element-plus'
import { toRealStyleApi, toColorPaletteApi, toSceneCompositionApi, sketchAddPrintApi, sketchToThreeApi, threeToThreeViewsApi } from '@/api/flow-canvas' import { toRealStyleApi, toColorPaletteApi, toSceneCompositionApi, sketchAddPrintApi, sketchToThreeApi, threeToThreeViewsApi } from '@/api/flow-canvas'
// import ToVideo from './to-video.vue' // import ToVideo from './to-video.vue'
// import AddPrint from './add-print.vue' // import AddPrint from './add-print.vue'
// import ToCAD from './to-cad.vue' // import ToCAD from './to-cad.vue'
const { t } = useI18n()
const attrs = useAttrs() const attrs = useAttrs()
const componentRef = ref(null) const componentRef = ref(null)
const components = [ const components = [
@@ -144,12 +147,12 @@
const onGenerateClick = async () => { const onGenerateClick = async () => {
const data = componentRef.value?.getApiData?.() || {} const data = componentRef.value?.getApiData?.() || {}
const subordNodes = stateManager.getSubordNodes(attrs.node.id) const subordNodes = stateManager.getSubordNodes(attrs.node.id)
const superiorNodeUrl = stateManager.getSuperiorNodeImage(attrs.node.data.superiorID)
if(!superiorNodeUrl)return console.log('superiorNodeUrl 找不到原始图片')
emit('update-data', componentRef.value?.data) emit('update-data', componentRef.value?.data)
if(!attrs.node?.data?.originalImage)console.log('originalImage 找不到原始图片')
const apiData = { const apiData = {
sketchId: props.sketchId, sketchId: props.sketchId,
imageUrl: attrs.node?.data?.originalImage, imageUrl: superiorNodeUrl,
...data, ...data,
} }
const taskList = await currentComponent.value.api(apiData).then((rv)=>{ const taskList = await currentComponent.value.api(apiData).then((rv)=>{
@@ -177,8 +180,9 @@
}) })
} }
//删除功能卡片 //删除功能卡片
const onDeleteClick = ()=>{ const onDeleteClick = async ()=>{
stateManager.deleteNode(attrs.node.id,{isElMessageBox:true}) console.log(stateManager.nodes)
stateManager.getSubordinateAllNodes(attrs.node.id,{ isElMessageBox: true })
} }
const setDate = () => { const setDate = () => {
for (const key in props.data) { for (const key in props.data) {

View File

@@ -9,12 +9,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted, useAttrs } from 'vue' import { reactive, inject, useAttrs, computed } from 'vue'
import uploadFile from '../../tools/upload-file.vue' import uploadFile from '../../tools/upload-file.vue'
const attrs = useAttrs() const attrs = useAttrs()
const stateManager = inject('stateManager') as any
const data = reactive({ const data = reactive({
url: attrs.node?.data?.originalImage, url: computed(()=>stateManager.getSuperiorNodeImage(attrs.node?.data?.superiorID)),
}) })
const getApiData = ()=>{ const getApiData = ()=>{
return { return {

View File

@@ -13,7 +13,7 @@
const attrs = useAttrs() const attrs = useAttrs()
const stateManager = inject('stateManager') as any const stateManager = inject('stateManager') as any
const data = reactive({ const data = reactive({
url: attrs.node.data.originalImage, url: computed(()=>stateManager.getSuperiorNodeImage(attrs.node?.data?.superiorID)),
}) })
const getApiData = ()=>{ const getApiData = ()=>{
let glbUrl = null let glbUrl = null

View File

@@ -253,18 +253,11 @@
) )
const onAdd = () => { const onAdd = () => {
const tier_ = tier.value + 1 const tier_ = tier.value + 1
// 从data中获取originalImage
let nodeData = props.node?.data?.data.imageProcessTasks.filter(
(v) => v.taskId === props.node?.data?.data.selectTaskId
)
const subordNodes = stateManager.getSubordNodes(props.node.id) const subordNodes = stateManager.getSubordNodes(props.node.id)
const originalImage = nodeData[0]?.url
if (!originalImage) console.log('originalImage 找不到原始图片')
stateManager.nodeManager.createCardsSelect({ stateManager.nodeManager.createCardsSelect({
data: { data: {
tier: tier_, tier: tier_,
superiorID: props.node.id, superiorID: props.node.id,
originalImage,
createIndexPosition: subordNodes.length + 1, createIndexPosition: subordNodes.length + 1,
isActive: subordNodes.length == 0 isActive: subordNodes.length == 0
} }

View File

@@ -94,7 +94,7 @@ export class EventManager {
handleDelete(event: any, activeNodeID: string) { handleDelete(event: any, activeNodeID: string) {
event.preventDefault() event.preventDefault()
if (!activeNodeID) return console.warn('没有选中节点') if (!activeNodeID) return console.warn('没有选中节点')
this.stateManager.deleteNode(activeNodeID, { isElMessageBox: true }) this.stateManager.getSubordinateAllNodes(activeNodeID, { isElMessageBox: true })
} }
/** 处理键盘事件 */ /** 处理键盘事件 */
_handleKeyDown: any _handleKeyDown: any

View File

@@ -10,7 +10,6 @@ interface NodeData {
superiorNodeType?: string// 上级节点类型 superiorNodeType?: string// 上级节点类型
disableDelete?: boolean// 是否禁用删除 disableDelete?: boolean// 是否禁用删除
disableCopy?: boolean// 是否禁用复制 disableCopy?: boolean// 是否禁用复制
originalImage?: string// 要进行生成的图片
createIndexPosition?: number// 创建索引位置 createIndexPosition?: number// 创建索引位置
isActive?: boolean// 是否激活 isActive?: boolean// 是否激活
} }
@@ -35,7 +34,7 @@ export class NodeManager {
/** 删除节点 */ /** 删除节点 */
deleteNode(id: string) { deleteNode(id: string) {
this.stateManager.deleteNode(id) this.stateManager.getSubordinateAllNodes(id, { isElMessageBox: true })
} }
/** 添加节点 */ /** 添加节点 */
addNode(node: any) { addNode(node: any) {

View File

@@ -119,37 +119,69 @@ export class StateManager {
this.exportFlow() this.exportFlow()
} }
/** 删除节点 */ /** 删除节点 */
async deleteNode(id: string, { isElMessageBox } = { isElMessageBox: false }) { async deleteNode(id: string) {
const node = this.getNodeById(id)
if (!node) return console.warn(`没有找到指定id:${id}`)
if (node.data.disableDelete) return console.warn('该节点禁用删除')
let deletePromise: any = true
if (isElMessageBox) {
deletePromise = await new Promise<void>((resolve, reject) => {
ElMessageBox.confirm(
t('flowCanvas.deleteCardConfirm'),
'',
{
confirmButtonText: t('flowCanvas.confirm'),
cancelButtonText: t('flowCanvas.cancel'),
}
).then(() => {
resolve(true)
}).catch(() => {
resolve(false)
})
})
}
if (!deletePromise) return console.log('删除操作被取消')
this.nodes.value = this.nodes.value.filter((node: NodesItem) => node.id !== id) this.nodes.value = this.nodes.value.filter((node: NodesItem) => node.id !== id)
this.recordState()
this.exportFlow()
} }
/** 获取节点 */ /** 获取节点 */
getNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.id === id) } getNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.id === id) }
/** 获取下级节点 */ /** 获取下级节点 */
getSubordNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.data.superiorID === id) } getSubordNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.data.superiorID === id) }
getLastNode() { console.log(this.nodes.value); return this.nodes.value[this.nodes.value.length - 1] } getLastNode() { console.log(this.nodes.value); return this.nodes.value[this.nodes.value.length - 1] }
/** 获取上级生成节点的图片 */
getSuperiorNodeImage(superiorID: string) {
const superiorNode = this.getNodeById(superiorID)
if(!superiorNode){
ElMessage.error(t('flowCanvas.cannotFindSuperiorImage'))
return null
}
const superiorNodeUrl = superiorNode.data.data.imageProcessTasks.filter((item)=>{
return item.taskId == superiorNode.data.data.selectTaskId
})[0]?.url
return superiorNodeUrl
}
/** 获取下级所有子级节点 */
async getSubordinateAllNodes(id: string,{ isElMessageBox } = { isElMessageBox: false }) {
const node = this.getNodeById(id)
if (!node) return console.warn(`没有找到指定id:${id}`)
if (node.data.disableDelete) return ElMessage.error(t('flowCanvas.initialNodeProhibited'))
const result = [node]
const findChildren = (parentId: string) => {
const children = this.nodes.value.filter(item => item.data.superiorID === parentId)
children.forEach(child => {
if(child.data.type !== NODE_DATATYPE.RESULT_IMAGE){
result.push(child)
}
findChildren(child.id)
})
}
let deletePromise: any = true
if (isElMessageBox && result.length > 1) {
deletePromise = await new Promise<void>((resolve, reject) => {
ElMessageBox.confirm(
t('flowCanvas.deleteSubordinateCard'),
'',
{
confirmButtonText: t('flowCanvas.confirm'),
cancelButtonText: t('flowCanvas.cancel'),
}
).then(() => {resolve(true)
}).catch(() => {
resolve(false)
})
})
}
if(!deletePromise) return console.log('删除操作被取消')
this.deleteNode(id)
result.forEach(item => {
this.deleteNode(item.id)
})
this.recordState()
this.exportFlow()
}
/** 设置工具 */ /** 设置工具 */
setTool(tool: string) { this.tool.value = tool } setTool(tool: string) { this.tool.value = tool }
/** 设置光标 */ /** 设置光标 */

View File

@@ -178,10 +178,12 @@ export default {
export: 'Export', export: 'Export',
}, },
flowCanvas: { flowCanvas: {
deleteCardConfirm: 'Are you sure you want to delete this function card?',
confirm: 'Confirm', confirm: 'Confirm',
cancel: 'Cancel', cancel: 'Cancel',
confirmLeave: 'Are you sure you want to leave? You may have unsaved changes.', confirmLeave: 'Are you sure you want to leave? You may have unsaved changes.',
cannotFindSuperiorImage: 'Cannot find the superior image',
deleteSubordinateCard: 'After deletion, all the function cards will also be deleted.',
initialNodeProhibited: 'Initial node is prohibited from being deleted.',
}, },
assistant: { assistant: {
inputPlaceholder: 'Ask anything', inputPlaceholder: 'Ask anything',

View File

@@ -179,10 +179,11 @@ export default {
edit: '编辑' edit: '编辑'
}, },
flowCanvas: { flowCanvas: {
deleteCardConfirm: '确定要删除该功能卡片吗?',
confirm: '确认', confirm: '确认',
cancel: '取消', cancel: '取消',
confirmLeave: '您可能有未保存的更改,确定要离开吗?', confirmLeave: '您可能有未保存的更改,确定要离开吗?',
cannotFindSuperiorImage: '找不到上级图片',
initialNodeProhibited: 'Initial node is prohibited from being deleted.',
}, },
assistant: { assistant: {
inputPlaceholder: '请输入' inputPlaceholder: '请输入'

View File

@@ -125,7 +125,6 @@ const {} = toRefs(data)
<el-drawer <el-drawer
v-model="versionTreeData.drawer" v-model="versionTreeData.drawer"
:close-on-press-escape="false" :close-on-press-escape="false"
:close-on-click-modal="false"
:size="treeState ? '73.5rem' : '73.5rem'" :size="treeState ? '73.5rem' : '73.5rem'"
body-class="versionTreeBody" body-class="versionTreeBody"
:with-header="false" :with-header="false"