Merge branch 'master' of http://101.43.238.71:3000/zouju/auto-solution
This commit is contained in:
@@ -68,6 +68,11 @@ public class FireRuleController extends BaseController {
|
|||||||
return success(ruleService.findAllPlatformComponents());
|
return success(ruleService.findAllPlatformComponents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/platforms/basic")
|
||||||
|
public AjaxResult platformsBasic(){
|
||||||
|
return success(ruleService.findAllBasicPlatformComponents());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据平台id获取平台下所有组件
|
* 根据平台id获取平台下所有组件
|
||||||
* @param platformId
|
* @param platformId
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class GraphNode implements Serializable {
|
|||||||
|
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
|
private boolean multiable;
|
||||||
|
|
||||||
private List<Templateparameterdef> parameters;
|
private List<Templateparameterdef> parameters;
|
||||||
|
|
||||||
private List<GraphVariable> variables;
|
private List<GraphVariable> variables;
|
||||||
@@ -61,6 +63,14 @@ public class GraphNode implements Serializable {
|
|||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMultiable() {
|
||||||
|
return multiable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMultiable(boolean multiable) {
|
||||||
|
this.multiable = multiable;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ public class Nodeparameter extends BaseEntity
|
|||||||
@Excel(name = "节点实例设置的具体参数值 (覆盖模板默认值)")
|
@Excel(name = "节点实例设置的具体参数值 (覆盖模板默认值)")
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
|
private int groupIndex;
|
||||||
|
|
||||||
public void setId(Long id)
|
public void setId(Long id)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -80,6 +82,14 @@ public class Nodeparameter extends BaseEntity
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getGroupIndex() {
|
||||||
|
return groupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupIndex(int groupIndex) {
|
||||||
|
this.groupIndex = groupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public class Nodetemplate extends BaseEntity
|
|||||||
@Excel(name = "模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
@Excel(name = "模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
||||||
private String templateType;
|
private String templateType;
|
||||||
|
|
||||||
|
private boolean multiable;
|
||||||
|
|
||||||
public Nodetemplate() {
|
public Nodetemplate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +55,7 @@ public class Nodetemplate extends BaseEntity
|
|||||||
this.description = template.description;
|
this.description = template.description;
|
||||||
this.englishName = template.englishName;
|
this.englishName = template.englishName;
|
||||||
this.templateType = template.templateType;
|
this.templateType = template.templateType;
|
||||||
|
this.multiable = template.multiable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Long id)
|
public void setId(Long id)
|
||||||
@@ -125,6 +128,14 @@ public class Nodetemplate extends BaseEntity
|
|||||||
return templateType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMultiable() {
|
||||||
|
return multiable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMultiable(boolean multiable) {
|
||||||
|
this.multiable = multiable;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public class Templateparameterdef extends BaseEntity
|
|||||||
@Excel(name = "判断参数模版是节点的参数模版还是条件的参数模版")
|
@Excel(name = "判断参数模版是节点的参数模版还是条件的参数模版")
|
||||||
private String templateType;
|
private String templateType;
|
||||||
|
|
||||||
|
private int groupIndex;
|
||||||
|
|
||||||
public void setId(Long id)
|
public void setId(Long id)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -112,6 +114,14 @@ public class Templateparameterdef extends BaseEntity
|
|||||||
return templateType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getGroupIndex() {
|
||||||
|
return groupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupIndex(int groupIndex) {
|
||||||
|
this.groupIndex = groupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="nodeInstanceId" column="node_instance_id" />
|
<result property="nodeInstanceId" column="node_instance_id" />
|
||||||
<result property="paramDefId" column="param_def_id" />
|
<result property="paramDefId" column="param_def_id" />
|
||||||
<result property="value" column="value" />
|
<result property="value" column="value" />
|
||||||
|
<result property="groupIndex" column="group_index" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<delete id="deleteByTreeId">
|
<delete id="deleteByTreeId">
|
||||||
@@ -17,7 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<sql id="selectNodeparameterVo">
|
<sql id="selectNodeparameterVo">
|
||||||
select id, treeId, node_instance_id, param_def_id, value from nodeparameter
|
select id, treeId, node_instance_id, param_def_id,`value`, group_index from nodeparameter
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectNodeparameterList" parameterType="Nodeparameter" resultMap="NodeparameterResult">
|
<select id="selectNodeparameterList" parameterType="Nodeparameter" resultMap="NodeparameterResult">
|
||||||
@@ -41,12 +42,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="nodeInstanceId != null">node_instance_id,</if>
|
<if test="nodeInstanceId != null">node_instance_id,</if>
|
||||||
<if test="paramDefId != null">param_def_id,</if>
|
<if test="paramDefId != null">param_def_id,</if>
|
||||||
<if test="value != null">value,</if>
|
<if test="value != null">value,</if>
|
||||||
|
group_index
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="treeId != null">#{treeId},</if>
|
<if test="treeId != null">#{treeId},</if>
|
||||||
<if test="nodeInstanceId != null">#{nodeInstanceId},</if>
|
<if test="nodeInstanceId != null">#{nodeInstanceId},</if>
|
||||||
<if test="paramDefId != null">#{paramDefId},</if>
|
<if test="paramDefId != null">#{paramDefId},</if>
|
||||||
<if test="value != null">#{value},</if>
|
<if test="value != null">#{value},</if>
|
||||||
|
#{groupIndex}
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -57,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="nodeInstanceId != null">node_instance_id = #{nodeInstanceId},</if>
|
<if test="nodeInstanceId != null">node_instance_id = #{nodeInstanceId},</if>
|
||||||
<if test="paramDefId != null">param_def_id = #{paramDefId},</if>
|
<if test="paramDefId != null">param_def_id = #{paramDefId},</if>
|
||||||
<if test="value != null">value = #{value},</if>
|
<if test="value != null">value = #{value},</if>
|
||||||
|
group_index=#{groupIndex}
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="description" column="description" />
|
<result property="description" column="description" />
|
||||||
<result property="englishName" column="english_name" />
|
<result property="englishName" column="english_name" />
|
||||||
<result property="templateType" column="templete_type" />
|
<result property="templateType" column="templete_type" />
|
||||||
|
<result property="multiable" column="is_multiable" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectNodetemplateVo">
|
<sql id="selectNodetemplateVo">
|
||||||
select id, type, name, logic_handler, description, english_name, templete_type from nodetemplate
|
select id, type, name, logic_handler, description, english_name, templete_type, is_multiable from nodetemplate
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectNodetemplateList" parameterType="Nodetemplate" resultMap="NodetemplateResult">
|
<select id="selectNodetemplateList" parameterType="Nodetemplate" resultMap="NodetemplateResult">
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.solution.rule.domain;
|
||||||
|
/*
|
||||||
|
* 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 java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BasicPlatform implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,43 +8,12 @@ package com.solution.rule.domain;
|
|||||||
* that was distributed with this source code.
|
* that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Platform implements Serializable {
|
public class Platform extends BasicPlatform {
|
||||||
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
private List<PlatformComponent> components;
|
private List<PlatformComponent> components;
|
||||||
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PlatformComponent> getComponents() {
|
public List<PlatformComponent> getComponents() {
|
||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
@@ -52,5 +21,4 @@ public class Platform implements Serializable {
|
|||||||
public void setComponents(List<PlatformComponent> components) {
|
public void setComponents(List<PlatformComponent> components) {
|
||||||
this.components = components;
|
this.components = components;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.solution.rule.mapper;
|
package com.solution.rule.mapper;
|
||||||
|
|
||||||
|
import com.solution.rule.domain.BasicPlatform;
|
||||||
import com.solution.rule.domain.Platform;
|
import com.solution.rule.domain.Platform;
|
||||||
import com.solution.rule.domain.PlatformComponent;
|
import com.solution.rule.domain.PlatformComponent;
|
||||||
import com.solution.rule.domain.vo.ComponentCountVO;
|
import com.solution.rule.domain.vo.ComponentCountVO;
|
||||||
@@ -44,4 +45,6 @@ public interface FireRuleMapper {
|
|||||||
List<Platform> findPlatformComponents(Integer scenarioId);
|
List<Platform> findPlatformComponents(Integer scenarioId);
|
||||||
|
|
||||||
List<Platform> findAllPlatformComponents();
|
List<Platform> findAllPlatformComponents();
|
||||||
|
|
||||||
|
List<BasicPlatform> findAllBasicPlatformComponents();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.solution.rule.service;
|
package com.solution.rule.service;
|
||||||
|
|
||||||
|
import com.solution.rule.domain.BasicPlatform;
|
||||||
import com.solution.rule.domain.FireRuleExecuteDTO;
|
import com.solution.rule.domain.FireRuleExecuteDTO;
|
||||||
import com.solution.rule.domain.Platform;
|
import com.solution.rule.domain.Platform;
|
||||||
import com.solution.rule.domain.PlatformComponent;
|
import com.solution.rule.domain.PlatformComponent;
|
||||||
@@ -47,4 +48,6 @@ public interface FireRuleService {
|
|||||||
List<Platform> findPlatformComponents(Integer scenarioId);
|
List<Platform> findPlatformComponents(Integer scenarioId);
|
||||||
|
|
||||||
List<Platform> findAllPlatformComponents();
|
List<Platform> findAllPlatformComponents();
|
||||||
|
|
||||||
|
List<BasicPlatform> findAllBasicPlatformComponents();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ package com.solution.rule.service.impl;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.solution.common.constant.ExceptionConstants;
|
import com.solution.common.constant.ExceptionConstants;
|
||||||
import com.solution.rule.domain.FireRuleExecuteDTO;
|
import com.solution.rule.domain.*;
|
||||||
import com.solution.rule.domain.Platform;
|
|
||||||
import com.solution.rule.domain.PlatformComponent;
|
|
||||||
import com.solution.rule.domain.RuleParam;
|
|
||||||
import com.solution.rule.domain.dto.WeaponModelDTO;
|
import com.solution.rule.domain.dto.WeaponModelDTO;
|
||||||
import com.solution.rule.domain.vo.ComponentCountVO;
|
import com.solution.rule.domain.vo.ComponentCountVO;
|
||||||
import com.solution.rule.domain.vo.PlatformComponentNamesVO;
|
import com.solution.rule.domain.vo.PlatformComponentNamesVO;
|
||||||
@@ -181,4 +178,9 @@ public class FireRuleServiceImpl implements FireRuleService {
|
|||||||
return ruleMapper.findAllPlatformComponents();
|
return ruleMapper.findAllPlatformComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BasicPlatform> findAllBasicPlatformComponents() {
|
||||||
|
return ruleMapper.findAllBasicPlatformComponents();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,16 @@
|
|||||||
WHERE platform_id=#{platformId} AND platform_component.type = "comm"
|
WHERE platform_id=#{platformId} AND platform_component.type = "comm"
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<resultMap id="VPBasicPlatformMap" type="com.solution.rule.domain.BasicPlatform">
|
||||||
|
<result property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
<result property="description" column="description"/>
|
||||||
|
</resultMap>
|
||||||
|
<select id="findAllBasicPlatformComponents" resultMap="VPBasicPlatformMap">
|
||||||
|
SELECT *
|
||||||
|
FROM platform
|
||||||
|
</select>
|
||||||
|
|
||||||
<resultMap id="VPlatformMap" type="com.solution.rule.domain.Platform">
|
<resultMap id="VPlatformMap" type="com.solution.rule.domain.Platform">
|
||||||
<result property="id" column="id"/>
|
<result property="id" column="id"/>
|
||||||
<result property="name" column="name"/>
|
<result property="name" column="name"/>
|
||||||
|
|||||||
@@ -1830,3 +1830,44 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ks-add-parameter-action{
|
||||||
|
color: #eee;
|
||||||
|
position: absolute;
|
||||||
|
right: 14px;
|
||||||
|
top: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ks-parameter-setting-tabs{
|
||||||
|
.ant-tabs-nav{
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
.ant-tabs-nav-list{
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
&.ant-tabs-left >.ant-tabs-content-holder,
|
||||||
|
&.ant-tabs-left >div>.ant-tabs-content-holder{
|
||||||
|
border-left-color: #09264b;
|
||||||
|
}
|
||||||
|
.ant-tabs-tab-remove{
|
||||||
|
//position: absolute;
|
||||||
|
//right: 10px;
|
||||||
|
//top: 7px;
|
||||||
|
.anticon{
|
||||||
|
color: rgb(173 206 224);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.ant-tabs-left >.ant-tabs-nav .ant-tabs-tab{
|
||||||
|
border-radius: 0!important;
|
||||||
|
}
|
||||||
|
&.ant-tabs-card >.ant-tabs-nav .ant-tabs-tab-active,
|
||||||
|
&.ant-tabs-card >div>.ant-tabs-nav .ant-tabs-tab-active {
|
||||||
|
background: #09264c;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ant-tabs-left >.ant-tabs-content-holder >.ant-tabs-content>.ant-tabs-tabpane,
|
||||||
|
&.ant-tabs-left >div>.ant-tabs-content-holder >.ant-tabs-content>.ant-tabs-tabpane{
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||||
|
import {useRouter} from 'vue-router';
|
||||||
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, type NodeProperties } from '@antv/x6';
|
import { Graph, Node, type NodeProperties } from '@antv/x6';
|
||||||
@@ -54,8 +55,9 @@ import { Wrapper } from '@/components/wrapper';
|
|||||||
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
|
||||||
import Header from '../header.vue';
|
import Header from '../header.vue';
|
||||||
|
|
||||||
import type { PlatformWithComponents, Scenario } from './types';
|
import type { Scenario } from './types';
|
||||||
import { createGraphTaskElement, createLineOptions, type GraphContainer, type GraphTaskElement, resolveGraph, useGraphCanvas } from '../graph';
|
import type { PlatformWithComponents } from '../types';
|
||||||
|
import { createLineOptions, type GraphContainer, type GraphTaskElement, resolveGraph, useGraphCanvas } from '../graph';
|
||||||
|
|
||||||
import { registerScenarioElement } from './register';
|
import { registerScenarioElement } from './register';
|
||||||
import { createGraphScenarioElement, createGraphTaskElementFromScenario } from './utils';
|
import { createGraphScenarioElement, createGraphTaskElementFromScenario } from './utils';
|
||||||
@@ -63,7 +65,7 @@ import { createGraphScenarioElement, createGraphTaskElementFromScenario } from '
|
|||||||
import PlatformCard from './platform-card.vue';
|
import PlatformCard from './platform-card.vue';
|
||||||
import NodesCard from './nodes-card.vue';
|
import NodesCard from './nodes-card.vue';
|
||||||
import { saveScenario } from './api';
|
import { saveScenario } from './api';
|
||||||
import {resolveConnectionRelation} from './relation'
|
import { resolveConnectionRelation } from './relation';
|
||||||
|
|
||||||
const TeleportContainer = defineComponent(getTeleport());
|
const TeleportContainer = defineComponent(getTeleport());
|
||||||
|
|
||||||
@@ -82,6 +84,7 @@ export default defineComponent({
|
|||||||
TeleportContainer,
|
TeleportContainer,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const router = useRouter();
|
||||||
const canvas = ref<HTMLDivElement | null>(null);
|
const canvas = ref<HTMLDivElement | null>(null);
|
||||||
const graph = ref<Graph | null>(null);
|
const graph = ref<Graph | null>(null);
|
||||||
const currentZoom = ref<number>(1);
|
const currentZoom = ref<number>(1);
|
||||||
@@ -105,6 +108,19 @@ export default defineComponent({
|
|||||||
resizeCanvas,
|
resizeCanvas,
|
||||||
} = useGraphCanvas();
|
} = useGraphCanvas();
|
||||||
|
|
||||||
|
const destroy = ()=> {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
if (graph.value) {
|
||||||
|
try {
|
||||||
|
graph.value.clearCells();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('销毁画布时出错:', error);
|
||||||
|
}
|
||||||
|
graph.value = null;
|
||||||
|
console.log('画布已销毁');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 处理拖动开始
|
// 处理拖动开始
|
||||||
const handleDragStart = (nm: PlatformWithComponents) => {
|
const handleDragStart = (nm: PlatformWithComponents) => {
|
||||||
draggedNodeData.value = nm;
|
draggedNodeData.value = nm;
|
||||||
@@ -293,6 +309,14 @@ export default defineComponent({
|
|||||||
currentScenarioEditing.value = null !== currentScenario.value;
|
currentScenarioEditing.value = null !== currentScenario.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handleGraphEvent('node:dblclick', () => {
|
||||||
|
destroy()
|
||||||
|
window.location.href = '/app/decision/designer'
|
||||||
|
// router.push({
|
||||||
|
// path: '/app/decision/designer'
|
||||||
|
// })
|
||||||
|
});
|
||||||
|
|
||||||
handleGraphEvent('node:click', (args: any) => {
|
handleGraphEvent('node:click', (args: any) => {
|
||||||
const node = args.node as Node<NodeProperties>;
|
const node = args.node as Node<NodeProperties>;
|
||||||
const newElement = node.getData() as GraphTaskElement;
|
const newElement = node.getData() as GraphTaskElement;
|
||||||
@@ -382,18 +406,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 清理
|
// 清理
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => destroy());
|
||||||
window.removeEventListener('resize', handleResize);
|
|
||||||
if (graph.value) {
|
|
||||||
try {
|
|
||||||
graph.value.clearCells();
|
|
||||||
} catch (error) {
|
|
||||||
console.warn('销毁画布时出错:', error);
|
|
||||||
}
|
|
||||||
graph.value = null;
|
|
||||||
console.log('画布已销毁');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scenariosCardRef,
|
scenariosCardRef,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import type { ApiDataResponse, NullableString, PageableResponse } from '@/types';
|
import type { NullableString, PageableResponse } from '@/types';
|
||||||
import type { GraphContainer } from '../graph';
|
import type { GraphContainer } from '../graph';
|
||||||
import type { Platform, PlatformComponent } from '../types';
|
import type { Platform, PlatformComponent } from '../types';
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import type { GraphRect, GraphTaskElement } from '../graph';
|
import type { GraphRect, GraphTaskElement } from '../graph';
|
||||||
import { generateKey } from '@/utils/strings';
|
import { generateKey } from '@/utils/strings';
|
||||||
import type { PlatformWithComponents } from './types';
|
import type { PlatformWithComponents } from '../types';
|
||||||
|
|
||||||
export const createGraphTaskElementFromScenario = (
|
export const createGraphTaskElementFromScenario = (
|
||||||
platform: PlatformWithComponents,
|
platform: PlatformWithComponents,
|
||||||
@@ -28,6 +28,7 @@ export const createGraphTaskElementFromScenario = (
|
|||||||
template: 0,
|
template: 0,
|
||||||
templateType: null,
|
templateType: null,
|
||||||
category: null,
|
category: null,
|
||||||
|
multiable: false,
|
||||||
group: null,
|
group: null,
|
||||||
description: platform.description,
|
description: platform.description,
|
||||||
order: 0,
|
order: 0,
|
||||||
|
|||||||
@@ -69,61 +69,64 @@
|
|||||||
|
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|
||||||
<a-tabs v-if="currentElement" v-model:activeKey="activeBottomTabsKey" class="ks-model-builder-tabs parameters-tabs">
|
<a-tabs v-if="currentElement?.multiable === true" v-model:activeKey="activeBottomTabsKey" class="ks-model-builder-tabs parameters-tabs">
|
||||||
<template #leftExtra>
|
<template #leftExtra>
|
||||||
<span class="ks-model-builder-title-icon icon-input"></span>
|
<span class="ks-model-builder-title-icon icon-input"></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #rightExtra v-if="multiableParameters">
|
||||||
|
<a-tooltip title="添加平台" placement="left">
|
||||||
|
<div class="ks-add-parameter-action" @click="()=> addParameterTab()">
|
||||||
|
<a-space>
|
||||||
|
<PlusCircleOutlined/>
|
||||||
|
<span>添加</span>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
<a-tab-pane key="1" tab="节点变量">
|
<a-tab-pane key="1" tab="节点变量">
|
||||||
|
<template v-if="currentElement.parameters && currentElement.parameters.length > 0">
|
||||||
<a-form
|
<a-form
|
||||||
v-if="currentElement.parameters && currentElement.parameters.length > 0"
|
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
name="basic"
|
name="basic"
|
||||||
style="padding-bottom:15px;"
|
style="padding-bottom:15px;"
|
||||||
>
|
>
|
||||||
<a-form-item v-for="setting in currentElement.parameters" :label="setting.description">
|
|
||||||
<a-input-number v-if="setting.dataType === 'double'" v-model:value="setting.defaultValue" :placeholder="setting.description" size="small" style="width:100%;" />
|
<template v-if="multiableParameters">
|
||||||
|
<a-tabs class="ks-parameter-setting-tabs"
|
||||||
|
v-model:activeKey="groupedParametersActiveTab"
|
||||||
|
tab-position="left"
|
||||||
|
hide-add
|
||||||
|
size="small"
|
||||||
|
type="editable-card"
|
||||||
|
@edit="onEditParameterTab">
|
||||||
|
<a-tab-pane v-for="(grouped,index) in groupedParameters" :key="index" :tab="`平台 ${index + 1}`" :closable="true">
|
||||||
|
<a-form-item v-for="setting in grouped" :label="setting.description">
|
||||||
|
<a-input-number v-if="setting.dataType === 'double'" v-model:value="setting.defaultValue"
|
||||||
|
:placeholder="setting.description" size="small" style="width:100%;" />
|
||||||
<a-input v-else v-model:value="setting.defaultValue" :placeholder="setting.description" size="small" />
|
<a-input v-else v-model:value="setting.defaultValue" :placeholder="setting.description" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-tab-pane>
|
||||||
<a-empty v-else>
|
<!-- <template #leftExtra>-->
|
||||||
|
<!-- <a-button class="ks-btn" size="small" style="margin-bottom: 15px; width: 100%" block @click="()=> addParameterTab()">-->
|
||||||
</a-empty>
|
<!-- <PlusOutlined />-->
|
||||||
<!-- <div class="w-full">-->
|
<!--<!– <span>添加</span>–>-->
|
||||||
<!-- <a-space>-->
|
|
||||||
<!-- <a-button size="small" type="primary" @click="addVariable">添加</a-button>-->
|
|
||||||
<!-- </a-space>-->
|
|
||||||
<!-- <a-table-->
|
|
||||||
<!-- :columns="actionSpaceColumns"-->
|
|
||||||
<!-- :dataSource="currentElement.variables"-->
|
|
||||||
<!-- :pagination="false"-->
|
|
||||||
<!-- :scroll="{ x: 500 }"-->
|
|
||||||
<!-- class="mt-1"-->
|
|
||||||
<!-- row-key="key"-->
|
|
||||||
<!-- size="small"-->
|
|
||||||
<!-- style="overflow-y:auto;height:35vh;"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <template #bodyCell="{column, record, index}">-->
|
|
||||||
<!-- <template v-if="column.dataIndex === 'index'">-->
|
|
||||||
<!-- {{ index + 1 }}-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- <template v-else-if="column.dataIndex === '_actions'">-->
|
|
||||||
<!-- <a-button-->
|
|
||||||
<!-- class="btn-link-delete"-->
|
|
||||||
<!-- danger-->
|
|
||||||
<!-- size="small"-->
|
|
||||||
<!-- type="text"-->
|
|
||||||
<!-- @click="()=> removeVariable(record)"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- 删除-->
|
|
||||||
<!-- </a-button>-->
|
<!-- </a-button>-->
|
||||||
<!-- </template>-->
|
<!-- </template>-->
|
||||||
<!-- <template v-else>-->
|
</a-tabs>
|
||||||
<!-- <a-input v-model:value="record[column.dataIndex]" size="small" />-->
|
</template>
|
||||||
<!-- </template>-->
|
<template v-else>
|
||||||
<!-- </template>-->
|
<a-form-item v-for="setting in currentElement.parameters" :label="setting.description">
|
||||||
<!-- </a-table>-->
|
<a-input-number v-if="setting.dataType === 'double'" v-model:value="setting.defaultValue"
|
||||||
<!-- </div>-->
|
:placeholder="setting.description" size="small" style="width:100%;" />
|
||||||
|
<a-input v-else v-model:value="setting.defaultValue" :placeholder="setting.description" size="small" />
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
<a-empty v-else>
|
||||||
|
</a-empty>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|
||||||
@@ -146,8 +149,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, type PropType, ref, watch } from 'vue';
|
import { defineComponent, onMounted, type PropType, ref, watch } from 'vue';
|
||||||
import { CheckOutlined } from '@ant-design/icons-vue';
|
import { CheckOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||||
import type { ElementVariable, GraphTaskElement } from '../graph';
|
import type { ElementParameter, ElementVariable, GraphTaskElement } from '../graph';
|
||||||
import type { BehaviorTree } from './tree';
|
import type { BehaviorTree } from './tree';
|
||||||
import type { Graph, Node, NodeProperties } from '@antv/x6';
|
import type { Graph, Node, NodeProperties } from '@antv/x6';
|
||||||
import { generateKey } from '@/utils/strings';
|
import { generateKey } from '@/utils/strings';
|
||||||
@@ -161,7 +164,7 @@ const actionSpaceColumns = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { CheckOutlined },
|
components: { CheckOutlined, PlusOutlined, PlusCircleOutlined },
|
||||||
props: {
|
props: {
|
||||||
tree: { type: [Object, null] as PropType<BehaviorTree | null | undefined>, required: false },
|
tree: { type: [Object, null] as PropType<BehaviorTree | null | undefined>, required: false },
|
||||||
treeEditing: { type: Boolean as PropType<boolean>, required: true, default: false },
|
treeEditing: { type: Boolean as PropType<boolean>, required: true, default: false },
|
||||||
@@ -179,10 +182,98 @@ export default defineComponent({
|
|||||||
const currentNode = ref<Node | null>(props.node ?? null);
|
const currentNode = ref<Node | null>(props.node ?? null);
|
||||||
const currentElement = ref<GraphTaskElement | null>(null);
|
const currentElement = ref<GraphTaskElement | null>(null);
|
||||||
|
|
||||||
const load = () => {
|
const emptyParameters = ref<ElementParameter[]>([]);
|
||||||
|
const groupedParameters = ref<Array<ElementParameter[]>>([]);
|
||||||
|
const multiableParameters = ref<boolean>(false);
|
||||||
|
const groupedParametersActiveTab = ref<number>(0);
|
||||||
|
|
||||||
|
const createEmptyParameters = (): ElementParameter[] => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(JSON.stringify(currentElement.value?.parameters ?? [])) as ElementParameter[];
|
||||||
|
} catch (e: any) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dumpParameters = (): ElementParameter[] => {
|
||||||
|
return JSON.parse(JSON.stringify(emptyParameters.value)) as ElementParameter[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const addParameterTab = () => {
|
||||||
|
let newParameters = dumpParameters();
|
||||||
|
// 新增一个空的参数分组
|
||||||
|
groupedParameters.value.push(newParameters);
|
||||||
|
// 自动切换到新增的分组
|
||||||
|
groupedParametersActiveTab.value = groupedParameters.value.length - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const removeParameterTab = (index: number) => {
|
||||||
|
// 边界判断:防止删除不存在的分组 / 只剩一个分组时禁止删除
|
||||||
|
if (index < 0 || index >= groupedParameters.value.length) return;
|
||||||
|
if (groupedParameters.value.length <= 1) return;
|
||||||
|
|
||||||
|
// 从数组中删除对应索引的分组
|
||||||
|
groupedParameters.value.splice(index, 1);
|
||||||
|
|
||||||
|
if (groupedParameters.value.length === 0) {
|
||||||
|
groupedParameters.value.push(dumpParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除后处理激活状态:
|
||||||
|
// 如果删除的是最后一个分组,激活前一个
|
||||||
|
if (groupedParametersActiveTab.value >= groupedParameters.value.length) {
|
||||||
|
groupedParametersActiveTab.value = groupedParameters.value.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEditParameterTab = (targetKey: number | MouseEvent, action: string) => {
|
||||||
|
if (action === 'add') {
|
||||||
|
addParameterTab();
|
||||||
|
} else {
|
||||||
|
removeParameterTab(targetKey as number);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolveGroupedParameters = () => {
|
||||||
|
emptyParameters.value = createEmptyParameters();
|
||||||
|
// 解构获取当前元素的关键属性,简化代码
|
||||||
|
const { multiable, parameters } = currentElement.value || {};
|
||||||
|
|
||||||
|
// 1. 不满足多分组条件:直接清空分组
|
||||||
|
if (multiable !== true || !parameters || parameters.length === 0) {
|
||||||
|
groupedParameters.value = [];
|
||||||
|
multiableParameters.value = multiable === true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 满足条件:根据 groupIndex 对参数进行分组
|
||||||
|
// 第一步:用 Map 做临时分组(key=groupIndex,value=当前分组的参数数组)
|
||||||
|
const groupMap = new Map<number, ElementParameter[]>();
|
||||||
|
parameters.forEach(param => {
|
||||||
|
const index = param.groupIndex;
|
||||||
|
// 如果 Map 中没有该分组,先初始化空数组
|
||||||
|
if (!groupMap.has(index)) {
|
||||||
|
groupMap.set(index, []);
|
||||||
|
}
|
||||||
|
// 将当前参数推入对应分组
|
||||||
|
groupMap.get(index)!.push(param);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 第二步:将 Map 转换为二维数组(按 groupIndex 升序排序)
|
||||||
|
groupedParameters.value = Array.from(groupMap.entries())
|
||||||
|
// 按分组索引从小到大排序(保证分组顺序正确)
|
||||||
|
.sort((a, b) => a[0] - b[0])
|
||||||
|
// 只保留分组后的参数数组,丢弃 key
|
||||||
|
.map(item => item[1]);
|
||||||
|
|
||||||
|
multiableParameters.value = multiable === true && groupedParameters.value.length > 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const resolveNode = (n?: Node | null | undefined) => {
|
const resolveNode = (n?: Node | null | undefined) => {
|
||||||
|
groupedParametersActiveTab.value = 0;
|
||||||
currentNode.value = n ?? null;
|
currentNode.value = n ?? null;
|
||||||
if (n) {
|
if (n) {
|
||||||
const data = n.getData();
|
const data = n.getData();
|
||||||
@@ -190,6 +281,7 @@ export default defineComponent({
|
|||||||
} else {
|
} else {
|
||||||
currentElement.value = null;
|
currentElement.value = null;
|
||||||
}
|
}
|
||||||
|
resolveGroupedParameters();
|
||||||
};
|
};
|
||||||
|
|
||||||
const addVariable = () => {
|
const addVariable = () => {
|
||||||
@@ -220,6 +312,17 @@ export default defineComponent({
|
|||||||
if (currentNode.value && currentElement.value) {
|
if (currentNode.value && currentElement.value) {
|
||||||
// 深拷贝当前元素数据
|
// 深拷贝当前元素数据
|
||||||
const newElement = JSON.parse(JSON.stringify(currentElement.value)) as GraphTaskElement;
|
const newElement = JSON.parse(JSON.stringify(currentElement.value)) as GraphTaskElement;
|
||||||
|
|
||||||
|
if (multiableParameters.value) {
|
||||||
|
newElement.parameters = groupedParameters.value.flatMap((group, groupIndex) => {
|
||||||
|
// 遍历每个分组,给组内所有参数统一设置/保持 groupIndex
|
||||||
|
return group.map(param => ({
|
||||||
|
...param,
|
||||||
|
groupIndex: groupIndex // 强制保证:当前参数的分组索引 = 所在分组的索引
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 更新节点数据
|
// 更新节点数据
|
||||||
currentNode.value.replaceData(newElement);
|
currentNode.value.replaceData(newElement);
|
||||||
// 触发事件通知父组件
|
// 触发事件通知父组件
|
||||||
@@ -227,6 +330,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const load = () => {
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.node,
|
() => props.node,
|
||||||
(n?: Node | null | undefined) => resolveNode(n),
|
(n?: Node | null | undefined) => resolveNode(n),
|
||||||
@@ -249,11 +355,18 @@ export default defineComponent({
|
|||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(() => groupedParameters.value, () => updateNode(), { deep: true });
|
||||||
|
|
||||||
watch(() => currentElement.value, () => updateNode(), { deep: true });
|
watch(() => currentElement.value, () => updateNode(), { deep: true });
|
||||||
|
|
||||||
onMounted(() => load());
|
onMounted(() => load());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
addParameterTab,
|
||||||
|
groupedParametersActiveTab,
|
||||||
|
multiableParameters,
|
||||||
|
onEditParameterTab,
|
||||||
|
groupedParameters,
|
||||||
actionSpaceColumns,
|
actionSpaceColumns,
|
||||||
activeTopTabsKey,
|
activeTopTabsKey,
|
||||||
activeBottomTabsKey,
|
activeBottomTabsKey,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface NodeTemplate {
|
|||||||
templateType: NullableString;
|
templateType: NullableString;
|
||||||
englishName: NullableString;
|
englishName: NullableString;
|
||||||
parameters: ElementParameter[],
|
parameters: ElementParameter[],
|
||||||
|
multiable?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeDragTemplate extends NodeTemplate {
|
export interface NodeDragTemplate extends NodeTemplate {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const createGraphTaskElementFromTemplate = (
|
|||||||
category: template.type,
|
category: template.type,
|
||||||
group: template.group,
|
group: template.group,
|
||||||
description: template.description,
|
description: template.description,
|
||||||
|
multiable: template.multiable === true,
|
||||||
order: 0,
|
order: 0,
|
||||||
position: {
|
position: {
|
||||||
x: realRect.x ?? 0,
|
x: realRect.x ?? 0,
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export interface ElementParameter {
|
|||||||
defaultValue: NullableString,
|
defaultValue: NullableString,
|
||||||
description: NullableString,
|
description: NullableString,
|
||||||
templateType: NullableString,
|
templateType: NullableString,
|
||||||
|
groupIndex: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ export interface GraphTaskElement extends GraphBaseElement {
|
|||||||
inputs: any;
|
inputs: any;
|
||||||
outputs: any;
|
outputs: any;
|
||||||
order: number;
|
order: number;
|
||||||
|
multiable:boolean,
|
||||||
variables: ElementVariable[];
|
variables: ElementVariable[];
|
||||||
parameters: ElementParameter[];
|
parameters: ElementParameter[];
|
||||||
children?: GraphTaskElement[],
|
children?: GraphTaskElement[],
|
||||||
|
|||||||
@@ -183,6 +183,11 @@ export const useGraphCanvas = (readonly: boolean = false): UseGraphCanvas => {
|
|||||||
emitGraphEvent('node:click', ctx);
|
emitGraphEvent('node:click', ctx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
graph.value.on('node:dblclick', (ctx: NodeViewPositionEventArgs<Dom.ClickEvent>) => {
|
||||||
|
console.info('node:dblclick', ctx);
|
||||||
|
emitGraphEvent('node:dblclick', ctx);
|
||||||
|
});
|
||||||
|
|
||||||
// 监听节点选中事件
|
// 监听节点选中事件
|
||||||
graph.value.on('node:selected', ({ node }) => {
|
graph.value.on('node:selected', ({ node }) => {
|
||||||
console.info('node select', node);
|
console.info('node select', node);
|
||||||
|
|||||||
Reference in New Issue
Block a user