UPDATE: VERSION-20260313
This commit is contained in:
@@ -79,7 +79,7 @@ export const createGraphConnectingAttributes = (): Partial<Connecting> => {
|
||||
const targetData = targetCell.getData() as ModelElement;
|
||||
|
||||
// 根节点不能作为子节点
|
||||
if (targetData.type === 'startEvent') {
|
||||
if (targetData.category === 'root') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
<a-card
|
||||
:class="[
|
||||
'ks-designer-node',
|
||||
`ks-designer-${element?.category ?? 'model'}-node`
|
||||
`ks-designer-${element?.category ?? 'model'}-node`,
|
||||
`ks-designer-group-${element?.group ?? 'general'}`
|
||||
]"
|
||||
hoverable
|
||||
>
|
||||
<template #title>
|
||||
<a-space>
|
||||
<span class="ks-designer-node-icon"></span>
|
||||
<span class="ks-designer-node-title">{{ element?.name ?? '-' }}</span>
|
||||
<!-- <span class="ks-designer-node-icon"></span>-->
|
||||
<span class="ks-designer-node-title">{{ element?.name ?? '-' }} {{element?.category}}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<div class="port port-in">
|
||||
<div class="port port-in" magnet="active">
|
||||
<div class="triangle-left" data-port="in-0" magnet="passive"></div>
|
||||
</div>
|
||||
<div class="w-full ks-designer-node-text">
|
||||
@@ -30,7 +31,7 @@
|
||||
{{ substring(element?.description ?? (element?.name ?? '-'), 40) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="port port-out">
|
||||
<div class="port port-out" magnet="active">
|
||||
<div class="triangle-right" data-port="out-0" magnet="active"></div>
|
||||
</div>
|
||||
</a-card>
|
||||
@@ -190,7 +191,7 @@ export default defineComponent({
|
||||
border-radius: 0;
|
||||
font-size: 12px;
|
||||
padding: 10px 30px !important;
|
||||
border-top: 1px solid rgba(108, 99, 255, 0.5);
|
||||
//border-top: 1px solid rgba(108, 99, 255, 0.5);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -234,39 +235,42 @@ export default defineComponent({
|
||||
.triangle-left {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 5px solid transparent;
|
||||
border-right: 10px solid #3c82f6;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-top: 4px solid transparent;
|
||||
border-right: 5px solid #5da1df;
|
||||
border-bottom: 4px solid transparent;
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 2px;
|
||||
top: 0.5px;
|
||||
magnet: passive;
|
||||
}
|
||||
|
||||
/* 右三角形 */
|
||||
.triangle-right {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 5px solid transparent;
|
||||
border-left: 10px solid #3c82f6;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-top: 4px solid transparent;
|
||||
border-left: 5px solid #5da1df;
|
||||
border-bottom: 4px solid transparent;
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: 2px;
|
||||
top: 0.5px;
|
||||
magnet: passive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 左侧入桩样式
|
||||
.port-in {
|
||||
background-color: #6C63FF;
|
||||
//background-color: #3c82f6;
|
||||
margin-right: 8px;
|
||||
//border: 1px solid #093866;
|
||||
magnet: passive;
|
||||
box-shadow: none;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
display: block;
|
||||
background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||
//background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||
border: 2px solid #5da1df;
|
||||
|
||||
position: absolute;
|
||||
//top: 7px;
|
||||
@@ -279,10 +283,12 @@ export default defineComponent({
|
||||
margin-right: 5px;
|
||||
magnet: active;
|
||||
box-shadow: none;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
display: block;
|
||||
background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||
//background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||
border: 2px solid #5da1df;
|
||||
background:#5da1df;
|
||||
|
||||
position: absolute;
|
||||
//right: 8px;
|
||||
@@ -302,9 +308,6 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
&.ks-designer-root-node{
|
||||
.ant-card-head {
|
||||
background: url('@/assets/icons/card-head-gray.png') center / 100% 100%;
|
||||
}
|
||||
.ks-designer-node-icon {
|
||||
background: url('@/assets/icons/icon-root.svg') center / 100% 100%;
|
||||
}
|
||||
@@ -320,32 +323,66 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
&.ks-designer-sequence-node{
|
||||
.ant-card-head {
|
||||
background: url('@/assets/icons/card-head-green.png') center / 100% 100%;
|
||||
}
|
||||
.ks-designer-node-icon {
|
||||
background: url('@/assets/icons/icon-sequence.svg') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.ks-designer-parallel-node{
|
||||
.ant-card-head {
|
||||
background: url('@/assets/icons/card-head-blue.png') center / 100% 100%;
|
||||
}
|
||||
.ks-designer-node-icon {
|
||||
background: url('@/assets/icons/icon-parallel.svg') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.ks-designer-precondition-node{
|
||||
.ant-card-head {
|
||||
background: url('@/assets/icons/card-head-dark.png') center / 100% 100%;
|
||||
}
|
||||
.ks-designer-node-icon {
|
||||
background: url('@/assets/icons/icon-branch.svg') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.ks-designer-group-control,
|
||||
&.ks-designer-group-condition {
|
||||
.ant-card-head{
|
||||
display:none;
|
||||
}
|
||||
.ant-card-body {
|
||||
height: calc(100%);
|
||||
border-radius: 8px;
|
||||
background: url('@/assets/icons/card-head-gray.png') center / 100% 100%;
|
||||
}
|
||||
|
||||
&.ks-designer-root-node{
|
||||
.ant-card-body {
|
||||
background: url('@/assets/icons/card-head-dark.png') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
&.ks-designer-sequence-node{
|
||||
.ant-card-body {
|
||||
background: url('@/assets/icons/card-head-green.png') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.ks-designer-parallel-node{
|
||||
.ant-card-body {
|
||||
background: url('@/assets/icons/card-head-blue.png') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.ks-designer-precondition-node{
|
||||
.ant-card-body {
|
||||
background: url('@/assets/icons/card-head-dark.png') center / 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.port-in,
|
||||
.port-out {
|
||||
top: 40%;
|
||||
}
|
||||
.ks-designer-node-text{
|
||||
line-height: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
//&.ks-designer-precondition-node{
|
||||
// border:0;
|
||||
// box-shadown:none;
|
||||
|
||||
@@ -18,10 +18,9 @@ export const createGraphTaskElement = (element: GraphTaskElement, width: number
|
||||
if (!realHeight) {
|
||||
realHeight = 120;
|
||||
}
|
||||
// if(element.category === 'precondition') {
|
||||
// width = 100;
|
||||
// realHeight = 100;
|
||||
// }
|
||||
if(element.group === 'condition' || element.group === 'control') {
|
||||
realHeight = 60;
|
||||
}
|
||||
return {
|
||||
shape: 'task',
|
||||
id: element.key,
|
||||
|
||||
@@ -74,7 +74,7 @@ import { Wrapper } from '@/components/wrapper';
|
||||
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
||||
import Header from './header.vue';
|
||||
import Properties from './properties.vue';
|
||||
import type { BehaviorTree, NodeTemplate } from './types';
|
||||
import type { BehaviorTree, NodeDragTemplate, NodeTemplate } from './types';
|
||||
import type { GraphTaskElement, NodeGraph } from './builder/element';
|
||||
import { useGraphCanvas } from './builder/hooks';
|
||||
import { registerNodeElement } from './builder/register';
|
||||
@@ -106,7 +106,7 @@ export default defineComponent({
|
||||
const canvas = ref<HTMLDivElement | null>(null);
|
||||
const graph = ref<Graph | null>(null);
|
||||
const currentZoom = ref<number>(1);
|
||||
const draggedNodeData = ref<NodeTemplate | null>(null);
|
||||
const draggedNodeData = ref<NodeDragTemplate | null>(null);
|
||||
const isDraggingOver = ref(false);
|
||||
const currentTreeEditing = ref<boolean>(false);
|
||||
const currentBehaviorTree = ref<BehaviorTree | null>(null);
|
||||
@@ -127,7 +127,7 @@ export default defineComponent({
|
||||
} = useGraphCanvas();
|
||||
|
||||
// 处理拖动开始
|
||||
const handleDragStart = (nm: NodeTemplate) => {
|
||||
const handleDragStart = (nm: NodeDragTemplate) => {
|
||||
draggedNodeData.value = nm;
|
||||
};
|
||||
|
||||
@@ -178,7 +178,7 @@ export default defineComponent({
|
||||
|
||||
try {
|
||||
// 获取拖动的数据
|
||||
const template = draggedNodeData.value as NodeTemplate;
|
||||
const template = draggedNodeData.value as NodeDragTemplate;
|
||||
|
||||
if (!hasElements(graph.value as Graph) && template.type !== 'root') {
|
||||
message.error('请先添加根节点.');
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
:data-type="nm.type"
|
||||
class="ks-model-drag-item"
|
||||
@dragend="handleDragEnd"
|
||||
@dragstart="handleDragStart($event, nm)"
|
||||
@dragstart="handleDragStart($event, nm, 'control')"
|
||||
>
|
||||
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||
<span class="desc">{{ nm.name }}</span>
|
||||
@@ -34,7 +34,7 @@
|
||||
:data-type="nm.type"
|
||||
class="ks-model-drag-item"
|
||||
@dragend="handleDragEnd"
|
||||
@dragstart="handleDragStart($event, nm)"
|
||||
@dragstart="handleDragStart($event, nm, 'condition')"
|
||||
>
|
||||
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||
<span class="desc">{{ nm.name }}</span>
|
||||
@@ -55,7 +55,7 @@
|
||||
:data-type="nm.type"
|
||||
class="ks-model-drag-item"
|
||||
@dragend="handleDragEnd"
|
||||
@dragstart="handleDragStart($event, nm)"
|
||||
@dragstart="handleDragStart($event, nm, 'action')"
|
||||
>
|
||||
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||
<span class="desc">{{ nm.name }}</span>
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, ref } from 'vue';
|
||||
import type { NodeTemplate } from './types';
|
||||
import type { NodeDragTemplate, NodeTemplate } from './types';
|
||||
import { findNodeTemplates } from './api';
|
||||
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
||||
|
||||
@@ -82,7 +82,7 @@ export default defineComponent({
|
||||
const activeKey = ref<number>(1);
|
||||
const templateData = ref<NodeTemplate[]>([]);
|
||||
const isDraggingOver = ref<boolean>(false);
|
||||
const draggedNodeData = ref<NodeTemplate | null>(null);
|
||||
const draggedNodeData = ref<NodeDragTemplate | null>(null);
|
||||
// 控制节点
|
||||
const controlTemplates = ref<NodeTemplate[]>([]);
|
||||
// 条件节点
|
||||
@@ -111,15 +111,16 @@ export default defineComponent({
|
||||
});
|
||||
};
|
||||
|
||||
const handleDragStart = (e: DragEvent, nm: NodeTemplate) => {
|
||||
draggedNodeData.value = nm;
|
||||
const handleDragStart = (e: DragEvent, nm: NodeTemplate, group: String) => {
|
||||
let dragNode: NodeDragTemplate = { ...nm, group: group };
|
||||
draggedNodeData.value = dragNode as NodeDragTemplate;
|
||||
|
||||
if (e.dataTransfer) {
|
||||
e.dataTransfer.setData('text/plain', JSON.stringify(draggedNodeData.value));
|
||||
e.dataTransfer.effectAllowed = 'copyMove';
|
||||
|
||||
const dragPreview = document.createElement('div');
|
||||
dragPreview.textContent = draggedNodeData.value.name || '';
|
||||
dragPreview.textContent = dragNode.name || '';
|
||||
dragPreview.style.cssText = `
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
@@ -132,8 +133,8 @@ export default defineComponent({
|
||||
`;
|
||||
document.body.appendChild(dragPreview);
|
||||
e.dataTransfer.setDragImage(dragPreview, dragPreview.offsetWidth / 2, dragPreview.offsetHeight / 2);
|
||||
emit('drag-item-start', nm, isDraggingOver.value, e);
|
||||
console.log('开始拖动:', nm);
|
||||
emit('drag-item-start', dragNode, group, isDraggingOver.value, e);
|
||||
console.log('开始拖动:', dragNode);
|
||||
setTimeout(() => document.body.removeChild(dragPreview), 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,6 +21,10 @@ export interface NodeTemplate {
|
||||
parameters: ElementParameter[],
|
||||
}
|
||||
|
||||
export interface NodeDragTemplate extends NodeTemplate {
|
||||
group: String
|
||||
}
|
||||
|
||||
export interface NodeTemplatesResponse extends ApiDataResponse<NodeTemplate[]> {
|
||||
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
import type { NodeTemplate } from '../types';
|
||||
import type { NodeDragTemplate } from '../types';
|
||||
import type { GraphTaskElement, GraphTaskRect } from '../builder/element';
|
||||
import { generateKey } from '@/utils/strings';
|
||||
|
||||
export const createGraphTaskElementFromTemplate = (
|
||||
template: NodeTemplate,
|
||||
template: NodeDragTemplate,
|
||||
rect?: GraphTaskRect,
|
||||
): GraphTaskElement => {
|
||||
let realRect = { width: 120, height: 80, x: 0, y: 0, ...rect || {} };
|
||||
@@ -25,6 +25,7 @@ export const createGraphTaskElementFromTemplate = (
|
||||
templateType: template.templateType,
|
||||
name: template.name,
|
||||
category: template.type,
|
||||
group: template.group,
|
||||
description: template.description,
|
||||
order: 0,
|
||||
position: {
|
||||
|
||||
Reference in New Issue
Block a user