Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/FiDA_Front
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import flowCanvas from './FlowCanvas/flow-canvas.vue'
|
||||
import card from './FlowCanvas/components/cards/index.vue'
|
||||
import card from './FlowCanvas/components/nodes/cards/index.vue'
|
||||
import { computed, ref, markRaw, onMounted, reactive, nextTick } from 'vue'
|
||||
const data = reactive({
|
||||
x: 100,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:position="handle.position"
|
||||
:connectable="false"
|
||||
/>
|
||||
<div class="item">
|
||||
<div class="item" @mousedown="(e) => stateManager.setActiveNodeID(node.id)">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="add" @mousedown.stop v-if="isAdd" @click="onAdd">
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
|
||||
<style lang="less" scoped>
|
||||
.card {
|
||||
width: 250px;
|
||||
width: 244px;
|
||||
height: auto;
|
||||
--border-radius: 16px;
|
||||
border-radius: var(--border-radius);
|
||||
@@ -164,6 +164,9 @@
|
||||
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&.active {
|
||||
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05), 0 0 0 2px #fae5d8;
|
||||
}
|
||||
> .header {
|
||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
||||
height: 50px;
|
||||
@@ -173,7 +176,7 @@
|
||||
padding: 0 16px;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
> .delete-icon{
|
||||
> .delete-icon {
|
||||
margin-left: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
<template>
|
||||
<!-- 结果图片 -->
|
||||
<div
|
||||
class="text"
|
||||
:class="{ edit }"
|
||||
@click="onClick"
|
||||
@mousedown="onMouseDown"
|
||||
@dblclick="onDoubleClick"
|
||||
>
|
||||
<div class="text" @mousedown="onMouseDown">
|
||||
<div
|
||||
tabindex="0"
|
||||
class="input"
|
||||
ref="inputRef"
|
||||
:contenteditable="edit"
|
||||
:contenteditable="active"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@paste.prevent
|
||||
@@ -20,8 +14,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, nextTick } from 'vue'
|
||||
import { reactive, ref, onMounted, nextTick, watch } from 'vue'
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
@@ -31,7 +29,6 @@
|
||||
const data = reactive({
|
||||
text: props.data?.text || '点击编辑文本'
|
||||
})
|
||||
const edit = ref(false)
|
||||
const time = ref(null)
|
||||
const inputRef = ref<any>()
|
||||
const onInput = () => {
|
||||
@@ -39,27 +36,26 @@
|
||||
data.text = text
|
||||
emit('update-data', data)
|
||||
}
|
||||
const onBlur = () => {
|
||||
edit.value = false
|
||||
}
|
||||
const onClick = () => {
|
||||
if (edit.value) return
|
||||
edit.value = true
|
||||
nextTick(() => {
|
||||
// 光标定位到文本末尾
|
||||
const range = document.createRange()
|
||||
const selection = window.getSelection()
|
||||
range.selectNodeContents(inputRef.value)
|
||||
range.collapse(false)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
})
|
||||
}
|
||||
const onDoubleClick = () => {
|
||||
clearTimeout(time.value)
|
||||
}
|
||||
// watch(
|
||||
// () => props.active,
|
||||
// (newVal) => {
|
||||
// if (!newVal) return
|
||||
// nextTick(() => {
|
||||
// // 光标定位到文本末尾
|
||||
// const range = document.createRange()
|
||||
// const selection = window.getSelection()
|
||||
// range.selectNodeContents(inputRef.value)
|
||||
// range.collapse(false)
|
||||
// selection.removeAllRanges()
|
||||
// selection.addRange(range)
|
||||
// })
|
||||
// }
|
||||
// )
|
||||
const onMouseDown = (e: MouseEvent) => {
|
||||
if (edit.value) e.stopPropagation()
|
||||
if (props.active) e.stopPropagation()
|
||||
}
|
||||
const onBlur = () => {
|
||||
// emit('update-data', data)
|
||||
}
|
||||
onMounted(() => {
|
||||
inputRef.value.innerHTML = data.text
|
||||
@@ -73,7 +69,7 @@
|
||||
user-select: none;
|
||||
border: 1px solid transparent;
|
||||
padding: 2px;
|
||||
&.edit {
|
||||
&.active {
|
||||
border-color: #000;
|
||||
> .input {
|
||||
cursor: text;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
>
|
||||
<component
|
||||
:is="components[node.data.component]"
|
||||
:class="{ active: stateManager.activeNodeID.value === node.id }"
|
||||
:active="stateManager.activeNodeID.value === node.id"
|
||||
:node="node"
|
||||
:config="node.data"
|
||||
:data="node.data.data"
|
||||
@@ -127,7 +129,11 @@
|
||||
stateManager.nodes.value = layout(
|
||||
stateManager.nodes.value,
|
||||
stateManager.edges.value,
|
||||
direction
|
||||
direction,
|
||||
{
|
||||
nodesep: nodeManager.nodesep,
|
||||
ranksep: nodeManager.ranksep
|
||||
}
|
||||
)
|
||||
nextTick(() => {
|
||||
fitView({ maxZoom: 1 })
|
||||
@@ -187,6 +193,15 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
nodeManager.createResultNode({
|
||||
data: {
|
||||
disableDelete: true,
|
||||
isHeader: false,
|
||||
data: {
|
||||
url: props.config.url
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
||||
@@ -26,6 +26,7 @@ export class EventManager {
|
||||
}
|
||||
/** 处理点击 */
|
||||
handleClick(event: any) {
|
||||
this.stateManager.setActiveNodeID("")
|
||||
const tool = this.stateManager.tool.value
|
||||
if (tool === TOOLS.TEXT) {
|
||||
const { x, y, zoom } = this.vueFlow.value.viewport
|
||||
|
||||
@@ -12,6 +12,8 @@ interface NodeOptions {
|
||||
export class NodeManager {
|
||||
stateManager: any
|
||||
vueFlow: any
|
||||
nodesep = 100 // 节点间距
|
||||
ranksep = 100 // 层级间距
|
||||
constructor(options) {
|
||||
this.stateManager = options.stateManager;
|
||||
this.vueFlow = options.vueFlow
|
||||
@@ -37,7 +39,7 @@ export class NodeManager {
|
||||
(!snode ?
|
||||
{ x: positionX, y: positionY } :
|
||||
{
|
||||
x: snode.position.x + snode.dimensions.width + 50 + positionX,
|
||||
x: snode.position.x + snode.dimensions.width + this.nodesep + positionX,
|
||||
y: snode.position.y + positionY
|
||||
})
|
||||
const data = options?.data || {}
|
||||
@@ -100,18 +102,18 @@ export class NodeManager {
|
||||
}
|
||||
return this.createNode(options_)
|
||||
}
|
||||
|
||||
|
||||
copyNodeById(id: string) {
|
||||
const node = this.stateManager.getNodeById(id)
|
||||
const flowNode = this.stateManager.flowManager.getNodeById(id)
|
||||
console.log(node,this.stateManager.flowManager.getNodeById(id))
|
||||
console.log(node, this.stateManager.flowManager.getNodeById(id))
|
||||
if (!node) return console.warn(`copyNodeById: ${id}找不到对应节点`)
|
||||
const node_ = {
|
||||
...JSON.parse(JSON.stringify(node)),
|
||||
id: createId(),
|
||||
position: {
|
||||
x: node.position.x,
|
||||
y: node.position.y + (flowNode?.dimensions?.height || 0) + 50,
|
||||
y: node.position.y + (flowNode?.dimensions?.height || 0) + this.ranksep,
|
||||
}
|
||||
}
|
||||
delete node_.data?.superiorID
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface NodesItem {
|
||||
}
|
||||
export class StateManager {
|
||||
vueFlow: any
|
||||
activeNodeID: any
|
||||
nodes: any
|
||||
nodes_: any
|
||||
edges: any
|
||||
@@ -49,6 +50,7 @@ export class StateManager {
|
||||
this.historyList = ref([])
|
||||
this.historyIndex = ref(0)
|
||||
|
||||
this.activeNodeID = ref("")
|
||||
this.nodes = ref<NodesItem[]>([]);
|
||||
this.nodes_ = computed(() => {
|
||||
return this.nodes.value.map((node, index) => {
|
||||
@@ -90,6 +92,8 @@ export class StateManager {
|
||||
})
|
||||
|
||||
}
|
||||
/** 设置激活节点 */
|
||||
setActiveNodeID(id: string) { this.activeNodeID.value = id }
|
||||
/** 添加节点 */
|
||||
addNode(node: NodesItem) {
|
||||
this.nodes.value.push(node);
|
||||
|
||||
Reference in New Issue
Block a user