端到端功能后台应用功能入口部分提交

This commit is contained in:
ouyang 2023-05-11 19:03:33 +08:00
parent 90b1d0af07
commit 2a5378a9df
9 changed files with 293 additions and 0 deletions

View File

@ -11,4 +11,10 @@ public interface SubProcessConst {
// 端到端流程存放父节点 参数名
String SUB_PROCESS_MODEL_LOCATION = "SUB_PROCESS_MODEL_LOCATION";
// 前置流程属性key
String LEAD_PROCESS_ATTR_ID = "lead_process";
// 后置流程属性key
String REAR_PROCESS_ATTR_ID = "rear_process";
}

View File

@ -0,0 +1,56 @@
package com.actionsoft.apps.coe.method.process.subprocess.graph;
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
import java.util.ArrayList;
import java.util.List;
/**
* 用邻接矩阵表示图模型 并实现相关的操作
* @author oYang
* @create 2023-05-11 17:10
*/
public class GraphAdjMatrix {
private int[][] adjMatrix; // 邻接矩阵
private List<Node> vertexList; // 存储节点
private int numEdges; // 边的数目
/**
* 构造函数 初始化邻接矩阵
* @param numVertices
*/
public GraphAdjMatrix(int numVertices) {
adjMatrix = new int[numVertices][numVertices];
vertexList = new ArrayList<>(numVertices);
numEdges = 0;
}
/**
* 添加一条从顶点 u 到顶点 v 的有向边
*/
public void addEdge(int u, int v) {
adjMatrix[u][v] = 1; // 设置邻接矩阵中相应的位置为 1
numEdges++;
}
/**
* 获取从顶点 u 出发可以到达的所有顶点
*/
public List<Integer> getNeighbors(int u) {
List<Integer> neighbors = new ArrayList<>();
for (int i = 0; i < vertexList.size(); i++) {
if (adjMatrix[u][i] == 1) {
neighbors.add(i);
}
}
return neighbors;
}
/**
* 判断从顶点 u 是否可以到达顶点 v
*/
public boolean hasEdge(int u, int v) {
return adjMatrix[u][v] == 1;
}
}

View File

@ -0,0 +1,57 @@
package com.actionsoft.apps.coe.method.process.subprocess.mode;
/**
* @author oYang
* @create 2023-05-11 17:21
*/
public class Node {
private String id;
private double x;
private double y;
public double displaceX; // x方向移动位移
public double displaceY; // y方向移动位移
public Node(String id) {
this.id = id;
}
public Node(String id, double x, double y) {
this.id = id;
this.x = x;
this.y = y;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "Node{" +
"id='" + id + '\'' +
", x=" + x +
", y=" + y +
'}';
}
}

View File

@ -0,0 +1,22 @@
package com.actionsoft.apps.coe.method.process.subprocess.uitl;
/**
* @author oYang
* @create 2023-05-11 13:57
*/
public class Node {
public int id; // 节点id
public double x; // 节点x坐标
public double y; // 节点y坐标
public double displaceX; // x方向移动位移
public double displaceY; // y方向移动位移
public Node(int id) {
this.id = id;
this.x = 0;
this.y = 0;
this.displaceX = 0;
this.displaceY = 0;
}
}

View File

