Initial commit
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 MiB After Width: | Height: | Size: 418 KiB |
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { HttpRequestClient } from '@/utils/request';
|
import { HttpRequestClient } from '@/utils/request';
|
||||||
import type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, NodeTemplatesResponse, TreeModelDetailsResponse, TreeModelGraph } from './types';
|
import type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, NodeTemplatesResponse } from './types';
|
||||||
import type { BasicResponse } from '@/types';
|
import type { BasicResponse } from '@/types';
|
||||||
|
|
||||||
const req = HttpRequestClient.create<BasicResponse>({
|
const req = HttpRequestClient.create<BasicResponse>({
|
||||||
@@ -23,17 +23,17 @@ export const findTreesByQuery = (query: Partial<BehaviorTree> = {}): Promise<Beh
|
|||||||
return req.get<BehaviorTreePageResponse>('/system/behaviortree/list', query);
|
return req.get<BehaviorTreePageResponse>('/system/behaviortree/list', query);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const findOneTreeById = (id: number): Promise<BehaviorTreeDetailsResponse> => {
|
export const findOneTreeById = (id: number): Promise<BehaviorTreeDetailsResponse> => {
|
||||||
return req.get(`/system/behaviortree/${id}`);
|
return req.get(`/system/behaviortree/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateTree = (rt: Partial<TreeModelGraph>): Promise<BasicResponse> => {
|
|
||||||
return req.postJson('/behavior-trees', rt);
|
export const updateTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
||||||
|
return req.postJson('/system/behaviortree/${id}', rt);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createTree = (rt: Partial<TreeModelGraph>): Promise<BasicResponse> => {
|
export const createTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
||||||
return req.putJson('/behavior-trees', rt);
|
return req.putJson('/system/behaviortree/${id}', rt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the kernelstudio package.
|
|
||||||
*
|
|
||||||
* (c) 2014-2026 zlin <admin@kernelstudio.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE file
|
|
||||||
* that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { TreeModelsData, NodeTemplateQuery, NodeTemplateData } from './types';
|
|
||||||
import type { ApiPagination, ApiPaginationQuery } from '@/types';
|
|
||||||
|
|
||||||
export const defaultPagination = {
|
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
|
||||||
total: 0,
|
|
||||||
total_pages: 0,
|
|
||||||
} as ApiPagination;
|
|
||||||
|
|
||||||
export const defaultTreeModelsData = {
|
|
||||||
trees: [],
|
|
||||||
pagination: { ...defaultPagination },
|
|
||||||
} as TreeModelsData;
|
|
||||||
|
|
||||||
export const defaultPaginationRequest = {
|
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
|
||||||
keyword: null,
|
|
||||||
} as ApiPaginationQuery
|
|
||||||
|
|
||||||
export const defaultNodeTemplateQuery = {
|
|
||||||
page: 1,
|
|
||||||
limit: 1000,
|
|
||||||
keyword: null,
|
|
||||||
include_params: true,
|
|
||||||
} as NodeTemplateQuery
|
|
||||||
|
|
||||||
export const defaultNodeTemplateData = {
|
|
||||||
templates: [],
|
|
||||||
total: 0
|
|
||||||
} as NodeTemplateData
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="ks-model-builder-content">
|
<div class="ks-model-builder-content">
|
||||||
<div class="ks-model-builder-actions">
|
<div class="ks-model-builder-actions">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-tooltip v-if="graph && currentNodeGraph" placement="top">
|
<a-tooltip v-if="graph && currentBehaviorTree" placement="top">
|
||||||
<template #title>
|
<template #title>
|
||||||
保存
|
保存
|
||||||
</template>
|
</template>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { getTeleport } from '@antv/x6-vue-shape';
|
import { getTeleport } from '@antv/x6-vue-shape';
|
||||||
import { Graph, Node,Edge, type NodeProperties } from '@antv/x6';
|
import { Graph, Node, type NodeProperties } from '@antv/x6';
|
||||||
import { CheckCircleOutlined, CheckOutlined, RollbackOutlined, SaveOutlined } from '@ant-design/icons-vue';
|
import { CheckCircleOutlined, CheckOutlined, RollbackOutlined, SaveOutlined } from '@ant-design/icons-vue';
|
||||||
import { Wrapper } from '@/components/wrapper';
|
import { Wrapper } from '@/components/wrapper';
|
||||||
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
||||||
@@ -68,7 +68,7 @@ import Header from './header.vue';
|
|||||||
import Properties from './properties.vue';
|
import Properties from './properties.vue';
|
||||||
import { useGraphCanvas } from './builder/hooks';
|
import { useGraphCanvas } from './builder/hooks';
|
||||||
import { registerNodeElement } from './builder/register';
|
import { registerNodeElement } from './builder/register';
|
||||||
import type { BehaviorTree, NodeGraph, NodeTemplate, SettingTaskNodeElement, TreeModel, TreeModelGraph } from './types';
|
import type { BehaviorTree, EdgeNodeElement, NodeGraph, NodeTemplate, SettingTaskNodeElement } from './types';
|
||||||
import { createTree, findOneTreeById, updateTree } from './api';
|
import { createTree, findOneTreeById, updateTree } from './api';
|
||||||
import { createTaskNodeElement, createTaskNodeElementFromTemplate, hasElements, hasRootElementNode, resolveNodeGraph } from './utils/node';
|
import { createTaskNodeElement, createTaskNodeElementFromTemplate, hasElements, hasRootElementNode, resolveNodeGraph } from './utils/node';
|
||||||
import TressCard from './trees-card.vue';
|
import TressCard from './trees-card.vue';
|
||||||
@@ -97,6 +97,7 @@ export default defineComponent({
|
|||||||
const currentZoom = ref<number>(1);
|
const currentZoom = ref<number>(1);
|
||||||
const draggedNodeData = ref<NodeTemplate | null>(null);
|
const draggedNodeData = ref<NodeTemplate | null>(null);
|
||||||
const isDraggingOver = ref(false);
|
const isDraggingOver = ref(false);
|
||||||
|
const currentBehaviorTree = ref<BehaviorTree | null>(null);
|
||||||
const currentNodeGraph = ref<NodeGraph | null>(null);
|
const currentNodeGraph = ref<NodeGraph | null>(null);
|
||||||
const selectedModelNode = ref<Node<NodeProperties> | null>(null);
|
const selectedModelNode = ref<Node<NodeProperties> | null>(null);
|
||||||
const selectedNodeTaskElement = ref<SettingTaskNodeElement | null>(null);
|
const selectedNodeTaskElement = ref<SettingTaskNodeElement | null>(null);
|
||||||
@@ -151,7 +152,7 @@ export default defineComponent({
|
|||||||
safeStopPropagation(e);
|
safeStopPropagation(e);
|
||||||
isDraggingOver.value = false;
|
isDraggingOver.value = false;
|
||||||
|
|
||||||
if (!currentNodeGraph.value) {
|
if (!currentBehaviorTree.value) {
|
||||||
message.error('请先选择或者创建行为树.');
|
message.error('请先选择或者创建行为树.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -200,26 +201,42 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectTree = (tree: BehaviorTree) => {
|
||||||
|
console.error('handleSelectTree', tree);
|
||||||
|
findOneTreeById(tree.id).then(r => {
|
||||||
|
if (r.data) {
|
||||||
|
currentBehaviorTree.value = r.data;
|
||||||
|
try {
|
||||||
|
currentBehaviorTree.value.graph = JSON.parse(r.data?.xmlContent as unknown as string) as unknown as NodeGraph;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error('parse error,cause:', e);
|
||||||
|
}
|
||||||
|
createElements();
|
||||||
|
} else {
|
||||||
|
message.error(r.msg ?? '行为树不存在.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const createElements = () => {
|
const createElements = () => {
|
||||||
|
if (!currentBehaviorTree.value?.graph) {
|
||||||
|
currentBehaviorTree.value?.graph = {
|
||||||
|
nodes: [],
|
||||||
|
edges: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
if(graph.value && currentNodeGraph.value){
|
if(graph.value && currentNodeGraph.value){
|
||||||
graph.value.clearCells();
|
graph.value.clearCells();
|
||||||
setTimeout(()=> {
|
setTimeout(()=> {
|
||||||
nextTick(()=> {
|
nextTick(()=> {
|
||||||
try{
|
try{
|
||||||
if (currentNodeGraph.value && !currentNodeGraph.value?.graph){
|
const nodes: EdgeNodeElement[] = currentBehaviorTree.value?.graph?.nodes ?? [];
|
||||||
currentNodeGraph.value.graph = {
|
const edges: EdgeNodeElement[] = currentBehaviorTree.value?.graph?.edges ?? [];
|
||||||
nodes: [],
|
nodes.forEach((n: any) => {
|
||||||
edges: [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const nodes = currentNodeGraph.value?.graph?.nodes ?? [];
|
|
||||||
const edges = currentNodeGraph.value?.graph?.edges ?? [];
|
|
||||||
|
|
||||||
nodes.forEach(n=> {
|
|
||||||
const node = createTaskNodeElement(n);
|
const node = createTaskNodeElement(n);
|
||||||
graph.value?.addNode(node as Node);
|
graph.value?.addNode(node as Node);
|
||||||
})
|
})
|
||||||
edges.forEach(g=> {
|
edges.forEach((g: any) => {
|
||||||
graph.value?.addEdge( g as any);
|
graph.value?.addEdge( g as any);
|
||||||
})
|
})
|
||||||
} catch (e){
|
} catch (e){
|
||||||
@@ -293,40 +310,29 @@ export default defineComponent({
|
|||||||
changed.value = true
|
changed.value = true
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectTree = (treeModel: TreeModel) => {
|
|
||||||
console.error('handleSelectTree', treeModel);
|
|
||||||
findOneTreeById(treeModel.id).then(r => {
|
|
||||||
if (r.data) {
|
|
||||||
currentNodeGraph.value = r.data;
|
|
||||||
createElements();
|
|
||||||
} else {
|
|
||||||
message.error(r.message ?? '行为树不存在.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
const graphData: NodeGraph = resolveNodeGraph(graph.value as Graph);
|
const graphData: NodeGraph = resolveNodeGraph(graph.value as Graph);
|
||||||
console.info('handleSave', graphData);
|
console.info('handleSave', graphData);
|
||||||
if (!currentNodeGraph.value) {
|
if (!currentBehaviorTree.value) {
|
||||||
message.error('当前决策树不存在');
|
message.error('当前决策树不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const newModel: TreeModelGraph = {
|
const newTree: BehaviorTree = {
|
||||||
...currentNodeGraph.value,
|
...currentBehaviorTree.value,
|
||||||
graph: graphData,
|
graph: graphData,
|
||||||
|
xmlContent: JSON.stringify(graphData),
|
||||||
};
|
};
|
||||||
let res = null;
|
let res = null;
|
||||||
if (currentNodeGraph.value.id > 0) {
|
if (currentBehaviorTree.value.id > 0) {
|
||||||
res = createTree(newModel);
|
res = createTree(newTree);
|
||||||
} else {
|
} else {
|
||||||
res = updateTree(newModel);
|
res = updateTree(newTree);
|
||||||
}
|
}
|
||||||
res.then(r => {
|
res.then(r => {
|
||||||
if (r.code === 200) {
|
if (r.code === 200) {
|
||||||
message.success(r.message ?? '操作成功.');
|
message.success(r.msg ?? '操作成功.');
|
||||||
} else {
|
} else {
|
||||||
message.error(r.message ?? '操作失败.');
|
message.error(r.msg ?? '操作失败.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -351,6 +357,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
currentBehaviorTree,
|
||||||
currentNodeGraph,
|
currentNodeGraph,
|
||||||
selectedNodeTaskElement,
|
selectedNodeTaskElement,
|
||||||
selectedModelNode,
|
selectedModelNode,
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
* that was distributed with this source code.
|
* that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NullableString, PageableResponse, ApiDataResponse } from '@/types';
|
import type { ApiDataResponse, NullableString, PageableResponse } from '@/types';
|
||||||
|
import type { NodeGraph } from './node';
|
||||||
|
|
||||||
export interface BehaviorTree {
|
export interface BehaviorTree {
|
||||||
|
|
||||||
id: number,
|
id: number,
|
||||||
name: NullableString,
|
name: NullableString,
|
||||||
description: NullableString,
|
description: NullableString,
|
||||||
@@ -18,6 +18,7 @@ export interface BehaviorTree {
|
|||||||
updatedAt: NullableString,
|
updatedAt: NullableString,
|
||||||
englishName: NullableString,
|
englishName: NullableString,
|
||||||
xmlContent: NullableString,
|
xmlContent: NullableString,
|
||||||
|
graph: NodeGraph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user