Compare commits
26 Commits
e12c3c0302
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b3fe9b548 | ||
|
|
db30244cd1 | ||
|
|
c9bc62fb8c | ||
|
|
9d54395c29 | ||
|
|
35fd1c8937 | ||
|
|
579d0f2bd8 | ||
|
|
7f8abf2ff2 | ||
|
|
f1bcd3812d | ||
|
|
d3fda27bb0 | ||
|
|
538a43f597 | ||
|
|
fcab8585c5 | ||
|
|
0ffc42ab69 | ||
|
|
46bead08a0 | ||
|
|
e07b11ef95 | ||
|
|
a78781782e | ||
|
|
0b55384442 | ||
|
|
43837901f3 | ||
|
|
8898cd2e6f | ||
|
|
f34274ea35 | ||
|
|
5ffdb5e508 | ||
|
|
a5a3c93135 | ||
|
|
af697e9304 | ||
|
|
e7abfca9f7 | ||
|
|
1058d666a0 | ||
|
|
58d36a3d6d | ||
|
|
b544391b5c |
@@ -1,8 +1,14 @@
|
|||||||
package com.solution.web.controller.algo;
|
package com.solution.web.controller.algo;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@@ -37,6 +43,51 @@ public class AlgorithmController extends BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IAlgorithmService algorithmService;
|
private IAlgorithmService algorithmService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出规则列表
|
||||||
|
*/
|
||||||
|
@ApiOperation("运行python程序")
|
||||||
|
@PostMapping("/run")
|
||||||
|
public Object run(@RequestBody Algorithm algorithm) {
|
||||||
|
List<Algorithm> list = algorithmService.selectAlgorithmList(algorithm);
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
for (Algorithm al : list) {
|
||||||
|
String codePath = al.getCodePath();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String jsonInput = objectMapper.writeValueAsString(al);
|
||||||
|
String pythonExe = "E:\\Apps\\anaconda3\\python.exe";
|
||||||
|
ProcessBuilder pb = new ProcessBuilder(pythonExe, codePath);
|
||||||
|
Process process = pb.start();
|
||||||
|
|
||||||
|
try (OutputStream os = process.getOutputStream()) {
|
||||||
|
os.write(jsonInput.getBytes(StandardCharsets.UTF_8));
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
String result;
|
||||||
|
// 修改你 Java 代码中的这一段
|
||||||
|
try (BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
|
||||||
|
result = reader.lines().collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int exitCode = process.waitFor();
|
||||||
|
if (exitCode != 0) {
|
||||||
|
return "Python执行失败,错误码:" + exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectMapper.readTree(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "执行异常: " + e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "未找到算法";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询规则列表
|
* 查询规则列表
|
||||||
*/
|
*/
|
||||||
@@ -56,7 +107,7 @@ public class AlgorithmController extends BaseController {
|
|||||||
@PreAuthorize("@ss.hasPermi('algo:algorithm:export')")
|
@PreAuthorize("@ss.hasPermi('algo:algorithm:export')")
|
||||||
@Log(title = "规则", businessType = BusinessType.EXPORT)
|
@Log(title = "规则", businessType = BusinessType.EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(HttpServletResponse response, Algorithm algorithm) {
|
public void export(HttpServletResponse response, @RequestBody Algorithm algorithm) {
|
||||||
List<Algorithm> list = algorithmService.selectAlgorithmList(algorithm);
|
List<Algorithm> list = algorithmService.selectAlgorithmList(algorithm);
|
||||||
ExcelUtil<Algorithm> util = new ExcelUtil<Algorithm>(Algorithm.class);
|
ExcelUtil<Algorithm> util = new ExcelUtil<Algorithm>(Algorithm.class);
|
||||||
util.exportExcel(response, list, "规则数据");
|
util.exportExcel(response, list, "规则数据");
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.solution.web.controller.behaviour;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.solution.web.core.BehaviortreeProcessor;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@@ -38,6 +39,9 @@ public class BehaviortreeController extends BaseController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IBehaviortreeService behaviortreeService;
|
private IBehaviortreeService behaviortreeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BehaviortreeProcessor behaviortreeProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询行为树主列表
|
* 查询行为树主列表
|
||||||
*/
|
*/
|
||||||
@@ -84,7 +88,7 @@ public class BehaviortreeController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@RequestBody Behaviortree behaviortree)
|
public AjaxResult add(@RequestBody Behaviortree behaviortree)
|
||||||
{
|
{
|
||||||
return toAjax(behaviortreeService.insertBehaviortree(behaviortree));
|
return toAjax(behaviortreeProcessor.create(behaviortree));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +100,7 @@ public class BehaviortreeController extends BaseController
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@RequestBody Behaviortree behaviortree)
|
public AjaxResult edit(@RequestBody Behaviortree behaviortree)
|
||||||
{
|
{
|
||||||
return toAjax(behaviortreeService.updateBehaviortree(behaviortree));
|
return toAjax(behaviortreeProcessor.update(behaviortree));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -95,26 +95,26 @@ public class NodetemplateController extends BaseController {
|
|||||||
if (CollectionUtils.isEmpty(list)) {
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
return R.ok(null);
|
return R.ok(null);
|
||||||
}
|
}
|
||||||
// Map<String, List<NodetemplateDTO>> groupedByTemplateType = list.stream()
|
Map<String, List<NodetemplateDTO>> groupedByTemplateType = list.stream()
|
||||||
// .map(template -> {
|
.map(template -> {
|
||||||
// NodetemplateDTO dto = new NodetemplateDTO();
|
NodetemplateDTO dto = new NodetemplateDTO();
|
||||||
// dto.setId(template.getId());
|
dto.setId(template.getId());
|
||||||
// dto.setName(template.getName());
|
dto.setName(template.getName());
|
||||||
// dto.setDescription(template.getDescription());
|
dto.setDescription(template.getDescription());
|
||||||
// dto.setEnglishName(template.getEnglishName());
|
dto.setEnglishName(template.getEnglishName());
|
||||||
// dto.setLogicHandler(template.getLogicHandler());
|
dto.setLogicHandler(template.getLogicHandler());
|
||||||
// dto.setTempleteType(template.getTempleteType());
|
dto.setTemplateType(template.getTemplateType());
|
||||||
// return dto;
|
return dto;
|
||||||
// })
|
})
|
||||||
// .collect(Collectors.groupingBy(NodetemplateDTO::getTempleteType));
|
.collect(Collectors.groupingBy(NodetemplateDTO::getTemplateType));
|
||||||
// List<NodetemplateVO> vos = new ArrayList<>();
|
List<NodetemplateVO> vos = new ArrayList<>();
|
||||||
// groupedByTemplateType.forEach((key, value) -> {
|
groupedByTemplateType.forEach((key, value) -> {
|
||||||
// // 处理逻辑
|
// 处理逻辑
|
||||||
// NodetemplateVO vo = new NodetemplateVO();
|
NodetemplateVO vo = new NodetemplateVO();
|
||||||
// vo.setTempleteType(key);
|
vo.setTemplateType(key);
|
||||||
// vo.setDtoList(value);
|
vo.setDtoList(value);
|
||||||
// vos.add(vo);
|
vos.add(vo);
|
||||||
// });
|
});
|
||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class NodetemplateDTO {
|
|||||||
@ApiModelProperty("afsim 中转换的节点名")
|
@ApiModelProperty("afsim 中转换的节点名")
|
||||||
private String englishName;
|
private String englishName;
|
||||||
|
|
||||||
private String templeteType;
|
private String templateType;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
@@ -65,11 +65,11 @@ public class NodetemplateDTO {
|
|||||||
this.englishName = englishName;
|
this.englishName = englishName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTempleteType() {
|
public String getTemplateType() {
|
||||||
return templeteType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTempleteType(String templeteType) {
|
public void setTemplateType(String templateType) {
|
||||||
this.templeteType = templeteType;
|
this.templateType = templateType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ import java.util.List;
|
|||||||
public class NodetemplateVO {
|
public class NodetemplateVO {
|
||||||
/** 模版类型,节点模版或者条件判断,例如“node”,precondition“ */
|
/** 模版类型,节点模版或者条件判断,例如“node”,precondition“ */
|
||||||
@ApiModelProperty("模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
@ApiModelProperty("模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
||||||
private String templeteType;
|
private String templateType;
|
||||||
|
|
||||||
@ApiModelProperty("节点模板数据")
|
@ApiModelProperty("节点模板数据")
|
||||||
private List<NodetemplateDTO> dtoList;
|
private List<NodetemplateDTO> dtoList;
|
||||||
|
|
||||||
public String getTempleteType() {
|
public String getTemplateType() {
|
||||||
return templeteType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTempleteType(String templeteType) {
|
public void setTemplateType(String templateType) {
|
||||||
this.templeteType = templeteType;
|
this.templateType = templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NodetemplateDTO> getDtoList() {
|
public List<NodetemplateDTO> getDtoList() {
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package com.solution.web.core;
|
||||||
|
/*
|
||||||
|
* 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 com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.solution.system.domain.*;
|
||||||
|
import com.solution.system.service.IBehaviortreeService;
|
||||||
|
import com.solution.system.service.INodeconnectionService;
|
||||||
|
import com.solution.system.service.INodeparameterService;
|
||||||
|
import com.solution.system.service.ITreenodeinstanceService;
|
||||||
|
import com.solution.web.core.graph.Graph;
|
||||||
|
import com.solution.web.core.graph.GraphEdge;
|
||||||
|
import com.solution.web.core.graph.GraphNode;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BehaviortreeProcessor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBehaviortreeService behaviortreeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITreenodeinstanceService treenodeinstanceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private INodeparameterService nodeparameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private INodeconnectionService nodeconnectionService;
|
||||||
|
|
||||||
|
private ObjectMapper objectMapper = createObjectMapper();
|
||||||
|
|
||||||
|
public static ObjectMapper createObjectMapper() {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
return objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int create(Behaviortree behaviortree) {
|
||||||
|
int result = behaviortreeService.insertBehaviortree(behaviortree);
|
||||||
|
processGraph(behaviortree);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int update(Behaviortree behaviortree) {
|
||||||
|
int result = behaviortreeService.updateBehaviortree(behaviortree);
|
||||||
|
|
||||||
|
// 删除节点实例
|
||||||
|
treenodeinstanceService.deleteByTreeId(behaviortree.getId());
|
||||||
|
|
||||||
|
// 删除参数
|
||||||
|
nodeparameterService.deleteByTreeId(behaviortree.getId());
|
||||||
|
|
||||||
|
// 删除连线
|
||||||
|
nodeconnectionService.deleteByTreeId(behaviortree.getId());
|
||||||
|
|
||||||
|
processGraph(behaviortree);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processGraph(Behaviortree behaviortree) {
|
||||||
|
|
||||||
|
Graph graph = null;
|
||||||
|
try {
|
||||||
|
graph = objectMapper.readValue(behaviortree.getXmlContent(), Graph.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// skip
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == graph) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入节点 treenodeinstance
|
||||||
|
Map<String, Treenodeinstance> instanceKeyMap = new HashMap<>();
|
||||||
|
Map<String, Long> nodeKeyIndexMap = new HashMap<>();
|
||||||
|
if (graph.hasNodes()) {
|
||||||
|
Long index = 0L;
|
||||||
|
for (GraphNode node : graph.getNodes()) {
|
||||||
|
Treenodeinstance instance = createNodeInstance(behaviortree, node);
|
||||||
|
treenodeinstanceService.insertTreenodeinstance(instance);
|
||||||
|
instanceKeyMap.put(node.getKey(), instance);
|
||||||
|
|
||||||
|
if (node.hasParameters()) {
|
||||||
|
// 插入parameter nodeparameter
|
||||||
|
for (Templateparameterdef parameter : node.getParameters()) {
|
||||||
|
Nodeparameter nodeparameter = createNodeParameter(behaviortree, parameter, instance);
|
||||||
|
nodeparameterService.insertNodeparameter(nodeparameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodeKeyIndexMap.put(node.getKey(), index);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入连线 nodeconnection
|
||||||
|
if (graph.hasEdges()) {
|
||||||
|
for (GraphEdge edge : graph.getEdges()) {
|
||||||
|
Nodeconnection connection = createConnection(behaviortree, edge, instanceKeyMap, nodeKeyIndexMap);
|
||||||
|
nodeconnectionService.insertNodeconnection(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Nodeconnection createConnection(Behaviortree behaviortree, GraphEdge edge,
|
||||||
|
Map<String, Treenodeinstance> instanceKeyMap,
|
||||||
|
Map<String, Long> nodeKeyIndexMap) {
|
||||||
|
Nodeconnection connection = new Nodeconnection();
|
||||||
|
connection.setTreeId(behaviortree.getId());
|
||||||
|
if (null != instanceKeyMap.get(edge.getSource().getCell())) {
|
||||||
|
Treenodeinstance parent = instanceKeyMap.get(edge.getSource().getCell());
|
||||||
|
connection.setParentNodeId(parent.getId());
|
||||||
|
}
|
||||||
|
if (null != instanceKeyMap.get(edge.getTarget().getCell())) {
|
||||||
|
Treenodeinstance children = instanceKeyMap.get(edge.getTarget().getCell());
|
||||||
|
connection.setChildNodeId(children.getId());
|
||||||
|
}
|
||||||
|
if (null != nodeKeyIndexMap.get(edge.getSource().getCell())) {
|
||||||
|
connection.setOrderIndex(nodeKeyIndexMap.get(edge.getSource().getCell()));
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Nodeparameter createNodeParameter(Behaviortree behaviortree, Templateparameterdef parameter,
|
||||||
|
Treenodeinstance instance) {
|
||||||
|
Nodeparameter nodeparameter = new Nodeparameter();
|
||||||
|
nodeparameter.setTreeId(behaviortree.getId());
|
||||||
|
nodeparameter.setNodeInstanceId(instance.getId());
|
||||||
|
nodeparameter.setParamDefId(parameter.getId());
|
||||||
|
nodeparameter.setValue(parameter.getDefaultValue());
|
||||||
|
return nodeparameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Treenodeinstance createNodeInstance(Behaviortree behaviortree, GraphNode node) {
|
||||||
|
Treenodeinstance instance = new Treenodeinstance();
|
||||||
|
instance.setTreeId(behaviortree.getId());
|
||||||
|
instance.setTemplateId((long) node.getTemplate());
|
||||||
|
instance.setInstanceName(node.getName());
|
||||||
|
instance.setIsRoot((long) (node.isRoot() ? 1 : 0));
|
||||||
|
if ("precondition".equalsIgnoreCase(node.getTemplateType())) {
|
||||||
|
instance.setPreconditionTempleteId((long) node.getTemplate());
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.solution.web.core.graph;
|
||||||
|
/*
|
||||||
|
* 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 Graph implements Serializable {
|
||||||
|
|
||||||
|
private List<GraphNode> nodes;
|
||||||
|
|
||||||
|
private List<GraphEdge> edges;
|
||||||
|
|
||||||
|
public boolean hasNodes() {
|
||||||
|
return nodes != null && !nodes.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasEdges() {
|
||||||
|
return edges != null && !edges.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Graph{" +
|
||||||
|
"nodes=" + nodes +
|
||||||
|
", edges=" + edges +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GraphNode> getNodes() {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodes(List<GraphNode> nodes) {
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GraphEdge> getEdges() {
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEdges(List<GraphEdge> edges) {
|
||||||
|
this.edges = edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.solution.web.core.graph;
|
||||||
|
/*
|
||||||
|
* 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 org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class GraphEdge implements Serializable {
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private Line source;
|
||||||
|
|
||||||
|
private Line target;
|
||||||
|
|
||||||
|
public boolean hasSource() {
|
||||||
|
return source != null && StringUtils.hasText(source.cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasTarget() {
|
||||||
|
return target != null && StringUtils.hasText(target.cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Line implements Serializable {
|
||||||
|
|
||||||
|
private String cell;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Line{" +
|
||||||
|
"cell='" + cell + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCell() {
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCell(String cell) {
|
||||||
|
this.cell = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GraphEdge{" +
|
||||||
|
"key='" + key + '\'' +
|
||||||
|
", source='" + source + '\'' +
|
||||||
|
", target='" + target + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSource(Line source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(Line target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package com.solution.web.core.graph;
|
||||||
|
/*
|
||||||
|
* 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 com.solution.system.domain.Templateparameterdef;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GraphNode implements Serializable {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private int template;
|
||||||
|
|
||||||
|
private String templateType;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
private List<Templateparameterdef> parameters;
|
||||||
|
|
||||||
|
private List<GraphVariable> variables;
|
||||||
|
|
||||||
|
public boolean hasParameters() {
|
||||||
|
return parameters != null && !parameters.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasVariables() {
|
||||||
|
return variables != null && !variables.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRoot() {
|
||||||
|
return "root".equalsIgnoreCase(this.category);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GraphNode{" +
|
||||||
|
"id=" + id +
|
||||||
|
", key='" + key + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", description='" + description + '\'' +
|
||||||
|
", parameters=" + parameters +
|
||||||
|
", variables=" + variables +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplateType() {
|
||||||
|
return templateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemplateType(String templateType) {
|
||||||
|
this.templateType = templateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTemplate() {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemplate(int template) {
|
||||||
|
this.template = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Templateparameterdef> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameters(List<Templateparameterdef> parameters) {
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GraphVariable> getVariables() {
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVariables(List<GraphVariable> variables) {
|
||||||
|
this.variables = variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.solution.web.core.graph;
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public class GraphVariable implements Serializable {
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private String defaults;
|
||||||
|
|
||||||
|
private String unit;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GraphVariable{" +
|
||||||
|
"key='" + key + '\'' +
|
||||||
|
", value='" + value + '\'' +
|
||||||
|
", defaults='" + defaults + '\'' +
|
||||||
|
", unit='" + unit + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaults() {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaults(String defaults) {
|
||||||
|
this.defaults = defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnit(String unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package com.solution.algo;
|
||||||
|
/*
|
||||||
|
* 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 com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||||
|
import com.solution.algo.domain.AlgorithmConfig;
|
||||||
|
import org.apache.ibatis.type.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@MappedTypes(List.class)
|
||||||
|
@MappedJdbcTypes({
|
||||||
|
JdbcType.VARCHAR,
|
||||||
|
JdbcType.BLOB
|
||||||
|
})
|
||||||
|
public class AlgorithmConfigTypeHandler extends BaseTypeHandler<List<AlgorithmConfig>>
|
||||||
|
implements TypeHandler<List<AlgorithmConfig>> {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
private final CollectionType collectionType = objectMapper.getTypeFactory()
|
||||||
|
.constructCollectionType(List.class, AlgorithmConfig.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNonNullParameter(PreparedStatement ps, int i, List<AlgorithmConfig> parameter, JdbcType jdbcType)
|
||||||
|
throws SQLException {
|
||||||
|
ps.setString(i, serialize(parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String serialize(List<AlgorithmConfig> indicatorConfig) {
|
||||||
|
if (null != indicatorConfig) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(indicatorConfig);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Can not serialize", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AlgorithmConfig> deserialize(String config) throws SQLException {
|
||||||
|
if (StringUtils.hasText(config)) {
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(config, collectionType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Can not deserialize", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AlgorithmConfig> getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
String jsonValue = rs.getString(columnName);
|
||||||
|
return deserialize(jsonValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AlgorithmConfig> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
|
String jsonValue = rs.getString(columnIndex);
|
||||||
|
return deserialize(jsonValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AlgorithmConfig> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
|
String jsonValue = cs.getString(columnIndex);
|
||||||
|
return deserialize(jsonValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,6 +34,13 @@ public class Algorithm
|
|||||||
@Excel(name = "算法描述")
|
@Excel(name = "算法描述")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
/** 算法配置 */
|
||||||
|
@Excel(name = "算法配置")
|
||||||
|
private String algoConfig;
|
||||||
|
|
||||||
|
/** 算法配置 */
|
||||||
|
private List<AlgorithmConfig> algoConfigList;
|
||||||
|
|
||||||
/** 算法参数定义信息 */
|
/** 算法参数定义信息 */
|
||||||
private List<AlgorithmParam> algorithmParamList;
|
private List<AlgorithmParam> algorithmParamList;
|
||||||
|
|
||||||
@@ -87,6 +94,16 @@ public class Algorithm
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAlgoConfig(String algoConfig)
|
||||||
|
{
|
||||||
|
this.algoConfig = algoConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlgoConfig()
|
||||||
|
{
|
||||||
|
return algoConfig;
|
||||||
|
}
|
||||||
|
|
||||||
public List<AlgorithmParam> getAlgorithmParamList()
|
public List<AlgorithmParam> getAlgorithmParamList()
|
||||||
{
|
{
|
||||||
return algorithmParamList;
|
return algorithmParamList;
|
||||||
@@ -97,6 +114,14 @@ public class Algorithm
|
|||||||
this.algorithmParamList = algorithmParamList;
|
this.algorithmParamList = algorithmParamList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<AlgorithmConfig> getAlgoConfigList() {
|
||||||
|
return algoConfigList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlgoConfigList(List<AlgorithmConfig> algoConfigList) {
|
||||||
|
this.algoConfigList = algoConfigList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@@ -105,6 +130,7 @@ public class Algorithm
|
|||||||
.append("type", getType())
|
.append("type", getType())
|
||||||
.append("codePath", getCodePath())
|
.append("codePath", getCodePath())
|
||||||
.append("description", getDescription())
|
.append("description", getDescription())
|
||||||
|
.append("algoConfig", getAlgoConfig())
|
||||||
.append("algorithmParamList", getAlgorithmParamList())
|
.append("algorithmParamList", getAlgorithmParamList())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.solution.algo.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;
|
||||||
|
|
||||||
|
public class AlgorithmConfig implements Serializable {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String operation;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOperation() {
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOperation(String operation) {
|
||||||
|
this.operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="type" column="type" />
|
<result property="type" column="type" />
|
||||||
<result property="codePath" column="code_path" />
|
<result property="codePath" column="code_path" />
|
||||||
<result property="description" column="description" />
|
<result property="description" column="description" />
|
||||||
|
<result property="algoConfig" column="algo_config" />
|
||||||
|
<result property="algoConfigList" column="algo_config_list" typeHandler="com.solution.algo.AlgorithmConfigTypeHandler" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="AlgorithmAlgorithmParamResult" type="Algorithm" extends="AlgorithmResult">
|
<resultMap id="AlgorithmAlgorithmParamResult" type="Algorithm" extends="AlgorithmResult">
|
||||||
@@ -25,7 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectAlgorithmVo">
|
<sql id="selectAlgorithmVo">
|
||||||
select id, name, type, code_path, description from algorithm
|
select id, name, type, code_path, description, algo_config, algo_config_list from algorithm
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectAlgorithmList" parameterType="Algorithm" resultMap="AlgorithmAlgorithmParamResult">
|
<select id="selectAlgorithmList" parameterType="Algorithm" resultMap="AlgorithmAlgorithmParamResult">
|
||||||
@@ -35,11 +37,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="type != null and type != ''"> and type = #{type}</if>
|
<if test="type != null and type != ''"> and type = #{type}</if>
|
||||||
<if test="codePath != null and codePath != ''"> and code_path = #{codePath}</if>
|
<if test="codePath != null and codePath != ''"> and code_path = #{codePath}</if>
|
||||||
<if test="description != null and description != ''"> and description = #{description}</if>
|
<if test="description != null and description != ''"> and description = #{description}</if>
|
||||||
|
<if test="algoConfig != null and algoConfig != ''"> and algo_config = #{algoConfig}</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectAlgorithmById" parameterType="Long" resultMap="AlgorithmAlgorithmParamResult">
|
<select id="selectAlgorithmById" parameterType="Long" resultMap="AlgorithmAlgorithmParamResult">
|
||||||
select id, name, type, code_path, description
|
select id, name, type, code_path, description, algo_config
|
||||||
from algorithm
|
from algorithm
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</select>
|
</select>
|
||||||
@@ -57,12 +60,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="type != null and type != ''">type,</if>
|
<if test="type != null and type != ''">type,</if>
|
||||||
<if test="codePath != null">code_path,</if>
|
<if test="codePath != null">code_path,</if>
|
||||||
<if test="description != null">description,</if>
|
<if test="description != null">description,</if>
|
||||||
|
<if test="algoConfig != null">algo_config,</if>
|
||||||
|
<if test="algoConfigList != null">algo_config_list,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="name != null and name != ''">#{name},</if>
|
<if test="name != null and name != ''">#{name},</if>
|
||||||
<if test="type != null and type != ''">#{type},</if>
|
<if test="type != null and type != ''">#{type},</if>
|
||||||
<if test="codePath != null">#{codePath},</if>
|
<if test="codePath != null">#{codePath},</if>
|
||||||
<if test="description != null">#{description},</if>
|
<if test="description != null">#{description},</if>
|
||||||
|
<if test="algoConfig != null">#{algoConfig},</if>
|
||||||
|
<if test="algoConfigList != null">#{algoConfigList,typeHandler=com.solution.algo.AlgorithmConfigTypeHandler},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -73,6 +80,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="type != null and type != ''">type = #{type},</if>
|
<if test="type != null and type != ''">type = #{type},</if>
|
||||||
<if test="codePath != null">code_path = #{codePath},</if>
|
<if test="codePath != null">code_path = #{codePath},</if>
|
||||||
<if test="description != null">description = #{description},</if>
|
<if test="description != null">description = #{description},</if>
|
||||||
|
<if test="algoConfig != null">algo_config = #{algoConfig},</if>
|
||||||
|
<if test="algoConfigList != null">algo_config_list = #{algoConfigList,typeHandler=com.solution.algo.AlgorithmConfigTypeHandler},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class Nodeconnection extends BaseEntity
|
|||||||
/** 连接ID (主键) */
|
/** 连接ID (主键) */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
private Long treeId;
|
||||||
|
|
||||||
/** 父节点 (外键: TreeInstanceNode.id) */
|
/** 父节点 (外键: TreeInstanceNode.id) */
|
||||||
@Excel(name = "父节点 (外键: TreeInstanceNode.id)")
|
@Excel(name = "父节点 (外键: TreeInstanceNode.id)")
|
||||||
private Long parentNodeId;
|
private Long parentNodeId;
|
||||||
@@ -40,6 +42,14 @@ public class Nodeconnection extends BaseEntity
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getTreeId() {
|
||||||
|
return treeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTreeId(Long treeId) {
|
||||||
|
this.treeId = treeId;
|
||||||
|
}
|
||||||
|
|
||||||
public void setParentNodeId(Long parentNodeId)
|
public void setParentNodeId(Long parentNodeId)
|
||||||
{
|
{
|
||||||
this.parentNodeId = parentNodeId;
|
this.parentNodeId = parentNodeId;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class Nodeparameter extends BaseEntity
|
|||||||
/** 节点参数ID (主键) */
|
/** 节点参数ID (主键) */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
private Long treeId;
|
||||||
|
|
||||||
/** 关联到哪个节点实例 (外键: TreeInstanceNode.id) */
|
/** 关联到哪个节点实例 (外键: TreeInstanceNode.id) */
|
||||||
@Excel(name = "关联到哪个节点实例 (外键: TreeInstanceNode.id)")
|
@Excel(name = "关联到哪个节点实例 (外键: TreeInstanceNode.id)")
|
||||||
private Long nodeInstanceId;
|
private Long nodeInstanceId;
|
||||||
@@ -40,6 +42,14 @@ public class Nodeparameter extends BaseEntity
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getTreeId() {
|
||||||
|
return treeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTreeId(Long treeId) {
|
||||||
|
this.treeId = treeId;
|
||||||
|
}
|
||||||
|
|
||||||
public void setNodeInstanceId(Long nodeInstanceId)
|
public void setNodeInstanceId(Long nodeInstanceId)
|
||||||
{
|
{
|
||||||
this.nodeInstanceId = nodeInstanceId;
|
this.nodeInstanceId = nodeInstanceId;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class Nodetemplate extends BaseEntity
|
|||||||
|
|
||||||
/** 模版类型,节点模版或者条件判断,例如“node”,precondition“ */
|
/** 模版类型,节点模版或者条件判断,例如“node”,precondition“ */
|
||||||
@Excel(name = "模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
@Excel(name = "模版类型,节点模版或者条件判断,例如“node”,precondition“")
|
||||||
private String templeteType;
|
private String templateType;
|
||||||
|
|
||||||
public Nodetemplate() {
|
public Nodetemplate() {
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ public class Nodetemplate extends BaseEntity
|
|||||||
this.logicHandler = template.logicHandler;
|
this.logicHandler = template.logicHandler;
|
||||||
this.description = template.description;
|
this.description = template.description;
|
||||||
this.englishName = template.englishName;
|
this.englishName = template.englishName;
|
||||||
this.templeteType = template.templeteType;
|
this.templateType = template.templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Long id)
|
public void setId(Long id)
|
||||||
@@ -115,14 +115,14 @@ public class Nodetemplate extends BaseEntity
|
|||||||
return englishName;
|
return englishName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTempleteType(String templeteType)
|
public void setTemplateType(String templateType)
|
||||||
{
|
{
|
||||||
this.templeteType = templeteType;
|
this.templateType = templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTempleteType()
|
public String getTemplateType()
|
||||||
{
|
{
|
||||||
return templeteType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -134,7 +134,7 @@ public class Nodetemplate extends BaseEntity
|
|||||||
.append("logicHandler", getLogicHandler())
|
.append("logicHandler", getLogicHandler())
|
||||||
.append("description", getDescription())
|
.append("description", getDescription())
|
||||||
.append("englishName", getEnglishName())
|
.append("englishName", getEnglishName())
|
||||||
.append("templeteType", getTempleteType())
|
.append("templateType", getTemplateType())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.solution.system.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.solution.system.domain.Nodeconnection;
|
import com.solution.system.domain.Nodeconnection;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点连接Mapper接口
|
* 节点连接Mapper接口
|
||||||
@@ -11,6 +12,8 @@ import com.solution.system.domain.Nodeconnection;
|
|||||||
*/
|
*/
|
||||||
public interface NodeconnectionMapper
|
public interface NodeconnectionMapper
|
||||||
{
|
{
|
||||||
|
void deleteByTreeId(@Param("treeId") Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点连接
|
* 查询节点连接
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.solution.system.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.solution.system.domain.Nodeparameter;
|
import com.solution.system.domain.Nodeparameter;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点参数Mapper接口
|
* 节点参数Mapper接口
|
||||||
@@ -11,6 +12,8 @@ import com.solution.system.domain.Nodeparameter;
|
|||||||
*/
|
*/
|
||||||
public interface NodeparameterMapper
|
public interface NodeparameterMapper
|
||||||
{
|
{
|
||||||
|
void deleteByTreeId(@Param("treeId") Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点参数
|
* 查询节点参数
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.solution.system.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.solution.system.domain.Treenodeinstance;
|
import com.solution.system.domain.Treenodeinstance;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 行为树实例节点Mapper接口
|
* 行为树实例节点Mapper接口
|
||||||
@@ -11,6 +12,8 @@ import com.solution.system.domain.Treenodeinstance;
|
|||||||
*/
|
*/
|
||||||
public interface TreenodeinstanceMapper
|
public interface TreenodeinstanceMapper
|
||||||
{
|
{
|
||||||
|
void deleteByTreeId(@Param(value = "treeId") Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询行为树实例节点
|
* 查询行为树实例节点
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.solution.system.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.solution.system.domain.Nodeconnection;
|
import com.solution.system.domain.Nodeconnection;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点连接Service接口
|
* 节点连接Service接口
|
||||||
@@ -11,6 +12,9 @@ import com.solution.system.domain.Nodeconnection;
|
|||||||
*/
|
*/
|
||||||
public interface INodeconnectionService
|
public interface INodeconnectionService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void deleteByTreeId(@Param("treeId") Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点连接
|
* 查询节点连接
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import com.solution.system.domain.Nodeparameter;
|
|||||||
*/
|
*/
|
||||||
public interface INodeparameterService
|
public interface INodeparameterService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void deleteByTreeId(Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点参数
|
* 查询节点参数
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import com.solution.system.domain.Treenodeinstance;
|
|||||||
*/
|
*/
|
||||||
public interface ITreenodeinstanceService
|
public interface ITreenodeinstanceService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void deleteByTreeId(Long treeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询行为树实例节点
|
* 查询行为树实例节点
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ public class NodeconnectionServiceImpl implements INodeconnectionService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NodeconnectionMapper nodeconnectionMapper;
|
private NodeconnectionMapper nodeconnectionMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByTreeId(Long treeId) {
|
||||||
|
nodeconnectionMapper.deleteByTreeId(treeId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点连接
|
* 查询节点连接
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ public class NodeparameterServiceImpl implements INodeparameterService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NodeparameterMapper nodeparameterMapper;
|
private NodeparameterMapper nodeparameterMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByTreeId(Long treeId) {
|
||||||
|
nodeparameterMapper.deleteByTreeId(treeId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询节点参数
|
* 查询节点参数
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ public class TreenodeinstanceServiceImpl implements ITreenodeinstanceService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TreenodeinstanceMapper treenodeinstanceMapper;
|
private TreenodeinstanceMapper treenodeinstanceMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByTreeId(Long treeId) {
|
||||||
|
treenodeinstanceMapper.deleteByTreeId(treeId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询行为树实例节点
|
* 查询行为树实例节点
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,18 +6,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
|
|
||||||
<resultMap type="Nodeconnection" id="NodeconnectionResult">
|
<resultMap type="Nodeconnection" id="NodeconnectionResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
|
<result property="treeId" column="tree_id" />
|
||||||
<result property="parentNodeId" column="parent_node_id" />
|
<result property="parentNodeId" column="parent_node_id" />
|
||||||
<result property="childNodeId" column="child_node_id" />
|
<result property="childNodeId" column="child_node_id" />
|
||||||
<result property="orderIndex" column="order_index" />
|
<result property="orderIndex" column="order_index" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<delete id="deleteByTreeId">
|
||||||
|
delete from nodeconnection where tree_id=#{treeId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
<sql id="selectNodeconnectionVo">
|
<sql id="selectNodeconnectionVo">
|
||||||
select id, parent_node_id, child_node_id, order_index from nodeconnection
|
select id, tree_id, parent_node_id, child_node_id, order_index from nodeconnection
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectNodeconnectionList" parameterType="Nodeconnection" resultMap="NodeconnectionResult">
|
<select id="selectNodeconnectionList" parameterType="Nodeconnection" resultMap="NodeconnectionResult">
|
||||||
<include refid="selectNodeconnectionVo"/>
|
<include refid="selectNodeconnectionVo"/>
|
||||||
<where>
|
<where>
|
||||||
|
<if test="treeId != null "> and tree_id = #{treeId}</if>
|
||||||
<if test="parentNodeId != null "> and parent_node_id = #{parentNodeId}</if>
|
<if test="parentNodeId != null "> and parent_node_id = #{parentNodeId}</if>
|
||||||
<if test="childNodeId != null "> and child_node_id = #{childNodeId}</if>
|
<if test="childNodeId != null "> and child_node_id = #{childNodeId}</if>
|
||||||
<if test="orderIndex != null "> and order_index = #{orderIndex}</if>
|
<if test="orderIndex != null "> and order_index = #{orderIndex}</if>
|
||||||
@@ -32,11 +38,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<insert id="insertNodeconnection" parameterType="Nodeconnection" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertNodeconnection" parameterType="Nodeconnection" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into nodeconnection
|
insert into nodeconnection
|
||||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="treeId != null">tree_id,</if>
|
||||||
<if test="parentNodeId != null">parent_node_id,</if>
|
<if test="parentNodeId != null">parent_node_id,</if>
|
||||||
<if test="childNodeId != null">child_node_id,</if>
|
<if test="childNodeId != null">child_node_id,</if>
|
||||||
<if test="orderIndex != null">order_index,</if>
|
<if test="orderIndex != null">order_index,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="treeId != null">#{treeId},</if>
|
||||||
<if test="parentNodeId != null">#{parentNodeId},</if>
|
<if test="parentNodeId != null">#{parentNodeId},</if>
|
||||||
<if test="childNodeId != null">#{childNodeId},</if>
|
<if test="childNodeId != null">#{childNodeId},</if>
|
||||||
<if test="orderIndex != null">#{orderIndex},</if>
|
<if test="orderIndex != null">#{orderIndex},</if>
|
||||||
@@ -46,6 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<update id="updateNodeconnection" parameterType="Nodeconnection">
|
<update id="updateNodeconnection" parameterType="Nodeconnection">
|
||||||
update nodeconnection
|
update nodeconnection
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="treeId != null">tree_id = #{treeId},</if>
|
||||||
<if test="parentNodeId != null">parent_node_id = #{parentNodeId},</if>
|
<if test="parentNodeId != null">parent_node_id = #{parentNodeId},</if>
|
||||||
<if test="childNodeId != null">child_node_id = #{childNodeId},</if>
|
<if test="childNodeId != null">child_node_id = #{childNodeId},</if>
|
||||||
<if test="orderIndex != null">order_index = #{orderIndex},</if>
|
<if test="orderIndex != null">order_index = #{orderIndex},</if>
|
||||||
|
|||||||
@@ -6,13 +6,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
|
|
||||||
<resultMap type="Nodeparameter" id="NodeparameterResult">
|
<resultMap type="Nodeparameter" id="NodeparameterResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
|
<result property="treeId" column="tree_id" />
|
||||||
<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" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<delete id="deleteByTreeId">
|
||||||
|
delete from nodeparameter where tree_id=#{treeId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
<sql id="selectNodeparameterVo">
|
<sql id="selectNodeparameterVo">
|
||||||
select id, node_instance_id, param_def_id, value from nodeparameter
|
select id, treeId, node_instance_id, param_def_id, value from nodeparameter
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectNodeparameterList" parameterType="Nodeparameter" resultMap="NodeparameterResult">
|
<select id="selectNodeparameterList" parameterType="Nodeparameter" resultMap="NodeparameterResult">
|
||||||
@@ -32,11 +37,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<insert id="insertNodeparameter" parameterType="Nodeparameter" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertNodeparameter" parameterType="Nodeparameter" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into nodeparameter
|
insert into nodeparameter
|
||||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="treeId != null">tree_id,</if>
|
||||||
<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>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<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>
|
||||||
@@ -46,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<update id="updateNodeparameter" parameterType="Nodeparameter">
|
<update id="updateNodeparameter" parameterType="Nodeparameter">
|
||||||
update nodeparameter
|
update nodeparameter
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="treeId != null">tree_id = #{treeId},</if>
|
||||||
<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>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="logicHandler" column="logic_handler" />
|
<result property="logicHandler" column="logic_handler" />
|
||||||
<result property="description" column="description" />
|
<result property="description" column="description" />
|
||||||
<result property="englishName" column="english_name" />
|
<result property="englishName" column="english_name" />
|
||||||
<result property="templeteType" column="templete_type" />
|
<result property="templateType" column="templete_type" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectNodetemplateVo">
|
<sql id="selectNodetemplateVo">
|
||||||
@@ -26,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="logicHandler != null and logicHandler != ''"> and logic_handler = #{logicHandler}</if>
|
<if test="logicHandler != null and logicHandler != ''"> and logic_handler = #{logicHandler}</if>
|
||||||
<if test="description != null and description != ''"> and description = #{description}</if>
|
<if test="description != null and description != ''"> and description = #{description}</if>
|
||||||
<if test="englishName != null and englishName != ''"> and english_name like concat('%', #{englishName}, '%')</if>
|
<if test="englishName != null and englishName != ''"> and english_name like concat('%', #{englishName}, '%')</if>
|
||||||
<if test="templeteType != null and templeteType != ''"> and templete_type = #{templeteType}</if>
|
<if test="templateType != null and templateType != ''"> and templete_type = #{templateType}</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="logicHandler != null">logic_handler,</if>
|
<if test="logicHandler != null">logic_handler,</if>
|
||||||
<if test="description != null">description,</if>
|
<if test="description != null">description,</if>
|
||||||
<if test="englishName != null">english_name,</if>
|
<if test="englishName != null">english_name,</if>
|
||||||
<if test="templeteType != null and templeteType != ''">templete_type,</if>
|
<if test="templateType != null and templateType != ''">templete_type,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="type != null and type != ''">#{type},</if>
|
<if test="type != null and type != ''">#{type},</if>
|
||||||
@@ -51,7 +51,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="logicHandler != null">#{logicHandler},</if>
|
<if test="logicHandler != null">#{logicHandler},</if>
|
||||||
<if test="description != null">#{description},</if>
|
<if test="description != null">#{description},</if>
|
||||||
<if test="englishName != null">#{englishName},</if>
|
<if test="englishName != null">#{englishName},</if>
|
||||||
<if test="templeteType != null and templeteType != ''">#{templeteType},</if>
|
<if test="templateType != null and templateType != ''">#{templateType},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="logicHandler != null">logic_handler = #{logicHandler},</if>
|
<if test="logicHandler != null">logic_handler = #{logicHandler},</if>
|
||||||
<if test="description != null">description = #{description},</if>
|
<if test="description != null">description = #{description},</if>
|
||||||
<if test="englishName != null">english_name = #{englishName},</if>
|
<if test="englishName != null">english_name = #{englishName},</if>
|
||||||
<if test="templeteType != null and templeteType != ''">templete_type = #{templeteType},</if>
|
<if test="templateType != null and templateType != ''">templete_type = #{templateType},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="desciption" column="desciption" />
|
<result property="desciption" column="desciption" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<delete id="deleteByTreeId">
|
||||||
|
delete from treenodeinstance where tree_id=#{treeId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
<sql id="selectTreenodeinstanceVo">
|
<sql id="selectTreenodeinstanceVo">
|
||||||
select id, tree_id, template_id, instance_name, is_root, precondition_templete_id, uuid,desciption from treenodeinstance
|
select id, tree_id, template_id, instance_name, is_root, precondition_templete_id, uuid,desciption from treenodeinstance
|
||||||
</sql>
|
</sql>
|
||||||
|
|||||||
BIN
modeler/src/assets/icons/bg-node-head.png
Normal file
BIN
modeler/src/assets/icons/bg-node-head.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -34,4 +34,12 @@ export const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/decision/designer.vue'),
|
component: () => import('@/views/decision/designer.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'decision-algorithm-management',
|
||||||
|
path: '/app/decision/algorithm/management',
|
||||||
|
meta: {
|
||||||
|
title: '指挥决策规则库管理',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/decision/algorithm/management.vue'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
@@ -270,20 +270,68 @@
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
min-height: calc(100vh - 90px);
|
min-height: calc(100vh - 90px);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
background: url('@/assets/icons/bg-fk.png') center / 100% 100%;
|
||||||
|
|
||||||
|
.ant-tabs .ant-tabs-ink-bar {
|
||||||
|
position: absolute;
|
||||||
|
background: transparent;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ant-steps-horizontal{
|
||||||
|
&.ant-steps.ant-steps-navigation .ant-steps-item.ant-steps-item-active::before {
|
||||||
|
width: 30%;
|
||||||
|
margin-left: 37%;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ant-steps-item-active{
|
||||||
|
.ant-steps-item-container{
|
||||||
|
&:after{
|
||||||
|
height: 1px;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
background: #377ead;
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.ant-card-head {
|
.ant-card-head {
|
||||||
border: 0;
|
border: 0;
|
||||||
color: #11aed7;
|
color: #a2b1ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .ant-card-head {
|
& > .ant-card-head {
|
||||||
height: 50px;
|
height: 40px;
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
font-size: 16px;
|
border-radius: 0;
|
||||||
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .ant-card-head {
|
& > .ant-card-head {
|
||||||
background: url('@/assets/icons/page-card-head.png') center / 100% 100%;
|
background: url('@/assets/icons/page-card-head.png') center / 100% 100%;
|
||||||
|
background: url('@/assets/icons/bg-fk-title.png') center / 100% 100%;
|
||||||
|
color: #eee;
|
||||||
|
|
||||||
|
.point {
|
||||||
|
background: url('@/assets/icons/bg-fk-point.png') center / 100% 100%;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
display: block;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin-top: 5px;
|
||||||
|
display: block;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .ant-card-body {
|
& > .ant-card-body {
|
||||||
@@ -979,6 +1027,8 @@
|
|||||||
border-right: 1px solid #062850;
|
border-right: 1px solid #062850;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
background: #081229;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,6 +1036,7 @@
|
|||||||
width: 300px;
|
width: 300px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
|
background: #041b36db;
|
||||||
|
|
||||||
.observation-items{
|
.observation-items{
|
||||||
//height: 160px;
|
//height: 160px;
|
||||||
@@ -1319,11 +1370,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-btn-default {
|
|
||||||
background: #7dd3f9;
|
|
||||||
border-color: #7dd3f9;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-field {
|
.btn-field {
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
@@ -1485,3 +1531,114 @@
|
|||||||
.ant-divider {
|
.ant-divider {
|
||||||
border-block-start: 1px solid rgb(255 255 255 / 17%);
|
border-block-start: 1px solid rgb(255 255 255 / 17%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.ant-pagination {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.ant-pagination-disabled .ant-pagination-item-link,
|
||||||
|
.ant-pagination-disabled:hover .ant-pagination-item-link,
|
||||||
|
.ant-pagination-prev .ant-pagination-item-link,
|
||||||
|
.ant-pagination-next .ant-pagination-item-link,
|
||||||
|
&.ant-pagination-mini .ant-pagination-total-text,
|
||||||
|
&.ant-pagination-mini .ant-pagination-simple-pager {
|
||||||
|
color: rgb(255 255 255 / 95%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ant-pagination-simple .ant-pagination-simple-pager input {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #0f4a7c;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.ant-empty-small {
|
||||||
|
margin-block: 8px;
|
||||||
|
color: rgb(207 207 207 / 66%);
|
||||||
|
}
|
||||||
|
.ant-btn >span {
|
||||||
|
display: inline-block;
|
||||||
|
float: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn,
|
||||||
|
.ant-input {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary {
|
||||||
|
color: #eee;
|
||||||
|
//border-color: #1b5b7d;
|
||||||
|
//background: linear-gradient(90deg, #1e4c65 0%, #0b3a62 100%);
|
||||||
|
border-color: #29759c;
|
||||||
|
background: linear-gradient(0deg, #0f374c 0, #154c69 100%);
|
||||||
|
&.selected,
|
||||||
|
&:not(:disabled):hover,
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
border-color: #166094;
|
||||||
|
background: linear-gradient(90deg, #3687bc 0%, #074375 100%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-default {
|
||||||
|
&.ant-btn-dangerous{
|
||||||
|
background: transparent!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
color: #eee;
|
||||||
|
//border-color: #144087;
|
||||||
|
//background: linear-gradient(90deg, #0f4a7c 0%, #0a365b 100%);
|
||||||
|
border-color: #1c468b;
|
||||||
|
background: linear-gradient(0deg, #14223b 0, #1c468b 100%);
|
||||||
|
&.selected,
|
||||||
|
&:not(:disabled):hover,
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
color: #fff;
|
||||||
|
border-color: #166094;
|
||||||
|
background: linear-gradient(90deg, #3687bc 0%, #074375 100%);
|
||||||
|
}
|
||||||
|
&:disabled,
|
||||||
|
&.disabled{
|
||||||
|
color: #a9a3a3;
|
||||||
|
&:hover{
|
||||||
|
color:#eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-field {
|
||||||
|
min-width: 120px;
|
||||||
|
background: #5796b2;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
color: #fff;
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px solid #5796b2;
|
||||||
|
|
||||||
|
.anticon {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.selected {
|
||||||
|
background: #19b0ff;
|
||||||
|
border-color: #19b0ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.gold {
|
||||||
|
background: transparent;
|
||||||
|
border-color: #b5b39d;
|
||||||
|
color: #b5b39d;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
modeler/src/views/decision/algorithm/api.ts
Normal file
36
modeler/src/views/decision/algorithm/api.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 { HttpRequestClient } from '@/utils/request';
|
||||||
|
import type { Algorithm, AlgorithmPageableResponse, AlgorithmRequest } from './types';
|
||||||
|
import type { BasicResponse } from '@/types';
|
||||||
|
|
||||||
|
const req = HttpRequestClient.create<BasicResponse>({
|
||||||
|
baseURL: '/api',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const findAlgorithmsByQuery = (query: Partial<AlgorithmRequest> = {}): Promise<AlgorithmPageableResponse> => {
|
||||||
|
return req.get('/algo/algorithm/list', query);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createAlgorithm = (algorithm: Algorithm): Promise<BasicResponse> => {
|
||||||
|
return req.postJson('/algo/algorithm', algorithm);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const runAlgorithm = (algorithm: Algorithm): Promise<BasicResponse> => {
|
||||||
|
return req.postJson('/algo/algorithm/run', algorithm);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateAlgorithm = (algorithm: Algorithm): Promise<BasicResponse> => {
|
||||||
|
return req.putJson('/algo/algorithm', algorithm);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAlgorithm = (id: number): Promise<BasicResponse> => {
|
||||||
|
return req.delete(`/algo/algorithm/${id}`);
|
||||||
|
};
|
||||||
42
modeler/src/views/decision/algorithm/config.ts
Normal file
42
modeler/src/views/decision/algorithm/config.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const algorithmTypes = [
|
||||||
|
{
|
||||||
|
type: 'defense',
|
||||||
|
name: '防守',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'offense',
|
||||||
|
name: '进攻',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'formation',
|
||||||
|
name: '队形',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export const algorithmConfigOperations = [
|
||||||
|
{
|
||||||
|
type: '+',
|
||||||
|
name: '加',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: '-',
|
||||||
|
name: '减',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: '*',
|
||||||
|
name: '乘',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: '/',
|
||||||
|
name: '除',
|
||||||
|
},
|
||||||
|
]
|
||||||
513
modeler/src/views/decision/algorithm/management.vue
Normal file
513
modeler/src/views/decision/algorithm/management.vue
Normal file
@@ -0,0 +1,513 @@
|
|||||||
|
<template>
|
||||||
|
<Layout>
|
||||||
|
<template #sidebar>
|
||||||
|
<div class="ks-sidebar-header">
|
||||||
|
<a-flex class="ks-sidebar-title">
|
||||||
|
<span class="icon"></span>
|
||||||
|
<span class="text">指挥决策规则库管理</span>
|
||||||
|
</a-flex>
|
||||||
|
<a-button class="ks-sidebar-add" size="small" @click="handleCreate">
|
||||||
|
<PlusOutlined />
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<a-list item-layout="horizontal" :data-source="algorithms" class="ks-algorithm-list">
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<a-list-item @click="()=> handleSelect(item)" :class="selectedAlgorithm?.id === item.id ? 'selected' : null">
|
||||||
|
<a-list-item-meta :description="substring(item.description,20)">
|
||||||
|
<template #title>
|
||||||
|
<span class="ks-algorithm-name">{{ substring(item.name, 20) }}</span>
|
||||||
|
<span class="ks-algorithm-type"><a-badge size="small" :count="getAlgorithmTypeName(item.type)"></a-badge></span>
|
||||||
|
</template>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
</template>
|
||||||
|
</a-list>
|
||||||
|
|
||||||
|
<a-pagination
|
||||||
|
v-model:current="query.pageNum"
|
||||||
|
:page-size="query.pageSize"
|
||||||
|
:total="algorithmsTotal"
|
||||||
|
simple size="small" @change="handleChange" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="w-full h-full">
|
||||||
|
|
||||||
|
<a-card class="ks-page-card ks-algorithm-card">
|
||||||
|
|
||||||
|
<template #title>
|
||||||
|
<a-space>
|
||||||
|
<span class="point"></span>
|
||||||
|
<span class="text">规则配置</span>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="ks-scrollable" style="height: 80.5vh;overflow-y: auto;padding-right: 10px">
|
||||||
|
|
||||||
|
<a-row :gutter="15">
|
||||||
|
<a-col :span="16">
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:label-col="{span: 6}"
|
||||||
|
:model="selectedAlgorithm"
|
||||||
|
autocomplete="off"
|
||||||
|
layout="horizontal"
|
||||||
|
name="basic"
|
||||||
|
>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="规则名称"
|
||||||
|
:rules="[{ required: true, message: '请输入算法名称!', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['name']"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="selectedAlgorithm.name" placeholder="请输入算法名称" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="业务类型"
|
||||||
|
:rules="[{ required: true, message: '请输入业务类型!', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['type']"
|
||||||
|
>
|
||||||
|
<a-select placeholder="请选择业务类型" allow-clear v-model:value="selectedAlgorithm.type" @change="(v: any)=> selectedAlgorithm.type = v">
|
||||||
|
<a-select-option v-for="a in algorithmTypes" :value="a.type">{{ a.name }}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="算法文件路径"
|
||||||
|
:rules="[{ required: true, message: '请输入算法文件路径!', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['codePath']"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="selectedAlgorithm.codePath" placeholder="请输入算法文件路径" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="算法描述"
|
||||||
|
:rules="[{ required: false, message: '请输入算法描述', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['description']"
|
||||||
|
>
|
||||||
|
<a-textarea v-model:value="selectedAlgorithm.description" placeholder="请输入算法描述" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="算法参数定义"
|
||||||
|
:rules="[{ required: true, message: '请输入算法参数定义', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['algorithmParamList']"
|
||||||
|
>
|
||||||
|
<a-form-item-rest>
|
||||||
|
<div class="ks-algorithm-param-list">
|
||||||
|
<div class="ks-algorithm-param-item" v-for="(item,index) in selectedAlgorithm.algorithmParamList">
|
||||||
|
<a-row :gutter="15">
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-input v-model:value="item.paramName" placeholder="请输入参数名" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-input v-model:value="item.defaultValue" placeholder="请输入默认值" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-input v-model:value="item.description" placeholder="请输入描述" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="3">
|
||||||
|
<a-space class="ks-algorithm-param-actions">
|
||||||
|
<MinusCircleOutlined @click="()=> handleMinus(index)" />
|
||||||
|
<PlusCircleOutlined @click="handleAdd" v-if="index === 0" />
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-form-item-rest>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
label="算法配置"
|
||||||
|
:rules="[{ required: false, message: '请输入算法配置', trigger: ['input', 'change'] }]"
|
||||||
|
:name="['algoConfig']"
|
||||||
|
>
|
||||||
|
<a-form-item-rest>
|
||||||
|
<div class="ks-algorithm-param-list">
|
||||||
|
<div class="ks-algorithm-param-item" v-for="(t,index) in selectedAlgorithm.algoConfigList">
|
||||||
|
<a-row :gutter="15">
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-select placeholder="请选择参数" v-model:value="t.name" @change="(v: any)=> t.name = v">
|
||||||
|
<a-select-option :value="v.paramName" v-for="v in selectedAlgorithm.algorithmParamList">{{v.paramName}}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-select placeholder="请选择操作" v-model:value="t.operation" @change="(v: any)=> t.operation = v">
|
||||||
|
<a-select-option :value="o.type" v-for="o in algorithmConfigOperations">{{o.name}} {{o.type}}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="3">
|
||||||
|
<a-space class="ks-algorithm-param-actions">
|
||||||
|
<MinusCircleOutlined @click="()=> handleMinusConfig(index)" />
|
||||||
|
<PlusCircleOutlined @click="handleAddConfig" v-if="index === 0" />
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-form-item-rest>
|
||||||
|
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:wrapper-col="{offset: 6}"
|
||||||
|
>
|
||||||
|
<a-space>
|
||||||
|
<a-button @click="handleSave" type="primary">保存规则</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="selectedAlgorithm && selectedAlgorithm.id > 0"
|
||||||
|
title="确定运行?"
|
||||||
|
@confirm="handleRun"
|
||||||
|
>
|
||||||
|
<a-button>运行规则</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="selectedAlgorithm && selectedAlgorithm.id > 0"
|
||||||
|
title="确定删除?"
|
||||||
|
@confirm="handleDelete"
|
||||||
|
>
|
||||||
|
<a-button danger>删除规则</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
</a-form>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { type FormInstance, message } from 'ant-design-vue';
|
||||||
|
import { MinusCircleOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||||
|
import Layout from '../layout.vue';
|
||||||
|
import { createAlgorithm, deleteAlgorithm, findAlgorithmsByQuery, updateAlgorithm, runAlgorithm } from './api';
|
||||||
|
import type { Algorithm, AlgorithmParam, AlgorithmRequest } from './types';
|
||||||
|
import { substring } from '@/utils/strings';
|
||||||
|
import { algorithmTypes,algorithmConfigOperations } from './config';
|
||||||
|
import type { NullableString } from '@/types';
|
||||||
|
|
||||||
|
const query = ref<Partial<AlgorithmRequest>>({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultAlgorithmParam: AlgorithmParam = {
|
||||||
|
id: 0,
|
||||||
|
algorithmId: 0,
|
||||||
|
// 参数名
|
||||||
|
paramName: null,
|
||||||
|
// 默认值
|
||||||
|
defaultValue: null,
|
||||||
|
// 描述
|
||||||
|
description: null,
|
||||||
|
};
|
||||||
|
const defaultAlgorithm: Algorithm = {
|
||||||
|
id: 0,
|
||||||
|
// 算法名称
|
||||||
|
name: null,
|
||||||
|
// 业务类型
|
||||||
|
type: undefined,
|
||||||
|
// 算法文件路径
|
||||||
|
codePath: null,
|
||||||
|
// 算法描述
|
||||||
|
description: null,
|
||||||
|
// 算法配置
|
||||||
|
algoConfig: null,
|
||||||
|
// 算法配置
|
||||||
|
algoConfigList: [],
|
||||||
|
// 算法参数定义信息
|
||||||
|
algorithmParamList: [
|
||||||
|
{ ...defaultAlgorithmParam },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const resolveItem = (item: Algorithm) => {
|
||||||
|
let newItem = JSON.parse(JSON.stringify(item))
|
||||||
|
if (!newItem.algorithmParamList) {
|
||||||
|
newItem.algorithmParamList = [];
|
||||||
|
}
|
||||||
|
if (newItem.algorithmParamList.length === 0) {
|
||||||
|
newItem.algorithmParamList.push({ ...defaultAlgorithmParam });
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
newItem.algoConfigList = JSON.parse(newItem.algoConfigList)
|
||||||
|
} catch (e: any){
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!newItem.algoConfigList){
|
||||||
|
newItem.algoConfigList = []
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newItem.algoConfigList.length === 0){
|
||||||
|
newItem.algoConfigList.push({
|
||||||
|
name: undefined,
|
||||||
|
operation: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return newItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
const algorithms = ref<Algorithm[]>([]);
|
||||||
|
const algorithmsTotal = ref<number>(0);
|
||||||
|
const selectedAlgorithm = ref<Algorithm>(resolveItem(defaultAlgorithm));
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
|
||||||
|
const getAlgorithmTypeName = (type: NullableString): NullableString => {
|
||||||
|
let v = algorithmTypes.find(c => c.type === type);
|
||||||
|
return v && v.name ? v.name : type;
|
||||||
|
};
|
||||||
|
|
||||||
|
const load = () => {
|
||||||
|
algorithms.value = [];
|
||||||
|
algorithmsTotal.value = 0;
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
selectedAlgorithm.value = resolveItem(defaultAlgorithm);
|
||||||
|
|
||||||
|
findAlgorithmsByQuery(query.value).then(r => {
|
||||||
|
algorithms.value = r.rows ?? [];
|
||||||
|
algorithmsTotal.value = r.total ?? 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleCreate = () => {
|
||||||
|
selectedAlgorithm.value = resolveItem(defaultAlgorithm);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (item: Algorithm) => {
|
||||||
|
selectedAlgorithm.value = resolveItem(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
selectedAlgorithm.value.algorithmParamList.push({ ...defaultAlgorithmParam });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMinus = (index: number) => {
|
||||||
|
const paramList = selectedAlgorithm.value.algorithmParamList;
|
||||||
|
if (index === 0 && selectedAlgorithm.value.algorithmParamList.length === 1) {
|
||||||
|
selectedAlgorithm.value.algorithmParamList = [{ ...defaultAlgorithmParam }];
|
||||||
|
} else if (index >= 0 && index < paramList.length && paramList.length > 1) {
|
||||||
|
paramList.splice(index, 1);
|
||||||
|
selectedAlgorithm.value.algorithmParamList = [...paramList];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddConfig = () => {
|
||||||
|
selectedAlgorithm.value.algoConfigList.push({ name: null, operation: null });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMinusConfig = (index: number) => {
|
||||||
|
const paramList = selectedAlgorithm.value.algoConfigList;
|
||||||
|
if (index === 0 && selectedAlgorithm.value.algoConfigList.length === 1) {
|
||||||
|
selectedAlgorithm.value.algoConfigList = [{ name: null, operation: null }];
|
||||||
|
} else if (index >= 0 && index < paramList.length && paramList.length > 1) {
|
||||||
|
paramList.splice(index, 1);
|
||||||
|
selectedAlgorithm.value.algoConfigList = [...paramList];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = () => {
|
||||||
|
if (selectedAlgorithm.value && selectedAlgorithm.value.id > 0) {
|
||||||
|
deleteAlgorithm(selectedAlgorithm.value.id).then(r => {
|
||||||
|
if (r.code === 200) {
|
||||||
|
load();
|
||||||
|
message.info(r.msg ?? '删除成功');
|
||||||
|
} else {
|
||||||
|
message.error(r.msg ?? '删除失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
if (formRef.value) {
|
||||||
|
formRef.value.validate().then(() => {
|
||||||
|
let res = null;
|
||||||
|
let savedValue: Algorithm = JSON.parse(JSON.stringify(selectedAlgorithm.value)) as any as Algorithm;
|
||||||
|
let algoConfig = '';
|
||||||
|
if( savedValue.algoConfigList ){
|
||||||
|
savedValue.algoConfigList.forEach(o=> {
|
||||||
|
if(o.name){
|
||||||
|
algoConfig = algoConfig + o.name;
|
||||||
|
}
|
||||||
|
if(o.operation){
|
||||||
|
algoConfig = algoConfig + o.operation;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
savedValue.algoConfig = algoConfig;
|
||||||
|
|
||||||
|
if (savedValue.id > 0) {
|
||||||
|
res = updateAlgorithm(savedValue);
|
||||||
|
} else {
|
||||||
|
res = createAlgorithm(savedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
res.then(r => {
|
||||||
|
if (r.code === 200) {
|
||||||
|
load();
|
||||||
|
message.info(r.msg ?? '操作成功');
|
||||||
|
} else {
|
||||||
|
message.error(r.msg ?? '操作失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRun = ()=> {
|
||||||
|
if (formRef.value) {
|
||||||
|
formRef.value.validate().then(() => {
|
||||||
|
runAlgorithm(selectedAlgorithm.value).then(r => {
|
||||||
|
if (r.code === 200) {
|
||||||
|
message.info(r.msg ?? '运行成功');
|
||||||
|
} else {
|
||||||
|
message.error(r.msg ?? '运行失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (page: number, pageSize: number) => {
|
||||||
|
query.value.pageNum = page;
|
||||||
|
query.value.pageSize = pageSize;
|
||||||
|
load();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => load());
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.ks-algorithm-card {
|
||||||
|
.ant-card-head-title {
|
||||||
|
span.text {
|
||||||
|
display: block;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ks-sidebar-header {
|
||||||
|
line-height: 40px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
background: #081d36;
|
||||||
|
min-height: 40px;
|
||||||
|
background: url(@/assets/icons/card-head.png) left / 180% 100%;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
.ks-sidebar-title {
|
||||||
|
color: #7ae8fc;
|
||||||
|
font-size: 16px;
|
||||||
|
.icon {
|
||||||
|
background: url(@/assets/icons/list.png) center / 100% 100%;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
display: block;
|
||||||
|
margin-top: 7px;
|
||||||
|
}
|
||||||
|
.text{
|
||||||
|
margin-left: 40px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ks-sidebar-add {
|
||||||
|
position: absolute;
|
||||||
|
right: 7px;
|
||||||
|
top: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
.anticon {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-list {
|
||||||
|
&.ks-algorithm-list {
|
||||||
|
.ant-list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.5s;
|
||||||
|
border-left: 2px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.selected,
|
||||||
|
&:hover {
|
||||||
|
background: #0a1b3c;
|
||||||
|
border-left: 2px solid #11377e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ks-algorithm-type {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
|
||||||
|
.ant-badge {
|
||||||
|
.ant-badge-count {
|
||||||
|
color: #c3c2c2;
|
||||||
|
background: #333f7d;
|
||||||
|
box-shadow: 0 0 0 1px #325478;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-list-item-meta {
|
||||||
|
.ant-list-item-meta-title {
|
||||||
|
color: #7ae8fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-list-item-meta-description {
|
||||||
|
color: #4d8c98;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ks-algorithm-param-list {
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #475f71;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.ks-algorithm-param-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ks-algorithm-param-actions {
|
||||||
|
.anticon {
|
||||||
|
color: #7ae8fc;
|
||||||
|
font-size: 20px;
|
||||||
|
display: block;
|
||||||
|
line-height: 26px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
54
modeler/src/views/decision/algorithm/types.ts
Normal file
54
modeler/src/views/decision/algorithm/types.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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 { NullableString, PageableResponse } from '@/types';
|
||||||
|
|
||||||
|
export interface AlgorithmParam {
|
||||||
|
id: number,
|
||||||
|
algorithmId: number,
|
||||||
|
// 参数名
|
||||||
|
paramName: NullableString,
|
||||||
|
// 默认值
|
||||||
|
defaultValue: NullableString,
|
||||||
|
// 描述
|
||||||
|
description: NullableString,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlgorithmConfig {
|
||||||
|
name: NullableString,
|
||||||
|
operation: NullableString,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Algorithm {
|
||||||
|
|
||||||
|
id: number,
|
||||||
|
// 算法名称
|
||||||
|
name: NullableString,
|
||||||
|
// 业务类型
|
||||||
|
type: NullableString | undefined,
|
||||||
|
// 算法文件路径
|
||||||
|
codePath: NullableString,
|
||||||
|
// 算法描述
|
||||||
|
description: NullableString,
|
||||||
|
// 算法配置
|
||||||
|
algoConfig: NullableString,
|
||||||
|
// 算法配置
|
||||||
|
algoConfigList: AlgorithmConfig[],
|
||||||
|
// 算法参数定义信息
|
||||||
|
algorithmParamList: AlgorithmParam[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlgorithmRequest extends Algorithm {
|
||||||
|
pageNum: number,
|
||||||
|
pageSize: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlgorithmPageableResponse extends PageableResponse<Algorithm> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { HttpRequestClient } from '@/utils/request';
|
import { HttpRequestClient } from '@/utils/request';
|
||||||
import type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, NodeTemplatesResponse } from './types';
|
import type { BehaviorTree, BehaviorTreeDetailsResponse, BehaviorTreePageResponse, BehaviorTreeRequest, NodeTemplatesResponse } from './types';
|
||||||
import type { BasicResponse } from '@/types';
|
import type { BasicResponse } from '@/types';
|
||||||
|
|
||||||
const req = HttpRequestClient.create<BasicResponse>({
|
const req = HttpRequestClient.create<BasicResponse>({
|
||||||
@@ -19,7 +19,7 @@ export const findNodeTemplates = (): Promise<NodeTemplatesResponse> => {
|
|||||||
return req.get('/system/nodetemplate/all');
|
return req.get('/system/nodetemplate/all');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findTreesByQuery = (query: Partial<BehaviorTree> = {}): Promise<BehaviorTreePageResponse> => {
|
export const findTreesByQuery = (query: Partial<BehaviorTreeRequest> = {}): Promise<BehaviorTreePageResponse> => {
|
||||||
return req.get<BehaviorTreePageResponse>('/system/behaviortree/list', query);
|
return req.get<BehaviorTreePageResponse>('/system/behaviortree/list', query);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,6 +27,9 @@ export const findOneTreeById = (id: number): Promise<BehaviorTreeDetailsResponse
|
|||||||
return req.get(`/system/behaviortree/${id}`);
|
return req.get(`/system/behaviortree/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteOneTreeById = (id: number): Promise<BehaviorTreeDetailsResponse> => {
|
||||||
|
return req.delete(`/system/behaviortree/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
export const updateTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
export const updateTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
||||||
return req.postJson(`/system/behaviortree`, rt);
|
return req.postJson(`/system/behaviortree`, rt);
|
||||||
@@ -35,18 +38,3 @@ export const updateTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> =>
|
|||||||
export const createTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
export const createTree = (rt: Partial<BehaviorTree>): Promise<BasicResponse> => {
|
||||||
return req.putJson(`/system/behaviortree`, rt);
|
return req.putJson(`/system/behaviortree`, rt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// export const findOneTreeById = (id: number): Promise<TreeModelDetailsResponse> => {
|
|
||||||
// return req.postJson(`/tree-details`,{
|
|
||||||
// tree_id: id
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// export const updateTree = (rt: Partial<TreeModelGraph>): Promise<BasicResponse> => {
|
|
||||||
// return req.postJson('/update-tree', rt);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// export const createTree = (rt: Partial<TreeModelGraph>): Promise<BasicResponse> => {
|
|
||||||
// return req.postJson('/update-tree', rt);
|
|
||||||
// };
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NullableString } from '@/types';
|
import type { NullableString } from '@/types';
|
||||||
import type { NodeSetting } from '@/views/decision/types';
|
|
||||||
|
|
||||||
export interface DraggableElement {
|
export interface DraggableElement {
|
||||||
id: number | null,
|
id: number | null,
|
||||||
@@ -19,12 +18,23 @@ export interface DraggableElement {
|
|||||||
draggable: boolean,
|
draggable: boolean,
|
||||||
parent?: DraggableElement,
|
parent?: DraggableElement,
|
||||||
children: DraggableElement[]
|
children: DraggableElement[]
|
||||||
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ElementStatus = 'default' | 'success' | 'failed' | 'running' | string | null
|
export type ElementStatus = 'default' | 'success' | 'failed' | 'running' | string | null
|
||||||
|
|
||||||
export interface ElementPosition {
|
export interface ElementParameter {
|
||||||
|
id: number,
|
||||||
|
templateId: number,
|
||||||
|
paramKey: NullableString,
|
||||||
|
dataType: NullableString,
|
||||||
|
defaultValue: NullableString,
|
||||||
|
description: NullableString,
|
||||||
|
templateType: NullableString,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GraphPosition {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
@@ -37,57 +47,57 @@ export interface ElementVariable {
|
|||||||
unit: NullableString;
|
unit: NullableString;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BaseElement {
|
export interface GraphTaskRect {
|
||||||
key: string;
|
|
||||||
name: string;
|
|
||||||
type: string;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
position: ElementPosition;
|
|
||||||
category: NullableString;
|
|
||||||
element?: DraggableElement;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskNodeRect {
|
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
x?: number;
|
x?: number;
|
||||||
y?: number;
|
y?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskNodeElement extends BaseElement {
|
export interface BaseElement {
|
||||||
template: number;
|
id: number;
|
||||||
inputs: any;
|
key: NullableString;
|
||||||
outputs: any;
|
name: NullableString;
|
||||||
variables: ElementVariable[];
|
description: NullableString;
|
||||||
parameters: Record<any, any>;
|
type: NullableString;
|
||||||
|
width: number;
|
||||||
children?: TaskNodeElement[],
|
height: number;
|
||||||
|
position: GraphPosition;
|
||||||
|
category: NullableString;
|
||||||
|
element?: DraggableElement;
|
||||||
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingTaskNodeElement extends TaskNodeElement {
|
export interface GraphTaskElement extends BaseElement {
|
||||||
settings: NodeSetting[];
|
template: number;
|
||||||
|
templateType: NullableString,
|
||||||
|
inputs: any;
|
||||||
|
outputs: any;
|
||||||
|
variables: ElementVariable[];
|
||||||
|
parameters: ElementParameter[];
|
||||||
|
children?: GraphTaskElement[],
|
||||||
|
|
||||||
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModelElement extends BaseElement {
|
export interface ModelElement extends BaseElement {
|
||||||
edges: EdgeNodeElement[];
|
edges: GraphEdgeElement[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EdgeNodeElement {
|
export interface GraphEdgeElement {
|
||||||
|
id: number;
|
||||||
key: NullableString;
|
key: NullableString;
|
||||||
source: NullableString;
|
source: NullableString;
|
||||||
sourceName: NullableString;
|
|
||||||
target: NullableString;
|
target: NullableString;
|
||||||
targetName: NullableString;
|
|
||||||
attrs: Record<any, any>;
|
attrs: Record<any, any>;
|
||||||
router: Record<any, any>;
|
router: Record<any, any>;
|
||||||
connector: any;
|
connector: any;
|
||||||
|
|
||||||
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeGraph {
|
export interface NodeGraph {
|
||||||
edges: EdgeNodeElement[];
|
edges: GraphEdgeElement[];
|
||||||
nodes: TaskNodeElement[];
|
nodes: GraphTaskElement[];
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
import { Edge, Graph, Path, Selection } from '@antv/x6';
|
import { Edge, Graph, Path, Selection } from '@antv/x6';
|
||||||
import type { ModelElement } from './element';
|
import type { ModelElement } from './element';
|
||||||
import type { Connecting } from '@antv/x6/lib/graph/options';
|
import type { Connecting } from '@antv/x6/lib/graph/options';
|
||||||
import {createLineOptions} from './line'
|
import { createLineOptions } from './line';
|
||||||
|
|
||||||
Graph.registerConnector(
|
Graph.registerConnector(
|
||||||
'sequenceFlowConnector',
|
'sequenceFlowConnector',
|
||||||
@@ -55,7 +55,7 @@ export const createGraphConnectingAttributes = (): Partial<Connecting> => {
|
|||||||
attrs: lineOptions.attrs,
|
attrs: lineOptions.attrs,
|
||||||
animation: lineOptions.animation,
|
animation: lineOptions.animation,
|
||||||
markup: lineOptions.markup,
|
markup: lineOptions.markup,
|
||||||
})
|
});
|
||||||
return edge;
|
return edge;
|
||||||
},
|
},
|
||||||
validateConnection(this: Graph, { sourceCell, targetCell }) {
|
validateConnection(this: Graph, { sourceCell, targetCell }) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import type { NodeViewPositionEventArgs } from '@antv/x6/es/view/node/type';
|
|||||||
import { createGraphCanvas } from './graph';
|
import { createGraphCanvas } from './graph';
|
||||||
import { EventListener } from '@/utils/event';
|
import { EventListener } from '@/utils/event';
|
||||||
import type { ModelElement } from './element';
|
import type { ModelElement } from './element';
|
||||||
|
|
||||||
// import {createLineOptions} from './line'
|
// import {createLineOptions} from './line'
|
||||||
|
|
||||||
export interface UseGraphCanvas {
|
export interface UseGraphCanvas {
|
||||||
@@ -155,6 +156,7 @@ export const useGraphCanvas = (readonly: boolean = false): UseGraphCanvas => {
|
|||||||
|
|
||||||
if (!existingEdge) {
|
if (!existingEdge) {
|
||||||
sourceEdges.push({
|
sourceEdges.push({
|
||||||
|
id: sourceData.id,
|
||||||
key: edge.id,
|
key: edge.id,
|
||||||
source: sourceNode.id,
|
source: sourceNode.id,
|
||||||
sourceName: sourceData.name,
|
sourceName: sourceData.name,
|
||||||
@@ -162,7 +164,7 @@ export const useGraphCanvas = (readonly: boolean = false): UseGraphCanvas => {
|
|||||||
router: {},
|
router: {},
|
||||||
attrs: {},
|
attrs: {},
|
||||||
target: targetNode.id,
|
target: targetNode.id,
|
||||||
targetName: targetData.name
|
targetName: targetData.name,
|
||||||
});
|
});
|
||||||
sourceNode.replaceData({ ...sourceData, edges: sourceEdges });
|
sourceNode.replaceData({ ...sourceData, edges: sourceEdges });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,5 +43,5 @@ export const createLineOptions = (): any => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
@@ -9,64 +9,25 @@
|
|||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<a-space>
|
<a-space>
|
||||||
<span class="ks-designer-node-icon"></span>
|
|
||||||
<span class="ks-designer-node-title">{{ element?.name ?? '-' }}</span>
|
<span class="ks-designer-node-title">{{ element?.name ?? '-' }}</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 节点内容区域 -->
|
|
||||||
<div class="w-full">
|
|
||||||
<div class="ks-designer-node-content">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in element?.children || []"
|
|
||||||
:key="item.id || index"
|
|
||||||
class="ks-designer-node-row"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
:data-port="`in-${item.id || index}`"
|
|
||||||
:title="`入桩: ${item.name}`"
|
|
||||||
class="port port-in"
|
|
||||||
magnet="passive"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<!-- child名称 -->
|
|
||||||
<div class="ks-designer-node-name">
|
|
||||||
{{ item.name }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧出桩:只能作为连线源 -->
|
|
||||||
<div
|
|
||||||
:data-port="`out-${item.id || index}`"
|
|
||||||
:title="`出桩: ${item.name}`"
|
|
||||||
class="port port-out"
|
|
||||||
magnet="active"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="!(element?.children && element?.children?.length > 0)" class="ks-designer-node-row">
|
|
||||||
<div class="port port-in" data-port="in-0" magnet="passive"></div>
|
<div class="port port-in" data-port="in-0" magnet="passive"></div>
|
||||||
<div class="ks-designer-node-name" v-if="element?.category !== 'component'">
|
<div class="w-full">
|
||||||
{{ element?.name ?? '-' }}
|
<a-tooltip v-if="(element?.description ?? (element?.name ?? '-')).length >= 38">
|
||||||
</div>
|
<template #title>
|
||||||
<div class="ks-designer-node-name" v-else>
|
{{ element?.description ?? element?.name }}
|
||||||
<p>隐藏纬度: {{ element?.parameters?.hiddenLatitude ?? '-' }}</p>
|
</template>
|
||||||
<p>激活函数: {{ element?.parameters?.activationFunction ?? '-' }}</p>
|
<p>
|
||||||
|
{{ substring(element?.description ?? (element?.name ?? '-'), 40) }}
|
||||||
|
</p>
|
||||||
|
</a-tooltip>
|
||||||
|
<p v-else>
|
||||||
|
{{ substring(element?.description ?? (element?.name ?? '-'), 40) }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="port port-out" data-port="out-0" magnet="active"></div>
|
<div class="port port-out" data-port="out-0" magnet="active"></div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div class="w-full" v-else>-->
|
|
||||||
<!-- <div class="ks-designer-node-content">-->
|
|
||||||
<!-- <div class="port port-in" data-port="in-0" magnet="passive"></div>-->
|
|
||||||
<!-- <div class="ks-designer-node-name">-->
|
|
||||||
<!-- <p>隐藏纬度: {{ element?.parameters?.hiddenLatitude ?? '-' }}</p>-->
|
|
||||||
<!-- <p>激活函数: {{ element?.parameters?.activationFunction ?? '-' }}</p>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="port port-out" data-port="out-0" magnet="active"></div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
@@ -88,6 +49,7 @@ import { elementProps } from './props';
|
|||||||
import type { ModelElement } from './element';
|
import type { ModelElement } from './element';
|
||||||
import { DeleteOutlined, SettingOutlined } from '@ant-design/icons-vue';
|
import { DeleteOutlined, SettingOutlined } from '@ant-design/icons-vue';
|
||||||
import type { Graph } from '@antv/x6';
|
import type { Graph } from '@antv/x6';
|
||||||
|
import { substring } from '@/utils/strings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ModelElement',
|
name: 'ModelElement',
|
||||||
@@ -157,6 +119,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
element,
|
element,
|
||||||
|
substring,
|
||||||
handleMenuClick,
|
handleMenuClick,
|
||||||
handleVisibleChange,
|
handleVisibleChange,
|
||||||
};
|
};
|
||||||
@@ -166,23 +129,37 @@ export default defineComponent({
|
|||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.ks-designer-node {
|
.ks-designer-node {
|
||||||
background: linear-gradient(150deg, #093866 1%, #1f69b3 55%);
|
background: linear-gradient(150deg, rgba(108, 99, 255) 1%, rgba(108, 99, 255) 100%);
|
||||||
border: 0;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background: #1e2533;
|
||||||
|
border: 1px solid #4a7aff;
|
||||||
|
|
||||||
|
border: 2px solid #000000;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 2px solid #4a7aff;
|
||||||
|
box-shadow: 0 0 10px rgba(74, 122, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
.ant-card-head {
|
.ant-card-head {
|
||||||
border: 0;
|
border: 0;
|
||||||
height: 38px;
|
height: 25px;
|
||||||
min-height: 38px;
|
min-height: 25px;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
color: #ddd;
|
color: #fff;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
background: linear-gradient(to bottom, #3a4c70, #2d3a56);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
background: linear-gradient(to bottom, rgba(108, 99, 255, 0.15), rgba(108, 99, 255, 0.05));
|
||||||
|
background: url('@/assets/icons/bg-node-head.png') center / 100% 100%;
|
||||||
|
//background: linear-gradient(to bottom, rgb(234 234 234 / 20%), rgb(191 191 191 / 58%));
|
||||||
}
|
}
|
||||||
|
|
||||||
.ks-designer-node-icon {
|
.ks-designer-node-icon {
|
||||||
@@ -197,136 +174,163 @@ export default defineComponent({
|
|||||||
|
|
||||||
.ks-designer-node-title {
|
.ks-designer-node-title {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
color: #fff;
|
||||||
|
color: #312e2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-card-body {
|
.ant-card-body {
|
||||||
color: #fff;
|
color: #f5f5f5;
|
||||||
height: calc(100% - 38px);
|
height: calc(100% - 25px);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 8px 15px;
|
padding: 8px 15px !important;
|
||||||
overflow-y: auto;
|
border-top: 1px solid rgba(108, 99, 255, 0.5);
|
||||||
border-top: 1px solid #195693;
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-shadow: 0 0 10px rgba(74, 122, 255, 0.3);
|
||||||
|
|
||||||
|
white-space: normal; // 恢复默认的换行行为
|
||||||
|
word-wrap: break-word; // 允许长单词换行
|
||||||
|
word-break: break-all; // 允许在任意字符处换行
|
||||||
|
line-height: 1.4; // 增加行高提升可读性
|
||||||
|
box-shadow: 0 0 10px rgba(74, 122, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.ks-designer-task-node {
|
// model/task 节点:浅紫渐变
|
||||||
background: linear-gradient(150deg, #20421b 1%, #4a6646 55%);
|
//&.ks-designer-model-node,
|
||||||
|
//&.ks-designer-task-node {
|
||||||
.ant-card-body {
|
// background: linear-gradient(150deg, rgba(92,84,247,0.9) 1%, rgba(115,108,250,0.7) 55%);
|
||||||
border-top: 1px solid #466741;
|
//
|
||||||
}
|
// .ant-card-body {
|
||||||
|
// border-top: 1px solid rgba(92,84,247,0.5);
|
||||||
.ks-designer-node-icon {
|
// }
|
||||||
background: url('@/assets/icons/m-02.png') center / 100% 100%;
|
//
|
||||||
}
|
// .ks-designer-node-icon {
|
||||||
}
|
// background: url('@/assets/icons/m-02.png') center / 100% 100%;
|
||||||
&.ks-designer-input-node {
|
// }
|
||||||
background: linear-gradient(150deg, #083058 1%, #1e5d9b 55%);
|
//}
|
||||||
|
//
|
||||||
.ant-card-body {
|
//// input 节点:深紫渐变
|
||||||
border-top: 1px solid #105ca7;
|
//&.ks-designer-input-node {
|
||||||
}
|
// background: linear-gradient(150deg, rgba(82,73,245,0.9) 1%, rgba(105,98,249,0.7) 55%);
|
||||||
|
//
|
||||||
.ks-designer-node-icon {
|
// .ant-card-body {
|
||||||
background: url('@/assets/icons/icon-model-input.png') center / 100% 100%;
|
// border-top: 1px solid rgba(82,73,245,0.5);
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// .ks-designer-node-icon {
|
||||||
&.ks-designer-action-node {
|
// background: url('@/assets/icons/icon-model-input.png') center / 100% 100%;
|
||||||
background: linear-gradient(150deg, #343207 1%, #485010 55%);
|
// }
|
||||||
|
//}
|
||||||
.ant-card-body {
|
//
|
||||||
border-top: 1px solid #59550e;
|
//// action 节点:亮紫渐变(对应之前的action-node)
|
||||||
}
|
//&.ks-designer-action-node {
|
||||||
|
// background: linear-gradient(150deg, rgba(108,99,255,0.9) 1%, rgba(140,133,255,0.7) 55%);
|
||||||
.ks-designer-node-icon {
|
//
|
||||||
background: url('@/assets/icons/bg-fk-point.png') center / 100% 100%;
|
// .ant-card-body {
|
||||||
}
|
// border-top: 1px solid rgba(108,99,255,0.5);
|
||||||
}
|
// }
|
||||||
&.ks-designer-component-node {
|
//
|
||||||
background: linear-gradient(150deg, #06226b 1%, #1a43a7 55%);
|
// .ks-designer-node-icon {
|
||||||
|
// background: url('@/assets/icons/bg-fk-point.png') center / 100% 100%;
|
||||||
.ant-card-body {
|
// }
|
||||||
border-top: 1px solid #26448c;
|
//}
|
||||||
}
|
//
|
||||||
}
|
//// precondition/component 节点:蓝紫渐变
|
||||||
|
//&.ks-designer-precondition-node,
|
||||||
&.ks-designer-control-node {
|
//&.ks-designer-component-node {
|
||||||
background: linear-gradient(150deg, #1d4f32 1%, #326a5d 55%);
|
// background: linear-gradient(150deg, rgba(72,64,243,0.9) 1%, rgba(95,88,248,0.7) 55%);
|
||||||
|
//
|
||||||
.ant-card-body {
|
// .ant-card-body {
|
||||||
border-top: 1px solid #326a5d;
|
// border-top: 1px solid rgba(72,64,243,0.5);
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
.ks-designer-node-icon {
|
//
|
||||||
background: url('@/assets/icons/bg-model-builder-card-title.png') center / 100% 100%;
|
//// select/control 节点:浅蓝紫渐变
|
||||||
}
|
//&.ks-designer-select-node,
|
||||||
}
|
//&.ks-designer-control-node {
|
||||||
|
// background: linear-gradient(150deg, rgba(90,82,246,0.9) 1%, rgba(118,111,251,0.7) 55%);
|
||||||
|
//
|
||||||
|
// .ant-card-body {
|
||||||
|
// border-top: 1px solid rgba(90,82,246,0.5);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// .ks-designer-node-icon {
|
||||||
|
// background: url('@/assets/icons/bg-model-builder-card-title.png') center / 100% 100%;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
// 连接桩容器样式
|
// 连接桩容器样式
|
||||||
.ks-designer-node-content {
|
.ks-designer-node-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 4px; // 每个child行之间的间距
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每个child行(包含左右桩+文本)
|
|
||||||
.ks-designer-node-row {
|
.ks-designer-node-row {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 24px; // 固定行高,保证桩对齐
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 连接桩基础样式
|
|
||||||
.port {
|
.port {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
box-shadow: 0 0 0 2px rgb(74 114 214 / 80%);
|
box-shadow: 0 0 0 2px rgb(108, 99, 255, 0.8);
|
||||||
z-index: 10; // 确保桩在最上层
|
z-index: 10;
|
||||||
// X6 标记为可连线的磁体
|
|
||||||
magnet: true;
|
magnet: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 左侧入桩样式
|
// 左侧入桩样式
|
||||||
.port-in {
|
.port-in {
|
||||||
background-color: #093866; // 青色:入桩
|
background-color: #6C63FF;
|
||||||
margin-right: 8px; // 与文本的间距
|
margin-right: 8px;
|
||||||
//border: 1px solid #093866;
|
//border: 1px solid #093866;
|
||||||
// X6 只能作为连线目标(入)
|
|
||||||
magnet: passive;
|
magnet: passive;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
width: 20px;
|
width: 15px;
|
||||||
height: 20px;
|
height: 15px;
|
||||||
display: block;
|
display: block;
|
||||||
background: url('@/assets/icons/point.svg') center / 100% 100%;
|
background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
//top: 7px;
|
||||||
|
left: -8px;
|
||||||
|
top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 右侧出桩样式
|
|
||||||
.port-out {
|
.port-out {
|
||||||
margin-left: 8px; // 与文本的间距
|
margin-left: 8px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
// X6 只能作为连线源(出)
|
|
||||||
magnet: active;
|
magnet: active;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
width: 20px;
|
width: 15px;
|
||||||
height: 20px;
|
height: 15px;
|
||||||
display: block;
|
display: block;
|
||||||
background: url('@/assets/icons/arrow-right.svg') center / 100% 100%;
|
background: url('@/assets/icons/point.svg') center / 100% 100%;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
//right: 8px;
|
||||||
|
//top: 7px;
|
||||||
|
top: 50%;
|
||||||
|
right: -12px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 节点文本样式
|
// 节点文本样式
|
||||||
.ks-designer-node-name {
|
.ks-designer-node-name {
|
||||||
flex: 1; // 占满中间空间
|
flex: 1;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
//white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -21,7 +21,7 @@ import ModelElement from './node.vue';
|
|||||||
export const registerNodeElement = () => {
|
export const registerNodeElement = () => {
|
||||||
console.info('registerNodeElement');
|
console.info('registerNodeElement');
|
||||||
register({
|
register({
|
||||||
shape: 'node',
|
shape: 'task',
|
||||||
component: ModelElement,
|
component: ModelElement,
|
||||||
width: 120,
|
width: 120,
|
||||||
attrs: {
|
attrs: {
|
||||||
|
|||||||
@@ -6,20 +6,20 @@
|
|||||||
* For the full copyright and license information, please view the LICENSE file
|
* For the full copyright and license information, please view the LICENSE file
|
||||||
* that was distributed with this source code.
|
* that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
import type { EdgeNodeElement, NodeGraph, TaskNodeElement } from './element';
|
import type { GraphEdgeElement, GraphTaskElement, NodeGraph } from './element';
|
||||||
import { Edge, Graph, Node } from '@antv/x6';
|
import { Edge, Graph, Node } from '@antv/x6';
|
||||||
|
|
||||||
export const defaultHeight: Record<string, number> = {
|
export const defaultHeight: Record<string, number> = {
|
||||||
component: 110,
|
component: 110,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createModelNode = (element: TaskNodeElement, width: number = 250, height: number = 120): any => {
|
export const createGraphTaskElement = (element: GraphTaskElement, width: number = 250, height: number = 120): any => {
|
||||||
let realHeight = defaultHeight[element.category as string];
|
let realHeight = defaultHeight[element.category as string];
|
||||||
if (!realHeight) {
|
if (!realHeight) {
|
||||||
realHeight = 120;
|
realHeight = 120;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
shape: 'node',
|
shape: 'task',
|
||||||
id: element.key,
|
id: element.key,
|
||||||
position: {
|
position: {
|
||||||
x: element.position?.x || 0,
|
x: element.position?.x || 0,
|
||||||
@@ -38,13 +38,13 @@ export const createModelNode = (element: TaskNodeElement, width: number = 250, h
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const resolveNodeTaskElements = (graph: Graph): TaskNodeElement[] => {
|
export const resolveGraphTaskElements = (graph: Graph): GraphTaskElement[] => {
|
||||||
const taskElements: TaskNodeElement[] = [];
|
const taskElements: GraphTaskElement[] = [];
|
||||||
if (graph) {
|
if (graph) {
|
||||||
const nodes = graph?.getNodes() as Node[];
|
const nodes = graph?.getNodes() as Node[];
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
const nodeData = node.getData() as TaskNodeElement;
|
const nodeData = node.getData() as GraphTaskElement;
|
||||||
const newElement = {
|
const newElement = {
|
||||||
...nodeData,
|
...nodeData,
|
||||||
key: node.id,
|
key: node.id,
|
||||||
@@ -59,13 +59,13 @@ export const resolveNodeTaskElements = (graph: Graph): TaskNodeElement[] => {
|
|||||||
return taskElements;
|
return taskElements;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const resolveNodeEdgeElements = (graph: Graph): EdgeNodeElement[] => {
|
export const resolveGraphEdgeElements = (graph: Graph): GraphEdgeElement[] => {
|
||||||
const edgeElements: EdgeNodeElement[] = [];
|
const edgeElements: GraphEdgeElement[] = [];
|
||||||
if (graph) {
|
if (graph) {
|
||||||
const graphEdges = graph?.getEdges() ?? [] as Edge[];
|
const graphEdges = graph?.getEdges() ?? [] as Edge[];
|
||||||
if (graphEdges) {
|
if (graphEdges) {
|
||||||
graphEdges.forEach(edge => {
|
graphEdges.forEach(edge => {
|
||||||
const nodeData = edge.getData() as TaskNodeElement;
|
const nodeData = edge.getData() as GraphTaskElement;
|
||||||
edgeElements.push({
|
edgeElements.push({
|
||||||
id: nodeData?.id ?? 0,
|
id: nodeData?.id ?? 0,
|
||||||
key: edge.id,
|
key: edge.id,
|
||||||
@@ -84,8 +84,8 @@ export const resolveNodeEdgeElements = (graph: Graph): EdgeNodeElement[] => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const resolveNodeGraph = (graph: Graph): NodeGraph => {
|
export const resolveNodeGraph = (graph: Graph): NodeGraph => {
|
||||||
const nodes: TaskNodeElement[] = resolveNodeTaskElements(graph);
|
const nodes: GraphTaskElement[] = resolveGraphTaskElements(graph);
|
||||||
const edges: EdgeNodeElement[] = resolveNodeEdgeElements(graph);
|
const edges: GraphEdgeElement[] = resolveGraphEdgeElements(graph);
|
||||||
return {
|
return {
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
@@ -94,7 +94,7 @@ export const resolveNodeGraph = (graph: Graph): NodeGraph => {
|
|||||||
|
|
||||||
export const hasElements = (graph: Graph): boolean => {
|
export const hasElements = (graph: Graph): boolean => {
|
||||||
if (graph) {
|
if (graph) {
|
||||||
const taskElements: TaskNodeElement[] = resolveNodeTaskElements(graph);
|
const taskElements: GraphTaskElement[] = resolveGraphTaskElements(graph);
|
||||||
return taskElements.length > 0;
|
return taskElements.length > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -102,7 +102,7 @@ export const hasElements = (graph: Graph): boolean => {
|
|||||||
|
|
||||||
export const hasRootElementNode = (graph: Graph): boolean => {
|
export const hasRootElementNode = (graph: Graph): boolean => {
|
||||||
if (graph) {
|
if (graph) {
|
||||||
const taskElements: TaskNodeElement[] = resolveNodeTaskElements(graph);
|
const taskElements: GraphTaskElement[] = resolveGraphTaskElements(graph);
|
||||||
return taskElements.filter(e => e.type === 'root').length === 1;
|
return taskElements.filter(e => e.type === 'root').length === 1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
<div class="ks-model-builder-body">
|
<div class="ks-model-builder-body">
|
||||||
<div class="ks-model-builder-left">
|
<div class="ks-model-builder-left">
|
||||||
<TressCard
|
<TressCard
|
||||||
|
ref="treesCardRef"
|
||||||
|
@create-tree="handleCreateTree"
|
||||||
@select-tree="handleSelectTree"
|
@select-tree="handleSelectTree"
|
||||||
/>
|
/>
|
||||||
<NodesCard
|
<NodesCard
|
||||||
@@ -17,20 +19,24 @@
|
|||||||
<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 && currentBehaviorTree" placement="top">
|
<!-- <a-tooltip v-if="graph && currentBehaviorTree" placement="top">-->
|
||||||
<template #title>
|
<!-- <template #title>-->
|
||||||
保存
|
<!-- 保存-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
<a-popconfirm
|
<!-- <a-popconfirm-->
|
||||||
title="确定保存?"
|
<!-- title="确定保存?"-->
|
||||||
@confirm="handleSave"
|
<!-- @confirm="handleSave"-->
|
||||||
>
|
<!-- >-->
|
||||||
<a-button class="ks-model-builder-save" size="small">
|
<!-- <a-button class="ks-model-builder-save" size="small">-->
|
||||||
|
<!-- <CheckOutlined />-->
|
||||||
|
<!-- <span>保存</span>-->
|
||||||
|
<!-- </a-button>-->
|
||||||
|
<!-- </a-popconfirm>-->
|
||||||
|
<!-- </a-tooltip>-->
|
||||||
|
<a-button v-if="graph && currentBehaviorTree" class="ks-model-builder-save" size="small" @click="handleSave">
|
||||||
<CheckOutlined />
|
<CheckOutlined />
|
||||||
<span>保存</span>
|
<span>保存</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<!-- 画布容器,添加拖放事件 -->
|
<!-- 画布容器,添加拖放事件 -->
|
||||||
@@ -46,10 +52,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<Properties
|
<Properties
|
||||||
v-if="graph"
|
v-if="graph"
|
||||||
@update-element="handleUpdateElement"
|
|
||||||
:element="selectedNodeTaskElement"
|
:element="selectedNodeTaskElement"
|
||||||
:graph="graph as any"
|
:graph="graph as any"
|
||||||
:node="selectedModelNode as any" />
|
:node="selectedModelNode as any"
|
||||||
|
:tree="currentBehaviorTree"
|
||||||
|
:tree-editing="currentTreeEditing"
|
||||||
|
@update-element="handleUpdateElement" />
|
||||||
</div>
|
</div>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
@@ -66,16 +74,16 @@ 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 Properties from './properties.vue';
|
import Properties from './properties.vue';
|
||||||
|
import type { BehaviorTree, NodeTemplate } from './types';
|
||||||
|
import type { GraphTaskElement, NodeGraph } from './builder/element';
|
||||||
import { useGraphCanvas } from './builder/hooks';
|
import { useGraphCanvas } from './builder/hooks';
|
||||||
import { registerNodeElement } from './builder/register';
|
import { registerNodeElement } from './builder/register';
|
||||||
import type { BehaviorTree, NodeTemplate } from './types';
|
import { createLineOptions } from './builder/line';
|
||||||
import type { NodeGraph, SettingTaskNodeElement, TaskNodeElement } from './builder/element';
|
|
||||||
import { createTree, findOneTreeById, updateTree } from './api';
|
import { createTree, findOneTreeById, updateTree } from './api';
|
||||||
import { createModelNode, hasElements, hasRootElementNode, resolveNodeGraph } from './builder/utils';
|
import { createGraphTaskElement, hasElements, hasRootElementNode, resolveNodeGraph } from './builder/utils';
|
||||||
import { createTaskNodeElementFromTemplate } from './utils/node';
|
import { createGraphTaskElementFromTemplate } from './utils/node';
|
||||||
import TressCard from './trees-card.vue';
|
import TressCard from './trees-card.vue';
|
||||||
import NodesCard from './nodes-card.vue';
|
import NodesCard from './nodes-card.vue';
|
||||||
import { createLineOptions } from '@/views/decision/builder/line.ts';
|
|
||||||
|
|
||||||
const TeleportContainer = defineComponent(getTeleport());
|
const TeleportContainer = defineComponent(getTeleport());
|
||||||
|
|
||||||
@@ -100,11 +108,13 @@ 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 currentTreeEditing = ref<boolean>(false);
|
||||||
const currentBehaviorTree = ref<BehaviorTree | null>(null);
|
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<GraphTaskElement | null>(null);
|
||||||
const changed = ref<boolean>(false)
|
const changed = ref<boolean>(false);
|
||||||
|
const treesCardRef = ref<InstanceType<typeof TressCard> | null>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleGraphEvent,
|
handleGraphEvent,
|
||||||
@@ -154,6 +164,7 @@ export default defineComponent({
|
|||||||
safePreventDefault(e);
|
safePreventDefault(e);
|
||||||
safeStopPropagation(e);
|
safeStopPropagation(e);
|
||||||
isDraggingOver.value = false;
|
isDraggingOver.value = false;
|
||||||
|
currentTreeEditing.value = false;
|
||||||
|
|
||||||
if (!currentBehaviorTree.value) {
|
if (!currentBehaviorTree.value) {
|
||||||
message.error('请先选择或者创建行为树.');
|
message.error('请先选择或者创建行为树.');
|
||||||
@@ -188,9 +199,9 @@ export default defineComponent({
|
|||||||
console.log('放置节点:', { ...template, x, y });
|
console.log('放置节点:', { ...template, x, y });
|
||||||
|
|
||||||
// 创建节点数据
|
// 创建节点数据
|
||||||
const settingTaskElement: SettingTaskNodeElement = createTaskNodeElementFromTemplate(template, { x, y });
|
const settingTaskElement: GraphTaskElement = createGraphTaskElementFromTemplate(template, { x, y });
|
||||||
// 创建节点
|
// 创建节点
|
||||||
const settingTaskNode = createModelNode(settingTaskElement);
|
const settingTaskNode = createGraphTaskElement(settingTaskElement);
|
||||||
console.info('create settingTaskNode: ', settingTaskElement, settingTaskNode);
|
console.info('create settingTaskNode: ', settingTaskElement, settingTaskNode);
|
||||||
|
|
||||||
// 将节点添加到画布
|
// 将节点添加到画布
|
||||||
@@ -224,6 +235,7 @@ export default defineComponent({
|
|||||||
...r.data,
|
...r.data,
|
||||||
graph: nodeGraph,
|
graph: nodeGraph,
|
||||||
};
|
};
|
||||||
|
currentTreeEditing.value = true;
|
||||||
createElements();
|
createElements();
|
||||||
} else {
|
} else {
|
||||||
message.error(r.msg ?? '行为树不存在.');
|
message.error(r.msg ?? '行为树不存在.');
|
||||||
@@ -233,11 +245,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
const createElements = () => {
|
const createElements = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
try {
|
||||||
graph.value?.clearCells();
|
graph.value?.clearCells();
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error('clear cells error, cause:', e);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
if (currentBehaviorTree.value?.graph && graph.value) {
|
if (currentBehaviorTree.value?.graph && graph.value) {
|
||||||
if (currentBehaviorTree.value?.graph.nodes) {
|
if (currentBehaviorTree.value?.graph.nodes) {
|
||||||
currentBehaviorTree.value?.graph.nodes.forEach(ele => {
|
currentBehaviorTree.value?.graph.nodes.forEach(ele => {
|
||||||
const node = createModelNode(ele as TaskNodeElement);
|
const node = createGraphTaskElement(ele as GraphTaskElement);
|
||||||
console.info('create node: ', ele);
|
console.info('create node: ', ele);
|
||||||
// 将节点添加到画布
|
// 将节点添加到画布
|
||||||
graph.value?.addNode(node as Node);
|
graph.value?.addNode(node as Node);
|
||||||
@@ -255,9 +272,34 @@ export default defineComponent({
|
|||||||
}, 100); // 延迟一会儿,免得连线错位
|
}, 100); // 延迟一会儿,免得连线错位
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCreateTree = () => {
|
||||||
|
currentBehaviorTree.value = {
|
||||||
|
id: 0,
|
||||||
|
name: '行为树',
|
||||||
|
description: null,
|
||||||
|
englishName: null,
|
||||||
|
xmlContent: null,
|
||||||
|
createdAt: null,
|
||||||
|
graph: {
|
||||||
|
edges: [],
|
||||||
|
nodes: [],
|
||||||
|
},
|
||||||
|
updatedAt: null,
|
||||||
|
};
|
||||||
|
currentNodeGraph.value = {
|
||||||
|
edges: [],
|
||||||
|
nodes: [],
|
||||||
|
};
|
||||||
|
selectedModelNode.value = null;
|
||||||
|
selectedNodeTaskElement.value = null;
|
||||||
|
|
||||||
|
createElements();
|
||||||
|
};
|
||||||
|
|
||||||
// 初始化X6画布
|
// 初始化X6画布
|
||||||
const initGraph = () => {
|
const initGraph = () => {
|
||||||
if (!canvas.value) {
|
if (!canvas.value) {
|
||||||
@@ -275,12 +317,18 @@ export default defineComponent({
|
|||||||
currentZoom.value = sx;
|
currentZoom.value = sx;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handleGraphEvent('blank:click', () => {
|
||||||
|
selectedModelNode.value = null;
|
||||||
|
selectedNodeTaskElement.value = null;
|
||||||
|
currentTreeEditing.value = null !== currentBehaviorTree.value;
|
||||||
|
});
|
||||||
|
|
||||||
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 SettingTaskNodeElement;
|
const newElement = node.getData() as GraphTaskElement;
|
||||||
|
|
||||||
selectedModelNode.value = node;
|
selectedModelNode.value = node;
|
||||||
selectedNodeTaskElement.value = JSON.parse(JSON.stringify(newElement || {})) as SettingTaskNodeElement;
|
selectedNodeTaskElement.value = JSON.parse(JSON.stringify(newElement || {})) as GraphTaskElement;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听节点鼠标事件,显示/隐藏连接点
|
// 监听节点鼠标事件,显示/隐藏连接点
|
||||||
@@ -310,7 +358,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateElement = (element: SettingTaskNodeElement) => {
|
const handleUpdateElement = (element: GraphTaskElement) => {
|
||||||
// 更新选中的节点数据
|
// 更新选中的节点数据
|
||||||
if (selectedModelNode.value) {
|
if (selectedModelNode.value) {
|
||||||
selectedModelNode.value.replaceData(element);
|
selectedModelNode.value.replaceData(element);
|
||||||
@@ -318,7 +366,7 @@ export default defineComponent({
|
|||||||
console.info('handleUpdateElement', element);
|
console.info('handleUpdateElement', element);
|
||||||
// 更新本地引用
|
// 更新本地引用
|
||||||
selectedNodeTaskElement.value = element;
|
selectedNodeTaskElement.value = element;
|
||||||
changed.value = true
|
changed.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
@@ -333,6 +381,14 @@ export default defineComponent({
|
|||||||
graph: graphData,
|
graph: graphData,
|
||||||
xmlContent: JSON.stringify(graphData),
|
xmlContent: JSON.stringify(graphData),
|
||||||
};
|
};
|
||||||
|
if (!newTree.name) {
|
||||||
|
message.error('行为树名称不能为空.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!newTree.englishName) {
|
||||||
|
message.error('行为树英文名称不能为空.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
let res = null;
|
let res = null;
|
||||||
if (currentBehaviorTree.value.id > 0) {
|
if (currentBehaviorTree.value.id > 0) {
|
||||||
res = createTree(newTree);
|
res = createTree(newTree);
|
||||||
@@ -341,6 +397,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
res.then(r => {
|
res.then(r => {
|
||||||
if (r.code === 200) {
|
if (r.code === 200) {
|
||||||
|
treesCardRef.value?.refresh();
|
||||||
message.success(r.msg ?? '操作成功.');
|
message.success(r.msg ?? '操作成功.');
|
||||||
} else {
|
} else {
|
||||||
message.error(r.msg ?? '操作失败.');
|
message.error(r.msg ?? '操作失败.');
|
||||||
@@ -368,6 +425,9 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
treesCardRef,
|
||||||
|
handleCreateTree,
|
||||||
|
currentTreeEditing,
|
||||||
currentBehaviorTree,
|
currentBehaviorTree,
|
||||||
currentNodeGraph,
|
currentNodeGraph,
|
||||||
selectedNodeTaskElement,
|
selectedNodeTaskElement,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="w-full h-full">
|
<div class="w-full h-full">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12" v-for="nm in controlTemplates">
|
<a-col v-for="nm in controlTemplates" :span="12">
|
||||||
<div
|
<div
|
||||||
:key="nm.id"
|
:key="nm.id"
|
||||||
:data-type="nm.type"
|
:data-type="nm.type"
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
@dragend="handleDragEnd"
|
@dragend="handleDragEnd"
|
||||||
@dragstart="handleDragStart($event, nm)"
|
@dragstart="handleDragStart($event, nm)"
|
||||||
>
|
>
|
||||||
<img class="icon" src="@/assets/icons/model-4.svg" :alt="nm.name ?? ''" />
|
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||||
<span class="desc">{{ nm.name }}</span>
|
<span class="desc">{{ nm.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="w-full h-full">
|
<div class="w-full h-full">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12" v-for="nm in conditionTemplates">
|
<a-col v-for="nm in conditionTemplates" :span="12">
|
||||||
<div
|
<div
|
||||||
:key="nm.id"
|
:key="nm.id"
|
||||||
:data-type="nm.type"
|
:data-type="nm.type"
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
@dragend="handleDragEnd"
|
@dragend="handleDragEnd"
|
||||||
@dragstart="handleDragStart($event, nm)"
|
@dragstart="handleDragStart($event, nm)"
|
||||||
>
|
>
|
||||||
<img class="icon" src="@/assets/icons/model-4.svg" :alt="nm.name ?? ''" />
|
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||||
<span class="desc">{{ nm.name }}</span>
|
<span class="desc">{{ nm.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="w-full h-full">
|
<div class="w-full h-full">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12" v-for="nm in actionsTemplates">
|
<a-col v-for="nm in actionsTemplates" :span="12">
|
||||||
<div
|
<div
|
||||||
:key="nm.id"
|
:key="nm.id"
|
||||||
:data-type="nm.type"
|
:data-type="nm.type"
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
@dragend="handleDragEnd"
|
@dragend="handleDragEnd"
|
||||||
@dragstart="handleDragStart($event, nm)"
|
@dragstart="handleDragStart($event, nm)"
|
||||||
>
|
>
|
||||||
<img class="icon" src="@/assets/icons/model-4.svg" :alt="nm.name ?? ''" />
|
<img :alt="nm.name ?? ''" class="icon" src="@/assets/icons/model-4.svg" />
|
||||||
<span class="desc">{{ nm.name }}</span>
|
<span class="desc">{{ nm.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -161,6 +161,6 @@ export default defineComponent({
|
|||||||
handleDragEnd,
|
handleDragEnd,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -1,12 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ks-model-builder-right">
|
<div class="ks-model-builder-right">
|
||||||
<template v-if="currentElement">
|
<template v-if="currentElement || tree">
|
||||||
|
|
||||||
<a-tabs v-model:activeKey="activeTopTabsKey" class="ks-model-builder-tabs settings-tab">
|
<a-tabs v-model:activeKey="activeTopTabsKey" class="ks-model-builder-tabs settings-tab">
|
||||||
<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>
|
||||||
<a-tab-pane key="1" tab="节点属性">
|
|
||||||
|
<a-tab-pane v-if="tree" key="1" tab="行为树属性">
|
||||||
|
<a-form
|
||||||
|
autocomplete="off"
|
||||||
|
layout="vertical"
|
||||||
|
name="basic"
|
||||||
|
style="padding-bottom:15px;"
|
||||||
|
>
|
||||||
|
<a-form-item label="行为树名称">
|
||||||
|
<a-input v-model:value="tree.name" placeholder="行为树名称" size="small" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="行为树英文名称">
|
||||||
|
<a-input v-model:value="tree.englishName" placeholder="行为树英文名称" size="small" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="行为树说明">
|
||||||
|
<a-textarea v-model:value="tree.description" placeholder="行为树说明" size="small" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
</a-form>
|
||||||
|
</a-tab-pane>
|
||||||
|
|
||||||
|
<a-tab-pane v-if="currentElement" key="2" tab="节点属性">
|
||||||
<a-form
|
<a-form
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
@@ -14,41 +37,35 @@
|
|||||||
style="padding-bottom:15px;"
|
style="padding-bottom:15px;"
|
||||||
>
|
>
|
||||||
<a-form-item label="节点名称">
|
<a-form-item label="节点名称">
|
||||||
<a-input size="small" v-model:value="currentElement.name" :placeholder="currentElement.name" />
|
<a-input v-model:value="currentElement.name" :placeholder="currentElement.name" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="节点介绍">
|
<a-form-item label="节点介绍">
|
||||||
<a-textarea size="small" v-model:value="currentElement.description" :placeholder="currentElement.description" />
|
<a-textarea v-model:value="currentElement.description" :placeholder="currentElement.description" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-divider />
|
<a-divider />
|
||||||
|
|
||||||
<a-form-item label="输入">
|
<a-form-item label="输入">
|
||||||
<a-textarea size="small" v-model:value="currentElement.inputs" />
|
<a-textarea v-model:value="currentElement.inputs" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="输出">
|
<a-form-item label="输出">
|
||||||
<a-textarea size="small" v-model:value="currentElement.outputs" />
|
<a-textarea v-model:value="currentElement.outputs" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-divider v-if="currentElement.settings && currentElement.settings.length > 0"/>
|
<a-divider v-if="currentElement.settings && currentElement.parameters.length > 0" />
|
||||||
|
|
||||||
<a-form-item :label="setting.description" v-for="setting in currentElement.settings">
|
<a-form-item v-for="setting in currentElement.parameters" :label="setting.description">
|
||||||
<a-input-number size="small" style="width:100%;" v-if="setting.data_type === 'double'" v-model:value="setting.default_value" :placeholder="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 size="small" v-model:value="setting.default_value" :placeholder="setting.description" />
|
<a-input v-else v-model:value="setting.defaultValue" :placeholder="setting.description" size="small" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
|
||||||
<!-- <a-tab-pane key="2" tab="外观">-->
|
|
||||||
|
|
||||||
<!-- </a-tab-pane>-->
|
|
||||||
<!-- <a-tab-pane key="3" tab="系统">-->
|
|
||||||
|
|
||||||
<!-- </a-tab-pane>-->
|
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|
||||||
<a-tabs v-model:activeKey="activeBottomTabsKey" class="ks-model-builder-tabs parameters-tabs">
|
<a-tabs v-if="currentElement" 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>
|
||||||
@@ -83,7 +100,7 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<a-input v-model:value="record[column.dataIndex]" size="small"/>
|
<a-input v-model:value="record[column.dataIndex]" size="small" />
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
@@ -111,9 +128,10 @@
|
|||||||
<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 } from '@ant-design/icons-vue';
|
||||||
import type { ElementVariable, SettingTaskNodeElement } from './builder/element';
|
import type { ElementVariable, GraphTaskElement } from './builder/element';
|
||||||
|
import type { BehaviorTree } from './types';
|
||||||
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';
|
||||||
|
|
||||||
const actionSpaceColumns = [
|
const actionSpaceColumns = [
|
||||||
{ title: '序号', dataIndex: 'index', key: 'index', width: 40 },
|
{ title: '序号', dataIndex: 'index', key: 'index', width: 40 },
|
||||||
@@ -126,17 +144,21 @@ const actionSpaceColumns = [
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { CheckOutlined },
|
components: { CheckOutlined },
|
||||||
props: {
|
props: {
|
||||||
|
tree: { type: [Object, null] as PropType<BehaviorTree | null | undefined>, required: false },
|
||||||
|
treeEditing: { type: Boolean as PropType<boolean>, required: true, default: false },
|
||||||
node: { type: [Object, null] as PropType<Node<NodeProperties> | null | undefined>, required: false },
|
node: { type: [Object, null] as PropType<Node<NodeProperties> | null | undefined>, required: false },
|
||||||
graph: { type: [Object, null] as PropType<Graph | null | undefined>, required: true }
|
graph: { type: [Object, null] as PropType<Graph | null | undefined>, required: true },
|
||||||
},
|
},
|
||||||
emits: ['update-element'],
|
emits: ['update-element', 'update-tree'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const activeTopTabsKey = ref<string>('1');
|
const activeTopTabsKey = ref<string>('1');
|
||||||
const activeBottomTabsKey = ref<string>('1');
|
const activeBottomTabsKey = ref<string>('1');
|
||||||
const activeBottomTabs2Key = ref<string>('1');
|
const activeBottomTabs2Key = ref<string>('1');
|
||||||
|
|
||||||
|
const currentTree = ref<BehaviorTree | null>(props.tree ?? null);
|
||||||
|
const treeEditing = ref<boolean>(props.treeEditing);
|
||||||
const currentNode = ref<Node | null>(props.node ?? null);
|
const currentNode = ref<Node | null>(props.node ?? null);
|
||||||
const currentElement = ref<SettingTaskNodeElement | null>(null);
|
const currentElement = ref<GraphTaskElement | null>(null);
|
||||||
|
|
||||||
const load = () => {
|
const load = () => {
|
||||||
};
|
};
|
||||||
@@ -145,13 +167,13 @@ export default defineComponent({
|
|||||||
currentNode.value = n ?? null;
|
currentNode.value = n ?? null;
|
||||||
if (n) {
|
if (n) {
|
||||||
const data = n.getData();
|
const data = n.getData();
|
||||||
currentElement.value = JSON.parse(JSON.stringify(data || {})) as SettingTaskNodeElement;
|
currentElement.value = JSON.parse(JSON.stringify(data || {})) as GraphTaskElement;
|
||||||
} else {
|
} else {
|
||||||
currentElement.value = null;
|
currentElement.value = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addVariable = ()=> {
|
const addVariable = () => {
|
||||||
if (!currentElement.value) {
|
if (!currentElement.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -165,8 +187,8 @@ export default defineComponent({
|
|||||||
value: null,
|
value: null,
|
||||||
defaults: null,
|
defaults: null,
|
||||||
unit: null,
|
unit: null,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const removeVariable = (row: ElementVariable) => {
|
const removeVariable = (row: ElementVariable) => {
|
||||||
if (currentElement.value && currentElement.value.variables) {
|
if (currentElement.value && currentElement.value.variables) {
|
||||||
@@ -178,7 +200,7 @@ export default defineComponent({
|
|||||||
const updateNode = () => {
|
const updateNode = () => {
|
||||||
if (currentNode.value && currentElement.value) {
|
if (currentNode.value && currentElement.value) {
|
||||||
// 深拷贝当前元素数据
|
// 深拷贝当前元素数据
|
||||||
const newElement = JSON.parse(JSON.stringify(currentElement.value)) as SettingTaskNodeElement;
|
const newElement = JSON.parse(JSON.stringify(currentElement.value)) as GraphTaskElement;
|
||||||
// 更新节点数据
|
// 更新节点数据
|
||||||
currentNode.value.replaceData(newElement);
|
currentNode.value.replaceData(newElement);
|
||||||
// 触发事件通知父组件
|
// 触发事件通知父组件
|
||||||
@@ -192,6 +214,22 @@ export default defineComponent({
|
|||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.tree,
|
||||||
|
(n?: BehaviorTree | null | undefined) => {
|
||||||
|
currentTree.value = n ?? null;
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.treeEditing,
|
||||||
|
(n?: boolean | null | undefined) => {
|
||||||
|
treeEditing.value = n === true;
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
watch(() => currentElement.value, () => updateNode(), { deep: true });
|
watch(() => currentElement.value, () => updateNode(), { deep: true });
|
||||||
|
|
||||||
onMounted(() => load());
|
onMounted(() => load());
|
||||||
@@ -204,6 +242,8 @@ export default defineComponent({
|
|||||||
currentElement,
|
currentElement,
|
||||||
addVariable,
|
addVariable,
|
||||||
removeVariable,
|
removeVariable,
|
||||||
|
currentTree,
|
||||||
|
treeEditing,
|
||||||
// currentElementParameters,
|
// currentElementParameters,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,45 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-collapse v-model:activeKey="activeKey" :accordion="false">
|
<a-collapse v-model:activeKey="activeKey" :accordion="false" class="ks-trees-collapse">
|
||||||
<a-collapse-panel key="1">
|
<a-collapse-panel key="1" style="position: relative">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="ks-model-builder-title-icon icon-model"></span>我的行为树
|
<a-flex>
|
||||||
|
<span class="ks-model-builder-title-icon icon-model"></span>
|
||||||
|
<span style="color: #82c4e9;font-size: 16px;">我的行为树</span>
|
||||||
|
<!-- <span style="position: absolute; right: 15px;"><PlusOutlined @click="$emit('create-tree')"/></span>-->
|
||||||
|
</a-flex>
|
||||||
</template>
|
</template>
|
||||||
<a-list size="small" :data-source="behaviorTrees || []" style="min-height: 25vh">
|
<div class="w-full" style="padding: 5px;">
|
||||||
|
<a-flex>
|
||||||
|
<a-input-search v-model:value="behaviorTreeQuery.name" allowClear placeholder="行为树名称" size="small" @search="loadTress" />
|
||||||
|
<a-button size="small" style="margin-left: 10px;">
|
||||||
|
<PlusOutlined style="margin-top: 0px;display: block;" @click="$emit('create-tree')" />
|
||||||
|
</a-button>
|
||||||
|
</a-flex>
|
||||||
|
</div>
|
||||||
|
<a-list :data-source="behaviorTrees || []" size="small" style="min-height: 25vh">
|
||||||
<template #renderItem="{ item }">
|
<template #renderItem="{ item }">
|
||||||
<a-tooltip placement="right">
|
<a-list-item>
|
||||||
|
<a-flex>
|
||||||
|
<a-tooltip placement="bottom">
|
||||||
<template #title>
|
<template #title>
|
||||||
<p>名称: {{ item.name }}</p>
|
<p>名称: {{ item.name }}</p>
|
||||||
<p>说明: {{item.description}}</p>
|
<p>说明: {{ item.description }}</p>
|
||||||
</template>
|
</template>
|
||||||
<a-list-item @click="()=> handleSelect(item)">
|
<span>{{ substring(item.name, 15) }}</span>
|
||||||
{{ substring(item.name, 15) }}
|
|
||||||
</a-list-item>
|
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
<a-flex class="ks-tree-actions">
|
||||||
|
<span style="margin-right: 10px" @click="()=> handleSelect(item)"><EditFilled /></span>
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定删除?"
|
||||||
|
@confirm="()=> handleDelete(item)"
|
||||||
|
>
|
||||||
|
<span class="ks-tree-action ks-tree-action-delete"><DeleteOutlined /></span>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-flex>
|
||||||
|
</a-flex>
|
||||||
|
</a-list-item>
|
||||||
</template>
|
</template>
|
||||||
</a-list>
|
</a-list>
|
||||||
|
<a-pagination
|
||||||
|
v-model:current="behaviorTreeQuery.pageNum"
|
||||||
|
:page-size="behaviorTreeQuery.pageSize"
|
||||||
|
:total="totalTress"
|
||||||
|
simple size="small" @change="handleChange" />
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, ref } from 'vue';
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
import { CheckOutlined, DeleteOutlined, EditFilled, PlusOutlined } from '@ant-design/icons-vue';
|
||||||
import type { BehaviorTree } from './types';
|
import type { BehaviorTree, BehaviorTreeRequest } from './types';
|
||||||
import { findTreesByQuery } from './api';
|
import { deleteOneTreeById, findTreesByQuery } from './api';
|
||||||
import {substring} from '@/utils/strings'
|
import { substring } from '@/utils/strings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
emits: ['select-tree'],
|
emits: ['select-tree', 'create-tree'],
|
||||||
components: {
|
components: {
|
||||||
PlusOutlined
|
CheckOutlined,
|
||||||
|
PlusOutlined,
|
||||||
|
DeleteOutlined,
|
||||||
|
EditFilled,
|
||||||
},
|
},
|
||||||
setup(_props, { emit }) {
|
setup(_props, { emit }) {
|
||||||
const behaviorTrees = ref<BehaviorTree[]>([]);
|
const behaviorTrees = ref<BehaviorTree[]>([]);
|
||||||
const behaviorTreeQuery = ref<Partial<BehaviorTree>>({});
|
const behaviorTreeQuery = ref<Partial<BehaviorTreeRequest>>({
|
||||||
const activeKey = ref<number>(1)
|
name: null,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 8,
|
||||||
|
});
|
||||||
|
const activeKey = ref<number>(1);
|
||||||
|
const totalTress = ref<number>(0);
|
||||||
|
|
||||||
const loadTress = () => {
|
const loadTress = () => {
|
||||||
findTreesByQuery(behaviorTreeQuery.value).then(r => {
|
findTreesByQuery(behaviorTreeQuery.value).then(r => {
|
||||||
behaviorTrees.value = r.rows;
|
behaviorTrees.value = r.rows;
|
||||||
|
totalTress.value = r.total ?? 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (page: number, pageSize: number) => {
|
||||||
|
behaviorTreeQuery.value.pageNum = page;
|
||||||
|
behaviorTreeQuery.value.pageSize = pageSize;
|
||||||
|
loadTress();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (item: BehaviorTree) => {
|
||||||
|
deleteOneTreeById(item.id).then(r => {
|
||||||
|
if (r.code === 200) {
|
||||||
|
loadTress();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,7 +104,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const handleSelect = (record: BehaviorTree) => {
|
const handleSelect = (record: BehaviorTree) => {
|
||||||
emit('select-tree', record);
|
emit('select-tree', record);
|
||||||
}
|
};
|
||||||
|
|
||||||
const customRow = (record: BehaviorTree) => {
|
const customRow = (record: BehaviorTree) => {
|
||||||
return {
|
return {
|
||||||
@@ -62,11 +114,15 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refresh = () => loadTress();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadTress();
|
loadTress();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
refresh,
|
||||||
|
totalTress,
|
||||||
substring,
|
substring,
|
||||||
activeKey,
|
activeKey,
|
||||||
behaviorTrees,
|
behaviorTrees,
|
||||||
@@ -75,19 +131,57 @@ export default defineComponent({
|
|||||||
columns,
|
columns,
|
||||||
customRow,
|
customRow,
|
||||||
handleSelect,
|
handleSelect,
|
||||||
|
handleChange,
|
||||||
|
handleDelete,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less">
|
||||||
.create-tree-icon{
|
.ant-collapse {
|
||||||
|
.ant-list-sm {
|
||||||
|
.ant-list-item {
|
||||||
|
padding: 4px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: rgb(130 196 233);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.ks-tree-actions {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #0d2d4e;
|
||||||
|
|
||||||
|
.ks-tree-actions {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ks-trees-collapse {
|
||||||
|
|
||||||
|
.ant-collapse-content-box {
|
||||||
|
padding: 0;
|
||||||
|
height: 40vh;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-tree-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-list-item {
|
.ant-list-item {
|
||||||
padding: 5px 5px;
|
padding: 3px 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: rgb(130 196 233);
|
color: rgb(130 196 233);
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,5 @@
|
|||||||
* that was distributed with this source code.
|
* that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './tree'
|
export * from './tree';
|
||||||
export * from './template'
|
export * from './template';
|
||||||
export * from './parameter'
|
|
||||||
|
|||||||
@@ -1,20 +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 { NullableString } from '@/types';
|
|
||||||
|
|
||||||
export interface NodeSetting {
|
|
||||||
id: number;
|
|
||||||
name: NullableString;
|
|
||||||
type: NullableString;
|
|
||||||
default_value: NullableString;
|
|
||||||
data_type: NullableString;
|
|
||||||
required: boolean;
|
|
||||||
description: NullableString;
|
|
||||||
}
|
|
||||||
@@ -8,16 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ApiDataResponse, NullableString } from '@/types';
|
import type { ApiDataResponse, NullableString } from '@/types';
|
||||||
|
import type { ElementParameter } from '../builder/element';
|
||||||
export interface NodeTemplateParameter {
|
|
||||||
id: number,
|
|
||||||
templateId: number,
|
|
||||||
paramKey: NullableString,
|
|
||||||
dataType: NullableString,
|
|
||||||
defaultValue: NullableString,
|
|
||||||
description: NullableString,
|
|
||||||
templateType: NullableString,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NodeTemplate {
|
export interface NodeTemplate {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -25,9 +16,9 @@ export interface NodeTemplate {
|
|||||||
type: NullableString;
|
type: NullableString;
|
||||||
logicHandler: NullableString;
|
logicHandler: NullableString;
|
||||||
description: NullableString;
|
description: NullableString;
|
||||||
templeteType: NullableString;
|
templateType: NullableString;
|
||||||
englishName: NullableString;
|
englishName: NullableString;
|
||||||
parameters: NodeTemplateParameter[],
|
parameters: ElementParameter[],
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeTemplatesResponse extends ApiDataResponse<NodeTemplate[]> {
|
export interface NodeTemplatesResponse extends ApiDataResponse<NodeTemplate[]> {
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ export interface BehaviorTree {
|
|||||||
graph: NodeGraph
|
graph: NodeGraph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BehaviorTreeRequest extends BehaviorTree {
|
||||||
|
pageNum: number,
|
||||||
|
pageSize: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface BehaviorTreeDetailsResponse extends ApiDataResponse<BehaviorTree> {
|
export interface BehaviorTreeDetailsResponse extends ApiDataResponse<BehaviorTree> {
|
||||||
|
|
||||||
|
|||||||
@@ -8,22 +8,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NodeTemplate } from '../types';
|
import type { NodeTemplate } from '../types';
|
||||||
import type { SettingTaskNodeElement, TaskNodeRect } from '../builder/element';
|
import type { GraphTaskElement, GraphTaskRect } from '../builder/element';
|
||||||
import { generateKey } from '@/utils/strings';
|
import { generateKey } from '@/utils/strings';
|
||||||
|
|
||||||
export const createTaskNodeElementFromTemplate = (
|
export const createGraphTaskElementFromTemplate = (
|
||||||
template: NodeTemplate,
|
template: NodeTemplate,
|
||||||
rect?: TaskNodeRect,
|
rect?: GraphTaskRect,
|
||||||
): SettingTaskNodeElement => {
|
): GraphTaskElement => {
|
||||||
let realRect = { width: 200, height: 100, x: 0, y: 0, ...rect || {} }
|
let realRect = { width: 120, height: 80, x: 0, y: 0, ...rect || {} };
|
||||||
console.info('rect',rect)
|
console.info('rect', rect);
|
||||||
return {
|
return {
|
||||||
id: 0,
|
id: 0,
|
||||||
key: generateKey(template.type),
|
key: generateKey(template.type),
|
||||||
status: null,
|
type: 'task',
|
||||||
template: template.id,
|
template: template.id,
|
||||||
type: template.type,
|
templateType: template.templateType,
|
||||||
name: template.name,
|
name: template.name,
|
||||||
|
category: template.type,
|
||||||
description: template.description,
|
description: template.description,
|
||||||
position: {
|
position: {
|
||||||
x: realRect.x ?? 0,
|
x: realRect.x ?? 0,
|
||||||
@@ -31,25 +32,9 @@ export const createTaskNodeElementFromTemplate = (
|
|||||||
},
|
},
|
||||||
width: realRect.width,
|
width: realRect.width,
|
||||||
height: realRect.height,
|
height: realRect.height,
|
||||||
// settings: JSON.parse(JSON.stringify(template.parameter_defs ?? [])),
|
|
||||||
inputs: null,
|
inputs: null,
|
||||||
outputs: null,
|
outputs: null,
|
||||||
parameters: {},
|
parameters: template.parameters ?? [],
|
||||||
variables: [
|
variables: [],
|
||||||
{
|
} as GraphTaskElement;
|
||||||
key: generateKey('var_'),
|
|
||||||
name: '范围',
|
|
||||||
value: '1000',
|
|
||||||
defaults: '1000',
|
|
||||||
unit: 'KM'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: generateKey('var_'),
|
|
||||||
name: '武器名称',
|
|
||||||
value: '地对空导弹',
|
|
||||||
defaults: '地对空导弹',
|
|
||||||
unit: '个'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
} as SettingTaskNodeElement;
|
|
||||||
};
|
};
|
||||||
|
|||||||
22
modeler/types/components.d.ts
vendored
22
modeler/types/components.d.ts
vendored
@@ -13,10 +13,9 @@ export {}
|
|||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
||||||
|
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
ACarousel: typeof import('ant-design-vue/es')['Carousel']
|
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
|
||||||
ACol: typeof import('ant-design-vue/es')['Col']
|
ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
||||||
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
||||||
@@ -29,7 +28,6 @@ declare module 'vue' {
|
|||||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||||
AFormItemRest: typeof import('ant-design-vue/es')['FormItemRest']
|
AFormItemRest: typeof import('ant-design-vue/es')['FormItemRest']
|
||||||
AInput: typeof import('ant-design-vue/es')['Input']
|
AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
|
|
||||||
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
||||||
@@ -39,18 +37,15 @@ declare module 'vue' {
|
|||||||
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
||||||
AList: typeof import('ant-design-vue/es')['List']
|
AList: typeof import('ant-design-vue/es')['List']
|
||||||
AListItem: typeof import('ant-design-vue/es')['ListItem']
|
AListItem: typeof import('ant-design-vue/es')['ListItem']
|
||||||
|
AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
|
||||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
APopover: typeof import('ant-design-vue/es')['Popover']
|
|
||||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
ASlider: typeof import('ant-design-vue/es')['Slider']
|
|
||||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
ASteps: typeof import('ant-design-vue/es')['Steps']
|
|
||||||
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
||||||
ATable: typeof import('ant-design-vue/es')['Table']
|
ATable: typeof import('ant-design-vue/es')['Table']
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
@@ -65,10 +60,9 @@ declare module 'vue' {
|
|||||||
// For TSX support
|
// For TSX support
|
||||||
declare global {
|
declare global {
|
||||||
const AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
const AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
||||||
|
const ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||||
const AButton: typeof import('ant-design-vue/es')['Button']
|
const AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
const ACard: typeof import('ant-design-vue/es')['Card']
|
const ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
const ACarousel: typeof import('ant-design-vue/es')['Carousel']
|
|
||||||
const ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
|
||||||
const ACol: typeof import('ant-design-vue/es')['Col']
|
const ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
const ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
const ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
||||||
const ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
const ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
||||||
@@ -81,7 +75,6 @@ declare global {
|
|||||||
const AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
const AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||||
const AFormItemRest: typeof import('ant-design-vue/es')['FormItemRest']
|
const AFormItemRest: typeof import('ant-design-vue/es')['FormItemRest']
|
||||||
const AInput: typeof import('ant-design-vue/es')['Input']
|
const AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
const AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
|
|
||||||
const AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
const AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||||
const AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
const AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
const AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
const AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
||||||
@@ -91,18 +84,15 @@ declare global {
|
|||||||
const ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
const ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
||||||
const AList: typeof import('ant-design-vue/es')['List']
|
const AList: typeof import('ant-design-vue/es')['List']
|
||||||
const AListItem: typeof import('ant-design-vue/es')['ListItem']
|
const AListItem: typeof import('ant-design-vue/es')['ListItem']
|
||||||
|
const AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
|
||||||
const AMenu: typeof import('ant-design-vue/es')['Menu']
|
const AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||||
const AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
const AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
const AModal: typeof import('ant-design-vue/es')['Modal']
|
const APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
const APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
const APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
const APopover: typeof import('ant-design-vue/es')['Popover']
|
|
||||||
const AProgress: typeof import('ant-design-vue/es')['Progress']
|
|
||||||
const ARow: typeof import('ant-design-vue/es')['Row']
|
const ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
const ASelect: typeof import('ant-design-vue/es')['Select']
|
const ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
const ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
const ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
const ASlider: typeof import('ant-design-vue/es')['Slider']
|
|
||||||
const ASpace: typeof import('ant-design-vue/es')['Space']
|
const ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
const ASteps: typeof import('ant-design-vue/es')['Steps']
|
|
||||||
const ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
const ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
||||||
const ATable: typeof import('ant-design-vue/es')['Table']
|
const ATable: typeof import('ant-design-vue/es')['Table']
|
||||||
const ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
const ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
|
|||||||
Reference in New Issue
Block a user