端到端功能后台应用功能

This commit is contained in:
ouyang 2023-05-17 17:49:48 +08:00
parent 890239354a
commit 7d76405fff
11 changed files with 230 additions and 22 deletions

View File

@ -25,6 +25,6 @@
<requires/>
<palMethodIcon>{"process.epc":{"code": "&amp;#xe605;","color": "#4E7FF9"}}</palMethodIcon>
<properties>
<property action="disabled" group="功能入口相关" name="SUB_PROCESS_MODEL_LOCATION" title="端到端模型存放目录" type="input" isSystem="false" desc="指定生成的端到端模型存放的根目录" ref="">process/3d2f5b3d-3e66-4777-808a-2c56e91dc8cc</property>
<property action="disabled" group="功能入口相关" name="SUB_PROCESS_MODEL_LOCATION" title="端到端模型存放目录" type="input" isSystem="false" desc="指定生成的端到端模型存放的根目录&lt;br&gt;{资产库名称}/{根目录}/{一级目录} " ref="">伊利/流程制度/专门存放端到端总图</property>
</properties>
</app>

View File

@ -1,5 +1,6 @@
package com.actionsoft.apps.coe.method.process.subprocess;
import com.actionsoft.apps.coe.method.process.subprocess.mode.vo.IndependentNodeVo;
import com.actionsoft.apps.coe.method.process.subprocess.web.SubProcessWeb;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
@ -8,6 +9,8 @@ import com.actionsoft.bpms.server.bind.annotation.Mapping;
import com.actionsoft.exception.AWSException;
import com.alibaba.fastjson.JSONArray;
import java.util.List;
/**
* @author oYang
* @create 2023-05-09 15:37
@ -90,6 +93,48 @@ public class SubProcessController {
}
}
/**
* 生成图->前置处理独立节点
* @param uc
* @param processIdJsonArr
* @return
*/
@Mapping("com.actionsoft.apps.coe.method.process.subprocess.independent_node_pre_handle")
public String vertexPreHandleIndependentNode(UserContext uc, String processIdJsonArr){
try {
SubProcessWeb processWeb = new SubProcessWeb(uc);
List<IndependentNodeVo> independentNodeVos = processWeb.vertexPreHandleIndependentNode(processIdJsonArr);
ResponseObject ro = ResponseObject.newOkResponse();
ro.put("independentNodeVos",independentNodeVos);
return ro.toString();
} catch (AWSException e) {
return ResponseObject.newErrResponse(e.getMessage()).toString();
}
}
/**
* 生成图->前置处理
* 前置流程或后置流程是否在所选的范围内
* @param uc
* @param processIdJsonArr
* @param excludeProcessIdJsonArr
* @return
*/
@Mapping("com.actionsoft.apps.coe.method.process.subprocess.lead_rear_node_pre_handle")
public String vertexPreHandle2(UserContext uc, String processIdJsonArr, String excludeProcessIdJsonArr){
return null;
}
/**
* 功能->生成图
* @param uc
* @param processIdJsonArr
* @param locationId
* @param direction
* @param modelName
* @return
*/
@Mapping("com.actionsoft.apps.coe.method.process.subprocess.generator_end_to_end_model")
public String generatorEndToEndModel(UserContext uc, String processIdJsonArr, String locationId, String direction, String modelName){
SubProcessWeb processWeb = new SubProcessWeb(uc);

View File

@ -20,7 +20,7 @@ public class ForceDirectedGraphLayout {
private final double[] displacementY; // 节点位移的y方向补偿
private double temperature = 100.0; // 温度
private double temperatureDecay = 0.1; // 温度衰减率
private final double maxDisplacement = 50.0; // 最大位移量
private final double maxDisplacement = 180.0; // 最大位移量
private final Random random = new Random();
private final double width; // 画布宽度
private final double height; // 画布高度

View File

@ -2,8 +2,13 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph;
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
import com.actionsoft.apps.coe.method.process.subprocess.mode.vo.IndependentNodeVo;
import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache;
import com.actionsoft.apps.coe.pal.pal.repository.dao.PALRepository;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.dao.DesignerShapeRelationDao;
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.exception.AWSException;
import java.util.ArrayList;
@ -11,15 +16,53 @@ import java.util.List;
import java.util.Map;
/**
* 图模型节点预处理
* 选择的若干子流程 其中某些子流程配置的上下游流程并不在所选的若干子流程中
* 那么这些配置上的上下游流程怎么归属
* 是包含进总图中还是排除掉
* 模型节点预处理
* 1.校验该子流程是否是独立的节点
* 判定规则 该子流程既没有前置流程也没有后置流程同时也不被别的节点指向则判定为独立节点
*
* 2.选择若干子流程如ABCDE在这五个子流程中其中如果A存在前置或后置流程HJ
* 那么对于HJ这一类节点是否包含进总图返回给前台由用户抉择
*
* @author oYang
* @create 2023-05-12 15:30
*/
public class VertexPreHandle {
/**
* 收集独立子流程
* @param processIdList
* @return
* @throws AWSException
*/
public List<IndependentNodeVo> collectIndependentNode(List<String> processIdList) throws AWSException{
List<IndependentNodeVo> independentNodeVos = new ArrayList<>();
List<String> attrIdList = new ArrayList<>();
attrIdList.add(SubProcessConst.LEAD_PROCESS_ATTR_ID);
attrIdList.add(SubProcessConst.REAR_PROCESS_ATTR_ID);
for (String processId : processIdList) {
// 1. 该子流程是否存在前置或后置流程
List<DesignerShapeRelationModel> leadProcessList = DesignerShapeRelationCache.getByFileId(processId, SubProcessConst.LEAD_PROCESS_ATTR_ID);
if (leadProcessList != null && leadProcessList.size() > 0) continue;
List<DesignerShapeRelationModel> rearProcessList = DesignerShapeRelationCache.getByFileId(processId, SubProcessConst.REAR_PROCESS_ATTR_ID);
if (rearProcessList != null && rearProcessList.size() > 0) continue;
// 2. 该节点是否被别的节点
DesignerShapeRelationDao relationDao = new DesignerShapeRelationDao();
List<DesignerShapeRelationModel> relationModels = relationDao.getModelListByRelationFileIdAndAttrIds(processId, attrIdList);
if (relationModels != null && relationModels.size() > 0) continue;
// 3. 收集独立节点信息返回给前台
PALRepositoryModel repositoryModel = PALRepositoryCache.getCache().get(processId);
IndependentNodeVo independentNodeVo = new IndependentNodeVo(processId, repositoryModel.getName());
independentNodeVos.add(independentNodeVo);
}
return independentNodeVos;
}
/**
* 包含进总图中
* @param processIdList 选择的若干子流程ID

View File

@ -13,7 +13,8 @@ public class Node {
private String id;
private double x;
private double y;
private double vx;
private double vy;
private List<DesignerShapeRelationModel> learModeList;
private List<DesignerShapeRelationModel> rearModeList;
@ -28,6 +29,14 @@ public class Node {
this.y = y;
}
public Node(String id, double x, double y, double vx, double vy) {
this.id = id;
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
}
public String getId() {
return id;
}
@ -69,6 +78,22 @@ public class Node {
}
public double getVx() {
return vx;
}
public void setVx(double vx) {
this.vx = vx;
}
public double getVy() {
return vy;
}
public void setVy(double vy) {
this.vy = vy;
}
@Override
public String toString() {
return "Node{" +

View File

@ -0,0 +1,32 @@
package com.actionsoft.apps.coe.method.process.subprocess.mode.vo;
/**
* @author oYang
* @create 2023-05-17 15:13
*/
public class IndependentNodeVo {
private String id;
private String name;
public IndependentNodeVo(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -3,6 +3,7 @@ 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.*;
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
import com.actionsoft.apps.coe.method.process.subprocess.mode.vo.IndependentNodeVo;
import com.actionsoft.apps.coe.method.process.subprocess.mode.vo.SubProcessTagVo;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryQueryAPIManager;
@ -19,6 +20,9 @@ import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import com.actionsoft.apps.coe.pal.pal.repository.model.impl.PALRepositoryModelImpl;
import com.actionsoft.apps.coe.pal.pal.repository.util.CoeProcessLevelUtil;
import com.actionsoft.apps.coe.pal.pal.repository.web.CoeProcessLevelWeb;
import com.actionsoft.apps.coe.pal.pal.ws.dao.CoeWorkSpace;
import com.actionsoft.apps.coe.pal.pal.ws.dao.CoeWorkSpaceDaoFactory;
import com.actionsoft.apps.coe.pal.pal.ws.model.CoeWorkSpaceModel;
import com.actionsoft.bpms.commons.mvc.view.ActionWeb;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
@ -49,20 +53,32 @@ public class SubProcessWeb extends ActionWeb {
}
public String initData() throws AWSException{
// {资产库名称}/{根目录}/{一级目录} 伊利/流程制度/专门存放端到端总图
// 获取端到端文件存储的根目录
String property = SDK.getAppAPI().getProperty(SubProcessConst.APP_ID, SubProcessConst.SUB_PROCESS_MODEL_LOCATION);
if (UtilString.isEmpty(property))
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】异常");
String[] locationIds = property.split("/");
String[] locationPathNames = property.split("/");
if (locationPathNames.length != 3)
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】异常");
CoeWorkSpace workSpace = CoeWorkSpaceDaoFactory.createCoeWorkSpace();
List<CoeWorkSpaceModel> workSpaceModels = workSpace.getInstanceAll();
Optional<CoeWorkSpaceModel> o1 = workSpaceModels.stream().filter(coeWorkSpaceModel -> locationPathNames[0].equals(coeWorkSpaceModel.getWsName())).findFirst();
if (!o1.isPresent())
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】中配置的资产库【"+locationPathNames[0]+"】不存在");
String workSpaceId = o1.get().getUUId();
// 查看一级目录是否存在
List<PALRepositoryModel> modelList = IteratorUtils.toList(PALRepositoryCache.getByPid(workSpaceId, "process"));
Optional<PALRepositoryModel> o2 = modelList.stream().filter(repositoryModel -> locationPathNames[2].equals(repositoryModel.getName())).findFirst();
if (!o2.isPresent())
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】中配置的一级目录【"+locationPathNames[2]+"】不存在");
PALRepositoryModel repositoryModel = o2.get();
StringBuffer dirName = new StringBuffer(I18nRes.findValue(CoEConstant.APP_ID, locationIds[0]) + "/");
PALRepositoryModel model = PALRepositoryCache.getCache().get(locationIds[1]);
if (model == null)
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】中配置的一级目录在当前资产库中不存在");
dirName.append(model.getName()).append("/");
ResponseObject ro = ResponseObject.newOkResponse();
ro.put("dirRootName", dirName.toString());
ro.put("dirRootPath", property);
ro.put("dirRootName", locationPathNames[1] + "/" + locationPathNames[2]);
ro.put("dirRootPath", workSpaceId + "/process/" + repositoryModel.getId());
ro.put("locationId", repositoryModel.getId());
return ro.toString();
}
@ -186,20 +202,20 @@ public class SubProcessWeb extends ActionWeb {
String property = SDK.getAppAPI().getProperty(SubProcessConst.APP_ID, SubProcessConst.SUB_PROCESS_MODEL_LOCATION);
if (UtilString.isEmpty(property))
throw new AWSException("应用参数【" + SubProcessConst.SUB_PROCESS_MODEL_LOCATION + "】异常");
String[] locationIds = property.split("/");
String[] locationIdPathNames = property.split("/");
if (UtilString.isEmpty(pid)){
JSONArray result = PALRepositoryQueryAPIManager.getInstance().getPalRepositoryTreeRoot(uc, wsId, null, teamId);
result = result.stream()
.filter(item -> {
JSONObject model = (JSONObject) item;
return locationIds[0].equals(model.getString("id"));
return "process".equals(model.getString("id"));
}).collect(Collectors.toCollection(JSONArray :: new));
return result;
}
JSONArray result = PALRepositoryQueryAPIManager.getInstance().getUsedPalRepositoryTreeDataByPidNew(uc, wsId, teamId, pid);
if (locationIds[0].equals(pid)){
if ("process".equals(pid)){
result = result.stream()
.filter(item -> locationIds[1].equals(((JSONObject)item).getString("id")))
.filter(item -> locationIdPathNames[2].equals(((JSONObject)item).getString("name")))
.collect(Collectors.toCollection(JSONArray :: new));
return result;
}
@ -212,15 +228,45 @@ public class SubProcessWeb extends ActionWeb {
return result;
}
/**
* 生成图->前置处理独立节点
* @param uc
* @param processIdJsonArr
* @return
*/
public List<IndependentNodeVo> vertexPreHandleIndependentNode(String processIdJsonArr) throws AWSException{
List<String> processIdList = JSONArray.parseArray(processIdJsonArr, String.class);
// 节点预处理
VertexPreHandle vertexPreHandle = new VertexPreHandle();
return vertexPreHandle.collectIndependentNode(processIdList);
}
/**
* 生成图->前置处理
* 前置流程或后置流程是否在所选的范围内
* @param uc
* @param processIdJsonArr
* @param excludeProcessIdJsonArr
* @return
*/
public void vertexPreHandle2(String processIdJsonArr, String excludeProcessIdJsonArr){
List<String> processIdList = JSONArray.parseArray(processIdJsonArr, String.class);
List<String> excludeProcessIdList = JSONArray.parseArray(excludeProcessIdJsonArr, String.class);
}
public void generatorEndToEndModel(String processIdJsonArr, String locationId, String direction, String modelName) throws AWSException{
if (UtilString.isEmpty(processIdJsonArr))
throw new AWSException("参数异常");
List<String> processIdList = JSONArray.parseArray(processIdJsonArr, String.class);
// 节点预处理
Map<String, Integer> nodeIndexMap = new HashMap<>();
VertexPreHandle vertexPreHandle = new VertexPreHandle();
Map<String, Integer> nodeIndexMap = new HashMap<>();
List<Node> nodeList = vertexPreHandle.includeLearAndRearNode(processIdList, nodeIndexMap);
// 构建有向图邻接矩阵

View File

@ -17,6 +17,9 @@
<param name="teamId"/>
<param name="pid"/>
</cmd-bean>
<cmd-bean name="com.actionsoft.apps.coe.method.process.subprocess.independent_node_pre_handle">
<param name="processIdJsonArr"/>
</cmd-bean>
<cmd-bean name="com.actionsoft.apps.coe.method.process.subprocess.generator_end_to_end_model">
<param name="processIdJsonArr"/>
<param name="locationId"/>

View File

@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.actionsoft.bpms.commons.database.BatchPreparedStatementSetter;
import com.actionsoft.bpms.commons.database.RowMapper;
@ -464,6 +465,19 @@ public class DesignerShapeRelationDao extends DaoObject<DesignerShapeRelationMod
return DBSql.query(sql.toString(), rowMapper(), shapeId, relationFileId);
}
}
/**
* 根据指定属性及被关联的文件查询源文件
* @param relationFileId
* @param attrIdList
* @return
*/
public List<DesignerShapeRelationModel> getModelListByRelationFileIdAndAttrIds(String relationFileId, List<String> attrIdList){
attrIdList = attrIdList.stream().map(item -> "'" + item + "'").collect(Collectors.toList());
String attrIdS = String.join(",", attrIdList);
String sql = "select * from " + entityName() + " where RELATIONFILEID = ? and ATTRID in (" + attrIdS + ")";
return DBSql.query(sql, rowMapper(), relationFileId);
}
/**
* 查询图形A与文件B的关联信息