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 type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, NodeTemplatesResponse, TreeModelDetailsResponse, TreeModelGraph } from './types';
|
||||
import type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, NodeTemplatesResponse } from './types';
|
||||
import type { BasicResponse } from '@/types';
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
export const findOneTreeById = (id: number): Promise<BehaviorTreeDetailsResponse> => {
|
||||
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> => {
|
||||
return req.putJson('/behavior-trees', rt);
|
||||
export const createTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
||||
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-actions">
|
||||
<a-space>
|
||||
<a-tooltip v-if="graph && currentNodeGraph" placement="top">
|
||||
<a-tooltip v-if="graph && currentBehaviorTree" placement="top">
|
||||
<template #title>
|
||||
保存
|
||||
</template>
|
||||
@@ -60,7 +60,7 @@
|
||||
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
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 { Wrapper } from '@/components/wrapper';
|
||||
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
||||
@@ -68,7 +68,7 @@ import Header from './header.vue';
|
||||
import Properties from './properties.vue';
|
||||
import { useGraphCanvas } from './builder/hooks';
|
||||
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 { createTaskNodeElement, createTaskNodeElementFromTemplate, hasElements, hasRootElementNode, resolveNodeGraph } from './utils/node';
|
||||
import TressCard from './trees-card.vue';
|
||||
@@ -97,6 +97,7 @@ export default defineComponent({
|
||||
const currentZoom = ref<number>(1);
|
||||
const draggedNodeData = ref<NodeTemplate | null>(null);
|
||||
const isDraggingOver = ref(false);
|
||||
const currentBehaviorTree = ref<BehaviorTree | null>(null);
|
||||
const currentNodeGraph = ref<NodeGraph | null>(null);
|
||||
const selectedModelNode = ref<Node<NodeProperties> | null>(null);
|
||||
const selectedNodeTaskElement = ref<SettingTaskNodeElement | null>(null);
|
||||
@@ -151,7 +152,7 @@ export default defineComponent({
|
||||
safeStopPropagation(e);
|
||||
isDraggingOver.value = false;
|
||||
|
||||
if (!currentNodeGraph.value) {
|
||||
if (!currentBehaviorTree.value) {
|
||||
message.error('请先选择或者创建行为树.');
|
||||
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 = () => {
|
||||
if (!currentBehaviorTree.value?.graph) {
|
||||
currentBehaviorTree.value?.graph = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
}
|
||||
if(graph.value && currentNodeGraph.value){
|
||||
graph.value.clearCells();
|
||||
setTimeout(()=> {
|
||||
nextTick(()=> {
|
||||
try{
|
||||
if (currentNodeGraph.value && !currentNodeGraph.value?.graph){
|
||||
currentNodeGraph.value.graph = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
}
|
||||
}
|
||||
const nodes = currentNodeGraph.value?.graph?.nodes ?? [];
|
||||
const edges = currentNodeGraph.value?.graph?.edges ?? [];
|
||||
|
||||
nodes.forEach(n=> {
|
||||
const nodes: EdgeNodeElement[] = currentBehaviorTree.value?.graph?.nodes ?? [];
|
||||
const edges: EdgeNodeElement[] = currentBehaviorTree.value?.graph?.edges ?? [];
|
||||
nodes.forEach((n: any) => {
|
||||
const node = createTaskNodeElement(n);
|
||||
graph.value?.addNode(node as Node);
|
||||
})
|
||||
edges.forEach(g=> {
|
||||
edges.forEach((g: any) => {
|
||||
graph.value?.addEdge( g as any);
|
||||
})
|
||||
} catch (e){
|
||||
@@ -293,40 +310,29 @@ export default defineComponent({
|
||||
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 graphData: NodeGraph = resolveNodeGraph(graph.value as Graph);
|
||||
console.info('handleSave', graphData);
|
||||
if (!currentNodeGraph.value) {
|
||||
if (!currentBehaviorTree.value) {
|
||||
message.error('当前决策树不存在');
|
||||
return;
|
||||
}
|
||||
const newModel: TreeModelGraph = {
|
||||
...currentNodeGraph.value,
|
||||
const newTree: BehaviorTree = {
|
||||
...currentBehaviorTree.value,
|
||||
graph: graphData,
|
||||
xmlContent: JSON.stringify(graphData),
|
||||
};
|
||||
let res = null;
|
||||
if (currentNodeGraph.value.id > 0) {
|
||||
res = createTree(newModel);
|
||||
if (currentBehaviorTree.value.id > 0) {
|
||||
res = createTree(newTree);
|
||||
} else {
|
||||
res = updateTree(newModel);
|
||||
res = updateTree(newTree);
|
||||
}
|
||||
res.then(r => {
|
||||
if (r.code === 200) {
|
||||
message.success(r.message ?? '操作成功.');
|
||||
message.success(r.msg ?? '操作成功.');
|
||||
} else {
|
||||
message.error(r.message ?? '操作失败.');
|
||||
message.error(r.msg ?? '操作失败.');
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -351,6 +357,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
return {
|
||||
currentBehaviorTree,
|
||||
currentNodeGraph,
|
||||
selectedNodeTaskElement,
|
||||
selectedModelNode,
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* 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 {
|
||||
|
||||
id: number,
|
||||
name: NullableString,
|
||||
description: NullableString,
|
||||
@@ -18,6 +18,7 @@ export interface BehaviorTree {
|
||||
updatedAt: NullableString,
|
||||
englishName: NullableString,
|
||||
xmlContent: NullableString,
|
||||
graph: NodeGraph
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user