@ -0,0 +1,113 @@
package com.actionsoft.apps.coe.method.process.subprocess.uitl;
import java.util.ArrayList;
import java.util.Random;
/**
* @author oYang
* @create 2023-05-11 13:53
*/
public class UtilTestGraph {
private final int width; // 布局区域宽度
private final int height; // 布局区域高度
private final double k; // 弹性系数
private final double k2; // 斥力系数
private final double damping; // 阻尼系数
private final double maxDisplace; // 最大移动距离
private final int maxIterations; // 最大迭代次数
// 存储每个节点的位置信息
private ArrayList<Node> nodes;
// 存储每个节点之间的连线信息邻接矩阵
private int[][] adjacencyMatrix;
public UtilTestGraph(int width, int height, double k, double k2, double damping, double maxDisplace, int maxIterations, int nodeCount) {
this.width = width;
this.height = height;
this.k = k;
this.k2 = k2;
this.damping = damping;
this.maxDisplace = maxDisplace;
this.maxIterations = maxIterations;
// 初始化节点数组
this.nodes = new ArrayList<>(nodeCount);
for (int i = 0; i < nodeCount; i++) {
Node node = new Node(i);
node.x = Math.random() * this.width;
node.y = Math.random() * this.height;
nodes.add(node);
}
// 初始化邻接矩阵
this.adjacencyMatrix = new int[nodeCount][nodeCount];
Random random = new Random();
for (int i = 0; i < nodeCount; i++) {
for (int j = i + 1; j < nodeCount; j++) {
// 随机生成一个有连线的概率
double p = random.nextDouble();
if (p < 0.3) {
adjacencyMatrix[i][j] = 1;
adjacencyMatrix[j][i] = 1;
}
}
}
}
// 执行布局操作
public void executeLayout() {
for (int i = 0; i < maxIterations; i++) {
for (int j = 0; j < nodes.size(); j++) {
Node node = nodes.get(j);
node.displaceX = 0;
node.displaceY = 0;
for (int k = 0; k < nodes.size(); k++) {
if (j == k) continue;
Node other = nodes.get(k);
double dx = other.x - node.x;
double dy = other.y - node.y;
double distanceSquared = dx * dx + dy * dy;
if (distanceSquared == 0) {
dx = randomDisplacement();
dy = randomDisplacement();
distanceSquared = dx * dx + dy * dy;
}
double distance = Math.sqrt(distanceSquared);
double force = (k * k / distance) - (k2 * distance);
node.displaceX += (dx / distance) * force;
node.displaceY += (dy / distance) * force;
}
}
// 移动节点的位置
for (Node node : nodes) {
double xDisplace = node.displaceX * damping;
double yDisplace = node.displaceY * damping;
double displace = Math.sqrt(xDisplace * xDisplace + yDisplace * yDisplace);
if (displace > maxDisplace) {
xDisplace *= maxDisplace / displace;
yDisplace *= maxDisplace / displace;
}
node.x += xDisplace;
node.y += yDisplace;
}
}
}
// 随机生成一个小的位移量
private double randomDisplacement() {
return (Math.random() - 0.5) * 0.1;
}
public static void main(String[] args) {
UtilTestGraph layout = new UtilTestGraph(800, 600, 5.0, 0.1, 0.9, 5.0, 100, 20);
layout.executeLayout();
// 输出节点的最终位置
for (Node node : layout.nodes) {
System.out.println("Node " + node.id + ": (" + node.x + ", " + node.y + ")");
}
}
}

View File

@ -1,10 +1,14 @@
package com.actionsoft.apps.coe.method.process.subprocess.web;
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
import com.actionsoft.apps.coe.method.process.subprocess.graph.GraphAdjMatrix;
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
import com.actionsoft.apps.coe.method.process.subprocess.model.vo.SubProcessTagVo;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryQueryAPIManager;
import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.model.DesignerShapeRelationModel;
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import com.actionsoft.apps.coe.pal.pal.repository.web.CoeProcessLevelWeb;
import com.actionsoft.bpms.commons.mvc.view.ActionWeb;
@ -198,4 +202,31 @@ public class SubProcessWeb extends ActionWeb {
}).collect(Collectors.toCollection(JSONArray :: new));
return result;
}
public void generatorEndToEndModel(String processIdJsonArr){
List<String> processIdList = JSONArray.parseArray(processIdJsonArr, String.class);
// 1.校验
// 2.根据文件中前游流程与后游流程来确定关联关系
GraphAdjMatrix graphAdjMatrix = new GraphAdjMatrix(processIdList.size());
List<Node> nodeList = new ArrayList<>();
for (String processId : processIdList) {
Node node = new Node(processId);
// 前置流程
List<DesignerShapeRelationModel> learProcessList = DesignerShapeRelationCache.getByFileId(processId, SubProcessConst.LEAD_PROCESS_ATTR_ID);
// 后置流程
List<DesignerShapeRelationModel> rearProcessList = DesignerShapeRelationCache.getByFileId(processId, SubProcessConst.REAR_PROCESS_ATTR_ID);
}
// 3.根据关联关系数据模型来决定分布位置
// 3.1 每个子流程模型有一个 子流程模型的图形属性处理
// 4.在分布好的位置上根据关联关系数据模型连线
}
}

View File

@ -33,4 +33,6 @@ public class CoEConstant {
public static final String APP_BATCH_ID = "com.actionsoft.apps.coe.pal.batch";// 流程批处理id
public static final String APP_SUB_PROCESS_ID = "com.actionsoft.apps.coe.method.process.subprocess"; // 端到端应用ID
}

View File

@ -10392,6 +10392,12 @@ public String deleteReply(String replyid, String messageid) {
}else {
ro.put("modelConvertInstall",false);
}
// 端到端应用是否安装
if (SDK.getAppAPI().isActive(CoEConstant.APP_SUB_PROCESS_ID)){
ro.put("subProcessAppVisible", true);
}else {
ro.put("subProcessAppVisible", false);
}
// 流程批处理是否显示
boolean batchAppVisible = false;
String batchDlg = "";