Excel导入流程图review 实现过程,修改特殊图形的处理方式

This commit is contained in:
anhc 2022-09-19 14:30:31 +08:00
parent 36c70877ce
commit 7c18223db9
2 changed files with 177 additions and 552 deletions

View File

@ -4,8 +4,6 @@ import com.actionsoft.apps.coe.pal.batch.constant.BatchConst;
import com.actionsoft.apps.coe.pal.batch.util.LogUtil;
import com.actionsoft.apps.coe.pal.batch.web.create.shape.model.CellObject;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryAPIManager;
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.constant.CoeDesignerConstant;
import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager;
@ -17,7 +15,6 @@ import com.actionsoft.apps.coe.pal.pal.repository.designer.util.CoeDesignerUtil;
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import com.actionsoft.apps.coe.pal.yili.log.datamigration.log.Cache.LogRealTimeCountCache;
import com.actionsoft.apps.coe.pal.yili.log.datamigration.log.Model.LogRealTimeCountModel;
import com.actionsoft.bpms.commons.security.logging.model.Level;
import com.actionsoft.bpms.org.model.DepartmentModel;
import com.actionsoft.bpms.org.model.RoleModel;
import com.actionsoft.bpms.org.model.UserModel;
@ -30,15 +27,10 @@ import com.actionsoft.sdk.local.SDK;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.AtomicDouble;
import org.apache.commons.lang.StringUtils;
import org.codehaus.groovy.util.ListHashMap;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
@ -68,12 +60,8 @@ public class ImportShapeExcel1 {
this.fullLogFile = fullLogFile;
this.simpleLogFile = simpleLogFile;
// 单独创建一个成功日志
// successLogFile = new File(fullLogFile.getParentFile().getPath() + File.separator + BatchConst.IMPORT_LOG_FILE_SUCCESS);
// matchErrImportFile = new File(fullLogFile.getParentFile().getPath() + File.separator + BatchConst.IMPORT_LOG_FILE_MATCH_ERR);
checkTableFile = new File(fullLogFile.getParentFile().getPath() + File.separator + BatchConst.IMPORT_LOG_FILE_CHECK_TABLE);
try {
// successLogFile.createNewFile();
// matchErrImportFile.createNewFile();
checkTableFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
@ -89,21 +77,15 @@ public class ImportShapeExcel1 {
LogUtil.appendLog("\n[信息]操作人:" + uc.getUserName() + "<" + uc.getUID() + ">", simpleLogFile, fullLogFile);
LogUtil.appendLog("[信息]操作时间:" + UtilDate.datetimeFormat(startDate), simpleLogFile, fullLogFile);
// todo
// LogUtil.appendLog("[信息]模型文件:" + fileName, simpleLogFile, fullLogFile);
// LogUtil.appendLog("[信息]模型文件路径:" + filePath, simpleLogFile, fullLogFile);
LogUtil.appendLog("PAL 泳道图Excel批量导入模型 Begin " + UtilDate.datetimeFormat(startDate), simpleLogFile, fullLogFile);
LogUtil.appendLog("--------------------------------", simpleLogFile, fullLogFile);
LogUtil.appendLog("若模型存在多版本,只与模型使用中版本进行匹配,过往版本忽略不进行任何处理,若最新版本模型非可编辑状态(已发布、已停用、审批中),直接跳过该模型,不做任何调整", simpleLogFile, fullLogFile);
//前端入参table数据读取
JSONObject data = object.getJSONObject("data");
JSONArray importData = data.getJSONArray("okData");
//文件下根据分支分组表格数据
Map<String,Map<String,List<CellObject>>> fileData = new LinkedHashMap<>();
this.collectTableCellBranch(importData,fileData);
@ -112,32 +94,28 @@ public class ImportShapeExcel1 {
Map<String,Map<String,Map<String,Map<String, List<CellObject>>>>> fileDataMap = new LinkedHashMap<>();
//文件下特殊分支处理, 只绘制图形不连线
Map<String,List<CellObject>> specialMap = new LinkedHashMap<>();
this.transformCollectBranchToCellMap(fileData,fileDataMap,specialMap);
// 放入cache
// 日志放入cache
int totalCount = fileDataMap.size();
LogRealTimeCountModel countModel = new LogRealTimeCountModel();
countModel.setTotalCount(totalCount);
countModel.setSuccessCount(0);
LogRealTimeCountCache.getCache().put(logId, countModel, true);
//根据基准数据绘制图形+连线关系
for (String repositoryId : fileDataMap.keySet()) {
//全局初始偏移量每个分支最右侧分界线
double offsetX = ShapeConst.SHAPE_BRANCH_INTERVAL;
double rightMaxLine = 0;
LogUtil.appendLog("准备导入" + I18nRes.findValue(CoEConstant.APP_ID, methodCategory) + "数据[开始]", fullLogFile);
//计算后形状与连线保存这里顺序
//计算后形状与连线保存数据保存
Map<String,List<JSONObject>> nodeMap = new LinkedHashMap<>();
// 形状关联属性结果集
//形状关联属性结果集
List<DesignerShapeRelationModel> relationList = new ArrayList<>();
//常规图形绘制
//多分支常规图形绘制
LogUtil.appendLog(BatchConst.LOG_DESC + "[执行阶段][绘制常规分支图形]", simpleLogFile, fullLogFile);
Map<String, Map<String, Map<String, List<CellObject>>>> branchData = fileDataMap.get(repositoryId);
JSONObject drawBranchShape = this.drawBranchShape(repositoryId, branchData, offsetX, nodeMap, relationList);
@ -152,30 +130,12 @@ public class ImportShapeExcel1 {
//特殊图形绘制
LogUtil.appendLog(BatchConst.LOG_DESC + "[执行阶段][绘制特殊分支图形]", simpleLogFile, fullLogFile);
List<CellObject> specicalCell = specialMap.get(repositoryId);
if (specicalCell == null || specicalCell.isEmpty()){
continue;
}
for (int i = 0; i < specicalCell.size(); i++) {
CellObject node = specicalCell.get(i);
//节点的图形数据
List<JSONObject> shapes = new ArrayList<>();
//节点画图,
JSONObject shape =this.drawShape(node, 0, offsetX, i, i);
//计算最右边界
rightMaxLine = this.getrightMaxLine(shape,rightMaxLine);
shapes.add(shape);
nodeMap.put(this.getCellObjectUUID(node),shapes);
}
rightMaxLine = this.drawSpecialShape(offsetX,rightMaxLine,specicalCell,nodeMap);
//文件操作
LogUtil.appendLog(BatchConst.LOG_END + "[执行阶段][保存模型阶段]", simpleLogFile, fullLogFile);
this.saveDefine(repositoryId,nodeMap,rightMaxLine,maxLevel);
//关联属性处理
DesignerShapeRelationDao relationDao = new DesignerShapeRelationDao();
if (relationList.size() == 0) {
@ -195,24 +155,18 @@ public class ImportShapeExcel1 {
LogUtil.appendLog(BatchConst.LOG_WARNING + "新增形状属性关联属性内容失败详情查看BPM平台运行日志", simpleLogFile, fullLogFile);
}
}
}
endTime = System.currentTimeMillis();
Timestamp endDate = new Timestamp(endTime);
LogRealTimeCountModel model = LogRealTimeCountCache.getCache().get(logId);
String takeTimeText = takeTime(endTime, startTime);
String resultMsg = "导入完成,总耗时" + takeTimeText + ",模型清单总共[" + model.getTotalCount() + "],导入成功[" + model.getSuccessCount() + "]条,导入失败[" + (model.getTotalCount() - model.getSuccessCount())
+ "]条)";
String resultMsg = "导入完成,总耗时" + takeTimeText + ",模型清单总共[" + model.getTotalCount() + "],导入成功[" + model.getSuccessCount() + "]条,导入失败[" + (model.getTotalCount() - model.getSuccessCount()) + "]条)";
LogUtil.appendLog("\n" + BatchConst.LOG_END + resultMsg, simpleLogFile, fullLogFile);
LogUtil.appendLog("\n" + "PAL批量导入模型 End " + UtilDate.datetimeFormat(endDate), simpleLogFile, fullLogFile);
LogUtil.appendLog("--------------------------------", simpleLogFile, fullLogFile);
LogUtil.appendLog(BatchConst.END_LOG, simpleLogFile, fullLogFile);
LogUtil.appendLog(BatchConst.LOG_END + "[执行结束][Excel导入完成]", simpleLogFile, fullLogFile);
LogRealTimeCountCache.getCache().remove(logId);
// 关联属性缓存重新刷新
@ -233,8 +187,6 @@ public class ImportShapeExcel1 {
double offsetX = originOffsetX;
int maxLevelNum = 0;
for (Map.Entry<String, Map<String, Map<String, List<CellObject>>>> branch : branchData.entrySet()) {
// <层级同级别map>
Map<String, Map<String, List<CellObject>>> levelMap = branch.getValue();
@ -244,123 +196,25 @@ public class ImportShapeExcel1 {
maxLevelNum = Math.max(maxLevel,maxLevelNum);
//遍历层级产出图+连线
for (int level = 0; level < maxLevel; level++) {
//同层级多分支节点信息, <序号同序号listNode>
Map<String, List<CellObject>> numList = levelMap.get("" + level);
//计算同层级索引
int levelNodeIndex = 0;
for (int i = 0; i < numList.keySet().size()+1; i++) {
//构建同层级的分支序号
String levelNo = this.getLevelNo(level, i);
//当前分支的最终节点同序号节点list
List<CellObject> nodes = numList.get(levelNo);
if (null == nodes){
continue;
}
//找到上级节点可跨级
JSONObject upNodes = this.findUpLevelNode(levelNo, levelMap, nodeMap);
JSONArray upList = upNodes.getJSONArray("upList");
//根据上级计算offset没有上级一个上级多个上级
double levelOffset = offsetX;
int size = 1;
if (null !=upList && !upList.isEmpty()){
if (upList.size()==1){
//只有一个上级节点
JSONObject upNode = upList.getJSONObject(0);
levelOffset = upNode.getJSONObject("props").getDouble("x");
if (upNode.getString("shapeNum").contains(".")){
//分支下的分支计算偏移量重新计算
levelNodeIndex = 0;
size = nodes.size();
}else {
size = numList.keySet().size();
}
}else{
if (levelNo.contains(".")){
//当前节点是分支下节点
//多个父级节点计算偏移量
Double minX = null;
Double maxX = null;
for (int upIndex = 0; upIndex < upList.size(); upIndex++) {
JSONObject upNode = upList.getJSONObject(upIndex);
JSONObject props = (JSONObject)upNode.get("props");
if (minX == null && maxX == null){
minX = props.getDouble("x");
maxX = minX;
}
maxX = Math.max(props.getDouble("x"), maxX);
minX = Math.min(props.getDouble("x"), minX);
}
levelOffset =((maxX - minX) * 0.5 ) + minX;
}
}
}
//同级别节点是一分二分节点三分节点计算offset
double offset = this.getLevelStartNodeOffset(size,levelOffset);
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++,levelNodeIndex++) {
CellObject node = nodes.get(nodeIndex);
//保存当前节点的图形数据+连线数据
List<JSONObject> shapes = new ArrayList<>();
//绘制当前节点图形
JSONObject shape = this.drawShape(node, levelNodeIndex, offset, level, i);
LogUtil.appendLog(BatchConst.LOG_START + "[新增][" + node.getShapeName() + "]形状", simpleLogFile, fullLogFile);
LogUtil.appendLog(BatchConst.LOG_START + "[新增][" + node.getShapeName() + "]形状,形状类型[" + node.getShapeType() + "]", fullLogFile);
//计算最右边边界
rightMaxLine = this.getrightMaxLine(shape, rightMaxLine);
//图形拓展属性处理
JSONArray expandArr = node.getExpandArr();
this.handleExpandAttr(repositoryId,shape,expandArr,relationList);
shapes.add(shape);
if (upNodes.getBooleanValue("isUp")){
//存在父级节点计算与上级节点list的连线
if (nodes.size()>1 && upList.size()>1){
//多下级与多上级的连线不处理
continue;
}
//与多个上级节点直接连线
for (Object o : upList) {
JSONObject linker = this.drawLinker((JSONObject) o, shape, nodeIndex);
shapes.add(linker);
}
}
//计算最终确定位置map的key名称+类型+序号
nodeMap.put(this.getCellObjectUUID(node),shapes);
}
}
}
rightMaxLine = this.drawShapeAndLinker(repositoryId, maxLevel, offsetX, rightMaxLine, levelMap, nodeMap, relationList);
//位置重叠偏移计算
//左边界
double leftMinLine = offsetX - ShapeConst.SHAPE_BRANCH_INTERVAL;
JSONObject object = this.changeShapePosition(levelMap, nodeMap, offsetX, rightMaxLine, leftMinLine);
Double changeLeftMinLine = object.getDouble("leftMinLine");
Double changeRightMaxLine = object.getDouble("rightMaxLine");
rightMaxLine = Math.max(changeRightMaxLine,rightMaxLine);
//比较返回左边界<leftMinLine 则需要将分支整体向右调整offset = leftMinLine - 左边界
// 整体调整分支偏移量比较返回左边界<leftMinLine 则需要将分支整体向右调整offset = leftMinLine - 左边界
if (changeLeftMinLine <= leftMinLine){
//整体调整分支偏移量
//计算偏移
double offset = leftMinLine - changeLeftMinLine + 100;
double moveToRightOffset = this.branchMoveToRight(levelMap, nodeMap, offset, rightMaxLine);
rightMaxLine = Math.max(moveToRightOffset,rightMaxLine);
}
//下一个分支偏移量
offsetX = rightMaxLine + ShapeConst.SHAPE_BRANCH_INTERVAL;
}
@ -370,6 +224,122 @@ public class ImportShapeExcel1 {
return res;
}
/**
* 绘制特殊处理的图形只画图不连线
* @param offsetX
* @param rightMaxLine
* @param specicalCell
* @param nodeMap
* @return
*/
private double drawSpecialShape(double offsetX,double rightMaxLine,List<CellObject> specicalCell,Map<String,List<JSONObject>> nodeMap){
if (null == specicalCell){
return rightMaxLine;
}
for (int i = 0; i < specicalCell.size(); i++) {
CellObject node = specicalCell.get(i);
//节点的图形数据
List<JSONObject> shapes = new ArrayList<>();
//节点画图,
JSONObject shape =this.drawShape(node, 0, offsetX, i, i);
//计算最右边界
rightMaxLine = this.getRightMaxLine(shape,rightMaxLine);
shapes.add(shape);
nodeMap.put(this.getCellObjectUUID(node),shapes);
}
return rightMaxLine;
}
/**
* 绘制分支数据的图形+连线
* @param repositoryId
* @param maxLevel
* @param offsetX
* @param rightMaxLine
* @param levelMap
* @param nodeMap
* @param relationList
* @return
*/
private double drawShapeAndLinker(String repositoryId,int maxLevel,double offsetX ,double rightMaxLine,Map<String, Map<String, List<CellObject>>> levelMap,Map<String,List<JSONObject>> nodeMap,List<DesignerShapeRelationModel> relationList){
for (int level = 0; level < maxLevel; level++) {
//同层级多分支节点信息, <序号同序号listNode>
Map<String, List<CellObject>> numList = levelMap.get("" + level);
if (null == numList){
continue;
}
//计算同层级索引
int levelNodeIndex = 0;
for (int i = 0; i < numList.keySet().size()+1; i++) {
//构建同层级的分支序号
String levelNo = this.getLevelNo(level, i);
//当前分支的最终节点同序号节点list
List<CellObject> nodes = numList.get(levelNo);
if (null == nodes){
continue;
}
//找到上级节点可跨级
JSONObject upNodes = this.findUpLevelNode(levelNo, levelMap, nodeMap);
JSONArray upList = upNodes.getJSONArray("upList");
// 根据上级计算offset没有上级一个上级多个上级
double offset = this.getLevelStartNodeOffset(levelNo,offsetX,upList,nodes,numList);
// 分支下的分支计算同序号偏移量重新计算
if (null != upList && !upList.isEmpty() && upList.size()==1 && upList.getJSONObject(0).getString("shapeNum").contains(".")){
levelNodeIndex = 0;
}
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++,levelNodeIndex++) {
CellObject node = nodes.get(nodeIndex);
//保存当前节点的图形数据+连线数据
List<JSONObject> shapes = new ArrayList<>();
//绘制当前节点图形
JSONObject shape = this.drawShape(node, levelNodeIndex, offset, level, i);
LogUtil.appendLog(BatchConst.LOG_START + "[新增][" + node.getShapeName() + "]形状", simpleLogFile, fullLogFile);
LogUtil.appendLog(BatchConst.LOG_START + "[新增][" + node.getShapeName() + "]形状,形状类型[" + node.getShapeType() + "]", fullLogFile);
//计算最右边边界
rightMaxLine = this.getRightMaxLine(shape, rightMaxLine);
//图形拓展属性处理
JSONArray expandArr = node.getExpandArr();
this.handleExpandAttr(repositoryId,shape,expandArr,relationList);
shapes.add(shape);
//存在父级节点计算与上级节点list的连线
if (upNodes.getBooleanValue("isUp")){
if (nodes.size()>1 && upList.size()>1){
//多下级与多上级的连线不处理
continue;
}
//与多个上级节点直接连线
for (Object o : upList) {
JSONObject linker = this.drawLinker((JSONObject) o, shape, nodeIndex);
shapes.add(linker);
}
}
//计算最终确定位置map的key名称+类型+序号
nodeMap.put(this.getCellObjectUUID(node),shapes);
}
}
}
return rightMaxLine;
}
private double branchMoveToRight(Map<String, Map<String, List<CellObject>>> levelMap,Map<String,List<JSONObject>> nodeMap,double offset,double rightMaxLine){
double rightLine = rightMaxLine;
@ -418,7 +388,7 @@ public class ImportShapeExcel1 {
props.put("x",(double) x + offset);
//计算最右边界
rightLine = this.getrightMaxLine(shape,rightLine);
rightLine = this.getRightMaxLine(shape,rightLine);
}
}
}
@ -485,11 +455,9 @@ public class ImportShapeExcel1 {
for (int level = maxLevel-1; level>=startLevel; level--){
//同层级多分支节点信息
Map<String, List<CellObject>> numList = levelMap.get("" + level);
// if (numList.keySet().size()<=1 && !numList.keySet().contains(".")){
// //只调整分支节点
// continue;
// }
if (null == numList){
continue;
}
//奇数左半部分支调整,逆序
int branchMedian = (int) medianBranch;
@ -498,7 +466,6 @@ public class ImportShapeExcel1 {
String leftLevelNo = this.getLevelNo(level, i);
String rightLevelNo = this.getLevelNo(level,i+1);
//同分支序号多节点list
List<CellObject> leftNodes = numList.get(leftLevelNo);
List<CellObject> rightNodes = numList.get(rightLevelNo);
@ -506,10 +473,6 @@ public class ImportShapeExcel1 {
continue;
}
if (leftLevelNo.equals("4.1")){
Object o = new Object();
}
if (rightNodes == null || rightNodes.isEmpty()){
//递归向上找分支结点
rightNodes = this.findUpBranchNode(levelMap,rightLevelNo);
@ -518,16 +481,14 @@ public class ImportShapeExcel1 {
}
}
//左右节点的起始X偏移量
double leftShapeX = this.getNumListLeftShapeX(leftNodes, nodeMap);
double rightShapeX = this.getNumListRightShapeX(rightNodes, nodeMap);
if (leftShapeX + 15 > rightShapeX){
//需要调整,向左边移动
double offset = leftShapeX - (rightShapeX - ShapeConst.SHAPE_NODE_INTERVAL - ShapeConst.SHAPE_NODE_WIDTH );
double leftOffset = this.leftOffsetNode(leftNodes, levelMap, nodeMap, offset, leftMinLine);
res.put("leftMinLine",Math.min(leftOffset,leftMinLine));
}
}
@ -537,6 +498,7 @@ public class ImportShapeExcel1 {
//构建同层级的分支序号
String leftLevelNo = this.getLevelNo(level, i);
String rightLevelNo = this.getLevelNo(level,i+1);
//同分支序号多节点list
List<CellObject> leftNodes = numList.get(leftLevelNo);
List<CellObject> rightNodes = numList.get(rightLevelNo);
@ -558,7 +520,6 @@ public class ImportShapeExcel1 {
//需要调整向右边移动
double offset = leftShapeX + ShapeConst.SHAPE_NODE_INTERVAL + ShapeConst.SHAPE_NODE_WIDTH;
double rightOffset = this.rightOffsetNode(rightNodes, levelMap, nodeMap, offset, rightMaxLine);
res.put("rightMaxLine",Math.max(rightMaxLine,rightOffset));
}
}
@ -577,12 +538,11 @@ public class ImportShapeExcel1 {
for (int level = maxLevel-1; level>=startLevel; level--){
//同层级多分支节点信息
Map<String, List<CellObject>> numList = levelMap.get("" + level);
if (numList.keySet().size()<=1){
if (null == numList){
//只调整分支节点
continue;
}
//偶数左半部分支调整,逆序
int branchMedian = (int) Math.ceil(medianBranch);
for (int i = branchMedian-1; i >=1; i--){
@ -610,7 +570,6 @@ public class ImportShapeExcel1 {
//需要调整,向左边移动
double offset = leftShapeX - (rightShapeX - ShapeConst.SHAPE_NODE_INTERVAL - ShapeConst.SHAPE_NODE_WIDTH );
double leftOffset = this.leftOffsetNode(leftNodes, levelMap, nodeMap, offset, leftMinLine);
res.put("leftMinLine",Math.min(leftMinLine,leftOffset));
}
}
@ -621,7 +580,6 @@ public class ImportShapeExcel1 {
//构建同层级的分支序号
String leftLevelNo = "-1";
String rightLevelNo = this.getLevelNo(level,i+1);
if (i > medianBranch){
leftLevelNo = this.getLevelNo(level, i);
}
@ -645,11 +603,9 @@ public class ImportShapeExcel1 {
//需要调整向右边移动
double offset = leftShapeX + ShapeConst.SHAPE_NODE_INTERVAL + ShapeConst.SHAPE_NODE_WIDTH;
double rightOffset = this.rightOffsetNode(rightNodes, levelMap, nodeMap, offset, rightMaxLine);
res.put("rightMaxLine",Math.max(rightMaxLine,rightOffset));
}
}
}
return res;
@ -1004,7 +960,7 @@ public class ImportShapeExcel1 {
return jsonObjects == null || jsonObjects.isEmpty() ? null:jsonObjects.get(0);
}
private double getrightMaxLine(JSONObject shape,double rightMaxLine){
private double getRightMaxLine(JSONObject shape, double rightMaxLine){
if (null == shape){
return 0;
}
@ -1361,13 +1317,15 @@ public class ImportShapeExcel1 {
private void collectTableCellBranch(JSONArray importData,Map<String,Map<String,List<CellObject>>> fileData){
for (int i = 0; i < importData.size(); i++) {
JSONObject rowData = importData.getJSONObject(i);
if (!rowData.getBoolean("isRowOk")){
continue;
}
String repositoryId = rowData.getString("repositoryId");
Map<String,List<CellObject>> branchMap = fileData.get(repositoryId);
if (branchMap == null){
branchMap = new LinkedHashMap<>();
}
String branch = "";
//解析入参的table数据
@ -1699,6 +1657,44 @@ public class ImportShapeExcel1 {
return branch;
}
private double getLevelStartNodeOffset(String levelNo, double offsetX,JSONArray upList,List<CellObject> nodes,Map<String, List<CellObject>> numList){
//根据上级计算offset没有上级一个上级多个上级
double levelOffset = offsetX;
int size = 1;
if (null !=upList && !upList.isEmpty()){
if (upList.size()==1){
//只有一个上级节点
JSONObject upNode = upList.getJSONObject(0);
levelOffset = upNode.getJSONObject("props").getDouble("x");
if (upNode.getString("shapeNum").contains(".")){
size = nodes.size();
}else {
size = numList.keySet().size();
}
}else{
if (levelNo.contains(".")){
//当前节点是分支下节点
//多个父级节点计算偏移量
Double minX = null;
Double maxX = null;
for (int upIndex = 0; upIndex < upList.size(); upIndex++) {
JSONObject upNode = upList.getJSONObject(upIndex);
JSONObject props = (JSONObject)upNode.get("props");
if (minX == null && maxX == null){
minX = props.getDouble("x");
maxX = minX;
}
maxX = Math.max(props.getDouble("x"), maxX);
minX = Math.min(props.getDouble("x"), minX);
}
levelOffset =((maxX - minX) * 0.5 ) + minX;
}
}
}
// 同级别节点是一分二分节点三分节点计算offset
return this.getLevelStartNodeOffset(size,levelOffset);
}
/**
* 计算同级别节点初始偏移量
@ -1724,6 +1720,7 @@ public class ImportShapeExcel1 {
double res = offset - r - w;
return res;
}
private double drawShapeX (int index,double offset){
double x = index * (ShapeConst.SHAPE_NODE_WIDTH + ShapeConst.SHAPE_NODE_INTERVAL) + offset;
return x;
@ -1762,129 +1759,6 @@ public class ImportShapeExcel1 {
return point;
}
/**
* 获取已有形状的最大纵向高度
* @param elements
* @return
*/
private int getMaxPositionY(JSONObject elements) {
int max = 0;
Iterator<String> it = elements.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
JSONObject shape = elements.getJSONObject(key);
String shapeName = shape.getString("name");
if(!"linker".equals(shapeName)) {
JSONObject props = shape.getJSONObject("props");
int y = props.getIntValue("y") + props.getIntValue("h");
max = max > y ? max : y;
}
}
return max;
}
/**
* 获取形状的最大层级zindex
* @param elements
* @return
*/
private int getMaxPropsZIndex(JSONObject elements) {
int max = 0;
Iterator<String> it = elements.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
JSONObject shape = elements.getJSONObject(key);
JSONObject props = shape.getJSONObject("props");
int zindex = props.getIntValue("zindex");
max = max > zindex ? max : zindex;
}
return max;
}
/**
* 数据更新/新增处理
* @param palModel
* @param palId
* @param elements
* @param relationDao
* @param relationModelList
* @param delRelationIdList
*/
private void batchOpData(PALRepositoryModel palModel, String palId, JSONObject elements, DesignerShapeRelationDao relationDao, List<DesignerShapeRelationModel> relationModelList, List<DesignerShapeRelationModel> delRelationIdList) {
handleShapeDefaultAttr(wsId, palModel, elements, methodAttrsMap);
BaseModel defineModel = CoeDesignerAPIManager.getInstance().getDefinition(palId, 0);
if (defineModel == null) {
defineModel = CoeDesignerUtil.createModel(palId, 0);
defineModel.setCreateHistory(false);
}
String define = defineModel.getDefinition();
JSONObject definition = JSONObject.parseObject(define);
definition.put("elements", elements);
defineModel.setDefinition(definition.toString());
defineModel.setUpdateTime(new SimpleDateFormat(CoeDesignerConstant.DATE_TIME_STYLE_YYYY_MM_DD_HH_MM_SS).format(new Date()));
// 保存文件
LogUtil.appendLog(BatchConst.LOG_START + "保存流程文件", fullLogFile);
CoeDesignerAPIManager.getInstance().storeDefinition(defineModel);// dao操作
LogUtil.appendLog(BatchConst.LOG_END + "保存流程文件", fullLogFile);
if (relationModelList.size() == 0) {
LogUtil.appendLog(BatchConst.LOG_WARNING + "新增形状属性关联属性内容忽略", simpleLogFile, fullLogFile);
} else {
LogUtil.appendLog(BatchConst.LOG_START + "新增形状属性关联属性内容", simpleLogFile, fullLogFile);
boolean insertProps = relationDao.barchInsert(relationModelList);
if (insertProps) {
for (int i = 0; i < relationModelList.size(); i++) {
String name = relationModelList.get(i).getAttrId();
String value = relationModelList.get(i).getRelationShapeText();
LogUtil.appendLog(BatchConst.LOG_DESC + "形状属性关联属性内容[" + name + "],属性内容值为[" + value + "]", simpleLogFile, fullLogFile);
}
LogUtil.appendLog(BatchConst.LOG_END + "新增形状属性关联属性内容,总共新增[" + relationModelList.size() + "]条", simpleLogFile, fullLogFile);
} else {
LogUtil.appendLog(BatchConst.LOG_WARNING + "新增形状属性关联属性内容失败详情查看BPM平台运行日志", simpleLogFile, fullLogFile);
}
}
if (delRelationIdList.size() == 0) {
LogUtil.appendLog(BatchConst.LOG_WARNING + "删除原有形状属性关联属性内容忽略", simpleLogFile, fullLogFile);
} else {
LogUtil.appendLog(BatchConst.LOG_START + "删除原有形状属性关联属性内容", simpleLogFile, fullLogFile);
try {
relationDao.batchDeleteRelationListById(delRelationIdList);
for (int i = 0; i < delRelationIdList.size(); i++) {
String name = delRelationIdList.get(i).getAttrId();
String value = delRelationIdList.get(i).getRelationShapeText();
LogUtil.appendLog(BatchConst.LOG_DESC + "删除原有形状属性关联属性内容[" + name + "],属性内容值为[" + value + "]", simpleLogFile, fullLogFile);
}
LogUtil.appendLog(BatchConst.LOG_END + "删除原有形状属性关联属性内容,总共删除[" + delRelationIdList.size() + "]条", simpleLogFile, fullLogFile);
} catch (SQLException e) {
e.printStackTrace();
LogUtil.appendLog(BatchConst.LOG_WARNING + "删除原有形状属性关联属性内容失败详情查看BPM平台运行日志", simpleLogFile, fullLogFile);
}
}
LogUtil.appendLog("导入 " + palModel.getName() + "(v" + palModel.getVersion() + ".0)" + " 流程模型结构[完成]", simpleLogFile, fullLogFile);
// 更新其他自定义属性
LogUtil.appendLog(BatchConst.LOG_START + "完善模型内形状自定义属性配置", simpleLogFile, fullLogFile);
PALRepositoryAPIManager.getInstance().updateRepositoryProperty(palModel.getId());
LogUtil.appendLog(BatchConst.LOG_END + "完善模型内形状自定义属性配置", simpleLogFile, fullLogFile);
LogUtil.appendLog(BatchConst.LOG_END + "[执行阶段][保存模型阶段]", simpleLogFile, fullLogFile);
// 记录成功日志记录
LogRealTimeCountCache.getCache().get(logId).setSuccessCount(LogRealTimeCountCache.getCache().get(logId).getSuccessCount() + 1);
}
/**
* 自定义属性
* @param wsId
@ -1968,58 +1842,6 @@ public class ImportShapeExcel1 {
return object2;
}
/**
* 按照模型进行分类
* @param importData
* @return
*/
private Map<String, Map<String, List<JSONObject>>> handleRepositoryData(JSONArray importData) {
Map<String, Map<String, List<JSONObject>>> result = new LinkedHashMap<>();
for (int i = 0; i < importData.size(); i++) {
JSONObject row = importData.getJSONObject(i);
String palId = row.getString("repositoryId");
String type = row.getString("result");// add/update
String shapeId = row.getString("shapeId");
if (!result.containsKey(palId)) {
result.put(palId, new HashMap<>());
}
if (!result.get(palId).containsKey(type)) {
result.get(palId).put(type, new ArrayList<>());
}
result.get(palId).get(type).add(row);
}
return result;
}
/**
* 将存在信息错误的内容筛选出去并记录日志
* @param importData
* @return
*/
private JSONArray handleRowErrData(JSONArray importData) {
JSONArray result = new JSONArray();
for (int i = 0; i < importData.size(); i++) {
JSONObject row = importData.getJSONObject(i);
if (row.getBooleanValue("isRowOk")) {// 只获取校验通过的数据
result.add(row);
} else {
LogUtil.appendLog(BatchConst.LOG_WARNING + "校验未通过数据过滤,第[" + (i+1) + "]行数据,错误类型[" + row.getString("result") + "]", simpleLogFile);
LogUtil.appendLog(BatchConst.LOG_WARNING + "校验未通过数据过滤,第[" + (i+1) + "]行数据,错误类型[" + row.getString("result") + "],错误详细信息:" + row, fullLogFile);
}
}
return result;
}
/**
* 数据校验的结果记录到相关日志未来如果有需要可以做界面化输出和Excel输出
* @param importData
*/
private void recordTableLog(JSONArray importData) {
for (int i = 0; i < importData.size(); i++) {
LogUtil.appendLog(importData.getJSONObject(i).toString(), checkTableFile);
}
}
/**
* 计算使用时间
* @param endTime
@ -2039,201 +1861,4 @@ public class ImportShapeExcel1 {
return timeMsg;
}
/**
* 设置所有连线
* @param newElements
* @param shapeRowCount
* @return
*/
private JSONArray setElementLinkersJSONArray(JSONArray newElements, int shapeRowCount, int maxZIndex) {
JSONArray result = new JSONArray();
int zindex = maxZIndex + 1;
int count = 0;
if (newElements.size() > 1) {
for (int i = 0; i < newElements.size() - 1; i++) {
count++;
boolean isNewRow = false;
if (count % shapeRowCount == 0) {
isNewRow = true;
}
JSONObject fromShape = newElements.getJSONObject(i);
JSONObject toShape = newElements.getJSONObject(i+1);
String fromId = fromShape.getString("id");
String toId = toShape.getString("id");
JSONObject shape = JSONObject.parseObject(linkerDef);
JSONObject linker = JSON.parseObject(shape.toString());
String shapeId = UUIDGener.getObjectId();//连线id
linker.put("id", shapeId);
JSONObject fromProps = fromShape.getJSONObject("props");
JSONObject toProps = toShape.getJSONObject("props");
int fromX = validateJson(fromProps.getInteger("x"));
int fromY = validateJson(fromProps.getInteger("y"));
int fromW = validateJson(fromProps.getInteger("w"));
int fromH = validateJson(fromProps.getInteger("h"));
int toX = validateJson(toProps.getInteger("x"));
int toY = validateJson(toProps.getInteger("y"));
int toW = validateJson(toProps.getInteger("w"));
int toH = validateJson(toProps.getInteger("h"));
JSONArray fromAnchors = fromShape.getJSONArray("anchors");
int fromRightX = getRightX(fromAnchors, fromW, fromH);
JSONArray toAnchors = toShape.getJSONArray("anchors");
int toLeftX = getLeftX(toAnchors, toW, toH);
JSONObject from = new JSONObject();
JSONObject to = new JSONObject();
if (isNewRow) {
from.put("x", fromX + fromW / 2);
from.put("y", fromY + fromH);
from.put("angle", 4.71238898038469);
to.put("x", toX + toW / 2);
to.put("y", toY);
to.put("angle", 1.5707964);
JSONArray points = new JSONArray();
JSONObject point1 = new JSONObject();
point1.put("x", validateJson(from.getInteger("x")));
point1.put("y", (validateJson(from.getInteger("y")) + validateJson(to.getInteger("y"))) / 2);
points.add(point1);
JSONObject point2 = new JSONObject();
point2.put("x", validateJson(to.getInteger("x")));
point2.put("y", (validateJson(from.getInteger("y")) + validateJson(to.getInteger("y"))) / 2);
points.add(point2);
linker.put("points", points);
} else {
from.put("x", fromX + fromRightX);
from.put("y", fromY + fromH / 2);
from.put("angle", 3.141592653589793);
to.put("x", toX + toLeftX);
to.put("y", toY + toH / 2);
to.put("angle", 0);
JSONArray points = new JSONArray();
JSONObject point1 = new JSONObject();
point1.put("x", (validateJson(from.getInteger("x")) + validateJson(to.getInteger("x"))) / 2);
point1.put("y", validateJson(to.getInteger("y")));
points.add(point1);
JSONObject point2 = new JSONObject();
point2.put("x", (validateJson(from.getInteger("x")) + validateJson(to.getInteger("x"))) / 2);
point2.put("y", validateJson(to.getInteger("y")));
points.add(point2);
linker.put("points", points);
}
from.put("id", fromShape.getString("id"));
to.put("id", toShape.getString("id"));
JSONObject props = new JSONObject();
props.put("zindex", zindex);
linker.put("props", props);
linker.put("from", from);
linker.put("to", to);
result.add(linker);
zindex++;
}
}
return result;
}
private int getLeftX(JSONArray toAnchors, int w, int h) {
int minX = 99999;
for (int i = 0; i < toAnchors.size(); i++) {
String strX = toAnchors.getJSONObject(i).getString("x").replace("w", w + "").replace("h", h + "").replace("Mat" + h, "Math");
double x = Double.parseDouble(runJs(strX));
minX = minX < (int) x ? minX : (int) x;
}
return minX;
}
private int getRightX(JSONArray fromAnchors, int w, int h) {
int maxX = -999;
for (int i = 0; i < fromAnchors.size(); i++) {
String strX = fromAnchors.getJSONObject(i).getString("x").replace("w", w + "").replace("h", h + "").replace("Mat" + h, "Math");
double x = Double.parseDouble(runJs(strX));
maxX = maxX > (int) x ? maxX : (int) x;
}
return maxX;
}
/**
* 创建具有合理位置的节点数据
*
* @param elements
* @param shapeRowCount
* @return
*/
private JSONArray getMethodElementsJSONArray(JSONArray elements, int shapeRowCount, int maxZIndex, int initY) {
JSONArray result = new JSONArray();
int zindex = maxZIndex;
int initX = 0;
int pageEdge = 100;
int count = 0;
initX += pageEdge;
initY += pageEdge;
if (maxZIndex > 0) {// 在已有图的基础上增加的形状缩小默认的纵轴距离高度
initY = initY - pageEdge;
}
for (int i = 0; i < elements.size(); i++) {
JSONObject shape = elements.getJSONObject(i);
count++;
if (count % (shapeRowCount+1) == 0) {
count = 1;
initY += 90;
// 换行
initX = 0;
initX = pageEdge + initX;
}
zindex++;
if (shape.containsKey("dataAttributes")) {
JSONArray dataAttributes = JSONArray.parseArray(shape.getString("dataAttributes"));
for (int index = 0; index < dataAttributes.size(); index++) {
dataAttributes.getJSONObject(index).put("id", UUIDGener.getObjectId());
}
shape.put("dataAttributes", dataAttributes);
}
int totalWidth = 160;// 每个节点总宽度空白+节点+空白
int totalHeight = 200;// 每个节点总高度空白+节点+空白
int x = 0;
int y = 0;
int w = validateJson(shape.getJSONObject("props").getInteger("w"));
int h = validateJson(shape.getJSONObject("props").getInteger("h"));
int leftBlankWidth = (totalWidth - w)/2;
int topBlankHeight = (totalHeight - h)/2;
x = initX + leftBlankWidth;
initX = x + w + leftBlankWidth;
y = initY + topBlankHeight;
// y = pageEdge + initY;
// if (y < 0) {
// y = 100;
// }
JSONObject props = shape.getJSONObject("props");
props.put("x", x);
props.put("y", y);
props.put("zindex", zindex);
shape.put("props", props);
result.add(shape);
}
return result;
}
private int validateJson(Integer index) {
return index == null ? 0 : index;
}
/**
* 转换为js
*
* @param val
* @return string
*/
private static String runJs(String val) {
String jsVal = "";
try {
Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects();
Object result = cx.evaluateString(scope, val, null, 1, null);
jsVal = Context.toString(result);
} finally {
Context.exit();
}
return jsVal;
}
}